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 */
52 /* my IP, the broadcast IP and the Netmask */
54 struct in_addr bcast_ip;
55 struct in_addr Netmask;
60 case handling on filenames
62 int case_default = CASE_LOWER;
65 /* size of reads during a direct file to file transfer */
66 int ReadSize = 16*1024;
68 pstring debugf = "/tmp/log.samba";
71 /* the following control case operations - they are put here so the
72 client can link easily */
75 BOOL use_mangled_map = False;
76 BOOL short_case_preserve;
79 fstring remote_machine="";
80 fstring local_machine="";
81 fstring remote_arch="UNKNOWN";
82 fstring remote_proto="UNKNOWN";
83 pstring myhostname="";
84 pstring user_socket_options="";
85 pstring sesssetup_user="";
88 static char *filename_dos(char *path,char *buf);
90 static BOOL stdout_logging = False;
93 /*******************************************************************
94 get ready for syslog stuff
95 ******************************************************************/
96 void setup_logging(char *pname,BOOL interactive)
100 char *p = strrchr(pname,'/');
102 openlog(pname, LOG_PID, LOG_DAEMON);
106 stdout_logging = True;
112 BOOL append_log=False;
115 /****************************************************************************
117 ****************************************************************************/
118 void reopen_logs(void)
125 strcpy(fname,debugf);
126 if (lp_loaded() && (*lp_logfile()))
127 strcpy(fname,lp_logfile());
129 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
131 strcpy(debugf,fname);
132 if (dbf) fclose(dbf);
134 dbf = fopen(debugf,"a");
136 dbf = fopen(debugf,"w");
137 if (dbf) setbuf(dbf,NULL);
151 /*******************************************************************
152 check if the log has grown too big
153 ********************************************************************/
154 static void check_log_size(void)
156 static int debug_count=0;
160 if (debug_count++ < 100) return;
162 maxlog = lp_max_log_size() * 1024;
163 if (!dbf || maxlog <= 0) return;
165 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
166 fclose(dbf); dbf = NULL;
168 if (dbf && file_size(debugf) > maxlog) {
170 fclose(dbf); dbf = NULL;
171 sprintf(name,"%s.old",debugf);
172 sys_rename(debugf,name);
180 /*******************************************************************
181 write an debug message on the debugfile. This is called by the DEBUG
183 ********************************************************************/
185 int Debug1(char *format_str, ...)
195 if (stdout_logging) {
197 va_start(ap, format_str);
200 format_str = va_arg(ap,char *);
202 vfprintf(dbf,format_str,ap);
208 if (!lp_syslog_only())
213 dbf = fopen(debugf,"w");
222 if (syslog_level < lp_syslog())
225 * map debug levels to syslog() priorities
226 * note that not all DEBUG(0, ...) calls are
229 static int priority_map[] = {
238 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
240 priority = LOG_DEBUG;
242 priority = priority_map[syslog_level];
245 va_start(ap, format_str);
248 format_str = va_arg(ap,char *);
250 vsprintf(msgbuf, format_str, ap);
254 syslog(priority, "%s", msgbuf);
259 if (!lp_syslog_only())
263 va_start(ap, format_str);
266 format_str = va_arg(ap,char *);
268 vfprintf(dbf,format_str,ap);
278 /****************************************************************************
279 routine to do file locking
280 ****************************************************************************/
281 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
288 uint32 mask = 0xC0000000;
290 /* make sure the count is reasonable, we might kill the lockd otherwise */
293 /* the offset is often strange - remove 2 of its bits if either of
294 the top two bits are set. Shift the top ones by two bits. This
295 still allows OLE2 apps to operate, but should stop lockd from
297 if ((offset & mask) != 0)
298 offset = (offset & ~mask) | ((offset & mask) >> 2);
300 unsigned long mask = ((unsigned)1<<31);
302 /* interpret negative counts as large numbers */
306 /* no negative offsets */
309 /* count + offset must be in range */
310 while ((offset < 0 || (offset + count < 0)) && mask)
318 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
321 lock.l_whence = SEEK_SET;
322 lock.l_start = (int)offset;
323 lock.l_len = (int)count;
328 ret = fcntl(fd,op,&lock);
331 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
337 (lock.l_type != F_UNLCK) &&
339 (lock.l_pid != getpid()))
341 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
345 /* it must be not locked or locked by me */
349 /* a lock set or unset */
352 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
353 offset,count,op,type,strerror(errno)));
355 /* perhaps it doesn't support this sort of locking?? */
358 DEBUG(3,("locking not supported? returning True\n"));
365 /* everything went OK */
366 DEBUG(5,("Lock call successful\n"));
374 /*******************************************************************
375 lock a file - returning a open file descriptor or -1 on failure
376 The timeout is in seconds. 0 means no timeout
377 ********************************************************************/
378 int file_lock(char *name,int timeout)
380 int fd = open(name,O_RDWR|O_CREAT,0666);
382 if (fd < 0) return(-1);
385 if (timeout) t = time(NULL);
386 while (!timeout || (time(NULL)-t < timeout)) {
387 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
388 msleep(LOCK_RETRY_TIMEOUT);
396 /*******************************************************************
397 unlock a file locked by file_lock
398 ********************************************************************/
399 void file_unlock(int fd)
403 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
408 /****************************************************************************
409 determine if a file descriptor is in fact a socket
410 ****************************************************************************/
411 BOOL is_a_socket(int fd)
415 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
419 static char *last_ptr=NULL;
421 /****************************************************************************
422 Get the next token from a string, return False if none found
423 handles double-quotes.
424 Based on a routine by GJC@VILLAGE.COM.
425 Extensively modified by Andrew.Tridgell@anu.edu.au
426 ****************************************************************************/
427 BOOL next_token(char **ptr,char *buff,char *sep)
432 if (!ptr) ptr = &last_ptr;
433 if (!ptr) return(False);
437 /* default to simple separators */
438 if (!sep) sep = " \t\n\r";
440 /* find the first non sep char */
441 while(*s && strchr(sep,*s)) s++;
444 if (! *s) return(False);
446 /* copy over the token */
447 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
455 *ptr = (*s) ? s+1 : s;
462 /****************************************************************************
463 Convert list of tokens to array; dependent on above routine.
464 Uses last_ptr from above - bit of a hack.
465 ****************************************************************************/
466 char **toktocliplist(int *ctok, char *sep)
472 if (!sep) sep = " \t\n\r";
474 while(*s && strchr(sep,*s)) s++;
477 if (!*s) return(NULL);
481 while(*s && (!strchr(sep,*s))) s++;
482 while(*s && strchr(sep,*s)) *s++=0;
488 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
500 /*******************************************************************
501 safely copies memory, ensuring no overlap problems.
502 this is only used if the machine does not have it's own memmove().
503 this is not the fastest algorithm in town, but it will do for our
505 ********************************************************************/
506 void *MemMove(void *dest,void *src,int size)
510 if (dest==src || !size) return(dest);
512 d = (unsigned long)dest;
513 s = (unsigned long)src;
515 if ((d >= (s+size)) || (s >= (d+size))) {
517 memcpy(dest,src,size);
523 /* we can forward copy */
524 if (s-d >= sizeof(int) &&
525 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
526 /* do it all as words */
527 int *idest = (int *)dest;
528 int *isrc = (int *)src;
530 for (i=0;i<size;i++) idest[i] = isrc[i];
533 char *cdest = (char *)dest;
534 char *csrc = (char *)src;
535 for (i=0;i<size;i++) cdest[i] = csrc[i];
540 /* must backward copy */
541 if (d-s >= sizeof(int) &&
542 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
543 /* do it all as words */
544 int *idest = (int *)dest;
545 int *isrc = (int *)src;
547 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
550 char *cdest = (char *)dest;
551 char *csrc = (char *)src;
552 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
560 /****************************************************************************
561 prompte a dptr (to make it recently used)
562 ****************************************************************************/
563 void array_promote(char *array,int elsize,int element)
569 p = (char *)malloc(elsize);
573 DEBUG(5,("Ahh! Can't malloc\n"));
576 memcpy(p,array + element * elsize, elsize);
577 memmove(array + elsize,array,elsize*element);
578 memcpy(array,p,elsize);
582 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
591 } socket_options[] = {
592 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
593 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
594 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
596 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
598 #ifdef IPTOS_LOWDELAY
599 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
601 #ifdef IPTOS_THROUGHPUT
602 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
605 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
608 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
611 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
614 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
620 /****************************************************************************
621 set user socket options
622 ****************************************************************************/
623 void set_socket_options(int fd, char *options)
627 while (next_token(&options,tok," \t,"))
632 BOOL got_value = False;
634 if ((p = strchr(tok,'=')))
641 for (i=0;socket_options[i].name;i++)
642 if (strequal(socket_options[i].name,tok))
645 if (!socket_options[i].name)
647 DEBUG(0,("Unknown socket option %s\n",tok));
651 switch (socket_options[i].opttype)
655 ret = setsockopt(fd,socket_options[i].level,
656 socket_options[i].option,(char *)&value,sizeof(int));
661 DEBUG(0,("syntax error - %s does not take a value\n",tok));
664 int on = socket_options[i].value;
665 ret = setsockopt(fd,socket_options[i].level,
666 socket_options[i].option,(char *)&on,sizeof(int));
672 DEBUG(0,("Failed to set socket option %s\n",tok));
678 /****************************************************************************
679 close the socket communication
680 ****************************************************************************/
681 void close_sockets(void )
687 /****************************************************************************
688 determine whether we are in the specified group
689 ****************************************************************************/
690 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
694 if (group == current_gid) return(True);
696 for (i=0;i<ngroups;i++)
697 if (group == groups[i])
703 /****************************************************************************
704 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
705 ****************************************************************************/
706 char *StrCpy(char *dest,char *src)
711 /* I don't want to get lazy with these ... */
713 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
718 if (!dest) return(NULL);
723 while ((*d++ = *src++)) ;
727 /****************************************************************************
728 line strncpy but always null terminates. Make sure there is room!
729 ****************************************************************************/
730 char *StrnCpy(char *dest,const char *src,int n)
733 if (!dest) return(NULL);
738 while (n-- && (*d++ = *src++)) ;
744 /*******************************************************************
745 copy an IP address from one buffer to another
746 ********************************************************************/
747 void putip(void *dest,void *src)
753 /****************************************************************************
754 interpret the weird netbios "name". Return the name type
755 ****************************************************************************/
756 static int name_interpret(char *in,char *out)
759 int len = (*in++) / 2;
763 if (len > 30 || len<1) return(0);
767 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
771 *out = ((in[0]-'A')<<4) + (in[1]-'A');
779 /* Handle any scope names */
782 *out++ = '.'; /* Scope names are separated by periods */
783 len = *(unsigned char *)in++;
784 StrnCpy(out, in, len);
793 /****************************************************************************
794 mangle a name into netbios format
795 ****************************************************************************/
796 int name_mangle(char *In,char *Out,char name_type)
800 char *in = (char *)&buf[0];
801 char *out = (char *)Out;
806 StrnCpy(name,In,sizeof(name)-1);
807 sprintf(buf,"%-15.15s%c",name,name_type);
810 memset(&buf[1],0,16);
815 char c = toupper(in[i]);
816 out[i*2] = (c>>4) + 'A';
817 out[i*2+1] = (c & 0xF) + 'A';
825 p = strchr(label, '.');
827 p = label + strlen(label);
829 memcpy(out, label, p - label);
831 label += p - label + (*p == '.');
834 return(name_len(Out));
838 /*******************************************************************
839 check if a file exists
840 ********************************************************************/
841 BOOL file_exist(char *fname,struct stat *sbuf)
844 if (!sbuf) sbuf = &st;
846 if (sys_stat(fname,sbuf) != 0)
849 return(S_ISREG(sbuf->st_mode));
852 /*******************************************************************
853 check a files mod time
854 ********************************************************************/
855 time_t file_modtime(char *fname)
859 if (sys_stat(fname,&st) != 0)
865 /*******************************************************************
866 check if a directory exists
867 ********************************************************************/
868 BOOL directory_exist(char *dname,struct stat *st)
873 if (sys_stat(dname,st) != 0)
876 return(S_ISDIR(st->st_mode));
879 /*******************************************************************
880 returns the size in bytes of the named file
881 ********************************************************************/
882 uint32 file_size(char *file_name)
886 sys_stat(file_name,&buf);
890 /*******************************************************************
891 return a string representing an attribute for a file
892 ********************************************************************/
893 char *attrib_string(int mode)
895 static char attrstr[10];
899 if (mode & aVOLID) strcat(attrstr,"V");
900 if (mode & aDIR) strcat(attrstr,"D");
901 if (mode & aARCH) strcat(attrstr,"A");
902 if (mode & aHIDDEN) strcat(attrstr,"H");
903 if (mode & aSYSTEM) strcat(attrstr,"S");
904 if (mode & aRONLY) strcat(attrstr,"R");
910 /*******************************************************************
911 case insensitive string compararison
912 ********************************************************************/
913 int StrCaseCmp(char *s, char *t)
915 for (; tolower(*s) == tolower(*t); ++s, ++t)
918 return tolower(*s) - tolower(*t);
921 /*******************************************************************
922 case insensitive string compararison, length limited
923 ********************************************************************/
924 int StrnCaseCmp(char *s, char *t, int n)
926 while (n-- && *s && *t) {
927 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
930 if (n) return(tolower(*s) - tolower(*t));
935 /*******************************************************************
937 ********************************************************************/
938 BOOL strequal(char *s1,char *s2)
940 if (s1 == s2) return(True);
941 if (!s1 || !s2) return(False);
943 return(StrCaseCmp(s1,s2)==0);
946 /*******************************************************************
947 compare 2 strings up to and including the nth char.
948 ******************************************************************/
949 BOOL strnequal(char *s1,char *s2,int n)
951 if (s1 == s2) return(True);
952 if (!s1 || !s2 || !n) return(False);
954 return(StrnCaseCmp(s1,s2,n)==0);
957 /*******************************************************************
958 compare 2 strings (case sensitive)
959 ********************************************************************/
960 BOOL strcsequal(char *s1,char *s2)
962 if (s1 == s2) return(True);
963 if (!s1 || !s2) return(False);
965 return(strcmp(s1,s2)==0);
969 /*******************************************************************
970 convert a string to lower case
971 ********************************************************************/
972 void strlower(char *s)
977 if (is_shift_jis (*s)) {
979 } else if (is_kana (*s)) {
994 /*******************************************************************
995 convert a string to upper case
996 ********************************************************************/
997 void strupper(char *s)
1002 if (is_shift_jis (*s)) {
1004 } else if (is_kana (*s)) {
1019 /*******************************************************************
1020 convert a string to "normal" form
1021 ********************************************************************/
1022 void strnorm(char *s)
1024 if (case_default == CASE_UPPER)
1030 /*******************************************************************
1031 check if a string is in "normal" case
1032 ********************************************************************/
1033 BOOL strisnormal(char *s)
1035 if (case_default == CASE_UPPER)
1036 return(!strhaslower(s));
1038 return(!strhasupper(s));
1042 /****************************************************************************
1044 ****************************************************************************/
1045 void string_replace(char *s,char oldc,char newc)
1050 if (is_shift_jis (*s)) {
1052 } else if (is_kana (*s)) {
1067 /****************************************************************************
1068 make a file into unix format
1069 ****************************************************************************/
1070 void unix_format(char *fname)
1073 string_replace(fname,'\\','/');
1075 dos2unix_format(fname, True);
1080 strcpy(namecopy,fname);
1082 strcat(fname,namecopy);
1086 /****************************************************************************
1087 make a file into dos format
1088 ****************************************************************************/
1089 void dos_format(char *fname)
1092 unix2dos_format(fname, True);
1094 string_replace(fname,'/','\\');
1098 /*******************************************************************
1099 show a smb message structure
1100 ********************************************************************/
1101 void show_msg(char *buf)
1108 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1110 (int)CVAL(buf,smb_com),
1111 (int)CVAL(buf,smb_rcls),
1112 (int)CVAL(buf,smb_reh),
1113 (int)SVAL(buf,smb_err),
1114 (int)CVAL(buf,smb_flg),
1115 (int)SVAL(buf,smb_flg2)));
1116 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1117 (int)SVAL(buf,smb_tid),
1118 (int)SVAL(buf,smb_pid),
1119 (int)SVAL(buf,smb_uid),
1120 (int)SVAL(buf,smb_mid),
1121 (int)CVAL(buf,smb_wct)));
1122 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1123 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1124 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1125 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1126 DEBUG(5,("smb_bcc=%d\n",bcc));
1127 if (DEBUGLEVEL < 10)
1129 for (i=0;i<MIN(bcc,128);i++)
1130 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1134 /*******************************************************************
1135 return the length of an smb packet
1136 ********************************************************************/
1137 int smb_len(char *buf)
1139 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1142 /*******************************************************************
1143 set the length of an smb packet
1144 ********************************************************************/
1145 void _smb_setlen(char *buf,int len)
1148 buf[1] = (len&0x10000)>>16;
1149 buf[2] = (len&0xFF00)>>8;
1153 /*******************************************************************
1154 set the length and marker of an smb packet
1155 ********************************************************************/
1156 void smb_setlen(char *buf,int len)
1158 _smb_setlen(buf,len);
1166 /*******************************************************************
1167 setup the word count and byte count for a smb message
1168 ********************************************************************/
1169 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1172 bzero(buf + smb_size,num_words*2 + num_bytes);
1173 CVAL(buf,smb_wct) = num_words;
1174 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1175 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1176 return (smb_size + num_words*2 + num_bytes);
1179 /*******************************************************************
1180 return the number of smb words
1181 ********************************************************************/
1182 int smb_numwords(char *buf)
1184 return (CVAL(buf,smb_wct));
1187 /*******************************************************************
1188 return the size of the smb_buf region of a message
1189 ********************************************************************/
1190 int smb_buflen(char *buf)
1192 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1195 /*******************************************************************
1196 return a pointer to the smb_buf data area
1197 ********************************************************************/
1198 int smb_buf_ofs(char *buf)
1200 return (smb_size + CVAL(buf,smb_wct)*2);
1203 /*******************************************************************
1204 return a pointer to the smb_buf data area
1205 ********************************************************************/
1206 char *smb_buf(char *buf)
1208 return (buf + smb_buf_ofs(buf));
1211 /*******************************************************************
1212 return the SMB offset into an SMB buffer
1213 ********************************************************************/
1214 int smb_offset(char *p,char *buf)
1216 return(PTR_DIFF(p,buf+4));
1220 /*******************************************************************
1221 skip past some strings in a buffer
1222 ********************************************************************/
1223 char *skip_string(char *buf,int n)
1226 buf += strlen(buf) + 1;
1230 /*******************************************************************
1231 trim the specified elements off the front and back of a string
1232 ********************************************************************/
1233 BOOL trim_string(char *s,char *front,char *back)
1236 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1242 if (!(*p = p[strlen(front)]))
1247 while (back && *back && strlen(s) >= strlen(back) &&
1248 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1251 s[strlen(s)-strlen(back)] = 0;
1257 /*******************************************************************
1258 reduce a file name, removing .. elements.
1259 ********************************************************************/
1260 void dos_clean_name(char *s)
1264 DEBUG(3,("dos_clean_name [%s]\n",s));
1266 /* remove any double slashes */
1267 string_sub(s, "\\\\", "\\");
1269 while ((p = strstr(s,"\\..\\")) != NULL)
1276 if ((p=strrchr(s,'\\')) != NULL)
1283 trim_string(s,NULL,"\\..");
1285 string_sub(s, "\\.\\", "\\");
1288 /*******************************************************************
1289 reduce a file name, removing .. elements.
1290 ********************************************************************/
1291 void unix_clean_name(char *s)
1295 DEBUG(3,("unix_clean_name [%s]\n",s));
1297 /* remove any double slashes */
1298 string_sub(s, "//","/");
1300 while ((p = strstr(s,"/../")) != NULL)
1307 if ((p=strrchr(s,'/')) != NULL)
1314 trim_string(s,NULL,"/..");
1318 /*******************************************************************
1319 a wrapper for the normal chdir() function
1320 ********************************************************************/
1321 int ChDir(char *path)
1324 static pstring LastDir="";
1326 if (strcsequal(path,".")) return(0);
1328 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1329 DEBUG(3,("chdir to %s\n",path));
1330 res = sys_chdir(path);
1332 strcpy(LastDir,path);
1337 /*******************************************************************
1338 return the absolute current directory path. A dumb version.
1339 ********************************************************************/
1340 static char *Dumb_GetWd(char *s)
1343 return ((char *)getcwd(s,sizeof(pstring)));
1345 return ((char *)getwd(s));
1350 /* number of list structures for a caching GetWd function. */
1351 #define MAX_GETWDCACHE (50)
1359 } ino_list[MAX_GETWDCACHE];
1361 BOOL use_getwd_cache=True;
1363 /*******************************************************************
1364 return the absolute current directory path
1365 ********************************************************************/
1366 char *GetWd(char *str)
1369 static BOOL getwd_cache_init = False;
1370 struct stat st, st2;
1375 if (!use_getwd_cache)
1376 return(Dumb_GetWd(str));
1378 /* init the cache */
1379 if (!getwd_cache_init)
1381 getwd_cache_init = True;
1382 for (i=0;i<MAX_GETWDCACHE;i++)
1384 string_init(&ino_list[i].text,"");
1385 ino_list[i].valid = False;
1389 /* Get the inode of the current directory, if this doesn't work we're
1392 if (stat(".",&st) == -1)
1394 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1395 return(Dumb_GetWd(str));
1399 for (i=0; i<MAX_GETWDCACHE; i++)
1400 if (ino_list[i].valid)
1403 /* If we have found an entry with a matching inode and dev number
1404 then find the inode number for the directory in the cached string.
1405 If this agrees with that returned by the stat for the current
1406 directory then all is o.k. (but make sure it is a directory all
1409 if (st.st_ino == ino_list[i].inode &&
1410 st.st_dev == ino_list[i].dev)
1412 if (stat(ino_list[i].text,&st2) == 0)
1414 if (st.st_ino == st2.st_ino &&
1415 st.st_dev == st2.st_dev &&
1416 (st2.st_mode & S_IFMT) == S_IFDIR)
1418 strcpy (str, ino_list[i].text);
1420 /* promote it for future use */
1421 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1426 /* If the inode is different then something's changed,
1427 scrub the entry and start from scratch. */
1428 ino_list[i].valid = False;
1435 /* We don't have the information to hand so rely on traditional methods.
1436 The very slow getcwd, which spawns a process on some systems, or the
1437 not quite so bad getwd. */
1441 DEBUG(0,("Getwd failed, errno %d\n",errno));
1447 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1449 /* add it to the cache */
1450 i = MAX_GETWDCACHE - 1;
1451 string_set(&ino_list[i].text,s);
1452 ino_list[i].dev = st.st_dev;
1453 ino_list[i].inode = st.st_ino;
1454 ino_list[i].valid = True;
1456 /* put it at the top of the list */
1457 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1464 /*******************************************************************
1465 reduce a file name, removing .. elements and checking that
1466 it is below dir in the heirachy. This uses GetWd() and so must be run
1467 on the system that has the referenced file system.
1469 widelinks are allowed if widelinks is true
1470 ********************************************************************/
1471 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1473 #ifndef REDUCE_PATHS
1481 BOOL relative = (*s != '/');
1483 *dir2 = *wd = *basename = *newname = 0;
1488 /* can't have a leading .. */
1489 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1491 DEBUG(3,("Illegal file name? (%s)\n",s));
1497 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1499 /* remove any double slashes */
1500 string_sub(s,"//","/");
1503 p = strrchr(basename,'/');
1510 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1514 if (ChDir(dir) != 0)
1516 DEBUG(0,("couldn't chdir to %s\n",dir));
1522 DEBUG(0,("couldn't getwd for %s\n",dir));
1528 if (p && (p != basename))
1531 if (strcmp(p+1,".")==0)
1533 if (strcmp(p+1,"..")==0)
1537 if (ChDir(basename) != 0)
1540 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1544 if (!GetWd(newname))
1547 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1551 if (p && (p != basename))
1553 strcat(newname,"/");
1554 strcat(newname,p+1);
1558 int l = strlen(dir2);
1559 if (dir2[l-1] == '/')
1562 if (strncmp(newname,dir2,l) != 0)
1565 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1571 if (newname[l] == '/')
1572 strcpy(s,newname + l + 1);
1574 strcpy(s,newname+l);
1585 DEBUG(3,("reduced to %s\n",s));
1590 /****************************************************************************
1592 ****************************************************************************/
1593 static void expand_one(char *Mask,int len)
1596 while ((p1 = strchr(Mask,'*')) != NULL)
1598 int lfill = (len+1) - strlen(Mask);
1599 int l1= (p1 - Mask);
1602 memset(tmp+l1,'?',lfill);
1603 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1608 /****************************************************************************
1609 expand a wildcard expression, replacing *s with ?s
1610 ****************************************************************************/
1611 void expand_mask(char *Mask,BOOL doext)
1616 BOOL hasdot = False;
1618 BOOL absolute = (*Mask == '\\');
1620 *mbeg = *mext = *dirpart = *filepart = 0;
1622 /* parse the directory and filename */
1623 if (strchr(Mask,'\\'))
1624 dirname_dos(Mask,dirpart);
1626 filename_dos(Mask,filepart);
1628 strcpy(mbeg,filepart);
1629 if ((p1 = strchr(mbeg,'.')) != NULL)
1639 if (strlen(mbeg) > 8)
1641 strcpy(mext,mbeg + 8);
1647 strcpy(mbeg,"????????");
1648 if ((*mext == 0) && doext && !hasdot)
1651 if (strequal(mbeg,"*") && *mext==0)
1659 strcpy(Mask,dirpart);
1660 if (*dirpart || absolute) strcat(Mask,"\\");
1665 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1669 /****************************************************************************
1670 does a string have any uppercase chars in it?
1671 ****************************************************************************/
1672 BOOL strhasupper(char *s)
1677 if (is_shift_jis (*s)) {
1679 } else if (is_kana (*s)) {
1682 if (isupper(*s)) return(True);
1686 if (isupper(*s)) return(True);
1693 /****************************************************************************
1694 does a string have any lowercase chars in it?
1695 ****************************************************************************/
1696 BOOL strhaslower(char *s)
1701 if (is_shift_jis (*s)) {
1703 } else if (is_kana (*s)) {
1706 if (islower(*s)) return(True);
1710 if (islower(*s)) return(True);
1717 /****************************************************************************
1718 find the number of chars in a string
1719 ****************************************************************************/
1720 int count_chars(char *s,char c)
1733 /****************************************************************************
1735 ****************************************************************************/
1736 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1743 if ((mode & aDIR) != 0)
1746 memset(buf+1,' ',11);
1747 if ((p = strchr(mask2,'.')) != NULL)
1750 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1751 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1755 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1757 bzero(buf+21,DIR_STRUCT_SIZE-21);
1758 CVAL(buf,21) = mode;
1759 put_dos_date(buf,22,date);
1760 SSVAL(buf,26,size & 0xFFFF);
1761 SSVAL(buf,28,size >> 16);
1762 StrnCpy(buf+30,fname,12);
1763 if (!case_sensitive)
1765 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1769 /*******************************************************************
1770 close the low 3 fd's and open dev/null in their place
1771 ********************************************************************/
1772 void close_low_fds(void)
1776 close(0); close(1); close(2);
1777 /* try and use up these file descriptors, so silly
1778 library routines writing to stdout etc won't cause havoc */
1780 fd = open("/dev/null",O_RDWR,0);
1781 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1783 DEBUG(0,("Can't open /dev/null\n"));
1787 DEBUG(0,("Didn't get file descriptor %d\n",i));
1794 /****************************************************************************
1796 ****************************************************************************/
1797 int write_socket(int fd,char *buf,int len)
1803 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1804 ret = write_data(fd,buf,len);
1806 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1810 /****************************************************************************
1812 ****************************************************************************/
1813 int read_udp_socket(int fd,char *buf,int len)
1816 struct sockaddr sock;
1819 socklen = sizeof(sock);
1820 bzero((char *)&sock,socklen);
1821 bzero((char *)&lastip,sizeof(lastip));
1822 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1824 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1828 lastip = *(struct in_addr *) &sock.sa_data[2];
1829 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1834 /****************************************************************************
1835 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1837 if SYSV use O_NDELAY
1839 ****************************************************************************/
1840 int set_blocking(int fd, BOOL set)
1844 #define FLAG_TO_SET O_NONBLOCK
1847 #define FLAG_TO_SET O_NDELAY
1849 #define FLAG_TO_SET FNDELAY
1853 if((val = fcntl(fd, F_GETFL, 0))==-1)
1855 if(set) /* Turn blocking on - ie. clear nonblock flag */
1856 val &= ~FLAG_TO_SET;
1859 return fcntl( fd, F_SETFL, val);
1864 /****************************************************************************
1865 Calculate the difference in timeout values. Return 1 if val1 > val2,
1866 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
1867 may be == val1 or val2
1868 ****************************************************************************/
1869 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
1871 int usecdiff = val1->tv_usec - val2->tv_usec;
1872 int secdiff = val1->tv_sec - val2->tv_sec;
1874 usecdiff = 1000000 + usecdiff;
1877 retval->tv_sec = secdiff;
1878 retval->tv_usec = usecdiff;
1883 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
1886 /****************************************************************************
1887 read data from a device with a timout in msec.
1888 mincount = if timeout, minimum to read before returning
1889 maxcount = number to be read.
1890 ****************************************************************************/
1891 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
1897 struct timeval timeout, tval1, tval2, tvaldiff;
1898 int error_limit = 5;
1900 /* just checking .... */
1901 if (maxcnt <= 0) return(0);
1904 time_out = DEFAULT_PIPE_TIMEOUT;
1908 if (mincnt == 0) mincnt = maxcnt;
1910 while (nread < mincnt)
1912 readret = read(fd, buf + nread, maxcnt - nread);
1913 if (readret <= 0) return(nread);
1919 /* Non blocking read */
1921 set_blocking(fd, False);
1922 nread = read_data(fd, buf, mincnt);
1924 nread += read(fd,buf+nread,maxcnt-nread);
1925 if(nread == -1 && errno == EWOULDBLOCK)
1927 set_blocking(fd,True);
1931 /* Most difficult - timeout read */
1932 /* If this is ever called on a disk file and
1933 mincnt is greater then the filesize then
1934 system performance will suffer severely as
1935 select always return true on disk files */
1937 /* Set initial timeout */
1938 timeout.tv_sec = time_out / 1000;
1939 timeout.tv_usec = 1000 * (time_out % 1000);
1941 /* As most UNIXes don't modify the value of timeout
1942 when they return from select we need to get the timeofday (in usec)
1943 now, and also after the select returns so we know
1944 how much time has elapsed */
1947 GetTimeOfDay( &tval1);
1948 nread = 0; /* Number of bytes we have read */
1955 selrtn = sys_select(&fds,&timeout);
1957 /* Check if error */
1963 /* Did we timeout ? */
1965 if (nread < mincnt) return -1;
1969 readret = read(fd, buf+nread, maxcnt-nread);
1970 if (readret == 0 && nread < mincnt) {
1971 /* error_limit should not really be needed, but some systems
1972 do strange things ... I don't want to just continue
1973 indefinately in case we get an infinite loop */
1974 if (error_limit--) continue;
1979 /* force a particular error number for
1981 DEBUG(5,("read gave error %s\n",strerror(errno)));
1988 /* If we have read more than mincnt then return */
1989 if (nread >= mincnt)
1992 /* We need to do another select - but first reduce the
1993 time_out by the amount of time already elapsed - if
1994 this is less than zero then return */
1996 GetTimeOfDay(&tval2);
1997 (void)tval_sub( &tvaldiff, &tval2, &tval1);
1999 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
2000 break; /* We timed out */
2003 /* Save the time of day as we need to do the select
2004 again (saves a system call) */
2008 /* Return the number we got */
2012 /****************************************************************************
2013 read data from the client. Maxtime is in milliseconds
2014 ****************************************************************************/
2015 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2020 struct timeval timeout;
2025 timeout.tv_sec = maxtime / 1000;
2026 timeout.tv_usec = (maxtime % 1000) * 1000;
2028 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2030 if (!FD_ISSET(fd,&fds))
2033 nread = read_udp_socket(fd, buffer, bufsize);
2035 /* return the number got */
2039 /*******************************************************************
2040 find the difference in milliseconds between two struct timeval
2042 ********************************************************************/
2043 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2045 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2046 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2049 /****************************************************************************
2050 send a keepalive packet (rfc1002)
2051 ****************************************************************************/
2052 BOOL send_keepalive(int client)
2054 unsigned char buf[4];
2057 buf[1] = buf[2] = buf[3] = 0;
2059 return(write_data(client,(char *)buf,4) == 4);
2064 /****************************************************************************
2065 read data from the client, reading exactly N bytes.
2066 ****************************************************************************/
2067 int read_data(int fd,char *buffer,int N)
2074 ret = read(fd,buffer + total,N - total);
2076 /* this is for portability */
2088 /****************************************************************************
2090 ****************************************************************************/
2091 int write_data(int fd,char *buffer,int N)
2098 ret = write(fd,buffer + total,N - total);
2109 /* variables used by the read prediction module */
2114 int rp_predict_fd = -1;
2115 int rp_predict_offset = 0;
2116 int rp_predict_length = 0;
2119 char *rp_buffer = NULL;
2120 BOOL predict_skip=False;
2121 time_t smb_last_time=(time_t)0;
2123 /****************************************************************************
2124 handle read prediction on a file
2125 ****************************************************************************/
2126 int read_predict(int fd,int offset,char *buf,char **ptr,int num)
2129 int possible = rp_length - (offset - rp_offset);
2131 possible = MIN(possible,num);
2133 /* give data if possible */
2135 offset >= rp_offset &&
2137 smb_last_time-rp_time < rp_timeout)
2141 memcpy(buf,rp_buffer + (offset-rp_offset),possible);
2143 *ptr = rp_buffer + (offset-rp_offset);
2144 DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
2148 predict_skip = True;
2150 predict_skip = False;
2152 /* prepare the next prediction */
2154 rp_predict_offset = offset + num;
2155 rp_predict_length = num;
2158 if (ret < 0) ret = 0;
2163 /****************************************************************************
2165 ****************************************************************************/
2166 void do_read_prediction()
2168 if (predict_skip) return;
2170 if (rp_predict_fd == -1)
2173 rp_fd = rp_predict_fd;
2174 rp_offset = rp_predict_offset;
2179 rp_predict_length = MIN(rp_predict_length,2*ReadSize);
2180 rp_predict_length = MAX(rp_predict_length,1024);
2181 rp_offset = (rp_offset/1024)*1024;
2182 rp_predict_length = (rp_predict_length/1024)*1024;
2184 if (rp_predict_length > rp_alloced)
2186 rp_buffer = Realloc(rp_buffer,rp_predict_length);
2187 rp_alloced = rp_predict_length;
2190 DEBUG(0,("can't allocate read-prediction buffer\n"));
2198 if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
2204 rp_length = read(rp_fd,rp_buffer,rp_predict_length);
2205 rp_time = time(NULL);
2210 /****************************************************************************
2211 invalidate read-prediction on a fd
2212 ****************************************************************************/
2213 void invalidate_read_prediction(int fd)
2217 if (rp_predict_fd == fd)
2222 /****************************************************************************
2223 transfer some data between two fd's
2224 ****************************************************************************/
2225 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2227 static char *buf=NULL;
2229 static int size = 0;
2232 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2234 if ((size < ReadSize) && buf) {
2239 size = MAX(ReadSize,1024);
2241 while (!buf && size>0) {
2242 buf = (char *)Realloc(buf,size+8);
2243 if (!buf) size /= 2;
2246 DEBUG(0,("Can't allocate transfer buffer!\n"));
2250 abuf = buf + (align%8);
2257 int s = MIN(n,size);
2262 if (header && (headlen >= MIN(s,1024))) {
2272 if (header && headlen > 0)
2274 ret = MIN(headlen,size);
2275 memcpy(buf1,header,ret);
2278 if (headlen <= 0) header = NULL;
2282 ret += read(infd,buf1+ret,s-ret);
2286 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2287 if (ret2 > 0) total += ret2;
2288 /* if we can't write then dump excess data */
2290 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2292 if (ret <= 0 || ret2 != ret)
2300 /****************************************************************************
2301 read 4 bytes of a smb packet and return the smb length of the packet
2302 possibly store the result in the buffer
2303 ****************************************************************************/
2304 int read_smb_length(int fd,char *inbuf,int timeout)
2308 int len=0, msg_type;
2319 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2321 ok = (read_data(fd,buffer,4) == 4);
2327 DEBUG(10,("select timeout (%d)\n", timeout));
2332 DEBUG(6,("couldn't read from client\n"));
2337 len = smb_len(buffer);
2338 msg_type = CVAL(buffer,0);
2340 if (msg_type == 0x85)
2342 DEBUG(5,( "Got keepalive packet\n"));
2347 DEBUG(10,("got smb length of %d\n",len));
2354 /****************************************************************************
2355 read an smb from a fd and return it's length
2356 The timeout is in milli seconds
2357 ****************************************************************************/
2358 BOOL receive_smb(int fd,char *buffer,int timeout)
2363 bzero(buffer,smb_size + 100);
2365 len = read_smb_length(fd,buffer,timeout);
2369 if (len > BUFFER_SIZE) {
2370 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2371 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2375 ok = (read_data(fd,buffer+4,len) == len);
2387 /****************************************************************************
2389 ****************************************************************************/
2390 BOOL send_smb(int fd,char *buffer)
2394 len = smb_len(buffer) + 4;
2396 while (nwritten < len)
2398 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2401 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2413 /****************************************************************************
2414 find a pointer to a netbios name
2415 ****************************************************************************/
2416 char *name_ptr(char *buf,int ofs)
2418 unsigned char c = *(unsigned char *)(buf+ofs);
2420 if ((c & 0xC0) == 0xC0)
2424 memcpy(p,buf+ofs,2);
2427 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2434 /****************************************************************************
2435 extract a netbios name from a buf
2436 ****************************************************************************/
2437 int name_extract(char *buf,int ofs,char *name)
2439 char *p = name_ptr(buf,ofs);
2440 int d = PTR_DIFF(p,buf+ofs);
2442 if (d < -50 || d > 50) return(0);
2443 return(name_interpret(p,name));
2447 /****************************************************************************
2448 return the total storage length of a mangled name
2449 ****************************************************************************/
2450 int name_len(char *s)
2453 unsigned char c = *(unsigned char *)s;
2454 if ((c & 0xC0) == 0xC0)
2456 while (*s) s += (*s)+1;
2457 return(PTR_DIFF(s,s0)+1);
2460 /****************************************************************************
2461 send a single packet to a port on another machine
2462 ****************************************************************************/
2463 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2467 struct sockaddr_in sock_out;
2472 /* create a socket to write to */
2473 out_fd = socket(AF_INET, type, 0);
2476 DEBUG(0,("socket failed"));
2480 /* set the address and port */
2481 bzero((char *)&sock_out,sizeof(sock_out));
2482 putip((char *)&sock_out.sin_addr,(char *)&ip);
2483 sock_out.sin_port = htons( port );
2484 sock_out.sin_family = AF_INET;
2487 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2488 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2491 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2494 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2495 inet_ntoa(ip),port,errno));
2501 /*******************************************************************
2502 sleep for a specified number of milliseconds
2503 ********************************************************************/
2507 struct timeval tval,t1,t2;
2514 tval.tv_sec = (t-tdiff)/1000;
2515 tval.tv_usec = 1000*((t-tdiff)%1000);
2519 sys_select(&fds,&tval);
2522 tdiff = TvalDiff(&t1,&t2);
2526 /****************************************************************************
2527 check if a string is part of a list
2528 ****************************************************************************/
2529 BOOL in_list(char *s,char *list,BOOL casesensitive)
2534 if (!list) return(False);
2536 while (next_token(&p,tok,LIST_SEP))
2538 if (casesensitive) {
2539 if (strcmp(tok,s) == 0)
2542 if (StrCaseCmp(tok,s) == 0)
2549 /* this is used to prevent lots of mallocs of size 1 */
2550 static char *null_string = NULL;
2552 /****************************************************************************
2553 set a string value, allocing the space for the string
2554 ****************************************************************************/
2555 BOOL string_init(char **dest,char *src)
2566 null_string = (char *)malloc(1);
2569 *dest = null_string;
2573 *dest = (char *)malloc(l+1);
2579 /****************************************************************************
2581 ****************************************************************************/
2582 void string_free(char **s)
2584 if (!s || !(*s)) return;
2585 if (*s == null_string)
2591 /****************************************************************************
2592 set a string value, allocing the space for the string, and deallocating any
2594 ****************************************************************************/
2595 BOOL string_set(char **dest,char *src)
2599 return(string_init(dest,src));
2602 /****************************************************************************
2603 substitute a string for a pattern in another string. Make sure there is
2606 This routine looks for pattern in s and replaces it with
2607 insert. It may do multiple replacements.
2609 return True if a substitution was done.
2610 ****************************************************************************/
2611 BOOL string_sub(char *s,char *pattern,char *insert)
2617 if (!insert || !pattern || !s) return(False);
2620 lp = strlen(pattern);
2621 li = strlen(insert);
2623 if (!*pattern) return(False);
2625 while (lp <= ls && (p = strstr(s,pattern)))
2628 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2629 memcpy(p,insert,li);
2638 /*********************************************************
2639 * Recursive routine that is called by mask_match.
2640 * Does the actual matching.
2641 *********************************************************/
2642 BOOL do_match(char *str, char *regexp, int case_sig)
2646 for( p = regexp; *p && *str; ) {
2653 /* Look for a character matching
2654 the one after the '*' */
2657 return True; /* Automatic match */
2659 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2661 if(do_match(str,p,case_sig))
2675 if(toupper(*str) != toupper(*p))
2685 if (!*p && str[0] == '.' && str[1] == 0)
2688 if (!*str && *p == '?')
2690 while (*p == '?') p++;
2694 if(!*str && (*p == '*' && p[1] == '\0'))
2700 /*********************************************************
2701 * Routine to match a given string with a regexp - uses
2702 * simplified regexp that takes * and ? only. Case can be
2703 * significant or not.
2704 *********************************************************/
2705 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2709 fstring ebase,eext,sbase,sext;
2713 /* Make local copies of str and regexp */
2714 StrnCpy(p1,regexp,sizeof(pstring)-1);
2715 StrnCpy(p2,str,sizeof(pstring)-1);
2717 if (!strchr(p2,'.')) {
2722 if (!strchr(p1,'.')) {
2730 string_sub(p1,"*.*","*");
2731 string_sub(p1,".*","*");
2735 /* Remove any *? and ** as they are meaningless */
2736 for(p = p1; *p; p++)
2737 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2738 (void)strcpy( &p[1], &p[2]);
2740 if (strequal(p1,"*")) return(True);
2742 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2748 if ((p=strrchr(p1,'.'))) {
2757 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2767 matched = do_match(sbase,ebase,case_sig) &&
2768 (trans2 || do_match(sext,eext,case_sig));
2770 DEBUG(5,("mask_match returning %d\n", matched));
2777 /****************************************************************************
2778 become a daemon, discarding the controlling terminal
2779 ****************************************************************************/
2780 void become_daemon(void)
2782 #ifndef NO_FORK_DEBUG
2786 /* detach from the terminal */
2792 int i = open("/dev/tty", O_RDWR);
2795 ioctl(i, (int) TIOCNOTTY, (char *)0);
2804 /****************************************************************************
2805 calculate the default netmask for an address
2806 ****************************************************************************/
2807 static void default_netmask(struct in_addr *inm, struct in_addr *iad)
2809 unsigned long ad = ntohl(iad->s_addr);
2812 ** Guess a netmask based on the class of the IP address given.
2814 if ( (ad & 0x80000000) == 0 ) {
2815 /* class A address */
2817 } else if ( (ad & 0xC0000000) == 0x80000000 ) {
2818 /* class B address */
2820 } else if ( (ad & 0xE0000000) == 0xC0000000 ) {
2821 /* class C address */
2824 /* class D or E; netmask doesn't make much sense - guess 4 bits */
2827 inm->s_addr = htonl(nm);
2830 /****************************************************************************
2831 get the broadcast address for our address
2832 (troyer@saifr00.ateng.az.honeywell.com)
2833 ****************************************************************************/
2834 void get_broadcast(struct in_addr *if_ipaddr,
2835 struct in_addr *if_bcast,
2836 struct in_addr *if_nmask)
2839 #ifndef NO_GET_BROADCAST
2840 int sock = -1; /* AF_INET raw socket desc */
2842 struct ifreq *ifr=NULL;
2845 #if defined(EVEREST)
2848 struct ifreq *ifreqs;
2849 #elif defined(USE_IFREQ)
2851 struct strioctl strioctl;
2858 /* get a default netmask and broadcast */
2859 default_netmask(if_nmask, if_ipaddr);
2861 #ifndef NO_GET_BROADCAST
2862 /* Create a socket to the INET kernel. */
2864 if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
2866 if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
2869 DEBUG(0,( "Unable to open socket to get broadcast address\n"));
2873 /* Get a list of the configured interfaces */
2875 /* This is part of SCO Openserver 5: The ioctls are no longer part
2876 if the lower level STREAMS interface glue. They are now real
2879 if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
2880 DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
2882 DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
2884 ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
2885 ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
2887 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
2888 DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
2892 for (i = 0; i < n_interfaces; ++i) {
2893 if (if_ipaddr->s_addr ==
2894 ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
2901 #elif defined(USE_IFREQ)
2902 ifc = (struct ifconf *)buff;
2903 ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
2904 strioctl.ic_cmd = SIOCGIFCONF;
2905 strioctl.ic_dp = (char *)ifc;
2906 strioctl.ic_len = sizeof(buff);
2907 if (ioctl(sock, I_STR, &strioctl) < 0) {
2908 DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
2910 ifr = (struct ifreq *)ifc->ifc_req;
2912 /* Loop through interfaces, looking for given IP address */
2913 for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
2914 if (if_ipaddr->s_addr ==
2915 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2921 #elif defined(__FreeBSD__) || defined(NETBSD)
2922 ifc.ifc_len = sizeof(buff);
2924 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
2925 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
2928 /* Loop through interfaces, looking for given IP address */
2931 if (if_ipaddr->s_addr ==
2932 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2936 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
2937 ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
2941 ifc.ifc_len = sizeof(buff);
2943 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
2944 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
2948 /* Loop through interfaces, looking for given IP address */
2949 for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
2951 if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
2953 if (if_ipaddr->s_addr ==
2954 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2963 DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
2965 /* Get the netmask address from the kernel */
2969 strioctl.ic_cmd = SIOCGIFNETMASK;
2970 strioctl.ic_dp = (char *)&ifreq;
2971 strioctl.ic_len = sizeof(struct ifreq);
2972 if (ioctl(sock, I_STR, &strioctl) < 0)
2973 DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
2975 *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
2977 if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
2978 DEBUG(0,("SIOCGIFNETMASK failed\n"));
2980 *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
2983 DEBUG(2,("Netmask for %s = %s\n", ifr->ifr_name,
2984 inet_ntoa(*if_nmask)));
2992 /* sanity check on the netmask */
2994 unsigned long nm = ntohl(if_nmask->s_addr);
2995 if ((nm >> 24) != 0xFF) {
2996 DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
2997 default_netmask(if_nmask, if_ipaddr);
3001 /* derive the broadcast assuming a 1's broadcast, as this is what
3002 all MS operating systems do, we have to comply even if the unix
3003 box is setup differently */
3005 unsigned long ad = ntohl(if_ipaddr->s_addr);
3006 unsigned long nm = ntohl(if_nmask->s_addr);
3007 unsigned long bc = (ad & nm) | (0xffffffff & ~nm);
3008 if_bcast->s_addr = htonl(bc);
3011 DEBUG(2,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
3012 } /* get_broadcast */
3015 /****************************************************************************
3016 put up a yes/no prompt
3017 ****************************************************************************/
3023 if (!fgets(ans,sizeof(ans)-1,stdin))
3026 if (*ans == 'y' || *ans == 'Y')
3032 /****************************************************************************
3033 read a line from a file with possible \ continuation chars.
3034 Blanks at the start or end of a line are stripped.
3035 The string will be allocated if s2 is NULL
3036 ****************************************************************************/
3037 char *fgets_slash(char *s2,int maxlen,FILE *f)
3042 BOOL start_of_line = True;
3049 maxlen = MIN(maxlen,8);
3050 s = (char *)Realloc(s,maxlen);
3053 if (!s || maxlen < 2) return(NULL);
3057 while (len < maxlen-1)
3065 while (len > 0 && s[len-1] == ' ')
3069 if (len > 0 && s[len-1] == '\\')
3072 start_of_line = True;
3077 if (len <= 0 && !s2)
3079 return(len>0?s:NULL);
3084 start_of_line = False;
3088 if (!s2 && len > maxlen-3)
3091 s = (char *)Realloc(s,maxlen);
3092 if (!s) return(NULL);
3100 /****************************************************************************
3101 set the length of a file from a filedescriptor.
3102 Returns 0 on success, -1 on failure.
3103 ****************************************************************************/
3104 int set_filelen(int fd, long len)
3106 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3107 extend a file with ftruncate. Provide alternate implementation
3110 #if FTRUNCATE_CAN_EXTEND
3111 return ftruncate(fd, len);
3115 long currpos = lseek(fd, 0L, SEEK_CUR);
3119 /* Do an fstat to see if the file is longer than
3120 the requested size (call ftruncate),
3121 or shorter, in which case seek to len - 1 and write 1
3123 if(fstat(fd, &st)<0)
3127 if (S_ISFIFO(st.st_mode)) return 0;
3130 if(st.st_size == len)
3132 if(st.st_size > len)
3133 return ftruncate(fd, len);
3135 if(lseek(fd, len-1, SEEK_SET) != len -1)
3137 if(write(fd, &c, 1)!=1)
3139 /* Seek to where we were */
3140 lseek(fd, currpos, SEEK_SET);
3146 /****************************************************************************
3147 return the byte checksum of some data
3148 ****************************************************************************/
3149 int byte_checksum(char *buf,int len)
3151 unsigned char *p = (unsigned char *)buf;
3161 /****************************************************************************
3162 this is a version of setbuffer() for those machines that only have setvbuf
3163 ****************************************************************************/
3164 void setbuffer(FILE *f,char *buf,int bufsize)
3166 setvbuf(f,buf,_IOFBF,bufsize);
3171 /****************************************************************************
3172 parse out a directory name from a path name. Assumes dos style filenames.
3173 ****************************************************************************/
3174 char *dirname_dos(char *path,char *buf)
3176 char *p = strrchr(path,'\\');
3191 /****************************************************************************
3192 parse out a filename from a path name. Assumes dos style filenames.
3193 ****************************************************************************/
3194 static char *filename_dos(char *path,char *buf)
3196 char *p = strrchr(path,'\\');
3208 /****************************************************************************
3209 expand a pointer to be a particular size
3210 ****************************************************************************/
3211 void *Realloc(void *p,int size)
3217 DEBUG(5,("Realloc asked for 0 bytes\n"));
3222 ret = (void *)malloc(size);
3224 ret = (void *)realloc(p,size);
3227 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3233 /****************************************************************************
3235 ****************************************************************************/
3236 char *strdup(char *s)
3239 if (!s) return(NULL);
3240 ret = (char *)malloc(strlen(s)+1);
3241 if (!ret) return(NULL);
3248 /****************************************************************************
3249 Signal handler for SIGPIPE (write on a disconnected socket)
3250 ****************************************************************************/
3253 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3258 #ifdef REPLACE_STRLEN
3259 /****************************************************************************
3260 a replacement strlen() that returns int for solaris
3261 ****************************************************************************/
3273 /*******************************************************************
3274 ftruncate for operating systems that don't have it
3275 ********************************************************************/
3276 int ftruncate(int f,long l)
3283 fl.l_type = F_WRLCK;
3284 return fcntl(f, F_FREESP, &fl);
3290 /****************************************************************************
3291 get my own name and IP
3292 ****************************************************************************/
3293 BOOL get_myname(char *myname,struct in_addr *ip)
3300 /* get my host name */
3301 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3303 DEBUG(0,("gethostname failed\n"));
3308 if ((hp = Get_Hostbyname(hostname)) == 0)
3310 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3316 /* split off any parts after an initial . */
3317 char *p = strchr(hostname,'.');
3320 strcpy(myname,hostname);
3324 putip((char *)ip,(char *)hp->h_addr);
3330 /****************************************************************************
3331 true if two IP addresses are equal
3332 ****************************************************************************/
3333 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3335 unsigned long a1,a2;
3336 a1 = ntohl(ip1.s_addr);
3337 a2 = ntohl(ip2.s_addr);
3342 /****************************************************************************
3343 open a socket of the specified type, port and address for incoming data
3344 ****************************************************************************/
3345 int open_socket_in(int type, int port, int dlevel)
3348 struct sockaddr_in sock;
3352 /* get my host name */
3353 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3354 { DEBUG(0,("gethostname failed\n")); return -1; }
3357 if ((hp = Get_Hostbyname(host_name)) == 0)
3359 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3363 bzero((char *)&sock,sizeof(sock));
3364 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3365 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3366 sock.sin_len = sizeof(sock);
3368 sock.sin_port = htons( port );
3369 sock.sin_family = hp->h_addrtype;
3370 sock.sin_addr.s_addr = INADDR_ANY;
3371 res = socket(hp->h_addrtype, type, 0);
3373 { DEBUG(0,("socket failed\n")); return -1; }
3377 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3380 /* now we've got a socket - we need to bind it */
3381 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3384 if (port == SMB_PORT || port == NMB_PORT)
3385 DEBUG(dlevel,("bind failed on port %d (%s)\n",
3386 port,strerror(errno)));
3389 if (dlevel > 0 && port < 1000)
3392 if (port >= 1000 && port < 9000)
3393 return(open_socket_in(type,port+1,dlevel));
3398 DEBUG(3,("bind succeeded on port %d\n",port));
3404 /****************************************************************************
3405 create an outgoing socket
3406 **************************************************************************/
3407 int open_socket_out(int type, struct in_addr *addr, int port )
3409 struct sockaddr_in sock_out;
3412 /* create a socket to write to */
3413 res = socket(PF_INET, type, 0);
3415 { DEBUG(0,("socket error\n")); return -1; }
3417 if (type != SOCK_STREAM) return(res);
3419 bzero((char *)&sock_out,sizeof(sock_out));
3420 putip((char *)&sock_out.sin_addr,(char *)addr);
3422 sock_out.sin_port = htons( port );
3423 sock_out.sin_family = PF_INET;
3425 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3427 /* and connect it to the destination */
3428 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
3429 DEBUG(0,("connect error: %s\n",strerror(errno)));
3438 /****************************************************************************
3439 interpret a protocol description string, with a default
3440 ****************************************************************************/
3441 int interpret_protocol(char *str,int def)
3443 if (strequal(str,"NT1"))
3444 return(PROTOCOL_NT1);
3445 if (strequal(str,"LANMAN2"))
3446 return(PROTOCOL_LANMAN2);
3447 if (strequal(str,"LANMAN1"))
3448 return(PROTOCOL_LANMAN1);
3449 if (strequal(str,"CORE"))
3450 return(PROTOCOL_CORE);
3451 if (strequal(str,"COREPLUS"))
3452 return(PROTOCOL_COREPLUS);
3453 if (strequal(str,"CORE+"))
3454 return(PROTOCOL_COREPLUS);
3456 DEBUG(0,("Unrecognised protocol level %s\n",str));
3461 /****************************************************************************
3462 interpret a security level
3463 ****************************************************************************/
3464 int interpret_security(char *str,int def)
3466 if (strequal(str,"SERVER"))
3468 if (strequal(str,"USER"))
3470 if (strequal(str,"SHARE"))
3473 DEBUG(0,("Unrecognised security level %s\n",str));
3479 /****************************************************************************
3480 interpret an internet address or name into an IP address in 4 byte form
3481 ****************************************************************************/
3482 unsigned long interpret_addr(char *str)
3487 if (strcmp(str,"0.0.0.0") == 0) return(0);
3488 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3490 /* if it's in the form of an IP address then get the lib to interpret it */
3491 if (isdigit(str[0])) {
3492 res = inet_addr(str);
3494 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
3495 if ((hp = Get_Hostbyname(str)) == 0) {
3496 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3499 putip((char *)&res,(char *)hp->h_addr);
3502 if (res == (unsigned long)-1) return(0);
3507 /*******************************************************************
3508 a convenient addition to interpret_addr()
3509 ******************************************************************/
3510 struct in_addr *interpret_addr2(char *str)
3512 static struct in_addr ret;
3513 unsigned long a = interpret_addr(str);
3514 putip((char *)&ret,(char *)&a);
3518 /*******************************************************************
3519 check if an IP is the 0.0.0.0
3520 ******************************************************************/
3521 BOOL zero_ip(struct in_addr ip)
3524 putip((char *)&a,(char *)&ip);
3528 /*******************************************************************
3529 sub strings with useful parameters
3530 ********************************************************************/
3531 void standard_sub_basic(char *s)
3533 if (!strchr(s,'%')) return;
3535 string_sub(s,"%R",remote_proto);
3536 string_sub(s,"%a",remote_arch);
3537 string_sub(s,"%m",remote_machine);
3538 string_sub(s,"%L",local_machine);
3540 if (!strchr(s,'%')) return;
3542 string_sub(s,"%v",VERSION);
3543 string_sub(s,"%h",myhostname);
3544 string_sub(s,"%U",sesssetup_user);
3546 if (!strchr(s,'%')) return;
3548 string_sub(s,"%I",Client_info.addr);
3549 string_sub(s,"%M",Client_info.name);
3550 string_sub(s,"%T",timestring());
3552 if (!strchr(s,'%')) return;
3556 sprintf(pidstr,"%d",(int)getpid());
3557 string_sub(s,"%d",pidstr);
3560 if (!strchr(s,'%')) return;
3563 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3565 string_sub(s,"%G",gidtoname(pass->pw_gid));
3571 /*******************************************************************
3572 are two IPs on the same subnet?
3573 ********************************************************************/
3574 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3576 unsigned long net1,net2,nmask;
3578 nmask = ntohl(mask.s_addr);
3579 net1 = ntohl(ip1.s_addr);
3580 net2 = ntohl(ip2.s_addr);
3582 return((net1 & nmask) == (net2 & nmask));
3586 /*******************************************************************
3587 write a string in unicoode format
3588 ********************************************************************/
3589 int PutUniCode(char *dst,char *src)
3593 dst[ret++] = src[0];
3602 /****************************************************************************
3603 a wrapper for gethostbyname() that tries with all lower and all upper case
3604 if the initial name fails
3605 ****************************************************************************/
3606 struct hostent *Get_Hostbyname(char *name)
3608 char *name2 = strdup(name);
3609 struct hostent *ret;
3613 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3617 if (!isalnum(*name2))
3623 ret = gethostbyname(name2);
3630 /* try with all lowercase */
3632 ret = gethostbyname(name2);
3639 /* try with all uppercase */
3641 ret = gethostbyname(name2);
3648 /* nothing works :-( */
3654 /****************************************************************************
3655 check if a process exists. Does this work on all unixes?
3656 ****************************************************************************/
3657 BOOL process_exists(int pid)
3661 sprintf(s,"/proc/%d",pid);
3662 return(directory_exist(s,NULL));
3665 static BOOL tested=False;
3666 static BOOL ok=False;
3670 sprintf(s,"/proc/%05d",getpid());
3671 ok = file_exist(s,NULL);
3674 sprintf(s,"/proc/%05d",pid);
3675 return(file_exist(s,NULL));
3679 /* a best guess for non root access */
3680 if (geteuid() != 0) return(True);
3682 /* otherwise use kill */
3683 return(pid == getpid() || kill(pid,0) == 0);
3688 /*******************************************************************
3689 turn a uid into a user name
3690 ********************************************************************/
3691 char *uidtoname(int uid)
3693 static char name[40];
3694 struct passwd *pass = getpwuid(uid);
3695 if (pass) return(pass->pw_name);
3696 sprintf(name,"%d",uid);
3700 /*******************************************************************
3701 turn a gid into a group name
3702 ********************************************************************/
3703 char *gidtoname(int gid)
3705 static char name[40];
3706 struct group *grp = getgrgid(gid);
3707 if (grp) return(grp->gr_name);
3708 sprintf(name,"%d",gid);
3712 /*******************************************************************
3714 ********************************************************************/
3715 void BlockSignals(BOOL block)
3718 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3719 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3722 sigblock(block_mask);
3724 sigunblock(block_mask);
3729 /*******************************************************************
3730 my own panic function - not suitable for general use
3731 ********************************************************************/
3732 void ajt_panic(void)
3734 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &");
3739 #define DIRECT direct
3741 #define DIRECT dirent
3744 /*******************************************************************
3745 a readdir wrapper which just returns the file name
3746 also return the inode number if requested
3747 ********************************************************************/
3748 char *readdirname(void *p)
3753 if (!p) return(NULL);
3755 ptr = (struct DIRECT *)readdir(p);
3756 if (!ptr) return(NULL);
3758 dname = ptr->d_name;
3764 unix_to_dos(buf, True);
3770 if (telldir(p) < 0) return(NULL);
3774 /* this handles a broken compiler setup, causing a mixture
3775 of BSD and SYSV headers and libraries */
3777 static BOOL broken_readdir = False;
3778 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3780 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3781 broken_readdir = True;
3793 #if (defined(SecureWare) && defined(SCO))
3794 /* This is needed due to needing the nap() function but we don't want
3795 to include the Xenix libraries since that will break other things...
3796 BTW: system call # 0x0c28 is the same as calling nap() */
3797 long nap(long milliseconds) {
3798 return syscall(0x0c28, milliseconds);
3802 #ifdef NO_INITGROUPS
3803 #include <sys/types.h>
3808 #define NULL (void *)0
3811 /****************************************************************************
3812 some systems don't have an initgroups call
3813 ****************************************************************************/
3814 int initgroups(char *name,gid_t id)
3817 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
3820 gid_t grouplst[NGROUPS_MAX];
3827 while (i < NGROUPS_MAX &&
3828 ((g = (struct group *)getgrent()) != (struct group *)NULL))
3830 if (g->gr_gid == id)
3834 while (gr && (*gr != (char)NULL)) {
3835 if (strcmp(name,gr) == 0) {
3836 grouplst[i] = g->gr_gid;
3841 gr = g->gr_mem[++j];
3845 return(setgroups(i,grouplst));
3853 /* undo the wrapping temporarily */
3858 /****************************************************************************
3859 wrapper for malloc() to catch memory errors
3860 ****************************************************************************/
3861 void *malloc_wrapped(int size,char *file,int line)
3863 #ifdef xx_old_malloc
3864 void *res = xx_old_malloc(size);
3866 void *res = malloc(size);
3868 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3870 size,(unsigned int)res));
3874 /****************************************************************************
3875 wrapper for realloc() to catch memory errors
3876 ****************************************************************************/
3877 void *realloc_wrapped(void *ptr,int size,char *file,int line)
3879 #ifdef xx_old_realloc
3880 void *res = xx_old_realloc(ptr,size);
3882 void *res = realloc(ptr,size);
3884 DEBUG(3,("Realloc\n"));
3885 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3887 (unsigned int)ptr));
3888 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3890 size,(unsigned int)res));
3894 /****************************************************************************
3895 wrapper for free() to catch memory errors
3896 ****************************************************************************/
3897 void free_wrapped(void *ptr,char *file,int line)
3904 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3905 file,line,(unsigned int)ptr));
3909 /* and re-do the define for spots lower in this file */
3910 #define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
3911 #define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
3912 #define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
3916 #ifdef REPLACE_STRSTR
3917 /****************************************************************************
3918 Mips version of strstr doesn't seem to work correctly.
3919 There is a #define in includes.h to redirect calls to this function.
3920 ****************************************************************************/
3921 char *Strstr(char *s, char *p)
3923 int len = strlen(p);
3925 while ( *s != '\0' ) {
3926 if ( strncmp(s, p, len) == 0 )
3933 #endif /* REPLACE_STRSTR */
3936 #ifdef REPLACE_MKTIME
3937 /*******************************************************************
3938 a mktime() replacement for those who don't have it - contributed by
3939 C.A. Lademann <cal@zls.com>
3940 ********************************************************************/
3942 #define HOUR 60*MINUTE
3944 #define YEAR 365*DAY
3945 time_t Mktime(struct tm *t)
3949 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
3955 epoch = (t->tm_year - 70) * YEAR +
3956 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
3961 for(i = 0; i < t->tm_mon; i++) {
3962 epoch += mon [m] * DAY;
3963 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
3972 epoch += (t->tm_mday - 1) * DAY;
3973 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
3975 if((u = localtime(&epoch)) != NULL) {
3976 t->tm_sec = u->tm_sec;
3977 t->tm_min = u->tm_min;
3978 t->tm_hour = u->tm_hour;
3979 t->tm_mday = u->tm_mday;
3980 t->tm_mon = u->tm_mon;
3981 t->tm_year = u->tm_year;
3982 t->tm_wday = u->tm_wday;
3983 t->tm_yday = u->tm_yday;
3984 t->tm_isdst = u->tm_isdst;
3986 memcpy(t->tm_name, u->tm_name, LTZNMAX);
3992 #endif /* REPLACE_MKTIME */
3996 #ifdef REPLACE_RENAME
3997 /* Rename a file. (from libiberty in GNU binutils) */
3998 int rename (zfrom, zto)
4002 if (link (zfrom, zto) < 0)
4004 if (errno != EEXIST)
4006 if (unlink (zto) < 0
4007 || link (zfrom, zto) < 0)
4010 return unlink (zfrom);
4015 #ifdef REPLACE_INNETGR
4017 * Search for a match in a netgroup. This replaces it on broken systems.
4019 int InNetGr(char *group,char *host,char *user,char *dom)
4021 char *hst, *usr, *dm;
4024 while (getnetgrent(&hst, &usr, &dm))
4025 if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
4026 ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
4027 ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
4039 /*******************************************************************
4040 a wrapper around memcpy for diagnostic purposes
4041 ********************************************************************/
4042 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
4044 if (l>64 && (((int)d)%4) != (((int)s)%4))
4045 DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
4046 #ifdef xx_old_memcpy
4047 return(xx_old_memcpy(d,s,l));
4049 return(memcpy(d,s,l));
4052 #define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)