2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 int Protocol
= PROTOCOL_COREPLUS
;
32 /* a default finfo structure to ensure all fields are sensible */
33 file_info def_finfo
= {-1,0,0,0,0,0,0,""};
35 /* these are some file handles where debug info will be stored */
38 /* the client file descriptor */
41 /* the last IP received from */
42 struct in_addr lastip
;
44 /* the last port received from */
47 /* this is used by the chaining code */
53 case handling on filenames
55 int case_default
= CASE_LOWER
;
60 /* the following control case operations - they are put here so the
61 client can link easily */
64 BOOL use_mangled_map
= False
;
65 BOOL short_case_preserve
;
68 fstring remote_machine
="";
69 fstring local_machine
="";
70 fstring remote_arch
="UNKNOWN";
71 fstring remote_proto
="UNKNOWN";
72 pstring myhostname
="";
73 pstring user_socket_options
="";
74 pstring sesssetup_user
="";
76 fstring myworkgroup
= "";
77 char **my_netbios_names
;
79 int smb_read_error
= 0;
81 static BOOL stdout_logging
= False
;
83 static char *filename_dos(char *path
,char *buf
);
85 /*******************************************************************
86 get ready for syslog stuff
87 ******************************************************************/
88 void setup_logging(char *pname
,BOOL interactive
)
92 char *p
= strrchr(pname
,'/');
94 openlog(pname
, LOG_PID
, LOG_DAEMON
);
98 stdout_logging
= True
;
104 BOOL append_log
=False
;
107 /****************************************************************************
109 ****************************************************************************/
110 void reopen_logs(void)
117 strcpy(fname
,debugf
);
118 if (lp_loaded() && (*lp_logfile()))
119 strcpy(fname
,lp_logfile());
121 if (!strcsequal(fname
,debugf
) || !dbf
|| !file_exist(debugf
,NULL
))
123 int oldumask
= umask(022);
124 strcpy(debugf
,fname
);
125 if (dbf
) fclose(dbf
);
127 dbf
= fopen(debugf
,"a");
129 dbf
= fopen(debugf
,"w");
130 if (dbf
) setbuf(dbf
,NULL
);
145 /*******************************************************************
146 check if the log has grown too big
147 ********************************************************************/
148 static void check_log_size(void)
150 static int debug_count
=0;
154 if (debug_count
++ < 100) return;
156 maxlog
= lp_max_log_size() * 1024;
157 if (!dbf
|| maxlog
<= 0) return;
159 if (fstat(fileno(dbf
),&st
) == 0 && st
.st_size
> maxlog
) {
160 fclose(dbf
); dbf
= NULL
;
162 if (dbf
&& file_size(debugf
) > maxlog
) {
164 fclose(dbf
); dbf
= NULL
;
165 sprintf(name
,"%s.old",debugf
);
166 sys_rename(debugf
,name
);
174 /*******************************************************************
175 write an debug message on the debugfile. This is called by the DEBUG
177 ********************************************************************/
179 int Debug1(char *format_str
, ...)
189 if (stdout_logging
) {
191 va_start(ap
, format_str
);
194 format_str
= va_arg(ap
,char *);
196 vfprintf(dbf
,format_str
,ap
);
202 if (!lp_syslog_only())
207 int oldumask
= umask(022);
208 dbf
= fopen(debugf
,"w");
218 if (syslog_level
< lp_syslog())
221 * map debug levels to syslog() priorities
222 * note that not all DEBUG(0, ...) calls are
225 static int priority_map
[] = {
234 if (syslog_level
>= sizeof(priority_map
) / sizeof(priority_map
[0]) ||
236 priority
= LOG_DEBUG
;
238 priority
= priority_map
[syslog_level
];
241 va_start(ap
, format_str
);
244 format_str
= va_arg(ap
,char *);
246 vsprintf(msgbuf
, format_str
, ap
);
250 syslog(priority
, "%s", msgbuf
);
255 if (!lp_syslog_only())
259 va_start(ap
, format_str
);
262 format_str
= va_arg(ap
,char *);
264 vfprintf(dbf
,format_str
,ap
);
274 /****************************************************************************
275 find a suitable temporary directory. The result should be copied immediately
276 as it may be overwritten by a subsequent call
277 ****************************************************************************/
281 if ((p
= getenv("TMPDIR"))) {
289 /****************************************************************************
290 determine if a file descriptor is in fact a socket
291 ****************************************************************************/
292 BOOL
is_a_socket(int fd
)
296 return(getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (char *)&v
, &l
) == 0);
300 static char *last_ptr
=NULL
;
302 /****************************************************************************
303 Get the next token from a string, return False if none found
304 handles double-quotes.
305 Based on a routine by GJC@VILLAGE.COM.
306 Extensively modified by Andrew.Tridgell@anu.edu.au
307 ****************************************************************************/
308 BOOL
next_token(char **ptr
,char *buff
,char *sep
)
313 if (!ptr
) ptr
= &last_ptr
;
314 if (!ptr
) return(False
);
318 /* default to simple separators */
319 if (!sep
) sep
= " \t\n\r";
321 /* find the first non sep char */
322 while(*s
&& strchr(sep
,*s
)) s
++;
325 if (! *s
) return(False
);
327 /* copy over the token */
328 for (quoted
= False
; *s
&& (quoted
|| !strchr(sep
,*s
)); s
++)
336 *ptr
= (*s
) ? s
+1 : s
;
343 /****************************************************************************
344 Convert list of tokens to array; dependent on above routine.
345 Uses last_ptr from above - bit of a hack.
346 ****************************************************************************/
347 char **toktocliplist(int *ctok
, char *sep
)
353 if (!sep
) sep
= " \t\n\r";
355 while(*s
&& strchr(sep
,*s
)) s
++;
358 if (!*s
) return(NULL
);
362 while(*s
&& (!strchr(sep
,*s
))) s
++;
363 while(*s
&& strchr(sep
,*s
)) *s
++=0;
369 if (!(ret
=iret
=malloc(ictok
*sizeof(char *)))) return NULL
;
381 /*******************************************************************
382 safely copies memory, ensuring no overlap problems.
383 this is only used if the machine does not have it's own memmove().
384 this is not the fastest algorithm in town, but it will do for our
386 ********************************************************************/
387 void *MemMove(void *dest
,void *src
,int size
)
391 if (dest
==src
|| !size
) return(dest
);
393 d
= (unsigned long)dest
;
394 s
= (unsigned long)src
;
396 if ((d
>= (s
+size
)) || (s
>= (d
+size
))) {
398 memcpy(dest
,src
,size
);
404 /* we can forward copy */
405 if (s
-d
>= sizeof(int) &&
406 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
407 /* do it all as words */
408 int *idest
= (int *)dest
;
409 int *isrc
= (int *)src
;
411 for (i
=0;i
<size
;i
++) idest
[i
] = isrc
[i
];
414 char *cdest
= (char *)dest
;
415 char *csrc
= (char *)src
;
416 for (i
=0;i
<size
;i
++) cdest
[i
] = csrc
[i
];
421 /* must backward copy */
422 if (d
-s
>= sizeof(int) &&
423 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
424 /* do it all as words */
425 int *idest
= (int *)dest
;
426 int *isrc
= (int *)src
;
428 for (i
=size
-1;i
>=0;i
--) idest
[i
] = isrc
[i
];
431 char *cdest
= (char *)dest
;
432 char *csrc
= (char *)src
;
433 for (i
=size
-1;i
>=0;i
--) cdest
[i
] = csrc
[i
];
441 /****************************************************************************
442 prompte a dptr (to make it recently used)
443 ****************************************************************************/
444 void array_promote(char *array
,int elsize
,int element
)
450 p
= (char *)malloc(elsize
);
454 DEBUG(5,("Ahh! Can't malloc\n"));
457 memcpy(p
,array
+ element
* elsize
, elsize
);
458 memmove(array
+ elsize
,array
,elsize
*element
);
459 memcpy(array
,p
,elsize
);
463 enum SOCK_OPT_TYPES
{OPT_BOOL
,OPT_INT
,OPT_ON
};
472 } socket_options
[] = {
473 {"SO_KEEPALIVE", SOL_SOCKET
, SO_KEEPALIVE
, 0, OPT_BOOL
},
474 {"SO_REUSEADDR", SOL_SOCKET
, SO_REUSEADDR
, 0, OPT_BOOL
},
475 {"SO_BROADCAST", SOL_SOCKET
, SO_BROADCAST
, 0, OPT_BOOL
},
477 {"TCP_NODELAY", IPPROTO_TCP
, TCP_NODELAY
, 0, OPT_BOOL
},
479 #ifdef IPTOS_LOWDELAY
480 {"IPTOS_LOWDELAY", IPPROTO_IP
, IP_TOS
, IPTOS_LOWDELAY
, OPT_ON
},
482 #ifdef IPTOS_THROUGHPUT
483 {"IPTOS_THROUGHPUT", IPPROTO_IP
, IP_TOS
, IPTOS_THROUGHPUT
, OPT_ON
},
486 {"SO_SNDBUF", SOL_SOCKET
, SO_SNDBUF
, 0, OPT_INT
},
489 {"SO_RCVBUF", SOL_SOCKET
, SO_RCVBUF
, 0, OPT_INT
},
492 {"SO_SNDLOWAT", SOL_SOCKET
, SO_SNDLOWAT
, 0, OPT_INT
},
495 {"SO_RCVLOWAT", SOL_SOCKET
, SO_RCVLOWAT
, 0, OPT_INT
},
498 {"SO_SNDTIMEO", SOL_SOCKET
, SO_SNDTIMEO
, 0, OPT_INT
},
501 {"SO_RCVTIMEO", SOL_SOCKET
, SO_RCVTIMEO
, 0, OPT_INT
},
507 /****************************************************************************
508 set user socket options
509 ****************************************************************************/
510 void set_socket_options(int fd
, char *options
)
514 while (next_token(&options
,tok
," \t,"))
519 BOOL got_value
= False
;
521 if ((p
= strchr(tok
,'=')))
528 for (i
=0;socket_options
[i
].name
;i
++)
529 if (strequal(socket_options
[i
].name
,tok
))
532 if (!socket_options
[i
].name
)
534 DEBUG(0,("Unknown socket option %s\n",tok
));
538 switch (socket_options
[i
].opttype
)
542 ret
= setsockopt(fd
,socket_options
[i
].level
,
543 socket_options
[i
].option
,(char *)&value
,sizeof(int));
548 DEBUG(0,("syntax error - %s does not take a value\n",tok
));
551 int on
= socket_options
[i
].value
;
552 ret
= setsockopt(fd
,socket_options
[i
].level
,
553 socket_options
[i
].option
,(char *)&on
,sizeof(int));
559 DEBUG(0,("Failed to set socket option %s\n",tok
));
565 /****************************************************************************
566 close the socket communication
567 ****************************************************************************/
568 void close_sockets(void )
574 /****************************************************************************
575 determine whether we are in the specified group
576 ****************************************************************************/
577 BOOL
in_group(gid_t group
, int current_gid
, int ngroups
, int *groups
)
581 if (group
== current_gid
) return(True
);
583 for (i
=0;i
<ngroups
;i
++)
584 if (group
== groups
[i
])
590 /****************************************************************************
591 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
592 ****************************************************************************/
593 char *StrCpy(char *dest
,char *src
)
598 /* I don't want to get lazy with these ... */
600 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
605 if (!dest
) return(NULL
);
610 while ((*d
++ = *src
++)) ;
614 /****************************************************************************
615 line strncpy but always null terminates. Make sure there is room!
616 ****************************************************************************/
617 char *StrnCpy(char *dest
,char *src
,int n
)
620 if (!dest
) return(NULL
);
625 while (n
-- && (*d
++ = *src
++)) ;
631 /*******************************************************************
632 copy an IP address from one buffer to another
633 ********************************************************************/
634 void putip(void *dest
,void *src
)
640 /****************************************************************************
641 interpret the weird netbios "name". Return the name type
642 ****************************************************************************/
643 static int name_interpret(char *in
,char *out
)
646 int len
= (*in
++) / 2;
650 if (len
> 30 || len
<1) return(0);
654 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
658 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
666 /* Handle any scope names */
669 *out
++ = '.'; /* Scope names are separated by periods */
670 len
= *(unsigned char *)in
++;
671 StrnCpy(out
, in
, len
);
680 /****************************************************************************
681 mangle a name into netbios format
682 ****************************************************************************/
683 int name_mangle(char *In
,char *Out
,char name_type
)
687 char *in
= (char *)&buf
[0];
688 char *out
= (char *)Out
;
693 StrnCpy(name
,In
,sizeof(name
)-1);
694 sprintf(buf
,"%-15.15s%c",name
,name_type
);
697 memset(&buf
[1],0,16);
702 char c
= toupper(in
[i
]);
703 out
[i
*2] = (c
>>4) + 'A';
704 out
[i
*2+1] = (c
& 0xF) + 'A';
712 p
= strchr(label
, '.');
714 p
= label
+ strlen(label
);
716 memcpy(out
, label
, p
- label
);
718 label
+= p
- label
+ (*p
== '.');
721 return(name_len(Out
));
725 /*******************************************************************
726 check if a file exists
727 ********************************************************************/
728 BOOL
file_exist(char *fname
,struct stat
*sbuf
)
731 if (!sbuf
) sbuf
= &st
;
733 if (sys_stat(fname
,sbuf
) != 0)
736 return(S_ISREG(sbuf
->st_mode
));
739 /*******************************************************************
740 check a files mod time
741 ********************************************************************/
742 time_t file_modtime(char *fname
)
746 if (sys_stat(fname
,&st
) != 0)
752 /*******************************************************************
753 check if a directory exists
754 ********************************************************************/
755 BOOL
directory_exist(char *dname
,struct stat
*st
)
760 if (sys_stat(dname
,st
) != 0)
763 return(S_ISDIR(st
->st_mode
));
766 /*******************************************************************
767 returns the size in bytes of the named file
768 ********************************************************************/
769 uint32
file_size(char *file_name
)
773 sys_stat(file_name
,&buf
);
777 /*******************************************************************
778 return a string representing an attribute for a file
779 ********************************************************************/
780 char *attrib_string(int mode
)
782 static char attrstr
[10];
786 if (mode
& aVOLID
) strcat(attrstr
,"V");
787 if (mode
& aDIR
) strcat(attrstr
,"D");
788 if (mode
& aARCH
) strcat(attrstr
,"A");
789 if (mode
& aHIDDEN
) strcat(attrstr
,"H");
790 if (mode
& aSYSTEM
) strcat(attrstr
,"S");
791 if (mode
& aRONLY
) strcat(attrstr
,"R");
797 /*******************************************************************
798 case insensitive string compararison
799 ********************************************************************/
800 int StrCaseCmp(const char *s
, const char *t
)
802 /* compare until we run out of string, either t or s, or find a difference */
803 /* We *must* use toupper rather than tolower here due to the
804 asynchronous upper to lower mapping.
806 while (*s
&& *t
&& toupper(*s
) == toupper(*t
))
811 return(toupper(*s
) - toupper(*t
));
814 /*******************************************************************
815 case insensitive string compararison, length limited
816 ********************************************************************/
817 int StrnCaseCmp(const char *s
, const char *t
, int n
)
819 /* compare until we run out of string, either t or s, or chars */
820 /* We *must* use toupper rather than tolower here due to the
821 asynchronous upper to lower mapping.
823 while (n
-- && *s
&& *t
&& toupper(*s
) == toupper(*t
))
828 /* not run out of chars - strings are different lengths */
829 if (n
) return(toupper(*s
) - toupper(*t
));
831 /* identical up to where we run out of chars, and strings are same length */
835 /*******************************************************************
837 ********************************************************************/
838 BOOL
strequal(const char *s1
, const char *s2
)
840 if (s1
== s2
) return(True
);
841 if (!s1
|| !s2
) return(False
);
843 return(StrCaseCmp(s1
,s2
)==0);
846 /*******************************************************************
847 compare 2 strings up to and including the nth char.
848 ******************************************************************/
849 BOOL
strnequal(const char *s1
,const char *s2
,int n
)
851 if (s1
== s2
) return(True
);
852 if (!s1
|| !s2
|| !n
) return(False
);
854 return(StrnCaseCmp(s1
,s2
,n
)==0);
857 /*******************************************************************
858 compare 2 strings (case sensitive)
859 ********************************************************************/
860 BOOL
strcsequal(char *s1
,char *s2
)
862 if (s1
== s2
) return(True
);
863 if (!s1
|| !s2
) return(False
);
865 return(strcmp(s1
,s2
)==0);
869 /*******************************************************************
870 convert a string to lower case
871 ********************************************************************/
872 void strlower(char *s
)
877 if (is_shift_jis (*s
)) {
879 } else if (is_kana (*s
)) {
894 /*******************************************************************
895 convert a string to upper case
896 ********************************************************************/
897 void strupper(char *s
)
902 if (is_shift_jis (*s
)) {
904 } else if (is_kana (*s
)) {
919 /*******************************************************************
920 convert a string to "normal" form
921 ********************************************************************/
922 void strnorm(char *s
)
924 if (case_default
== CASE_UPPER
)
930 /*******************************************************************
931 check if a string is in "normal" case
932 ********************************************************************/
933 BOOL
strisnormal(char *s
)
935 if (case_default
== CASE_UPPER
)
936 return(!strhaslower(s
));
938 return(!strhasupper(s
));
942 /****************************************************************************
944 ****************************************************************************/
945 void string_replace(char *s
,char oldc
,char newc
)
950 if (is_shift_jis (*s
)) {
952 } else if (is_kana (*s
)) {
967 /****************************************************************************
968 make a file into unix format
969 ****************************************************************************/
970 void unix_format(char *fname
)
973 string_replace(fname
,'\\','/');
977 strcpy(namecopy
,fname
);
979 strcat(fname
,namecopy
);
983 /****************************************************************************
984 make a file into dos format
985 ****************************************************************************/
986 void dos_format(char *fname
)
988 string_replace(fname
,'/','\\');
992 /*******************************************************************
993 show a smb message structure
994 ********************************************************************/
995 void show_msg(char *buf
)
1003 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1005 (int)CVAL(buf
,smb_com
),
1006 (int)CVAL(buf
,smb_rcls
),
1007 (int)CVAL(buf
,smb_reh
),
1008 (int)SVAL(buf
,smb_err
),
1009 (int)CVAL(buf
,smb_flg
),
1010 (int)SVAL(buf
,smb_flg2
)));
1011 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1012 (int)SVAL(buf
,smb_tid
),
1013 (int)SVAL(buf
,smb_pid
),
1014 (int)SVAL(buf
,smb_uid
),
1015 (int)SVAL(buf
,smb_mid
),
1016 (int)CVAL(buf
,smb_wct
)));
1017 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
1018 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i
,
1019 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
1020 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
1021 DEBUG(5,("smb_bcc=%d\n",bcc
));
1022 if (DEBUGLEVEL
< 10)
1024 for (i
= 0; i
< MIN(bcc
, 256); i
+= 16)
1026 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1029 DEBUG(10,("%2X ",CVAL(smb_buf(buf
),i
+j
)));
1030 if (j
== 7) DEBUG(10, (" "));
1035 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1037 unsigned char c
= CVAL(smb_buf(buf
),i
+j
);
1038 if (c
< 32 || c
> 128) c
= '.';
1041 if (j
== 7) DEBUG(10, (" "));
1048 /*******************************************************************
1049 return the length of an smb packet
1050 ********************************************************************/
1051 int smb_len(char *buf
)
1053 return( PVAL(buf
,3) | (PVAL(buf
,2)<<8) | ((PVAL(buf
,1)&1)<<16) );
1056 /*******************************************************************
1057 set the length of an smb packet
1058 ********************************************************************/
1059 void _smb_setlen(char *buf
,int len
)
1062 buf
[1] = (len
&0x10000)>>16;
1063 buf
[2] = (len
&0xFF00)>>8;
1067 /*******************************************************************
1068 set the length and marker of an smb packet
1069 ********************************************************************/
1070 void smb_setlen(char *buf
,int len
)
1072 _smb_setlen(buf
,len
);
1080 /*******************************************************************
1081 setup the word count and byte count for a smb message
1082 ********************************************************************/
1083 int set_message(char *buf
,int num_words
,int num_bytes
,BOOL zero
)
1086 bzero(buf
+ smb_size
,num_words
*2 + num_bytes
);
1087 CVAL(buf
,smb_wct
) = num_words
;
1088 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1089 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1090 return (smb_size
+ num_words
*2 + num_bytes
);
1093 /*******************************************************************
1094 return the number of smb words
1095 ********************************************************************/
1096 int smb_numwords(char *buf
)
1098 return (CVAL(buf
,smb_wct
));
1101 /*******************************************************************
1102 return the size of the smb_buf region of a message
1103 ********************************************************************/
1104 int smb_buflen(char *buf
)
1106 return(SVAL(buf
,smb_vwv0
+ smb_numwords(buf
)*2));
1109 /*******************************************************************
1110 return a pointer to the smb_buf data area
1111 ********************************************************************/
1112 int smb_buf_ofs(char *buf
)
1114 return (smb_size
+ CVAL(buf
,smb_wct
)*2);
1117 /*******************************************************************
1118 return a pointer to the smb_buf data area
1119 ********************************************************************/
1120 char *smb_buf(char *buf
)
1122 return (buf
+ smb_buf_ofs(buf
));
1125 /*******************************************************************
1126 return the SMB offset into an SMB buffer
1127 ********************************************************************/
1128 int smb_offset(char *p
,char *buf
)
1130 return(PTR_DIFF(p
,buf
+4) + chain_size
);
1134 /*******************************************************************
1135 skip past some strings in a buffer
1136 ********************************************************************/
1137 char *skip_string(char *buf
,int n
)
1140 buf
+= strlen(buf
) + 1;
1144 /*******************************************************************
1145 trim the specified elements off the front and back of a string
1146 ********************************************************************/
1147 BOOL
trim_string(char *s
,char *front
,char *back
)
1150 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1156 if (!(*p
= p
[strlen(front
)]))
1161 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1162 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1165 s
[strlen(s
)-strlen(back
)] = 0;
1171 /*******************************************************************
1172 reduce a file name, removing .. elements.
1173 ********************************************************************/
1174 void dos_clean_name(char *s
)
1178 DEBUG(3,("dos_clean_name [%s]\n",s
));
1180 /* remove any double slashes */
1181 string_sub(s
, "\\\\", "\\");
1183 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1190 if ((p
=strrchr(s
,'\\')) != NULL
)
1197 trim_string(s
,NULL
,"\\..");
1199 string_sub(s
, "\\.\\", "\\");
1202 /*******************************************************************
1203 reduce a file name, removing .. elements.
1204 ********************************************************************/
1205 void unix_clean_name(char *s
)
1209 DEBUG(3,("unix_clean_name [%s]\n",s
));
1211 /* remove any double slashes */
1212 string_sub(s
, "//","/");
1214 /* Remove leading ./ characters */
1215 if(strncmp(s
, "./", 2) == 0) {
1216 trim_string(s
, "./", NULL
);
1221 while ((p
= strstr(s
,"/../")) != NULL
)
1228 if ((p
=strrchr(s
,'/')) != NULL
)
1235 trim_string(s
,NULL
,"/..");
1239 /*******************************************************************
1240 a wrapper for the normal chdir() function
1241 ********************************************************************/
1242 int ChDir(char *path
)
1245 static pstring LastDir
="";
1247 if (strcsequal(path
,".")) return(0);
1249 if (*path
== '/' && strcsequal(LastDir
,path
)) return(0);
1250 DEBUG(3,("chdir to %s\n",path
));
1251 res
= sys_chdir(path
);
1253 strcpy(LastDir
,path
);
1258 /*******************************************************************
1259 return the absolute current directory path. A dumb version.
1260 ********************************************************************/
1261 static char *Dumb_GetWd(char *s
)
1265 p
= (char *)getcwd(s
,sizeof(pstring
));
1267 p
= (char *)getwd(s
));
1272 /* Ensure we always return in dos format. */
1273 unix_to_dos(p
,True
);
1278 /* number of list structures for a caching GetWd function. */
1279 #define MAX_GETWDCACHE (50)
1287 } ino_list
[MAX_GETWDCACHE
];
1289 BOOL use_getwd_cache
=True
;
1291 /*******************************************************************
1292 return the absolute current directory path
1293 ********************************************************************/
1294 char *GetWd(char *str
)
1297 static BOOL getwd_cache_init
= False
;
1298 struct stat st
, st2
;
1303 if (!use_getwd_cache
)
1304 return(Dumb_GetWd(str
));
1306 /* init the cache */
1307 if (!getwd_cache_init
)
1309 getwd_cache_init
= True
;
1310 for (i
=0;i
<MAX_GETWDCACHE
;i
++)
1312 string_init(&ino_list
[i
].text
,"");
1313 ino_list
[i
].valid
= False
;
1317 /* Get the inode of the current directory, if this doesn't work we're
1320 if (stat(".",&st
) == -1)
1322 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1323 return(Dumb_GetWd(str
));
1327 for (i
=0; i
<MAX_GETWDCACHE
; i
++)
1328 if (ino_list
[i
].valid
)
1331 /* If we have found an entry with a matching inode and dev number
1332 then find the inode number for the directory in the cached string.
1333 If this agrees with that returned by the stat for the current
1334 directory then all is o.k. (but make sure it is a directory all
1337 if (st
.st_ino
== ino_list
[i
].inode
&&
1338 st
.st_dev
== ino_list
[i
].dev
)
1340 if (stat(ino_list
[i
].text
,&st2
) == 0)
1342 if (st
.st_ino
== st2
.st_ino
&&
1343 st
.st_dev
== st2
.st_dev
&&
1344 (st2
.st_mode
& S_IFMT
) == S_IFDIR
)
1346 strcpy (str
, ino_list
[i
].text
);
1348 /* promote it for future use */
1349 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1354 /* If the inode is different then something's changed,
1355 scrub the entry and start from scratch. */
1356 ino_list
[i
].valid
= False
;
1363 /* We don't have the information to hand so rely on traditional methods.
1364 The very slow getcwd, which spawns a process on some systems, or the
1365 not quite so bad getwd. */
1369 DEBUG(0,("Getwd failed, errno %d\n",errno
));
1375 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s
,(int)st
.st_ino
,(int)st
.st_dev
));
1377 /* add it to the cache */
1378 i
= MAX_GETWDCACHE
- 1;
1379 string_set(&ino_list
[i
].text
,s
);
1380 ino_list
[i
].dev
= st
.st_dev
;
1381 ino_list
[i
].inode
= st
.st_ino
;
1382 ino_list
[i
].valid
= True
;
1384 /* put it at the top of the list */
1385 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1392 /*******************************************************************
1393 reduce a file name, removing .. elements and checking that
1394 it is below dir in the heirachy. This uses GetWd() and so must be run
1395 on the system that has the referenced file system.
1397 widelinks are allowed if widelinks is true
1398 ********************************************************************/
1399 BOOL
reduce_name(char *s
,char *dir
,BOOL widelinks
)
1401 #ifndef REDUCE_PATHS
1409 BOOL relative
= (*s
!= '/');
1411 *dir2
= *wd
= *basename
= *newname
= 0;
1416 /* can't have a leading .. */
1417 if (strncmp(s
,"..",2) == 0 && (s
[2]==0 || s
[2]=='/'))
1419 DEBUG(3,("Illegal file name? (%s)\n",s
));
1429 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1431 /* remove any double slashes */
1432 string_sub(s
,"//","/");
1435 p
= strrchr(basename
,'/');
1442 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1446 if (ChDir(dir
) != 0)
1448 DEBUG(0,("couldn't chdir to %s\n",dir
));
1454 DEBUG(0,("couldn't getwd for %s\n",dir
));
1460 if (p
&& (p
!= basename
))
1463 if (strcmp(p
+1,".")==0)
1465 if (strcmp(p
+1,"..")==0)
1469 if (ChDir(basename
) != 0)
1472 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,basename
));
1476 if (!GetWd(newname
))
1479 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1483 if (p
&& (p
!= basename
))
1485 strcat(newname
,"/");
1486 strcat(newname
,p
+1);
1490 int l
= strlen(dir2
);
1491 if (dir2
[l
-1] == '/')
1494 if (strncmp(newname
,dir2
,l
) != 0)
1497 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1503 if (newname
[l
] == '/')
1504 strcpy(s
,newname
+ l
+ 1);
1506 strcpy(s
,newname
+l
);
1517 DEBUG(3,("reduced to %s\n",s
));
1522 /****************************************************************************
1524 ****************************************************************************/
1525 static void expand_one(char *Mask
,int len
)
1528 while ((p1
= strchr(Mask
,'*')) != NULL
)
1530 int lfill
= (len
+1) - strlen(Mask
);
1531 int l1
= (p1
- Mask
);
1534 memset(tmp
+l1
,'?',lfill
);
1535 strcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1540 /****************************************************************************
1541 expand a wildcard expression, replacing *s with ?s
1542 ****************************************************************************/
1543 void expand_mask(char *Mask
,BOOL doext
)
1548 BOOL hasdot
= False
;
1550 BOOL absolute
= (*Mask
== '\\');
1552 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
1554 /* parse the directory and filename */
1555 if (strchr(Mask
,'\\'))
1556 dirname_dos(Mask
,dirpart
);
1558 filename_dos(Mask
,filepart
);
1560 strcpy(mbeg
,filepart
);
1561 if ((p1
= strchr(mbeg
,'.')) != NULL
)
1571 if (strlen(mbeg
) > 8)
1573 strcpy(mext
,mbeg
+ 8);
1579 strcpy(mbeg
,"????????");
1580 if ((*mext
== 0) && doext
&& !hasdot
)
1583 if (strequal(mbeg
,"*") && *mext
==0)
1591 strcpy(Mask
,dirpart
);
1592 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
1597 DEBUG(6,("Mask expanded to [%s]\n",Mask
));
1601 /****************************************************************************
1602 does a string have any uppercase chars in it?
1603 ****************************************************************************/
1604 BOOL
strhasupper(char *s
)
1609 if (is_shift_jis (*s
)) {
1611 } else if (is_kana (*s
)) {
1614 if (isupper(*s
)) return(True
);
1618 if (isupper(*s
)) return(True
);
1625 /****************************************************************************
1626 does a string have any lowercase chars in it?
1627 ****************************************************************************/
1628 BOOL
strhaslower(char *s
)
1633 if (is_shift_jis (*s
)) {
1635 } else if (is_kana (*s
)) {
1638 if (islower(*s
)) return(True
);
1642 if (islower(*s
)) return(True
);
1649 /****************************************************************************
1650 find the number of chars in a string
1651 ****************************************************************************/
1652 int count_chars(char *s
,char c
)
1665 /****************************************************************************
1667 ****************************************************************************/
1668 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1675 if ((mode
& aDIR
) != 0)
1678 memset(buf
+1,' ',11);
1679 if ((p
= strchr(mask2
,'.')) != NULL
)
1682 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1683 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
1687 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),11));
1689 bzero(buf
+21,DIR_STRUCT_SIZE
-21);
1690 CVAL(buf
,21) = mode
;
1691 put_dos_date(buf
,22,date
);
1692 SSVAL(buf
,26,size
& 0xFFFF);
1693 SSVAL(buf
,28,size
>> 16);
1694 StrnCpy(buf
+30,fname
,12);
1695 if (!case_sensitive
)
1697 DEBUG(8,("put name [%s] into dir struct\n",buf
+30));
1701 /*******************************************************************
1702 close the low 3 fd's and open dev/null in their place
1703 ********************************************************************/
1704 void close_low_fds(void)
1708 close(0); close(1); close(2);
1709 /* try and use up these file descriptors, so silly
1710 library routines writing to stdout etc won't cause havoc */
1712 fd
= open("/dev/null",O_RDWR
,0);
1713 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
1715 DEBUG(0,("Can't open /dev/null\n"));
1719 DEBUG(0,("Didn't get file descriptor %d\n",i
));
1725 /****************************************************************************
1726 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1728 if SYSV use O_NDELAY
1730 ****************************************************************************/
1731 int set_blocking(int fd
, BOOL set
)
1735 #define FLAG_TO_SET O_NONBLOCK
1738 #define FLAG_TO_SET O_NDELAY
1740 #define FLAG_TO_SET FNDELAY
1744 if((val
= fcntl(fd
, F_GETFL
, 0)) == -1)
1746 if(set
) /* Turn blocking on - ie. clear nonblock flag */
1747 val
&= ~FLAG_TO_SET
;
1750 return fcntl( fd
, F_SETFL
, val
);
1755 /****************************************************************************
1757 ****************************************************************************/
1758 int write_socket(int fd
,char *buf
,int len
)
1764 DEBUG(6,("write_socket(%d,%d)\n",fd
,len
));
1765 ret
= write_data(fd
,buf
,len
);
1767 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,len
,ret
));
1771 /****************************************************************************
1773 ****************************************************************************/
1774 int read_udp_socket(int fd
,char *buf
,int len
)
1777 struct sockaddr sock
;
1780 socklen
= sizeof(sock
);
1781 bzero((char *)&sock
,socklen
);
1782 bzero((char *)&lastip
,sizeof(lastip
));
1783 ret
= recvfrom(fd
,buf
,len
,0,&sock
,&socklen
);
1785 DEBUG(2,("read socket failed. ERRNO=%d\n",errno
));
1789 lastip
= *(struct in_addr
*) &sock
.sa_data
[2];
1790 lastport
= ntohs(((struct sockaddr_in
*)&sock
)->sin_port
);
1795 /****************************************************************************
1796 read data from a device with a timout in msec.
1797 mincount = if timeout, minimum to read before returning
1798 maxcount = number to be read.
1799 ****************************************************************************/
1800 int read_with_timeout(int fd
,char *buf
,int mincnt
,int maxcnt
,long time_out
)
1806 struct timeval timeout
;
1808 /* just checking .... */
1809 if (maxcnt
<= 0) return(0);
1814 if (time_out
<= 0) {
1815 if (mincnt
== 0) mincnt
= maxcnt
;
1817 while (nread
< mincnt
) {
1818 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
1820 smb_read_error
= READ_EOF
;
1824 if (readret
== -1) {
1825 smb_read_error
= READ_ERROR
;
1833 /* Most difficult - timeout read */
1834 /* If this is ever called on a disk file and
1835 mincnt is greater then the filesize then
1836 system performance will suffer severely as
1837 select always return true on disk files */
1839 /* Set initial timeout */
1840 timeout
.tv_sec
= time_out
/ 1000;
1841 timeout
.tv_usec
= 1000 * (time_out
% 1000);
1843 for (nread
=0; nread
<mincnt
; )
1848 selrtn
= sys_select(&fds
,&timeout
);
1850 /* Check if error */
1852 /* something is wrong. Maybe the socket is dead? */
1853 smb_read_error
= READ_ERROR
;
1857 /* Did we timeout ? */
1859 smb_read_error
= READ_TIMEOUT
;
1863 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
1865 /* we got EOF on the file descriptor */
1866 smb_read_error
= READ_EOF
;
1870 if (readret
== -1) {
1871 /* the descriptor is probably dead */
1872 smb_read_error
= READ_ERROR
;
1879 /* Return the number we got */
1883 /****************************************************************************
1884 read data from the client. Maxtime is in milliseconds
1885 ****************************************************************************/
1886 int read_max_udp(int fd
,char *buffer
,int bufsize
,int maxtime
)
1891 struct timeval timeout
;
1896 timeout
.tv_sec
= maxtime
/ 1000;
1897 timeout
.tv_usec
= (maxtime
% 1000) * 1000;
1899 selrtn
= sys_select(&fds
,maxtime
>0?&timeout
:NULL
);
1901 if (!FD_ISSET(fd
,&fds
))
1904 nread
= read_udp_socket(fd
, buffer
, bufsize
);
1906 /* return the number got */
1910 /*******************************************************************
1911 find the difference in milliseconds between two struct timeval
1913 ********************************************************************/
1914 int TvalDiff(struct timeval
*tvalold
,struct timeval
*tvalnew
)
1916 return((tvalnew
->tv_sec
- tvalold
->tv_sec
)*1000 +
1917 ((int)tvalnew
->tv_usec
- (int)tvalold
->tv_usec
)/1000);
1920 /****************************************************************************
1921 send a keepalive packet (rfc1002)
1922 ****************************************************************************/
1923 BOOL
send_keepalive(int client
)
1925 unsigned char buf
[4];
1928 buf
[1] = buf
[2] = buf
[3] = 0;
1930 return(write_data(client
,(char *)buf
,4) == 4);
1935 /****************************************************************************
1936 read data from the client, reading exactly N bytes.
1937 ****************************************************************************/
1938 int read_data(int fd
,char *buffer
,int N
)
1947 ret
= read(fd
,buffer
+ total
,N
- total
);
1949 smb_read_error
= READ_EOF
;
1953 smb_read_error
= READ_ERROR
;
1962 /****************************************************************************
1964 ****************************************************************************/
1965 int write_data(int fd
,char *buffer
,int N
)
1972 ret
= write(fd
,buffer
+ total
,N
- total
);
1974 if (ret
== -1) return -1;
1975 if (ret
== 0) return total
;
1983 /****************************************************************************
1984 transfer some data between two fd's
1985 ****************************************************************************/
1986 int transfer_file(int infd
,int outfd
,int n
,char *header
,int headlen
,int align
)
1988 static char *buf
=NULL
;
1993 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
1996 size
= lp_readsize();
1997 size
= MAX(size
,1024);
2000 while (!buf
&& size
>0) {
2001 buf
= (char *)Realloc(buf
,size
+8);
2002 if (!buf
) size
/= 2;
2006 DEBUG(0,("Can't allocate transfer buffer!\n"));
2010 abuf
= buf
+ (align
%8);
2017 int s
= MIN(n
,size
);
2022 if (header
&& (headlen
>= MIN(s
,1024))) {
2032 if (header
&& headlen
> 0)
2034 ret
= MIN(headlen
,size
);
2035 memcpy(buf1
,header
,ret
);
2038 if (headlen
<= 0) header
= NULL
;
2042 ret
+= read(infd
,buf1
+ret
,s
-ret
);
2046 ret2
= (outfd
>=0?write_data(outfd
,buf1
,ret
):ret
);
2047 if (ret2
> 0) total
+= ret2
;
2048 /* if we can't write then dump excess data */
2050 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
2052 if (ret
<= 0 || ret2
!= ret
)
2060 /****************************************************************************
2061 read 4 bytes of a smb packet and return the smb length of the packet
2062 possibly store the result in the buffer
2063 ****************************************************************************/
2064 int read_smb_length(int fd
,char *inbuf
,int timeout
)
2068 int len
=0, msg_type
;
2079 ok
= (read_with_timeout(fd
,buffer
,4,4,timeout
) == 4);
2081 ok
= (read_data(fd
,buffer
,4) == 4);
2086 len
= smb_len(buffer
);
2087 msg_type
= CVAL(buffer
,0);
2089 if (msg_type
== 0x85)
2091 DEBUG(5,("Got keepalive packet\n"));
2096 DEBUG(10,("got smb length of %d\n",len
));
2103 /****************************************************************************
2104 read an smb from a fd and return it's length
2105 The timeout is in milli seconds
2106 ****************************************************************************/
2107 BOOL
receive_smb(int fd
,char *buffer
,int timeout
)
2113 bzero(buffer
,smb_size
+ 100);
2115 len
= read_smb_length(fd
,buffer
,timeout
);
2119 if (len
> BUFFER_SIZE
) {
2120 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2121 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2125 ret
= read_data(fd
,buffer
+4,len
);
2127 smb_read_error
= READ_ERROR
;
2135 /****************************************************************************
2137 ****************************************************************************/
2138 BOOL
send_smb(int fd
,char *buffer
)
2142 len
= smb_len(buffer
) + 4;
2144 while (nwritten
< len
)
2146 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2149 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
2161 /****************************************************************************
2162 find a pointer to a netbios name
2163 ****************************************************************************/
2164 char *name_ptr(char *buf
,int ofs
)
2166 unsigned char c
= *(unsigned char *)(buf
+ofs
);
2168 if ((c
& 0xC0) == 0xC0)
2172 memcpy(p
,buf
+ofs
,2);
2175 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
2182 /****************************************************************************
2183 extract a netbios name from a buf
2184 ****************************************************************************/
2185 int name_extract(char *buf
,int ofs
,char *name
)
2187 char *p
= name_ptr(buf
,ofs
);
2188 int d
= PTR_DIFF(p
,buf
+ofs
);
2190 if (d
< -50 || d
> 50) return(0);
2191 return(name_interpret(p
,name
));
2195 /****************************************************************************
2196 return the total storage length of a mangled name
2197 ****************************************************************************/
2198 int name_len(char *s
)
2201 unsigned char c
= *(unsigned char *)s
;
2202 if ((c
& 0xC0) == 0xC0)
2204 while (*s
) s
+= (*s
)+1;
2205 return(PTR_DIFF(s
,s0
)+1);
2208 /****************************************************************************
2209 send a single packet to a port on another machine
2210 ****************************************************************************/
2211 BOOL
send_one_packet(char *buf
,int len
,struct in_addr ip
,int port
,int type
)
2215 struct sockaddr_in sock_out
;
2220 /* create a socket to write to */
2221 out_fd
= socket(AF_INET
, type
, 0);
2224 DEBUG(0,("socket failed"));
2228 /* set the address and port */
2229 bzero((char *)&sock_out
,sizeof(sock_out
));
2230 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
2231 sock_out
.sin_port
= htons( port
);
2232 sock_out
.sin_family
= AF_INET
;
2235 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2236 len
,inet_ntoa(ip
),port
,type
==SOCK_DGRAM
?"DGRAM":"STREAM"));
2239 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2242 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2243 inet_ntoa(ip
),port
,errno
));
2249 /*******************************************************************
2250 sleep for a specified number of milliseconds
2251 ********************************************************************/
2255 struct timeval tval
,t1
,t2
;
2262 tval
.tv_sec
= (t
-tdiff
)/1000;
2263 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2267 sys_select(&fds
,&tval
);
2270 tdiff
= TvalDiff(&t1
,&t2
);
2274 /****************************************************************************
2275 check if a string is part of a list
2276 ****************************************************************************/
2277 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
2282 if (!list
) return(False
);
2284 while (next_token(&p
,tok
,LIST_SEP
))
2286 if (casesensitive
) {
2287 if (strcmp(tok
,s
) == 0)
2290 if (StrCaseCmp(tok
,s
) == 0)
2297 /* this is used to prevent lots of mallocs of size 1 */
2298 static char *null_string
= NULL
;
2300 /****************************************************************************
2301 set a string value, allocing the space for the string
2302 ****************************************************************************/
2303 BOOL
string_init(char **dest
,char *src
)
2314 null_string
= (char *)malloc(1);
2317 *dest
= null_string
;
2321 *dest
= (char *)malloc(l
+1);
2327 /****************************************************************************
2329 ****************************************************************************/
2330 void string_free(char **s
)
2332 if (!s
|| !(*s
)) return;
2333 if (*s
== null_string
)
2339 /****************************************************************************
2340 set a string value, allocing the space for the string, and deallocating any
2342 ****************************************************************************/
2343 BOOL
string_set(char **dest
,char *src
)
2347 return(string_init(dest
,src
));
2350 /****************************************************************************
2351 substitute a string for a pattern in another string. Make sure there is
2354 This routine looks for pattern in s and replaces it with
2355 insert. It may do multiple replacements.
2357 return True if a substitution was done.
2358 ****************************************************************************/
2359 BOOL
string_sub(char *s
,char *pattern
,char *insert
)
2365 if (!insert
|| !pattern
|| !s
) return(False
);
2368 lp
= strlen(pattern
);
2369 li
= strlen(insert
);
2371 if (!*pattern
) return(False
);
2373 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2376 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2377 memcpy(p
,insert
,li
);
2386 /*********************************************************
2387 * Recursive routine that is called by mask_match.
2388 * Does the actual matching.
2389 *********************************************************/
2390 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
2394 for( p
= regexp
; *p
&& *str
; ) {
2401 /* Look for a character matching
2402 the one after the '*' */
2405 return True
; /* Automatic match */
2407 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2409 if(do_match(str
,p
,case_sig
))
2423 if(toupper(*str
) != toupper(*p
))
2433 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2436 if (!*str
&& *p
== '?')
2438 while (*p
== '?') p
++;
2442 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2448 /*********************************************************
2449 * Routine to match a given string with a regexp - uses
2450 * simplified regexp that takes * and ? only. Case can be
2451 * significant or not.
2452 *********************************************************/
2453 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
2457 fstring ebase
,eext
,sbase
,sext
;
2461 /* Make local copies of str and regexp */
2462 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
2463 StrnCpy(p2
,str
,sizeof(pstring
)-1);
2465 if (!strchr(p2
,'.')) {
2470 if (!strchr(p1,'.')) {
2478 string_sub(p1
,"*.*","*");
2479 string_sub(p1
,".*","*");
2483 /* Remove any *? and ** as they are meaningless */
2484 for(p
= p1
; *p
; p
++)
2485 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
2486 (void)strcpy( &p
[1], &p
[2]);
2488 if (strequal(p1
,"*")) return(True
);
2490 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
2496 if ((p
=strrchr(p1
,'.'))) {
2505 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
2515 matched
= do_match(sbase
,ebase
,case_sig
) &&
2516 (trans2
|| do_match(sext
,eext
,case_sig
));
2518 DEBUG(5,("mask_match returning %d\n", matched
));
2525 /****************************************************************************
2526 become a daemon, discarding the controlling terminal
2527 ****************************************************************************/
2528 void become_daemon(void)
2530 #ifndef NO_FORK_DEBUG
2534 /* detach from the terminal */
2537 #else /* USE_SETSID */
2540 int i
= open("/dev/tty", O_RDWR
);
2543 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
2547 #endif /* TIOCNOTTY */
2548 #endif /* USE_SETSID */
2549 /* Close fd's 0,1,2. Needed if started by rsh */
2551 #endif /* NO_FORK_DEBUG */
2555 /****************************************************************************
2556 put up a yes/no prompt
2557 ****************************************************************************/
2563 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
2566 if (*ans
== 'y' || *ans
== 'Y')
2572 /****************************************************************************
2573 read a line from a file with possible \ continuation chars.
2574 Blanks at the start or end of a line are stripped.
2575 The string will be allocated if s2 is NULL
2576 ****************************************************************************/
2577 char *fgets_slash(char *s2
,int maxlen
,FILE *f
)
2582 BOOL start_of_line
= True
;
2589 maxlen
= MIN(maxlen
,8);
2590 s
= (char *)Realloc(s
,maxlen
);
2593 if (!s
|| maxlen
< 2) return(NULL
);
2597 while (len
< maxlen
-1)
2605 while (len
> 0 && s
[len
-1] == ' ')
2609 if (len
> 0 && s
[len
-1] == '\\')
2612 start_of_line
= True
;
2617 if (len
<= 0 && !s2
)
2619 return(len
>0?s
:NULL
);
2624 start_of_line
= False
;
2628 if (!s2
&& len
> maxlen
-3)
2631 s
= (char *)Realloc(s
,maxlen
);
2632 if (!s
) return(NULL
);
2640 /****************************************************************************
2641 set the length of a file from a filedescriptor.
2642 Returns 0 on success, -1 on failure.
2643 ****************************************************************************/
2644 int set_filelen(int fd
, long len
)
2646 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2647 extend a file with ftruncate. Provide alternate implementation
2650 #if FTRUNCATE_CAN_EXTEND
2651 return ftruncate(fd
, len
);
2655 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
2659 /* Do an fstat to see if the file is longer than
2660 the requested size (call ftruncate),
2661 or shorter, in which case seek to len - 1 and write 1
2663 if(fstat(fd
, &st
)<0)
2667 if (S_ISFIFO(st
.st_mode
)) return 0;
2670 if(st
.st_size
== len
)
2672 if(st
.st_size
> len
)
2673 return ftruncate(fd
, len
);
2675 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
2677 if(write(fd
, &c
, 1)!=1)
2679 /* Seek to where we were */
2680 lseek(fd
, currpos
, SEEK_SET
);
2686 /****************************************************************************
2687 return the byte checksum of some data
2688 ****************************************************************************/
2689 int byte_checksum(char *buf
,int len
)
2691 unsigned char *p
= (unsigned char *)buf
;
2701 /****************************************************************************
2702 this is a version of setbuffer() for those machines that only have setvbuf
2703 ****************************************************************************/
2704 void setbuffer(FILE *f
,char *buf
,int bufsize
)
2706 setvbuf(f
,buf
,_IOFBF
,bufsize
);
2711 /****************************************************************************
2712 parse out a directory name from a path name. Assumes dos style filenames.
2713 ****************************************************************************/
2714 char *dirname_dos(char *path
,char *buf
)
2716 char *p
= strrchr(path
,'\\');
2731 /****************************************************************************
2732 parse out a filename from a path name. Assumes dos style filenames.
2733 ****************************************************************************/
2734 static char *filename_dos(char *path
,char *buf
)
2736 char *p
= strrchr(path
,'\\');
2748 /****************************************************************************
2749 expand a pointer to be a particular size
2750 ****************************************************************************/
2751 void *Realloc(void *p
,int size
)
2757 DEBUG(5,("Realloc asked for 0 bytes\n"));
2762 ret
= (void *)malloc(size
);
2764 ret
= (void *)realloc(p
,size
);
2767 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
2773 /****************************************************************************
2775 ****************************************************************************/
2776 char *strdup(char *s
)
2779 if (!s
) return(NULL
);
2780 ret
= (char *)malloc(strlen(s
)+1);
2781 if (!ret
) return(NULL
);
2788 /****************************************************************************
2789 Signal handler for SIGPIPE (write on a disconnected socket)
2790 ****************************************************************************/
2793 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2797 /****************************************************************************
2798 get my own name and IP
2799 ****************************************************************************/
2800 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
2807 /* get my host name */
2808 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
2810 DEBUG(0,("gethostname failed\n"));
2815 if ((hp
= Get_Hostbyname(hostname
)) == 0)
2817 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
2823 /* split off any parts after an initial . */
2824 char *p
= strchr(hostname
,'.');
2827 strcpy(my_name
,hostname
);
2831 putip((char *)ip
,(char *)hp
->h_addr
);
2837 /****************************************************************************
2838 true if two IP addresses are equal
2839 ****************************************************************************/
2840 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
2843 a1
= ntohl(ip1
.s_addr
);
2844 a2
= ntohl(ip2
.s_addr
);
2849 /****************************************************************************
2850 open a socket of the specified type, port and address for incoming data
2851 ****************************************************************************/
2852 int open_socket_in(int type
, int port
, int dlevel
,uint32 socket_addr
)
2855 struct sockaddr_in sock
;
2859 /* get my host name */
2860 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
2861 { DEBUG(0,("gethostname failed\n")); return -1; }
2864 if ((hp
= Get_Hostbyname(host_name
)) == 0)
2866 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
2870 bzero((char *)&sock
,sizeof(sock
));
2871 memcpy((char *)&sock
.sin_addr
,(char *)hp
->h_addr
, hp
->h_length
);
2872 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2873 sock
.sin_len
= sizeof(sock
);
2875 sock
.sin_port
= htons( port
);
2876 sock
.sin_family
= hp
->h_addrtype
;
2877 sock
.sin_addr
.s_addr
= socket_addr
;
2878 res
= socket(hp
->h_addrtype
, type
, 0);
2880 { DEBUG(0,("socket failed\n")); return -1; }
2884 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
2887 /* now we've got a socket - we need to bind it */
2888 if (bind(res
, (struct sockaddr
* ) &sock
,sizeof(sock
)) < 0)
2891 if (port
== SMB_PORT
|| port
== NMB_PORT
)
2892 DEBUG(dlevel
,("bind failed on port %d socket_addr=%x (%s)\n",
2893 port
,socket_addr
,strerror(errno
)));
2896 if (dlevel
> 0 && port
< 1000)
2899 if (port
>= 1000 && port
< 9000)
2900 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
2905 DEBUG(3,("bind succeeded on port %d\n",port
));
2911 /****************************************************************************
2912 create an outgoing socket
2913 **************************************************************************/
2914 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
2916 struct sockaddr_in sock_out
;
2918 int connect_loop
= 250; /* 250 milliseconds */
2919 int loops
= (timeout
* 1000) / connect_loop
;
2921 /* create a socket to write to */
2922 res
= socket(PF_INET
, type
, 0);
2924 { DEBUG(0,("socket error\n")); return -1; }
2926 if (type
!= SOCK_STREAM
) return(res
);
2928 bzero((char *)&sock_out
,sizeof(sock_out
));
2929 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
2931 sock_out
.sin_port
= htons( port
);
2932 sock_out
.sin_family
= PF_INET
;
2934 /* set it non-blocking */
2935 set_blocking(res
,False
);
2937 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
2939 /* and connect it to the destination */
2941 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
2943 /* Some systems return EAGAIN when they mean EINPROGRESS */
2944 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2945 errno
== EAGAIN
) && loops
--) {
2946 msleep(connect_loop
);
2950 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2952 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
2958 if (ret
< 0 && errno
== EISCONN
) {
2965 DEBUG(1,("error connecting to %s:%d (%s)\n",
2966 inet_ntoa(*addr
),port
,strerror(errno
)));
2970 /* set it blocking again */
2971 set_blocking(res
,True
);
2977 /****************************************************************************
2978 interpret a protocol description string, with a default
2979 ****************************************************************************/
2980 int interpret_protocol(char *str
,int def
)
2982 if (strequal(str
,"NT1"))
2983 return(PROTOCOL_NT1
);
2984 if (strequal(str
,"LANMAN2"))
2985 return(PROTOCOL_LANMAN2
);
2986 if (strequal(str
,"LANMAN1"))
2987 return(PROTOCOL_LANMAN1
);
2988 if (strequal(str
,"CORE"))
2989 return(PROTOCOL_CORE
);
2990 if (strequal(str
,"COREPLUS"))
2991 return(PROTOCOL_COREPLUS
);
2992 if (strequal(str
,"CORE+"))
2993 return(PROTOCOL_COREPLUS
);
2995 DEBUG(0,("Unrecognised protocol level %s\n",str
));
3000 /****************************************************************************
3001 interpret a security level
3002 ****************************************************************************/
3003 int interpret_security(char *str
,int def
)
3005 if (strequal(str
,"SERVER"))
3007 if (strequal(str
,"USER"))
3009 if (strequal(str
,"SHARE"))
3012 DEBUG(0,("Unrecognised security level %s\n",str
));
3018 /****************************************************************************
3019 interpret an internet address or name into an IP address in 4 byte form
3020 ****************************************************************************/
3021 uint32
interpret_addr(char *str
)
3026 BOOL pure_address
= True
;
3028 if (strcmp(str
,"0.0.0.0") == 0) return(0);
3029 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
3031 for (i
=0; pure_address
&& str
[i
]; i
++)
3032 if (!(isdigit(str
[i
]) || str
[i
] == '.'))
3033 pure_address
= False
;
3035 /* if it's in the form of an IP address then get the lib to interpret it */
3037 res
= inet_addr(str
);
3039 /* otherwise assume it's a network name of some sort and use
3041 if ((hp
= Get_Hostbyname(str
)) == 0) {
3042 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
3045 putip((char *)&res
,(char *)hp
->h_addr
);
3048 if (res
== (uint32
)-1) return(0);
3053 /*******************************************************************
3054 a convenient addition to interpret_addr()
3055 ******************************************************************/
3056 struct in_addr
*interpret_addr2(char *str
)
3058 static struct in_addr ret
;
3059 uint32 a
= interpret_addr(str
);
3064 /*******************************************************************
3065 check if an IP is the 0.0.0.0
3066 ******************************************************************/
3067 BOOL
zero_ip(struct in_addr ip
)
3070 putip((char *)&a
,(char *)&ip
);
3075 /*******************************************************************
3076 matchname - determine if host name matches IP address
3077 ******************************************************************/
3078 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
3083 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
3084 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost
));
3089 * Make sure that gethostbyname() returns the "correct" host name.
3090 * Unfortunately, gethostbyname("localhost") sometimes yields
3091 * "localhost.domain". Since the latter host name comes from the
3092 * local DNS, we just have to trust it (all bets are off if the local
3093 * DNS is perverted). We always check the address list, though.
3096 if (strcasecmp(remotehost
, hp
->h_name
)
3097 && strcasecmp(remotehost
, "localhost")) {
3098 DEBUG(0,("host name/name mismatch: %s != %s",
3099 remotehost
, hp
->h_name
));
3103 /* Look up the host address in the address list we just got. */
3104 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
3105 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
3110 * The host name does not map to the original host address. Perhaps
3111 * someone has compromised a name server. More likely someone botched
3112 * it, but that could be dangerous, too.
3115 DEBUG(0,("host name/address mismatch: %s != %s",
3116 inet_ntoa(addr
), hp
->h_name
));
3120 /*******************************************************************
3121 Reset the 'done' variables so after a client process is created
3122 from a fork call these calls will be re-done. This should be
3123 expanded if more variables need reseting.
3124 ******************************************************************/
3126 static BOOL global_client_name_done
= False
;
3127 static BOOL global_client_addr_done
= False
;
3129 void reset_globals_after_fork()
3131 global_client_name_done
= False
;
3132 global_client_addr_done
= False
;
3135 /*******************************************************************
3136 return the DNS name of the client
3137 ******************************************************************/
3138 char *client_name(void)
3142 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3143 int length
= sizeof(sa
);
3144 static pstring name_buf
;
3147 if (global_client_name_done
)
3150 strcpy(name_buf
,"UNKNOWN");
3152 if (getpeername(Client
, &sa
, &length
) < 0) {
3153 DEBUG(0,("getpeername failed\n"));
3157 /* Look up the remote host name. */
3158 if ((hp
= gethostbyaddr((char *) &sockin
->sin_addr
,
3159 sizeof(sockin
->sin_addr
),
3161 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3162 StrnCpy(name_buf
,client_addr(),sizeof(name_buf
) - 1);
3164 StrnCpy(name_buf
,(char *)hp
->h_name
,sizeof(name_buf
) - 1);
3165 if (!matchname(name_buf
, sockin
->sin_addr
)) {
3166 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,client_addr()));
3167 strcpy(name_buf
,"UNKNOWN");
3170 global_client_name_done
= True
;
3174 /*******************************************************************
3175 return the IP addr of the client as a string
3176 ******************************************************************/
3177 char *client_addr(void)
3181 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3182 int length
= sizeof(sa
);
3183 static fstring addr_buf
;
3185 if (global_client_addr_done
)
3188 strcpy(addr_buf
,"0.0.0.0");
3190 if (getpeername(Client
, &sa
, &length
) < 0) {
3191 DEBUG(0,("getpeername failed\n"));
3195 strcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
3197 global_client_addr_done
= True
;
3201 /*******************************************************************
3202 sub strings with useful parameters
3203 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3204 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3205 ********************************************************************/
3206 void standard_sub_basic(char *string
)
3210 struct passwd
*pass
;
3212 for (s
= string
; (p
= strchr(s
,'%')) != NULL
; s
= p
)
3216 case 'G' : if ((pass
= Get_Pwnam(sesssetup_user
,False
))!=NULL
)
3217 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
3221 case 'I' : string_sub(p
,"%I",client_addr()); break;
3222 case 'L' : string_sub(p
,"%L",local_machine
); break;
3223 case 'M' : string_sub(p
,"%M",client_name()); break;
3224 case 'R' : string_sub(p
,"%R",remote_proto
); break;
3225 case 'T' : string_sub(p
,"%T",timestring()); break;
3226 case 'U' : string_sub(p
,"%U",sesssetup_user
); break;
3227 case 'a' : string_sub(p
,"%a",remote_arch
); break;
3228 case 'd' : sprintf(pidstr
,"%d",(int)getpid());
3229 string_sub(p
,"%d",pidstr
);
3231 case 'h' : string_sub(p
,"%h",myhostname
); break;
3232 case 'm' : string_sub(p
,"%m",remote_machine
); break;
3233 case 'v' : string_sub(p
,"%v",VERSION
); break;
3234 case '\0' : p
++; break; /* don't run off end if last character is % */
3235 default : p
+=2; break;
3241 /*******************************************************************
3242 are two IPs on the same subnet?
3243 ********************************************************************/
3244 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
3246 uint32 net1
,net2
,nmask
;
3248 nmask
= ntohl(mask
.s_addr
);
3249 net1
= ntohl(ip1
.s_addr
);
3250 net2
= ntohl(ip2
.s_addr
);
3252 return((net1
& nmask
) == (net2
& nmask
));
3256 /*******************************************************************
3257 write a string in unicoode format
3258 ********************************************************************/
3259 int PutUniCode(char *dst
,char *src
)
3263 dst
[ret
++] = src
[0];
3272 /****************************************************************************
3273 a wrapper for gethostbyname() that tries with all lower and all upper case
3274 if the initial name fails
3275 ****************************************************************************/
3276 struct hostent
*Get_Hostbyname(char *name
)
3278 char *name2
= strdup(name
);
3279 struct hostent
*ret
;
3283 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3287 if (!isalnum(*name2
))
3293 ret
= sys_gethostbyname(name2
);
3300 /* try with all lowercase */
3302 ret
= sys_gethostbyname(name2
);
3309 /* try with all uppercase */
3311 ret
= sys_gethostbyname(name2
);
3318 /* nothing works :-( */
3324 /****************************************************************************
3325 check if a process exists. Does this work on all unixes?
3326 ****************************************************************************/
3327 BOOL
process_exists(int pid
)
3331 sprintf(s
,"/proc/%d",pid
);
3332 return(directory_exist(s
,NULL
));
3335 static BOOL tested
=False
;
3336 static BOOL ok
=False
;
3340 sprintf(s
,"/proc/%05d",(int)getpid());
3341 ok
= file_exist(s
,NULL
);
3344 sprintf(s
,"/proc/%05d",pid
);
3345 return(file_exist(s
,NULL
));
3349 /* CGH 8/16/96 - added ESRCH test */
3350 return(pid
== getpid() || kill(pid
,0) == 0 || errno
!= ESRCH
);
3355 /*******************************************************************
3356 turn a uid into a user name
3357 ********************************************************************/
3358 char *uidtoname(int uid
)
3360 static char name
[40];
3361 struct passwd
*pass
= getpwuid(uid
);
3362 if (pass
) return(pass
->pw_name
);
3363 sprintf(name
,"%d",uid
);
3367 /*******************************************************************
3368 turn a gid into a group name
3369 ********************************************************************/
3370 char *gidtoname(int gid
)
3372 static char name
[40];
3373 struct group
*grp
= getgrgid(gid
);
3374 if (grp
) return(grp
->gr_name
);
3375 sprintf(name
,"%d",gid
);
3379 /*******************************************************************
3381 ********************************************************************/
3382 void BlockSignals(BOOL block
,int signum
)
3385 int block_mask
= sigmask(signum
);
3386 static int oldmask
= 0;
3388 oldmask
= sigblock(block_mask
);
3390 sigsetmask(oldmask
);
3391 #elif defined(USE_SIGPROCMASK)
3394 sigaddset(&set
,signum
);
3395 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
3400 /*******************************************************************
3401 my own panic function - not suitable for general use
3402 ********************************************************************/
3403 void ajt_panic(void)
3405 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3410 #define DIRECT direct
3412 #define DIRECT dirent
3415 /*******************************************************************
3416 a readdir wrapper which just returns the file name
3417 also return the inode number if requested
3418 ********************************************************************/
3419 char *readdirname(void *p
)
3424 if (!p
) return(NULL
);
3426 ptr
= (struct DIRECT
*)readdir(p
);
3427 if (!ptr
) return(NULL
);
3429 dname
= ptr
->d_name
;
3432 if (telldir(p
) < 0) return(NULL
);
3436 /* this handles a broken compiler setup, causing a mixture
3437 of BSD and SYSV headers and libraries */
3439 static BOOL broken_readdir
= False
;
3440 if (!broken_readdir
&& !(*(dname
)) && strequal("..",dname
-2))
3442 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3443 broken_readdir
= True
;
3453 unix_to_dos(buf
, True
);
3461 * Utility function used to decide if the last component
3462 * of a path matches a (possibly wildcarded) entry in a namelist.
3465 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
3467 pstring last_component
;
3470 DEBUG(5, ("is_in_path: %s\n", name
));
3472 /* if we have no list it's obviously not in the path */
3473 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
3475 DEBUG(5,("is_in_path: no name list.\n"));
3479 /* Get the last component of the unix name. */
3480 p
= strrchr(name
, '/');
3481 strncpy(last_component
, p
? p
: name
, sizeof(last_component
)-1);
3482 last_component
[sizeof(last_component
)-1] = '\0';
3484 for(; namelist
->name
!= NULL
; namelist
++)
3486 if(namelist
->is_wild
)
3488 /* look for a wildcard match. */
3489 if (mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
3491 DEBUG(5,("is_in_path: mask match succeeded\n"));
3497 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
3498 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
3500 DEBUG(5,("is_in_path: match succeeded\n"));
3505 DEBUG(5,("is_in_path: match not found\n"));
3511 * Strip a '/' separated list into an array of
3512 * name_compare_enties structures suitable for
3513 * passing to is_in_path(). We do this for
3514 * speed so we can pre-parse all the names in the list
3515 * and don't do it for each call to is_in_path().
3516 * namelist is modified here and is assumed to be
3517 * a copy owned by the caller.
3518 * We also check if the entry contains a wildcard to
3519 * remove a potentially expensive call to mask_match
3523 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
3526 char *nameptr
= namelist
;
3527 int num_entries
= 0;
3530 (*ppname_array
) = NULL
;
3532 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
3535 /* We need to make two passes over the string. The
3536 first to count the number of elements, the second
3541 if ( *nameptr
== '/' )
3543 /* cope with multiple (useless) /s) */
3547 /* find the next / */
3548 name_end
= strchr(nameptr
, '/');
3550 /* oops - the last check for a / didn't find one. */
3551 if (name_end
== NULL
)
3554 /* next segment please */
3555 nameptr
= name_end
+ 1;
3559 if(num_entries
== 0)
3562 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
3563 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
3565 DEBUG(0,("set_namearray: malloc fail\n"));
3569 /* Now copy out the names */
3574 if ( *nameptr
== '/' )
3576 /* cope with multiple (useless) /s) */
3580 /* find the next / */
3581 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
3586 /* oops - the last check for a / didn't find one. */
3587 if (name_end
== NULL
)
3590 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
3591 (strchr( nameptr
, '*')!=NULL
));
3592 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
3594 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3598 /* next segment please */
3599 nameptr
= name_end
+ 1;
3603 (*ppname_array
)[i
].name
= NULL
;
3608 /****************************************************************************
3609 routine to free a namearray.
3610 ****************************************************************************/
3612 void free_namearray(name_compare_entry
*name_array
)
3617 if(name_array
->name
!= NULL
)
3618 free(name_array
->name
);
3620 free((char *)name_array
);
3623 /****************************************************************************
3624 routine to do file locking
3625 ****************************************************************************/
3626 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
3633 uint32 mask
= 0xC0000000;
3635 /* make sure the count is reasonable, we might kill the lockd otherwise */
3638 /* the offset is often strange - remove 2 of its bits if either of
3639 the top two bits are set. Shift the top ones by two bits. This
3640 still allows OLE2 apps to operate, but should stop lockd from
3642 if ((offset
& mask
) != 0)
3643 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
3645 uint32 mask
= ((unsigned)1<<31);
3647 /* interpret negative counts as large numbers */
3651 /* no negative offsets */
3654 /* count + offset must be in range */
3655 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
3663 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
3666 lock
.l_whence
= SEEK_SET
;
3667 lock
.l_start
= (int)offset
;
3668 lock
.l_len
= (int)count
;
3673 ret
= fcntl(fd
,op
,&lock
);
3676 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
3682 (lock
.l_type
!= F_UNLCK
) &&
3683 (lock
.l_pid
!= 0) &&
3684 (lock
.l_pid
!= getpid()))
3686 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
3690 /* it must be not locked or locked by me */
3694 /* a lock set or unset */
3697 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3698 offset
,count
,op
,type
,strerror(errno
)));
3700 /* perhaps it doesn't support this sort of locking?? */
3701 if (errno
== EINVAL
)
3703 DEBUG(3,("locking not supported? returning True\n"));
3710 /* everything went OK */
3711 DEBUG(5,("Lock call successful\n"));
3719 /*******************************************************************
3720 lock a file - returning a open file descriptor or -1 on failure
3721 The timeout is in seconds. 0 means no timeout
3722 ********************************************************************/
3723 int file_lock(char *name
,int timeout
)
3725 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
3727 if (fd
< 0) return(-1);
3730 if (timeout
) t
= time(NULL
);
3731 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
3732 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
3733 msleep(LOCK_RETRY_TIMEOUT
);
3741 /*******************************************************************
3742 unlock a file locked by file_lock
3743 ********************************************************************/
3744 void file_unlock(int fd
)
3748 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
3753 /*******************************************************************
3754 is the name specified one of my netbios names
3755 returns true is it is equal, false otherwise
3756 ********************************************************************/
3757 BOOL
is_myname(const char *s
)
3762 for (n
=0; my_netbios_names
[n
]; n
++) {
3763 if (strequal(my_netbios_names
[n
], s
))
3766 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));