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 static enum remote_arch_types ra_type = RA_UNKNOWN;
72 fstring remote_proto="UNKNOWN";
73 pstring myhostname="";
74 pstring user_socket_options="";
75 pstring sesssetup_user="";
77 fstring myworkgroup = "";
78 char **my_netbios_names;
80 int smb_read_error = 0;
82 static BOOL stdout_logging = False;
84 static char *filename_dos(char *path,char *buf);
86 /*******************************************************************
87 get ready for syslog stuff
88 ******************************************************************/
89 void setup_logging(char *pname,BOOL interactive)
93 char *p = strrchr(pname,'/');
96 openlog(pname, LOG_PID, LOG_DAEMON);
97 #else /* LOG_DAEMON - for old systems that have no facility codes. */
98 openlog(pname, LOG_PID);
99 #endif /* LOG_DAEMON */
103 stdout_logging = True;
109 BOOL append_log=False;
112 /****************************************************************************
114 ****************************************************************************/
115 void reopen_logs(void)
122 strcpy(fname,debugf);
123 if (lp_loaded() && (*lp_logfile()))
124 strcpy(fname,lp_logfile());
126 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
128 int oldumask = umask(022);
129 strcpy(debugf,fname);
130 if (dbf) fclose(dbf);
132 dbf = fopen(debugf,"a");
134 dbf = fopen(debugf,"w");
135 if (dbf) setbuf(dbf,NULL);
150 /*******************************************************************
151 check if the log has grown too big
152 ********************************************************************/
153 static void check_log_size(void)
155 static int debug_count=0;
159 if (debug_count++ < 100) return;
161 maxlog = lp_max_log_size() * 1024;
162 if (!dbf || maxlog <= 0) return;
164 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
165 fclose(dbf); dbf = NULL;
167 if (dbf && file_size(debugf) > maxlog) {
169 fclose(dbf); dbf = NULL;
170 sprintf(name,"%s.old",debugf);
171 sys_rename(debugf,name);
179 /*******************************************************************
180 write an debug message on the debugfile. This is called by the DEBUG
182 ********************************************************************/
184 int Debug1(char *format_str, ...)
194 if (stdout_logging) {
196 va_start(ap, format_str);
199 format_str = va_arg(ap,char *);
201 vfprintf(dbf,format_str,ap);
207 if (!lp_syslog_only())
212 int oldumask = umask(022);
213 dbf = fopen(debugf,"w");
223 if (syslog_level < lp_syslog())
226 * map debug levels to syslog() priorities
227 * note that not all DEBUG(0, ...) calls are
230 static int priority_map[] = {
239 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
241 priority = LOG_DEBUG;
243 priority = priority_map[syslog_level];
246 va_start(ap, format_str);
249 format_str = va_arg(ap,char *);
251 vsprintf(msgbuf, format_str, ap);
255 syslog(priority, "%s", msgbuf);
260 if (!lp_syslog_only())
264 va_start(ap, format_str);
267 format_str = va_arg(ap,char *);
269 vfprintf(dbf,format_str,ap);
279 /****************************************************************************
280 find a suitable temporary directory. The result should be copied immediately
281 as it may be overwritten by a subsequent call
282 ****************************************************************************/
286 if ((p = getenv("TMPDIR"))) {
294 /****************************************************************************
295 determine if a file descriptor is in fact a socket
296 ****************************************************************************/
297 BOOL is_a_socket(int fd)
301 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
305 static char *last_ptr=NULL;
307 /****************************************************************************
308 Get the next token from a string, return False if none found
309 handles double-quotes.
310 Based on a routine by GJC@VILLAGE.COM.
311 Extensively modified by Andrew.Tridgell@anu.edu.au
312 ****************************************************************************/
313 BOOL next_token(char **ptr,char *buff,char *sep)
318 if (!ptr) ptr = &last_ptr;
319 if (!ptr) return(False);
323 /* default to simple separators */
324 if (!sep) sep = " \t\n\r";
326 /* find the first non sep char */
327 while(*s && strchr(sep,*s)) s++;
330 if (! *s) return(False);
332 /* copy over the token */
333 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
341 *ptr = (*s) ? s+1 : s;
348 /****************************************************************************
349 Convert list of tokens to array; dependent on above routine.
350 Uses last_ptr from above - bit of a hack.
351 ****************************************************************************/
352 char **toktocliplist(int *ctok, char *sep)
358 if (!sep) sep = " \t\n\r";
360 while(*s && strchr(sep,*s)) s++;
363 if (!*s) return(NULL);
367 while(*s && (!strchr(sep,*s))) s++;
368 while(*s && strchr(sep,*s)) *s++=0;
374 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
386 /*******************************************************************
387 safely copies memory, ensuring no overlap problems.
388 this is only used if the machine does not have it's own memmove().
389 this is not the fastest algorithm in town, but it will do for our
391 ********************************************************************/
392 void *MemMove(void *dest,void *src,int size)
396 if (dest==src || !size) return(dest);
398 d = (unsigned long)dest;
399 s = (unsigned long)src;
401 if ((d >= (s+size)) || (s >= (d+size))) {
403 memcpy(dest,src,size);
409 /* we can forward copy */
410 if (s-d >= sizeof(int) &&
411 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
412 /* do it all as words */
413 int *idest = (int *)dest;
414 int *isrc = (int *)src;
416 for (i=0;i<size;i++) idest[i] = isrc[i];
419 char *cdest = (char *)dest;
420 char *csrc = (char *)src;
421 for (i=0;i<size;i++) cdest[i] = csrc[i];
426 /* must backward copy */
427 if (d-s >= sizeof(int) &&
428 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
429 /* do it all as words */
430 int *idest = (int *)dest;
431 int *isrc = (int *)src;
433 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
436 char *cdest = (char *)dest;
437 char *csrc = (char *)src;
438 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
446 /****************************************************************************
447 prompte a dptr (to make it recently used)
448 ****************************************************************************/
449 void array_promote(char *array,int elsize,int element)
455 p = (char *)malloc(elsize);
459 DEBUG(5,("Ahh! Can't malloc\n"));
462 memcpy(p,array + element * elsize, elsize);
463 memmove(array + elsize,array,elsize*element);
464 memcpy(array,p,elsize);
468 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
477 } socket_options[] = {
478 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
479 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
480 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
482 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
484 #ifdef IPTOS_LOWDELAY
485 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
487 #ifdef IPTOS_THROUGHPUT
488 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
491 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
494 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
497 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
500 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
503 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
506 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
512 /****************************************************************************
513 set user socket options
514 ****************************************************************************/
515 void set_socket_options(int fd, char *options)
519 while (next_token(&options,tok," \t,"))
524 BOOL got_value = False;
526 if ((p = strchr(tok,'=')))
533 for (i=0;socket_options[i].name;i++)
534 if (strequal(socket_options[i].name,tok))
537 if (!socket_options[i].name)
539 DEBUG(0,("Unknown socket option %s\n",tok));
543 switch (socket_options[i].opttype)
547 ret = setsockopt(fd,socket_options[i].level,
548 socket_options[i].option,(char *)&value,sizeof(int));
553 DEBUG(0,("syntax error - %s does not take a value\n",tok));
556 int on = socket_options[i].value;
557 ret = setsockopt(fd,socket_options[i].level,
558 socket_options[i].option,(char *)&on,sizeof(int));
564 DEBUG(0,("Failed to set socket option %s\n",tok));
570 /****************************************************************************
571 close the socket communication
572 ****************************************************************************/
573 void close_sockets(void )
579 /****************************************************************************
580 determine whether we are in the specified group
581 ****************************************************************************/
582 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
586 if (group == current_gid) return(True);
588 for (i=0;i<ngroups;i++)
589 if (group == groups[i])
595 /****************************************************************************
596 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
597 ****************************************************************************/
598 char *StrCpy(char *dest,char *src)
603 /* I don't want to get lazy with these ... */
605 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
610 if (!dest) return(NULL);
615 while ((*d++ = *src++)) ;
619 /****************************************************************************
620 line strncpy but always null terminates. Make sure there is room!
621 ****************************************************************************/
622 char *StrnCpy(char *dest,char *src,int n)
625 if (!dest) return(NULL);
630 while (n-- && (*d++ = *src++)) ;
636 /*******************************************************************
637 copy an IP address from one buffer to another
638 ********************************************************************/
639 void putip(void *dest,void *src)
645 /****************************************************************************
646 interpret the weird netbios "name". Return the name type
647 ****************************************************************************/
648 static int name_interpret(char *in,char *out)
651 int len = (*in++) / 2;
655 if (len > 30 || len<1) return(0);
659 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
663 *out = ((in[0]-'A')<<4) + (in[1]-'A');
671 /* Handle any scope names */
674 *out++ = '.'; /* Scope names are separated by periods */
675 len = *(unsigned char *)in++;
676 StrnCpy(out, in, len);
685 /****************************************************************************
686 mangle a name into netbios format
687 ****************************************************************************/
688 int name_mangle(char *In,char *Out,char name_type)
692 char *in = (char *)&buf[0];
693 char *out = (char *)Out;
698 StrnCpy(name,In,sizeof(name)-1);
699 sprintf(buf,"%-15.15s%c",name,name_type);
702 memset(&buf[1],0,16);
707 char c = toupper(in[i]);
708 out[i*2] = (c>>4) + 'A';
709 out[i*2+1] = (c & 0xF) + 'A';
717 p = strchr(label, '.');
719 p = label + strlen(label);
721 memcpy(out, label, p - label);
723 label += p - label + (*p == '.');
726 return(name_len(Out));
730 /*******************************************************************
731 check if a file exists
732 ********************************************************************/
733 BOOL file_exist(char *fname,struct stat *sbuf)
736 if (!sbuf) sbuf = &st;
738 if (sys_stat(fname,sbuf) != 0)
741 return(S_ISREG(sbuf->st_mode));
744 /*******************************************************************
745 check a files mod time
746 ********************************************************************/
747 time_t file_modtime(char *fname)
751 if (sys_stat(fname,&st) != 0)
757 /*******************************************************************
758 check if a directory exists
759 ********************************************************************/
760 BOOL directory_exist(char *dname,struct stat *st)
767 if (sys_stat(dname,st) != 0)
770 ret = S_ISDIR(st->st_mode);
776 /*******************************************************************
777 returns the size in bytes of the named file
778 ********************************************************************/
779 uint32 file_size(char *file_name)
783 sys_stat(file_name,&buf);
787 /*******************************************************************
788 return a string representing an attribute for a file
789 ********************************************************************/
790 char *attrib_string(int mode)
792 static char attrstr[10];
796 if (mode & aVOLID) strcat(attrstr,"V");
797 if (mode & aDIR) strcat(attrstr,"D");
798 if (mode & aARCH) strcat(attrstr,"A");
799 if (mode & aHIDDEN) strcat(attrstr,"H");
800 if (mode & aSYSTEM) strcat(attrstr,"S");
801 if (mode & aRONLY) strcat(attrstr,"R");
807 /*******************************************************************
808 case insensitive string compararison
809 ********************************************************************/
810 int StrCaseCmp(char *s, char *t)
812 /* compare until we run out of string, either t or s, or find a difference */
813 /* We *must* use toupper rather than tolower here due to the
814 asynchronous upper to lower mapping.
816 #if !defined(KANJI_WIN95_COMPATIBILITY)
817 if(lp_client_code_page() == KANJI_CODEPAGE)
819 /* Win95 treats full width ascii characters as case sensitive. */
824 return toupper (*s) - toupper (*t);
825 else if (is_sj_alph (*s) && is_sj_alph (*t))
827 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
833 else if (is_shift_jis (*s) && is_shift_jis (*t))
835 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
838 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
844 else if (is_shift_jis (*s))
846 else if (is_shift_jis (*t))
850 diff = toupper (*s) - toupper (*t);
859 #endif /* KANJI_WIN95_COMPATIBILITY */
861 while (*s && *t && toupper(*s) == toupper(*t))
867 return(toupper(*s) - toupper(*t));
871 /*******************************************************************
872 case insensitive string compararison, length limited
873 ********************************************************************/
874 int StrnCaseCmp(char *s, char *t, int n)
876 /* compare until we run out of string, either t or s, or chars */
877 /* We *must* use toupper rather than tolower here due to the
878 asynchronous upper to lower mapping.
880 #if !defined(KANJI_WIN95_COMPATIBILITY)
881 if(lp_client_code_page() == KANJI_CODEPAGE)
883 /* Win95 treats full width ascii characters as case sensitive. */
888 return toupper (*s) - toupper (*t);
889 else if (is_sj_alph (*s) && is_sj_alph (*t))
891 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
898 else if (is_shift_jis (*s) && is_shift_jis (*t))
900 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
903 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
910 else if (is_shift_jis (*s))
912 else if (is_shift_jis (*t))
916 diff = toupper (*s) - toupper (*t);
927 #endif /* KANJI_WIN95_COMPATIBILITY */
929 while (n-- && *s && *t && toupper(*s) == toupper(*t))
935 /* not run out of chars - strings are different lengths */
937 return(toupper(*s) - toupper(*t));
939 /* identical up to where we run out of chars,
940 and strings are same length */
945 /*******************************************************************
947 ********************************************************************/
948 BOOL strequal(char *s1, char *s2)
950 if (s1 == s2) return(True);
951 if (!s1 || !s2) return(False);
953 return(StrCaseCmp(s1,s2)==0);
956 /*******************************************************************
957 compare 2 strings up to and including the nth char.
958 ******************************************************************/
959 BOOL strnequal(char *s1,char *s2,int n)
961 if (s1 == s2) return(True);
962 if (!s1 || !s2 || !n) return(False);
964 return(StrnCaseCmp(s1,s2,n)==0);
967 /*******************************************************************
968 compare 2 strings (case sensitive)
969 ********************************************************************/
970 BOOL strcsequal(char *s1,char *s2)
972 if (s1 == s2) return(True);
973 if (!s1 || !s2) return(False);
975 return(strcmp(s1,s2)==0);
979 /*******************************************************************
980 convert a string to lower case
981 ********************************************************************/
982 void strlower(char *s)
986 #if !defined(KANJI_WIN95_COMPATIBILITY)
987 if(lp_client_code_page() == KANJI_CODEPAGE)
989 /* Win95 treats full width ascii characters as case sensitive. */
990 if (is_shift_jis (*s))
992 if (is_sj_upper (s[0], s[1]))
993 s[1] = sj_tolower2 (s[1]);
996 else if (is_kana (*s))
1008 #endif /* KANJI_WIN95_COMPATIBILITY */
1017 /*******************************************************************
1018 convert a string to upper case
1019 ********************************************************************/
1020 void strupper(char *s)
1024 #if !defined(KANJI_WIN95_COMPATIBILITY)
1025 if(lp_client_code_page() == KANJI_CODEPAGE)
1027 /* Win95 treats full width ascii characters as case sensitive. */
1028 if (is_shift_jis (*s))
1030 if (is_sj_lower (s[0], s[1]))
1031 s[1] = sj_toupper2 (s[1]);
1034 else if (is_kana (*s))
1046 #endif /* KANJI_WIN95_COMPATIBILITY */
1055 /*******************************************************************
1056 convert a string to "normal" form
1057 ********************************************************************/
1058 void strnorm(char *s)
1060 if (case_default == CASE_UPPER)
1066 /*******************************************************************
1067 check if a string is in "normal" case
1068 ********************************************************************/
1069 BOOL strisnormal(char *s)
1071 if (case_default == CASE_UPPER)
1072 return(!strhaslower(s));
1074 return(!strhasupper(s));
1078 /****************************************************************************
1080 ****************************************************************************/
1081 void string_replace(char *s,char oldc,char newc)
1085 #if !defined(KANJI_WIN95_COMPATIBILITY)
1086 if(lp_client_code_page() == KANJI_CODEPAGE)
1088 /* Win95 treats full width ascii characters as case sensitive. */
1089 if (is_shift_jis (*s))
1091 else if (is_kana (*s))
1101 #endif /* KANJI_WIN95_COMPATIBILITY */
1110 /****************************************************************************
1111 make a file into unix format
1112 ****************************************************************************/
1113 void unix_format(char *fname)
1116 string_replace(fname,'\\','/');
1120 pstrcpy(namecopy,fname);
1122 strcat(fname,namecopy);
1126 /****************************************************************************
1127 make a file into dos format
1128 ****************************************************************************/
1129 void dos_format(char *fname)
1131 string_replace(fname,'/','\\');
1135 /*******************************************************************
1136 show a smb message structure
1137 ********************************************************************/
1138 void show_msg(char *buf)
1146 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1148 (int)CVAL(buf,smb_com),
1149 (int)CVAL(buf,smb_rcls),
1150 (int)CVAL(buf,smb_reh),
1151 (int)SVAL(buf,smb_err),
1152 (int)CVAL(buf,smb_flg),
1153 (int)SVAL(buf,smb_flg2)));
1154 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1155 (int)SVAL(buf,smb_tid),
1156 (int)SVAL(buf,smb_pid),
1157 (int)SVAL(buf,smb_uid),
1158 (int)SVAL(buf,smb_mid),
1159 (int)CVAL(buf,smb_wct)));
1160 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1161 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1162 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1163 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1164 DEBUG(5,("smb_bcc=%d\n",bcc));
1165 if (DEBUGLEVEL < 10)
1167 for (i = 0; i < MIN(bcc, 256); i += 16)
1169 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1172 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1173 if (j == 7) DEBUG(10, (" "));
1178 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1180 unsigned char c = CVAL(smb_buf(buf),i+j);
1181 if (c < 32 || c > 128) c = '.';
1184 if (j == 7) DEBUG(10, (" "));
1191 /*******************************************************************
1192 return the length of an smb packet
1193 ********************************************************************/
1194 int smb_len(char *buf)
1196 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1199 /*******************************************************************
1200 set the length of an smb packet
1201 ********************************************************************/
1202 void _smb_setlen(char *buf,int len)
1205 buf[1] = (len&0x10000)>>16;
1206 buf[2] = (len&0xFF00)>>8;
1210 /*******************************************************************
1211 set the length and marker of an smb packet
1212 ********************************************************************/
1213 void smb_setlen(char *buf,int len)
1215 _smb_setlen(buf,len);
1223 /*******************************************************************
1224 setup the word count and byte count for a smb message
1225 ********************************************************************/
1226 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1229 bzero(buf + smb_size,num_words*2 + num_bytes);
1230 CVAL(buf,smb_wct) = num_words;
1231 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1232 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1233 return (smb_size + num_words*2 + num_bytes);
1236 /*******************************************************************
1237 return the number of smb words
1238 ********************************************************************/
1239 int smb_numwords(char *buf)
1241 return (CVAL(buf,smb_wct));
1244 /*******************************************************************
1245 return the size of the smb_buf region of a message
1246 ********************************************************************/
1247 int smb_buflen(char *buf)
1249 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1252 /*******************************************************************
1253 return a pointer to the smb_buf data area
1254 ********************************************************************/
1255 int smb_buf_ofs(char *buf)
1257 return (smb_size + CVAL(buf,smb_wct)*2);
1260 /*******************************************************************
1261 return a pointer to the smb_buf data area
1262 ********************************************************************/
1263 char *smb_buf(char *buf)
1265 return (buf + smb_buf_ofs(buf));
1268 /*******************************************************************
1269 return the SMB offset into an SMB buffer
1270 ********************************************************************/
1271 int smb_offset(char *p,char *buf)
1273 return(PTR_DIFF(p,buf+4) + chain_size);
1277 /*******************************************************************
1278 skip past some strings in a buffer
1279 ********************************************************************/
1280 char *skip_string(char *buf,int n)
1283 buf += strlen(buf) + 1;
1287 /*******************************************************************
1288 trim the specified elements off the front and back of a string
1289 ********************************************************************/
1290 BOOL trim_string(char *s,char *front,char *back)
1293 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1299 if (!(*p = p[strlen(front)]))
1304 while (back && *back && strlen(s) >= strlen(back) &&
1305 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1308 s[strlen(s)-strlen(back)] = 0;
1314 /*******************************************************************
1315 reduce a file name, removing .. elements.
1316 ********************************************************************/
1317 void dos_clean_name(char *s)
1321 DEBUG(3,("dos_clean_name [%s]\n",s));
1323 /* remove any double slashes */
1324 string_sub(s, "\\\\", "\\");
1326 while ((p = strstr(s,"\\..\\")) != NULL)
1333 if ((p=strrchr(s,'\\')) != NULL)
1340 trim_string(s,NULL,"\\..");
1342 string_sub(s, "\\.\\", "\\");
1345 /*******************************************************************
1346 reduce a file name, removing .. elements.
1347 ********************************************************************/
1348 void unix_clean_name(char *s)
1352 DEBUG(3,("unix_clean_name [%s]\n",s));
1354 /* remove any double slashes */
1355 string_sub(s, "//","/");
1357 /* Remove leading ./ characters */
1358 if(strncmp(s, "./", 2) == 0) {
1359 trim_string(s, "./", NULL);
1364 while ((p = strstr(s,"/../")) != NULL)
1371 if ((p=strrchr(s,'/')) != NULL)
1378 trim_string(s,NULL,"/..");
1382 /*******************************************************************
1383 a wrapper for the normal chdir() function
1384 ********************************************************************/
1385 int ChDir(char *path)
1388 static pstring LastDir="";
1390 if (strcsequal(path,".")) return(0);
1392 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1393 DEBUG(3,("chdir to %s\n",path));
1394 res = sys_chdir(path);
1396 pstrcpy(LastDir,path);
1400 /* number of list structures for a caching GetWd function. */
1401 #define MAX_GETWDCACHE (50)
1409 } ino_list[MAX_GETWDCACHE];
1411 BOOL use_getwd_cache=True;
1413 /*******************************************************************
1414 return the absolute current directory path
1415 ********************************************************************/
1416 char *GetWd(char *str)
1419 static BOOL getwd_cache_init = False;
1420 struct stat st, st2;
1425 if (!use_getwd_cache)
1426 return(sys_getwd(str));
1428 /* init the cache */
1429 if (!getwd_cache_init)
1431 getwd_cache_init = True;
1432 for (i=0;i<MAX_GETWDCACHE;i++)
1434 string_init(&ino_list[i].text,"");
1435 ino_list[i].valid = False;
1439 /* Get the inode of the current directory, if this doesn't work we're
1442 if (stat(".",&st) == -1)
1444 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1445 return(sys_getwd(str));
1449 for (i=0; i<MAX_GETWDCACHE; i++)
1450 if (ino_list[i].valid)
1453 /* If we have found an entry with a matching inode and dev number
1454 then find the inode number for the directory in the cached string.
1455 If this agrees with that returned by the stat for the current
1456 directory then all is o.k. (but make sure it is a directory all
1459 if (st.st_ino == ino_list[i].inode &&
1460 st.st_dev == ino_list[i].dev)
1462 if (stat(ino_list[i].text,&st2) == 0)
1464 if (st.st_ino == st2.st_ino &&
1465 st.st_dev == st2.st_dev &&
1466 (st2.st_mode & S_IFMT) == S_IFDIR)
1468 strcpy (str, ino_list[i].text);
1470 /* promote it for future use */
1471 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1476 /* If the inode is different then something's changed,
1477 scrub the entry and start from scratch. */
1478 ino_list[i].valid = False;
1485 /* We don't have the information to hand so rely on traditional methods.
1486 The very slow getcwd, which spawns a process on some systems, or the
1487 not quite so bad getwd. */
1491 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1497 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1499 /* add it to the cache */
1500 i = MAX_GETWDCACHE - 1;
1501 string_set(&ino_list[i].text,s);
1502 ino_list[i].dev = st.st_dev;
1503 ino_list[i].inode = st.st_ino;
1504 ino_list[i].valid = True;
1506 /* put it at the top of the list */
1507 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1514 /*******************************************************************
1515 reduce a file name, removing .. elements and checking that
1516 it is below dir in the heirachy. This uses GetWd() and so must be run
1517 on the system that has the referenced file system.
1519 widelinks are allowed if widelinks is true
1520 ********************************************************************/
1521 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1523 #ifndef REDUCE_PATHS
1531 BOOL relative = (*s != '/');
1533 *dir2 = *wd = *basename = *newname = 0;
1538 /* can't have a leading .. */
1539 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1541 DEBUG(3,("Illegal file name? (%s)\n",s));
1551 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1553 /* remove any double slashes */
1554 string_sub(s,"//","/");
1556 pstrcpy(basename,s);
1557 p = strrchr(basename,'/');
1564 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1568 if (ChDir(dir) != 0)
1570 DEBUG(0,("couldn't chdir to %s\n",dir));
1576 DEBUG(0,("couldn't getwd for %s\n",dir));
1582 if (p && (p != basename))
1585 if (strcmp(p+1,".")==0)
1587 if (strcmp(p+1,"..")==0)
1591 if (ChDir(basename) != 0)
1594 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1598 if (!GetWd(newname))
1601 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1605 if (p && (p != basename))
1607 strcat(newname,"/");
1608 strcat(newname,p+1);
1612 int l = strlen(dir2);
1613 if (dir2[l-1] == '/')
1616 if (strncmp(newname,dir2,l) != 0)
1619 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1625 if (newname[l] == '/')
1626 pstrcpy(s,newname + l + 1);
1628 pstrcpy(s,newname+l);
1639 DEBUG(3,("reduced to %s\n",s));
1644 /****************************************************************************
1646 ****************************************************************************/
1647 static void expand_one(char *Mask,int len)
1650 while ((p1 = strchr(Mask,'*')) != NULL)
1652 int lfill = (len+1) - strlen(Mask);
1653 int l1= (p1 - Mask);
1656 memset(tmp+l1,'?',lfill);
1657 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1662 /****************************************************************************
1663 expand a wildcard expression, replacing *s with ?s
1664 ****************************************************************************/
1665 void expand_mask(char *Mask,BOOL doext)
1670 BOOL hasdot = False;
1672 BOOL absolute = (*Mask == '\\');
1674 *mbeg = *mext = *dirpart = *filepart = 0;
1676 /* parse the directory and filename */
1677 if (strchr(Mask,'\\'))
1678 dirname_dos(Mask,dirpart);
1680 filename_dos(Mask,filepart);
1682 pstrcpy(mbeg,filepart);
1683 if ((p1 = strchr(mbeg,'.')) != NULL)
1693 if (strlen(mbeg) > 8)
1695 pstrcpy(mext,mbeg + 8);
1701 strcpy(mbeg,"????????");
1702 if ((*mext == 0) && doext && !hasdot)
1705 if (strequal(mbeg,"*") && *mext==0)
1713 pstrcpy(Mask,dirpart);
1714 if (*dirpart || absolute) strcat(Mask,"\\");
1719 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1723 /****************************************************************************
1724 does a string have any uppercase chars in it?
1725 ****************************************************************************/
1726 BOOL strhasupper(char *s)
1730 #if !defined(KANJI_WIN95_COMPATIBILITY)
1731 if(lp_client_code_page() == KANJI_CODEPAGE)
1733 /* Win95 treats full width ascii characters as case sensitive. */
1734 if (is_shift_jis (*s))
1736 else if (is_kana (*s))
1746 #endif /* KANJI_WIN95_COMPATIBILITY */
1756 /****************************************************************************
1757 does a string have any lowercase chars in it?
1758 ****************************************************************************/
1759 BOOL strhaslower(char *s)
1763 #if !defined(KANJI_WIN95_COMPATIBILITY)
1764 if(lp_client_code_page() == KANJI_CODEPAGE)
1766 /* Win95 treats full width ascii characters as case sensitive. */
1767 if (is_shift_jis (*s))
1769 if (is_sj_upper (s[0], s[1]))
1771 if (is_sj_lower (s[0], s[1]))
1775 else if (is_kana (*s))
1787 #endif /* KANJI_WIN95_COMPATIBILITY */
1797 /****************************************************************************
1798 find the number of chars in a string
1799 ****************************************************************************/
1800 int count_chars(char *s,char c)
1804 #if !defined(KANJI_WIN95_COMPATIBILITY)
1805 if(lp_client_code_page() == KANJI_CODEPAGE)
1807 /* Win95 treats full width ascii characters as case sensitive. */
1810 if (is_shift_jis (*s))
1821 #endif /* KANJI_WIN95_COMPATIBILITY */
1834 /****************************************************************************
1836 ****************************************************************************/
1837 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1842 pstrcpy(mask2,mask);
1844 if ((mode & aDIR) != 0)
1847 memset(buf+1,' ',11);
1848 if ((p = strchr(mask2,'.')) != NULL)
1851 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1852 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1856 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1858 bzero(buf+21,DIR_STRUCT_SIZE-21);
1859 CVAL(buf,21) = mode;
1860 put_dos_date(buf,22,date);
1861 SSVAL(buf,26,size & 0xFFFF);
1862 SSVAL(buf,28,size >> 16);
1863 StrnCpy(buf+30,fname,12);
1864 if (!case_sensitive)
1866 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1870 /*******************************************************************
1871 close the low 3 fd's and open dev/null in their place
1872 ********************************************************************/
1873 void close_low_fds(void)
1877 close(0); close(1); close(2);
1878 /* try and use up these file descriptors, so silly
1879 library routines writing to stdout etc won't cause havoc */
1881 fd = open("/dev/null",O_RDWR,0);
1882 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1884 DEBUG(0,("Can't open /dev/null\n"));
1888 DEBUG(0,("Didn't get file descriptor %d\n",i));
1894 /****************************************************************************
1895 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1897 if SYSV use O_NDELAY
1899 ****************************************************************************/
1900 int set_blocking(int fd, BOOL set)
1904 #define FLAG_TO_SET O_NONBLOCK
1907 #define FLAG_TO_SET O_NDELAY
1909 #define FLAG_TO_SET FNDELAY
1913 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1915 if(set) /* Turn blocking on - ie. clear nonblock flag */
1916 val &= ~FLAG_TO_SET;
1919 return fcntl( fd, F_SETFL, val);
1924 /****************************************************************************
1926 ****************************************************************************/
1927 int write_socket(int fd,char *buf,int len)
1933 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1934 ret = write_data(fd,buf,len);
1936 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1940 /****************************************************************************
1942 ****************************************************************************/
1943 int read_udp_socket(int fd,char *buf,int len)
1946 struct sockaddr sock;
1949 socklen = sizeof(sock);
1950 bzero((char *)&sock,socklen);
1951 bzero((char *)&lastip,sizeof(lastip));
1952 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1954 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1958 lastip = *(struct in_addr *) &sock.sa_data[2];
1959 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1964 /****************************************************************************
1965 read data from a device with a timout in msec.
1966 mincount = if timeout, minimum to read before returning
1967 maxcount = number to be read.
1968 ****************************************************************************/
1969 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1975 struct timeval timeout;
1977 /* just checking .... */
1978 if (maxcnt <= 0) return(0);
1983 if (time_out <= 0) {
1984 if (mincnt == 0) mincnt = maxcnt;
1986 while (nread < mincnt) {
1987 readret = read(fd, buf + nread, maxcnt - nread);
1989 smb_read_error = READ_EOF;
1993 if (readret == -1) {
1994 smb_read_error = READ_ERROR;
2002 /* Most difficult - timeout read */
2003 /* If this is ever called on a disk file and
2004 mincnt is greater then the filesize then
2005 system performance will suffer severely as
2006 select always return true on disk files */
2008 /* Set initial timeout */
2009 timeout.tv_sec = time_out / 1000;
2010 timeout.tv_usec = 1000 * (time_out % 1000);
2012 for (nread=0; nread<mincnt; )
2017 selrtn = sys_select(&fds,&timeout);
2019 /* Check if error */
2021 /* something is wrong. Maybe the socket is dead? */
2022 smb_read_error = READ_ERROR;
2026 /* Did we timeout ? */
2028 smb_read_error = READ_TIMEOUT;
2032 readret = read(fd, buf+nread, maxcnt-nread);
2034 /* we got EOF on the file descriptor */
2035 smb_read_error = READ_EOF;
2039 if (readret == -1) {
2040 /* the descriptor is probably dead */
2041 smb_read_error = READ_ERROR;
2048 /* Return the number we got */
2052 /****************************************************************************
2053 read data from the client. Maxtime is in milliseconds
2054 ****************************************************************************/
2055 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2060 struct timeval timeout;
2065 timeout.tv_sec = maxtime / 1000;
2066 timeout.tv_usec = (maxtime % 1000) * 1000;
2068 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2070 if (!FD_ISSET(fd,&fds))
2073 nread = read_udp_socket(fd, buffer, bufsize);
2075 /* return the number got */
2079 /*******************************************************************
2080 find the difference in milliseconds between two struct timeval
2082 ********************************************************************/
2083 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2085 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2086 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2089 /****************************************************************************
2090 send a keepalive packet (rfc1002)
2091 ****************************************************************************/
2092 BOOL send_keepalive(int client)
2094 unsigned char buf[4];
2097 buf[1] = buf[2] = buf[3] = 0;
2099 return(write_data(client,(char *)buf,4) == 4);
2104 /****************************************************************************
2105 read data from the client, reading exactly N bytes.
2106 ****************************************************************************/
2107 int read_data(int fd,char *buffer,int N)
2116 ret = read(fd,buffer + total,N - total);
2118 smb_read_error = READ_EOF;
2122 smb_read_error = READ_ERROR;
2131 /****************************************************************************
2133 ****************************************************************************/
2134 int write_data(int fd,char *buffer,int N)
2141 ret = write(fd,buffer + total,N - total);
2143 if (ret == -1) return -1;
2144 if (ret == 0) return total;
2152 /****************************************************************************
2153 transfer some data between two fd's
2154 ****************************************************************************/
2155 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2157 static char *buf=NULL;
2162 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2165 size = lp_readsize();
2166 size = MAX(size,1024);
2169 while (!buf && size>0) {
2170 buf = (char *)Realloc(buf,size+8);
2171 if (!buf) size /= 2;
2175 DEBUG(0,("Can't allocate transfer buffer!\n"));
2179 abuf = buf + (align%8);
2186 int s = MIN(n,size);
2191 if (header && (headlen >= MIN(s,1024))) {
2201 if (header && headlen > 0)
2203 ret = MIN(headlen,size);
2204 memcpy(buf1,header,ret);
2207 if (headlen <= 0) header = NULL;
2211 ret += read(infd,buf1+ret,s-ret);
2215 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2216 if (ret2 > 0) total += ret2;
2217 /* if we can't write then dump excess data */
2219 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2221 if (ret <= 0 || ret2 != ret)
2229 /****************************************************************************
2230 read 4 bytes of a smb packet and return the smb length of the packet
2231 possibly store the result in the buffer
2232 ****************************************************************************/
2233 int read_smb_length(int fd,char *inbuf,int timeout)
2237 int len=0, msg_type;
2248 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2250 ok = (read_data(fd,buffer,4) == 4);
2255 len = smb_len(buffer);
2256 msg_type = CVAL(buffer,0);
2258 if (msg_type == 0x85)
2260 DEBUG(5,("Got keepalive packet\n"));
2265 DEBUG(10,("got smb length of %d\n",len));
2272 /****************************************************************************
2273 read an smb from a fd.
2274 The timeout is in milli seconds
2275 ****************************************************************************/
2276 BOOL receive_smb(int fd,char *buffer,int timeout)
2282 bzero(buffer,smb_size + 100);
2284 len = read_smb_length(fd,buffer,timeout);
2288 if (len > BUFFER_SIZE) {
2289 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2290 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2294 ret = read_data(fd,buffer+4,len);
2296 smb_read_error = READ_ERROR;
2304 /****************************************************************************
2305 Do a select on an two fd's - with timeout.
2307 If the first smbfd is ready then read an smb from it.
2308 if the second (loopback UDP) fd is ready then read a message
2309 from it and setup the buffer header to identify the length
2311 Returns False on timeout or error.
2314 The timeout is in milli seconds
2315 ****************************************************************************/
2316 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2317 char *buffer, int buffer_len,
2318 int timeout, BOOL *got_smb)
2328 FD_SET(oplock_fd,&fds);
2330 to.tv_sec = timeout / 1000;
2331 to.tv_usec = (timeout % 1000) * 1000;
2333 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2335 /* Check if error */
2337 /* something is wrong. Maybe the socket is dead? */
2338 smb_read_error = READ_ERROR;
2342 /* Did we timeout ? */
2344 smb_read_error = READ_TIMEOUT;
2348 if (FD_ISSET(smbfd,&fds))
2351 return receive_smb(smbfd, buffer, 0);
2356 * Read a udp message.
2358 struct sockaddr_in from;
2359 int fromlen = sizeof(from);
2363 msg_len = recvfrom(oplock_fd, &buffer[6+sizeof(struct in_addr)],
2364 buffer_len - (6 + sizeof(struct in_addr)), 0,
2365 (struct sockaddr *)&from, &fromlen);
2369 DEBUG(0,("Invalid loopback packet ! (%s).\n",strerror(errno)));
2373 port = ntohs(from.sin_port);
2375 /* Setup the message header */
2376 SIVAL(buffer,0,msg_len);
2377 SSVAL(buffer,4,port);
2378 memcpy(&buffer[6],(char *)&from.sin_addr,sizeof(struct in_addr));
2384 #endif /* USE_OPLOCKS */
2386 /****************************************************************************
2388 ****************************************************************************/
2389 BOOL send_smb(int fd,char *buffer)
2393 len = smb_len(buffer) + 4;
2395 while (nwritten < len)
2397 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2400 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2412 /****************************************************************************
2413 find a pointer to a netbios name
2414 ****************************************************************************/
2415 char *name_ptr(char *buf,int ofs)
2417 unsigned char c = *(unsigned char *)(buf+ofs);
2419 if ((c & 0xC0) == 0xC0)
2423 memcpy(p,buf+ofs,2);
2426 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2433 /****************************************************************************
2434 extract a netbios name from a buf
2435 ****************************************************************************/
2436 int name_extract(char *buf,int ofs,char *name)
2438 char *p = name_ptr(buf,ofs);
2439 int d = PTR_DIFF(p,buf+ofs);
2441 if (d < -50 || d > 50) return(0);
2442 return(name_interpret(p,name));
2446 /****************************************************************************
2447 return the total storage length of a mangled name
2448 ****************************************************************************/
2449 int name_len(char *s)
2452 unsigned char c = *(unsigned char *)s;
2453 if ((c & 0xC0) == 0xC0)
2455 while (*s) s += (*s)+1;
2456 return(PTR_DIFF(s,s0)+1);
2459 /****************************************************************************
2460 send a single packet to a port on another machine
2461 ****************************************************************************/
2462 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2466 struct sockaddr_in sock_out;
2471 /* create a socket to write to */
2472 out_fd = socket(AF_INET, type, 0);
2475 DEBUG(0,("socket failed"));
2479 /* set the address and port */
2480 bzero((char *)&sock_out,sizeof(sock_out));
2481 putip((char *)&sock_out.sin_addr,(char *)&ip);
2482 sock_out.sin_port = htons( port );
2483 sock_out.sin_family = AF_INET;
2486 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2487 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2490 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2493 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2494 inet_ntoa(ip),port,strerror(errno)));
2500 /*******************************************************************
2501 sleep for a specified number of milliseconds
2502 ********************************************************************/
2506 struct timeval tval,t1,t2;
2513 tval.tv_sec = (t-tdiff)/1000;
2514 tval.tv_usec = 1000*((t-tdiff)%1000);
2518 sys_select(&fds,&tval);
2521 tdiff = TvalDiff(&t1,&t2);
2525 /****************************************************************************
2526 check if a string is part of a list
2527 ****************************************************************************/
2528 BOOL in_list(char *s,char *list,BOOL casesensitive)
2533 if (!list) return(False);
2535 while (next_token(&p,tok,LIST_SEP))
2537 if (casesensitive) {
2538 if (strcmp(tok,s) == 0)
2541 if (StrCaseCmp(tok,s) == 0)
2548 /* this is used to prevent lots of mallocs of size 1 */
2549 static char *null_string = NULL;
2551 /****************************************************************************
2552 set a string value, allocing the space for the string
2553 ****************************************************************************/
2554 BOOL string_init(char **dest,char *src)
2565 null_string = (char *)malloc(1);
2568 *dest = null_string;
2572 (*dest) = (char *)malloc(l+1);
2573 if ((*dest) == NULL) {
2574 DEBUG(0,("Out of memory in string_init\n"));
2583 /****************************************************************************
2585 ****************************************************************************/
2586 void string_free(char **s)
2588 if (!s || !(*s)) return;
2589 if (*s == null_string)
2595 /****************************************************************************
2596 set a string value, allocing the space for the string, and deallocating any
2598 ****************************************************************************/
2599 BOOL string_set(char **dest,char *src)
2603 return(string_init(dest,src));
2606 /****************************************************************************
2607 substitute a string for a pattern in another string. Make sure there is
2610 This routine looks for pattern in s and replaces it with
2611 insert. It may do multiple replacements.
2613 return True if a substitution was done.
2614 ****************************************************************************/
2615 BOOL string_sub(char *s,char *pattern,char *insert)
2621 if (!insert || !pattern || !s) return(False);
2624 lp = strlen(pattern);
2625 li = strlen(insert);
2627 if (!*pattern) return(False);
2629 while (lp <= ls && (p = strstr(s,pattern)))
2632 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2633 memcpy(p,insert,li);
2642 /*********************************************************
2643 * Recursive routine that is called by mask_match.
2644 * Does the actual matching.
2645 *********************************************************/
2646 BOOL do_match(char *str, char *regexp, int case_sig)
2650 for( p = regexp; *p && *str; ) {
2657 /* Look for a character matching
2658 the one after the '*' */
2661 return True; /* Automatic match */
2663 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2665 if(do_match(str,p,case_sig))
2679 if(toupper(*str) != toupper(*p))
2689 if (!*p && str[0] == '.' && str[1] == 0)
2692 if (!*str && *p == '?')
2694 while (*p == '?') p++;
2698 if(!*str && (*p == '*' && p[1] == '\0'))
2704 /*********************************************************
2705 * Routine to match a given string with a regexp - uses
2706 * simplified regexp that takes * and ? only. Case can be
2707 * significant or not.
2708 *********************************************************/
2709 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2713 fstring ebase,eext,sbase,sext;
2717 /* Make local copies of str and regexp */
2718 StrnCpy(p1,regexp,sizeof(pstring)-1);
2719 StrnCpy(p2,str,sizeof(pstring)-1);
2721 if (!strchr(p2,'.')) {
2726 if (!strchr(p1,'.')) {
2734 string_sub(p1,"*.*","*");
2735 string_sub(p1,".*","*");
2739 /* Remove any *? and ** as they are meaningless */
2740 for(p = p1; *p; p++)
2741 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2742 (void)strcpy( &p[1], &p[2]);
2744 if (strequal(p1,"*")) return(True);
2746 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2752 if ((p=strrchr(p1,'.'))) {
2761 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2771 matched = do_match(sbase,ebase,case_sig) &&
2772 (trans2 || do_match(sext,eext,case_sig));
2774 DEBUG(5,("mask_match returning %d\n", matched));
2781 /****************************************************************************
2782 become a daemon, discarding the controlling terminal
2783 ****************************************************************************/
2784 void become_daemon(void)
2786 #ifndef NO_FORK_DEBUG
2790 /* detach from the terminal */
2793 #else /* USE_SETSID */
2796 int i = open("/dev/tty", O_RDWR);
2799 ioctl(i, (int) TIOCNOTTY, (char *)0);
2803 #endif /* TIOCNOTTY */
2804 #endif /* USE_SETSID */
2805 /* Close fd's 0,1,2. Needed if started by rsh */
2807 #endif /* NO_FORK_DEBUG */
2811 /****************************************************************************
2812 put up a yes/no prompt
2813 ****************************************************************************/
2819 if (!fgets(ans,sizeof(ans)-1,stdin))
2822 if (*ans == 'y' || *ans == 'Y')
2828 /****************************************************************************
2829 read a line from a file with possible \ continuation chars.
2830 Blanks at the start or end of a line are stripped.
2831 The string will be allocated if s2 is NULL
2832 ****************************************************************************/
2833 char *fgets_slash(char *s2,int maxlen,FILE *f)
2838 BOOL start_of_line = True;
2845 maxlen = MIN(maxlen,8);
2846 s = (char *)Realloc(s,maxlen);
2849 if (!s || maxlen < 2) return(NULL);
2853 while (len < maxlen-1)
2861 while (len > 0 && s[len-1] == ' ')
2865 if (len > 0 && s[len-1] == '\\')
2868 start_of_line = True;
2873 if (len <= 0 && !s2)
2875 return(len>0?s:NULL);
2880 start_of_line = False;
2884 if (!s2 && len > maxlen-3)
2887 s = (char *)Realloc(s,maxlen);
2888 if (!s) return(NULL);
2896 /****************************************************************************
2897 set the length of a file from a filedescriptor.
2898 Returns 0 on success, -1 on failure.
2899 ****************************************************************************/
2900 int set_filelen(int fd, long len)
2902 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2903 extend a file with ftruncate. Provide alternate implementation
2906 #if FTRUNCATE_CAN_EXTEND
2907 return ftruncate(fd, len);
2911 long currpos = lseek(fd, 0L, SEEK_CUR);
2915 /* Do an fstat to see if the file is longer than
2916 the requested size (call ftruncate),
2917 or shorter, in which case seek to len - 1 and write 1
2919 if(fstat(fd, &st)<0)
2923 if (S_ISFIFO(st.st_mode)) return 0;
2926 if(st.st_size == len)
2928 if(st.st_size > len)
2929 return ftruncate(fd, len);
2931 if(lseek(fd, len-1, SEEK_SET) != len -1)
2933 if(write(fd, &c, 1)!=1)
2935 /* Seek to where we were */
2936 lseek(fd, currpos, SEEK_SET);
2942 /****************************************************************************
2943 return the byte checksum of some data
2944 ****************************************************************************/
2945 int byte_checksum(char *buf,int len)
2947 unsigned char *p = (unsigned char *)buf;
2957 /****************************************************************************
2958 this is a version of setbuffer() for those machines that only have setvbuf
2959 ****************************************************************************/
2960 void setbuffer(FILE *f,char *buf,int bufsize)
2962 setvbuf(f,buf,_IOFBF,bufsize);
2967 /****************************************************************************
2968 parse out a directory name from a path name. Assumes dos style filenames.
2969 ****************************************************************************/
2970 char *dirname_dos(char *path,char *buf)
2972 char *p = strrchr(path,'\\');
2987 /****************************************************************************
2988 parse out a filename from a path name. Assumes dos style filenames.
2989 ****************************************************************************/
2990 static char *filename_dos(char *path,char *buf)
2992 char *p = strrchr(path,'\\');
3004 /****************************************************************************
3005 expand a pointer to be a particular size
3006 ****************************************************************************/
3007 void *Realloc(void *p,int size)
3013 DEBUG(5,("Realloc asked for 0 bytes\n"));
3018 ret = (void *)malloc(size);
3020 ret = (void *)realloc(p,size);
3023 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3029 /****************************************************************************
3031 ****************************************************************************/
3032 char *strdup(char *s)
3035 if (!s) return(NULL);
3036 ret = (char *)malloc(strlen(s)+1);
3037 if (!ret) return(NULL);
3044 /****************************************************************************
3045 Signal handler for SIGPIPE (write on a disconnected socket)
3046 ****************************************************************************/
3049 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3053 /****************************************************************************
3054 get my own name and IP
3055 ****************************************************************************/
3056 BOOL get_myname(char *my_name,struct in_addr *ip)
3063 /* get my host name */
3064 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3066 DEBUG(0,("gethostname failed\n"));
3071 if ((hp = Get_Hostbyname(hostname)) == 0)
3073 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3079 /* split off any parts after an initial . */
3080 char *p = strchr(hostname,'.');
3083 fstrcpy(my_name,hostname);
3087 putip((char *)ip,(char *)hp->h_addr);
3093 /****************************************************************************
3094 true if two IP addresses are equal
3095 ****************************************************************************/
3096 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3099 a1 = ntohl(ip1.s_addr);
3100 a2 = ntohl(ip2.s_addr);
3105 /****************************************************************************
3106 open a socket of the specified type, port and address for incoming data
3107 ****************************************************************************/
3108 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3111 struct sockaddr_in sock;
3115 /* get my host name */
3116 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3117 { DEBUG(0,("gethostname failed\n")); return -1; }
3120 if ((hp = Get_Hostbyname(host_name)) == 0)
3122 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3126 bzero((char *)&sock,sizeof(sock));
3127 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3128 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3129 sock.sin_len = sizeof(sock);
3131 sock.sin_port = htons( port );
3132 sock.sin_family = hp->h_addrtype;
3133 sock.sin_addr.s_addr = socket_addr;
3134 res = socket(hp->h_addrtype, type, 0);
3136 { DEBUG(0,("socket failed\n")); return -1; }
3140 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3143 /* now we've got a socket - we need to bind it */
3144 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3147 if (port == SMB_PORT || port == NMB_PORT)
3148 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
3149 port,socket_addr,strerror(errno)));
3152 if (dlevel > 0 && port < 1000)
3155 if (port >= 1000 && port < 9000)
3156 return(open_socket_in(type,port+1,dlevel,socket_addr));
3161 DEBUG(3,("bind succeeded on port %d\n",port));
3167 /****************************************************************************
3168 create an outgoing socket
3169 **************************************************************************/
3170 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3172 struct sockaddr_in sock_out;
3174 int connect_loop = 250; /* 250 milliseconds */
3175 int loops = (timeout * 1000) / connect_loop;
3177 /* create a socket to write to */
3178 res = socket(PF_INET, type, 0);
3180 { DEBUG(0,("socket error\n")); return -1; }
3182 if (type != SOCK_STREAM) return(res);
3184 bzero((char *)&sock_out,sizeof(sock_out));
3185 putip((char *)&sock_out.sin_addr,(char *)addr);
3187 sock_out.sin_port = htons( port );
3188 sock_out.sin_family = PF_INET;
3190 /* set it non-blocking */
3191 set_blocking(res,False);
3193 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3195 /* and connect it to the destination */
3197 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3199 /* Some systems return EAGAIN when they mean EINPROGRESS */
3200 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3201 errno == EAGAIN) && loops--) {
3202 msleep(connect_loop);
3206 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3208 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3214 if (ret < 0 && errno == EISCONN) {
3221 DEBUG(1,("error connecting to %s:%d (%s)\n",
3222 inet_ntoa(*addr),port,strerror(errno)));
3226 /* set it blocking again */
3227 set_blocking(res,True);
3233 /****************************************************************************
3234 interpret a protocol description string, with a default
3235 ****************************************************************************/
3236 int interpret_protocol(char *str,int def)
3238 if (strequal(str,"NT1"))
3239 return(PROTOCOL_NT1);
3240 if (strequal(str,"LANMAN2"))
3241 return(PROTOCOL_LANMAN2);
3242 if (strequal(str,"LANMAN1"))
3243 return(PROTOCOL_LANMAN1);
3244 if (strequal(str,"CORE"))
3245 return(PROTOCOL_CORE);
3246 if (strequal(str,"COREPLUS"))
3247 return(PROTOCOL_COREPLUS);
3248 if (strequal(str,"CORE+"))
3249 return(PROTOCOL_COREPLUS);
3251 DEBUG(0,("Unrecognised protocol level %s\n",str));
3256 /****************************************************************************
3257 interpret a security level
3258 ****************************************************************************/
3259 int interpret_security(char *str,int def)
3261 if (strequal(str,"SERVER"))
3263 if (strequal(str,"USER"))
3265 if (strequal(str,"SHARE"))
3268 DEBUG(0,("Unrecognised security level %s\n",str));
3274 /****************************************************************************
3275 interpret an internet address or name into an IP address in 4 byte form
3276 ****************************************************************************/
3277 uint32 interpret_addr(char *str)
3282 BOOL pure_address = True;
3284 if (strcmp(str,"0.0.0.0") == 0) return(0);
3285 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3287 for (i=0; pure_address && str[i]; i++)
3288 if (!(isdigit(str[i]) || str[i] == '.'))
3289 pure_address = False;
3291 /* if it's in the form of an IP address then get the lib to interpret it */
3293 res = inet_addr(str);
3295 /* otherwise assume it's a network name of some sort and use
3297 if ((hp = Get_Hostbyname(str)) == 0) {
3298 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3301 putip((char *)&res,(char *)hp->h_addr);
3304 if (res == (uint32)-1) return(0);
3309 /*******************************************************************
3310 a convenient addition to interpret_addr()
3311 ******************************************************************/
3312 struct in_addr *interpret_addr2(char *str)
3314 static struct in_addr ret;
3315 uint32 a = interpret_addr(str);
3320 /*******************************************************************
3321 check if an IP is the 0.0.0.0
3322 ******************************************************************/
3323 BOOL zero_ip(struct in_addr ip)
3326 putip((char *)&a,(char *)&ip);
3331 /*******************************************************************
3332 matchname - determine if host name matches IP address
3333 ******************************************************************/
3334 static BOOL matchname(char *remotehost,struct in_addr addr)
3339 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3340 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3345 * Make sure that gethostbyname() returns the "correct" host name.
3346 * Unfortunately, gethostbyname("localhost") sometimes yields
3347 * "localhost.domain". Since the latter host name comes from the
3348 * local DNS, we just have to trust it (all bets are off if the local
3349 * DNS is perverted). We always check the address list, though.
3352 if (strcasecmp(remotehost, hp->h_name)
3353 && strcasecmp(remotehost, "localhost")) {
3354 DEBUG(0,("host name/name mismatch: %s != %s",
3355 remotehost, hp->h_name));
3359 /* Look up the host address in the address list we just got. */
3360 for (i = 0; hp->h_addr_list[i]; i++) {
3361 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3366 * The host name does not map to the original host address. Perhaps
3367 * someone has compromised a name server. More likely someone botched
3368 * it, but that could be dangerous, too.
3371 DEBUG(0,("host name/address mismatch: %s != %s",
3372 inet_ntoa(addr), hp->h_name));
3376 /*******************************************************************
3377 Reset the 'done' variables so after a client process is created
3378 from a fork call these calls will be re-done. This should be
3379 expanded if more variables need reseting.
3380 ******************************************************************/
3382 static BOOL global_client_name_done = False;
3383 static BOOL global_client_addr_done = False;
3385 void reset_globals_after_fork()
3387 global_client_name_done = False;
3388 global_client_addr_done = False;
3391 /*******************************************************************
3392 return the DNS name of the client
3393 ******************************************************************/
3394 char *client_name(void)
3398 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3399 int length = sizeof(sa);
3400 static pstring name_buf;
3403 if (global_client_name_done)
3406 strcpy(name_buf,"UNKNOWN");
3408 if (getpeername(Client, &sa, &length) < 0) {
3409 DEBUG(0,("getpeername failed\n"));
3413 /* Look up the remote host name. */
3414 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3415 sizeof(sockin->sin_addr),
3417 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3418 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3420 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3421 if (!matchname(name_buf, sockin->sin_addr)) {
3422 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3423 strcpy(name_buf,"UNKNOWN");
3426 global_client_name_done = True;
3430 /*******************************************************************
3431 return the IP addr of the client as a string
3432 ******************************************************************/
3433 char *client_addr(void)
3437 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3438 int length = sizeof(sa);
3439 static fstring addr_buf;
3441 if (global_client_addr_done)
3444 strcpy(addr_buf,"0.0.0.0");
3446 if (getpeername(Client, &sa, &length) < 0) {
3447 DEBUG(0,("getpeername failed\n"));
3451 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3453 global_client_addr_done = True;
3457 /*******************************************************************
3458 sub strings with useful parameters
3459 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3460 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3461 ********************************************************************/
3462 void standard_sub_basic(char *str)
3466 struct passwd *pass;
3468 for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3472 case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3473 string_sub(p,"%G",gidtoname(pass->pw_gid));
3477 case 'I' : string_sub(p,"%I",client_addr()); break;
3478 case 'L' : string_sub(p,"%L",local_machine); break;
3479 case 'M' : string_sub(p,"%M",client_name()); break;
3480 case 'R' : string_sub(p,"%R",remote_proto); break;
3481 case 'T' : string_sub(p,"%T",timestring()); break;
3482 case 'U' : string_sub(p,"%U",sesssetup_user); break;
3483 case 'a' : string_sub(p,"%a",remote_arch); break;
3484 case 'd' : sprintf(pidstr,"%d",(int)getpid());
3485 string_sub(p,"%d",pidstr);
3487 case 'h' : string_sub(p,"%h",myhostname); break;
3488 case 'm' : string_sub(p,"%m",remote_machine); break;
3489 case 'v' : string_sub(p,"%v",VERSION); break;
3490 case '\0' : p++; break; /* don't run off end if last character is % */
3491 default : p+=2; break;
3497 /*******************************************************************
3498 are two IPs on the same subnet?
3499 ********************************************************************/
3500 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3502 uint32 net1,net2,nmask;
3504 nmask = ntohl(mask.s_addr);
3505 net1 = ntohl(ip1.s_addr);
3506 net2 = ntohl(ip2.s_addr);
3508 return((net1 & nmask) == (net2 & nmask));
3512 /*******************************************************************
3513 write a string in unicoode format
3514 ********************************************************************/
3515 int PutUniCode(char *dst,char *src)
3519 dst[ret++] = src[0];
3528 /****************************************************************************
3529 a wrapper for gethostbyname() that tries with all lower and all upper case
3530 if the initial name fails
3531 ****************************************************************************/
3532 struct hostent *Get_Hostbyname(char *name)
3534 char *name2 = strdup(name);
3535 struct hostent *ret;
3539 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3543 if (!isalnum(*name2))
3549 ret = sys_gethostbyname(name2);
3556 /* try with all lowercase */
3558 ret = sys_gethostbyname(name2);
3565 /* try with all uppercase */
3567 ret = sys_gethostbyname(name2);
3574 /* nothing works :-( */
3580 /****************************************************************************
3581 check if a process exists. Does this work on all unixes?
3582 ****************************************************************************/
3583 BOOL process_exists(int pid)
3587 sprintf(s,"/proc/%d",pid);
3588 return(directory_exist(s,NULL));
3591 static BOOL tested=False;
3592 static BOOL ok=False;
3596 sprintf(s,"/proc/%05d",(int)getpid());
3597 ok = file_exist(s,NULL);
3600 sprintf(s,"/proc/%05d",pid);
3601 return(file_exist(s,NULL));
3605 /* CGH 8/16/96 - added ESRCH test */
3606 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3611 /*******************************************************************
3612 turn a uid into a user name
3613 ********************************************************************/
3614 char *uidtoname(int uid)
3616 static char name[40];
3617 struct passwd *pass = getpwuid(uid);
3618 if (pass) return(pass->pw_name);
3619 sprintf(name,"%d",uid);
3623 /*******************************************************************
3624 turn a gid into a group name
3625 ********************************************************************/
3626 char *gidtoname(int gid)
3628 static char name[40];
3629 struct group *grp = getgrgid(gid);
3630 if (grp) return(grp->gr_name);
3631 sprintf(name,"%d",gid);
3635 /*******************************************************************
3637 ********************************************************************/
3638 void BlockSignals(BOOL block,int signum)
3641 int block_mask = sigmask(signum);
3642 static int oldmask = 0;
3644 oldmask = sigblock(block_mask);
3646 sigsetmask(oldmask);
3647 #elif defined(USE_SIGPROCMASK)
3650 sigaddset(&set,signum);
3651 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3656 /*******************************************************************
3657 my own panic function - not suitable for general use
3658 ********************************************************************/
3659 void ajt_panic(void)
3661 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3666 #define DIRECT direct
3668 #define DIRECT dirent
3671 /*******************************************************************
3672 a readdir wrapper which just returns the file name
3673 also return the inode number if requested
3674 ********************************************************************/
3675 char *readdirname(void *p)
3680 if (!p) return(NULL);
3682 ptr = (struct DIRECT *)readdir(p);
3683 if (!ptr) return(NULL);
3685 dname = ptr->d_name;
3688 if (telldir(p) < 0) return(NULL);
3692 /* this handles a broken compiler setup, causing a mixture
3693 of BSD and SYSV headers and libraries */
3695 static BOOL broken_readdir = False;
3696 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3698 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3699 broken_readdir = True;
3708 pstrcpy(buf, dname);
3709 unix_to_dos(buf, True);
3717 * Utility function used to decide if the last component
3718 * of a path matches a (possibly wildcarded) entry in a namelist.
3721 BOOL is_in_path(char *name, name_compare_entry *namelist)
3723 pstring last_component;
3726 DEBUG(5, ("is_in_path: %s\n", name));
3728 /* if we have no list it's obviously not in the path */
3729 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3731 DEBUG(5,("is_in_path: no name list.\n"));
3735 /* Get the last component of the unix name. */
3736 p = strrchr(name, '/');
3737 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3738 last_component[sizeof(last_component)-1] = '\0';
3740 for(; namelist->name != NULL; namelist++)
3742 if(namelist->is_wild)
3744 /* look for a wildcard match. */
3745 if (mask_match(last_component, namelist->name, case_sensitive, False))
3747 DEBUG(5,("is_in_path: mask match succeeded\n"));
3753 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3754 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3756 DEBUG(5,("is_in_path: match succeeded\n"));
3761 DEBUG(5,("is_in_path: match not found\n"));
3767 * Strip a '/' separated list into an array of
3768 * name_compare_enties structures suitable for
3769 * passing to is_in_path(). We do this for
3770 * speed so we can pre-parse all the names in the list
3771 * and don't do it for each call to is_in_path().
3772 * namelist is modified here and is assumed to be
3773 * a copy owned by the caller.
3774 * We also check if the entry contains a wildcard to
3775 * remove a potentially expensive call to mask_match
3779 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3782 char *nameptr = namelist;
3783 int num_entries = 0;
3786 (*ppname_array) = NULL;
3788 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3791 /* We need to make two passes over the string. The
3792 first to count the number of elements, the second
3797 if ( *nameptr == '/' )
3799 /* cope with multiple (useless) /s) */
3803 /* find the next / */
3804 name_end = strchr(nameptr, '/');
3806 /* oops - the last check for a / didn't find one. */
3807 if (name_end == NULL)
3810 /* next segment please */
3811 nameptr = name_end + 1;
3815 if(num_entries == 0)
3818 if(( (*ppname_array) = (name_compare_entry *)malloc(
3819 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3821 DEBUG(0,("set_namearray: malloc fail\n"));
3825 /* Now copy out the names */
3830 if ( *nameptr == '/' )
3832 /* cope with multiple (useless) /s) */
3836 /* find the next / */
3837 if ((name_end = strchr(nameptr, '/')) != NULL)
3842 /* oops - the last check for a / didn't find one. */
3843 if(name_end == NULL)
3846 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3847 (strchr( nameptr, '*')!=NULL));
3848 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3850 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3854 /* next segment please */
3855 nameptr = name_end + 1;
3859 (*ppname_array)[i].name = NULL;
3864 /****************************************************************************
3865 routine to free a namearray.
3866 ****************************************************************************/
3868 void free_namearray(name_compare_entry *name_array)
3873 if(name_array->name != NULL)
3874 free(name_array->name);
3876 free((char *)name_array);
3879 /****************************************************************************
3880 routine to do file locking
3881 ****************************************************************************/
3882 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3889 uint32 mask = 0xC0000000;
3891 /* make sure the count is reasonable, we might kill the lockd otherwise */
3894 /* the offset is often strange - remove 2 of its bits if either of
3895 the top two bits are set. Shift the top ones by two bits. This
3896 still allows OLE2 apps to operate, but should stop lockd from
3898 if ((offset & mask) != 0)
3899 offset = (offset & ~mask) | ((offset & mask) >> 2);
3901 uint32 mask = ((unsigned)1<<31);
3903 /* interpret negative counts as large numbers */
3907 /* no negative offsets */
3910 /* count + offset must be in range */
3911 while ((offset < 0 || (offset + count < 0)) && mask)
3919 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3922 lock.l_whence = SEEK_SET;
3923 lock.l_start = (int)offset;
3924 lock.l_len = (int)count;
3929 ret = fcntl(fd,op,&lock);
3932 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3938 (lock.l_type != F_UNLCK) &&
3939 (lock.l_pid != 0) &&
3940 (lock.l_pid != getpid()))
3942 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3946 /* it must be not locked or locked by me */
3950 /* a lock set or unset */
3953 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3954 offset,count,op,type,strerror(errno)));
3956 /* perhaps it doesn't support this sort of locking?? */
3957 if (errno == EINVAL)
3959 DEBUG(3,("locking not supported? returning True\n"));
3966 /* everything went OK */
3967 DEBUG(5,("Lock call successful\n"));
3975 /*******************************************************************
3976 lock a file - returning a open file descriptor or -1 on failure
3977 The timeout is in seconds. 0 means no timeout
3978 ********************************************************************/
3979 int file_lock(char *name,int timeout)
3981 int fd = open(name,O_RDWR|O_CREAT,0666);
3983 if (fd < 0) return(-1);
3986 if (timeout) t = time(NULL);
3987 while (!timeout || (time(NULL)-t < timeout)) {
3988 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3989 msleep(LOCK_RETRY_TIMEOUT);
3997 /*******************************************************************
3998 unlock a file locked by file_lock
3999 ********************************************************************/
4000 void file_unlock(int fd)
4004 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4009 /*******************************************************************
4010 is the name specified one of my netbios names
4011 returns true is it is equal, false otherwise
4012 ********************************************************************/
4013 BOOL is_myname(char *s)
4018 for (n=0; my_netbios_names[n]; n++) {
4019 if (strequal(my_netbios_names[n], s))
4022 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4026 /*******************************************************************
4027 set the horrid remote_arch string based on an enum.
4028 ********************************************************************/
4029 void set_remote_arch(enum remote_arch_types type)
4035 strcpy(remote_arch, "WfWg");
4038 strcpy(remote_arch, "OS2");
4041 strcpy(remote_arch, "Win95");
4044 strcpy(remote_arch, "WinNT");
4047 strcpy(remote_arch,"Samba");
4050 ra_type = RA_UNKNOWN;
4051 strcpy(remote_arch, "UNKNOWN");
4056 /*******************************************************************
4057 Get the remote_arch type.
4058 ********************************************************************/
4059 enum remote_arch_types get_remote_arch()
4064 /*******************************************************************
4065 safe string copy into a fstring
4066 ********************************************************************/
4067 void fstrcpy(char *dest, char *src)
4069 int maxlength = sizeof(fstring) - 1;
4071 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4080 while (maxlength-- && *src)
4084 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4089 /*******************************************************************
4090 safe string copy into a pstring
4091 ********************************************************************/
4092 void pstrcpy(char *dest, char *src)
4094 int maxlength = sizeof(pstring) - 1;
4096 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4105 while (maxlength-- && *src)
4109 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",