2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1995
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.
31 int Protocol = PROTOCOL_COREPLUS;
33 /* a default finfo structure to ensure all fields are sensible */
34 file_info def_finfo = {-1,0,0,0,0,0,0,""};
36 /* these are some file handles where debug info will be stored */
39 /* the client file descriptor */
42 /* info on the client */
43 struct from_host Client_info=
44 {"UNKNOWN","0.0.0.0",NULL};
46 /* the last IP received from */
47 struct in_addr lastip;
49 /* the last port received from */
55 case handling on filenames
57 int case_default = CASE_LOWER;
60 /* size of reads during a direct file to file transfer */
61 int ReadSize = 16*1024;
63 pstring debugf = "/tmp/log.samba";
66 /* the following control case operations - they are put here so the
67 client can link easily */
70 BOOL use_mangled_map = False;
71 BOOL short_case_preserve;
74 fstring remote_machine="";
75 fstring local_machine="";
76 fstring remote_arch="UNKNOWN";
77 fstring remote_proto="UNKNOWN";
78 pstring myhostname="";
79 pstring user_socket_options="";
80 pstring sesssetup_user="";
83 static char *filename_dos(char *path,char *buf);
85 static BOOL stdout_logging = False;
88 /*******************************************************************
89 get ready for syslog stuff
90 ******************************************************************/
91 void setup_logging(char *pname,BOOL interactive)
95 char *p = strrchr(pname,'/');
97 openlog(pname, LOG_PID, LOG_DAEMON);
101 stdout_logging = True;
107 BOOL append_log=False;
110 /****************************************************************************
112 ****************************************************************************/
113 void reopen_logs(void)
120 strcpy(fname,debugf);
121 if (lp_loaded() && (*lp_logfile()))
122 strcpy(fname,lp_logfile());
124 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
126 strcpy(debugf,fname);
127 if (dbf) fclose(dbf);
129 dbf = fopen(debugf,"a");
131 dbf = fopen(debugf,"w");
132 if (dbf) setbuf(dbf,NULL);
146 /*******************************************************************
147 check if the log has grown too big
148 ********************************************************************/
149 static void check_log_size(void)
151 static int debug_count=0;
155 if (debug_count++ < 100) return;
157 maxlog = lp_max_log_size() * 1024;
158 if (!dbf || maxlog <= 0) return;
160 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
161 fclose(dbf); dbf = NULL;
163 if (dbf && file_size(debugf) > maxlog) {
165 fclose(dbf); dbf = NULL;
166 sprintf(name,"%s.old",debugf);
167 sys_rename(debugf,name);
175 /*******************************************************************
176 write an debug message on the debugfile. This is called by the DEBUG
178 ********************************************************************/
180 int Debug1(char *format_str, ...)
190 if (stdout_logging) {
192 va_start(ap, format_str);
195 format_str = va_arg(ap,char *);
197 vfprintf(dbf,format_str,ap);
203 if (!lp_syslog_only())
208 dbf = fopen(debugf,"w");
217 if (syslog_level < lp_syslog())
220 * map debug levels to syslog() priorities
221 * note that not all DEBUG(0, ...) calls are
224 static int priority_map[] = {
233 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
235 priority = LOG_DEBUG;
237 priority = priority_map[syslog_level];
240 va_start(ap, format_str);
243 format_str = va_arg(ap,char *);
245 vsprintf(msgbuf, format_str, ap);
249 syslog(priority, "%s", msgbuf);
254 if (!lp_syslog_only())
258 va_start(ap, format_str);
261 format_str = va_arg(ap,char *);
263 vfprintf(dbf,format_str,ap);
273 /****************************************************************************
274 routine to do file locking
275 ****************************************************************************/
276 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
283 uint32 mask = 0xC0000000;
285 /* make sure the count is reasonable, we might kill the lockd otherwise */
288 /* the offset is often strange - remove 2 of its bits if either of
289 the top two bits are set. Shift the top ones by two bits. This
290 still allows OLE2 apps to operate, but should stop lockd from
292 if ((offset & mask) != 0)
293 offset = (offset & ~mask) | ((offset & mask) >> 2);
295 unsigned long mask = ((unsigned)1<<31);
297 /* interpret negative counts as large numbers */
301 /* no negative offsets */
304 /* count + offset must be in range */
305 while ((offset < 0 || (offset + count < 0)) && mask)
313 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
316 lock.l_whence = SEEK_SET;
317 lock.l_start = (int)offset;
318 lock.l_len = (int)count;
323 ret = fcntl(fd,op,&lock);
326 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
332 (lock.l_type != F_UNLCK) &&
334 (lock.l_pid != getpid()))
336 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
340 /* it must be not locked or locked by me */
344 /* a lock set or unset */
347 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
348 offset,count,op,type,strerror(errno)));
350 /* perhaps it doesn't support this sort of locking?? */
353 DEBUG(3,("locking not supported? returning True\n"));
360 /* everything went OK */
361 DEBUG(5,("Lock call successful\n"));
369 /*******************************************************************
370 lock a file - returning a open file descriptor or -1 on failure
371 The timeout is in seconds. 0 means no timeout
372 ********************************************************************/
373 int file_lock(char *name,int timeout)
375 int fd = open(name,O_RDWR|O_CREAT,0666);
377 if (fd < 0) return(-1);
380 if (timeout) t = time(NULL);
381 while (!timeout || (time(NULL)-t < timeout)) {
382 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
383 msleep(LOCK_RETRY_TIMEOUT);
391 /*******************************************************************
392 unlock a file locked by file_lock
393 ********************************************************************/
394 void file_unlock(int fd)
398 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
403 /****************************************************************************
404 determine if a file descriptor is in fact a socket
405 ****************************************************************************/
406 BOOL is_a_socket(int fd)
410 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
414 static char *last_ptr=NULL;
416 /****************************************************************************
417 Get the next token from a string, return False if none found
418 handles double-quotes.
419 Based on a routine by GJC@VILLAGE.COM.
420 Extensively modified by Andrew.Tridgell@anu.edu.au
421 ****************************************************************************/
422 BOOL next_token(char **ptr,char *buff,char *sep)
427 if (!ptr) ptr = &last_ptr;
428 if (!ptr) return(False);
432 /* default to simple separators */
433 if (!sep) sep = " \t\n\r";
435 /* find the first non sep char */
436 while(*s && strchr(sep,*s)) s++;
439 if (! *s) return(False);
441 /* copy over the token */
442 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
450 *ptr = (*s) ? s+1 : s;
457 /****************************************************************************
458 Convert list of tokens to array; dependent on above routine.
459 Uses last_ptr from above - bit of a hack.
460 ****************************************************************************/
461 char **toktocliplist(int *ctok, char *sep)
467 if (!sep) sep = " \t\n\r";
469 while(*s && strchr(sep,*s)) s++;
472 if (!*s) return(NULL);
476 while(*s && (!strchr(sep,*s))) s++;
477 while(*s && strchr(sep,*s)) *s++=0;
483 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
495 /*******************************************************************
496 safely copies memory, ensuring no overlap problems.
497 this is only used if the machine does not have it's own memmove().
498 this is not the fastest algorithm in town, but it will do for our
500 ********************************************************************/
501 void *MemMove(void *dest,void *src,int size)
505 if (dest==src || !size) return(dest);
507 d = (unsigned long)dest;
508 s = (unsigned long)src;
510 if ((d >= (s+size)) || (s >= (d+size))) {
512 memcpy(dest,src,size);
518 /* we can forward copy */
519 if (s-d >= sizeof(int) &&
520 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
521 /* do it all as words */
522 int *idest = (int *)dest;
523 int *isrc = (int *)src;
525 for (i=0;i<size;i++) idest[i] = isrc[i];
528 char *cdest = (char *)dest;
529 char *csrc = (char *)src;
530 for (i=0;i<size;i++) cdest[i] = csrc[i];
535 /* must backward copy */
536 if (d-s >= sizeof(int) &&
537 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
538 /* do it all as words */
539 int *idest = (int *)dest;
540 int *isrc = (int *)src;
542 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
545 char *cdest = (char *)dest;
546 char *csrc = (char *)src;
547 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
555 /****************************************************************************
556 prompte a dptr (to make it recently used)
557 ****************************************************************************/
558 void array_promote(char *array,int elsize,int element)
564 p = (char *)malloc(elsize);
568 DEBUG(5,("Ahh! Can't malloc\n"));
571 memcpy(p,array + element * elsize, elsize);
572 memmove(array + elsize,array,elsize*element);
573 memcpy(array,p,elsize);
577 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
586 } socket_options[] = {
587 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
588 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
589 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
591 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
593 #ifdef IPTOS_LOWDELAY
594 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
596 #ifdef IPTOS_THROUGHPUT
597 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
600 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
603 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
606 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
609 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
615 /****************************************************************************
616 set user socket options
617 ****************************************************************************/
618 void set_socket_options(int fd, char *options)
622 while (next_token(&options,tok," \t,"))
627 BOOL got_value = False;
629 if ((p = strchr(tok,'=')))
636 for (i=0;socket_options[i].name;i++)
637 if (strequal(socket_options[i].name,tok))
640 if (!socket_options[i].name)
642 DEBUG(0,("Unknown socket option %s\n",tok));
646 switch (socket_options[i].opttype)
650 ret = setsockopt(fd,socket_options[i].level,
651 socket_options[i].option,(char *)&value,sizeof(int));
656 DEBUG(0,("syntax error - %s does not take a value\n",tok));
659 int on = socket_options[i].value;
660 ret = setsockopt(fd,socket_options[i].level,
661 socket_options[i].option,(char *)&on,sizeof(int));
667 DEBUG(0,("Failed to set socket option %s\n",tok));
673 /****************************************************************************
674 close the socket communication
675 ****************************************************************************/
676 void close_sockets(void )
682 /****************************************************************************
683 determine whether we are in the specified group
684 ****************************************************************************/
685 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
689 if (group == current_gid) return(True);
691 for (i=0;i<ngroups;i++)
692 if (group == groups[i])
698 /****************************************************************************
699 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
700 ****************************************************************************/
701 char *StrCpy(char *dest,char *src)
706 /* I don't want to get lazy with these ... */
708 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
713 if (!dest) return(NULL);
718 while ((*d++ = *src++)) ;
722 /****************************************************************************
723 line strncpy but always null terminates. Make sure there is room!
724 ****************************************************************************/
725 char *StrnCpy(char *dest,const char *src,int n)
728 if (!dest) return(NULL);
733 while (n-- && (*d++ = *src++)) ;
739 /*******************************************************************
740 copy an IP address from one buffer to another
741 ********************************************************************/
742 void putip(void *dest,void *src)
748 /****************************************************************************
749 interpret the weird netbios "name". Return the name type
750 ****************************************************************************/
751 static int name_interpret(char *in,char *out)
754 int len = (*in++) / 2;
758 if (len > 30 || len<1) return(0);
762 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
766 *out = ((in[0]-'A')<<4) + (in[1]-'A');
774 /* Handle any scope names */
777 *out++ = '.'; /* Scope names are separated by periods */
778 len = *(unsigned char *)in++;
779 StrnCpy(out, in, len);
788 /****************************************************************************
789 mangle a name into netbios format
790 ****************************************************************************/
791 int name_mangle(char *In,char *Out,char name_type)
795 char *in = (char *)&buf[0];
796 char *out = (char *)Out;
801 StrnCpy(name,In,sizeof(name)-1);
802 sprintf(buf,"%-15.15s%c",name,name_type);
805 memset(&buf[1],0,16);
810 char c = toupper(in[i]);
811 out[i*2] = (c>>4) + 'A';
812 out[i*2+1] = (c & 0xF) + 'A';
820 p = strchr(label, '.');
822 p = label + strlen(label);
824 memcpy(out, label, p - label);
826 label += p - label + (*p == '.');
829 return(name_len(Out));
833 /*******************************************************************
834 check if a file exists
835 ********************************************************************/
836 BOOL file_exist(char *fname,struct stat *sbuf)
839 if (!sbuf) sbuf = &st;
841 if (sys_stat(fname,sbuf) != 0)
844 return(S_ISREG(sbuf->st_mode));
847 /*******************************************************************
848 check a files mod time
849 ********************************************************************/
850 time_t file_modtime(char *fname)
854 if (sys_stat(fname,&st) != 0)
860 /*******************************************************************
861 check if a directory exists
862 ********************************************************************/
863 BOOL directory_exist(char *dname,struct stat *st)
868 if (sys_stat(dname,st) != 0)
871 return(S_ISDIR(st->st_mode));
874 /*******************************************************************
875 returns the size in bytes of the named file
876 ********************************************************************/
877 uint32 file_size(char *file_name)
881 sys_stat(file_name,&buf);
885 /*******************************************************************
886 return a string representing an attribute for a file
887 ********************************************************************/
888 char *attrib_string(int mode)
890 static char attrstr[10];
894 if (mode & aVOLID) strcat(attrstr,"V");
895 if (mode & aDIR) strcat(attrstr,"D");
896 if (mode & aARCH) strcat(attrstr,"A");
897 if (mode & aHIDDEN) strcat(attrstr,"H");
898 if (mode & aSYSTEM) strcat(attrstr,"S");
899 if (mode & aRONLY) strcat(attrstr,"R");
905 /*******************************************************************
906 case insensitive string compararison
907 ********************************************************************/
908 int StrCaseCmp(char *s, char *t)
910 for (; tolower(*s) == tolower(*t); ++s, ++t)
913 return tolower(*s) - tolower(*t);
916 /*******************************************************************
917 case insensitive string compararison, length limited
918 ********************************************************************/
919 int StrnCaseCmp(char *s, char *t, int n)
921 while (n-- && *s && *t) {
922 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
925 if (n) return(tolower(*s) - tolower(*t));
930 /*******************************************************************
932 ********************************************************************/
933 BOOL strequal(char *s1,char *s2)
935 if (s1 == s2) return(True);
936 if (!s1 || !s2) return(False);
938 return(StrCaseCmp(s1,s2)==0);
941 /*******************************************************************
942 compare 2 strings up to and including the nth char.
943 ******************************************************************/
944 BOOL strnequal(char *s1,char *s2,int n)
946 if (s1 == s2) return(True);
947 if (!s1 || !s2 || !n) return(False);
949 return(StrnCaseCmp(s1,s2,n)==0);
952 /*******************************************************************
953 compare 2 strings (case sensitive)
954 ********************************************************************/
955 BOOL strcsequal(char *s1,char *s2)
957 if (s1 == s2) return(True);
958 if (!s1 || !s2) return(False);
960 return(strcmp(s1,s2)==0);
964 /*******************************************************************
965 convert a string to lower case
966 ********************************************************************/
967 void strlower(char *s)
972 if (is_shift_jis (*s)) {
974 } else if (is_kana (*s)) {
989 /*******************************************************************
990 convert a string to upper case
991 ********************************************************************/
992 void strupper(char *s)
997 if (is_shift_jis (*s)) {
999 } else if (is_kana (*s)) {
1014 /*******************************************************************
1015 convert a string to "normal" form
1016 ********************************************************************/
1017 void strnorm(char *s)
1019 if (case_default == CASE_UPPER)
1025 /*******************************************************************
1026 check if a string is in "normal" case
1027 ********************************************************************/
1028 BOOL strisnormal(char *s)
1030 if (case_default == CASE_UPPER)
1031 return(!strhaslower(s));
1033 return(!strhasupper(s));
1037 /****************************************************************************
1039 ****************************************************************************/
1040 void string_replace(char *s,char oldc,char newc)
1045 if (is_shift_jis (*s)) {
1047 } else if (is_kana (*s)) {
1062 /****************************************************************************
1063 make a file into unix format
1064 ****************************************************************************/
1065 void unix_format(char *fname)
1068 string_replace(fname,'\\','/');
1070 dos2unix_format(fname, True);
1075 strcpy(namecopy,fname);
1077 strcat(fname,namecopy);
1081 /****************************************************************************
1082 make a file into dos format
1083 ****************************************************************************/
1084 void dos_format(char *fname)
1087 unix2dos_format(fname, True);
1089 string_replace(fname,'/','\\');
1093 /*******************************************************************
1094 show a smb message structure
1095 ********************************************************************/
1096 void show_msg(char *buf)
1103 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1105 (int)CVAL(buf,smb_com),
1106 (int)CVAL(buf,smb_rcls),
1107 (int)CVAL(buf,smb_reh),
1108 (int)SVAL(buf,smb_err),
1109 (int)CVAL(buf,smb_flg),
1110 (int)SVAL(buf,smb_flg2)));
1111 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1112 (int)SVAL(buf,smb_tid),
1113 (int)SVAL(buf,smb_pid),
1114 (int)SVAL(buf,smb_uid),
1115 (int)SVAL(buf,smb_mid),
1116 (int)CVAL(buf,smb_wct)));
1117 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1118 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1119 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1120 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1121 DEBUG(5,("smb_bcc=%d\n",bcc));
1122 if (DEBUGLEVEL < 10)
1124 for (i=0;i<MIN(bcc,128);i++)
1125 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1129 /*******************************************************************
1130 return the length of an smb packet
1131 ********************************************************************/
1132 int smb_len(char *buf)
1134 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1137 /*******************************************************************
1138 set the length of an smb packet
1139 ********************************************************************/
1140 void _smb_setlen(char *buf,int len)
1143 buf[1] = (len&0x10000)>>16;
1144 buf[2] = (len&0xFF00)>>8;
1148 /*******************************************************************
1149 set the length and marker of an smb packet
1150 ********************************************************************/
1151 void smb_setlen(char *buf,int len)
1153 _smb_setlen(buf,len);
1161 /*******************************************************************
1162 setup the word count and byte count for a smb message
1163 ********************************************************************/
1164 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1167 bzero(buf + smb_size,num_words*2 + num_bytes);
1168 CVAL(buf,smb_wct) = num_words;
1169 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1170 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1171 return (smb_size + num_words*2 + num_bytes);
1174 /*******************************************************************
1175 return the number of smb words
1176 ********************************************************************/
1177 int smb_numwords(char *buf)
1179 return (CVAL(buf,smb_wct));
1182 /*******************************************************************
1183 return the size of the smb_buf region of a message
1184 ********************************************************************/
1185 int smb_buflen(char *buf)
1187 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1190 /*******************************************************************
1191 return a pointer to the smb_buf data area
1192 ********************************************************************/
1193 int smb_buf_ofs(char *buf)
1195 return (smb_size + CVAL(buf,smb_wct)*2);
1198 /*******************************************************************
1199 return a pointer to the smb_buf data area
1200 ********************************************************************/
1201 char *smb_buf(char *buf)
1203 return (buf + smb_buf_ofs(buf));
1206 /*******************************************************************
1207 return the SMB offset into an SMB buffer
1208 ********************************************************************/
1209 int smb_offset(char *p,char *buf)
1211 return(PTR_DIFF(p,buf+4));
1215 /*******************************************************************
1216 skip past some strings in a buffer
1217 ********************************************************************/
1218 char *skip_string(char *buf,int n)
1221 buf += strlen(buf) + 1;
1225 /*******************************************************************
1226 trim the specified elements off the front and back of a string
1227 ********************************************************************/
1228 BOOL trim_string(char *s,char *front,char *back)
1231 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1237 if (!(*p = p[strlen(front)]))
1242 while (back && *back && strlen(s) >= strlen(back) &&
1243 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1246 s[strlen(s)-strlen(back)] = 0;
1252 /*******************************************************************
1253 reduce a file name, removing .. elements.
1254 ********************************************************************/
1255 void dos_clean_name(char *s)
1259 DEBUG(3,("dos_clean_name [%s]\n",s));
1261 /* remove any double slashes */
1262 string_sub(s, "\\\\", "\\");
1264 while ((p = strstr(s,"\\..\\")) != NULL)
1271 if ((p=strrchr(s,'\\')) != NULL)
1278 trim_string(s,NULL,"\\..");
1280 string_sub(s, "\\.\\", "\\");
1283 /*******************************************************************
1284 reduce a file name, removing .. elements.
1285 ********************************************************************/
1286 void unix_clean_name(char *s)
1290 DEBUG(3,("unix_clean_name [%s]\n",s));
1292 /* remove any double slashes */
1293 string_sub(s, "//","/");
1295 while ((p = strstr(s,"/../")) != NULL)
1302 if ((p=strrchr(s,'/')) != NULL)
1309 trim_string(s,NULL,"/..");
1313 /*******************************************************************
1314 a wrapper for the normal chdir() function
1315 ********************************************************************/
1316 int ChDir(char *path)
1319 static pstring LastDir="";
1321 if (strcsequal(path,".")) return(0);
1323 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1324 DEBUG(3,("chdir to %s\n",path));
1325 res = sys_chdir(path);
1327 strcpy(LastDir,path);
1332 /*******************************************************************
1333 return the absolute current directory path. A dumb version.
1334 ********************************************************************/
1335 static char *Dumb_GetWd(char *s)
1338 return ((char *)getcwd(s,sizeof(pstring)));
1340 return ((char *)getwd(s));
1345 /* number of list structures for a caching GetWd function. */
1346 #define MAX_GETWDCACHE (50)
1354 } ino_list[MAX_GETWDCACHE];
1356 BOOL use_getwd_cache=True;
1358 /*******************************************************************
1359 return the absolute current directory path
1360 ********************************************************************/
1361 char *GetWd(char *str)
1364 static BOOL getwd_cache_init = False;
1365 struct stat st, st2;
1370 if (!use_getwd_cache)
1371 return(Dumb_GetWd(str));
1373 /* init the cache */
1374 if (!getwd_cache_init)
1376 getwd_cache_init = True;
1377 for (i=0;i<MAX_GETWDCACHE;i++)
1379 string_init(&ino_list[i].text,"");
1380 ino_list[i].valid = False;
1384 /* Get the inode of the current directory, if this doesn't work we're
1387 if (stat(".",&st) == -1)
1389 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1390 return(Dumb_GetWd(str));
1394 for (i=0; i<MAX_GETWDCACHE; i++)
1395 if (ino_list[i].valid)
1398 /* If we have found an entry with a matching inode and dev number
1399 then find the inode number for the directory in the cached string.
1400 If this agrees with that returned by the stat for the current
1401 directory then all is o.k. (but make sure it is a directory all
1404 if (st.st_ino == ino_list[i].inode &&
1405 st.st_dev == ino_list[i].dev)
1407 if (stat(ino_list[i].text,&st2) == 0)
1409 if (st.st_ino == st2.st_ino &&
1410 st.st_dev == st2.st_dev &&
1411 (st2.st_mode & S_IFMT) == S_IFDIR)
1413 strcpy (str, ino_list[i].text);
1415 /* promote it for future use */
1416 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1421 /* If the inode is different then something's changed,
1422 scrub the entry and start from scratch. */
1423 ino_list[i].valid = False;
1430 /* We don't have the information to hand so rely on traditional methods.
1431 The very slow getcwd, which spawns a process on some systems, or the
1432 not quite so bad getwd. */
1436 DEBUG(0,("Getwd failed, errno %d\n",errno));
1442 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1444 /* add it to the cache */
1445 i = MAX_GETWDCACHE - 1;
1446 string_set(&ino_list[i].text,s);
1447 ino_list[i].dev = st.st_dev;
1448 ino_list[i].inode = st.st_ino;
1449 ino_list[i].valid = True;
1451 /* put it at the top of the list */
1452 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1459 /*******************************************************************
1460 reduce a file name, removing .. elements and checking that
1461 it is below dir in the heirachy. This uses GetWd() and so must be run
1462 on the system that has the referenced file system.
1464 widelinks are allowed if widelinks is true
1465 ********************************************************************/
1466 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1468 #ifndef REDUCE_PATHS
1476 BOOL relative = (*s != '/');
1478 *dir2 = *wd = *basename = *newname = 0;
1483 /* can't have a leading .. */
1484 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1486 DEBUG(3,("Illegal file name? (%s)\n",s));
1492 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1494 /* remove any double slashes */
1495 string_sub(s,"//","/");
1498 p = strrchr(basename,'/');
1505 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1509 if (ChDir(dir) != 0)
1511 DEBUG(0,("couldn't chdir to %s\n",dir));
1517 DEBUG(0,("couldn't getwd for %s\n",dir));
1523 if (p && (p != basename))
1526 if (strcmp(p+1,".")==0)
1528 if (strcmp(p+1,"..")==0)
1532 if (ChDir(basename) != 0)
1535 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1539 if (!GetWd(newname))
1542 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1546 if (p && (p != basename))
1548 strcat(newname,"/");
1549 strcat(newname,p+1);
1553 int l = strlen(dir2);
1554 if (dir2[l-1] == '/')
1557 if (strncmp(newname,dir2,l) != 0)
1560 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1566 if (newname[l] == '/')
1567 strcpy(s,newname + l + 1);
1569 strcpy(s,newname+l);
1580 DEBUG(3,("reduced to %s\n",s));
1585 /****************************************************************************
1587 ****************************************************************************/
1588 static void expand_one(char *Mask,int len)
1591 while ((p1 = strchr(Mask,'*')) != NULL)
1593 int lfill = (len+1) - strlen(Mask);
1594 int l1= (p1 - Mask);
1597 memset(tmp+l1,'?',lfill);
1598 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1603 /****************************************************************************
1604 expand a wildcard expression, replacing *s with ?s
1605 ****************************************************************************/
1606 void expand_mask(char *Mask,BOOL doext)
1611 BOOL hasdot = False;
1613 BOOL absolute = (*Mask == '\\');
1615 *mbeg = *mext = *dirpart = *filepart = 0;
1617 /* parse the directory and filename */
1618 if (strchr(Mask,'\\'))
1619 dirname_dos(Mask,dirpart);
1621 filename_dos(Mask,filepart);
1623 strcpy(mbeg,filepart);
1624 if ((p1 = strchr(mbeg,'.')) != NULL)
1634 if (strlen(mbeg) > 8)
1636 strcpy(mext,mbeg + 8);
1642 strcpy(mbeg,"????????");
1643 if ((*mext == 0) && doext && !hasdot)
1646 if (strequal(mbeg,"*") && *mext==0)
1654 strcpy(Mask,dirpart);
1655 if (*dirpart || absolute) strcat(Mask,"\\");
1660 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1664 /****************************************************************************
1665 does a string have any uppercase chars in it?
1666 ****************************************************************************/
1667 BOOL strhasupper(char *s)
1672 if (is_shift_jis (*s)) {
1674 } else if (is_kana (*s)) {
1677 if (isupper(*s)) return(True);
1681 if (isupper(*s)) return(True);
1688 /****************************************************************************
1689 does a string have any lowercase chars in it?
1690 ****************************************************************************/
1691 BOOL strhaslower(char *s)
1696 if (is_shift_jis (*s)) {
1698 } else if (is_kana (*s)) {
1701 if (islower(*s)) return(True);
1705 if (islower(*s)) return(True);
1712 /****************************************************************************
1713 find the number of chars in a string
1714 ****************************************************************************/
1715 int count_chars(char *s,char c)
1728 /****************************************************************************
1730 ****************************************************************************/
1731 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1738 if ((mode & aDIR) != 0)
1741 memset(buf+1,' ',11);
1742 if ((p = strchr(mask2,'.')) != NULL)
1745 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1746 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1750 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1752 bzero(buf+21,DIR_STRUCT_SIZE-21);
1753 CVAL(buf,21) = mode;
1754 put_dos_date(buf,22,date);
1755 SSVAL(buf,26,size & 0xFFFF);
1756 SSVAL(buf,28,size >> 16);
1757 StrnCpy(buf+30,fname,12);
1758 if (!case_sensitive)
1760 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1764 /*******************************************************************
1765 close the low 3 fd's and open dev/null in their place
1766 ********************************************************************/
1767 void close_low_fds(void)
1771 close(0); close(1); close(2);
1772 /* try and use up these file descriptors, so silly
1773 library routines writing to stdout etc won't cause havoc */
1775 fd = open("/dev/null",O_RDWR,0);
1776 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1778 DEBUG(0,("Can't open /dev/null\n"));
1782 DEBUG(0,("Didn't get file descriptor %d\n",i));
1789 /****************************************************************************
1791 ****************************************************************************/
1792 int write_socket(int fd,char *buf,int len)
1798 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1799 ret = write_data(fd,buf,len);
1801 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1805 /****************************************************************************
1807 ****************************************************************************/
1808 int read_udp_socket(int fd,char *buf,int len)
1811 struct sockaddr sock;
1814 socklen = sizeof(sock);
1815 bzero((char *)&sock,socklen);
1816 bzero((char *)&lastip,sizeof(lastip));
1817 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1819 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1823 lastip = *(struct in_addr *) &sock.sa_data[2];
1824 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1829 /****************************************************************************
1830 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1832 if SYSV use O_NDELAY
1834 ****************************************************************************/
1835 int set_blocking(int fd, BOOL set)
1839 #define FLAG_TO_SET O_NONBLOCK
1842 #define FLAG_TO_SET O_NDELAY
1844 #define FLAG_TO_SET FNDELAY
1848 if((val = fcntl(fd, F_GETFL, 0))==-1)
1850 if(set) /* Turn blocking on - ie. clear nonblock flag */
1851 val &= ~FLAG_TO_SET;
1854 return fcntl( fd, F_SETFL, val);
1859 /****************************************************************************
1860 Calculate the difference in timeout values. Return 1 if val1 > val2,
1861 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
1862 may be == val1 or val2
1863 ****************************************************************************/
1864 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
1866 int usecdiff = val1->tv_usec - val2->tv_usec;
1867 int secdiff = val1->tv_sec - val2->tv_sec;
1869 usecdiff = 1000000 + usecdiff;
1872 retval->tv_sec = secdiff;
1873 retval->tv_usec = usecdiff;
1878 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
1881 /****************************************************************************
1882 read data from a device with a timout in msec.
1883 mincount = if timeout, minimum to read before returning
1884 maxcount = number to be read.
1885 ****************************************************************************/
1886 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
1892 struct timeval timeout, tval1, tval2, tvaldiff;
1893 int error_limit = 5;
1895 /* just checking .... */
1896 if (maxcnt <= 0) return(0);
1899 time_out = DEFAULT_PIPE_TIMEOUT;
1903 if (mincnt == 0) mincnt = maxcnt;
1905 while (nread < mincnt)
1907 readret = read(fd, buf + nread, maxcnt - nread);
1908 if (readret <= 0) return(nread);
1914 /* Non blocking read */
1916 set_blocking(fd, False);
1917 nread = read_data(fd, buf, mincnt);
1919 nread += read(fd,buf+nread,maxcnt-nread);
1920 if(nread == -1 && errno == EWOULDBLOCK)
1922 set_blocking(fd,True);
1926 /* Most difficult - timeout read */
1927 /* If this is ever called on a disk file and
1928 mincnt is greater then the filesize then
1929 system performance will suffer severely as
1930 select always return true on disk files */
1932 /* Set initial timeout */
1933 timeout.tv_sec = time_out / 1000;
1934 timeout.tv_usec = 1000 * (time_out % 1000);
1936 /* As most UNIXes don't modify the value of timeout
1937 when they return from select we need to get the timeofday (in usec)
1938 now, and also after the select returns so we know
1939 how much time has elapsed */
1942 GetTimeOfDay( &tval1);
1943 nread = 0; /* Number of bytes we have read */
1950 selrtn = sys_select(&fds,&timeout);
1952 /* Check if error */
1958 /* Did we timeout ? */
1960 if (nread < mincnt) return -1;
1964 readret = read(fd, buf+nread, maxcnt-nread);
1965 if (readret == 0 && nread < mincnt) {
1966 /* error_limit should not really be needed, but some systems
1967 do strange things ... I don't want to just continue
1968 indefinately in case we get an infinite loop */
1969 if (error_limit--) continue;
1974 /* force a particular error number for
1976 DEBUG(5,("read gave error %s\n",strerror(errno)));
1983 /* If we have read more than mincnt then return */
1984 if (nread >= mincnt)
1987 /* We need to do another select - but first reduce the
1988 time_out by the amount of time already elapsed - if
1989 this is less than zero then return */
1991 GetTimeOfDay(&tval2);
1992 (void)tval_sub( &tvaldiff, &tval2, &tval1);
1994 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
1995 break; /* We timed out */
1998 /* Save the time of day as we need to do the select
1999 again (saves a system call) */
2003 /* Return the number we got */
2007 /****************************************************************************
2008 read data from the client. Maxtime is in milliseconds
2009 ****************************************************************************/
2010 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2015 struct timeval timeout;
2020 timeout.tv_sec = maxtime / 1000;
2021 timeout.tv_usec = (maxtime % 1000) * 1000;
2023 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2025 if (!FD_ISSET(fd,&fds))
2028 nread = read_udp_socket(fd, buffer, bufsize);
2030 /* return the number got */
2034 /*******************************************************************
2035 find the difference in milliseconds between two struct timeval
2037 ********************************************************************/
2038 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2040 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2041 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2044 /****************************************************************************
2045 send a keepalive packet (rfc1002)
2046 ****************************************************************************/
2047 BOOL send_keepalive(int client)
2049 unsigned char buf[4];
2052 buf[1] = buf[2] = buf[3] = 0;
2054 return(write_data(client,(char *)buf,4) == 4);
2059 /****************************************************************************
2060 read data from the client, reading exactly N bytes.
2061 ****************************************************************************/
2062 int read_data(int fd,char *buffer,int N)
2069 ret = read(fd,buffer + total,N - total);
2071 /* this is for portability */
2083 /****************************************************************************
2085 ****************************************************************************/
2086 int write_data(int fd,char *buffer,int N)
2093 ret = write(fd,buffer + total,N - total);
2104 /* variables used by the read prediction module */
2109 int rp_predict_fd = -1;
2110 int rp_predict_offset = 0;
2111 int rp_predict_length = 0;
2114 char *rp_buffer = NULL;
2115 BOOL predict_skip=False;
2116 time_t smb_last_time=(time_t)0;
2118 /****************************************************************************
2119 handle read prediction on a file
2120 ****************************************************************************/
2121 int read_predict(int fd,int offset,char *buf,char **ptr,int num)
2124 int possible = rp_length - (offset - rp_offset);
2126 possible = MIN(possible,num);
2128 /* give data if possible */
2130 offset >= rp_offset &&
2132 smb_last_time-rp_time < rp_timeout)
2136 memcpy(buf,rp_buffer + (offset-rp_offset),possible);
2138 *ptr = rp_buffer + (offset-rp_offset);
2139 DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
2143 predict_skip = True;
2145 predict_skip = False;
2147 /* prepare the next prediction */
2149 rp_predict_offset = offset + num;
2150 rp_predict_length = num;
2153 if (ret < 0) ret = 0;
2158 /****************************************************************************
2160 ****************************************************************************/
2161 void do_read_prediction()
2163 if (predict_skip) return;
2165 if (rp_predict_fd == -1)
2168 rp_fd = rp_predict_fd;
2169 rp_offset = rp_predict_offset;
2174 rp_predict_length = MIN(rp_predict_length,2*ReadSize);
2175 rp_predict_length = MAX(rp_predict_length,1024);
2176 rp_offset = (rp_offset/1024)*1024;
2177 rp_predict_length = (rp_predict_length/1024)*1024;
2179 if (rp_predict_length > rp_alloced)
2181 rp_buffer = Realloc(rp_buffer,rp_predict_length);
2182 rp_alloced = rp_predict_length;
2185 DEBUG(0,("can't allocate read-prediction buffer\n"));
2193 if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
2199 rp_length = read(rp_fd,rp_buffer,rp_predict_length);
2200 rp_time = time(NULL);
2205 /****************************************************************************
2206 invalidate read-prediction on a fd
2207 ****************************************************************************/
2208 void invalidate_read_prediction(int fd)
2212 if (rp_predict_fd == fd)
2217 /****************************************************************************
2218 transfer some data between two fd's
2219 ****************************************************************************/
2220 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2222 static char *buf=NULL;
2224 static int size = 0;
2227 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2229 if ((size < ReadSize) && buf) {
2234 size = MAX(ReadSize,1024);
2236 while (!buf && size>0) {
2237 buf = (char *)Realloc(buf,size+8);
2238 if (!buf) size /= 2;
2241 DEBUG(0,("Can't allocate transfer buffer!\n"));
2245 abuf = buf + (align%8);
2252 int s = MIN(n,size);
2257 if (header && (headlen >= MIN(s,1024))) {
2267 if (header && headlen > 0)
2269 ret = MIN(headlen,size);
2270 memcpy(buf1,header,ret);
2273 if (headlen <= 0) header = NULL;
2277 ret += read(infd,buf1+ret,s-ret);
2281 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2282 if (ret2 > 0) total += ret2;
2283 /* if we can't write then dump excess data */
2285 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2287 if (ret <= 0 || ret2 != ret)
2295 /****************************************************************************
2296 read 4 bytes of a smb packet and return the smb length of the packet
2297 possibly store the result in the buffer
2298 ****************************************************************************/
2299 int read_smb_length(int fd,char *inbuf,int timeout)
2303 int len=0, msg_type;
2314 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2316 ok = (read_data(fd,buffer,4) == 4);
2322 DEBUG(10,("select timeout (%d)\n", timeout));
2327 DEBUG(6,("couldn't read from client\n"));
2332 len = smb_len(buffer);
2333 msg_type = CVAL(buffer,0);
2335 if (msg_type == 0x85)
2337 DEBUG(5,( "Got keepalive packet\n"));
2342 DEBUG(10,("got smb length of %d\n",len));
2349 /****************************************************************************
2350 read an smb from a fd and return it's length
2351 The timeout is in milli seconds
2352 ****************************************************************************/
2353 BOOL receive_smb(int fd,char *buffer,int timeout)
2358 bzero(buffer,smb_size + 100);
2360 len = read_smb_length(fd,buffer,timeout);
2364 if (len > BUFFER_SIZE) {
2365 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2366 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2370 ok = (read_data(fd,buffer+4,len) == len);
2382 /****************************************************************************
2384 ****************************************************************************/
2385 BOOL send_smb(int fd,char *buffer)
2389 len = smb_len(buffer) + 4;
2391 while (nwritten < len)
2393 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2396 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2408 /****************************************************************************
2409 find a pointer to a netbios name
2410 ****************************************************************************/
2411 char *name_ptr(char *buf,int ofs)
2413 unsigned char c = *(unsigned char *)(buf+ofs);
2415 if ((c & 0xC0) == 0xC0)
2419 memcpy(p,buf+ofs,2);
2422 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2429 /****************************************************************************
2430 extract a netbios name from a buf
2431 ****************************************************************************/
2432 int name_extract(char *buf,int ofs,char *name)
2434 char *p = name_ptr(buf,ofs);
2435 int d = PTR_DIFF(p,buf+ofs);
2437 if (d < -50 || d > 50) return(0);
2438 return(name_interpret(p,name));
2442 /****************************************************************************
2443 return the total storage length of a mangled name
2444 ****************************************************************************/
2445 int name_len(char *s)
2448 unsigned char c = *(unsigned char *)s;
2449 if ((c & 0xC0) == 0xC0)
2451 while (*s) s += (*s)+1;
2452 return(PTR_DIFF(s,s0)+1);
2455 /****************************************************************************
2456 send a single packet to a port on another machine
2457 ****************************************************************************/
2458 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2462 struct sockaddr_in sock_out;
2467 /* create a socket to write to */
2468 out_fd = socket(AF_INET, type, 0);
2471 DEBUG(0,("socket failed"));
2475 /* set the address and port */
2476 bzero((char *)&sock_out,sizeof(sock_out));
2477 putip((char *)&sock_out.sin_addr,(char *)&ip);
2478 sock_out.sin_port = htons( port );
2479 sock_out.sin_family = AF_INET;
2482 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2483 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2486 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2489 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2490 inet_ntoa(ip),port,errno));
2496 /*******************************************************************
2497 sleep for a specified number of milliseconds
2498 ********************************************************************/
2502 struct timeval tval,t1,t2;
2509 tval.tv_sec = (t-tdiff)/1000;
2510 tval.tv_usec = 1000*((t-tdiff)%1000);
2514 sys_select(&fds,&tval);
2517 tdiff = TvalDiff(&t1,&t2);
2521 /****************************************************************************
2522 check if a string is part of a list
2523 ****************************************************************************/
2524 BOOL in_list(char *s,char *list,BOOL casesensitive)
2529 if (!list) return(False);
2531 while (next_token(&p,tok,LIST_SEP))
2533 if (casesensitive) {
2534 if (strcmp(tok,s) == 0)
2537 if (StrCaseCmp(tok,s) == 0)
2544 /* this is used to prevent lots of mallocs of size 1 */
2545 static char *null_string = NULL;
2547 /****************************************************************************
2548 set a string value, allocing the space for the string
2549 ****************************************************************************/
2550 BOOL string_init(char **dest,char *src)
2561 null_string = (char *)malloc(1);
2564 *dest = null_string;
2568 *dest = (char *)malloc(l+1);
2574 /****************************************************************************
2576 ****************************************************************************/
2577 void string_free(char **s)
2579 if (!s || !(*s)) return;
2580 if (*s == null_string)
2586 /****************************************************************************
2587 set a string value, allocing the space for the string, and deallocating any
2589 ****************************************************************************/
2590 BOOL string_set(char **dest,char *src)
2594 return(string_init(dest,src));
2597 /****************************************************************************
2598 substitute a string for a pattern in another string. Make sure there is
2601 This routine looks for pattern in s and replaces it with
2602 insert. It may do multiple replacements.
2604 return True if a substitution was done.
2605 ****************************************************************************/
2606 BOOL string_sub(char *s,char *pattern,char *insert)
2612 if (!insert || !pattern || !s) return(False);
2615 lp = strlen(pattern);
2616 li = strlen(insert);
2618 if (!*pattern) return(False);
2620 while (lp <= ls && (p = strstr(s,pattern)))
2623 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2624 memcpy(p,insert,li);
2633 /*********************************************************
2634 * Recursive routine that is called by mask_match.
2635 * Does the actual matching.
2636 *********************************************************/
2637 BOOL do_match(char *str, char *regexp, int case_sig)
2641 for( p = regexp; *p && *str; ) {
2648 /* Look for a character matching
2649 the one after the '*' */
2652 return True; /* Automatic match */
2654 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2656 if(do_match(str,p,case_sig))
2670 if(toupper(*str) != toupper(*p))
2680 if (!*p && str[0] == '.' && str[1] == 0)
2683 if (!*str && *p == '?')
2685 while (*p == '?') p++;
2689 if(!*str && (*p == '*' && p[1] == '\0'))
2695 /*********************************************************
2696 * Routine to match a given string with a regexp - uses
2697 * simplified regexp that takes * and ? only. Case can be
2698 * significant or not.
2699 *********************************************************/
2700 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2704 fstring ebase,eext,sbase,sext;
2708 /* Make local copies of str and regexp */
2709 StrnCpy(p1,regexp,sizeof(pstring)-1);
2710 StrnCpy(p2,str,sizeof(pstring)-1);
2712 if (!strchr(p2,'.')) {
2717 if (!strchr(p1,'.')) {
2725 string_sub(p1,"*.*","*");
2726 string_sub(p1,".*","*");
2730 /* Remove any *? and ** as they are meaningless */
2731 for(p = p1; *p; p++)
2732 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2733 (void)strcpy( &p[1], &p[2]);
2735 if (strequal(p1,"*")) return(True);
2737 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2743 if ((p=strrchr(p1,'.'))) {
2752 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2762 matched = do_match(sbase,ebase,case_sig) &&
2763 (trans2 || do_match(sext,eext,case_sig));
2765 DEBUG(5,("mask_match returning %d\n", matched));
2772 /****************************************************************************
2773 become a daemon, discarding the controlling terminal
2774 ****************************************************************************/
2775 void become_daemon(void)
2777 #ifndef NO_FORK_DEBUG
2781 /* detach from the terminal */
2787 int i = open("/dev/tty", O_RDWR);
2790 ioctl(i, (int) TIOCNOTTY, (char *)0);
2800 /****************************************************************************
2801 put up a yes/no prompt
2802 ****************************************************************************/
2808 if (!fgets(ans,sizeof(ans)-1,stdin))
2811 if (*ans == 'y' || *ans == 'Y')
2817 /****************************************************************************
2818 read a line from a file with possible \ continuation chars.
2819 Blanks at the start or end of a line are stripped.
2820 The string will be allocated if s2 is NULL
2821 ****************************************************************************/
2822 char *fgets_slash(char *s2,int maxlen,FILE *f)
2827 BOOL start_of_line = True;
2834 maxlen = MIN(maxlen,8);
2835 s = (char *)Realloc(s,maxlen);
2838 if (!s || maxlen < 2) return(NULL);
2842 while (len < maxlen-1)
2850 while (len > 0 && s[len-1] == ' ')
2854 if (len > 0 && s[len-1] == '\\')
2857 start_of_line = True;
2862 if (len <= 0 && !s2)
2864 return(len>0?s:NULL);
2869 start_of_line = False;
2873 if (!s2 && len > maxlen-3)
2876 s = (char *)Realloc(s,maxlen);
2877 if (!s) return(NULL);
2885 /****************************************************************************
2886 set the length of a file from a filedescriptor.
2887 Returns 0 on success, -1 on failure.
2888 ****************************************************************************/
2889 int set_filelen(int fd, long len)
2891 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2892 extend a file with ftruncate. Provide alternate implementation
2895 #if FTRUNCATE_CAN_EXTEND
2896 return ftruncate(fd, len);
2900 long currpos = lseek(fd, 0L, SEEK_CUR);
2904 /* Do an fstat to see if the file is longer than
2905 the requested size (call ftruncate),
2906 or shorter, in which case seek to len - 1 and write 1
2908 if(fstat(fd, &st)<0)
2912 if (S_ISFIFO(st.st_mode)) return 0;
2915 if(st.st_size == len)
2917 if(st.st_size > len)
2918 return ftruncate(fd, len);
2920 if(lseek(fd, len-1, SEEK_SET) != len -1)
2922 if(write(fd, &c, 1)!=1)
2924 /* Seek to where we were */
2925 lseek(fd, currpos, SEEK_SET);
2931 /****************************************************************************
2932 return the byte checksum of some data
2933 ****************************************************************************/
2934 int byte_checksum(char *buf,int len)
2936 unsigned char *p = (unsigned char *)buf;
2946 /****************************************************************************
2947 this is a version of setbuffer() for those machines that only have setvbuf
2948 ****************************************************************************/
2949 void setbuffer(FILE *f,char *buf,int bufsize)
2951 setvbuf(f,buf,_IOFBF,bufsize);
2956 /****************************************************************************
2957 parse out a directory name from a path name. Assumes dos style filenames.
2958 ****************************************************************************/
2959 char *dirname_dos(char *path,char *buf)
2961 char *p = strrchr(path,'\\');
2976 /****************************************************************************
2977 parse out a filename from a path name. Assumes dos style filenames.
2978 ****************************************************************************/
2979 static char *filename_dos(char *path,char *buf)
2981 char *p = strrchr(path,'\\');
2993 /****************************************************************************
2994 expand a pointer to be a particular size
2995 ****************************************************************************/
2996 void *Realloc(void *p,int size)
3002 DEBUG(5,("Realloc asked for 0 bytes\n"));
3007 ret = (void *)malloc(size);
3009 ret = (void *)realloc(p,size);
3012 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3018 /****************************************************************************
3020 ****************************************************************************/
3021 char *strdup(char *s)
3024 if (!s) return(NULL);
3025 ret = (char *)malloc(strlen(s)+1);
3026 if (!ret) return(NULL);
3033 /****************************************************************************
3034 Signal handler for SIGPIPE (write on a disconnected socket)
3035 ****************************************************************************/
3038 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3043 #ifdef REPLACE_STRLEN
3044 /****************************************************************************
3045 a replacement strlen() that returns int for solaris
3046 ****************************************************************************/
3058 /*******************************************************************
3059 ftruncate for operating systems that don't have it
3060 ********************************************************************/
3061 int ftruncate(int f,long l)
3068 fl.l_type = F_WRLCK;
3069 return fcntl(f, F_FREESP, &fl);
3075 /****************************************************************************
3076 get my own name and IP
3077 ****************************************************************************/
3078 BOOL get_myname(char *myname,struct in_addr *ip)
3085 /* get my host name */
3086 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3088 DEBUG(0,("gethostname failed\n"));
3093 if ((hp = Get_Hostbyname(hostname)) == 0)
3095 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3101 /* split off any parts after an initial . */
3102 char *p = strchr(hostname,'.');
3105 strcpy(myname,hostname);
3109 putip((char *)ip,(char *)hp->h_addr);
3115 /****************************************************************************
3116 true if two IP addresses are equal
3117 ****************************************************************************/
3118 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3120 unsigned long a1,a2;
3121 a1 = ntohl(ip1.s_addr);
3122 a2 = ntohl(ip2.s_addr);
3127 /****************************************************************************
3128 open a socket of the specified type, port and address for incoming data
3129 ****************************************************************************/
3130 int open_socket_in(int type, int port, int dlevel)
3133 struct sockaddr_in sock;
3137 /* get my host name */
3138 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3139 { DEBUG(0,("gethostname failed\n")); return -1; }
3142 if ((hp = Get_Hostbyname(host_name)) == 0)
3144 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3148 bzero((char *)&sock,sizeof(sock));
3149 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3150 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3151 sock.sin_len = sizeof(sock);
3153 sock.sin_port = htons( port );
3154 sock.sin_family = hp->h_addrtype;
3155 sock.sin_addr.s_addr = INADDR_ANY;
3156 res = socket(hp->h_addrtype, type, 0);
3158 { DEBUG(0,("socket failed\n")); return -1; }
3162 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3165 /* now we've got a socket - we need to bind it */
3166 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3169 if (port == SMB_PORT || port == NMB_PORT)
3170 DEBUG(dlevel,("bind failed on port %d (%s)\n",
3171 port,strerror(errno)));
3174 if (dlevel > 0 && port < 1000)
3177 if (port >= 1000 && port < 9000)
3178 return(open_socket_in(type,port+1,dlevel));
3183 DEBUG(3,("bind succeeded on port %d\n",port));
3189 /****************************************************************************
3190 create an outgoing socket
3191 **************************************************************************/
3192 int open_socket_out(int type, struct in_addr *addr, int port )
3194 struct sockaddr_in sock_out;
3197 /* create a socket to write to */
3198 res = socket(PF_INET, type, 0);
3200 { DEBUG(0,("socket error\n")); return -1; }
3202 if (type != SOCK_STREAM) return(res);
3204 bzero((char *)&sock_out,sizeof(sock_out));
3205 putip((char *)&sock_out.sin_addr,(char *)addr);
3207 sock_out.sin_port = htons( port );
3208 sock_out.sin_family = PF_INET;
3210 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3212 /* and connect it to the destination */
3213 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
3214 DEBUG(0,("connect error: %s\n",strerror(errno)));
3223 /****************************************************************************
3224 interpret a protocol description string, with a default
3225 ****************************************************************************/
3226 int interpret_protocol(char *str,int def)
3228 if (strequal(str,"NT1"))
3229 return(PROTOCOL_NT1);
3230 if (strequal(str,"LANMAN2"))
3231 return(PROTOCOL_LANMAN2);
3232 if (strequal(str,"LANMAN1"))
3233 return(PROTOCOL_LANMAN1);
3234 if (strequal(str,"CORE"))
3235 return(PROTOCOL_CORE);
3236 if (strequal(str,"COREPLUS"))
3237 return(PROTOCOL_COREPLUS);
3238 if (strequal(str,"CORE+"))
3239 return(PROTOCOL_COREPLUS);
3241 DEBUG(0,("Unrecognised protocol level %s\n",str));
3246 /****************************************************************************
3247 interpret a security level
3248 ****************************************************************************/
3249 int interpret_security(char *str,int def)
3251 if (strequal(str,"SERVER"))
3253 if (strequal(str,"USER"))
3255 if (strequal(str,"SHARE"))
3258 DEBUG(0,("Unrecognised security level %s\n",str));
3264 /****************************************************************************
3265 interpret an internet address or name into an IP address in 4 byte form
3266 ****************************************************************************/
3267 unsigned long interpret_addr(char *str)
3272 if (strcmp(str,"0.0.0.0") == 0) return(0);
3273 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3275 /* if it's in the form of an IP address then get the lib to interpret it */
3276 if (isdigit(str[0])) {
3277 res = inet_addr(str);
3279 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
3280 if ((hp = Get_Hostbyname(str)) == 0) {
3281 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3284 putip((char *)&res,(char *)hp->h_addr);
3287 if (res == (unsigned long)-1) return(0);
3292 /*******************************************************************
3293 a convenient addition to interpret_addr()
3294 ******************************************************************/
3295 struct in_addr *interpret_addr2(char *str)
3297 static struct in_addr ret;
3298 unsigned long a = interpret_addr(str);
3303 /*******************************************************************
3304 check if an IP is the 0.0.0.0
3305 ******************************************************************/
3306 BOOL zero_ip(struct in_addr ip)
3309 putip((char *)&a,(char *)&ip);
3313 /*******************************************************************
3314 sub strings with useful parameters
3315 ********************************************************************/
3316 void standard_sub_basic(char *s)
3318 if (!strchr(s,'%')) return;
3320 string_sub(s,"%R",remote_proto);
3321 string_sub(s,"%a",remote_arch);
3322 string_sub(s,"%m",remote_machine);
3323 string_sub(s,"%L",local_machine);
3325 if (!strchr(s,'%')) return;
3327 string_sub(s,"%v",VERSION);
3328 string_sub(s,"%h",myhostname);
3329 string_sub(s,"%U",sesssetup_user);
3331 if (!strchr(s,'%')) return;
3333 string_sub(s,"%I",Client_info.addr);
3334 string_sub(s,"%M",Client_info.name);
3335 string_sub(s,"%T",timestring());
3337 if (!strchr(s,'%')) return;
3341 sprintf(pidstr,"%d",(int)getpid());
3342 string_sub(s,"%d",pidstr);
3345 if (!strchr(s,'%')) return;
3348 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3350 string_sub(s,"%G",gidtoname(pass->pw_gid));
3356 /*******************************************************************
3357 are two IPs on the same subnet?
3358 ********************************************************************/
3359 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3361 unsigned long net1,net2,nmask;
3363 nmask = ntohl(mask.s_addr);
3364 net1 = ntohl(ip1.s_addr);
3365 net2 = ntohl(ip2.s_addr);
3367 return((net1 & nmask) == (net2 & nmask));
3371 /*******************************************************************
3372 write a string in unicoode format
3373 ********************************************************************/
3374 int PutUniCode(char *dst,char *src)
3378 dst[ret++] = src[0];
3387 /****************************************************************************
3388 a wrapper for gethostbyname() that tries with all lower and all upper case
3389 if the initial name fails
3390 ****************************************************************************/
3391 struct hostent *Get_Hostbyname(char *name)
3393 char *name2 = strdup(name);
3394 struct hostent *ret;
3398 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3402 if (!isalnum(*name2))
3408 ret = gethostbyname(name2);
3415 /* try with all lowercase */
3417 ret = gethostbyname(name2);
3424 /* try with all uppercase */
3426 ret = gethostbyname(name2);
3433 /* nothing works :-( */
3439 /****************************************************************************
3440 check if a process exists. Does this work on all unixes?
3441 ****************************************************************************/
3442 BOOL process_exists(int pid)
3446 sprintf(s,"/proc/%d",pid);
3447 return(directory_exist(s,NULL));
3450 static BOOL tested=False;
3451 static BOOL ok=False;
3455 sprintf(s,"/proc/%05d",getpid());
3456 ok = file_exist(s,NULL);
3459 sprintf(s,"/proc/%05d",pid);
3460 return(file_exist(s,NULL));
3464 /* a best guess for non root access */
3465 if (geteuid() != 0) return(True);
3467 /* otherwise use kill */
3468 return(pid == getpid() || kill(pid,0) == 0);
3473 /*******************************************************************
3474 turn a uid into a user name
3475 ********************************************************************/
3476 char *uidtoname(int uid)
3478 static char name[40];
3479 struct passwd *pass = getpwuid(uid);
3480 if (pass) return(pass->pw_name);
3481 sprintf(name,"%d",uid);
3485 /*******************************************************************
3486 turn a gid into a group name
3487 ********************************************************************/
3488 char *gidtoname(int gid)
3490 static char name[40];
3491 struct group *grp = getgrgid(gid);
3492 if (grp) return(grp->gr_name);
3493 sprintf(name,"%d",gid);
3497 /*******************************************************************
3499 ********************************************************************/
3500 void BlockSignals(BOOL block)
3503 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3504 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3507 sigblock(block_mask);
3509 sigunblock(block_mask);
3514 /*******************************************************************
3515 my own panic function - not suitable for general use
3516 ********************************************************************/
3517 void ajt_panic(void)
3519 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
3524 #define DIRECT direct
3526 #define DIRECT dirent
3529 /*******************************************************************
3530 a readdir wrapper which just returns the file name
3531 also return the inode number if requested
3532 ********************************************************************/
3533 char *readdirname(void *p)
3538 if (!p) return(NULL);
3540 ptr = (struct DIRECT *)readdir(p);
3541 if (!ptr) return(NULL);
3543 dname = ptr->d_name;
3549 unix_to_dos(buf, True);
3555 if (telldir(p) < 0) return(NULL);
3559 /* this handles a broken compiler setup, causing a mixture
3560 of BSD and SYSV headers and libraries */
3562 static BOOL broken_readdir = False;
3563 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3565 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3566 broken_readdir = True;
3578 #if (defined(SecureWare) && defined(SCO))
3579 /* This is needed due to needing the nap() function but we don't want
3580 to include the Xenix libraries since that will break other things...
3581 BTW: system call # 0x0c28 is the same as calling nap() */
3582 long nap(long milliseconds) {
3583 return syscall(0x0c28, milliseconds);
3587 #ifdef NO_INITGROUPS
3588 #include <sys/types.h>
3593 #define NULL (void *)0
3596 /****************************************************************************
3597 some systems don't have an initgroups call
3598 ****************************************************************************/
3599 int initgroups(char *name,gid_t id)
3602 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
3605 gid_t grouplst[NGROUPS_MAX];
3612 while (i < NGROUPS_MAX &&
3613 ((g = (struct group *)getgrent()) != (struct group *)NULL))
3615 if (g->gr_gid == id)
3619 while (gr && (*gr != (char)NULL)) {
3620 if (strcmp(name,gr) == 0) {
3621 grouplst[i] = g->gr_gid;
3626 gr = g->gr_mem[++j];
3630 return(setgroups(i,grouplst));
3638 /* undo the wrapping temporarily */
3643 /****************************************************************************
3644 wrapper for malloc() to catch memory errors
3645 ****************************************************************************/
3646 void *malloc_wrapped(int size,char *file,int line)
3648 #ifdef xx_old_malloc
3649 void *res = xx_old_malloc(size);
3651 void *res = malloc(size);
3653 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3655 size,(unsigned int)res));
3659 /****************************************************************************
3660 wrapper for realloc() to catch memory errors
3661 ****************************************************************************/
3662 void *realloc_wrapped(void *ptr,int size,char *file,int line)
3664 #ifdef xx_old_realloc
3665 void *res = xx_old_realloc(ptr,size);
3667 void *res = realloc(ptr,size);
3669 DEBUG(3,("Realloc\n"));
3670 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3672 (unsigned int)ptr));
3673 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3675 size,(unsigned int)res));
3679 /****************************************************************************
3680 wrapper for free() to catch memory errors
3681 ****************************************************************************/
3682 void free_wrapped(void *ptr,char *file,int line)
3689 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3690 file,line,(unsigned int)ptr));
3694 /* and re-do the define for spots lower in this file */
3695 #define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
3696 #define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
3697 #define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
3701 #ifdef REPLACE_STRSTR
3702 /****************************************************************************
3703 Mips version of strstr doesn't seem to work correctly.
3704 There is a #define in includes.h to redirect calls to this function.
3705 ****************************************************************************/
3706 char *Strstr(char *s, char *p)
3708 int len = strlen(p);
3710 while ( *s != '\0' ) {
3711 if ( strncmp(s, p, len) == 0 )
3718 #endif /* REPLACE_STRSTR */
3721 #ifdef REPLACE_MKTIME
3722 /*******************************************************************
3723 a mktime() replacement for those who don't have it - contributed by
3724 C.A. Lademann <cal@zls.com>
3725 ********************************************************************/
3727 #define HOUR 60*MINUTE
3729 #define YEAR 365*DAY
3730 time_t Mktime(struct tm *t)
3734 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
3740 epoch = (t->tm_year - 70) * YEAR +
3741 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
3746 for(i = 0; i < t->tm_mon; i++) {
3747 epoch += mon [m] * DAY;
3748 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
3757 epoch += (t->tm_mday - 1) * DAY;
3758 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
3760 if((u = localtime(&epoch)) != NULL) {
3761 t->tm_sec = u->tm_sec;
3762 t->tm_min = u->tm_min;
3763 t->tm_hour = u->tm_hour;
3764 t->tm_mday = u->tm_mday;
3765 t->tm_mon = u->tm_mon;
3766 t->tm_year = u->tm_year;
3767 t->tm_wday = u->tm_wday;
3768 t->tm_yday = u->tm_yday;
3769 t->tm_isdst = u->tm_isdst;
3771 memcpy(t->tm_name, u->tm_name, LTZNMAX);
3777 #endif /* REPLACE_MKTIME */
3781 #ifdef REPLACE_RENAME
3782 /* Rename a file. (from libiberty in GNU binutils) */
3783 int rename (zfrom, zto)
3787 if (link (zfrom, zto) < 0)
3789 if (errno != EEXIST)
3791 if (unlink (zto) < 0
3792 || link (zfrom, zto) < 0)
3795 return unlink (zfrom);
3800 #ifdef REPLACE_INNETGR
3802 * Search for a match in a netgroup. This replaces it on broken systems.
3804 int InNetGr(char *group,char *host,char *user,char *dom)
3806 char *hst, *usr, *dm;
3809 while (getnetgrent(&hst, &usr, &dm))
3810 if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
3811 ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
3812 ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
3824 /*******************************************************************
3825 a wrapper around memcpy for diagnostic purposes
3826 ********************************************************************/
3827 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
3829 if (l>64 && (((int)d)%4) != (((int)s)%4))
3830 DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
3831 #ifdef xx_old_memcpy
3832 return(xx_old_memcpy(d,s,l));
3834 return(memcpy(d,s,l));
3837 #define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)