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;
35 /* a default finfo structure to ensure all fields are sensible */
36 file_info def_finfo = {-1,0,0,0,0,0,0,""};
38 /* these are some file handles where debug info will be stored */
41 /* the client file descriptor */
44 /* info on the client */
45 struct from_host Client_info=
46 {"UNKNOWN","0.0.0.0",NULL};
48 /* the last IP received from */
49 struct in_addr lastip;
51 /* the last port received from */
54 /* my IP, the broadcast IP and the Netmask */
56 struct in_addr bcast_ip;
57 struct in_addr Netmask;
62 case handling on filenames
64 int case_default = CASE_LOWER;
67 /* size of reads during a direct file to file transfer */
68 int ReadSize = 16*1024;
70 pstring debugf = "/tmp/log.samba";
73 /* the following control case operations - they are put here so the
74 client can link easily */
77 BOOL use_mangled_map = False;
78 BOOL short_case_preserve;
81 fstring remote_machine="";
82 fstring local_machine="";
83 fstring remote_arch="UNKNOWN";
84 fstring remote_proto="UNKNOWN";
85 pstring myhostname="";
86 pstring user_socket_options="";
87 pstring sesssetup_user="";
90 static char *filename_dos(char *path,char *buf);
92 static BOOL stdout_logging = False;
95 /*******************************************************************
96 get ready for syslog stuff
97 ******************************************************************/
98 void setup_logging(char *pname,BOOL interactive)
102 char *p = strrchr(pname,'/');
104 openlog(pname, LOG_PID, LOG_DAEMON);
108 stdout_logging = True;
114 BOOL append_log=False;
117 /****************************************************************************
119 ****************************************************************************/
120 void reopen_logs(void)
127 strcpy(fname,debugf);
128 if (lp_loaded() && (*lp_logfile()))
129 strcpy(fname,lp_logfile());
131 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
133 strcpy(debugf,fname);
134 if (dbf) fclose(dbf);
136 dbf = fopen(debugf,"a");
138 dbf = fopen(debugf,"w");
139 if (dbf) setbuf(dbf,NULL);
153 /*******************************************************************
154 check if the log has grown too big
155 ********************************************************************/
156 static void check_log_size(void)
158 static int debug_count=0;
162 if (debug_count++ < 100) return;
164 maxlog = lp_max_log_size() * 1024;
165 if (!dbf || maxlog <= 0) return;
167 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
168 fclose(dbf); dbf = NULL;
170 if (dbf && file_size(debugf) > maxlog) {
172 fclose(dbf); dbf = NULL;
173 sprintf(name,"%s.old",debugf);
174 sys_rename(debugf,name);
182 /*******************************************************************
183 write an debug message on the debugfile. This is called by the DEBUG
185 ********************************************************************/
187 int Debug1(char *format_str, ...)
197 if (stdout_logging) {
199 va_start(ap, format_str);
202 format_str = va_arg(ap,char *);
204 vfprintf(dbf,format_str,ap);
210 if (!lp_syslog_only())
215 dbf = fopen(debugf,"w");
224 if (syslog_level < lp_syslog())
227 * map debug levels to syslog() priorities
228 * note that not all DEBUG(0, ...) calls are
231 static int priority_map[] = {
240 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
242 priority = LOG_DEBUG;
244 priority = priority_map[syslog_level];
247 va_start(ap, format_str);
250 format_str = va_arg(ap,char *);
252 vsprintf(msgbuf, format_str, ap);
256 syslog(priority, "%s", msgbuf);
261 if (!lp_syslog_only())
265 va_start(ap, format_str);
268 format_str = va_arg(ap,char *);
270 vfprintf(dbf,format_str,ap);
280 /****************************************************************************
281 routine to do file locking
282 ****************************************************************************/
283 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
290 uint32 mask = 0xC0000000;
292 /* make sure the count is reasonable, we might kill the lockd otherwise */
295 /* the offset is often strange - remove 2 of its bits if either of
296 the top two bits are set. Shift the top ones by two bits. This
297 still allows OLE2 apps to operate, but should stop lockd from
299 if ((offset & mask) != 0)
300 offset = (offset & ~mask) | ((offset & mask) >> 2);
302 unsigned long mask = ((unsigned)1<<31);
304 /* interpret negative counts as large numbers */
308 /* no negative offsets */
311 /* count + offset must be in range */
312 while ((offset < 0 || (offset + count < 0)) && mask)
320 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
323 lock.l_whence = SEEK_SET;
324 lock.l_start = (int)offset;
325 lock.l_len = (int)count;
330 ret = fcntl(fd,op,&lock);
333 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
339 (lock.l_type != F_UNLCK) &&
341 (lock.l_pid != getpid()))
343 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
347 /* it must be not locked or locked by me */
351 /* a lock set or unset */
354 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
355 offset,count,op,type,strerror(errno)));
357 /* perhaps it doesn't support this sort of locking?? */
360 DEBUG(3,("locking not supported? returning True\n"));
367 /* everything went OK */
368 DEBUG(5,("Lock call successful\n"));
376 /*******************************************************************
377 lock a file - returning a open file descriptor or -1 on failure
378 The timeout is in seconds. 0 means no timeout
379 ********************************************************************/
380 int file_lock(char *name,int timeout)
382 int fd = open(name,O_RDWR|O_CREAT,0666);
384 if (fd < 0) return(-1);
387 if (timeout) t = time(NULL);
388 while (!timeout || (time(NULL)-t < timeout)) {
389 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
390 msleep(LOCK_RETRY_TIMEOUT);
398 /*******************************************************************
399 unlock a file locked by file_lock
400 ********************************************************************/
401 void file_unlock(int fd)
405 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
410 /*******************************************************************
411 a gettimeofday wrapper
412 ********************************************************************/
413 void GetTimeOfDay(struct timeval *tval)
418 gettimeofday(tval,NULL);
422 int extra_time_offset = 0;
424 static int timediff = 0;
426 /*******************************************************************
427 init the time differences
428 ********************************************************************/
431 struct tm tm_utc,tm_local;
436 tm_utc = *(gmtime(&t));
437 tm_local = *(localtime(&t));
440 timediff = -tm_local.tm_gmtoff;
442 timediff = mktime(&tm_utc) - mktime(&tm_local);
445 if (serverzone == 0) {
446 serverzone = timediff - DSTDiff(t);
447 DEBUG(4,("Serverzone is %d\n",serverzone));
452 /*******************************************************************
453 return the DST offset for a particular time
454 We keep a table of DST offsets to prevent calling localtime() on each
455 call of this function. This saves a LOT of time on many unixes.
456 ********************************************************************/
457 int DSTDiff(time_t t)
459 static struct dst_table {time_t start,end; BOOL is_dst;} *dst_table = NULL;
460 static int table_size = 0;
464 if (t == 0) t = time(NULL);
467 for (i=0;i<table_size;i++)
468 if (t >= dst_table[i].start && t <= dst_table[i].end) break;
471 is_dst = dst_table[i].is_dst;
475 dst_table = (struct dst_table *)Realloc(dst_table,
476 sizeof(dst_table[0])*(i+1));
484 dst_table[i].is_dst = is_dst = (localtime(&t)->tm_isdst?True:False);
485 dst_table[i].start = dst_table[i].end = t;
487 /* no entry will cover more than 6 months */
488 low = t - 3*30*24*60*60;
490 /* widen the new entry using two bisection searches */
491 while (low+60*60 < dst_table[i].start) {
492 t = low + (dst_table[i].start-low)/2;
493 if ((localtime(&t)->tm_isdst?True:False) == is_dst)
494 dst_table[i].start = t;
499 high = low + 3*30*24*60*60;
500 while (high-60*60 > dst_table[i].end) {
501 t = high - (high-dst_table[i].end)/2;
502 if ((localtime(&t)->tm_isdst?True:False) == is_dst)
503 dst_table[i].end = t;
509 DEBUG(1,("Added DST entry from %s ",
510 asctime(localtime(&dst_table[i].start))));
511 DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)),
512 dst_table[i].is_dst));
517 return((is_dst?60*60:0) - (extra_time_offset*60));
520 /****************************************************************************
521 return the difference between local and GMT time
522 ****************************************************************************/
523 int TimeDiff(time_t t)
525 static BOOL initialised = False;
526 if (!initialised) {initialised=True; TimeInit();}
527 return(timediff - DSTDiff(t));
530 /****************************************************************************
531 try to optimise the localtime call, it can be quite expenive on some machines
532 timemul is normally LOCAL_TO_GMT, GMT_TO_LOCAL or 0
533 ****************************************************************************/
534 struct tm *LocalTime(time_t *t,int timemul)
539 t2 += timemul * TimeDiff(t2);
545 /****************************************************************************
546 determine if a file descriptor is in fact a socket
547 ****************************************************************************/
548 BOOL is_a_socket(int fd)
552 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
556 static char *last_ptr=NULL;
558 /****************************************************************************
559 Get the next token from a string, return False if none found
560 handles double-quotes.
561 Based on a routine by GJC@VILLAGE.COM.
562 Extensively modified by Andrew.Tridgell@anu.edu.au
563 ****************************************************************************/
564 BOOL next_token(char **ptr,char *buff,char *sep)
569 if (!ptr) ptr = &last_ptr;
570 if (!ptr) return(False);
574 /* default to simple separators */
575 if (!sep) sep = " \t\n\r";
577 /* find the first non sep char */
578 while(*s && strchr(sep,*s)) s++;
581 if (! *s) return(False);
583 /* copy over the token */
584 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
592 *ptr = (*s) ? s+1 : s;
599 /****************************************************************************
600 Convert list of tokens to array; dependent on above routine.
601 Uses last_ptr from above - bit of a hack.
602 ****************************************************************************/
603 char **toktocliplist(int *ctok, char *sep)
609 if (!sep) sep = " \t\n\r";
611 while(*s && strchr(sep,*s)) s++;
614 if (!*s) return(NULL);
618 while(*s && (!strchr(sep,*s))) s++;
619 while(*s && strchr(sep,*s)) *s++=0;
625 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
637 /*******************************************************************
638 safely copies memory, ensuring no overlap problems.
639 this is only used if the machine does not have it's own memmove().
640 this is not the fastest algorithm in town, but it will do for our
642 ********************************************************************/
643 void *MemMove(void *dest,void *src,int size)
647 if (dest==src || !size) return(dest);
649 d = (unsigned long)dest;
650 s = (unsigned long)src;
652 if ((d >= (s+size)) || (s >= (d+size))) {
654 memcpy(dest,src,size);
660 /* we can forward copy */
661 if (s-d >= sizeof(int) &&
662 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
663 /* do it all as words */
664 int *idest = (int *)dest;
665 int *isrc = (int *)src;
667 for (i=0;i<size;i++) idest[i] = isrc[i];
670 char *cdest = (char *)dest;
671 char *csrc = (char *)src;
672 for (i=0;i<size;i++) cdest[i] = csrc[i];
677 /* must backward copy */
678 if (d-s >= sizeof(int) &&
679 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
680 /* do it all as words */
681 int *idest = (int *)dest;
682 int *isrc = (int *)src;
684 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
687 char *cdest = (char *)dest;
688 char *csrc = (char *)src;
689 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
697 /****************************************************************************
698 prompte a dptr (to make it recently used)
699 ****************************************************************************/
700 void array_promote(char *array,int elsize,int element)
706 p = (char *)malloc(elsize);
710 DEBUG(5,("Ahh! Can't malloc\n"));
713 memcpy(p,array + element * elsize, elsize);
714 memmove(array + elsize,array,elsize*element);
715 memcpy(array,p,elsize);
719 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
728 } socket_options[] = {
729 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
730 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
731 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
733 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
735 #ifdef IPTOS_LOWDELAY
736 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
738 #ifdef IPTOS_THROUGHPUT
739 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
742 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
745 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
748 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
751 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
757 /****************************************************************************
758 set user socket options
759 ****************************************************************************/
760 void set_socket_options(int fd, char *options)
764 while (next_token(&options,tok," \t,"))
769 BOOL got_value = False;
771 if ((p = strchr(tok,'=')))
778 for (i=0;socket_options[i].name;i++)
779 if (strequal(socket_options[i].name,tok))
782 if (!socket_options[i].name)
784 DEBUG(0,("Unknown socket option %s\n",tok));
788 switch (socket_options[i].opttype)
792 ret = setsockopt(fd,socket_options[i].level,
793 socket_options[i].option,(char *)&value,sizeof(int));
798 DEBUG(0,("syntax error - %s does not take a value\n",tok));
801 int on = socket_options[i].value;
802 ret = setsockopt(fd,socket_options[i].level,
803 socket_options[i].option,(char *)&on,sizeof(int));
809 DEBUG(0,("Failed to set socket option %s\n",tok));
815 /****************************************************************************
816 close the socket communication
817 ****************************************************************************/
818 void close_sockets(void )
824 /****************************************************************************
825 return the date and time as a string
826 ****************************************************************************/
827 char *timestring(void )
829 static char TimeBuf[100];
833 strcpy(TimeBuf, asctime(LocalTime(&t,GMT_TO_LOCAL)));
834 #elif defined(CLIX) || defined(CONVEX)
835 strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",LocalTime(&t,GMT_TO_LOCAL));
837 strftime(TimeBuf,100,"%D %r",LocalTime(&t,GMT_TO_LOCAL));
838 #elif defined(TZ_TIME)
840 strftime(TimeBuf,100,"%D:%T",LocalTime(&t,0));
841 sprintf(TimeBuf+strlen(TimeBuf)," %+03d%02d",
842 -TimeDiff(t)/(60*60),-(TimeDiff(t)/60)%60);
845 strftime(TimeBuf,100,"%D %T",LocalTime(&t,GMT_TO_LOCAL));
850 /****************************************************************************
851 determine whether we are in the specified group
852 ****************************************************************************/
853 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
857 if (group == current_gid) return(True);
859 for (i=0;i<ngroups;i++)
860 if (group == groups[i])
866 /****************************************************************************
867 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
868 ****************************************************************************/
869 char *StrCpy(char *dest,char *src)
874 /* I don't want to get lazy with these ... */
876 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
881 if (!dest) return(NULL);
886 while ((*d++ = *src++)) ;
890 /****************************************************************************
891 line strncpy but always null terminates. Make sure there is room!
892 ****************************************************************************/
893 char *StrnCpy(char *dest,const char *src,int n)
896 if (!dest) return(NULL);
901 while (n-- && (*d++ = *src++)) ;
907 /*******************************************************************
908 copy an IP address from one buffer to another
909 ********************************************************************/
910 void putip(void *dest,void *src)
916 /****************************************************************************
917 interpret the weird netbios "name". Return the name type
918 ****************************************************************************/
919 static int name_interpret(char *in,char *out)
922 int len = (*in++) / 2;
926 if (len > 30 || len<1) return(0);
930 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
934 *out = ((in[0]-'A')<<4) + (in[1]-'A');
942 /* Handle any scope names */
945 *out++ = '.'; /* Scope names are separated by periods */
946 len = *(unsigned char *)in++;
947 StrnCpy(out, in, len);
956 /****************************************************************************
957 mangle a name into netbios format
958 ****************************************************************************/
959 int name_mangle(char *In,char *Out,char name_type)
963 char *in = (char *)&buf[0];
964 char *out = (char *)Out;
969 StrnCpy(name,In,sizeof(name)-1);
970 sprintf(buf,"%-15.15s%c",name,name_type);
973 memset(&buf[1],0,16);
978 char c = toupper(in[i]);
979 out[i*2] = (c>>4) + 'A';
980 out[i*2+1] = (c & 0xF) + 'A';
988 p = strchr(label, '.');
990 p = label + strlen(label);
992 memcpy(out, label, p - label);
994 label += p - label + (*p == '.');
997 return(name_len(Out));
1001 /*******************************************************************
1002 check if a file exists
1003 ********************************************************************/
1004 BOOL file_exist(char *fname,struct stat *sbuf)
1007 if (!sbuf) sbuf = &st;
1009 if (sys_stat(fname,sbuf) != 0)
1012 return(S_ISREG(sbuf->st_mode));
1015 /*******************************************************************
1016 check a files mod time
1017 ********************************************************************/
1018 time_t file_modtime(char *fname)
1022 if (sys_stat(fname,&st) != 0)
1025 return(st.st_mtime);
1028 /*******************************************************************
1029 check if a directory exists
1030 ********************************************************************/
1031 BOOL directory_exist(char *dname,struct stat *st)
1036 if (sys_stat(dname,st) != 0)
1039 return(S_ISDIR(st->st_mode));
1042 /*******************************************************************
1043 returns the size in bytes of the named file
1044 ********************************************************************/
1045 uint32 file_size(char *file_name)
1049 sys_stat(file_name,&buf);
1050 return(buf.st_size);
1053 /****************************************************************************
1054 check if it's a null mtime
1055 ****************************************************************************/
1056 static BOOL null_mtime(time_t mtime)
1058 if (mtime == 0 || mtime == 0xFFFFFFFF)
1063 /*******************************************************************
1064 create a 16 bit dos packed date
1065 ********************************************************************/
1066 static uint16 make_dos_date1(time_t unixdate,struct tm *t)
1069 ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
1070 ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
1074 /*******************************************************************
1075 create a 16 bit dos packed time
1076 ********************************************************************/
1077 static uint16 make_dos_time1(time_t unixdate,struct tm *t)
1080 ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3));
1081 ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
1085 /*******************************************************************
1086 create a 32 bit dos packed date/time from some parameters
1087 This takes a GMT time and returns a packed localtime structure
1088 ********************************************************************/
1089 static uint32 make_dos_date(time_t unixdate)
1094 t = LocalTime(&unixdate,GMT_TO_LOCAL);
1096 ret = make_dos_date1(unixdate,t);
1097 ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t);
1102 /*******************************************************************
1103 put a dos date into a buffer (time/date format)
1104 This takes GMT time and puts local time in the buffer
1105 ********************************************************************/
1106 void put_dos_date(char *buf,int offset,time_t unixdate)
1108 uint32 x = make_dos_date(unixdate);
1109 SIVAL(buf,offset,x);
1112 /*******************************************************************
1113 put a dos date into a buffer (date/time format)
1114 This takes GMT time and puts local time in the buffer
1115 ********************************************************************/
1116 void put_dos_date2(char *buf,int offset,time_t unixdate)
1118 uint32 x = make_dos_date(unixdate);
1119 x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
1120 SIVAL(buf,offset,x);
1123 /*******************************************************************
1124 put a dos 32 bit "unix like" date into a buffer. This routine takes
1125 GMT and converts it to LOCAL time before putting it (most SMBs assume
1126 localtime for this sort of date)
1127 ********************************************************************/
1128 void put_dos_date3(char *buf,int offset,time_t unixdate)
1130 if (!null_mtime(unixdate))
1131 unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
1132 SIVAL(buf,offset,unixdate);
1135 /*******************************************************************
1136 interpret a 32 bit dos packed date/time to some parameters
1137 ********************************************************************/
1138 static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second)
1142 p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF;
1143 p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
1145 *second = 2*(p0 & 0x1F);
1146 *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
1147 *hour = (p1>>3)&0xFF;
1149 *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
1150 *year = ((p3>>1)&0xFF) + 80;
1153 /*******************************************************************
1154 create a unix date (int GMT) from a dos date (which is actually in
1156 ********************************************************************/
1157 time_t make_unix_date(void *date_ptr)
1163 dos_date = IVAL(date_ptr,0);
1165 if (dos_date == 0) return(0);
1167 interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
1168 &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
1173 /* mktime() also does the local to GMT time conversion for us. XXXXX
1174 Do all unixes do this the same?? */
1180 /*******************************************************************
1181 like make_unix_date() but the words are reversed
1182 ********************************************************************/
1183 time_t make_unix_date2(void *date_ptr)
1187 x = IVAL(date_ptr,0);
1188 x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
1191 return(make_unix_date((void *)&x));
1194 /*******************************************************************
1195 create a unix GMT date from a dos date in 32 bit "unix like" format
1196 these generally arrive as localtimes, with corresponding DST
1197 ********************************************************************/
1198 time_t make_unix_date3(void *date_ptr)
1200 time_t t = IVAL(date_ptr,0);
1202 t += LOCAL_TO_GMT*TimeDiff(t);
1206 /*******************************************************************
1207 return a string representing an attribute for a file
1208 ********************************************************************/
1209 char *attrib_string(int mode)
1211 static char attrstr[10];
1215 if (mode & aVOLID) strcat(attrstr,"V");
1216 if (mode & aDIR) strcat(attrstr,"D");
1217 if (mode & aARCH) strcat(attrstr,"A");
1218 if (mode & aHIDDEN) strcat(attrstr,"H");
1219 if (mode & aSYSTEM) strcat(attrstr,"S");
1220 if (mode & aRONLY) strcat(attrstr,"R");
1226 /*******************************************************************
1227 case insensitive string compararison
1228 ********************************************************************/
1229 int StrCaseCmp(char *s, char *t)
1231 for (; tolower(*s) == tolower(*t); ++s, ++t)
1234 return tolower(*s) - tolower(*t);
1237 /*******************************************************************
1238 case insensitive string compararison, length limited
1239 ********************************************************************/
1240 int StrnCaseCmp(char *s, char *t, int n)
1242 while (n-- && *s && *t) {
1243 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
1246 if (n) return(tolower(*s) - tolower(*t));
1251 /*******************************************************************
1253 ********************************************************************/
1254 BOOL strequal(char *s1,char *s2)
1256 if (s1 == s2) return(True);
1257 if (!s1 || !s2) return(False);
1259 return(StrCaseCmp(s1,s2)==0);
1262 /*******************************************************************
1263 compare 2 strings up to and including the nth char.
1264 ******************************************************************/
1265 BOOL strnequal(char *s1,char *s2,int n)
1267 if (s1 == s2) return(True);
1268 if (!s1 || !s2 || !n) return(False);
1270 return(StrnCaseCmp(s1,s2,n)==0);
1273 /*******************************************************************
1274 compare 2 strings (case sensitive)
1275 ********************************************************************/
1276 BOOL strcsequal(char *s1,char *s2)
1278 if (s1 == s2) return(True);
1279 if (!s1 || !s2) return(False);
1281 return(strcmp(s1,s2)==0);
1285 /*******************************************************************
1286 convert a string to lower case
1287 ********************************************************************/
1288 void strlower(char *s)
1293 if (is_shift_jis (*s)) {
1295 } else if (is_kana (*s)) {
1310 /*******************************************************************
1311 convert a string to upper case
1312 ********************************************************************/
1313 void strupper(char *s)
1318 if (is_shift_jis (*s)) {
1320 } else if (is_kana (*s)) {
1335 /*******************************************************************
1336 convert a string to "normal" form
1337 ********************************************************************/
1338 void strnorm(char *s)
1340 if (case_default == CASE_UPPER)
1346 /*******************************************************************
1347 check if a string is in "normal" case
1348 ********************************************************************/
1349 BOOL strisnormal(char *s)
1351 if (case_default == CASE_UPPER)
1352 return(!strhaslower(s));
1354 return(!strhasupper(s));
1358 /****************************************************************************
1360 ****************************************************************************/
1361 void string_replace(char *s,char oldc,char newc)
1366 if (is_shift_jis (*s)) {
1368 } else if (is_kana (*s)) {
1383 /****************************************************************************
1384 make a file into unix format
1385 ****************************************************************************/
1386 void unix_format(char *fname)
1389 string_replace(fname,'\\','/');
1391 dos2unix_format(fname, True);
1396 strcpy(namecopy,fname);
1398 strcat(fname,namecopy);
1402 /****************************************************************************
1403 make a file into dos format
1404 ****************************************************************************/
1405 void dos_format(char *fname)
1408 unix2dos_format(fname, True);
1410 string_replace(fname,'/','\\');
1414 /*******************************************************************
1415 show a smb message structure
1416 ********************************************************************/
1417 void show_msg(char *buf)
1424 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1426 (int)CVAL(buf,smb_com),
1427 (int)CVAL(buf,smb_rcls),
1428 (int)CVAL(buf,smb_reh),
1429 (int)SVAL(buf,smb_err),
1430 (int)CVAL(buf,smb_flg),
1431 (int)SVAL(buf,smb_flg2)));
1432 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1433 (int)SVAL(buf,smb_tid),
1434 (int)SVAL(buf,smb_pid),
1435 (int)SVAL(buf,smb_uid),
1436 (int)SVAL(buf,smb_mid),
1437 (int)CVAL(buf,smb_wct)));
1438 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1439 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1440 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1441 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1442 DEBUG(5,("smb_bcc=%d\n",bcc));
1443 if (DEBUGLEVEL < 10)
1445 for (i=0;i<MIN(bcc,128);i++)
1446 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1450 /*******************************************************************
1451 return the length of an smb packet
1452 ********************************************************************/
1453 int smb_len(char *buf)
1455 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1458 /*******************************************************************
1459 set the length of an smb packet
1460 ********************************************************************/
1461 void _smb_setlen(char *buf,int len)
1464 buf[1] = (len&0x10000)>>16;
1465 buf[2] = (len&0xFF00)>>8;
1469 /*******************************************************************
1470 set the length and marker of an smb packet
1471 ********************************************************************/
1472 void smb_setlen(char *buf,int len)
1474 _smb_setlen(buf,len);
1482 /*******************************************************************
1483 setup the word count and byte count for a smb message
1484 ********************************************************************/
1485 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1488 bzero(buf + smb_size,num_words*2 + num_bytes);
1489 CVAL(buf,smb_wct) = num_words;
1490 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1491 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1492 return (smb_size + num_words*2 + num_bytes);
1495 /*******************************************************************
1496 return the number of smb words
1497 ********************************************************************/
1498 int smb_numwords(char *buf)
1500 return (CVAL(buf,smb_wct));
1503 /*******************************************************************
1504 return the size of the smb_buf region of a message
1505 ********************************************************************/
1506 int smb_buflen(char *buf)
1508 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1511 /*******************************************************************
1512 return a pointer to the smb_buf data area
1513 ********************************************************************/
1514 int smb_buf_ofs(char *buf)
1516 return (smb_size + CVAL(buf,smb_wct)*2);
1519 /*******************************************************************
1520 return a pointer to the smb_buf data area
1521 ********************************************************************/
1522 char *smb_buf(char *buf)
1524 return (buf + smb_buf_ofs(buf));
1527 /*******************************************************************
1528 return the SMB offset into an SMB buffer
1529 ********************************************************************/
1530 int smb_offset(char *p,char *buf)
1532 return(PTR_DIFF(p,buf+4));
1536 /*******************************************************************
1537 skip past some strings in a buffer
1538 ********************************************************************/
1539 char *skip_string(char *buf,int n)
1542 buf += strlen(buf) + 1;
1546 /*******************************************************************
1547 trim the specified elements off the front and back of a string
1548 ********************************************************************/
1549 BOOL trim_string(char *s,char *front,char *back)
1552 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1558 if (!(*p = p[strlen(front)]))
1563 while (back && *back && strlen(s) >= strlen(back) &&
1564 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1567 s[strlen(s)-strlen(back)] = 0;
1573 /*******************************************************************
1574 reduce a file name, removing .. elements.
1575 ********************************************************************/
1576 void dos_clean_name(char *s)
1580 DEBUG(3,("dos_clean_name [%s]\n",s));
1582 /* remove any double slashes */
1583 string_sub(s, "\\\\", "\\");
1585 while ((p = strstr(s,"\\..\\")) != NULL)
1592 if ((p=strrchr(s,'\\')) != NULL)
1599 trim_string(s,NULL,"\\..");
1601 string_sub(s, "\\.\\", "\\");
1604 /*******************************************************************
1605 reduce a file name, removing .. elements.
1606 ********************************************************************/
1607 void unix_clean_name(char *s)
1611 DEBUG(3,("unix_clean_name [%s]\n",s));
1613 /* remove any double slashes */
1614 string_sub(s, "//","/");
1616 while ((p = strstr(s,"/../")) != NULL)
1623 if ((p=strrchr(s,'/')) != NULL)
1630 trim_string(s,NULL,"/..");
1634 /*******************************************************************
1635 a wrapper for the normal chdir() function
1636 ********************************************************************/
1637 int ChDir(char *path)
1640 static pstring LastDir="";
1642 if (strcsequal(path,".")) return(0);
1644 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1645 DEBUG(3,("chdir to %s\n",path));
1646 res = sys_chdir(path);
1648 strcpy(LastDir,path);
1653 /*******************************************************************
1654 return the absolute current directory path. A dumb version.
1655 ********************************************************************/
1656 static char *Dumb_GetWd(char *s)
1659 return ((char *)getcwd(s,sizeof(pstring)));
1661 return ((char *)getwd(s));
1666 /* number of list structures for a caching GetWd function. */
1667 #define MAX_GETWDCACHE (50)
1675 } ino_list[MAX_GETWDCACHE];
1677 BOOL use_getwd_cache=True;
1679 /*******************************************************************
1680 return the absolute current directory path
1681 ********************************************************************/
1682 char *GetWd(char *str)
1685 static BOOL getwd_cache_init = False;
1686 struct stat st, st2;
1691 if (!use_getwd_cache)
1692 return(Dumb_GetWd(str));
1694 /* init the cache */
1695 if (!getwd_cache_init)
1697 getwd_cache_init = True;
1698 for (i=0;i<MAX_GETWDCACHE;i++)
1700 string_init(&ino_list[i].text,"");
1701 ino_list[i].valid = False;
1705 /* Get the inode of the current directory, if this doesn't work we're
1708 if (stat(".",&st) == -1)
1710 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1711 return(Dumb_GetWd(str));
1715 for (i=0; i<MAX_GETWDCACHE; i++)
1716 if (ino_list[i].valid)
1719 /* If we have found an entry with a matching inode and dev number
1720 then find the inode number for the directory in the cached string.
1721 If this agrees with that returned by the stat for the current
1722 directory then all is o.k. (but make sure it is a directory all
1725 if (st.st_ino == ino_list[i].inode &&
1726 st.st_dev == ino_list[i].dev)
1728 if (stat(ino_list[i].text,&st2) == 0)
1730 if (st.st_ino == st2.st_ino &&
1731 st.st_dev == st2.st_dev &&
1732 (st2.st_mode & S_IFMT) == S_IFDIR)
1734 strcpy (str, ino_list[i].text);
1736 /* promote it for future use */
1737 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1742 /* If the inode is different then something's changed,
1743 scrub the entry and start from scratch. */
1744 ino_list[i].valid = False;
1751 /* We don't have the information to hand so rely on traditional methods.
1752 The very slow getcwd, which spawns a process on some systems, or the
1753 not quite so bad getwd. */
1757 DEBUG(0,("Getwd failed, errno %d\n",errno));
1763 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1765 /* add it to the cache */
1766 i = MAX_GETWDCACHE - 1;
1767 string_set(&ino_list[i].text,s);
1768 ino_list[i].dev = st.st_dev;
1769 ino_list[i].inode = st.st_ino;
1770 ino_list[i].valid = True;
1772 /* put it at the top of the list */
1773 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1780 /*******************************************************************
1781 reduce a file name, removing .. elements and checking that
1782 it is below dir in the heirachy. This uses GetWd() and so must be run
1783 on the system that has the referenced file system.
1785 widelinks are allowed if widelinks is true
1786 ********************************************************************/
1787 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1789 #ifndef REDUCE_PATHS
1797 BOOL relative = (*s != '/');
1799 *dir2 = *wd = *basename = *newname = 0;
1804 /* can't have a leading .. */
1805 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1807 DEBUG(3,("Illegal file name? (%s)\n",s));
1813 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1815 /* remove any double slashes */
1816 string_sub(s,"//","/");
1819 p = strrchr(basename,'/');
1826 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1830 if (ChDir(dir) != 0)
1832 DEBUG(0,("couldn't chdir to %s\n",dir));
1838 DEBUG(0,("couldn't getwd for %s\n",dir));
1844 if (p && (p != basename))
1847 if (strcmp(p+1,".")==0)
1849 if (strcmp(p+1,"..")==0)
1853 if (ChDir(basename) != 0)
1856 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1860 if (!GetWd(newname))
1863 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1867 if (p && (p != basename))
1869 strcat(newname,"/");
1870 strcat(newname,p+1);
1874 int l = strlen(dir2);
1875 if (dir2[l-1] == '/')
1878 if (strncmp(newname,dir2,l) != 0)
1881 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1887 if (newname[l] == '/')
1888 strcpy(s,newname + l + 1);
1890 strcpy(s,newname+l);
1901 DEBUG(3,("reduced to %s\n",s));
1906 /****************************************************************************
1908 ****************************************************************************/
1909 static void expand_one(char *Mask,int len)
1912 while ((p1 = strchr(Mask,'*')) != NULL)
1914 int lfill = (len+1) - strlen(Mask);
1915 int l1= (p1 - Mask);
1918 memset(tmp+l1,'?',lfill);
1919 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1924 /****************************************************************************
1925 expand a wildcard expression, replacing *s with ?s
1926 ****************************************************************************/
1927 void expand_mask(char *Mask,BOOL doext)
1932 BOOL hasdot = False;
1934 BOOL absolute = (*Mask == '\\');
1936 *mbeg = *mext = *dirpart = *filepart = 0;
1938 /* parse the directory and filename */
1939 if (strchr(Mask,'\\'))
1940 dirname_dos(Mask,dirpart);
1942 filename_dos(Mask,filepart);
1944 strcpy(mbeg,filepart);
1945 if ((p1 = strchr(mbeg,'.')) != NULL)
1955 if (strlen(mbeg) > 8)
1957 strcpy(mext,mbeg + 8);
1963 strcpy(mbeg,"????????");
1964 if ((*mext == 0) && doext && !hasdot)
1967 if (strequal(mbeg,"*") && *mext==0)
1975 strcpy(Mask,dirpart);
1976 if (*dirpart || absolute) strcat(Mask,"\\");
1981 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1985 /****************************************************************************
1986 does a string have any uppercase chars in it?
1987 ****************************************************************************/
1988 BOOL strhasupper(char *s)
1993 if (is_shift_jis (*s)) {
1995 } else if (is_kana (*s)) {
1998 if (isupper(*s)) return(True);
2002 if (isupper(*s)) return(True);
2009 /****************************************************************************
2010 does a string have any lowercase chars in it?
2011 ****************************************************************************/
2012 BOOL strhaslower(char *s)
2017 if (is_shift_jis (*s)) {
2019 } else if (is_kana (*s)) {
2022 if (islower(*s)) return(True);
2026 if (islower(*s)) return(True);
2033 /****************************************************************************
2034 find the number of chars in a string
2035 ****************************************************************************/
2036 int count_chars(char *s,char c)
2049 /****************************************************************************
2051 ****************************************************************************/
2052 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
2059 if ((mode & aDIR) != 0)
2062 memset(buf+1,' ',11);
2063 if ((p = strchr(mask2,'.')) != NULL)
2066 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
2067 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
2071 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
2073 bzero(buf+21,DIR_STRUCT_SIZE-21);
2074 CVAL(buf,21) = mode;
2075 put_dos_date(buf,22,date);
2076 SSVAL(buf,26,size & 0xFFFF);
2077 SSVAL(buf,28,size >> 16);
2078 StrnCpy(buf+30,fname,12);
2079 if (!case_sensitive)
2081 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2085 /*******************************************************************
2086 close the low 3 fd's and open dev/null in their place
2087 ********************************************************************/
2088 void close_low_fds(void)
2092 close(0); close(1); close(2);
2093 /* try and use up these file descriptors, so silly
2094 library routines writing to stdout etc won't cause havoc */
2096 fd = open("/dev/null",O_RDWR,0);
2097 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2099 DEBUG(0,("Can't open /dev/null\n"));
2103 DEBUG(0,("Didn't get file descriptor %d\n",i));
2110 /****************************************************************************
2112 ****************************************************************************/
2113 int write_socket(int fd,char *buf,int len)
2119 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2120 ret = write_data(fd,buf,len);
2122 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2126 /****************************************************************************
2128 ****************************************************************************/
2129 int read_udp_socket(int fd,char *buf,int len)
2132 struct sockaddr sock;
2135 socklen = sizeof(sock);
2136 bzero((char *)&sock,socklen);
2137 bzero((char *)&lastip,sizeof(lastip));
2138 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
2141 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
2145 lastip = *(struct in_addr *) &sock.sa_data[2];
2146 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
2151 /****************************************************************************
2152 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2154 if SYSV use O_NDELAY
2156 ****************************************************************************/
2157 int set_blocking(int fd, BOOL set)
2161 #define FLAG_TO_SET O_NONBLOCK
2164 #define FLAG_TO_SET O_NDELAY
2166 #define FLAG_TO_SET FNDELAY
2170 if((val = fcntl(fd, F_GETFL, 0))==-1)
2172 if(set) /* Turn blocking on - ie. clear nonblock flag */
2173 val &= ~FLAG_TO_SET;
2176 return fcntl( fd, F_SETFL, val);
2181 /****************************************************************************
2182 Calculate the difference in timeout values. Return 1 if val1 > val2,
2183 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
2184 may be == val1 or val2
2185 ****************************************************************************/
2186 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
2188 int usecdiff = val1->tv_usec - val2->tv_usec;
2189 int secdiff = val1->tv_sec - val2->tv_sec;
2191 usecdiff = 1000000 + usecdiff;
2194 retval->tv_sec = secdiff;
2195 retval->tv_usec = usecdiff;
2200 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
2203 /****************************************************************************
2204 read data from a device with a timout in msec.
2205 mincount = if timeout, minimum to read before returning
2206 maxcount = number to be read.
2207 ****************************************************************************/
2208 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
2214 struct timeval timeout, tval1, tval2, tvaldiff;
2215 int error_limit = 5;
2217 /* just checking .... */
2218 if (maxcnt <= 0) return(0);
2221 time_out = DEFAULT_PIPE_TIMEOUT;
2225 if (mincnt == 0) mincnt = maxcnt;
2227 while (nread < mincnt)
2229 readret = read(fd, buf + nread, maxcnt - nread);
2230 if (readret <= 0) return(nread);
2236 /* Non blocking read */
2238 set_blocking(fd, False);
2239 nread = read_data(fd, buf, mincnt);
2241 nread += read(fd,buf+nread,maxcnt-nread);
2242 if(nread == -1 && errno == EWOULDBLOCK)
2244 set_blocking(fd,True);
2248 /* Most difficult - timeout read */
2249 /* If this is ever called on a disk file and
2250 mincnt is greater then the filesize then
2251 system performance will suffer severely as
2252 select always return true on disk files */
2254 /* Set initial timeout */
2255 timeout.tv_sec = time_out / 1000;
2256 timeout.tv_usec = 1000 * (time_out % 1000);
2258 /* As most UNIXes don't modify the value of timeout
2259 when they return from select we need to get the timeofday (in usec)
2260 now, and also after the select returns so we know
2261 how much time has elapsed */
2264 GetTimeOfDay( &tval1);
2265 nread = 0; /* Number of bytes we have read */
2272 selrtn = sys_select(&fds,&timeout);
2274 /* Check if error */
2280 /* Did we timeout ? */
2282 if (nread < mincnt) return -1;
2286 readret = read(fd, buf+nread, maxcnt-nread);
2287 if (readret == 0 && nread < mincnt) {
2288 /* error_limit should not really be needed, but some systems
2289 do strange things ... I don't want to just continue
2290 indefinately in case we get an infinite loop */
2291 if (error_limit--) continue;
2296 /* force a particular error number for
2298 DEBUG(5,("read gave error %s\n",strerror(errno)));
2305 /* If we have read more than mincnt then return */
2306 if (nread >= mincnt)
2309 /* We need to do another select - but first reduce the
2310 time_out by the amount of time already elapsed - if
2311 this is less than zero then return */
2313 GetTimeOfDay(&tval2);
2314 (void)tval_sub( &tvaldiff, &tval2, &tval1);
2316 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
2317 break; /* We timed out */
2320 /* Save the time of day as we need to do the select
2321 again (saves a system call) */
2325 /* Return the number we got */
2329 /****************************************************************************
2330 read data from the client. Maxtime is in milliseconds
2331 ****************************************************************************/
2332 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2337 struct timeval timeout;
2342 timeout.tv_sec = maxtime / 1000;
2343 timeout.tv_usec = (maxtime % 1000) * 1000;
2345 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2347 if (!FD_ISSET(fd,&fds))
2350 nread = read_udp_socket(fd, buffer, bufsize);
2352 /* return the number got */
2356 /*******************************************************************
2357 find the difference in milliseconds between two struct timeval
2359 ********************************************************************/
2360 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2362 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2363 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2366 /****************************************************************************
2367 send a keepalive packet (rfc1002)
2368 ****************************************************************************/
2369 BOOL send_keepalive(int client)
2371 unsigned char buf[4];
2374 buf[1] = buf[2] = buf[3] = 0;
2376 return(write_data(client,(char *)buf,4) == 4);
2381 /****************************************************************************
2382 read data from the client, reading exactly N bytes.
2383 ****************************************************************************/
2384 int read_data(int fd,char *buffer,int N)
2391 ret = read(fd,buffer + total,N - total);
2393 /* this is for portability */
2405 /****************************************************************************
2407 ****************************************************************************/
2408 int write_data(int fd,char *buffer,int N)
2415 ret = write(fd,buffer + total,N - total);
2426 /* variables used by the read prediction module */
2431 int rp_predict_fd = -1;
2432 int rp_predict_offset = 0;
2433 int rp_predict_length = 0;
2436 char *rp_buffer = NULL;
2437 BOOL predict_skip=False;
2438 time_t smb_last_time=(time_t)0;
2440 /****************************************************************************
2441 handle read prediction on a file
2442 ****************************************************************************/
2443 int read_predict(int fd,int offset,char *buf,char **ptr,int num)
2446 int possible = rp_length - (offset - rp_offset);
2448 possible = MIN(possible,num);
2450 /* give data if possible */
2452 offset >= rp_offset &&
2454 smb_last_time-rp_time < rp_timeout)
2458 memcpy(buf,rp_buffer + (offset-rp_offset),possible);
2460 *ptr = rp_buffer + (offset-rp_offset);
2461 DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
2465 predict_skip = True;
2467 predict_skip = False;
2469 /* prepare the next prediction */
2471 rp_predict_offset = offset + num;
2472 rp_predict_length = num;
2475 if (ret < 0) ret = 0;
2480 /****************************************************************************
2482 ****************************************************************************/
2483 void do_read_prediction()
2485 if (predict_skip) return;
2487 if (rp_predict_fd == -1)
2490 rp_fd = rp_predict_fd;
2491 rp_offset = rp_predict_offset;
2496 rp_predict_length = MIN(rp_predict_length,2*ReadSize);
2497 rp_predict_length = MAX(rp_predict_length,1024);
2498 rp_offset = (rp_offset/1024)*1024;
2499 rp_predict_length = (rp_predict_length/1024)*1024;
2501 if (rp_predict_length > rp_alloced)
2503 rp_buffer = Realloc(rp_buffer,rp_predict_length);
2504 rp_alloced = rp_predict_length;
2507 DEBUG(0,("can't allocate read-prediction buffer\n"));
2515 if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
2521 rp_length = read(rp_fd,rp_buffer,rp_predict_length);
2522 rp_time = time(NULL);
2527 /****************************************************************************
2528 invalidate read-prediction on a fd
2529 ****************************************************************************/
2530 void invalidate_read_prediction(int fd)
2534 if (rp_predict_fd == fd)
2539 /****************************************************************************
2540 transfer some data between two fd's
2541 ****************************************************************************/
2542 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2544 static char *buf=NULL;
2546 static int size = 0;
2549 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2551 if ((size < ReadSize) && buf) {
2556 size = MAX(ReadSize,1024);
2558 while (!buf && size>0) {
2559 buf = (char *)Realloc(buf,size+8);
2560 if (!buf) size /= 2;
2563 DEBUG(0,("Can't allocate transfer buffer!\n"));
2567 abuf = buf + (align%8);
2574 int s = MIN(n,size);
2579 if (header && (headlen >= MIN(s,1024))) {
2589 if (header && headlen > 0)
2591 ret = MIN(headlen,size);
2592 memcpy(buf1,header,ret);
2595 if (headlen <= 0) header = NULL;
2599 ret += read(infd,buf1+ret,s-ret);
2603 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2604 if (ret2 > 0) total += ret2;
2605 /* if we can't write then dump excess data */
2607 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2609 if (ret <= 0 || ret2 != ret)
2617 /****************************************************************************
2618 read 4 bytes of a smb packet and return the smb length of the packet
2619 possibly store the result in the buffer
2620 ****************************************************************************/
2621 int read_smb_length(int fd,char *inbuf,int timeout)
2625 int len=0, msg_type;
2636 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2638 ok = (read_data(fd,buffer,4) == 4);
2644 DEBUG(10,("select timeout (%d)\n", timeout));
2649 DEBUG(6,("couldn't read from client\n"));
2654 len = smb_len(buffer);
2655 msg_type = CVAL(buffer,0);
2657 if (msg_type == 0x85)
2659 DEBUG(5,( "Got keepalive packet\n"));
2664 DEBUG(10,("got smb length of %d\n",len));
2671 /****************************************************************************
2672 read an smb from a fd and return it's length
2673 The timeout is in milli seconds
2674 ****************************************************************************/
2675 BOOL receive_smb(int fd,char *buffer,int timeout)
2680 bzero(buffer,smb_size + 100);
2682 len = read_smb_length(fd,buffer,timeout);
2686 if (len > BUFFER_SIZE) {
2687 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2688 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2692 ok = (read_data(fd,buffer+4,len) == len);
2704 /****************************************************************************
2706 ****************************************************************************/
2707 BOOL send_smb(int fd,char *buffer)
2711 len = smb_len(buffer) + 4;
2713 while (nwritten < len)
2715 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2718 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2730 /****************************************************************************
2731 find a pointer to a netbios name
2732 ****************************************************************************/
2733 char *name_ptr(char *buf,int ofs)
2735 unsigned char c = *(unsigned char *)(buf+ofs);
2737 if ((c & 0xC0) == 0xC0)
2741 memcpy(p,buf+ofs,2);
2744 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2751 /****************************************************************************
2752 extract a netbios name from a buf
2753 ****************************************************************************/
2754 int name_extract(char *buf,int ofs,char *name)
2756 char *p = name_ptr(buf,ofs);
2757 int d = PTR_DIFF(p,buf+ofs);
2759 if (d < -50 || d > 50) return(0);
2760 return(name_interpret(p,name));
2764 /****************************************************************************
2765 return the total storage length of a mangled name
2766 ****************************************************************************/
2767 int name_len(char *s)
2770 unsigned char c = *(unsigned char *)s;
2771 if ((c & 0xC0) == 0xC0)
2773 while (*s) s += (*s)+1;
2774 return(PTR_DIFF(s,s0)+1);
2777 /****************************************************************************
2778 send a single packet to a port on another machine
2779 ****************************************************************************/
2780 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2784 struct sockaddr_in sock_out;
2789 /* create a socket to write to */
2790 out_fd = socket(AF_INET, type, 0);
2793 DEBUG(0,("socket failed"));
2797 /* set the address and port */
2798 bzero((char *)&sock_out,sizeof(sock_out));
2799 putip((char *)&sock_out.sin_addr,(char *)&ip);
2800 sock_out.sin_port = htons( port );
2801 sock_out.sin_family = AF_INET;
2804 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2805 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2808 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2811 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2812 inet_ntoa(ip),port,errno));
2818 /*******************************************************************
2819 sleep for a specified number of milliseconds
2820 ********************************************************************/
2824 struct timeval tval,t1,t2;
2831 tval.tv_sec = (t-tdiff)/1000;
2832 tval.tv_usec = 1000*((t-tdiff)%1000);
2836 sys_select(&fds,&tval);
2839 tdiff = TvalDiff(&t1,&t2);
2843 /****************************************************************************
2844 check if a string is part of a list
2845 ****************************************************************************/
2846 BOOL in_list(char *s,char *list,BOOL casesensitive)
2851 if (!list) return(False);
2853 while (next_token(&p,tok,LIST_SEP))
2855 if (casesensitive) {
2856 if (strcmp(tok,s) == 0)
2859 if (StrCaseCmp(tok,s) == 0)
2866 /* this is used to prevent lots of mallocs of size 1 */
2867 static char *null_string = NULL;
2869 /****************************************************************************
2870 set a string value, allocing the space for the string
2871 ****************************************************************************/
2872 BOOL string_init(char **dest,char *src)
2883 null_string = (char *)malloc(1);
2886 *dest = null_string;
2890 *dest = (char *)malloc(l+1);
2896 /****************************************************************************
2898 ****************************************************************************/
2899 void string_free(char **s)
2901 if (!s || !(*s)) return;
2902 if (*s == null_string)
2908 /****************************************************************************
2909 set a string value, allocing the space for the string, and deallocating any
2911 ****************************************************************************/
2912 BOOL string_set(char **dest,char *src)
2916 return(string_init(dest,src));
2919 /****************************************************************************
2920 substitute a string for a pattern in another string. Make sure there is
2923 This routine looks for pattern in s and replaces it with
2924 insert. It may do multiple replacements.
2926 return True if a substitution was done.
2927 ****************************************************************************/
2928 BOOL string_sub(char *s,char *pattern,char *insert)
2934 if (!insert || !pattern || !s) return(False);
2937 lp = strlen(pattern);
2938 li = strlen(insert);
2940 if (!*pattern) return(False);
2942 while (lp <= ls && (p = strstr(s,pattern)))
2945 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2946 memcpy(p,insert,li);
2955 /*********************************************************
2956 * Recursive routine that is called by mask_match.
2957 * Does the actual matching.
2958 *********************************************************/
2959 BOOL do_match(char *str, char *regexp, int case_sig)
2963 for( p = regexp; *p && *str; ) {
2970 /* Look for a character matching
2971 the one after the '*' */
2974 return True; /* Automatic match */
2976 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2978 if(do_match(str,p,case_sig))
2992 if(toupper(*str) != toupper(*p))
3002 if (!*p && str[0] == '.' && str[1] == 0)
3005 if (!*str && *p == '?')
3007 while (*p == '?') p++;
3011 if(!*str && (*p == '*' && p[1] == '\0'))
3017 /*********************************************************
3018 * Routine to match a given string with a regexp - uses
3019 * simplified regexp that takes * and ? only. Case can be
3020 * significant or not.
3021 *********************************************************/
3022 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3026 fstring ebase,eext,sbase,sext;
3030 /* Make local copies of str and regexp */
3031 StrnCpy(p1,regexp,sizeof(pstring)-1);
3032 StrnCpy(p2,str,sizeof(pstring)-1);
3034 if (!strchr(p2,'.')) {
3039 if (!strchr(p1,'.')) {
3047 string_sub(p1,"*.*","*");
3048 string_sub(p1,".*","*");
3052 /* Remove any *? and ** as they are meaningless */
3053 for(p = p1; *p; p++)
3054 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3055 (void)strcpy( &p[1], &p[2]);
3057 if (strequal(p1,"*")) return(True);
3059 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3065 if ((p=strrchr(p1,'.'))) {
3074 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3084 matched = do_match(sbase,ebase,case_sig) &&
3085 (trans2 || do_match(sext,eext,case_sig));
3087 DEBUG(5,("mask_match returning %d\n", matched));
3094 /****************************************************************************
3095 become a daemon, discarding the controlling terminal
3096 ****************************************************************************/
3097 void become_daemon(void)
3099 #ifndef NO_FORK_DEBUG
3103 /* detach from the terminal */
3109 int i = open("/dev/tty", O_RDWR);
3112 ioctl(i, (int) TIOCNOTTY, (char *)0);
3121 /****************************************************************************
3122 calculate the default netmask for an address
3123 ****************************************************************************/
3124 static void default_netmask(struct in_addr *inm, struct in_addr *iad)
3126 unsigned long ad = ntohl(iad->s_addr);
3129 ** Guess a netmask based on the class of the IP address given.
3131 if ( (ad & 0x80000000) == 0 ) {
3132 /* class A address */
3134 } else if ( (ad & 0xC0000000) == 0x80000000 ) {
3135 /* class B address */
3137 } else if ( (ad & 0xE0000000) == 0xC0000000 ) {
3138 /* class C address */
3141 /* class D or E; netmask doesn't make much sense - guess 4 bits */
3144 inm->s_addr = htonl(nm);
3147 /****************************************************************************
3148 get the broadcast address for our address
3149 (troyer@saifr00.ateng.az.honeywell.com)
3150 ****************************************************************************/
3151 void get_broadcast(struct in_addr *if_ipaddr,
3152 struct in_addr *if_bcast,
3153 struct in_addr *if_nmask)
3156 #ifndef NO_GET_BROADCAST
3157 int sock = -1; /* AF_INET raw socket desc */
3159 struct ifreq *ifr=NULL;
3162 #if defined(EVEREST)
3165 struct ifreq *ifreqs;
3166 #elif defined(USE_IFREQ)
3168 struct strioctl strioctl;
3175 /* get a default netmask and broadcast */
3176 default_netmask(if_nmask, if_ipaddr);
3178 #ifndef NO_GET_BROADCAST
3179 /* Create a socket to the INET kernel. */
3181 if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
3183 if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
3186 DEBUG(0,( "Unable to open socket to get broadcast address\n"));
3190 /* Get a list of the configured interfaces */
3192 /* This is part of SCO Openserver 5: The ioctls are no longer part
3193 if the lower level STREAMS interface glue. They are now real
3196 if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
3197 DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
3199 DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
3201 ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
3202 ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
3204 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
3205 DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
3209 for (i = 0; i < n_interfaces; ++i) {
3210 if (if_ipaddr->s_addr ==
3211 ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
3218 #elif defined(USE_IFREQ)
3219 ifc = (struct ifconf *)buff;
3220 ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
3221 strioctl.ic_cmd = SIOCGIFCONF;
3222 strioctl.ic_dp = (char *)ifc;
3223 strioctl.ic_len = sizeof(buff);
3224 if (ioctl(sock, I_STR, &strioctl) < 0) {
3225 DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
3227 ifr = (struct ifreq *)ifc->ifc_req;
3229 /* Loop through interfaces, looking for given IP address */
3230 for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
3231 if (if_ipaddr->s_addr ==
3232 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3238 #elif defined(__FreeBSD__) || defined(NETBSD)
3239 ifc.ifc_len = sizeof(buff);
3241 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
3242 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
3245 /* Loop through interfaces, looking for given IP address */
3248 if (if_ipaddr->s_addr ==
3249 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3253 i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
3254 ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
3258 ifc.ifc_len = sizeof(buff);
3260 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
3261 DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
3265 /* Loop through interfaces, looking for given IP address */
3266 for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
3268 if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
3270 if (if_ipaddr->s_addr ==
3271 (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3280 DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
3282 /* Get the netmask address from the kernel */
3286 strioctl.ic_cmd = SIOCGIFNETMASK;
3287 strioctl.ic_dp = (char *)&ifreq;
3288 strioctl.ic_len = sizeof(struct ifreq);
3289 if (ioctl(sock, I_STR, &strioctl) < 0)
3290 DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
3292 *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
3294 if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
3295 DEBUG(0,("SIOCGIFNETMASK failed\n"));
3297 *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
3300 DEBUG(2,("Netmask for %s = %s\n", ifr->ifr_name,
3301 inet_ntoa(*if_nmask)));
3309 /* sanity check on the netmask */
3311 unsigned long nm = ntohl(if_nmask->s_addr);
3312 if ((nm >> 24) != 0xFF) {
3313 DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
3314 default_netmask(if_nmask, if_ipaddr);
3318 /* derive the broadcast assuming a 1's broadcast, as this is what
3319 all MS operating systems do, we have to comply even if the unix
3320 box is setup differently */
3322 unsigned long ad = ntohl(if_ipaddr->s_addr);
3323 unsigned long nm = ntohl(if_nmask->s_addr);
3324 unsigned long bc = (ad & nm) | (0xffffffff & ~nm);
3325 if_bcast->s_addr = htonl(bc);
3328 DEBUG(2,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
3329 } /* get_broadcast */
3332 /****************************************************************************
3333 put up a yes/no prompt
3334 ****************************************************************************/
3340 if (!fgets(ans,sizeof(ans)-1,stdin))
3343 if (*ans == 'y' || *ans == 'Y')
3349 /****************************************************************************
3350 read a line from a file with possible \ continuation chars.
3351 Blanks at the start or end of a line are stripped.
3352 The string will be allocated if s2 is NULL
3353 ****************************************************************************/
3354 char *fgets_slash(char *s2,int maxlen,FILE *f)
3359 BOOL start_of_line = True;
3366 maxlen = MIN(maxlen,8);
3367 s = (char *)Realloc(s,maxlen);
3370 if (!s || maxlen < 2) return(NULL);
3374 while (len < maxlen-1)
3382 while (len > 0 && s[len-1] == ' ')
3386 if (len > 0 && s[len-1] == '\\')
3389 start_of_line = True;
3394 if (len <= 0 && !s2)
3396 return(len>0?s:NULL);
3401 start_of_line = False;
3405 if (!s2 && len > maxlen-3)
3408 s = (char *)Realloc(s,maxlen);
3409 if (!s) return(NULL);
3417 /****************************************************************************
3418 set the length of a file from a filedescriptor.
3419 Returns 0 on success, -1 on failure.
3420 ****************************************************************************/
3421 int set_filelen(int fd, long len)
3423 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3424 extend a file with ftruncate. Provide alternate implementation
3427 #if FTRUNCATE_CAN_EXTEND
3428 return ftruncate(fd, len);
3432 long currpos = lseek(fd, 0L, SEEK_CUR);
3436 /* Do an fstat to see if the file is longer than
3437 the requested size (call ftruncate),
3438 or shorter, in which case seek to len - 1 and write 1
3440 if(fstat(fd, &st)<0)
3444 if (S_ISFIFO(st.st_mode)) return 0;
3447 if(st.st_size == len)
3449 if(st.st_size > len)
3450 return ftruncate(fd, len);
3452 if(lseek(fd, len-1, SEEK_SET) != len -1)
3454 if(write(fd, &c, 1)!=1)
3456 /* Seek to where we were */
3457 lseek(fd, currpos, SEEK_SET);
3463 /****************************************************************************
3464 return the byte checksum of some data
3465 ****************************************************************************/
3466 int byte_checksum(char *buf,int len)
3468 unsigned char *p = (unsigned char *)buf;
3478 /****************************************************************************
3479 this is a version of setbuffer() for those machines that only have setvbuf
3480 ****************************************************************************/
3481 void setbuffer(FILE *f,char *buf,int bufsize)
3483 setvbuf(f,buf,_IOFBF,bufsize);
3488 /****************************************************************************
3489 parse out a directory name from a path name. Assumes dos style filenames.
3490 ****************************************************************************/
3491 char *dirname_dos(char *path,char *buf)
3493 char *p = strrchr(path,'\\');
3508 /****************************************************************************
3509 parse out a filename from a path name. Assumes dos style filenames.
3510 ****************************************************************************/
3511 static char *filename_dos(char *path,char *buf)
3513 char *p = strrchr(path,'\\');
3525 /****************************************************************************
3526 expand a pointer to be a particular size
3527 ****************************************************************************/
3528 void *Realloc(void *p,int size)
3532 ret = (void *)malloc(size);
3534 ret = (void *)realloc(p,size);
3537 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3542 /****************************************************************************
3543 set the time on a file
3544 ****************************************************************************/
3545 BOOL set_filetime(char *fname,time_t mtime)
3547 struct utimbuf times;
3549 if (null_mtime(mtime)) return(True);
3551 times.modtime = times.actime = mtime;
3553 if (sys_utime(fname,×)) {
3554 DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
3562 /****************************************************************************
3564 ****************************************************************************/
3565 char *strdup(char *s)
3568 if (!s) return(NULL);
3569 ret = (char *)malloc(strlen(s)+1);
3570 if (!ret) return(NULL);
3577 /****************************************************************************
3578 Signal handler for SIGPIPE (write on a disconnected socket)
3579 ****************************************************************************/
3582 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3587 #ifdef REPLACE_STRLEN
3588 /****************************************************************************
3589 a replacement strlen() that returns int for solaris
3590 ****************************************************************************/
3601 /****************************************************************************
3602 return a time at the start of the current month
3603 ****************************************************************************/
3604 time_t start_of_month(void)
3606 time_t t = time(NULL);
3620 /*******************************************************************
3621 check for a sane unix date
3622 ********************************************************************/
3623 BOOL sane_unix_date(time_t unixdate)
3626 time_t t_today = time(NULL);
3628 t = *(LocalTime(&unixdate,LOCAL_TO_GMT));
3629 today = *(LocalTime(&t_today,LOCAL_TO_GMT));
3634 if (t.tm_year > today.tm_year)
3637 if (t.tm_year == today.tm_year &&
3638 t.tm_mon > today.tm_mon)
3642 if (t.tm_year == today.tm_year &&
3643 t.tm_mon == today.tm_mon &&
3644 t.tm_mday > (today.tm_mday+1))
3653 /*******************************************************************
3654 ftruncate for operating systems that don't have it
3655 ********************************************************************/
3656 int ftruncate(int f,long l)
3663 fl.l_type = F_WRLCK;
3664 return fcntl(f, F_FREESP, &fl);
3670 /****************************************************************************
3671 get my own name and IP
3672 ****************************************************************************/
3673 BOOL get_myname(char *myname,struct in_addr *ip)
3680 /* get my host name */
3681 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3683 DEBUG(0,("gethostname failed\n"));
3688 if ((hp = Get_Hostbyname(hostname)) == 0)
3690 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3696 /* split off any parts after an initial . */
3697 char *p = strchr(hostname,'.');
3700 strcpy(myname,hostname);
3704 putip((char *)ip,(char *)hp->h_addr);
3710 /****************************************************************************
3711 true if two IP addresses are equal
3712 ****************************************************************************/
3713 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3715 unsigned long a1,a2;
3716 a1 = ntohl(ip1.s_addr);
3717 a2 = ntohl(ip2.s_addr);
3722 /****************************************************************************
3723 open a socket of the specified type, port and address for incoming data
3724 ****************************************************************************/
3725 int open_socket_in(int type, int port, int dlevel)
3728 struct sockaddr_in sock;
3732 /* get my host name */
3733 #ifdef MAXHOSTNAMELEN
3734 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3736 if (gethostname(host_name, sizeof(host_name)) == -1)
3738 { DEBUG(0,("gethostname failed\n")); return -1; }
3741 if ((hp = Get_Hostbyname(host_name)) == 0)
3743 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3747 bzero((char *)&sock,sizeof(sock));
3748 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3749 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3750 sock.sin_len = sizeof(sock);
3752 sock.sin_port = htons( port );
3753 sock.sin_family = hp->h_addrtype;
3754 sock.sin_addr.s_addr = INADDR_ANY;
3755 res = socket(hp->h_addrtype, type, 0);
3757 { DEBUG(0,("socket failed\n")); return -1; }
3761 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3764 /* now we've got a socket - we need to bind it */
3765 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3768 if (port == 139 || port == 137)
3769 DEBUG(dlevel,("bind failed on port %d (%s)\n",
3770 port,strerror(errno)));
3773 if (dlevel > 0 && port < 1000)
3776 if (port >= 1000 && port < 9000)
3777 return(open_socket_in(type,port+1,dlevel));
3782 DEBUG(3,("bind succeeded on port %d\n",port));
3788 /****************************************************************************
3789 create an outgoing socket
3790 **************************************************************************/
3791 int open_socket_out(int type, struct in_addr *addr, int port )
3793 struct sockaddr_in sock_out;
3796 /* create a socket to write to */
3797 res = socket(PF_INET, type, 0);
3799 { DEBUG(0,("socket error\n")); return -1; }
3801 if (type != SOCK_STREAM) return(res);
3803 bzero((char *)&sock_out,sizeof(sock_out));
3804 putip((char *)&sock_out.sin_addr,(char *)addr);
3806 sock_out.sin_port = htons( port );
3807 sock_out.sin_family = PF_INET;
3809 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3811 /* and connect it to the destination */
3812 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
3813 DEBUG(0,("connect error: %s\n",strerror(errno)));
3822 /****************************************************************************
3823 interpret a protocol description string, with a default
3824 ****************************************************************************/
3825 int interpret_protocol(char *str,int def)
3827 if (strequal(str,"NT1"))
3828 return(PROTOCOL_NT1);
3829 if (strequal(str,"LANMAN2"))
3830 return(PROTOCOL_LANMAN2);
3831 if (strequal(str,"LANMAN1"))
3832 return(PROTOCOL_LANMAN1);
3833 if (strequal(str,"CORE"))
3834 return(PROTOCOL_CORE);
3835 if (strequal(str,"COREPLUS"))
3836 return(PROTOCOL_COREPLUS);
3837 if (strequal(str,"CORE+"))
3838 return(PROTOCOL_COREPLUS);
3840 DEBUG(0,("Unrecognised protocol level %s\n",str));
3845 /****************************************************************************
3846 interpret a security level
3847 ****************************************************************************/
3848 int interpret_security(char *str,int def)
3850 if (strequal(str,"SERVER"))
3852 if (strequal(str,"USER"))
3854 if (strequal(str,"SHARE"))
3857 DEBUG(0,("Unrecognised security level %s\n",str));
3863 /****************************************************************************
3864 interpret an internet address or name into an IP address in 4 byte form
3865 ****************************************************************************/
3866 unsigned long interpret_addr(char *str)
3871 if (strcmp(str,"0.0.0.0") == 0) return(0);
3872 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3874 /* if it's in the form of an IP address then get the lib to interpret it */
3875 if (isdigit(str[0])) {
3876 res = inet_addr(str);
3878 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
3879 if ((hp = Get_Hostbyname(str)) == 0) {
3880 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3883 putip((char *)&res,(char *)hp->h_addr);
3886 if (res == (unsigned long)-1) return(0);
3891 /*******************************************************************
3892 a convenient addition to interpret_addr()
3893 ******************************************************************/
3894 struct in_addr *interpret_addr2(char *str)
3896 static struct in_addr ret;
3897 unsigned long a = interpret_addr(str);
3898 putip((char *)&ret,(char *)&a);
3902 /*******************************************************************
3903 check if an IP is the 0.0.0.0
3904 ******************************************************************/
3905 BOOL zero_ip(struct in_addr ip)
3908 putip((char *)&a,(char *)&ip);
3912 #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
3914 /****************************************************************************
3915 interpret an 8 byte "filetime" structure to a time_t
3916 It's originally in "100ns units since jan 1st 1601"
3918 It appears to be kludge-GMT (at least for file listings). This means
3919 its the GMT you get by taking a localtime and adding the
3920 serverzone. This is NOT the same as GMT in some cases. This routine
3921 converts this to real GMT.
3922 ****************************************************************************/
3923 time_t interpret_long_date(char *p)
3931 if (thigh == 0) return(0);
3933 d = ((double)thigh)*4.0*(double)(1<<30);
3934 d += (tlow&0xFFF00000);
3937 /* now adjust by 369 years to make the secs since 1970 */
3938 d -= TIME_FIXUP_CONSTANT;
3943 ret = (time_t)(d+0.5);
3945 /* this takes us from kludge-GMT to real GMT */
3946 ret += TimeDiff(ret) - serverzone;
3952 /****************************************************************************
3953 put a 8 byte filetime from a time_t
3954 This takes real GMT as input and converts to kludge-GMT
3955 ****************************************************************************/
3956 void put_long_date(char *p,time_t t)
3962 SIVAL(p,0,0); SIVAL(p,4,0);
3966 /* this converts GMT to kludge-GMT */
3967 t -= TimeDiff(t) - serverzone;
3971 d += TIME_FIXUP_CONSTANT;
3975 thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
3976 tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
3982 /*******************************************************************
3983 sub strings with useful parameters
3984 ********************************************************************/
3985 void standard_sub_basic(char *s)
3987 if (!strchr(s,'%')) return;
3989 string_sub(s,"%R",remote_proto);
3990 string_sub(s,"%a",remote_arch);
3991 string_sub(s,"%m",remote_machine);
3992 string_sub(s,"%L",local_machine);
3994 if (!strchr(s,'%')) return;
3996 string_sub(s,"%v",VERSION);
3997 string_sub(s,"%h",myhostname);
3998 string_sub(s,"%U",sesssetup_user);
4000 if (!strchr(s,'%')) return;
4002 string_sub(s,"%I",Client_info.addr);
4003 string_sub(s,"%M",Client_info.name);
4004 string_sub(s,"%T",timestring());
4006 if (!strchr(s,'%')) return;
4010 sprintf(pidstr,"%d",(int)getpid());
4011 string_sub(s,"%d",pidstr);
4014 if (!strchr(s,'%')) return;
4017 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
4019 string_sub(s,"%G",gidtoname(pass->pw_gid));
4025 /*******************************************************************
4026 write a string in unicoode format
4027 ********************************************************************/
4028 int PutUniCode(char *dst,char *src)
4032 dst[ret++] = src[0];
4042 pstring smbrun_path = SMBRUN;
4044 /****************************************************************************
4045 run a command via system() using smbrun
4046 ****************************************************************************/
4047 int smbrun(char *cmd,char *outfile)
4052 if (!file_exist(smbrun_path,NULL))
4054 DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",smbrun_path));
4058 sprintf(syscmd,"%s \"(%s 2>&1) > %s\"",
4060 outfile?outfile:"/dev/null");
4062 DEBUG(5,("smbrun - running %s ",syscmd));
4063 ret = system(syscmd);
4064 DEBUG(5,("gave %d\n",ret));
4069 /****************************************************************************
4070 a wrapper for gethostbyname() that tries with all lower and all upper case
4071 if the initial name fails
4072 ****************************************************************************/
4073 struct hostent *Get_Hostbyname(char *name)
4075 char *name2 = strdup(name);
4076 struct hostent *ret;
4080 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4084 if (!isalnum(*name2))
4090 ret = gethostbyname(name2);
4097 /* try with all lowercase */
4099 ret = gethostbyname(name2);
4106 /* try with all uppercase */
4108 ret = gethostbyname(name2);
4115 /* nothing works :-( */
4121 /****************************************************************************
4122 check if a process exists. Does this work on all unixes?
4123 ****************************************************************************/
4124 BOOL process_exists(int pid)
4128 sprintf(s,"/proc/%d",pid);
4129 return(directory_exist(s,NULL));
4132 static BOOL tested=False;
4133 static BOOL ok=False;
4137 sprintf(s,"/proc/%05d",getpid());
4138 ok = file_exist(s,NULL);
4141 sprintf(s,"/proc/%05d",pid);
4142 return(file_exist(s,NULL));
4146 /* a best guess for non root access */
4147 if (geteuid() != 0) return(True);
4149 /* otherwise use kill */
4150 return(pid == getpid() || kill(pid,0) == 0);
4155 /*******************************************************************
4156 turn a uid into a user name
4157 ********************************************************************/
4158 char *uidtoname(int uid)
4160 static char name[40];
4161 struct passwd *pass = getpwuid(uid);
4162 if (pass) return(pass->pw_name);
4163 sprintf(name,"%d",uid);
4167 /*******************************************************************
4168 turn a gid into a group name
4169 ********************************************************************/
4170 char *gidtoname(int gid)
4172 static char name[40];
4173 struct group *grp = getgrgid(gid);
4174 if (grp) return(grp->gr_name);
4175 sprintf(name,"%d",gid);
4179 /*******************************************************************
4181 ********************************************************************/
4182 void BlockSignals(BOOL block)
4185 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
4186 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
4189 sigblock(block_mask);
4191 sigunblock(block_mask);
4196 /*******************************************************************
4197 my own panic function - not suitable for general use
4198 ********************************************************************/
4199 void ajt_panic(void)
4201 pstring cmd = "/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT &";
4207 #define DIRECT direct
4209 #define DIRECT dirent
4212 /*******************************************************************
4213 a readdir wrapper which just returns the file name
4214 also return the inode number if requested
4215 ********************************************************************/
4216 char *readdirname(void *p)
4221 if (!p) return(NULL);
4223 ptr = (struct DIRECT *)readdir(p);
4224 if (!ptr) return(NULL);
4226 dname = ptr->d_name;
4232 unix_to_dos(buf, True);
4238 if (telldir(p) < 0) return(NULL);
4242 /* this handles a broken compiler setup, causing a mixture
4243 of BSD and SYSV headers and libraries */
4245 static BOOL broken_readdir = False;
4246 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4248 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4249 broken_readdir = True;
4261 #if (defined(SecureWare) && defined(SCO))
4262 /* This is needed due to needing the nap() function but we don't want
4263 to include the Xenix libraries since that will break other things...
4264 BTW: system call # 0x0c28 is the same as calling nap() */
4265 long nap(long milliseconds) {
4266 return syscall(0x0c28, milliseconds);
4270 #ifdef NO_INITGROUPS
4271 #include <sys/types.h>
4276 #define NULL (void *)0
4279 /****************************************************************************
4280 some systems don't have an initgroups call
4281 ****************************************************************************/
4282 int initgroups(char *name,gid_t id)
4285 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
4288 gid_t grouplst[NGROUPS_MAX];
4295 while (i < NGROUPS_MAX &&
4296 ((g = (struct group *)getgrent()) != (struct group *)NULL))
4298 if (g->gr_gid == id)
4302 while (gr && (*gr != (char)NULL)) {
4303 if (strcmp(name,gr) == 0) {
4304 grouplst[i] = g->gr_gid;
4309 gr = g->gr_mem[++j];
4313 return(setgroups(i,grouplst));
4321 /* undo the wrapping temporarily */
4326 /****************************************************************************
4327 wrapper for malloc() to catch memory errors
4328 ****************************************************************************/
4329 void *malloc_wrapped(int size,char *file,int line)
4331 #ifdef xx_old_malloc
4332 void *res = xx_old_malloc(size);
4334 void *res = malloc(size);
4336 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
4338 size,(unsigned int)res));
4342 /****************************************************************************
4343 wrapper for realloc() to catch memory errors
4344 ****************************************************************************/
4345 void *realloc_wrapped(void *ptr,int size,char *file,int line)
4347 #ifdef xx_old_realloc
4348 void *res = xx_old_realloc(ptr,size);
4350 void *res = realloc(ptr,size);
4352 DEBUG(3,("Realloc\n"));
4353 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
4355 (unsigned int)ptr));
4356 DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
4358 size,(unsigned int)res));
4362 /****************************************************************************
4363 wrapper for free() to catch memory errors
4364 ****************************************************************************/
4365 void free_wrapped(void *ptr,char *file,int line)
4372 DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
4373 file,line,(unsigned int)ptr));
4377 /* and re-do the define for spots lower in this file */
4378 #define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
4379 #define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
4380 #define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
4384 #ifdef REPLACE_STRSTR
4385 /****************************************************************************
4386 Mips version of strstr doesn't seem to work correctly.
4387 There is a #define in includes.h to redirect calls to this function.
4388 ****************************************************************************/
4389 char *Strstr(char *s, char *p)
4391 int len = strlen(p);
4393 while ( *s != '\0' ) {
4394 if ( strncmp(s, p, len) == 0 )
4401 #endif /* REPLACE_STRSTR */
4404 #ifdef REPLACE_MKTIME
4405 /*******************************************************************
4406 a mktime() replacement for those who don't have it - contributed by
4407 C.A. Lademann <cal@zls.com>
4408 ********************************************************************/
4410 #define HOUR 60*MINUTE
4412 #define YEAR 365*DAY
4413 time_t Mktime(struct tm *t)
4417 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
4423 epoch = (t->tm_year - 70) * YEAR +
4424 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
4429 for(i = 0; i < t->tm_mon; i++) {
4430 epoch += mon [m] * DAY;
4431 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
4440 epoch += (t->tm_mday - 1) * DAY;
4441 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
4443 if((u = localtime(&epoch)) != NULL) {
4444 t->tm_sec = u->tm_sec;
4445 t->tm_min = u->tm_min;
4446 t->tm_hour = u->tm_hour;
4447 t->tm_mday = u->tm_mday;
4448 t->tm_mon = u->tm_mon;
4449 t->tm_year = u->tm_year;
4450 t->tm_wday = u->tm_wday;
4451 t->tm_yday = u->tm_yday;
4452 t->tm_isdst = u->tm_isdst;
4454 memcpy(t->tm_name, u->tm_name, LTZNMAX);
4460 #endif /* REPLACE_MKTIME */
4464 #ifdef REPLACE_RENAME
4465 /* Rename a file. (from libiberty in GNU binutils) */
4471 if (link (zfrom, zto) < 0)
4473 if (errno != EEXIST)
4475 if (unlink (zto) < 0
4476 || link (zfrom, zto) < 0)
4479 return unlink (zfrom);
4484 #ifdef REPLACE_INNETGR
4486 * Search for a match in a netgroup. This replaces it on broken systems.
4488 int InNetGr(group, host, user, dom)
4489 char *group, *host, *user, *dom;
4491 char *hst, *usr, *dm;
4494 while (getnetgrent(&hst, &usr, &dm))
4495 if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
4496 ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
4497 ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
4509 /*******************************************************************
4510 a wrapper around memcpy for diagnostic purposes
4511 ********************************************************************/
4512 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
4514 if (l>64 && (((int)d)%4) != (((int)s)%4))
4515 DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
4516 #ifdef xx_old_memcpy
4517 return(xx_old_memcpy(d,s,l));
4519 return(memcpy(d,s,l));
4522 #define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)