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)
2103 bzero(buffer,smb_size + 100);
2105 len = read_smb_length(fd,buffer,timeout);
2109 if (len > BUFFER_SIZE) {
2110 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2111 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2115 ok = (read_data(fd,buffer+4,len) == len);
2127 /****************************************************************************
2129 ****************************************************************************/
2130 BOOL send_smb(int fd,char *buffer)
2134 len = smb_len(buffer) + 4;
2136 while (nwritten < len)
2138 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2141 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2153 /****************************************************************************
2154 find a pointer to a netbios name
2155 ****************************************************************************/
2156 char *name_ptr(char *buf,int ofs)
2158 unsigned char c = *(unsigned char *)(buf+ofs);
2160 if ((c & 0xC0) == 0xC0)
2164 memcpy(p,buf+ofs,2);
2167 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2174 /****************************************************************************
2175 extract a netbios name from a buf
2176 ****************************************************************************/
2177 int name_extract(char *buf,int ofs,char *name)
2179 char *p = name_ptr(buf,ofs);
2180 int d = PTR_DIFF(p,buf+ofs);
2182 if (d < -50 || d > 50) return(0);
2183 return(name_interpret(p,name));
2187 /****************************************************************************
2188 return the total storage length of a mangled name
2189 ****************************************************************************/
2190 int name_len(char *s)
2193 unsigned char c = *(unsigned char *)s;
2194 if ((c & 0xC0) == 0xC0)
2196 while (*s) s += (*s)+1;
2197 return(PTR_DIFF(s,s0)+1);
2200 /****************************************************************************
2201 send a single packet to a port on another machine
2202 ****************************************************************************/
2203 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2207 struct sockaddr_in sock_out;
2212 /* create a socket to write to */
2213 out_fd = socket(AF_INET, type, 0);
2216 DEBUG(0,("socket failed"));
2220 /* set the address and port */
2221 bzero((char *)&sock_out,sizeof(sock_out));
2222 putip((char *)&sock_out.sin_addr,(char *)&ip);
2223 sock_out.sin_port = htons( port );
2224 sock_out.sin_family = AF_INET;
2227 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2228 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2231 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2234 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2235 inet_ntoa(ip),port,errno));
2241 /*******************************************************************
2242 sleep for a specified number of milliseconds
2243 ********************************************************************/
2247 struct timeval tval,t1,t2;
2254 tval.tv_sec = (t-tdiff)/1000;
2255 tval.tv_usec = 1000*((t-tdiff)%1000);
2259 sys_select(&fds,&tval);
2262 tdiff = TvalDiff(&t1,&t2);
2266 /****************************************************************************
2267 check if a string is part of a list
2268 ****************************************************************************/
2269 BOOL in_list(char *s,char *list,BOOL casesensitive)
2274 if (!list) return(False);
2276 while (next_token(&p,tok,LIST_SEP))
2278 if (casesensitive) {
2279 if (strcmp(tok,s) == 0)
2282 if (StrCaseCmp(tok,s) == 0)
2289 /* this is used to prevent lots of mallocs of size 1 */
2290 static char *null_string = NULL;
2292 /****************************************************************************
2293 set a string value, allocing the space for the string
2294 ****************************************************************************/
2295 BOOL string_init(char **dest,char *src)
2306 null_string = (char *)malloc(1);
2309 *dest = null_string;
2313 *dest = (char *)malloc(l+1);
2319 /****************************************************************************
2321 ****************************************************************************/
2322 void string_free(char **s)
2324 if (!s || !(*s)) return;
2325 if (*s == null_string)
2331 /****************************************************************************
2332 set a string value, allocing the space for the string, and deallocating any
2334 ****************************************************************************/
2335 BOOL string_set(char **dest,char *src)
2339 return(string_init(dest,src));
2342 /****************************************************************************
2343 substitute a string for a pattern in another string. Make sure there is
2346 This routine looks for pattern in s and replaces it with
2347 insert. It may do multiple replacements.
2349 return True if a substitution was done.
2350 ****************************************************************************/
2351 BOOL string_sub(char *s,char *pattern,char *insert)
2357 if (!insert || !pattern || !s) return(False);
2360 lp = strlen(pattern);
2361 li = strlen(insert);
2363 if (!*pattern) return(False);
2365 while (lp <= ls && (p = strstr(s,pattern)))
2368 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2369 memcpy(p,insert,li);
2378 /*********************************************************
2379 * Recursive routine that is called by mask_match.
2380 * Does the actual matching.
2381 *********************************************************/
2382 BOOL do_match(char *str, char *regexp, int case_sig)
2386 for( p = regexp; *p && *str; ) {
2393 /* Look for a character matching
2394 the one after the '*' */
2397 return True; /* Automatic match */
2399 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2401 if(do_match(str,p,case_sig))
2415 if(toupper(*str) != toupper(*p))
2425 if (!*p && str[0] == '.' && str[1] == 0)
2428 if (!*str && *p == '?')
2430 while (*p == '?') p++;
2434 if(!*str && (*p == '*' && p[1] == '\0'))
2440 /*********************************************************
2441 * Routine to match a given string with a regexp - uses
2442 * simplified regexp that takes * and ? only. Case can be
2443 * significant or not.
2444 *********************************************************/
2445 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2449 fstring ebase,eext,sbase,sext;
2453 /* Make local copies of str and regexp */
2454 StrnCpy(p1,regexp,sizeof(pstring)-1);
2455 StrnCpy(p2,str,sizeof(pstring)-1);
2457 if (!strchr(p2,'.')) {
2462 if (!strchr(p1,'.')) {
2470 string_sub(p1,"*.*","*");
2471 string_sub(p1,".*","*");
2475 /* Remove any *? and ** as they are meaningless */
2476 for(p = p1; *p; p++)
2477 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2478 (void)strcpy( &p[1], &p[2]);
2480 if (strequal(p1,"*")) return(True);
2482 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2488 if ((p=strrchr(p1,'.'))) {
2497 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2507 matched = do_match(sbase,ebase,case_sig) &&
2508 (trans2 || do_match(sext,eext,case_sig));
2510 DEBUG(5,("mask_match returning %d\n", matched));
2517 /****************************************************************************
2518 become a daemon, discarding the controlling terminal
2519 ****************************************************************************/
2520 void become_daemon(void)
2522 #ifndef NO_FORK_DEBUG
2526 /* detach from the terminal */
2532 int i = open("/dev/tty", O_RDWR);
2535 ioctl(i, (int) TIOCNOTTY, (char *)0);
2545 /****************************************************************************
2546 put up a yes/no prompt
2547 ****************************************************************************/
2553 if (!fgets(ans,sizeof(ans)-1,stdin))
2556 if (*ans == 'y' || *ans == 'Y')
2562 /****************************************************************************
2563 read a line from a file with possible \ continuation chars.
2564 Blanks at the start or end of a line are stripped.
2565 The string will be allocated if s2 is NULL
2566 ****************************************************************************/
2567 char *fgets_slash(char *s2,int maxlen,FILE *f)
2572 BOOL start_of_line = True;
2579 maxlen = MIN(maxlen,8);
2580 s = (char *)Realloc(s,maxlen);
2583 if (!s || maxlen < 2) return(NULL);
2587 while (len < maxlen-1)
2595 while (len > 0 && s[len-1] == ' ')
2599 if (len > 0 && s[len-1] == '\\')
2602 start_of_line = True;
2607 if (len <= 0 && !s2)
2609 return(len>0?s:NULL);
2614 start_of_line = False;
2618 if (!s2 && len > maxlen-3)
2621 s = (char *)Realloc(s,maxlen);
2622 if (!s) return(NULL);
2630 /****************************************************************************
2631 set the length of a file from a filedescriptor.
2632 Returns 0 on success, -1 on failure.
2633 ****************************************************************************/
2634 int set_filelen(int fd, long len)
2636 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2637 extend a file with ftruncate. Provide alternate implementation
2640 #if FTRUNCATE_CAN_EXTEND
2641 return ftruncate(fd, len);
2645 long currpos = lseek(fd, 0L, SEEK_CUR);
2649 /* Do an fstat to see if the file is longer than
2650 the requested size (call ftruncate),
2651 or shorter, in which case seek to len - 1 and write 1
2653 if(fstat(fd, &st)<0)
2657 if (S_ISFIFO(st.st_mode)) return 0;
2660 if(st.st_size == len)
2662 if(st.st_size > len)
2663 return ftruncate(fd, len);
2665 if(lseek(fd, len-1, SEEK_SET) != len -1)
2667 if(write(fd, &c, 1)!=1)
2669 /* Seek to where we were */
2670 lseek(fd, currpos, SEEK_SET);
2676 /****************************************************************************
2677 return the byte checksum of some data
2678 ****************************************************************************/
2679 int byte_checksum(char *buf,int len)
2681 unsigned char *p = (unsigned char *)buf;
2691 /****************************************************************************
2692 this is a version of setbuffer() for those machines that only have setvbuf
2693 ****************************************************************************/
2694 void setbuffer(FILE *f,char *buf,int bufsize)
2696 setvbuf(f,buf,_IOFBF,bufsize);
2701 /****************************************************************************
2702 parse out a directory name from a path name. Assumes dos style filenames.
2703 ****************************************************************************/
2704 char *dirname_dos(char *path,char *buf)
2706 char *p = strrchr(path,'\\');
2721 /****************************************************************************
2722 parse out a filename from a path name. Assumes dos style filenames.
2723 ****************************************************************************/
2724 static char *filename_dos(char *path,char *buf)
2726 char *p = strrchr(path,'\\');
2738 /****************************************************************************
2739 expand a pointer to be a particular size
2740 ****************************************************************************/
2741 void *Realloc(void *p,int size)
2747 DEBUG(5,("Realloc asked for 0 bytes\n"));
2752 ret = (void *)malloc(size);
2754 ret = (void *)realloc(p,size);
2757 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2763 /****************************************************************************
2765 ****************************************************************************/
2766 char *strdup(char *s)
2769 if (!s) return(NULL);
2770 ret = (char *)malloc(strlen(s)+1);
2771 if (!ret) return(NULL);
2778 /****************************************************************************
2779 Signal handler for SIGPIPE (write on a disconnected socket)
2780 ****************************************************************************/
2783 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2787 /****************************************************************************
2788 get my own name and IP
2789 ****************************************************************************/
2790 BOOL get_myname(char *myname,struct in_addr *ip)
2797 /* get my host name */
2798 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2800 DEBUG(0,("gethostname failed\n"));
2805 if ((hp = Get_Hostbyname(hostname)) == 0)
2807 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2813 /* split off any parts after an initial . */
2814 char *p = strchr(hostname,'.');
2817 strcpy(myname,hostname);
2821 putip((char *)ip,(char *)hp->h_addr);
2827 /****************************************************************************
2828 true if two IP addresses are equal
2829 ****************************************************************************/
2830 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2832 unsigned long a1,a2;
2833 a1 = ntohl(ip1.s_addr);
2834 a2 = ntohl(ip2.s_addr);
2839 /****************************************************************************
2840 open a socket of the specified type, port and address for incoming data
2841 ****************************************************************************/
2842 int open_socket_in(int type, int port, int dlevel)
2845 struct sockaddr_in sock;
2849 /* get my host name */
2850 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2851 { DEBUG(0,("gethostname failed\n")); return -1; }
2854 if ((hp = Get_Hostbyname(host_name)) == 0)
2856 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2860 bzero((char *)&sock,sizeof(sock));
2861 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2862 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2863 sock.sin_len = sizeof(sock);
2865 sock.sin_port = htons( port );
2866 sock.sin_family = hp->h_addrtype;
2867 sock.sin_addr.s_addr = INADDR_ANY;
2868 res = socket(hp->h_addrtype, type, 0);
2870 { DEBUG(0,("socket failed\n")); return -1; }
2874 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2877 /* now we've got a socket - we need to bind it */
2878 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2881 if (port == SMB_PORT || port == NMB_PORT)
2882 DEBUG(dlevel,("bind failed on port %d (%s)\n",
2883 port,strerror(errno)));
2886 if (dlevel > 0 && port < 1000)
2889 if (port >= 1000 && port < 9000)
2890 return(open_socket_in(type,port+1,dlevel));
2895 DEBUG(3,("bind succeeded on port %d\n",port));
2901 /****************************************************************************
2902 create an outgoing socket
2903 **************************************************************************/
2904 int open_socket_out(int type, struct in_addr *addr, int port )
2906 struct sockaddr_in sock_out;
2909 /* create a socket to write to */
2910 res = socket(PF_INET, type, 0);
2912 { DEBUG(0,("socket error\n")); return -1; }
2914 if (type != SOCK_STREAM) return(res);
2916 bzero((char *)&sock_out,sizeof(sock_out));
2917 putip((char *)&sock_out.sin_addr,(char *)addr);
2919 sock_out.sin_port = htons( port );
2920 sock_out.sin_family = PF_INET;
2922 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2924 /* and connect it to the destination */
2925 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
2926 DEBUG(0,("connect error: %s\n",strerror(errno)));
2935 /****************************************************************************
2936 interpret a protocol description string, with a default
2937 ****************************************************************************/
2938 int interpret_protocol(char *str,int def)
2940 if (strequal(str,"NT1"))
2941 return(PROTOCOL_NT1);
2942 if (strequal(str,"LANMAN2"))
2943 return(PROTOCOL_LANMAN2);
2944 if (strequal(str,"LANMAN1"))
2945 return(PROTOCOL_LANMAN1);
2946 if (strequal(str,"CORE"))
2947 return(PROTOCOL_CORE);
2948 if (strequal(str,"COREPLUS"))
2949 return(PROTOCOL_COREPLUS);
2950 if (strequal(str,"CORE+"))
2951 return(PROTOCOL_COREPLUS);
2953 DEBUG(0,("Unrecognised protocol level %s\n",str));
2958 /****************************************************************************
2959 interpret a security level
2960 ****************************************************************************/
2961 int interpret_security(char *str,int def)
2963 if (strequal(str,"SERVER"))
2965 if (strequal(str,"USER"))
2967 if (strequal(str,"SHARE"))
2970 DEBUG(0,("Unrecognised security level %s\n",str));
2976 /****************************************************************************
2977 interpret an internet address or name into an IP address in 4 byte form
2978 ****************************************************************************/
2979 unsigned long interpret_addr(char *str)
2984 if (strcmp(str,"0.0.0.0") == 0) return(0);
2985 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2987 /* if it's in the form of an IP address then get the lib to interpret it */
2988 if (isdigit(str[0])) {
2989 res = inet_addr(str);
2991 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
2992 if ((hp = Get_Hostbyname(str)) == 0) {
2993 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2996 putip((char *)&res,(char *)hp->h_addr);
2999 if (res == (unsigned long)-1) return(0);
3004 /*******************************************************************
3005 a convenient addition to interpret_addr()
3006 ******************************************************************/
3007 struct in_addr *interpret_addr2(char *str)
3009 static struct in_addr ret;
3010 unsigned long a = interpret_addr(str);
3015 /*******************************************************************
3016 check if an IP is the 0.0.0.0
3017 ******************************************************************/
3018 BOOL zero_ip(struct in_addr ip)
3021 putip((char *)&a,(char *)&ip);
3025 /*******************************************************************
3026 sub strings with useful parameters
3027 ********************************************************************/
3028 void standard_sub_basic(char *s)
3030 if (!strchr(s,'%')) return;
3032 string_sub(s,"%R",remote_proto);
3033 string_sub(s,"%a",remote_arch);
3034 string_sub(s,"%m",remote_machine);
3035 string_sub(s,"%L",local_machine);
3037 if (!strchr(s,'%')) return;
3039 string_sub(s,"%v",VERSION);
3040 string_sub(s,"%h",myhostname);
3041 string_sub(s,"%U",sesssetup_user);
3043 if (!strchr(s,'%')) return;
3045 string_sub(s,"%I",Client_info.addr);
3046 string_sub(s,"%M",Client_info.name);
3047 string_sub(s,"%T",timestring());
3049 if (!strchr(s,'%')) return;
3053 sprintf(pidstr,"%d",(int)getpid());
3054 string_sub(s,"%d",pidstr);
3057 if (!strchr(s,'%')) return;
3060 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3062 string_sub(s,"%G",gidtoname(pass->pw_gid));
3068 /*******************************************************************
3069 are two IPs on the same subnet?
3070 ********************************************************************/
3071 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3073 unsigned long net1,net2,nmask;
3075 nmask = ntohl(mask.s_addr);
3076 net1 = ntohl(ip1.s_addr);
3077 net2 = ntohl(ip2.s_addr);
3079 return((net1 & nmask) == (net2 & nmask));
3083 /*******************************************************************
3084 write a string in unicoode format
3085 ********************************************************************/
3086 int PutUniCode(char *dst,char *src)
3090 dst[ret++] = src[0];
3099 /****************************************************************************
3100 a wrapper for gethostbyname() that tries with all lower and all upper case
3101 if the initial name fails
3102 ****************************************************************************/
3103 struct hostent *Get_Hostbyname(char *name)
3105 char *name2 = strdup(name);
3106 struct hostent *ret;
3110 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3114 if (!isalnum(*name2))
3120 ret = gethostbyname(name2);
3127 /* try with all lowercase */
3129 ret = gethostbyname(name2);
3136 /* try with all uppercase */
3138 ret = gethostbyname(name2);
3145 /* nothing works :-( */
3151 /****************************************************************************
3152 check if a process exists. Does this work on all unixes?
3153 ****************************************************************************/
3154 BOOL process_exists(int pid)
3158 sprintf(s,"/proc/%d",pid);
3159 return(directory_exist(s,NULL));
3162 static BOOL tested=False;
3163 static BOOL ok=False;
3167 sprintf(s,"/proc/%05d",getpid());
3168 ok = file_exist(s,NULL);
3171 sprintf(s,"/proc/%05d",pid);
3172 return(file_exist(s,NULL));
3176 /* a best guess for non root access */
3177 if (geteuid() != 0) return(True);
3179 /* otherwise use kill */
3180 return(pid == getpid() || kill(pid,0) == 0);
3185 /*******************************************************************
3186 turn a uid into a user name
3187 ********************************************************************/
3188 char *uidtoname(int uid)
3190 static char name[40];
3191 struct passwd *pass = getpwuid(uid);
3192 if (pass) return(pass->pw_name);
3193 sprintf(name,"%d",uid);
3197 /*******************************************************************
3198 turn a gid into a group name
3199 ********************************************************************/
3200 char *gidtoname(int gid)
3202 static char name[40];
3203 struct group *grp = getgrgid(gid);
3204 if (grp) return(grp->gr_name);
3205 sprintf(name,"%d",gid);
3209 /*******************************************************************
3211 ********************************************************************/
3212 void BlockSignals(BOOL block)
3215 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3216 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3219 sigblock(block_mask);
3221 sigunblock(block_mask);
3226 /*******************************************************************
3227 my own panic function - not suitable for general use
3228 ********************************************************************/
3229 void ajt_panic(void)
3231 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
3236 #define DIRECT direct
3238 #define DIRECT dirent
3241 /*******************************************************************
3242 a readdir wrapper which just returns the file name
3243 also return the inode number if requested
3244 ********************************************************************/
3245 char *readdirname(void *p)
3250 if (!p) return(NULL);
3252 ptr = (struct DIRECT *)readdir(p);
3253 if (!ptr) return(NULL);
3255 dname = ptr->d_name;
3261 unix_to_dos(buf, True);
3267 if (telldir(p) < 0) return(NULL);
3271 /* this handles a broken compiler setup, causing a mixture
3272 of BSD and SYSV headers and libraries */
3274 static BOOL broken_readdir = False;
3275 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3277 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3278 broken_readdir = True;