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.
30 int Protocol = PROTOCOL_COREPLUS;
32 /* a default finfo structure to ensure all fields are sensible */
33 file_info def_finfo = {-1,0,0,0,0,0,0,""};
35 /* these are some file handles where debug info will be stored */
38 /* the client file descriptor */
41 /* info on the client */
42 struct from_host Client_info=
43 {"UNKNOWN","0.0.0.0",NULL};
45 /* the last IP received from */
46 struct in_addr lastip;
48 /* the last port received from */
54 case handling on filenames
56 int case_default = CASE_LOWER;
58 pstring debugf = "/tmp/log.samba";
61 /* the following control case operations - they are put here so the
62 client can link easily */
65 BOOL use_mangled_map = False;
66 BOOL short_case_preserve;
69 fstring remote_machine="";
70 fstring local_machine="";
71 fstring remote_arch="UNKNOWN";
72 fstring remote_proto="UNKNOWN";
73 pstring myhostname="";
74 pstring user_socket_options="";
75 pstring sesssetup_user="";
78 static char *filename_dos(char *path,char *buf);
80 static BOOL stdout_logging = False;
83 /*******************************************************************
84 get ready for syslog stuff
85 ******************************************************************/
86 void setup_logging(char *pname,BOOL interactive)
90 char *p = strrchr(pname,'/');
92 openlog(pname, LOG_PID, LOG_DAEMON);
96 stdout_logging = True;
102 BOOL append_log=False;
105 /****************************************************************************
107 ****************************************************************************/
108 void reopen_logs(void)
115 strcpy(fname,debugf);
116 if (lp_loaded() && (*lp_logfile()))
117 strcpy(fname,lp_logfile());
119 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
121 strcpy(debugf,fname);
122 if (dbf) fclose(dbf);
124 dbf = fopen(debugf,"a");
126 dbf = fopen(debugf,"w");
127 if (dbf) setbuf(dbf,NULL);
141 /*******************************************************************
142 check if the log has grown too big
143 ********************************************************************/
144 static void check_log_size(void)
146 static int debug_count=0;
150 if (debug_count++ < 100) return;
152 maxlog = lp_max_log_size() * 1024;
153 if (!dbf || maxlog <= 0) return;
155 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
156 fclose(dbf); dbf = NULL;
158 if (dbf && file_size(debugf) > maxlog) {
160 fclose(dbf); dbf = NULL;
161 sprintf(name,"%s.old",debugf);
162 sys_rename(debugf,name);
170 /*******************************************************************
171 write an debug message on the debugfile. This is called by the DEBUG
173 ********************************************************************/
175 int Debug1(char *format_str, ...)
185 if (stdout_logging) {
187 va_start(ap, format_str);
190 format_str = va_arg(ap,char *);
192 vfprintf(dbf,format_str,ap);
198 if (!lp_syslog_only())
203 dbf = fopen(debugf,"w");
212 if (syslog_level < lp_syslog())
215 * map debug levels to syslog() priorities
216 * note that not all DEBUG(0, ...) calls are
219 static int priority_map[] = {
228 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
230 priority = LOG_DEBUG;
232 priority = priority_map[syslog_level];
235 va_start(ap, format_str);
238 format_str = va_arg(ap,char *);
240 vsprintf(msgbuf, format_str, ap);
244 syslog(priority, "%s", msgbuf);
249 if (!lp_syslog_only())
253 va_start(ap, format_str);
256 format_str = va_arg(ap,char *);
258 vfprintf(dbf,format_str,ap);
268 /****************************************************************************
269 determine if a file descriptor is in fact a socket
270 ****************************************************************************/
271 BOOL is_a_socket(int fd)
275 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
279 static char *last_ptr=NULL;
281 /****************************************************************************
282 Get the next token from a string, return False if none found
283 handles double-quotes.
284 Based on a routine by GJC@VILLAGE.COM.
285 Extensively modified by Andrew.Tridgell@anu.edu.au
286 ****************************************************************************/
287 BOOL next_token(char **ptr,char *buff,char *sep)
292 if (!ptr) ptr = &last_ptr;
293 if (!ptr) return(False);
297 /* default to simple separators */
298 if (!sep) sep = " \t\n\r";
300 /* find the first non sep char */
301 while(*s && strchr(sep,*s)) s++;
304 if (! *s) return(False);
306 /* copy over the token */
307 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
315 *ptr = (*s) ? s+1 : s;
322 /****************************************************************************
323 Convert list of tokens to array; dependent on above routine.
324 Uses last_ptr from above - bit of a hack.
325 ****************************************************************************/
326 char **toktocliplist(int *ctok, char *sep)
332 if (!sep) sep = " \t\n\r";
334 while(*s && strchr(sep,*s)) s++;
337 if (!*s) return(NULL);
341 while(*s && (!strchr(sep,*s))) s++;
342 while(*s && strchr(sep,*s)) *s++=0;
348 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
360 /*******************************************************************
361 safely copies memory, ensuring no overlap problems.
362 this is only used if the machine does not have it's own memmove().
363 this is not the fastest algorithm in town, but it will do for our
365 ********************************************************************/
366 void *MemMove(void *dest,void *src,int size)
370 if (dest==src || !size) return(dest);
372 d = (unsigned long)dest;
373 s = (unsigned long)src;
375 if ((d >= (s+size)) || (s >= (d+size))) {
377 memcpy(dest,src,size);
383 /* we can forward copy */
384 if (s-d >= sizeof(int) &&
385 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
386 /* do it all as words */
387 int *idest = (int *)dest;
388 int *isrc = (int *)src;
390 for (i=0;i<size;i++) idest[i] = isrc[i];
393 char *cdest = (char *)dest;
394 char *csrc = (char *)src;
395 for (i=0;i<size;i++) cdest[i] = csrc[i];
400 /* must backward copy */
401 if (d-s >= sizeof(int) &&
402 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
403 /* do it all as words */
404 int *idest = (int *)dest;
405 int *isrc = (int *)src;
407 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
410 char *cdest = (char *)dest;
411 char *csrc = (char *)src;
412 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
420 /****************************************************************************
421 prompte a dptr (to make it recently used)
422 ****************************************************************************/
423 void array_promote(char *array,int elsize,int element)
429 p = (char *)malloc(elsize);
433 DEBUG(5,("Ahh! Can't malloc\n"));
436 memcpy(p,array + element * elsize, elsize);
437 memmove(array + elsize,array,elsize*element);
438 memcpy(array,p,elsize);
442 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
451 } socket_options[] = {
452 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
453 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
454 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
456 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
458 #ifdef IPTOS_LOWDELAY
459 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
461 #ifdef IPTOS_THROUGHPUT
462 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
465 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
468 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
471 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
474 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
480 /****************************************************************************
481 set user socket options
482 ****************************************************************************/
483 void set_socket_options(int fd, char *options)
487 while (next_token(&options,tok," \t,"))
492 BOOL got_value = False;
494 if ((p = strchr(tok,'=')))
501 for (i=0;socket_options[i].name;i++)
502 if (strequal(socket_options[i].name,tok))
505 if (!socket_options[i].name)
507 DEBUG(0,("Unknown socket option %s\n",tok));
511 switch (socket_options[i].opttype)
515 ret = setsockopt(fd,socket_options[i].level,
516 socket_options[i].option,(char *)&value,sizeof(int));
521 DEBUG(0,("syntax error - %s does not take a value\n",tok));
524 int on = socket_options[i].value;
525 ret = setsockopt(fd,socket_options[i].level,
526 socket_options[i].option,(char *)&on,sizeof(int));
532 DEBUG(0,("Failed to set socket option %s\n",tok));
538 /****************************************************************************
539 close the socket communication
540 ****************************************************************************/
541 void close_sockets(void )
547 /****************************************************************************
548 determine whether we are in the specified group
549 ****************************************************************************/
550 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
554 if (group == current_gid) return(True);
556 for (i=0;i<ngroups;i++)
557 if (group == groups[i])
563 /****************************************************************************
564 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
565 ****************************************************************************/
566 char *StrCpy(char *dest,char *src)
571 /* I don't want to get lazy with these ... */
573 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
578 if (!dest) return(NULL);
583 while ((*d++ = *src++)) ;
587 /****************************************************************************
588 line strncpy but always null terminates. Make sure there is room!
589 ****************************************************************************/
590 char *StrnCpy(char *dest,const char *src,int n)
593 if (!dest) return(NULL);
598 while (n-- && (*d++ = *src++)) ;
604 /*******************************************************************
605 copy an IP address from one buffer to another
606 ********************************************************************/
607 void putip(void *dest,void *src)
613 /****************************************************************************
614 interpret the weird netbios "name". Return the name type
615 ****************************************************************************/
616 static int name_interpret(char *in,char *out)
619 int len = (*in++) / 2;
623 if (len > 30 || len<1) return(0);
627 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
631 *out = ((in[0]-'A')<<4) + (in[1]-'A');
639 /* Handle any scope names */
642 *out++ = '.'; /* Scope names are separated by periods */
643 len = *(unsigned char *)in++;
644 StrnCpy(out, in, len);
653 /****************************************************************************
654 mangle a name into netbios format
655 ****************************************************************************/
656 int name_mangle(char *In,char *Out,char name_type)
660 char *in = (char *)&buf[0];
661 char *out = (char *)Out;
666 StrnCpy(name,In,sizeof(name)-1);
667 sprintf(buf,"%-15.15s%c",name,name_type);
670 memset(&buf[1],0,16);
675 char c = toupper(in[i]);
676 out[i*2] = (c>>4) + 'A';
677 out[i*2+1] = (c & 0xF) + 'A';
685 p = strchr(label, '.');
687 p = label + strlen(label);
689 memcpy(out, label, p - label);
691 label += p - label + (*p == '.');
694 return(name_len(Out));
698 /*******************************************************************
699 check if a file exists
700 ********************************************************************/
701 BOOL file_exist(char *fname,struct stat *sbuf)
704 if (!sbuf) sbuf = &st;
706 if (sys_stat(fname,sbuf) != 0)
709 return(S_ISREG(sbuf->st_mode));
712 /*******************************************************************
713 check a files mod time
714 ********************************************************************/
715 time_t file_modtime(char *fname)
719 if (sys_stat(fname,&st) != 0)
725 /*******************************************************************
726 check if a directory exists
727 ********************************************************************/
728 BOOL directory_exist(char *dname,struct stat *st)
733 if (sys_stat(dname,st) != 0)
736 return(S_ISDIR(st->st_mode));
739 /*******************************************************************
740 returns the size in bytes of the named file
741 ********************************************************************/
742 uint32 file_size(char *file_name)
746 sys_stat(file_name,&buf);
750 /*******************************************************************
751 return a string representing an attribute for a file
752 ********************************************************************/
753 char *attrib_string(int mode)
755 static char attrstr[10];
759 if (mode & aVOLID) strcat(attrstr,"V");
760 if (mode & aDIR) strcat(attrstr,"D");
761 if (mode & aARCH) strcat(attrstr,"A");
762 if (mode & aHIDDEN) strcat(attrstr,"H");
763 if (mode & aSYSTEM) strcat(attrstr,"S");
764 if (mode & aRONLY) strcat(attrstr,"R");
770 /*******************************************************************
771 case insensitive string compararison
772 ********************************************************************/
773 int StrCaseCmp(char *s, char *t)
775 for (; tolower(*s) == tolower(*t); ++s, ++t)
778 return tolower(*s) - tolower(*t);
781 /*******************************************************************
782 case insensitive string compararison, length limited
783 ********************************************************************/
784 int StrnCaseCmp(char *s, char *t, int n)
786 while (n-- && *s && *t) {
787 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
790 if (n) return(tolower(*s) - tolower(*t));
795 /*******************************************************************
797 ********************************************************************/
798 BOOL strequal(char *s1,char *s2)
800 if (s1 == s2) return(True);
801 if (!s1 || !s2) return(False);
803 return(StrCaseCmp(s1,s2)==0);
806 /*******************************************************************
807 compare 2 strings up to and including the nth char.
808 ******************************************************************/
809 BOOL strnequal(char *s1,char *s2,int n)
811 if (s1 == s2) return(True);
812 if (!s1 || !s2 || !n) return(False);
814 return(StrnCaseCmp(s1,s2,n)==0);
817 /*******************************************************************
818 compare 2 strings (case sensitive)
819 ********************************************************************/
820 BOOL strcsequal(char *s1,char *s2)
822 if (s1 == s2) return(True);
823 if (!s1 || !s2) return(False);
825 return(strcmp(s1,s2)==0);
829 /*******************************************************************
830 convert a string to lower case
831 ********************************************************************/
832 void strlower(char *s)
837 if (is_shift_jis (*s)) {
839 } else if (is_kana (*s)) {
854 /*******************************************************************
855 convert a string to upper case
856 ********************************************************************/
857 void strupper(char *s)
862 if (is_shift_jis (*s)) {
864 } else if (is_kana (*s)) {
879 /*******************************************************************
880 convert a string to "normal" form
881 ********************************************************************/
882 void strnorm(char *s)
884 if (case_default == CASE_UPPER)
890 /*******************************************************************
891 check if a string is in "normal" case
892 ********************************************************************/
893 BOOL strisnormal(char *s)
895 if (case_default == CASE_UPPER)
896 return(!strhaslower(s));
898 return(!strhasupper(s));
902 /****************************************************************************
904 ****************************************************************************/
905 void string_replace(char *s,char oldc,char newc)
910 if (is_shift_jis (*s)) {
912 } else if (is_kana (*s)) {
927 /****************************************************************************
928 make a file into unix format
929 ****************************************************************************/
930 void unix_format(char *fname)
933 string_replace(fname,'\\','/');
935 dos2unix_format(fname, True);
940 strcpy(namecopy,fname);
942 strcat(fname,namecopy);
946 /****************************************************************************
947 make a file into dos format
948 ****************************************************************************/
949 void dos_format(char *fname)
952 unix2dos_format(fname, True);
954 string_replace(fname,'/','\\');
958 /*******************************************************************
959 show a smb message structure
960 ********************************************************************/
961 void show_msg(char *buf)
968 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
970 (int)CVAL(buf,smb_com),
971 (int)CVAL(buf,smb_rcls),
972 (int)CVAL(buf,smb_reh),
973 (int)SVAL(buf,smb_err),
974 (int)CVAL(buf,smb_flg),
975 (int)SVAL(buf,smb_flg2)));
976 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
977 (int)SVAL(buf,smb_tid),
978 (int)SVAL(buf,smb_pid),
979 (int)SVAL(buf,smb_uid),
980 (int)SVAL(buf,smb_mid),
981 (int)CVAL(buf,smb_wct)));
982 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
983 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
984 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
985 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
986 DEBUG(5,("smb_bcc=%d\n",bcc));
989 for (i=0;i<MIN(bcc,128);i++)
990 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
994 /*******************************************************************
995 return the length of an smb packet
996 ********************************************************************/
997 int smb_len(char *buf)
999 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1002 /*******************************************************************
1003 set the length of an smb packet
1004 ********************************************************************/
1005 void _smb_setlen(char *buf,int len)
1008 buf[1] = (len&0x10000)>>16;
1009 buf[2] = (len&0xFF00)>>8;
1013 /*******************************************************************
1014 set the length and marker of an smb packet
1015 ********************************************************************/
1016 void smb_setlen(char *buf,int len)
1018 _smb_setlen(buf,len);
1026 /*******************************************************************
1027 setup the word count and byte count for a smb message
1028 ********************************************************************/
1029 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1032 bzero(buf + smb_size,num_words*2 + num_bytes);
1033 CVAL(buf,smb_wct) = num_words;
1034 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1035 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1036 return (smb_size + num_words*2 + num_bytes);
1039 /*******************************************************************
1040 return the number of smb words
1041 ********************************************************************/
1042 int smb_numwords(char *buf)
1044 return (CVAL(buf,smb_wct));
1047 /*******************************************************************
1048 return the size of the smb_buf region of a message
1049 ********************************************************************/
1050 int smb_buflen(char *buf)
1052 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1055 /*******************************************************************
1056 return a pointer to the smb_buf data area
1057 ********************************************************************/
1058 int smb_buf_ofs(char *buf)
1060 return (smb_size + CVAL(buf,smb_wct)*2);
1063 /*******************************************************************
1064 return a pointer to the smb_buf data area
1065 ********************************************************************/
1066 char *smb_buf(char *buf)
1068 return (buf + smb_buf_ofs(buf));
1071 /*******************************************************************
1072 return the SMB offset into an SMB buffer
1073 ********************************************************************/
1074 int smb_offset(char *p,char *buf)
1076 return(PTR_DIFF(p,buf+4));
1080 /*******************************************************************
1081 skip past some strings in a buffer
1082 ********************************************************************/
1083 char *skip_string(char *buf,int n)
1086 buf += strlen(buf) + 1;
1090 /*******************************************************************
1091 trim the specified elements off the front and back of a string
1092 ********************************************************************/
1093 BOOL trim_string(char *s,char *front,char *back)
1096 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1102 if (!(*p = p[strlen(front)]))
1107 while (back && *back && strlen(s) >= strlen(back) &&
1108 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1111 s[strlen(s)-strlen(back)] = 0;
1117 /*******************************************************************
1118 reduce a file name, removing .. elements.
1119 ********************************************************************/
1120 void dos_clean_name(char *s)
1124 DEBUG(3,("dos_clean_name [%s]\n",s));
1126 /* remove any double slashes */
1127 string_sub(s, "\\\\", "\\");
1129 while ((p = strstr(s,"\\..\\")) != NULL)
1136 if ((p=strrchr(s,'\\')) != NULL)
1143 trim_string(s,NULL,"\\..");
1145 string_sub(s, "\\.\\", "\\");
1148 /*******************************************************************
1149 reduce a file name, removing .. elements.
1150 ********************************************************************/
1151 void unix_clean_name(char *s)
1155 DEBUG(3,("unix_clean_name [%s]\n",s));
1157 /* remove any double slashes */
1158 string_sub(s, "//","/");
1160 while ((p = strstr(s,"/../")) != NULL)
1167 if ((p=strrchr(s,'/')) != NULL)
1174 trim_string(s,NULL,"/..");
1178 /*******************************************************************
1179 a wrapper for the normal chdir() function
1180 ********************************************************************/
1181 int ChDir(char *path)
1184 static pstring LastDir="";
1186 if (strcsequal(path,".")) return(0);
1188 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1189 DEBUG(3,("chdir to %s\n",path));
1190 res = sys_chdir(path);
1192 strcpy(LastDir,path);
1197 /*******************************************************************
1198 return the absolute current directory path. A dumb version.
1199 ********************************************************************/
1200 static char *Dumb_GetWd(char *s)
1203 return ((char *)getcwd(s,sizeof(pstring)));
1205 return ((char *)getwd(s));
1210 /* number of list structures for a caching GetWd function. */
1211 #define MAX_GETWDCACHE (50)
1219 } ino_list[MAX_GETWDCACHE];
1221 BOOL use_getwd_cache=True;
1223 /*******************************************************************
1224 return the absolute current directory path
1225 ********************************************************************/
1226 char *GetWd(char *str)
1229 static BOOL getwd_cache_init = False;
1230 struct stat st, st2;
1235 if (!use_getwd_cache)
1236 return(Dumb_GetWd(str));
1238 /* init the cache */
1239 if (!getwd_cache_init)
1241 getwd_cache_init = True;
1242 for (i=0;i<MAX_GETWDCACHE;i++)
1244 string_init(&ino_list[i].text,"");
1245 ino_list[i].valid = False;
1249 /* Get the inode of the current directory, if this doesn't work we're
1252 if (stat(".",&st) == -1)
1254 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1255 return(Dumb_GetWd(str));
1259 for (i=0; i<MAX_GETWDCACHE; i++)
1260 if (ino_list[i].valid)
1263 /* If we have found an entry with a matching inode and dev number
1264 then find the inode number for the directory in the cached string.
1265 If this agrees with that returned by the stat for the current
1266 directory then all is o.k. (but make sure it is a directory all
1269 if (st.st_ino == ino_list[i].inode &&
1270 st.st_dev == ino_list[i].dev)
1272 if (stat(ino_list[i].text,&st2) == 0)
1274 if (st.st_ino == st2.st_ino &&
1275 st.st_dev == st2.st_dev &&
1276 (st2.st_mode & S_IFMT) == S_IFDIR)
1278 strcpy (str, ino_list[i].text);
1280 /* promote it for future use */
1281 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1286 /* If the inode is different then something's changed,
1287 scrub the entry and start from scratch. */
1288 ino_list[i].valid = False;
1295 /* We don't have the information to hand so rely on traditional methods.
1296 The very slow getcwd, which spawns a process on some systems, or the
1297 not quite so bad getwd. */
1301 DEBUG(0,("Getwd failed, errno %d\n",errno));
1307 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1309 /* add it to the cache */
1310 i = MAX_GETWDCACHE - 1;
1311 string_set(&ino_list[i].text,s);
1312 ino_list[i].dev = st.st_dev;
1313 ino_list[i].inode = st.st_ino;
1314 ino_list[i].valid = True;
1316 /* put it at the top of the list */
1317 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1324 /*******************************************************************
1325 reduce a file name, removing .. elements and checking that
1326 it is below dir in the heirachy. This uses GetWd() and so must be run
1327 on the system that has the referenced file system.
1329 widelinks are allowed if widelinks is true
1330 ********************************************************************/
1331 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1333 #ifndef REDUCE_PATHS
1341 BOOL relative = (*s != '/');
1343 *dir2 = *wd = *basename = *newname = 0;
1348 /* can't have a leading .. */
1349 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1351 DEBUG(3,("Illegal file name? (%s)\n",s));
1357 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1359 /* remove any double slashes */
1360 string_sub(s,"//","/");
1363 p = strrchr(basename,'/');
1370 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1374 if (ChDir(dir) != 0)
1376 DEBUG(0,("couldn't chdir to %s\n",dir));
1382 DEBUG(0,("couldn't getwd for %s\n",dir));
1388 if (p && (p != basename))
1391 if (strcmp(p+1,".")==0)
1393 if (strcmp(p+1,"..")==0)
1397 if (ChDir(basename) != 0)
1400 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1404 if (!GetWd(newname))
1407 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1411 if (p && (p != basename))
1413 strcat(newname,"/");
1414 strcat(newname,p+1);
1418 int l = strlen(dir2);
1419 if (dir2[l-1] == '/')
1422 if (strncmp(newname,dir2,l) != 0)
1425 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1431 if (newname[l] == '/')
1432 strcpy(s,newname + l + 1);
1434 strcpy(s,newname+l);
1445 DEBUG(3,("reduced to %s\n",s));
1450 /****************************************************************************
1452 ****************************************************************************/
1453 static void expand_one(char *Mask,int len)
1456 while ((p1 = strchr(Mask,'*')) != NULL)
1458 int lfill = (len+1) - strlen(Mask);
1459 int l1= (p1 - Mask);
1462 memset(tmp+l1,'?',lfill);
1463 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1468 /****************************************************************************
1469 expand a wildcard expression, replacing *s with ?s
1470 ****************************************************************************/
1471 void expand_mask(char *Mask,BOOL doext)
1476 BOOL hasdot = False;
1478 BOOL absolute = (*Mask == '\\');
1480 *mbeg = *mext = *dirpart = *filepart = 0;
1482 /* parse the directory and filename */
1483 if (strchr(Mask,'\\'))
1484 dirname_dos(Mask,dirpart);
1486 filename_dos(Mask,filepart);
1488 strcpy(mbeg,filepart);
1489 if ((p1 = strchr(mbeg,'.')) != NULL)
1499 if (strlen(mbeg) > 8)
1501 strcpy(mext,mbeg + 8);
1507 strcpy(mbeg,"????????");
1508 if ((*mext == 0) && doext && !hasdot)
1511 if (strequal(mbeg,"*") && *mext==0)
1519 strcpy(Mask,dirpart);
1520 if (*dirpart || absolute) strcat(Mask,"\\");
1525 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1529 /****************************************************************************
1530 does a string have any uppercase chars in it?
1531 ****************************************************************************/
1532 BOOL strhasupper(char *s)
1537 if (is_shift_jis (*s)) {
1539 } else if (is_kana (*s)) {
1542 if (isupper(*s)) return(True);
1546 if (isupper(*s)) return(True);
1553 /****************************************************************************
1554 does a string have any lowercase chars in it?
1555 ****************************************************************************/
1556 BOOL strhaslower(char *s)
1561 if (is_shift_jis (*s)) {
1563 } else if (is_kana (*s)) {
1566 if (islower(*s)) return(True);
1570 if (islower(*s)) return(True);
1577 /****************************************************************************
1578 find the number of chars in a string
1579 ****************************************************************************/
1580 int count_chars(char *s,char c)
1593 /****************************************************************************
1595 ****************************************************************************/
1596 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1603 if ((mode & aDIR) != 0)
1606 memset(buf+1,' ',11);
1607 if ((p = strchr(mask2,'.')) != NULL)
1610 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1611 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1615 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1617 bzero(buf+21,DIR_STRUCT_SIZE-21);
1618 CVAL(buf,21) = mode;
1619 put_dos_date(buf,22,date);
1620 SSVAL(buf,26,size & 0xFFFF);
1621 SSVAL(buf,28,size >> 16);
1622 StrnCpy(buf+30,fname,12);
1623 if (!case_sensitive)
1625 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1629 /*******************************************************************
1630 close the low 3 fd's and open dev/null in their place
1631 ********************************************************************/
1632 void close_low_fds(void)
1636 close(0); close(1); close(2);
1637 /* try and use up these file descriptors, so silly
1638 library routines writing to stdout etc won't cause havoc */
1640 fd = open("/dev/null",O_RDWR,0);
1641 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1643 DEBUG(0,("Can't open /dev/null\n"));
1647 DEBUG(0,("Didn't get file descriptor %d\n",i));
1654 /****************************************************************************
1656 ****************************************************************************/
1657 int write_socket(int fd,char *buf,int len)
1663 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1664 ret = write_data(fd,buf,len);
1666 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1670 /****************************************************************************
1672 ****************************************************************************/
1673 int read_udp_socket(int fd,char *buf,int len)
1676 struct sockaddr sock;
1679 socklen = sizeof(sock);
1680 bzero((char *)&sock,socklen);
1681 bzero((char *)&lastip,sizeof(lastip));
1682 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1684 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1688 lastip = *(struct in_addr *) &sock.sa_data[2];
1689 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1694 /****************************************************************************
1695 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1697 if SYSV use O_NDELAY
1699 ****************************************************************************/
1700 int set_blocking(int fd, BOOL set)
1704 #define FLAG_TO_SET O_NONBLOCK
1707 #define FLAG_TO_SET O_NDELAY
1709 #define FLAG_TO_SET FNDELAY
1713 if((val = fcntl(fd, F_GETFL, 0))==-1)
1715 if(set) /* Turn blocking on - ie. clear nonblock flag */
1716 val &= ~FLAG_TO_SET;
1719 return fcntl( fd, F_SETFL, val);
1724 /****************************************************************************
1725 Calculate the difference in timeout values. Return 1 if val1 > val2,
1726 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
1727 may be == val1 or val2
1728 ****************************************************************************/
1729 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
1731 int usecdiff = val1->tv_usec - val2->tv_usec;
1732 int secdiff = val1->tv_sec - val2->tv_sec;
1734 usecdiff = 1000000 + usecdiff;
1737 retval->tv_sec = secdiff;
1738 retval->tv_usec = usecdiff;
1743 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
1746 /****************************************************************************
1747 read data from a device with a timout in msec.
1748 mincount = if timeout, minimum to read before returning
1749 maxcount = number to be read.
1750 ****************************************************************************/
1751 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
1757 struct timeval timeout, tval1, tval2, tvaldiff;
1758 int error_limit = 5;
1760 /* just checking .... */
1761 if (maxcnt <= 0) return(0);
1764 time_out = DEFAULT_PIPE_TIMEOUT;
1768 if (mincnt == 0) mincnt = maxcnt;
1770 while (nread < mincnt)
1772 readret = read(fd, buf + nread, maxcnt - nread);
1773 if (readret <= 0) return(nread);
1779 /* Non blocking read */
1781 set_blocking(fd, False);
1782 nread = read_data(fd, buf, mincnt);
1784 nread += read(fd,buf+nread,maxcnt-nread);
1785 if(nread == -1 && errno == EWOULDBLOCK)
1787 set_blocking(fd,True);
1791 /* Most difficult - timeout read */
1792 /* If this is ever called on a disk file and
1793 mincnt is greater then the filesize then
1794 system performance will suffer severely as
1795 select always return true on disk files */
1797 /* Set initial timeout */
1798 timeout.tv_sec = time_out / 1000;
1799 timeout.tv_usec = 1000 * (time_out % 1000);
1801 /* As most UNIXes don't modify the value of timeout
1802 when they return from select we need to get the timeofday (in usec)
1803 now, and also after the select returns so we know
1804 how much time has elapsed */
1807 GetTimeOfDay( &tval1);
1808 nread = 0; /* Number of bytes we have read */
1815 selrtn = sys_select(&fds,&timeout);
1817 /* Check if error */
1822 /* Did we timeout ? */
1824 if (nread < mincnt) return -1;
1828 readret = read(fd, buf+nread, maxcnt-nread);
1829 if (readret == 0 && nread < mincnt) {
1830 /* error_limit should not really be needed, but some systems
1831 do strange things ... I don't want to just continue
1832 indefinately in case we get an infinite loop */
1833 if (error_limit--) continue;
1838 /* force a particular error number for
1840 DEBUG(5,("read gave error %s\n",strerror(errno)));
1846 /* If we have read more than mincnt then return */
1847 if (nread >= mincnt)
1850 /* We need to do another select - but first reduce the
1851 time_out by the amount of time already elapsed - if
1852 this is less than zero then return */
1854 GetTimeOfDay(&tval2);
1855 (void)tval_sub( &tvaldiff, &tval2, &tval1);
1857 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
1858 break; /* We timed out */
1861 /* Save the time of day as we need to do the select
1862 again (saves a system call) */
1866 /* Return the number we got */
1870 /****************************************************************************
1871 read data from the client. Maxtime is in milliseconds
1872 ****************************************************************************/
1873 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1878 struct timeval timeout;
1883 timeout.tv_sec = maxtime / 1000;
1884 timeout.tv_usec = (maxtime % 1000) * 1000;
1886 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1888 if (!FD_ISSET(fd,&fds))
1891 nread = read_udp_socket(fd, buffer, bufsize);
1893 /* return the number got */
1897 /*******************************************************************
1898 find the difference in milliseconds between two struct timeval
1900 ********************************************************************/
1901 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1903 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1904 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1907 /****************************************************************************
1908 send a keepalive packet (rfc1002)
1909 ****************************************************************************/
1910 BOOL send_keepalive(int client)
1912 unsigned char buf[4];
1915 buf[1] = buf[2] = buf[3] = 0;
1917 return(write_data(client,(char *)buf,4) == 4);
1922 /****************************************************************************
1923 read data from the client, reading exactly N bytes.
1924 ****************************************************************************/
1925 int read_data(int fd,char *buffer,int N)
1932 ret = read(fd,buffer + total,N - total);
1942 /****************************************************************************
1944 ****************************************************************************/
1945 int write_data(int fd,char *buffer,int N)
1952 ret = write(fd,buffer + total,N - total);
1963 /****************************************************************************
1964 transfer some data between two fd's
1965 ****************************************************************************/
1966 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1968 static char *buf=NULL;
1973 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1976 size = lp_readsize();
1977 size = MAX(size,1024);
1980 while (!buf && size>0) {
1981 buf = (char *)Realloc(buf,size+8);
1982 if (!buf) size /= 2;
1986 DEBUG(0,("Can't allocate transfer buffer!\n"));
1990 abuf = buf + (align%8);
1997 int s = MIN(n,size);
2002 if (header && (headlen >= MIN(s,1024))) {
2012 if (header && headlen > 0)
2014 ret = MIN(headlen,size);
2015 memcpy(buf1,header,ret);
2018 if (headlen <= 0) header = NULL;
2022 ret += read(infd,buf1+ret,s-ret);
2026 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2027 if (ret2 > 0) total += ret2;
2028 /* if we can't write then dump excess data */
2030 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2032 if (ret <= 0 || ret2 != ret)
2040 /****************************************************************************
2041 read 4 bytes of a smb packet and return the smb length of the packet
2042 possibly store the result in the buffer
2043 ****************************************************************************/
2044 int read_smb_length(int fd,char *inbuf,int timeout)
2048 int len=0, msg_type;
2059 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2061 ok = (read_data(fd,buffer,4) == 4);
2067 DEBUG(10,("select timeout (%d)\n", timeout));
2072 DEBUG(6,("couldn't read from client\n"));
2077 len = smb_len(buffer);
2078 msg_type = CVAL(buffer,0);
2080 if (msg_type == 0x85)
2082 DEBUG(5,("Got keepalive packet\n"));
2087 DEBUG(10,("got smb length of %d\n",len));
2094 /****************************************************************************
2095 read an smb from a fd and return it's length
2096 The timeout is in milli seconds
2097 ****************************************************************************/
2098 BOOL receive_smb(int fd,char *buffer,int timeout)
2102 bzero(buffer,smb_size + 100);
2104 len = read_smb_length(fd,buffer,timeout);
2108 if (len > BUFFER_SIZE) {
2109 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2110 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2114 ret = read_data(fd,buffer+4,len);
2116 DEBUG(0,("ERROR: Invalid SMB length. Expected %d got %d\n",len,ret));
2124 /****************************************************************************
2126 ****************************************************************************/
2127 BOOL send_smb(int fd,char *buffer)
2131 len = smb_len(buffer) + 4;
2133 while (nwritten < len)
2135 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2138 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2150 /****************************************************************************
2151 find a pointer to a netbios name
2152 ****************************************************************************/
2153 char *name_ptr(char *buf,int ofs)
2155 unsigned char c = *(unsigned char *)(buf+ofs);
2157 if ((c & 0xC0) == 0xC0)
2161 memcpy(p,buf+ofs,2);
2164 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2171 /****************************************************************************
2172 extract a netbios name from a buf
2173 ****************************************************************************/
2174 int name_extract(char *buf,int ofs,char *name)
2176 char *p = name_ptr(buf,ofs);
2177 int d = PTR_DIFF(p,buf+ofs);
2179 if (d < -50 || d > 50) return(0);
2180 return(name_interpret(p,name));
2184 /****************************************************************************
2185 return the total storage length of a mangled name
2186 ****************************************************************************/
2187 int name_len(char *s)
2190 unsigned char c = *(unsigned char *)s;
2191 if ((c & 0xC0) == 0xC0)
2193 while (*s) s += (*s)+1;
2194 return(PTR_DIFF(s,s0)+1);
2197 /****************************************************************************
2198 send a single packet to a port on another machine
2199 ****************************************************************************/
2200 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2204 struct sockaddr_in sock_out;
2209 /* create a socket to write to */
2210 out_fd = socket(AF_INET, type, 0);
2213 DEBUG(0,("socket failed"));
2217 /* set the address and port */
2218 bzero((char *)&sock_out,sizeof(sock_out));
2219 putip((char *)&sock_out.sin_addr,(char *)&ip);
2220 sock_out.sin_port = htons( port );
2221 sock_out.sin_family = AF_INET;
2224 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2225 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2228 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2231 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2232 inet_ntoa(ip),port,errno));
2238 /*******************************************************************
2239 sleep for a specified number of milliseconds
2240 ********************************************************************/
2244 struct timeval tval,t1,t2;
2251 tval.tv_sec = (t-tdiff)/1000;
2252 tval.tv_usec = 1000*((t-tdiff)%1000);
2256 sys_select(&fds,&tval);
2259 tdiff = TvalDiff(&t1,&t2);
2263 /****************************************************************************
2264 check if a string is part of a list
2265 ****************************************************************************/
2266 BOOL in_list(char *s,char *list,BOOL casesensitive)
2271 if (!list) return(False);
2273 while (next_token(&p,tok,LIST_SEP))
2275 if (casesensitive) {
2276 if (strcmp(tok,s) == 0)
2279 if (StrCaseCmp(tok,s) == 0)
2286 /* this is used to prevent lots of mallocs of size 1 */
2287 static char *null_string = NULL;
2289 /****************************************************************************
2290 set a string value, allocing the space for the string
2291 ****************************************************************************/
2292 BOOL string_init(char **dest,char *src)
2303 null_string = (char *)malloc(1);
2306 *dest = null_string;
2310 *dest = (char *)malloc(l+1);
2316 /****************************************************************************
2318 ****************************************************************************/
2319 void string_free(char **s)
2321 if (!s || !(*s)) return;
2322 if (*s == null_string)
2328 /****************************************************************************
2329 set a string value, allocing the space for the string, and deallocating any
2331 ****************************************************************************/
2332 BOOL string_set(char **dest,char *src)
2336 return(string_init(dest,src));
2339 /****************************************************************************
2340 substitute a string for a pattern in another string. Make sure there is
2343 This routine looks for pattern in s and replaces it with
2344 insert. It may do multiple replacements.
2346 return True if a substitution was done.
2347 ****************************************************************************/
2348 BOOL string_sub(char *s,char *pattern,char *insert)
2354 if (!insert || !pattern || !s) return(False);
2357 lp = strlen(pattern);
2358 li = strlen(insert);
2360 if (!*pattern) return(False);
2362 while (lp <= ls && (p = strstr(s,pattern)))
2365 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2366 memcpy(p,insert,li);
2375 /*********************************************************
2376 * Recursive routine that is called by mask_match.
2377 * Does the actual matching.
2378 *********************************************************/
2379 BOOL do_match(char *str, char *regexp, int case_sig)
2383 for( p = regexp; *p && *str; ) {
2390 /* Look for a character matching
2391 the one after the '*' */
2394 return True; /* Automatic match */
2396 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2398 if(do_match(str,p,case_sig))
2412 if(toupper(*str) != toupper(*p))
2422 if (!*p && str[0] == '.' && str[1] == 0)
2425 if (!*str && *p == '?')
2427 while (*p == '?') p++;
2431 if(!*str && (*p == '*' && p[1] == '\0'))
2437 /*********************************************************
2438 * Routine to match a given string with a regexp - uses
2439 * simplified regexp that takes * and ? only. Case can be
2440 * significant or not.
2441 *********************************************************/
2442 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2446 fstring ebase,eext,sbase,sext;
2450 /* Make local copies of str and regexp */
2451 StrnCpy(p1,regexp,sizeof(pstring)-1);
2452 StrnCpy(p2,str,sizeof(pstring)-1);
2454 if (!strchr(p2,'.')) {
2459 if (!strchr(p1,'.')) {
2467 string_sub(p1,"*.*","*");
2468 string_sub(p1,".*","*");
2472 /* Remove any *? and ** as they are meaningless */
2473 for(p = p1; *p; p++)
2474 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2475 (void)strcpy( &p[1], &p[2]);
2477 if (strequal(p1,"*")) return(True);
2479 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2485 if ((p=strrchr(p1,'.'))) {
2494 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2504 matched = do_match(sbase,ebase,case_sig) &&
2505 (trans2 || do_match(sext,eext,case_sig));
2507 DEBUG(5,("mask_match returning %d\n", matched));
2514 /****************************************************************************
2515 become a daemon, discarding the controlling terminal
2516 ****************************************************************************/
2517 void become_daemon(void)
2519 #ifndef NO_FORK_DEBUG
2523 /* detach from the terminal */
2529 int i = open("/dev/tty", O_RDWR);
2532 ioctl(i, (int) TIOCNOTTY, (char *)0);
2542 /****************************************************************************
2543 put up a yes/no prompt
2544 ****************************************************************************/
2550 if (!fgets(ans,sizeof(ans)-1,stdin))
2553 if (*ans == 'y' || *ans == 'Y')
2559 /****************************************************************************
2560 read a line from a file with possible \ continuation chars.
2561 Blanks at the start or end of a line are stripped.
2562 The string will be allocated if s2 is NULL
2563 ****************************************************************************/
2564 char *fgets_slash(char *s2,int maxlen,FILE *f)
2569 BOOL start_of_line = True;
2576 maxlen = MIN(maxlen,8);
2577 s = (char *)Realloc(s,maxlen);
2580 if (!s || maxlen < 2) return(NULL);
2584 while (len < maxlen-1)
2592 while (len > 0 && s[len-1] == ' ')
2596 if (len > 0 && s[len-1] == '\\')
2599 start_of_line = True;
2604 if (len <= 0 && !s2)
2606 return(len>0?s:NULL);
2611 start_of_line = False;
2615 if (!s2 && len > maxlen-3)
2618 s = (char *)Realloc(s,maxlen);
2619 if (!s) return(NULL);
2627 /****************************************************************************
2628 set the length of a file from a filedescriptor.
2629 Returns 0 on success, -1 on failure.
2630 ****************************************************************************/
2631 int set_filelen(int fd, long len)
2633 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2634 extend a file with ftruncate. Provide alternate implementation
2637 #if FTRUNCATE_CAN_EXTEND
2638 return ftruncate(fd, len);
2642 long currpos = lseek(fd, 0L, SEEK_CUR);
2646 /* Do an fstat to see if the file is longer than
2647 the requested size (call ftruncate),
2648 or shorter, in which case seek to len - 1 and write 1
2650 if(fstat(fd, &st)<0)
2654 if (S_ISFIFO(st.st_mode)) return 0;
2657 if(st.st_size == len)
2659 if(st.st_size > len)
2660 return ftruncate(fd, len);
2662 if(lseek(fd, len-1, SEEK_SET) != len -1)
2664 if(write(fd, &c, 1)!=1)
2666 /* Seek to where we were */
2667 lseek(fd, currpos, SEEK_SET);
2673 /****************************************************************************
2674 return the byte checksum of some data
2675 ****************************************************************************/
2676 int byte_checksum(char *buf,int len)
2678 unsigned char *p = (unsigned char *)buf;
2688 /****************************************************************************
2689 this is a version of setbuffer() for those machines that only have setvbuf
2690 ****************************************************************************/
2691 void setbuffer(FILE *f,char *buf,int bufsize)
2693 setvbuf(f,buf,_IOFBF,bufsize);
2698 /****************************************************************************
2699 parse out a directory name from a path name. Assumes dos style filenames.
2700 ****************************************************************************/
2701 char *dirname_dos(char *path,char *buf)
2703 char *p = strrchr(path,'\\');
2718 /****************************************************************************
2719 parse out a filename from a path name. Assumes dos style filenames.
2720 ****************************************************************************/
2721 static char *filename_dos(char *path,char *buf)
2723 char *p = strrchr(path,'\\');
2735 /****************************************************************************
2736 expand a pointer to be a particular size
2737 ****************************************************************************/
2738 void *Realloc(void *p,int size)
2744 DEBUG(5,("Realloc asked for 0 bytes\n"));
2749 ret = (void *)malloc(size);
2751 ret = (void *)realloc(p,size);
2754 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2760 /****************************************************************************
2762 ****************************************************************************/
2763 char *strdup(char *s)
2766 if (!s) return(NULL);
2767 ret = (char *)malloc(strlen(s)+1);
2768 if (!ret) return(NULL);
2775 /****************************************************************************
2776 Signal handler for SIGPIPE (write on a disconnected socket)
2777 ****************************************************************************/
2780 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2784 /****************************************************************************
2785 get my own name and IP
2786 ****************************************************************************/
2787 BOOL get_myname(char *myname,struct in_addr *ip)
2794 /* get my host name */
2795 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2797 DEBUG(0,("gethostname failed\n"));
2802 if ((hp = Get_Hostbyname(hostname)) == 0)
2804 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2810 /* split off any parts after an initial . */
2811 char *p = strchr(hostname,'.');
2814 strcpy(myname,hostname);
2818 putip((char *)ip,(char *)hp->h_addr);
2824 /****************************************************************************
2825 true if two IP addresses are equal
2826 ****************************************************************************/
2827 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2829 unsigned long a1,a2;
2830 a1 = ntohl(ip1.s_addr);
2831 a2 = ntohl(ip2.s_addr);
2836 /****************************************************************************
2837 open a socket of the specified type, port and address for incoming data
2838 ****************************************************************************/
2839 int open_socket_in(int type, int port, int dlevel)
2842 struct sockaddr_in sock;
2846 /* get my host name */
2847 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2848 { DEBUG(0,("gethostname failed\n")); return -1; }
2851 if ((hp = Get_Hostbyname(host_name)) == 0)
2853 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2857 bzero((char *)&sock,sizeof(sock));
2858 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2859 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2860 sock.sin_len = sizeof(sock);
2862 sock.sin_port = htons( port );
2863 sock.sin_family = hp->h_addrtype;
2864 sock.sin_addr.s_addr = INADDR_ANY;
2865 res = socket(hp->h_addrtype, type, 0);
2867 { DEBUG(0,("socket failed\n")); return -1; }
2871 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2874 /* now we've got a socket - we need to bind it */
2875 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2878 if (port == SMB_PORT || port == NMB_PORT)
2879 DEBUG(dlevel,("bind failed on port %d (%s)\n",
2880 port,strerror(errno)));
2883 if (dlevel > 0 && port < 1000)
2886 if (port >= 1000 && port < 9000)
2887 return(open_socket_in(type,port+1,dlevel));
2892 DEBUG(3,("bind succeeded on port %d\n",port));
2898 /****************************************************************************
2899 create an outgoing socket
2900 **************************************************************************/
2901 int open_socket_out(int type, struct in_addr *addr, int port )
2903 struct sockaddr_in sock_out;
2906 /* create a socket to write to */
2907 res = socket(PF_INET, type, 0);
2909 { DEBUG(0,("socket error\n")); return -1; }
2911 if (type != SOCK_STREAM) return(res);
2913 bzero((char *)&sock_out,sizeof(sock_out));
2914 putip((char *)&sock_out.sin_addr,(char *)addr);
2916 sock_out.sin_port = htons( port );
2917 sock_out.sin_family = PF_INET;
2919 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2921 /* and connect it to the destination */
2922 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
2923 DEBUG(0,("connect error: %s\n",strerror(errno)));
2932 /****************************************************************************
2933 interpret a protocol description string, with a default
2934 ****************************************************************************/
2935 int interpret_protocol(char *str,int def)
2937 if (strequal(str,"NT1"))
2938 return(PROTOCOL_NT1);
2939 if (strequal(str,"LANMAN2"))
2940 return(PROTOCOL_LANMAN2);
2941 if (strequal(str,"LANMAN1"))
2942 return(PROTOCOL_LANMAN1);
2943 if (strequal(str,"CORE"))
2944 return(PROTOCOL_CORE);
2945 if (strequal(str,"COREPLUS"))
2946 return(PROTOCOL_COREPLUS);
2947 if (strequal(str,"CORE+"))
2948 return(PROTOCOL_COREPLUS);
2950 DEBUG(0,("Unrecognised protocol level %s\n",str));
2955 /****************************************************************************
2956 interpret a security level
2957 ****************************************************************************/
2958 int interpret_security(char *str,int def)
2960 if (strequal(str,"SERVER"))
2962 if (strequal(str,"USER"))
2964 if (strequal(str,"SHARE"))
2967 DEBUG(0,("Unrecognised security level %s\n",str));
2973 /****************************************************************************
2974 interpret an internet address or name into an IP address in 4 byte form
2975 ****************************************************************************/
2976 unsigned long interpret_addr(char *str)
2981 if (strcmp(str,"0.0.0.0") == 0) return(0);
2982 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2984 /* if it's in the form of an IP address then get the lib to interpret it */
2985 if (isdigit(str[0])) {
2986 res = inet_addr(str);
2988 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
2989 if ((hp = Get_Hostbyname(str)) == 0) {
2990 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2993 putip((char *)&res,(char *)hp->h_addr);
2996 if (res == (unsigned long)-1) return(0);
3001 /*******************************************************************
3002 a convenient addition to interpret_addr()
3003 ******************************************************************/
3004 struct in_addr *interpret_addr2(char *str)
3006 static struct in_addr ret;
3007 unsigned long a = interpret_addr(str);
3012 /*******************************************************************
3013 check if an IP is the 0.0.0.0
3014 ******************************************************************/
3015 BOOL zero_ip(struct in_addr ip)
3018 putip((char *)&a,(char *)&ip);
3022 /*******************************************************************
3023 sub strings with useful parameters
3024 ********************************************************************/
3025 void standard_sub_basic(char *s)
3027 if (!strchr(s,'%')) return;
3029 string_sub(s,"%R",remote_proto);
3030 string_sub(s,"%a",remote_arch);
3031 string_sub(s,"%m",remote_machine);
3032 string_sub(s,"%L",local_machine);
3034 if (!strchr(s,'%')) return;
3036 string_sub(s,"%v",VERSION);
3037 string_sub(s,"%h",myhostname);
3038 string_sub(s,"%U",sesssetup_user);
3040 if (!strchr(s,'%')) return;
3042 string_sub(s,"%I",Client_info.addr);
3043 string_sub(s,"%M",Client_info.name);
3044 string_sub(s,"%T",timestring());
3046 if (!strchr(s,'%')) return;
3050 sprintf(pidstr,"%d",(int)getpid());
3051 string_sub(s,"%d",pidstr);
3054 if (!strchr(s,'%')) return;
3057 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3059 string_sub(s,"%G",gidtoname(pass->pw_gid));
3065 /*******************************************************************
3066 are two IPs on the same subnet?
3067 ********************************************************************/
3068 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3070 unsigned long net1,net2,nmask;
3072 nmask = ntohl(mask.s_addr);
3073 net1 = ntohl(ip1.s_addr);
3074 net2 = ntohl(ip2.s_addr);
3076 return((net1 & nmask) == (net2 & nmask));
3080 /*******************************************************************
3081 write a string in unicoode format
3082 ********************************************************************/
3083 int PutUniCode(char *dst,char *src)
3087 dst[ret++] = src[0];
3096 /****************************************************************************
3097 a wrapper for gethostbyname() that tries with all lower and all upper case
3098 if the initial name fails
3099 ****************************************************************************/
3100 struct hostent *Get_Hostbyname(char *name)
3102 char *name2 = strdup(name);
3103 struct hostent *ret;
3107 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3111 if (!isalnum(*name2))
3117 ret = gethostbyname(name2);
3124 /* try with all lowercase */
3126 ret = gethostbyname(name2);
3133 /* try with all uppercase */
3135 ret = gethostbyname(name2);
3142 /* nothing works :-( */
3148 /****************************************************************************
3149 check if a process exists. Does this work on all unixes?
3150 ****************************************************************************/
3151 BOOL process_exists(int pid)
3155 sprintf(s,"/proc/%d",pid);
3156 return(directory_exist(s,NULL));
3159 static BOOL tested=False;
3160 static BOOL ok=False;
3164 sprintf(s,"/proc/%05d",getpid());
3165 ok = file_exist(s,NULL);
3168 sprintf(s,"/proc/%05d",pid);
3169 return(file_exist(s,NULL));
3173 /* a best guess for non root access */
3174 if (geteuid() != 0) return(True);
3176 /* otherwise use kill */
3177 return(pid == getpid() || kill(pid,0) == 0);
3182 /*******************************************************************
3183 turn a uid into a user name
3184 ********************************************************************/
3185 char *uidtoname(int uid)
3187 static char name[40];
3188 struct passwd *pass = getpwuid(uid);
3189 if (pass) return(pass->pw_name);
3190 sprintf(name,"%d",uid);
3194 /*******************************************************************
3195 turn a gid into a group name
3196 ********************************************************************/
3197 char *gidtoname(int gid)
3199 static char name[40];
3200 struct group *grp = getgrgid(gid);
3201 if (grp) return(grp->gr_name);
3202 sprintf(name,"%d",gid);
3206 /*******************************************************************
3208 ********************************************************************/
3209 void BlockSignals(BOOL block)
3212 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3213 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3216 sigblock(block_mask);
3218 sigunblock(block_mask);
3223 /*******************************************************************
3224 my own panic function - not suitable for general use
3225 ********************************************************************/
3226 void ajt_panic(void)
3228 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
3233 #define DIRECT direct
3235 #define DIRECT dirent
3238 /*******************************************************************
3239 a readdir wrapper which just returns the file name
3240 also return the inode number if requested
3241 ********************************************************************/
3242 char *readdirname(void *p)
3247 if (!p) return(NULL);
3249 ptr = (struct DIRECT *)readdir(p);
3250 if (!ptr) return(NULL);
3252 dname = ptr->d_name;
3258 unix_to_dos(buf, True);
3264 if (telldir(p) < 0) return(NULL);
3268 /* this handles a broken compiler setup, causing a mixture
3269 of BSD and SYSV headers and libraries */
3271 static BOOL broken_readdir = False;
3272 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3274 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3275 broken_readdir = True;