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);
1825 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1829 lastip = *(struct in_addr *) &sock.sa_data[2];
1830 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1835 /****************************************************************************
1836 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1838 if SYSV use O_NDELAY
1840 ****************************************************************************/
1841 int set_blocking(int fd, BOOL set)
1845 #define FLAG_TO_SET O_NONBLOCK
1848 #define FLAG_TO_SET O_NDELAY
1850 #define FLAG_TO_SET FNDELAY
1854 if((val = fcntl(fd, F_GETFL, 0))==-1)
1856 if(set) /* Turn blocking on - ie. clear nonblock flag */
1857 val &= ~FLAG_TO_SET;
1860 return fcntl( fd, F_SETFL, val);
1865 /****************************************************************************
1866 Calculate the difference in timeout values. Return 1 if val1 > val2,
1867 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
1868 may be == val1 or val2
1869 ****************************************************************************/
1870 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
1872 int usecdiff = val1->tv_usec - val2->tv_usec;
1873 int secdiff = val1->tv_sec - val2->tv_sec;
1875 usecdiff = 1000000 + usecdiff;
1878 retval->tv_sec = secdiff;
1879 retval->tv_usec = usecdiff;
1884 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
1887 /****************************************************************************
1888 read data from a device with a timout in msec.
1889 mincount = if timeout, minimum to read before returning
1890 maxcount = number to be read.
1891 ****************************************************************************/
1892 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
1898 struct timeval timeout, tval1, tval2, tvaldiff;
1899 int error_limit = 5;
1901 /* just checking .... */
1902 if (maxcnt <= 0) return(0);
1905 time_out = DEFAULT_PIPE_TIMEOUT;
1909 if (mincnt == 0) mincnt = maxcnt;
1911 while (nread < mincnt)
1913 readret = read(fd, buf + nread, maxcnt - nread);
1914 if (readret <= 0) return(nread);
1920 /* Non blocking read */
1922 set_blocking(fd, False);
1923 nread = read_data(fd, buf, mincnt);
1925 nread += read(fd,buf+nread,maxcnt-nread);
1926 if(nread == -1 && errno == EWOULDBLOCK)
1928 set_blocking(fd,True);
1932 /* Most difficult - timeout read */
1933 /* If this is ever called on a disk file and
1934 mincnt is greater then the filesize then
1935 system performance will suffer severely as
1936 select always return true on disk files */
1938 /* Set initial timeout */
1939 timeout.tv_sec = time_out / 1000;
1940 timeout.tv_usec = 1000 * (time_out % 1000);
1942 /* As most UNIXes don't modify the value of timeout
1943 when they return from select we need to get the timeofday (in usec)
1944 now, and also after the select returns so we know
1945 how much time has elapsed */
1948 GetTimeOfDay( &tval1);
1949 nread = 0; /* Number of bytes we have read */
1956 selrtn = sys_select(&fds,&timeout);
1958 /* Check if error */
1964 /* Did we timeout ? */
1966 if (nread < mincnt) return -1;
1970 readret = read(fd, buf+nread, maxcnt-nread);
1971 if (readret == 0 && nread < mincnt) {
1972 /* error_limit should not really be needed, but some systems
1973 do strange things ... I don't want to just continue
1974 indefinately in case we get an infinite loop */
1975 if (error_limit--) continue;
1980 /* force a particular error number for
1982 DEBUG(5,("read gave error %s\n",strerror(errno)));
1989 /* If we have read more than mincnt then return */
1990 if (nread >= mincnt)
1993 /* We need to do another select - but first reduce the
1994 time_out by the amount of time already elapsed - if
1995 this is less than zero then return */
1997 GetTimeOfDay(&tval2);
1998 (void)tval_sub( &tvaldiff, &tval2, &tval1);
2000 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
2001 break; /* We timed out */
2004 /* Save the time of day as we need to do the select
2005 again (saves a system call) */
2009 /* Return the number we got */
2013 /****************************************************************************
2014 read data from the client. Maxtime is in milliseconds
2015 ****************************************************************************/
2016 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2021 struct timeval timeout;
2026 timeout.tv_sec = maxtime / 1000;
2027 timeout.tv_usec = (maxtime % 1000) * 1000;
2029 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2031 if (!FD_ISSET(fd,&fds))
2034 nread = read_udp_socket(fd, buffer, bufsize);
2036 /* return the number got */
2040 /*******************************************************************
2041 find the difference in milliseconds between two struct timeval
2043 ********************************************************************/
2044 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2046 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2047 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2050 /****************************************************************************
2051 send a keepalive packet (rfc1002)
2052 ****************************************************************************/
2053 BOOL send_keepalive(int client)
2055 unsigned char buf[4];
2058 buf[1] = buf[2] = buf[3] = 0;
2060 return(write_data(client,(char *)buf,4) == 4);
2065 /****************************************************************************
2066 read data from the client, reading exactly N bytes.
2067 ****************************************************************************/
2068 int read_data(int fd,char *buffer,int N)
2075 ret = read(fd,buffer + total,N - total);
2077 /* this is for portability */
2089 /****************************************************************************
2091 ****************************************************************************/
2092 int write_data(int fd,char *buffer,int N)
2099 ret = write(fd,buffer + total,N - total);
2110 /* variables used by the read prediction module */
2115 int rp_predict_fd = -1;
2116 int rp_predict_offset = 0;
2117 int rp_predict_length = 0;
2120 char *rp_buffer = NULL;
2121 BOOL predict_skip=False;
2122 time_t smb_last_time=(time_t)0;
2124 /****************************************************************************
2125 handle read prediction on a file
2126 ****************************************************************************/
2127 int read_predict(int fd,int offset,char *buf,char **ptr,int num)
2130 int possible = rp_length - (offset - rp_offset);
2132 possible = MIN(possible,num);
2134 /* give data if possible */
2136 offset >= rp_offset &&
2138 smb_last_time-rp_time < rp_timeout)
2142 memcpy(buf,rp_buffer + (offset-rp_offset),possible);
2144 *ptr = rp_buffer + (offset-rp_offset);
2145 DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
2149 predict_skip = True;
2151 predict_skip = False;
2153 /* prepare the next prediction */
2155 rp_predict_offset = offset + num;
2156 rp_predict_length = num;
2159 if (ret < 0) ret = 0;
2164 /****************************************************************************
2166 ****************************************************************************/
2167 void do_read_prediction()
2169 if (predict_skip) return;
2171 if (rp_predict_fd == -1)
2174 rp_fd = rp_predict_fd;
2175 rp_offset = rp_predict_offset;
2180 rp_predict_length = MIN(rp_predict_length,2*ReadSize);
2181 rp_predict_length = MAX(rp_predict_length,1024);
2182 rp_offset = (rp_offset/1024)*1024;
2183 rp_predict_length = (rp_predict_length/1024)*1024;
2185 if (rp_predict_length > rp_alloced)
2187 rp_buffer = Realloc(rp_buffer,rp_predict_length);
2188 rp_alloced = rp_predict_length;
2191 DEBUG(0,("can't allocate read-prediction buffer\n"));
2199 if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
2205 rp_length = read(rp_fd,rp_buffer,rp_predict_length);
2206 rp_time = time(NULL);
2211 /****************************************************************************
2212 invalidate read-prediction on a fd
2213 ****************************************************************************/
2214 void invalidate_read_prediction(int fd)
2218 if (rp_predict_fd == fd)
2223 /****************************************************************************
2224 transfer some data between two fd's
2225 ****************************************************************************/
2226 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2228 static char *buf=NULL;
2230 static int size = 0;
2233 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2235 if ((size < ReadSize) && buf) {
2240 size = MAX(ReadSize,1024);
2242 while (!buf && size>0) {
2243 buf = (char *)Realloc(buf,size+8);
2244 if (!buf) size /= 2;
2247 DEBUG(0,("Can't allocate transfer buffer!\n"));
2251 abuf = buf + (align%8);
2258 int s = MIN(n,size);
2263 if (header && (headlen >= MIN(s,1024))) {
2273 if (header && headlen > 0)
2275 ret = MIN(headlen,size);
2276 memcpy(buf1,header,ret);
2279 if (headlen <= 0) header = NULL;
2283 ret += read(infd,buf1+ret,s-ret);
2287 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2288 if (ret2 > 0) total += ret2;
2289 /* if we can't write then dump excess data */
2291 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2293 if (ret <= 0 || ret2 != ret)
2301 /****************************************************************************
2302 read 4 bytes of a smb packet and return the smb length of the packet
2303 possibly store the result in the buffer
2304 ****************************************************************************/
2305 int read_smb_length(int fd,char *inbuf,int timeout)
2309 int len=0, msg_type;
2320 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2322 ok = (read_data(fd,buffer,4) == 4);
2328 DEBUG(10,("select timeout (%d)\n", timeout));
2333 DEBUG(6,("couldn't read from client\n"));
2338 len = smb_len(buffer);
2339 msg_type = CVAL(buffer,0);
2341 if (msg_type == 0x85)
2343 DEBUG(5,( "Got keepalive packet\n"));
2348 DEBUG(10,("got smb length of %d\n",len));
2355 /****************************************************************************
2356 read an smb from a fd and return it's length
2357 The timeout is in milli seconds
2358 ****************************************************************************/
2359 BOOL receive_smb(int fd,char *buffer,int timeout)
2364 bzero(buffer,smb_size + 100);
2366 len = read_smb_length(fd,buffer,timeout);
2370 if (len > BUFFER_SIZE) {
2371 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2372 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2376 ok = (read_data(fd,buffer+4,len) == len);
2388 /****************************************************************************
2390 ****************************************************************************/
2391 BOOL send_smb(int fd,char *buffer)
2395 len = smb_len(buffer) + 4;
2397 while (nwritten < len)
2399 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2402 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2414 /****************************************************************************
2415 find a pointer to a netbios name
2416 ****************************************************************************/
2417 char *name_ptr(char *buf,int ofs)
2419 unsigned char c = *(unsigned char *)(buf+ofs);
2421 if ((c & 0xC0) == 0xC0)
2425 memcpy(p,buf+ofs,2);
2428 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2435 /****************************************************************************
2436 extract a netbios name from a buf
2437 ****************************************************************************/
2438 int name_extract(char *buf,int ofs,char *name)
2440 char *p = name_ptr(buf,ofs);
2441 int d = PTR_DIFF(p,buf+ofs);
2443 if (d < -50 || d > 50) return(0);
2444 return(name_interpret(p,name));
2448 /****************************************************************************
2449 return the total storage length of a mangled name
2450 ****************************************************************************/
2451 int name_len(char *s)
2454 unsigned char c = *(unsigned char *)s;
2455 if ((c & 0xC0) == 0xC0)
2457 while (*s) s += (*s)+1;
2458 return(PTR_DIFF(s,s0)+1);
2461 /****************************************************************************
2462 send a single packet to a port on another machine
2463 ****************************************************************************/
2464 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2468 struct sockaddr_in sock_out;
2473 /* create a socket to write to */
2474 out_fd = socket(AF_INET, type, 0);
2477 DEBUG(0,("socket failed"));
2481 /* set the address and port */
2482 bzero((char *)&sock_out,sizeof(sock_out));
2483 putip((char *)&sock_out.sin_addr,(char *)&ip);
2484 sock_out.sin_port = htons( port );
2485 sock_out.sin_family = AF_INET;
2488 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2489 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2492 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2495 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2496 inet_ntoa(ip),port,errno));
2502 /*******************************************************************
2503 sleep for a specified number of milliseconds
2504 ********************************************************************/
2508 struct timeval tval,t1,t2;
2515 tval.tv_sec = (t-tdiff)/1000;
2516 tval.tv_usec = 1000*((t-tdiff)%1000);
2520 sys_select(&fds,&tval);
2523 tdiff = TvalDiff(&t1,&t2);
2527 /****************************************************************************
2528 check if a string is part of a list
2529 ****************************************************************************/
2530 BOOL in_list(char *s,char *list,BOOL casesensitive)
2535 if (!list) return(False);
2537 while (next_token(&p,tok,LIST_SEP))
2539 if (casesensitive) {
2540 if (strcmp(tok,s) == 0)
2543 if (StrCaseCmp(tok,s) == 0)
2550 /* this is used to prevent lots of mallocs of size 1 */
2551 static char *null_string = NULL;
2553 /****************************************************************************
2554 set a string value, allocing the space for the string
2555 ****************************************************************************/
2556 BOOL string_init(char **dest,char *src)
2567 null_string = (char *)malloc(1);
2570 *dest = null_string;
2574 *dest = (char *)malloc(l+1);
2580 /****************************************************************************
2582 ****************************************************************************/
2583 void string_free(char **s)
2585 if (!s || !(*s)) return;
2586 if (*s == null_string)
2592 /****************************************************************************
2593 set a string value, allocing the space for the string, and deallocating any
2595 ****************************************************************************/
2596 BOOL string_set(char **dest,char *src)
2600 return(string_init(dest,src));
2603 /****************************************************************************
2604 substitute a string for a pattern in another string. Make sure there is
2607 This routine looks for pattern in s and replaces it with
2608 insert. It may do multiple replacements.
2610 return True if a substitution was done.
2611 ****************************************************************************/
2612 BOOL string_sub(char *s,char *pattern,char *insert)
2618 if (!insert || !pattern || !s) return(False);
2621 lp = strlen(pattern);
2622 li = strlen(insert);
2624 if (!*pattern) return(False);
2626 while (lp <= ls && (p = strstr(s,pattern)))
2629 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2630 memcpy(p,insert,li);
2639 /*********************************************************
2640 * Recursive routine that is called by mask_match.
2641 * Does the actual matching.
2642 *********************************************************/
2643 BOOL do_match(char *str, char *regexp, int case_sig)
2647 for( p = regexp; *p && *str; ) {
2654 /* Look for a character matching
2655 the one after the '*' */
2658 return True; /* Automatic match */
2660 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2662 if(do_match(str,p,case_sig))
2676 if(toupper(*str) != toupper(*p))
2686 if (!*p && str[0] == '.' && str[1] == 0)
2689 if (!*str && *p == '?')
2691 while (*p == '?') p++;
2695 if(!*str && (*p == '*' && p[1] == '\0'))
2701 /*********************************************************
2702 * Routine to match a given string with a regexp - uses
2703 * simplified regexp that takes * and ? only. Case can be
2704 * significant or not.
2705 *********************************************************/
2706 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2710 fstring ebase,eext,sbase,sext;
2714 /* Make local copies of str and regexp */
2715 StrnCpy(p1,regexp,sizeof(pstring)-1);
2716 StrnCpy(p2,str,sizeof(pstring)-1);
2718 if (!strchr(p2,'.')) {
2723 if (!strchr(p1,'.')) {
2731 string_sub(p1,"*.*","*");
2732 string_sub(p1,".*","*");
2736 /* Remove any *? and ** as they are meaningless */
2737 for(p = p1; *p; p++)
2738 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2739 (void)strcpy( &p[1], &p[2]);
2741 if (strequal(p1,"*")) return(True);
2743 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2749 if ((p=strrchr(p1,'.'))) {
2758 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2768 matched = do_match(sbase,ebase,case_sig) &&
2769 (trans2 || do_match(sext,eext,case_sig));
2771 DEBUG(5,("mask_match returning %d\n", matched));
2778 /****************************************************************************
2779 become a daemon, discarding the controlling terminal
2780 ****************************************************************************/
2781 void become_daemon(void)
2783 #ifndef NO_FORK_DEBUG
2787 /* detach from the terminal */
2793 int i = open("/dev/tty", O_RDWR);
2796 ioctl(i, (int) TIOCNOTTY, (char *)0);
2805 /****************************************************************************
2806 calculate the default netmask for an address
2807 ****************************************************************************/
2808 static void default_netmask(struct in_addr *inm, struct in_addr *iad)
2810 unsigned long ad = ntohl(iad->s_addr);
2813 ** Guess a netmask based on the class of the IP address given.
2815 if ( (ad & 0x80000000) == 0 ) {
2816 /* class A address */
2818 } else if ( (ad & 0xC0000000) == 0x80000000 ) {
2819 /* class B address */
2821 } else if ( (ad & 0xE0000000) == 0xC0000000 ) {
2822 /* class C address */
2825 /* class D or E; netmask doesn't make much sense - guess 4 bits */
2828 inm->s_addr = htonl(nm);
2831 /****************************************************************************
2832 get the broadcast address for our address
2833 (troyer@saifr00.ateng.az.honeywell.com)
2834 ****************************************************************************/
2835 void get_broadcast(struct in_addr *if_ipaddr,
2836 struct in_addr *if_bcast,
2837 struct in_addr *if_nmask)
2840 #ifndef NO_GET_BROADCAST
2841 int sock = -1; /* AF_INET raw socket desc */
2843 struct ifreq *ifr=NULL;
2846 #if defined(EVEREST)
2849 struct ifreq *ifreqs;
2850 #elif defined(USE_IFREQ)
2852 struct strioctl strioctl;
2859 /* get a default netmask and broadcast */
2860 default_netmask(if_nmask, if_ipaddr);
2862 #ifndef NO_GET_BROADCAST
2863 /* Create a socket to the INET kernel. */
2865 if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
2867 if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
2870 DEBUG(0,( "Unable to open socket to get broadcast address\n"));
2874 /* Get a list of the configured interfaces */
2876 /* This is part of SCO Openserver 5: The ioctls are no longer part
2877 if the lower level STREAMS interface glue. They are now real
2880 if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
2881 DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
2883 DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
2885 ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
2886 ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
2888 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
2889 DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
2893 for (i = 0; i < n_interfaces; ++i) {
2894 if (if_ipaddr->s_addr ==
2895 ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
2902 #elif defined(USE_IFREQ)
2903 ifc = (struct ifconf *)buff;
2904 ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
2905 strioctl.ic_cmd = SIOCGIFCONF;
2906 strioctl.ic_dp = (char *)ifc;
2907 strioctl.ic_len = sizeof(buff);
2908 if (ioctl(sock, I_STR, &strioctl) < 0) {
2909 DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
2911 ifr = (struct ifreq *)ifc->ifc_req;
2913 /* Loop through interfaces, looking for given IP address */
2914 for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
2915 if (if_ipaddr->s_addr ==
2916 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2922 #elif defined(__FreeBSD__) || defined(NETBSD)
2923 ifc.ifc_len = sizeof(buff);
2925 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
2926 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
2929 /* Loop through interfaces, looking for given IP address */
2932 if (if_ipaddr->s_addr ==
2933 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2937 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
2938 ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
2942 ifc.ifc_len = sizeof(buff);
2944 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
2945 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
2949 /* Loop through interfaces, looking for given IP address */
2950 for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
2952 if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
2954 if (if_ipaddr->s_addr ==
2955 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
2964 DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
2966 /* Get the netmask address from the kernel */
2970 strioctl.ic_cmd = SIOCGIFNETMASK;
2971 strioctl.ic_dp = (char *)&ifreq;
2972 strioctl.ic_len = sizeof(struct ifreq);
2973 if (ioctl(sock, I_STR, &strioctl) < 0)
2974 DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
2976 *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
2978 if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
2979 DEBUG(0,("SIOCGIFNETMASK failed\n"));
2981 *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
2984 DEBUG(2,("Netmask for %s = %s\n", ifr->ifr_name,
2985 inet_ntoa(*if_nmask)));
2993 /* sanity check on the netmask */
2995 unsigned long nm = ntohl(if_nmask->s_addr);
2996 if ((nm >> 24) != 0xFF) {
2997 DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
2998 default_netmask(if_nmask, if_ipaddr);
3002 /* derive the broadcast assuming a 1's broadcast, as this is what
3003 all MS operating systems do, we have to comply even if the unix
3004 box is setup differently */
3006 unsigned long ad = ntohl(if_ipaddr->s_addr);
3007 unsigned long nm = ntohl(if_nmask->s_addr);
3008 unsigned long bc = (ad & nm) | (0xffffffff & ~nm);
3009 if_bcast->s_addr = htonl(bc);
3012 DEBUG(2,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
3013 } /* get_broadcast */
3016 /****************************************************************************
3017 put up a yes/no prompt
3018 ****************************************************************************/
3024 if (!fgets(ans,sizeof(ans)-1,stdin))
3027 if (*ans == 'y' || *ans == 'Y')
3033 /****************************************************************************
3034 read a line from a file with possible \ continuation chars.
3035 Blanks at the start or end of a line are stripped.
3036 The string will be allocated if s2 is NULL
3037 ****************************************************************************/
3038 char *fgets_slash(char *s2,int maxlen,FILE *f)
3043 BOOL start_of_line = True;
3050 maxlen = MIN(maxlen,8);
3051 s = (char *)Realloc(s,maxlen);
3054 if (!s || maxlen < 2) return(NULL);
3058 while (len < maxlen-1)
3066 while (len > 0 && s[len-1] == ' ')
3070 if (len > 0 && s[len-1] == '\\')
3073 start_of_line = True;
3078 if (len <= 0 && !s2)
3080 return(len>0?s:NULL);
3085 start_of_line = False;
3089 if (!s2 && len > maxlen-3)
3092 s = (char *)Realloc(s,maxlen);
3093 if (!s) return(NULL);
3101 /****************************************************************************
3102 set the length of a file from a filedescriptor.
3103 Returns 0 on success, -1 on failure.
3104 ****************************************************************************/
3105 int set_filelen(int fd, long len)
3107 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3108 extend a file with ftruncate. Provide alternate implementation
3111 #if FTRUNCATE_CAN_EXTEND
3112 return ftruncate(fd, len);
3116 long currpos = lseek(fd, 0L, SEEK_CUR);
3120 /* Do an fstat to see if the file is longer than
3121 the requested size (call ftruncate),
3122 or shorter, in which case seek to len - 1 and write 1
3124 if(fstat(fd, &st)<0)
3128 if (S_ISFIFO(st.st_mode)) return 0;
3131 if(st.st_size == len)
3133 if(st.st_size > len)
3134 return ftruncate(fd, len);
3136 if(lseek(fd, len-1, SEEK_SET) != len -1)
3138 if(write(fd, &c, 1)!=1)
3140 /* Seek to where we were */
3141 lseek(fd, currpos, SEEK_SET);
3147 /****************************************************************************
3148 return the byte checksum of some data
3149 ****************************************************************************/
3150 int byte_checksum(char *buf,int len)
3152 unsigned char *p = (unsigned char *)buf;
3162 /****************************************************************************
3163 this is a version of setbuffer() for those machines that only have setvbuf
3164 ****************************************************************************/
3165 void setbuffer(FILE *f,char *buf,int bufsize)
3167 setvbuf(f,buf,_IOFBF,bufsize);
3172 /****************************************************************************
3173 parse out a directory name from a path name. Assumes dos style filenames.
3174 ****************************************************************************/
3175 char *dirname_dos(char *path,char *buf)
3177 char *p = strrchr(path,'\\');
3192 /****************************************************************************
3193 parse out a filename from a path name. Assumes dos style filenames.
3194 ****************************************************************************/
3195 static char *filename_dos(char *path,char *buf)
3197 char *p = strrchr(path,'\\');
3209 /****************************************************************************
3210 expand a pointer to be a particular size
3211 ****************************************************************************/
3212 void *Realloc(void *p,int size)
3218 DEBUG(5,("Realloc asked for 0 bytes\n"));
3223 ret = (void *)malloc(size);
3225 ret = (void *)realloc(p,size);
3228 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3234 /****************************************************************************
3236 ****************************************************************************/
3237 char *strdup(char *s)
3240 if (!s) return(NULL);
3241 ret = (char *)malloc(strlen(s)+1);
3242 if (!ret) return(NULL);
3249 /****************************************************************************
3250 Signal handler for SIGPIPE (write on a disconnected socket)
3251 ****************************************************************************/
3254 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3259 #ifdef REPLACE_STRLEN
3260 /****************************************************************************
3261 a replacement strlen() that returns int for solaris
3262 ****************************************************************************/
3274 /*******************************************************************
3275 ftruncate for operating systems that don't have it
3276 ********************************************************************/
3277 int ftruncate(int f,long l)
3284 fl.l_type = F_WRLCK;
3285 return fcntl(f, F_FREESP, &fl);
3291 /****************************************************************************
3292 get my own name and IP
3293 ****************************************************************************/
3294 BOOL get_myname(char *myname,struct in_addr *ip)
3301 /* get my host name */
3302 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3304 DEBUG(0,("gethostname failed\n"));
3309 if ((hp = Get_Hostbyname(hostname)) == 0)
3311 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3317 /* split off any parts after an initial . */
3318 char *p = strchr(hostname,'.');
3321 strcpy(myname,hostname);
3325 putip((char *)ip,(char *)hp->h_addr);
3331 /****************************************************************************
3332 true if two IP addresses are equal
3333 ****************************************************************************/
3334 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3336 unsigned long a1,a2;
3337 a1 = ntohl(ip1.s_addr);
3338 a2 = ntohl(ip2.s_addr);
3343 /****************************************************************************
3344 open a socket of the specified type, port and address for incoming data
3345 ****************************************************************************/
3346 int open_socket_in(int type, int port, int dlevel)
3349 struct sockaddr_in sock;
3353 /* get my host name */
3354 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3355 { DEBUG(0,("gethostname failed\n")); return -1; }
3358 if ((hp = Get_Hostbyname(host_name)) == 0)
3360 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3364 bzero((char *)&sock,sizeof(sock));
3365 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3366 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3367 sock.sin_len = sizeof(sock);
3369 sock.sin_port = htons( port );
3370 sock.sin_family = hp->h_addrtype;
3371 sock.sin_addr.s_addr = INADDR_ANY;
3372 res = socket(hp->h_addrtype, type, 0);
3374 { DEBUG(0,("socket failed\n")); return -1; }
3378 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3381 /* now we've got a socket - we need to bind it */
3382 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3385 if (port == 139 || port == 137)
3386 DEBUG(dlevel,("bind failed on port %d (%s)\n",
3387 port,strerror(errno)));
3390 if (dlevel > 0 && port < 1000)
3393 if (port >= 1000 && port < 9000)
3394 return(open_socket_in(type,port+1,dlevel));
3399 DEBUG(3,("bind succeeded on port %d\n",port));
3405 /****************************************************************************
3406 create an outgoing socket
3407 **************************************************************************/
3408 int open_socket_out(int type, struct in_addr *addr, int port )
3410 struct sockaddr_in sock_out;
3413 /* create a socket to write to */
3414 res = socket(PF_INET, type, 0);
3416 { DEBUG(0,("socket error\n")); return -1; }
3418 if (type != SOCK_STREAM) return(res);
3420 bzero((char *)&sock_out,sizeof(sock_out));
3421 putip((char *)&sock_out.sin_addr,(char *)addr);
3423 sock_out.sin_port = htons( port );
3424 sock_out.sin_family = PF_INET;
3426 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3428 /* and connect it to the destination */
3429 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
3430 DEBUG(0,("connect error: %s\n",strerror(errno)));
3439 /****************************************************************************
3440 interpret a protocol description string, with a default
3441 ****************************************************************************/
3442 int interpret_protocol(char *str,int def)
3444 if (strequal(str,"NT1"))
3445 return(PROTOCOL_NT1);
3446 if (strequal(str,"LANMAN2"))
3447 return(PROTOCOL_LANMAN2);
3448 if (strequal(str,"LANMAN1"))
3449 return(PROTOCOL_LANMAN1);
3450 if (strequal(str,"CORE"))
3451 return(PROTOCOL_CORE);
3452 if (strequal(str,"COREPLUS"))
3453 return(PROTOCOL_COREPLUS);
3454 if (strequal(str,"CORE+"))
3455 return(PROTOCOL_COREPLUS);
3457 DEBUG(0,("Unrecognised protocol level %s\n",str));
3462 /****************************************************************************
3463 interpret a security level
3464 ****************************************************************************/
3465 int interpret_security(char *str,int def)
3467 if (strequal(str,"SERVER"))
3469 if (strequal(str,"USER"))
3471 if (strequal(str,"SHARE"))
3474 DEBUG(0,("Unrecognised security level %s\n",str));
3480 /****************************************************************************
3481 interpret an internet address or name into an IP address in 4 byte form
3482 ****************************************************************************/
3483 unsigned long interpret_addr(char *str)
3488 if (strcmp(str,"0.0.0.0") == 0) return(0);
3489 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3491 /* if it's in the form of an IP address then get the lib to interpret it */
3492 if (isdigit(str[0])) {
3493 res = inet_addr(str);
3495 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
3496 if ((hp = Get_Hostbyname(str)) == 0) {
3497 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3500 putip((char *)&res,(char *)hp->h_addr);
3503 if (res == (unsigned long)-1) return(0);
3508 /*******************************************************************
3509 a convenient addition to interpret_addr()
3510 ******************************************************************/
3511 struct in_addr *interpret_addr2(char *str)
3513 static struct in_addr ret;
3514 unsigned long a = interpret_addr(str);
3515 putip((char *)&ret,(char *)&a);
3519 /*******************************************************************
3520 check if an IP is the 0.0.0.0
3521 ******************************************************************/
3522 BOOL zero_ip(struct in_addr ip)
3525 putip((char *)&a,(char *)&ip);
3529 /*******************************************************************
3530 sub strings with useful parameters
3531 ********************************************************************/
3532 void standard_sub_basic(char *s)
3534 if (!strchr(s,'%')) return;
3536 string_sub(s,"%R",remote_proto);
3537 string_sub(s,"%a",remote_arch);
3538 string_sub(s,"%m",remote_machine);
3539 string_sub(s,"%L",local_machine);
3541 if (!strchr(s,'%')) return;
3543 string_sub(s,"%v",VERSION);
3544 string_sub(s,"%h",myhostname);
3545 string_sub(s,"%U",sesssetup_user);
3547 if (!strchr(s,'%')) return;
3549 string_sub(s,"%I",Client_info.addr);
3550 string_sub(s,"%M",Client_info.name);
3551 string_sub(s,"%T",timestring());
3553 if (!strchr(s,'%')) return;
3557 sprintf(pidstr,"%d",(int)getpid());
3558 string_sub(s,"%d",pidstr);
3561 if (!strchr(s,'%')) return;
3564 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3566 string_sub(s,"%G",gidtoname(pass->pw_gid));
3572 /*******************************************************************
3573 write a string in unicoode format
3574 ********************************************************************/
3575 int PutUniCode(char *dst,char *src)
3579 dst[ret++] = src[0];
3589 pstring smbrun_path = SMBRUN;
3591 /****************************************************************************
3592 run a command via system() using smbrun
3593 ****************************************************************************/
3594 int smbrun(char *cmd,char *outfile)
3599 if (!file_exist(smbrun_path,NULL))
3601 DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",smbrun_path));
3605 sprintf(syscmd,"%s \"(%s 2>&1) > %s\"",
3607 outfile?outfile:"/dev/null");
3609 DEBUG(5,("smbrun - running %s ",syscmd));
3610 ret = system(syscmd);
3611 DEBUG(5,("gave %d\n",ret));
3616 /****************************************************************************
3617 a wrapper for gethostbyname() that tries with all lower and all upper case
3618 if the initial name fails
3619 ****************************************************************************/
3620 struct hostent *Get_Hostbyname(char *name)
3622 char *name2 = strdup(name);
3623 struct hostent *ret;
3627 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3631 if (!isalnum(*name2))
3637 ret = gethostbyname(name2);
3644 /* try with all lowercase */
3646 ret = gethostbyname(name2);
3653 /* try with all uppercase */
3655 ret = gethostbyname(name2);
3662 /* nothing works :-( */
3668 /****************************************************************************
3669 check if a process exists. Does this work on all unixes?
3670 ****************************************************************************/
3671 BOOL process_exists(int pid)
3675 sprintf(s,"/proc/%d",pid);
3676 return(directory_exist(s,NULL));
3679 static BOOL tested=False;
3680 static BOOL ok=False;
3684 sprintf(s,"/proc/%05d",getpid());
3685 ok = file_exist(s,NULL);
3688 sprintf(s,"/proc/%05d",pid);
3689 return(file_exist(s,NULL));
3693 /* a best guess for non root access */
3694 if (geteuid() != 0) return(True);
3696 /* otherwise use kill */
3697 return(pid == getpid() || kill(pid,0) == 0);
3702 /*******************************************************************
3703 turn a uid into a user name
3704 ********************************************************************/
3705 char *uidtoname(int uid)
3707 static char name[40];
3708 struct passwd *pass = getpwuid(uid);
3709 if (pass) return(pass->pw_name);
3710 sprintf(name,"%d",uid);
3714 /*******************************************************************
3715 turn a gid into a group name
3716 ********************************************************************/
3717 char *gidtoname(int gid)
3719 static char name[40];
3720 struct group *grp = getgrgid(gid);
3721 if (grp) return(grp->gr_name);
3722 sprintf(name,"%d",gid);
3726 /*******************************************************************
3728 ********************************************************************/
3729 void BlockSignals(BOOL block)
3732 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3733 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3736 sigblock(block_mask);
3738 sigunblock(block_mask);
3743 /*******************************************************************
3744 my own panic function - not suitable for general use
3745 ********************************************************************/
3746 void ajt_panic(void)
3748 pstring cmd = "/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &";
3754 #define DIRECT direct
3756 #define DIRECT dirent
3759 /*******************************************************************
3760 a readdir wrapper which just returns the file name
3761 also return the inode number if requested
3762 ********************************************************************/
3763 char *readdirname(void *p)
3768 if (!p) return(NULL);
3770 ptr = (struct DIRECT *)readdir(p);
3771 if (!ptr) return(NULL);
3773 dname = ptr->d_name;
3779 unix_to_dos(buf, True);
3785 if (telldir(p) < 0) return(NULL);
3789 /* this handles a broken compiler setup, causing a mixture
3790 of BSD and SYSV headers and libraries */
3792 static BOOL broken_readdir = False;
3793 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3795 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3796 broken_readdir = True;
3808 #if (defined(SecureWare) && defined(SCO))
3809 /* This is needed due to needing the nap() function but we don't want
3810 to include the Xenix libraries since that will break other things...
3811 BTW: system call # 0x0c28 is the same as calling nap() */
3812 long nap(long milliseconds) {
3813 return syscall(0x0c28, milliseconds);
3817 #ifdef NO_INITGROUPS
3818 #include <sys/types.h>
3823 #define NULL (void *)0
3826 /****************************************************************************
3827 some systems don't have an initgroups call
3828 ****************************************************************************/
3829 int initgroups(char *name,gid_t id)
3832 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
3835 gid_t grouplst[NGROUPS_MAX];
3842 while (i < NGROUPS_MAX &&
3843 ((g = (struct group *)getgrent()) != (struct group *)NULL))
3845 if (g->gr_gid == id)
3849 while (gr && (*gr != (char)NULL)) {
3850 if (strcmp(name,gr) == 0) {
3851 grouplst[i] = g->gr_gid;
3856 gr = g->gr_mem[++j];
3860 return(setgroups(i,grouplst));
3868 /* undo the wrapping temporarily */
3873 /****************************************************************************
3874 wrapper for malloc() to catch memory errors
3875 ****************************************************************************/
3876 void *malloc_wrapped(int size,char *file,int line)
3878 #ifdef xx_old_malloc
3879 void *res = xx_old_malloc(size);
3881 void *res = malloc(size);
3883 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3885 size,(unsigned int)res));
3889 /****************************************************************************
3890 wrapper for realloc() to catch memory errors
3891 ****************************************************************************/
3892 void *realloc_wrapped(void *ptr,int size,char *file,int line)
3894 #ifdef xx_old_realloc
3895 void *res = xx_old_realloc(ptr,size);
3897 void *res = realloc(ptr,size);
3899 DEBUG(3,("Realloc\n"));
3900 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3902 (unsigned int)ptr));
3903 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
3905 size,(unsigned int)res));
3909 /****************************************************************************
3910 wrapper for free() to catch memory errors
3911 ****************************************************************************/
3912 void free_wrapped(void *ptr,char *file,int line)
3919 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
3920 file,line,(unsigned int)ptr));
3924 /* and re-do the define for spots lower in this file */
3925 #define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
3926 #define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
3927 #define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
3931 #ifdef REPLACE_STRSTR
3932 /****************************************************************************
3933 Mips version of strstr doesn't seem to work correctly.
3934 There is a #define in includes.h to redirect calls to this function.
3935 ****************************************************************************/
3936 char *Strstr(char *s, char *p)
3938 int len = strlen(p);
3940 while ( *s != '\0' ) {
3941 if ( strncmp(s, p, len) == 0 )
3948 #endif /* REPLACE_STRSTR */
3951 #ifdef REPLACE_MKTIME
3952 /*******************************************************************
3953 a mktime() replacement for those who don't have it - contributed by
3954 C.A. Lademann <cal@zls.com>
3955 ********************************************************************/
3957 #define HOUR 60*MINUTE
3959 #define YEAR 365*DAY
3960 time_t Mktime(struct tm *t)
3964 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
3970 epoch = (t->tm_year - 70) * YEAR +
3971 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
3976 for(i = 0; i < t->tm_mon; i++) {
3977 epoch += mon [m] * DAY;
3978 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
3987 epoch += (t->tm_mday - 1) * DAY;
3988 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
3990 if((u = localtime(&epoch)) != NULL) {
3991 t->tm_sec = u->tm_sec;
3992 t->tm_min = u->tm_min;
3993 t->tm_hour = u->tm_hour;
3994 t->tm_mday = u->tm_mday;
3995 t->tm_mon = u->tm_mon;
3996 t->tm_year = u->tm_year;
3997 t->tm_wday = u->tm_wday;
3998 t->tm_yday = u->tm_yday;
3999 t->tm_isdst = u->tm_isdst;
4001 memcpy(t->tm_name, u->tm_name, LTZNMAX);
4007 #endif /* REPLACE_MKTIME */
4011 #ifdef REPLACE_RENAME
4012 /* Rename a file. (from libiberty in GNU binutils) */
4018 if (link (zfrom, zto) < 0)
4020 if (errno != EEXIST)
4022 if (unlink (zto) < 0
4023 || link (zfrom, zto) < 0)
4026 return unlink (zfrom);
4031 #ifdef REPLACE_INNETGR
4033 * Search for a match in a netgroup. This replaces it on broken systems.
4035 int InNetGr(group, host, user, dom)
4036 char *group, *host, *user, *dom;
4038 char *hst, *usr, *dm;
4041 while (getnetgrent(&hst, &usr, &dm))
4042 if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
4043 ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
4044 ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
4056 /*******************************************************************
4057 a wrapper around memcpy for diagnostic purposes
4058 ********************************************************************/
4059 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
4061 if (l>64 && (((int)d)%4) != (((int)s)%4))
4062 DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
4063 #ifdef xx_old_memcpy
4064 return(xx_old_memcpy(d,s,l));
4066 return(memcpy(d,s,l));
4069 #define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)