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 strcpy(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 strcpy(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 %d\n",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,"//","/");
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 strcpy(s,newname + l + 1);
1628 strcpy(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 strcpy(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 strcpy(mbeg,filepart);
1683 if ((p1 = strchr(mbeg,'.')) != NULL)
1693 if (strlen(mbeg) > 8)
1695 strcpy(mext,mbeg + 8);
1701 strcpy(mbeg,"????????");
1702 if ((*mext == 0) && doext && !hasdot)
1705 if (strequal(mbeg,"*") && *mext==0)
1713 strcpy(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)
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=%d\n",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 and return it's length
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 /****************************************************************************
2306 ****************************************************************************/
2307 BOOL send_smb(int fd,char *buffer)
2311 len = smb_len(buffer) + 4;
2313 while (nwritten < len)
2315 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2318 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2330 /****************************************************************************
2331 find a pointer to a netbios name
2332 ****************************************************************************/
2333 char *name_ptr(char *buf,int ofs)
2335 unsigned char c = *(unsigned char *)(buf+ofs);
2337 if ((c & 0xC0) == 0xC0)
2341 memcpy(p,buf+ofs,2);
2344 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2351 /****************************************************************************
2352 extract a netbios name from a buf
2353 ****************************************************************************/
2354 int name_extract(char *buf,int ofs,char *name)
2356 char *p = name_ptr(buf,ofs);
2357 int d = PTR_DIFF(p,buf+ofs);
2359 if (d < -50 || d > 50) return(0);
2360 return(name_interpret(p,name));
2364 /****************************************************************************
2365 return the total storage length of a mangled name
2366 ****************************************************************************/
2367 int name_len(char *s)
2370 unsigned char c = *(unsigned char *)s;
2371 if ((c & 0xC0) == 0xC0)
2373 while (*s) s += (*s)+1;
2374 return(PTR_DIFF(s,s0)+1);
2377 /****************************************************************************
2378 send a single packet to a port on another machine
2379 ****************************************************************************/
2380 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2384 struct sockaddr_in sock_out;
2389 /* create a socket to write to */
2390 out_fd = socket(AF_INET, type, 0);
2393 DEBUG(0,("socket failed"));
2397 /* set the address and port */
2398 bzero((char *)&sock_out,sizeof(sock_out));
2399 putip((char *)&sock_out.sin_addr,(char *)&ip);
2400 sock_out.sin_port = htons( port );
2401 sock_out.sin_family = AF_INET;
2404 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2405 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2408 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2411 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2412 inet_ntoa(ip),port,errno));
2418 /*******************************************************************
2419 sleep for a specified number of milliseconds
2420 ********************************************************************/
2424 struct timeval tval,t1,t2;
2431 tval.tv_sec = (t-tdiff)/1000;
2432 tval.tv_usec = 1000*((t-tdiff)%1000);
2436 sys_select(&fds,&tval);
2439 tdiff = TvalDiff(&t1,&t2);
2443 /****************************************************************************
2444 check if a string is part of a list
2445 ****************************************************************************/
2446 BOOL in_list(char *s,char *list,BOOL casesensitive)
2451 if (!list) return(False);
2453 while (next_token(&p,tok,LIST_SEP))
2455 if (casesensitive) {
2456 if (strcmp(tok,s) == 0)
2459 if (StrCaseCmp(tok,s) == 0)
2466 /* this is used to prevent lots of mallocs of size 1 */
2467 static char *null_string = NULL;
2469 /****************************************************************************
2470 set a string value, allocing the space for the string
2471 ****************************************************************************/
2472 BOOL string_init(char **dest,char *src)
2483 null_string = (char *)malloc(1);
2486 *dest = null_string;
2490 *dest = (char *)malloc(l+1);
2496 /****************************************************************************
2498 ****************************************************************************/
2499 void string_free(char **s)
2501 if (!s || !(*s)) return;
2502 if (*s == null_string)
2508 /****************************************************************************
2509 set a string value, allocing the space for the string, and deallocating any
2511 ****************************************************************************/
2512 BOOL string_set(char **dest,char *src)
2516 return(string_init(dest,src));
2519 /****************************************************************************
2520 substitute a string for a pattern in another string. Make sure there is
2523 This routine looks for pattern in s and replaces it with
2524 insert. It may do multiple replacements.
2526 return True if a substitution was done.
2527 ****************************************************************************/
2528 BOOL string_sub(char *s,char *pattern,char *insert)
2534 if (!insert || !pattern || !s) return(False);
2537 lp = strlen(pattern);
2538 li = strlen(insert);
2540 if (!*pattern) return(False);
2542 while (lp <= ls && (p = strstr(s,pattern)))
2545 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2546 memcpy(p,insert,li);
2555 /*********************************************************
2556 * Recursive routine that is called by mask_match.
2557 * Does the actual matching.
2558 *********************************************************/
2559 BOOL do_match(char *str, char *regexp, int case_sig)
2563 for( p = regexp; *p && *str; ) {
2570 /* Look for a character matching
2571 the one after the '*' */
2574 return True; /* Automatic match */
2576 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2578 if(do_match(str,p,case_sig))
2592 if(toupper(*str) != toupper(*p))
2602 if (!*p && str[0] == '.' && str[1] == 0)
2605 if (!*str && *p == '?')
2607 while (*p == '?') p++;
2611 if(!*str && (*p == '*' && p[1] == '\0'))
2617 /*********************************************************
2618 * Routine to match a given string with a regexp - uses
2619 * simplified regexp that takes * and ? only. Case can be
2620 * significant or not.
2621 *********************************************************/
2622 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2626 fstring ebase,eext,sbase,sext;
2630 /* Make local copies of str and regexp */
2631 StrnCpy(p1,regexp,sizeof(pstring)-1);
2632 StrnCpy(p2,str,sizeof(pstring)-1);
2634 if (!strchr(p2,'.')) {
2639 if (!strchr(p1,'.')) {
2647 string_sub(p1,"*.*","*");
2648 string_sub(p1,".*","*");
2652 /* Remove any *? and ** as they are meaningless */
2653 for(p = p1; *p; p++)
2654 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2655 (void)strcpy( &p[1], &p[2]);
2657 if (strequal(p1,"*")) return(True);
2659 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2665 if ((p=strrchr(p1,'.'))) {
2674 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2684 matched = do_match(sbase,ebase,case_sig) &&
2685 (trans2 || do_match(sext,eext,case_sig));
2687 DEBUG(5,("mask_match returning %d\n", matched));
2694 /****************************************************************************
2695 become a daemon, discarding the controlling terminal
2696 ****************************************************************************/
2697 void become_daemon(void)
2699 #ifndef NO_FORK_DEBUG
2703 /* detach from the terminal */
2706 #else /* USE_SETSID */
2709 int i = open("/dev/tty", O_RDWR);
2712 ioctl(i, (int) TIOCNOTTY, (char *)0);
2716 #endif /* TIOCNOTTY */
2717 #endif /* USE_SETSID */
2718 /* Close fd's 0,1,2. Needed if started by rsh */
2720 #endif /* NO_FORK_DEBUG */
2724 /****************************************************************************
2725 put up a yes/no prompt
2726 ****************************************************************************/
2732 if (!fgets(ans,sizeof(ans)-1,stdin))
2735 if (*ans == 'y' || *ans == 'Y')
2741 /****************************************************************************
2742 read a line from a file with possible \ continuation chars.
2743 Blanks at the start or end of a line are stripped.
2744 The string will be allocated if s2 is NULL
2745 ****************************************************************************/
2746 char *fgets_slash(char *s2,int maxlen,FILE *f)
2751 BOOL start_of_line = True;
2758 maxlen = MIN(maxlen,8);
2759 s = (char *)Realloc(s,maxlen);
2762 if (!s || maxlen < 2) return(NULL);
2766 while (len < maxlen-1)
2774 while (len > 0 && s[len-1] == ' ')
2778 if (len > 0 && s[len-1] == '\\')
2781 start_of_line = True;
2786 if (len <= 0 && !s2)
2788 return(len>0?s:NULL);
2793 start_of_line = False;
2797 if (!s2 && len > maxlen-3)
2800 s = (char *)Realloc(s,maxlen);
2801 if (!s) return(NULL);
2809 /****************************************************************************
2810 set the length of a file from a filedescriptor.
2811 Returns 0 on success, -1 on failure.
2812 ****************************************************************************/
2813 int set_filelen(int fd, long len)
2815 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2816 extend a file with ftruncate. Provide alternate implementation
2819 #if FTRUNCATE_CAN_EXTEND
2820 return ftruncate(fd, len);
2824 long currpos = lseek(fd, 0L, SEEK_CUR);
2828 /* Do an fstat to see if the file is longer than
2829 the requested size (call ftruncate),
2830 or shorter, in which case seek to len - 1 and write 1
2832 if(fstat(fd, &st)<0)
2836 if (S_ISFIFO(st.st_mode)) return 0;
2839 if(st.st_size == len)
2841 if(st.st_size > len)
2842 return ftruncate(fd, len);
2844 if(lseek(fd, len-1, SEEK_SET) != len -1)
2846 if(write(fd, &c, 1)!=1)
2848 /* Seek to where we were */
2849 lseek(fd, currpos, SEEK_SET);
2855 /****************************************************************************
2856 return the byte checksum of some data
2857 ****************************************************************************/
2858 int byte_checksum(char *buf,int len)
2860 unsigned char *p = (unsigned char *)buf;
2870 /****************************************************************************
2871 this is a version of setbuffer() for those machines that only have setvbuf
2872 ****************************************************************************/
2873 void setbuffer(FILE *f,char *buf,int bufsize)
2875 setvbuf(f,buf,_IOFBF,bufsize);
2880 /****************************************************************************
2881 parse out a directory name from a path name. Assumes dos style filenames.
2882 ****************************************************************************/
2883 char *dirname_dos(char *path,char *buf)
2885 char *p = strrchr(path,'\\');
2900 /****************************************************************************
2901 parse out a filename from a path name. Assumes dos style filenames.
2902 ****************************************************************************/
2903 static char *filename_dos(char *path,char *buf)
2905 char *p = strrchr(path,'\\');
2917 /****************************************************************************
2918 expand a pointer to be a particular size
2919 ****************************************************************************/
2920 void *Realloc(void *p,int size)
2926 DEBUG(5,("Realloc asked for 0 bytes\n"));
2931 ret = (void *)malloc(size);
2933 ret = (void *)realloc(p,size);
2936 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2942 /****************************************************************************
2944 ****************************************************************************/
2945 char *strdup(char *s)
2948 if (!s) return(NULL);
2949 ret = (char *)malloc(strlen(s)+1);
2950 if (!ret) return(NULL);
2957 /****************************************************************************
2958 Signal handler for SIGPIPE (write on a disconnected socket)
2959 ****************************************************************************/
2962 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2966 /****************************************************************************
2967 get my own name and IP
2968 ****************************************************************************/
2969 BOOL get_myname(char *my_name,struct in_addr *ip)
2976 /* get my host name */
2977 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2979 DEBUG(0,("gethostname failed\n"));
2984 if ((hp = Get_Hostbyname(hostname)) == 0)
2986 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2992 /* split off any parts after an initial . */
2993 char *p = strchr(hostname,'.');
2996 strcpy(my_name,hostname);
3000 putip((char *)ip,(char *)hp->h_addr);
3006 /****************************************************************************
3007 true if two IP addresses are equal
3008 ****************************************************************************/
3009 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3012 a1 = ntohl(ip1.s_addr);
3013 a2 = ntohl(ip2.s_addr);
3018 /****************************************************************************
3019 open a socket of the specified type, port and address for incoming data
3020 ****************************************************************************/
3021 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3024 struct sockaddr_in sock;
3028 /* get my host name */
3029 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3030 { DEBUG(0,("gethostname failed\n")); return -1; }
3033 if ((hp = Get_Hostbyname(host_name)) == 0)
3035 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3039 bzero((char *)&sock,sizeof(sock));
3040 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3041 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3042 sock.sin_len = sizeof(sock);
3044 sock.sin_port = htons( port );
3045 sock.sin_family = hp->h_addrtype;
3046 sock.sin_addr.s_addr = socket_addr;
3047 res = socket(hp->h_addrtype, type, 0);
3049 { DEBUG(0,("socket failed\n")); return -1; }
3053 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3056 /* now we've got a socket - we need to bind it */
3057 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3060 if (port == SMB_PORT || port == NMB_PORT)
3061 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
3062 port,socket_addr,strerror(errno)));
3065 if (dlevel > 0 && port < 1000)
3068 if (port >= 1000 && port < 9000)
3069 return(open_socket_in(type,port+1,dlevel,socket_addr));
3074 DEBUG(3,("bind succeeded on port %d\n",port));
3080 /****************************************************************************
3081 create an outgoing socket
3082 **************************************************************************/
3083 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3085 struct sockaddr_in sock_out;
3087 int connect_loop = 250; /* 250 milliseconds */
3088 int loops = (timeout * 1000) / connect_loop;
3090 /* create a socket to write to */
3091 res = socket(PF_INET, type, 0);
3093 { DEBUG(0,("socket error\n")); return -1; }
3095 if (type != SOCK_STREAM) return(res);
3097 bzero((char *)&sock_out,sizeof(sock_out));
3098 putip((char *)&sock_out.sin_addr,(char *)addr);
3100 sock_out.sin_port = htons( port );
3101 sock_out.sin_family = PF_INET;
3103 /* set it non-blocking */
3104 set_blocking(res,False);
3106 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3108 /* and connect it to the destination */
3110 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3112 /* Some systems return EAGAIN when they mean EINPROGRESS */
3113 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3114 errno == EAGAIN) && loops--) {
3115 msleep(connect_loop);
3119 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3121 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3127 if (ret < 0 && errno == EISCONN) {
3134 DEBUG(1,("error connecting to %s:%d (%s)\n",
3135 inet_ntoa(*addr),port,strerror(errno)));
3139 /* set it blocking again */
3140 set_blocking(res,True);
3146 /****************************************************************************
3147 interpret a protocol description string, with a default
3148 ****************************************************************************/
3149 int interpret_protocol(char *str,int def)
3151 if (strequal(str,"NT1"))
3152 return(PROTOCOL_NT1);
3153 if (strequal(str,"LANMAN2"))
3154 return(PROTOCOL_LANMAN2);
3155 if (strequal(str,"LANMAN1"))
3156 return(PROTOCOL_LANMAN1);
3157 if (strequal(str,"CORE"))
3158 return(PROTOCOL_CORE);
3159 if (strequal(str,"COREPLUS"))
3160 return(PROTOCOL_COREPLUS);
3161 if (strequal(str,"CORE+"))
3162 return(PROTOCOL_COREPLUS);
3164 DEBUG(0,("Unrecognised protocol level %s\n",str));
3169 /****************************************************************************
3170 interpret a security level
3171 ****************************************************************************/
3172 int interpret_security(char *str,int def)
3174 if (strequal(str,"SERVER"))
3176 if (strequal(str,"USER"))
3178 if (strequal(str,"SHARE"))
3181 DEBUG(0,("Unrecognised security level %s\n",str));
3187 /****************************************************************************
3188 interpret an internet address or name into an IP address in 4 byte form
3189 ****************************************************************************/
3190 uint32 interpret_addr(char *str)
3195 BOOL pure_address = True;
3197 if (strcmp(str,"0.0.0.0") == 0) return(0);
3198 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3200 for (i=0; pure_address && str[i]; i++)
3201 if (!(isdigit(str[i]) || str[i] == '.'))
3202 pure_address = False;
3204 /* if it's in the form of an IP address then get the lib to interpret it */
3206 res = inet_addr(str);
3208 /* otherwise assume it's a network name of some sort and use
3210 if ((hp = Get_Hostbyname(str)) == 0) {
3211 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3214 putip((char *)&res,(char *)hp->h_addr);
3217 if (res == (uint32)-1) return(0);
3222 /*******************************************************************
3223 a convenient addition to interpret_addr()
3224 ******************************************************************/
3225 struct in_addr *interpret_addr2(char *str)
3227 static struct in_addr ret;
3228 uint32 a = interpret_addr(str);
3233 /*******************************************************************
3234 check if an IP is the 0.0.0.0
3235 ******************************************************************/
3236 BOOL zero_ip(struct in_addr ip)
3239 putip((char *)&a,(char *)&ip);
3244 /*******************************************************************
3245 matchname - determine if host name matches IP address
3246 ******************************************************************/
3247 static BOOL matchname(char *remotehost,struct in_addr addr)
3252 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3253 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3258 * Make sure that gethostbyname() returns the "correct" host name.
3259 * Unfortunately, gethostbyname("localhost") sometimes yields
3260 * "localhost.domain". Since the latter host name comes from the
3261 * local DNS, we just have to trust it (all bets are off if the local
3262 * DNS is perverted). We always check the address list, though.
3265 if (strcasecmp(remotehost, hp->h_name)
3266 && strcasecmp(remotehost, "localhost")) {
3267 DEBUG(0,("host name/name mismatch: %s != %s",
3268 remotehost, hp->h_name));
3272 /* Look up the host address in the address list we just got. */
3273 for (i = 0; hp->h_addr_list[i]; i++) {
3274 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3279 * The host name does not map to the original host address. Perhaps
3280 * someone has compromised a name server. More likely someone botched
3281 * it, but that could be dangerous, too.
3284 DEBUG(0,("host name/address mismatch: %s != %s",
3285 inet_ntoa(addr), hp->h_name));
3289 /*******************************************************************
3290 Reset the 'done' variables so after a client process is created
3291 from a fork call these calls will be re-done. This should be
3292 expanded if more variables need reseting.
3293 ******************************************************************/
3295 static BOOL global_client_name_done = False;
3296 static BOOL global_client_addr_done = False;
3298 void reset_globals_after_fork()
3300 global_client_name_done = False;
3301 global_client_addr_done = False;
3304 /*******************************************************************
3305 return the DNS name of the client
3306 ******************************************************************/
3307 char *client_name(void)
3311 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3312 int length = sizeof(sa);
3313 static pstring name_buf;
3316 if (global_client_name_done)
3319 strcpy(name_buf,"UNKNOWN");
3321 if (getpeername(Client, &sa, &length) < 0) {
3322 DEBUG(0,("getpeername failed\n"));
3326 /* Look up the remote host name. */
3327 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3328 sizeof(sockin->sin_addr),
3330 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3331 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3333 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3334 if (!matchname(name_buf, sockin->sin_addr)) {
3335 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3336 strcpy(name_buf,"UNKNOWN");
3339 global_client_name_done = True;
3343 /*******************************************************************
3344 return the IP addr of the client as a string
3345 ******************************************************************/
3346 char *client_addr(void)
3350 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3351 int length = sizeof(sa);
3352 static fstring addr_buf;
3354 if (global_client_addr_done)
3357 strcpy(addr_buf,"0.0.0.0");
3359 if (getpeername(Client, &sa, &length) < 0) {
3360 DEBUG(0,("getpeername failed\n"));
3364 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3366 global_client_addr_done = True;
3370 /*******************************************************************
3371 sub strings with useful parameters
3372 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3373 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3374 ********************************************************************/
3375 void standard_sub_basic(char *str)
3379 struct passwd *pass;
3381 for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3385 case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3386 string_sub(p,"%G",gidtoname(pass->pw_gid));
3390 case 'I' : string_sub(p,"%I",client_addr()); break;
3391 case 'L' : string_sub(p,"%L",local_machine); break;
3392 case 'M' : string_sub(p,"%M",client_name()); break;
3393 case 'R' : string_sub(p,"%R",remote_proto); break;
3394 case 'T' : string_sub(p,"%T",timestring()); break;
3395 case 'U' : string_sub(p,"%U",sesssetup_user); break;
3396 case 'a' : string_sub(p,"%a",remote_arch); break;
3397 case 'd' : sprintf(pidstr,"%d",(int)getpid());
3398 string_sub(p,"%d",pidstr);
3400 case 'h' : string_sub(p,"%h",myhostname); break;
3401 case 'm' : string_sub(p,"%m",remote_machine); break;
3402 case 'v' : string_sub(p,"%v",VERSION); break;
3403 case '\0' : p++; break; /* don't run off end if last character is % */
3404 default : p+=2; break;
3410 /*******************************************************************
3411 are two IPs on the same subnet?
3412 ********************************************************************/
3413 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3415 uint32 net1,net2,nmask;
3417 nmask = ntohl(mask.s_addr);
3418 net1 = ntohl(ip1.s_addr);
3419 net2 = ntohl(ip2.s_addr);
3421 return((net1 & nmask) == (net2 & nmask));
3425 /*******************************************************************
3426 write a string in unicoode format
3427 ********************************************************************/
3428 int PutUniCode(char *dst,char *src)
3432 dst[ret++] = src[0];
3441 /****************************************************************************
3442 a wrapper for gethostbyname() that tries with all lower and all upper case
3443 if the initial name fails
3444 ****************************************************************************/
3445 struct hostent *Get_Hostbyname(char *name)
3447 char *name2 = strdup(name);
3448 struct hostent *ret;
3452 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3456 if (!isalnum(*name2))
3462 ret = sys_gethostbyname(name2);
3469 /* try with all lowercase */
3471 ret = sys_gethostbyname(name2);
3478 /* try with all uppercase */
3480 ret = sys_gethostbyname(name2);
3487 /* nothing works :-( */
3493 /****************************************************************************
3494 check if a process exists. Does this work on all unixes?
3495 ****************************************************************************/
3496 BOOL process_exists(int pid)
3500 sprintf(s,"/proc/%d",pid);
3501 return(directory_exist(s,NULL));
3504 static BOOL tested=False;
3505 static BOOL ok=False;
3509 sprintf(s,"/proc/%05d",(int)getpid());
3510 ok = file_exist(s,NULL);
3513 sprintf(s,"/proc/%05d",pid);
3514 return(file_exist(s,NULL));
3518 /* CGH 8/16/96 - added ESRCH test */
3519 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3524 /*******************************************************************
3525 turn a uid into a user name
3526 ********************************************************************/
3527 char *uidtoname(int uid)
3529 static char name[40];
3530 struct passwd *pass = getpwuid(uid);
3531 if (pass) return(pass->pw_name);
3532 sprintf(name,"%d",uid);
3536 /*******************************************************************
3537 turn a gid into a group name
3538 ********************************************************************/
3539 char *gidtoname(int gid)
3541 static char name[40];
3542 struct group *grp = getgrgid(gid);
3543 if (grp) return(grp->gr_name);
3544 sprintf(name,"%d",gid);
3548 /*******************************************************************
3550 ********************************************************************/
3551 void BlockSignals(BOOL block,int signum)
3554 int block_mask = sigmask(signum);
3555 static int oldmask = 0;
3557 oldmask = sigblock(block_mask);
3559 sigsetmask(oldmask);
3560 #elif defined(USE_SIGPROCMASK)
3563 sigaddset(&set,signum);
3564 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3569 /*******************************************************************
3570 my own panic function - not suitable for general use
3571 ********************************************************************/
3572 void ajt_panic(void)
3574 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3579 #define DIRECT direct
3581 #define DIRECT dirent
3584 /*******************************************************************
3585 a readdir wrapper which just returns the file name
3586 also return the inode number if requested
3587 ********************************************************************/
3588 char *readdirname(void *p)
3593 if (!p) return(NULL);
3595 ptr = (struct DIRECT *)readdir(p);
3596 if (!ptr) return(NULL);
3598 dname = ptr->d_name;
3601 if (telldir(p) < 0) return(NULL);
3605 /* this handles a broken compiler setup, causing a mixture
3606 of BSD and SYSV headers and libraries */
3608 static BOOL broken_readdir = False;
3609 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3611 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3612 broken_readdir = True;
3622 unix_to_dos(buf, True);
3630 * Utility function used to decide if the last component
3631 * of a path matches a (possibly wildcarded) entry in a namelist.
3634 BOOL is_in_path(char *name, name_compare_entry *namelist)
3636 pstring last_component;
3639 DEBUG(5, ("is_in_path: %s\n", name));
3641 /* if we have no list it's obviously not in the path */
3642 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3644 DEBUG(5,("is_in_path: no name list.\n"));
3648 /* Get the last component of the unix name. */
3649 p = strrchr(name, '/');
3650 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3651 last_component[sizeof(last_component)-1] = '\0';
3653 for(; namelist->name != NULL; namelist++)
3655 if(namelist->is_wild)
3657 /* look for a wildcard match. */
3658 if (mask_match(last_component, namelist->name, case_sensitive, False))
3660 DEBUG(5,("is_in_path: mask match succeeded\n"));
3666 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3667 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3669 DEBUG(5,("is_in_path: match succeeded\n"));
3674 DEBUG(5,("is_in_path: match not found\n"));
3680 * Strip a '/' separated list into an array of
3681 * name_compare_enties structures suitable for
3682 * passing to is_in_path(). We do this for
3683 * speed so we can pre-parse all the names in the list
3684 * and don't do it for each call to is_in_path().
3685 * namelist is modified here and is assumed to be
3686 * a copy owned by the caller.
3687 * We also check if the entry contains a wildcard to
3688 * remove a potentially expensive call to mask_match
3692 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3695 char *nameptr = namelist;
3696 int num_entries = 0;
3699 (*ppname_array) = NULL;
3701 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3704 /* We need to make two passes over the string. The
3705 first to count the number of elements, the second
3710 if ( *nameptr == '/' )
3712 /* cope with multiple (useless) /s) */
3716 /* find the next / */
3717 name_end = strchr(nameptr, '/');
3719 /* oops - the last check for a / didn't find one. */
3720 if (name_end == NULL)
3723 /* next segment please */
3724 nameptr = name_end + 1;
3728 if(num_entries == 0)
3731 if(( (*ppname_array) = (name_compare_entry *)malloc(
3732 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3734 DEBUG(0,("set_namearray: malloc fail\n"));
3738 /* Now copy out the names */
3743 if ( *nameptr == '/' )
3745 /* cope with multiple (useless) /s) */
3749 /* find the next / */
3750 if ((name_end = strchr(nameptr, '/')) != NULL)
3755 /* oops - the last check for a / didn't find one. */
3756 if(name_end == NULL)
3759 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3760 (strchr( nameptr, '*')!=NULL));
3761 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3763 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3767 /* next segment please */
3768 nameptr = name_end + 1;
3772 (*ppname_array)[i].name = NULL;
3777 /****************************************************************************
3778 routine to free a namearray.
3779 ****************************************************************************/
3781 void free_namearray(name_compare_entry *name_array)
3786 if(name_array->name != NULL)
3787 free(name_array->name);
3789 free((char *)name_array);
3792 /****************************************************************************
3793 routine to do file locking
3794 ****************************************************************************/
3795 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3802 uint32 mask = 0xC0000000;
3804 /* make sure the count is reasonable, we might kill the lockd otherwise */
3807 /* the offset is often strange - remove 2 of its bits if either of
3808 the top two bits are set. Shift the top ones by two bits. This
3809 still allows OLE2 apps to operate, but should stop lockd from
3811 if ((offset & mask) != 0)
3812 offset = (offset & ~mask) | ((offset & mask) >> 2);
3814 uint32 mask = ((unsigned)1<<31);
3816 /* interpret negative counts as large numbers */
3820 /* no negative offsets */
3823 /* count + offset must be in range */
3824 while ((offset < 0 || (offset + count < 0)) && mask)
3832 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3835 lock.l_whence = SEEK_SET;
3836 lock.l_start = (int)offset;
3837 lock.l_len = (int)count;
3842 ret = fcntl(fd,op,&lock);
3845 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3851 (lock.l_type != F_UNLCK) &&
3852 (lock.l_pid != 0) &&
3853 (lock.l_pid != getpid()))
3855 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3859 /* it must be not locked or locked by me */
3863 /* a lock set or unset */
3866 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3867 offset,count,op,type,strerror(errno)));
3869 /* perhaps it doesn't support this sort of locking?? */
3870 if (errno == EINVAL)
3872 DEBUG(3,("locking not supported? returning True\n"));
3879 /* everything went OK */
3880 DEBUG(5,("Lock call successful\n"));
3888 /*******************************************************************
3889 lock a file - returning a open file descriptor or -1 on failure
3890 The timeout is in seconds. 0 means no timeout
3891 ********************************************************************/
3892 int file_lock(char *name,int timeout)
3894 int fd = open(name,O_RDWR|O_CREAT,0666);
3896 if (fd < 0) return(-1);
3899 if (timeout) t = time(NULL);
3900 while (!timeout || (time(NULL)-t < timeout)) {
3901 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3902 msleep(LOCK_RETRY_TIMEOUT);
3910 /*******************************************************************
3911 unlock a file locked by file_lock
3912 ********************************************************************/
3913 void file_unlock(int fd)
3917 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3922 /*******************************************************************
3923 is the name specified one of my netbios names
3924 returns true is it is equal, false otherwise
3925 ********************************************************************/
3926 BOOL is_myname(char *s)
3931 for (n=0; my_netbios_names[n]; n++) {
3932 if (strequal(my_netbios_names[n], s))
3935 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
3939 /*******************************************************************
3940 set the horrid remote_arch string based on an enum.
3941 ********************************************************************/
3942 void set_remote_arch(enum remote_arch_types type)
3948 strcpy(remote_arch, "WfWg");
3951 strcpy(remote_arch, "OS2");
3954 strcpy(remote_arch, "Win95");
3957 strcpy(remote_arch, "WinNT");
3960 strcpy(remote_arch,"Samba");
3963 ra_type = RA_UNKNOWN;
3964 strcpy(remote_arch, "UNKNOWN");
3969 /*******************************************************************
3970 Get the remote_arch type.
3971 ********************************************************************/
3972 enum remote_arch_types get_remote_arch()