2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 int Protocol = PROTOCOL_COREPLUS;
33 /* a default finfo structure to ensure all fields are sensible */
34 file_info def_finfo = {-1,0,0,0,0,0,0,""};
36 /* these are some file handles where debug info will be stored */
39 /* the client file descriptor */
42 /* info on the client */
43 struct from_host Client_info=
44 {"UNKNOWN","0.0.0.0",NULL};
46 /* the last IP received from */
47 struct in_addr lastip;
49 /* the last port received from */
55 case handling on filenames
57 int case_default = CASE_LOWER;
59 pstring debugf = "/tmp/log.samba";
62 /* the following control case operations - they are put here so the
63 client can link easily */
66 BOOL use_mangled_map = False;
67 BOOL short_case_preserve;
70 fstring remote_machine="";
71 fstring local_machine="";
72 fstring remote_arch="UNKNOWN";
73 fstring remote_proto="UNKNOWN";
74 pstring myhostname="";
75 pstring user_socket_options="";
76 pstring sesssetup_user="";
79 static char *filename_dos(char *path,char *buf);
81 static BOOL stdout_logging = False;
84 /*******************************************************************
85 get ready for syslog stuff
86 ******************************************************************/
87 void setup_logging(char *pname,BOOL interactive)
91 char *p = strrchr(pname,'/');
93 openlog(pname, LOG_PID, LOG_DAEMON);
97 stdout_logging = True;
103 BOOL append_log=False;
106 /****************************************************************************
108 ****************************************************************************/
109 void reopen_logs(void)
116 strcpy(fname,debugf);
117 if (lp_loaded() && (*lp_logfile()))
118 strcpy(fname,lp_logfile());
120 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
122 strcpy(debugf,fname);
123 if (dbf) fclose(dbf);
125 dbf = fopen(debugf,"a");
127 dbf = fopen(debugf,"w");
128 if (dbf) setbuf(dbf,NULL);
142 /*******************************************************************
143 check if the log has grown too big
144 ********************************************************************/
145 static void check_log_size(void)
147 static int debug_count=0;
151 if (debug_count++ < 100) return;
153 maxlog = lp_max_log_size() * 1024;
154 if (!dbf || maxlog <= 0) return;
156 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
157 fclose(dbf); dbf = NULL;
159 if (dbf && file_size(debugf) > maxlog) {
161 fclose(dbf); dbf = NULL;
162 sprintf(name,"%s.old",debugf);
163 sys_rename(debugf,name);
171 /*******************************************************************
172 write an debug message on the debugfile. This is called by the DEBUG
174 ********************************************************************/
176 int Debug1(char *format_str, ...)
186 if (stdout_logging) {
188 va_start(ap, format_str);
191 format_str = va_arg(ap,char *);
193 vfprintf(dbf,format_str,ap);
199 if (!lp_syslog_only())
204 dbf = fopen(debugf,"w");
213 if (syslog_level < lp_syslog())
216 * map debug levels to syslog() priorities
217 * note that not all DEBUG(0, ...) calls are
220 static int priority_map[] = {
229 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
231 priority = LOG_DEBUG;
233 priority = priority_map[syslog_level];
236 va_start(ap, format_str);
239 format_str = va_arg(ap,char *);
241 vsprintf(msgbuf, format_str, ap);
245 syslog(priority, "%s", msgbuf);
250 if (!lp_syslog_only())
254 va_start(ap, format_str);
257 format_str = va_arg(ap,char *);
259 vfprintf(dbf,format_str,ap);
269 /****************************************************************************
270 determine if a file descriptor is in fact a socket
271 ****************************************************************************/
272 BOOL is_a_socket(int fd)
276 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
280 static char *last_ptr=NULL;
282 /****************************************************************************
283 Get the next token from a string, return False if none found
284 handles double-quotes.
285 Based on a routine by GJC@VILLAGE.COM.
286 Extensively modified by Andrew.Tridgell@anu.edu.au
287 ****************************************************************************/
288 BOOL next_token(char **ptr,char *buff,char *sep)
293 if (!ptr) ptr = &last_ptr;
294 if (!ptr) return(False);
298 /* default to simple separators */
299 if (!sep) sep = " \t\n\r";
301 /* find the first non sep char */
302 while(*s && strchr(sep,*s)) s++;
305 if (! *s) return(False);
307 /* copy over the token */
308 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
316 *ptr = (*s) ? s+1 : s;
323 /****************************************************************************
324 Convert list of tokens to array; dependent on above routine.
325 Uses last_ptr from above - bit of a hack.
326 ****************************************************************************/
327 char **toktocliplist(int *ctok, char *sep)
333 if (!sep) sep = " \t\n\r";
335 while(*s && strchr(sep,*s)) s++;
338 if (!*s) return(NULL);
342 while(*s && (!strchr(sep,*s))) s++;
343 while(*s && strchr(sep,*s)) *s++=0;
349 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
361 /*******************************************************************
362 safely copies memory, ensuring no overlap problems.
363 this is only used if the machine does not have it's own memmove().
364 this is not the fastest algorithm in town, but it will do for our
366 ********************************************************************/
367 void *MemMove(void *dest,void *src,int size)
371 if (dest==src || !size) return(dest);
373 d = (unsigned long)dest;
374 s = (unsigned long)src;
376 if ((d >= (s+size)) || (s >= (d+size))) {
378 memcpy(dest,src,size);
384 /* we can forward copy */
385 if (s-d >= sizeof(int) &&
386 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
387 /* do it all as words */
388 int *idest = (int *)dest;
389 int *isrc = (int *)src;
391 for (i=0;i<size;i++) idest[i] = isrc[i];
394 char *cdest = (char *)dest;
395 char *csrc = (char *)src;
396 for (i=0;i<size;i++) cdest[i] = csrc[i];
401 /* must backward copy */
402 if (d-s >= sizeof(int) &&
403 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
404 /* do it all as words */
405 int *idest = (int *)dest;
406 int *isrc = (int *)src;
408 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
411 char *cdest = (char *)dest;
412 char *csrc = (char *)src;
413 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
421 /****************************************************************************
422 prompte a dptr (to make it recently used)
423 ****************************************************************************/
424 void array_promote(char *array,int elsize,int element)
430 p = (char *)malloc(elsize);
434 DEBUG(5,("Ahh! Can't malloc\n"));
437 memcpy(p,array + element * elsize, elsize);
438 memmove(array + elsize,array,elsize*element);
439 memcpy(array,p,elsize);
443 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
452 } socket_options[] = {
453 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
454 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
455 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
457 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
459 #ifdef IPTOS_LOWDELAY
460 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
462 #ifdef IPTOS_THROUGHPUT
463 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
466 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
469 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
472 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
475 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
481 /****************************************************************************
482 set user socket options
483 ****************************************************************************/
484 void set_socket_options(int fd, char *options)
488 while (next_token(&options,tok," \t,"))
493 BOOL got_value = False;
495 if ((p = strchr(tok,'=')))
502 for (i=0;socket_options[i].name;i++)
503 if (strequal(socket_options[i].name,tok))
506 if (!socket_options[i].name)
508 DEBUG(0,("Unknown socket option %s\n",tok));
512 switch (socket_options[i].opttype)
516 ret = setsockopt(fd,socket_options[i].level,
517 socket_options[i].option,(char *)&value,sizeof(int));
522 DEBUG(0,("syntax error - %s does not take a value\n",tok));
525 int on = socket_options[i].value;
526 ret = setsockopt(fd,socket_options[i].level,
527 socket_options[i].option,(char *)&on,sizeof(int));
533 DEBUG(0,("Failed to set socket option %s\n",tok));
539 /****************************************************************************
540 close the socket communication
541 ****************************************************************************/
542 void close_sockets(void )
548 /****************************************************************************
549 determine whether we are in the specified group
550 ****************************************************************************/
551 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
555 if (group == current_gid) return(True);
557 for (i=0;i<ngroups;i++)
558 if (group == groups[i])
564 /****************************************************************************
565 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
566 ****************************************************************************/
567 char *StrCpy(char *dest,char *src)
572 /* I don't want to get lazy with these ... */
574 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
579 if (!dest) return(NULL);
584 while ((*d++ = *src++)) ;
588 /****************************************************************************
589 line strncpy but always null terminates. Make sure there is room!
590 ****************************************************************************/
591 char *StrnCpy(char *dest,const char *src,int n)
594 if (!dest) return(NULL);
599 while (n-- && (*d++ = *src++)) ;
605 /*******************************************************************
606 copy an IP address from one buffer to another
607 ********************************************************************/
608 void putip(void *dest,void *src)
614 /****************************************************************************
615 interpret the weird netbios "name". Return the name type
616 ****************************************************************************/
617 static int name_interpret(char *in,char *out)
620 int len = (*in++) / 2;
624 if (len > 30 || len<1) return(0);
628 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
632 *out = ((in[0]-'A')<<4) + (in[1]-'A');
640 /* Handle any scope names */
643 *out++ = '.'; /* Scope names are separated by periods */
644 len = *(unsigned char *)in++;
645 StrnCpy(out, in, len);
654 /****************************************************************************
655 mangle a name into netbios format
656 ****************************************************************************/
657 int name_mangle(char *In,char *Out,char name_type)
661 char *in = (char *)&buf[0];
662 char *out = (char *)Out;
667 StrnCpy(name,In,sizeof(name)-1);
668 sprintf(buf,"%-15.15s%c",name,name_type);
671 memset(&buf[1],0,16);
676 char c = toupper(in[i]);
677 out[i*2] = (c>>4) + 'A';
678 out[i*2+1] = (c & 0xF) + 'A';
686 p = strchr(label, '.');
688 p = label + strlen(label);
690 memcpy(out, label, p - label);
692 label += p - label + (*p == '.');
695 return(name_len(Out));
699 /*******************************************************************
700 check if a file exists
701 ********************************************************************/
702 BOOL file_exist(char *fname,struct stat *sbuf)
705 if (!sbuf) sbuf = &st;
707 if (sys_stat(fname,sbuf) != 0)
710 return(S_ISREG(sbuf->st_mode));
713 /*******************************************************************
714 check a files mod time
715 ********************************************************************/
716 time_t file_modtime(char *fname)
720 if (sys_stat(fname,&st) != 0)
726 /*******************************************************************
727 check if a directory exists
728 ********************************************************************/
729 BOOL directory_exist(char *dname,struct stat *st)
734 if (sys_stat(dname,st) != 0)
737 return(S_ISDIR(st->st_mode));
740 /*******************************************************************
741 returns the size in bytes of the named file
742 ********************************************************************/
743 uint32 file_size(char *file_name)
747 sys_stat(file_name,&buf);
751 /*******************************************************************
752 return a string representing an attribute for a file
753 ********************************************************************/
754 char *attrib_string(int mode)
756 static char attrstr[10];
760 if (mode & aVOLID) strcat(attrstr,"V");
761 if (mode & aDIR) strcat(attrstr,"D");
762 if (mode & aARCH) strcat(attrstr,"A");
763 if (mode & aHIDDEN) strcat(attrstr,"H");
764 if (mode & aSYSTEM) strcat(attrstr,"S");
765 if (mode & aRONLY) strcat(attrstr,"R");
771 /*******************************************************************
772 case insensitive string compararison
773 ********************************************************************/
774 int StrCaseCmp(char *s, char *t)
776 for (; tolower(*s) == tolower(*t); ++s, ++t)
779 return tolower(*s) - tolower(*t);
782 /*******************************************************************
783 case insensitive string compararison, length limited
784 ********************************************************************/
785 int StrnCaseCmp(char *s, char *t, int n)
787 while (n-- && *s && *t) {
788 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
791 if (n) return(tolower(*s) - tolower(*t));
796 /*******************************************************************
798 ********************************************************************/
799 BOOL strequal(char *s1,char *s2)
801 if (s1 == s2) return(True);
802 if (!s1 || !s2) return(False);
804 return(StrCaseCmp(s1,s2)==0);
807 /*******************************************************************
808 compare 2 strings up to and including the nth char.
809 ******************************************************************/
810 BOOL strnequal(char *s1,char *s2,int n)
812 if (s1 == s2) return(True);
813 if (!s1 || !s2 || !n) return(False);
815 return(StrnCaseCmp(s1,s2,n)==0);
818 /*******************************************************************
819 compare 2 strings (case sensitive)
820 ********************************************************************/
821 BOOL strcsequal(char *s1,char *s2)
823 if (s1 == s2) return(True);
824 if (!s1 || !s2) return(False);
826 return(strcmp(s1,s2)==0);
830 /*******************************************************************
831 convert a string to lower case
832 ********************************************************************/
833 void strlower(char *s)
838 if (is_shift_jis (*s)) {
840 } else if (is_kana (*s)) {
855 /*******************************************************************
856 convert a string to upper case
857 ********************************************************************/
858 void strupper(char *s)
863 if (is_shift_jis (*s)) {
865 } else if (is_kana (*s)) {
880 /*******************************************************************
881 convert a string to "normal" form
882 ********************************************************************/
883 void strnorm(char *s)
885 if (case_default == CASE_UPPER)
891 /*******************************************************************
892 check if a string is in "normal" case
893 ********************************************************************/
894 BOOL strisnormal(char *s)
896 if (case_default == CASE_UPPER)
897 return(!strhaslower(s));
899 return(!strhasupper(s));
903 /****************************************************************************
905 ****************************************************************************/
906 void string_replace(char *s,char oldc,char newc)
911 if (is_shift_jis (*s)) {
913 } else if (is_kana (*s)) {
928 /****************************************************************************
929 make a file into unix format
930 ****************************************************************************/
931 void unix_format(char *fname)
934 string_replace(fname,'\\','/');
936 dos2unix_format(fname, True);
941 strcpy(namecopy,fname);
943 strcat(fname,namecopy);
947 /****************************************************************************
948 make a file into dos format
949 ****************************************************************************/
950 void dos_format(char *fname)
953 unix2dos_format(fname, True);
955 string_replace(fname,'/','\\');
959 /*******************************************************************
960 show a smb message structure
961 ********************************************************************/
962 void show_msg(char *buf)
969 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
971 (int)CVAL(buf,smb_com),
972 (int)CVAL(buf,smb_rcls),
973 (int)CVAL(buf,smb_reh),
974 (int)SVAL(buf,smb_err),
975 (int)CVAL(buf,smb_flg),
976 (int)SVAL(buf,smb_flg2)));
977 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
978 (int)SVAL(buf,smb_tid),
979 (int)SVAL(buf,smb_pid),
980 (int)SVAL(buf,smb_uid),
981 (int)SVAL(buf,smb_mid),
982 (int)CVAL(buf,smb_wct)));
983 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
984 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
985 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
986 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
987 DEBUG(5,("smb_bcc=%d\n",bcc));
990 for (i=0;i<MIN(bcc,128);i++)
991 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
995 /*******************************************************************
996 return the length of an smb packet
997 ********************************************************************/
998 int smb_len(char *buf)
1000 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1003 /*******************************************************************
1004 set the length of an smb packet
1005 ********************************************************************/
1006 void _smb_setlen(char *buf,int len)
1009 buf[1] = (len&0x10000)>>16;
1010 buf[2] = (len&0xFF00)>>8;
1014 /*******************************************************************
1015 set the length and marker of an smb packet
1016 ********************************************************************/
1017 void smb_setlen(char *buf,int len)
1019 _smb_setlen(buf,len);
1027 /*******************************************************************
1028 setup the word count and byte count for a smb message
1029 ********************************************************************/
1030 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1033 bzero(buf + smb_size,num_words*2 + num_bytes);
1034 CVAL(buf,smb_wct) = num_words;
1035 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1036 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1037 return (smb_size + num_words*2 + num_bytes);
1040 /*******************************************************************
1041 return the number of smb words
1042 ********************************************************************/
1043 int smb_numwords(char *buf)
1045 return (CVAL(buf,smb_wct));
1048 /*******************************************************************
1049 return the size of the smb_buf region of a message
1050 ********************************************************************/
1051 int smb_buflen(char *buf)
1053 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1056 /*******************************************************************
1057 return a pointer to the smb_buf data area
1058 ********************************************************************/
1059 int smb_buf_ofs(char *buf)
1061 return (smb_size + CVAL(buf,smb_wct)*2);
1064 /*******************************************************************
1065 return a pointer to the smb_buf data area
1066 ********************************************************************/
1067 char *smb_buf(char *buf)
1069 return (buf + smb_buf_ofs(buf));
1072 /*******************************************************************
1073 return the SMB offset into an SMB buffer
1074 ********************************************************************/
1075 int smb_offset(char *p,char *buf)
1077 return(PTR_DIFF(p,buf+4));
1081 /*******************************************************************
1082 skip past some strings in a buffer
1083 ********************************************************************/
1084 char *skip_string(char *buf,int n)
1087 buf += strlen(buf) + 1;
1091 /*******************************************************************
1092 trim the specified elements off the front and back of a string
1093 ********************************************************************/
1094 BOOL trim_string(char *s,char *front,char *back)
1097 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1103 if (!(*p = p[strlen(front)]))
1108 while (back && *back && strlen(s) >= strlen(back) &&
1109 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1112 s[strlen(s)-strlen(back)] = 0;
1118 /*******************************************************************
1119 reduce a file name, removing .. elements.
1120 ********************************************************************/
1121 void dos_clean_name(char *s)
1125 DEBUG(3,("dos_clean_name [%s]\n",s));
1127 /* remove any double slashes */
1128 string_sub(s, "\\\\", "\\");
1130 while ((p = strstr(s,"\\..\\")) != NULL)
1137 if ((p=strrchr(s,'\\')) != NULL)
1144 trim_string(s,NULL,"\\..");
1146 string_sub(s, "\\.\\", "\\");
1149 /*******************************************************************
1150 reduce a file name, removing .. elements.
1151 ********************************************************************/
1152 void unix_clean_name(char *s)
1156 DEBUG(3,("unix_clean_name [%s]\n",s));
1158 /* remove any double slashes */
1159 string_sub(s, "//","/");
1161 while ((p = strstr(s,"/../")) != NULL)
1168 if ((p=strrchr(s,'/')) != NULL)
1175 trim_string(s,NULL,"/..");
1179 /*******************************************************************
1180 a wrapper for the normal chdir() function
1181 ********************************************************************/
1182 int ChDir(char *path)
1185 static pstring LastDir="";
1187 if (strcsequal(path,".")) return(0);
1189 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1190 DEBUG(3,("chdir to %s\n",path));
1191 res = sys_chdir(path);
1193 strcpy(LastDir,path);
1198 /*******************************************************************
1199 return the absolute current directory path. A dumb version.
1200 ********************************************************************/
1201 static char *Dumb_GetWd(char *s)
1204 return ((char *)getcwd(s,sizeof(pstring)));
1206 return ((char *)getwd(s));
1211 /* number of list structures for a caching GetWd function. */
1212 #define MAX_GETWDCACHE (50)
1220 } ino_list[MAX_GETWDCACHE];
1222 BOOL use_getwd_cache=True;
1224 /*******************************************************************
1225 return the absolute current directory path
1226 ********************************************************************/
1227 char *GetWd(char *str)
1230 static BOOL getwd_cache_init = False;
1231 struct stat st, st2;
1236 if (!use_getwd_cache)
1237 return(Dumb_GetWd(str));
1239 /* init the cache */
1240 if (!getwd_cache_init)
1242 getwd_cache_init = True;
1243 for (i=0;i<MAX_GETWDCACHE;i++)
1245 string_init(&ino_list[i].text,"");
1246 ino_list[i].valid = False;
1250 /* Get the inode of the current directory, if this doesn't work we're
1253 if (stat(".",&st) == -1)
1255 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1256 return(Dumb_GetWd(str));
1260 for (i=0; i<MAX_GETWDCACHE; i++)
1261 if (ino_list[i].valid)
1264 /* If we have found an entry with a matching inode and dev number
1265 then find the inode number for the directory in the cached string.
1266 If this agrees with that returned by the stat for the current
1267 directory then all is o.k. (but make sure it is a directory all
1270 if (st.st_ino == ino_list[i].inode &&
1271 st.st_dev == ino_list[i].dev)
1273 if (stat(ino_list[i].text,&st2) == 0)
1275 if (st.st_ino == st2.st_ino &&
1276 st.st_dev == st2.st_dev &&
1277 (st2.st_mode & S_IFMT) == S_IFDIR)
1279 strcpy (str, ino_list[i].text);
1281 /* promote it for future use */
1282 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1287 /* If the inode is different then something's changed,
1288 scrub the entry and start from scratch. */
1289 ino_list[i].valid = False;
1296 /* We don't have the information to hand so rely on traditional methods.
1297 The very slow getcwd, which spawns a process on some systems, or the
1298 not quite so bad getwd. */
1302 DEBUG(0,("Getwd failed, errno %d\n",errno));
1308 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1310 /* add it to the cache */
1311 i = MAX_GETWDCACHE - 1;
1312 string_set(&ino_list[i].text,s);
1313 ino_list[i].dev = st.st_dev;
1314 ino_list[i].inode = st.st_ino;
1315 ino_list[i].valid = True;
1317 /* put it at the top of the list */
1318 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1325 /*******************************************************************
1326 reduce a file name, removing .. elements and checking that
1327 it is below dir in the heirachy. This uses GetWd() and so must be run
1328 on the system that has the referenced file system.
1330 widelinks are allowed if widelinks is true
1331 ********************************************************************/
1332 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1334 #ifndef REDUCE_PATHS
1342 BOOL relative = (*s != '/');
1344 *dir2 = *wd = *basename = *newname = 0;
1349 /* can't have a leading .. */
1350 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1352 DEBUG(3,("Illegal file name? (%s)\n",s));
1358 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1360 /* remove any double slashes */
1361 string_sub(s,"//","/");
1364 p = strrchr(basename,'/');
1371 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1375 if (ChDir(dir) != 0)
1377 DEBUG(0,("couldn't chdir to %s\n",dir));
1383 DEBUG(0,("couldn't getwd for %s\n",dir));
1389 if (p && (p != basename))
1392 if (strcmp(p+1,".")==0)
1394 if (strcmp(p+1,"..")==0)
1398 if (ChDir(basename) != 0)
1401 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1405 if (!GetWd(newname))
1408 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1412 if (p && (p != basename))
1414 strcat(newname,"/");
1415 strcat(newname,p+1);
1419 int l = strlen(dir2);
1420 if (dir2[l-1] == '/')
1423 if (strncmp(newname,dir2,l) != 0)
1426 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1432 if (newname[l] == '/')
1433 strcpy(s,newname + l + 1);
1435 strcpy(s,newname+l);
1446 DEBUG(3,("reduced to %s\n",s));
1451 /****************************************************************************
1453 ****************************************************************************/
1454 static void expand_one(char *Mask,int len)
1457 while ((p1 = strchr(Mask,'*')) != NULL)
1459 int lfill = (len+1) - strlen(Mask);
1460 int l1= (p1 - Mask);
1463 memset(tmp+l1,'?',lfill);
1464 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1469 /****************************************************************************
1470 expand a wildcard expression, replacing *s with ?s
1471 ****************************************************************************/
1472 void expand_mask(char *Mask,BOOL doext)
1477 BOOL hasdot = False;
1479 BOOL absolute = (*Mask == '\\');
1481 *mbeg = *mext = *dirpart = *filepart = 0;
1483 /* parse the directory and filename */
1484 if (strchr(Mask,'\\'))
1485 dirname_dos(Mask,dirpart);
1487 filename_dos(Mask,filepart);
1489 strcpy(mbeg,filepart);
1490 if ((p1 = strchr(mbeg,'.')) != NULL)
1500 if (strlen(mbeg) > 8)
1502 strcpy(mext,mbeg + 8);
1508 strcpy(mbeg,"????????");
1509 if ((*mext == 0) && doext && !hasdot)
1512 if (strequal(mbeg,"*") && *mext==0)
1520 strcpy(Mask,dirpart);
1521 if (*dirpart || absolute) strcat(Mask,"\\");
1526 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1530 /****************************************************************************
1531 does a string have any uppercase chars in it?
1532 ****************************************************************************/
1533 BOOL strhasupper(char *s)
1538 if (is_shift_jis (*s)) {
1540 } else if (is_kana (*s)) {
1543 if (isupper(*s)) return(True);
1547 if (isupper(*s)) return(True);
1554 /****************************************************************************
1555 does a string have any lowercase chars in it?
1556 ****************************************************************************/
1557 BOOL strhaslower(char *s)
1562 if (is_shift_jis (*s)) {
1564 } else if (is_kana (*s)) {
1567 if (islower(*s)) return(True);
1571 if (islower(*s)) return(True);
1578 /****************************************************************************
1579 find the number of chars in a string
1580 ****************************************************************************/
1581 int count_chars(char *s,char c)
1594 /****************************************************************************
1596 ****************************************************************************/
1597 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1604 if ((mode & aDIR) != 0)
1607 memset(buf+1,' ',11);
1608 if ((p = strchr(mask2,'.')) != NULL)
1611 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1612 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1616 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1618 bzero(buf+21,DIR_STRUCT_SIZE-21);
1619 CVAL(buf,21) = mode;
1620 put_dos_date(buf,22,date);
1621 SSVAL(buf,26,size & 0xFFFF);
1622 SSVAL(buf,28,size >> 16);
1623 StrnCpy(buf+30,fname,12);
1624 if (!case_sensitive)
1626 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1630 /*******************************************************************
1631 close the low 3 fd's and open dev/null in their place
1632 ********************************************************************/
1633 void close_low_fds(void)
1637 close(0); close(1); close(2);
1638 /* try and use up these file descriptors, so silly
1639 library routines writing to stdout etc won't cause havoc */
1641 fd = open("/dev/null",O_RDWR,0);
1642 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1644 DEBUG(0,("Can't open /dev/null\n"));
1648 DEBUG(0,("Didn't get file descriptor %d\n",i));
1655 /****************************************************************************
1657 ****************************************************************************/
1658 int write_socket(int fd,char *buf,int len)
1664 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1665 ret = write_data(fd,buf,len);
1667 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1671 /****************************************************************************
1673 ****************************************************************************/
1674 int read_udp_socket(int fd,char *buf,int len)
1677 struct sockaddr sock;
1680 socklen = sizeof(sock);
1681 bzero((char *)&sock,socklen);
1682 bzero((char *)&lastip,sizeof(lastip));
1683 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1685 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1689 lastip = *(struct in_addr *) &sock.sa_data[2];
1690 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1695 /****************************************************************************
1696 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1698 if SYSV use O_NDELAY
1700 ****************************************************************************/
1701 int set_blocking(int fd, BOOL set)
1705 #define FLAG_TO_SET O_NONBLOCK
1708 #define FLAG_TO_SET O_NDELAY
1710 #define FLAG_TO_SET FNDELAY
1714 if((val = fcntl(fd, F_GETFL, 0))==-1)
1716 if(set) /* Turn blocking on - ie. clear nonblock flag */
1717 val &= ~FLAG_TO_SET;
1720 return fcntl( fd, F_SETFL, val);
1725 /****************************************************************************
1726 Calculate the difference in timeout values. Return 1 if val1 > val2,
1727 0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
1728 may be == val1 or val2
1729 ****************************************************************************/
1730 static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
1732 int usecdiff = val1->tv_usec - val2->tv_usec;
1733 int secdiff = val1->tv_sec - val2->tv_sec;
1735 usecdiff = 1000000 + usecdiff;
1738 retval->tv_sec = secdiff;
1739 retval->tv_usec = usecdiff;
1744 return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
1747 /****************************************************************************
1748 read data from a device with a timout in msec.
1749 mincount = if timeout, minimum to read before returning
1750 maxcount = number to be read.
1751 ****************************************************************************/
1752 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
1758 struct timeval timeout, tval1, tval2, tvaldiff;
1759 int error_limit = 5;
1761 /* just checking .... */
1762 if (maxcnt <= 0) return(0);
1765 time_out = DEFAULT_PIPE_TIMEOUT;
1769 if (mincnt == 0) mincnt = maxcnt;
1771 while (nread < mincnt)
1773 readret = read(fd, buf + nread, maxcnt - nread);
1774 if (readret <= 0) return(nread);
1780 /* Non blocking read */
1782 set_blocking(fd, False);
1783 nread = read_data(fd, buf, mincnt);
1785 nread += read(fd,buf+nread,maxcnt-nread);
1786 if(nread == -1 && errno == EWOULDBLOCK)
1788 set_blocking(fd,True);
1792 /* Most difficult - timeout read */
1793 /* If this is ever called on a disk file and
1794 mincnt is greater then the filesize then
1795 system performance will suffer severely as
1796 select always return true on disk files */
1798 /* Set initial timeout */
1799 timeout.tv_sec = time_out / 1000;
1800 timeout.tv_usec = 1000 * (time_out % 1000);
1802 /* As most UNIXes don't modify the value of timeout
1803 when they return from select we need to get the timeofday (in usec)
1804 now, and also after the select returns so we know
1805 how much time has elapsed */
1808 GetTimeOfDay( &tval1);
1809 nread = 0; /* Number of bytes we have read */
1816 selrtn = sys_select(&fds,&timeout);
1818 /* Check if error */
1823 /* Did we timeout ? */
1825 if (nread < mincnt) return -1;
1829 readret = read(fd, buf+nread, maxcnt-nread);
1830 if (readret == 0 && nread < mincnt) {
1831 /* error_limit should not really be needed, but some systems
1832 do strange things ... I don't want to just continue
1833 indefinately in case we get an infinite loop */
1834 if (error_limit--) continue;
1839 /* force a particular error number for
1841 DEBUG(5,("read gave error %s\n",strerror(errno)));
1847 /* If we have read more than mincnt then return */
1848 if (nread >= mincnt)
1851 /* We need to do another select - but first reduce the
1852 time_out by the amount of time already elapsed - if
1853 this is less than zero then return */
1855 GetTimeOfDay(&tval2);
1856 (void)tval_sub( &tvaldiff, &tval2, &tval1);
1858 if (tval_sub(&timeout, &timeout, &tvaldiff) <= 0)
1859 break; /* We timed out */
1862 /* Save the time of day as we need to do the select
1863 again (saves a system call) */
1867 /* Return the number we got */
1871 /****************************************************************************
1872 read data from the client. Maxtime is in milliseconds
1873 ****************************************************************************/
1874 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1879 struct timeval timeout;
1884 timeout.tv_sec = maxtime / 1000;
1885 timeout.tv_usec = (maxtime % 1000) * 1000;
1887 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1889 if (!FD_ISSET(fd,&fds))
1892 nread = read_udp_socket(fd, buffer, bufsize);
1894 /* return the number got */
1898 /*******************************************************************
1899 find the difference in milliseconds between two struct timeval
1901 ********************************************************************/
1902 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1904 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1905 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1908 /****************************************************************************
1909 send a keepalive packet (rfc1002)
1910 ****************************************************************************/
1911 BOOL send_keepalive(int client)
1913 unsigned char buf[4];
1916 buf[1] = buf[2] = buf[3] = 0;
1918 return(write_data(client,(char *)buf,4) == 4);
1923 /****************************************************************************
1924 read data from the client, reading exactly N bytes.
1925 ****************************************************************************/
1926 int read_data(int fd,char *buffer,int N)
1933 ret = read(fd,buffer + total,N - total);
1943 /****************************************************************************
1945 ****************************************************************************/
1946 int write_data(int fd,char *buffer,int N)
1953 ret = write(fd,buffer + total,N - total);
1964 /****************************************************************************
1965 transfer some data between two fd's
1966 ****************************************************************************/
1967 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1969 static char *buf=NULL;
1974 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1977 size = lp_readsize();
1978 size = MAX(size,1024);
1981 while (!buf && size>0) {
1982 buf = (char *)Realloc(buf,size+8);
1983 if (!buf) size /= 2;
1987 DEBUG(0,("Can't allocate transfer buffer!\n"));
1991 abuf = buf + (align%8);
1998 int s = MIN(n,size);
2003 if (header && (headlen >= MIN(s,1024))) {
2013 if (header && headlen > 0)
2015 ret = MIN(headlen,size);
2016 memcpy(buf1,header,ret);
2019 if (headlen <= 0) header = NULL;
2023 ret += read(infd,buf1+ret,s-ret);
2027 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2028 if (ret2 > 0) total += ret2;
2029 /* if we can't write then dump excess data */
2031 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2033 if (ret <= 0 || ret2 != ret)
2041 /****************************************************************************
2042 read 4 bytes of a smb packet and return the smb length of the packet
2043 possibly store the result in the buffer
2044 ****************************************************************************/
2045 int read_smb_length(int fd,char *inbuf,int timeout)
2049 int len=0, msg_type;
2060 ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2062 ok = (read_data(fd,buffer,4) == 4);
2068 DEBUG(10,("select timeout (%d)\n", timeout));
2073 DEBUG(6,("couldn't read from client\n"));
2078 len = smb_len(buffer);
2079 msg_type = CVAL(buffer,0);
2081 if (msg_type == 0x85)
2083 DEBUG(5,( "Got keepalive packet\n"));
2088 DEBUG(10,("got smb length of %d\n",len));
2095 /****************************************************************************
2096 read an smb from a fd and return it's length
2097 The timeout is in milli seconds
2098 ****************************************************************************/
2099 BOOL receive_smb(int fd,char *buffer,int timeout)
2104 bzero(buffer,smb_size + 100);
2106 len = read_smb_length(fd,buffer,timeout);
2110 if (len > BUFFER_SIZE) {
2111 DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2112 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2116 ok = (read_data(fd,buffer+4,len) == len);
2128 /****************************************************************************
2130 ****************************************************************************/
2131 BOOL send_smb(int fd,char *buffer)
2135 len = smb_len(buffer) + 4;
2137 while (nwritten < len)
2139 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2142 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2154 /****************************************************************************
2155 find a pointer to a netbios name
2156 ****************************************************************************/
2157 char *name_ptr(char *buf,int ofs)
2159 unsigned char c = *(unsigned char *)(buf+ofs);
2161 if ((c & 0xC0) == 0xC0)
2165 memcpy(p,buf+ofs,2);
2168 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2175 /****************************************************************************
2176 extract a netbios name from a buf
2177 ****************************************************************************/
2178 int name_extract(char *buf,int ofs,char *name)
2180 char *p = name_ptr(buf,ofs);
2181 int d = PTR_DIFF(p,buf+ofs);
2183 if (d < -50 || d > 50) return(0);
2184 return(name_interpret(p,name));
2188 /****************************************************************************
2189 return the total storage length of a mangled name
2190 ****************************************************************************/
2191 int name_len(char *s)
2194 unsigned char c = *(unsigned char *)s;
2195 if ((c & 0xC0) == 0xC0)
2197 while (*s) s += (*s)+1;
2198 return(PTR_DIFF(s,s0)+1);
2201 /****************************************************************************
2202 send a single packet to a port on another machine
2203 ****************************************************************************/
2204 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2208 struct sockaddr_in sock_out;
2213 /* create a socket to write to */
2214 out_fd = socket(AF_INET, type, 0);
2217 DEBUG(0,("socket failed"));
2221 /* set the address and port */
2222 bzero((char *)&sock_out,sizeof(sock_out));
2223 putip((char *)&sock_out.sin_addr,(char *)&ip);
2224 sock_out.sin_port = htons( port );
2225 sock_out.sin_family = AF_INET;
2228 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2229 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2232 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2235 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2236 inet_ntoa(ip),port,errno));
2242 /*******************************************************************
2243 sleep for a specified number of milliseconds
2244 ********************************************************************/
2248 struct timeval tval,t1,t2;
2255 tval.tv_sec = (t-tdiff)/1000;
2256 tval.tv_usec = 1000*((t-tdiff)%1000);
2260 sys_select(&fds,&tval);
2263 tdiff = TvalDiff(&t1,&t2);
2267 /****************************************************************************
2268 check if a string is part of a list
2269 ****************************************************************************/
2270 BOOL in_list(char *s,char *list,BOOL casesensitive)
2275 if (!list) return(False);
2277 while (next_token(&p,tok,LIST_SEP))
2279 if (casesensitive) {
2280 if (strcmp(tok,s) == 0)
2283 if (StrCaseCmp(tok,s) == 0)
2290 /* this is used to prevent lots of mallocs of size 1 */
2291 static char *null_string = NULL;
2293 /****************************************************************************
2294 set a string value, allocing the space for the string
2295 ****************************************************************************/
2296 BOOL string_init(char **dest,char *src)
2307 null_string = (char *)malloc(1);
2310 *dest = null_string;
2314 *dest = (char *)malloc(l+1);
2320 /****************************************************************************
2322 ****************************************************************************/
2323 void string_free(char **s)
2325 if (!s || !(*s)) return;
2326 if (*s == null_string)
2332 /****************************************************************************
2333 set a string value, allocing the space for the string, and deallocating any
2335 ****************************************************************************/
2336 BOOL string_set(char **dest,char *src)
2340 return(string_init(dest,src));
2343 /****************************************************************************
2344 substitute a string for a pattern in another string. Make sure there is
2347 This routine looks for pattern in s and replaces it with
2348 insert. It may do multiple replacements.
2350 return True if a substitution was done.
2351 ****************************************************************************/
2352 BOOL string_sub(char *s,char *pattern,char *insert)
2358 if (!insert || !pattern || !s) return(False);
2361 lp = strlen(pattern);
2362 li = strlen(insert);
2364 if (!*pattern) return(False);
2366 while (lp <= ls && (p = strstr(s,pattern)))
2369 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2370 memcpy(p,insert,li);
2379 /*********************************************************
2380 * Recursive routine that is called by mask_match.
2381 * Does the actual matching.
2382 *********************************************************/
2383 BOOL do_match(char *str, char *regexp, int case_sig)
2387 for( p = regexp; *p && *str; ) {
2394 /* Look for a character matching
2395 the one after the '*' */
2398 return True; /* Automatic match */
2400 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2402 if(do_match(str,p,case_sig))
2416 if(toupper(*str) != toupper(*p))
2426 if (!*p && str[0] == '.' && str[1] == 0)
2429 if (!*str && *p == '?')
2431 while (*p == '?') p++;
2435 if(!*str && (*p == '*' && p[1] == '\0'))
2441 /*********************************************************
2442 * Routine to match a given string with a regexp - uses
2443 * simplified regexp that takes * and ? only. Case can be
2444 * significant or not.
2445 *********************************************************/
2446 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2450 fstring ebase,eext,sbase,sext;
2454 /* Make local copies of str and regexp */
2455 StrnCpy(p1,regexp,sizeof(pstring)-1);
2456 StrnCpy(p2,str,sizeof(pstring)-1);
2458 if (!strchr(p2,'.')) {
2463 if (!strchr(p1,'.')) {
2471 string_sub(p1,"*.*","*");
2472 string_sub(p1,".*","*");
2476 /* Remove any *? and ** as they are meaningless */
2477 for(p = p1; *p; p++)
2478 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2479 (void)strcpy( &p[1], &p[2]);
2481 if (strequal(p1,"*")) return(True);
2483 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2489 if ((p=strrchr(p1,'.'))) {
2498 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2508 matched = do_match(sbase,ebase,case_sig) &&
2509 (trans2 || do_match(sext,eext,case_sig));
2511 DEBUG(5,("mask_match returning %d\n", matched));
2518 /****************************************************************************
2519 become a daemon, discarding the controlling terminal
2520 ****************************************************************************/
2521 void become_daemon(void)
2523 #ifndef NO_FORK_DEBUG
2527 /* detach from the terminal */
2533 int i = open("/dev/tty", O_RDWR);
2536 ioctl(i, (int) TIOCNOTTY, (char *)0);
2546 /****************************************************************************
2547 put up a yes/no prompt
2548 ****************************************************************************/
2554 if (!fgets(ans,sizeof(ans)-1,stdin))
2557 if (*ans == 'y' || *ans == 'Y')
2563 /****************************************************************************
2564 read a line from a file with possible \ continuation chars.
2565 Blanks at the start or end of a line are stripped.
2566 The string will be allocated if s2 is NULL
2567 ****************************************************************************/
2568 char *fgets_slash(char *s2,int maxlen,FILE *f)
2573 BOOL start_of_line = True;
2580 maxlen = MIN(maxlen,8);
2581 s = (char *)Realloc(s,maxlen);
2584 if (!s || maxlen < 2) return(NULL);
2588 while (len < maxlen-1)
2596 while (len > 0 && s[len-1] == ' ')
2600 if (len > 0 && s[len-1] == '\\')
2603 start_of_line = True;
2608 if (len <= 0 && !s2)
2610 return(len>0?s:NULL);
2615 start_of_line = False;
2619 if (!s2 && len > maxlen-3)
2622 s = (char *)Realloc(s,maxlen);
2623 if (!s) return(NULL);
2631 /****************************************************************************
2632 set the length of a file from a filedescriptor.
2633 Returns 0 on success, -1 on failure.
2634 ****************************************************************************/
2635 int set_filelen(int fd, long len)
2637 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2638 extend a file with ftruncate. Provide alternate implementation
2641 #if FTRUNCATE_CAN_EXTEND
2642 return ftruncate(fd, len);
2646 long currpos = lseek(fd, 0L, SEEK_CUR);
2650 /* Do an fstat to see if the file is longer than
2651 the requested size (call ftruncate),
2652 or shorter, in which case seek to len - 1 and write 1
2654 if(fstat(fd, &st)<0)
2658 if (S_ISFIFO(st.st_mode)) return 0;
2661 if(st.st_size == len)
2663 if(st.st_size > len)
2664 return ftruncate(fd, len);
2666 if(lseek(fd, len-1, SEEK_SET) != len -1)
2668 if(write(fd, &c, 1)!=1)
2670 /* Seek to where we were */
2671 lseek(fd, currpos, SEEK_SET);
2677 /****************************************************************************
2678 return the byte checksum of some data
2679 ****************************************************************************/
2680 int byte_checksum(char *buf,int len)
2682 unsigned char *p = (unsigned char *)buf;
2692 /****************************************************************************
2693 this is a version of setbuffer() for those machines that only have setvbuf
2694 ****************************************************************************/
2695 void setbuffer(FILE *f,char *buf,int bufsize)
2697 setvbuf(f,buf,_IOFBF,bufsize);
2702 /****************************************************************************
2703 parse out a directory name from a path name. Assumes dos style filenames.
2704 ****************************************************************************/
2705 char *dirname_dos(char *path,char *buf)
2707 char *p = strrchr(path,'\\');
2722 /****************************************************************************
2723 parse out a filename from a path name. Assumes dos style filenames.
2724 ****************************************************************************/
2725 static char *filename_dos(char *path,char *buf)
2727 char *p = strrchr(path,'\\');
2739 /****************************************************************************
2740 expand a pointer to be a particular size
2741 ****************************************************************************/
2742 void *Realloc(void *p,int size)
2748 DEBUG(5,("Realloc asked for 0 bytes\n"));
2753 ret = (void *)malloc(size);
2755 ret = (void *)realloc(p,size);
2758 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2764 /****************************************************************************
2766 ****************************************************************************/
2767 char *strdup(char *s)
2770 if (!s) return(NULL);
2771 ret = (char *)malloc(strlen(s)+1);
2772 if (!ret) return(NULL);
2779 /****************************************************************************
2780 Signal handler for SIGPIPE (write on a disconnected socket)
2781 ****************************************************************************/
2784 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2788 /****************************************************************************
2789 get my own name and IP
2790 ****************************************************************************/
2791 BOOL get_myname(char *myname,struct in_addr *ip)
2798 /* get my host name */
2799 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2801 DEBUG(0,("gethostname failed\n"));
2806 if ((hp = Get_Hostbyname(hostname)) == 0)
2808 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2814 /* split off any parts after an initial . */
2815 char *p = strchr(hostname,'.');
2818 strcpy(myname,hostname);
2822 putip((char *)ip,(char *)hp->h_addr);
2828 /****************************************************************************
2829 true if two IP addresses are equal
2830 ****************************************************************************/
2831 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2833 unsigned long a1,a2;
2834 a1 = ntohl(ip1.s_addr);
2835 a2 = ntohl(ip2.s_addr);
2840 /****************************************************************************
2841 open a socket of the specified type, port and address for incoming data
2842 ****************************************************************************/
2843 int open_socket_in(int type, int port, int dlevel)
2846 struct sockaddr_in sock;
2850 /* get my host name */
2851 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2852 { DEBUG(0,("gethostname failed\n")); return -1; }
2855 if ((hp = Get_Hostbyname(host_name)) == 0)
2857 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2861 bzero((char *)&sock,sizeof(sock));
2862 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2863 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2864 sock.sin_len = sizeof(sock);
2866 sock.sin_port = htons( port );
2867 sock.sin_family = hp->h_addrtype;
2868 sock.sin_addr.s_addr = INADDR_ANY;
2869 res = socket(hp->h_addrtype, type, 0);
2871 { DEBUG(0,("socket failed\n")); return -1; }
2875 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2878 /* now we've got a socket - we need to bind it */
2879 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2882 if (port == SMB_PORT || port == NMB_PORT)
2883 DEBUG(dlevel,("bind failed on port %d (%s)\n",
2884 port,strerror(errno)));
2887 if (dlevel > 0 && port < 1000)
2890 if (port >= 1000 && port < 9000)
2891 return(open_socket_in(type,port+1,dlevel));
2896 DEBUG(3,("bind succeeded on port %d\n",port));
2902 /****************************************************************************
2903 create an outgoing socket
2904 **************************************************************************/
2905 int open_socket_out(int type, struct in_addr *addr, int port )
2907 struct sockaddr_in sock_out;
2910 /* create a socket to write to */
2911 res = socket(PF_INET, type, 0);
2913 { DEBUG(0,("socket error\n")); return -1; }
2915 if (type != SOCK_STREAM) return(res);
2917 bzero((char *)&sock_out,sizeof(sock_out));
2918 putip((char *)&sock_out.sin_addr,(char *)addr);
2920 sock_out.sin_port = htons( port );
2921 sock_out.sin_family = PF_INET;
2923 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2925 /* and connect it to the destination */
2926 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
2927 DEBUG(0,("connect error: %s\n",strerror(errno)));
2936 /****************************************************************************
2937 interpret a protocol description string, with a default
2938 ****************************************************************************/
2939 int interpret_protocol(char *str,int def)
2941 if (strequal(str,"NT1"))
2942 return(PROTOCOL_NT1);
2943 if (strequal(str,"LANMAN2"))
2944 return(PROTOCOL_LANMAN2);
2945 if (strequal(str,"LANMAN1"))
2946 return(PROTOCOL_LANMAN1);
2947 if (strequal(str,"CORE"))
2948 return(PROTOCOL_CORE);
2949 if (strequal(str,"COREPLUS"))
2950 return(PROTOCOL_COREPLUS);
2951 if (strequal(str,"CORE+"))
2952 return(PROTOCOL_COREPLUS);
2954 DEBUG(0,("Unrecognised protocol level %s\n",str));
2959 /****************************************************************************
2960 interpret a security level
2961 ****************************************************************************/
2962 int interpret_security(char *str,int def)
2964 if (strequal(str,"SERVER"))
2966 if (strequal(str,"USER"))
2968 if (strequal(str,"SHARE"))
2971 DEBUG(0,("Unrecognised security level %s\n",str));
2977 /****************************************************************************
2978 interpret an internet address or name into an IP address in 4 byte form
2979 ****************************************************************************/
2980 unsigned long interpret_addr(char *str)
2985 if (strcmp(str,"0.0.0.0") == 0) return(0);
2986 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2988 /* if it's in the form of an IP address then get the lib to interpret it */
2989 if (isdigit(str[0])) {
2990 res = inet_addr(str);
2992 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
2993 if ((hp = Get_Hostbyname(str)) == 0) {
2994 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2997 putip((char *)&res,(char *)hp->h_addr);
3000 if (res == (unsigned long)-1) return(0);
3005 /*******************************************************************
3006 a convenient addition to interpret_addr()
3007 ******************************************************************/
3008 struct in_addr *interpret_addr2(char *str)
3010 static struct in_addr ret;
3011 unsigned long a = interpret_addr(str);
3016 /*******************************************************************
3017 check if an IP is the 0.0.0.0
3018 ******************************************************************/
3019 BOOL zero_ip(struct in_addr ip)
3022 putip((char *)&a,(char *)&ip);
3026 /*******************************************************************
3027 sub strings with useful parameters
3028 ********************************************************************/
3029 void standard_sub_basic(char *s)
3031 if (!strchr(s,'%')) return;
3033 string_sub(s,"%R",remote_proto);
3034 string_sub(s,"%a",remote_arch);
3035 string_sub(s,"%m",remote_machine);
3036 string_sub(s,"%L",local_machine);
3038 if (!strchr(s,'%')) return;
3040 string_sub(s,"%v",VERSION);
3041 string_sub(s,"%h",myhostname);
3042 string_sub(s,"%U",sesssetup_user);
3044 if (!strchr(s,'%')) return;
3046 string_sub(s,"%I",Client_info.addr);
3047 string_sub(s,"%M",Client_info.name);
3048 string_sub(s,"%T",timestring());
3050 if (!strchr(s,'%')) return;
3054 sprintf(pidstr,"%d",(int)getpid());
3055 string_sub(s,"%d",pidstr);
3058 if (!strchr(s,'%')) return;
3061 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3063 string_sub(s,"%G",gidtoname(pass->pw_gid));
3069 /*******************************************************************
3070 are two IPs on the same subnet?
3071 ********************************************************************/
3072 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3074 unsigned long net1,net2,nmask;
3076 nmask = ntohl(mask.s_addr);
3077 net1 = ntohl(ip1.s_addr);
3078 net2 = ntohl(ip2.s_addr);
3080 return((net1 & nmask) == (net2 & nmask));
3084 /*******************************************************************
3085 write a string in unicoode format
3086 ********************************************************************/
3087 int PutUniCode(char *dst,char *src)
3091 dst[ret++] = src[0];
3100 /****************************************************************************
3101 a wrapper for gethostbyname() that tries with all lower and all upper case
3102 if the initial name fails
3103 ****************************************************************************/
3104 struct hostent *Get_Hostbyname(char *name)
3106 char *name2 = strdup(name);
3107 struct hostent *ret;
3111 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3115 if (!isalnum(*name2))
3121 ret = gethostbyname(name2);
3128 /* try with all lowercase */
3130 ret = gethostbyname(name2);
3137 /* try with all uppercase */
3139 ret = gethostbyname(name2);
3146 /* nothing works :-( */
3152 /****************************************************************************
3153 check if a process exists. Does this work on all unixes?
3154 ****************************************************************************/
3155 BOOL process_exists(int pid)
3159 sprintf(s,"/proc/%d",pid);
3160 return(directory_exist(s,NULL));
3163 static BOOL tested=False;
3164 static BOOL ok=False;
3168 sprintf(s,"/proc/%05d",getpid());
3169 ok = file_exist(s,NULL);
3172 sprintf(s,"/proc/%05d",pid);
3173 return(file_exist(s,NULL));
3177 /* a best guess for non root access */
3178 if (geteuid() != 0) return(True);
3180 /* otherwise use kill */
3181 return(pid == getpid() || kill(pid,0) == 0);
3186 /*******************************************************************
3187 turn a uid into a user name
3188 ********************************************************************/
3189 char *uidtoname(int uid)
3191 static char name[40];
3192 struct passwd *pass = getpwuid(uid);
3193 if (pass) return(pass->pw_name);
3194 sprintf(name,"%d",uid);
3198 /*******************************************************************
3199 turn a gid into a group name
3200 ********************************************************************/
3201 char *gidtoname(int gid)
3203 static char name[40];
3204 struct group *grp = getgrgid(gid);
3205 if (grp) return(grp->gr_name);
3206 sprintf(name,"%d",gid);
3210 /*******************************************************************
3212 ********************************************************************/
3213 void BlockSignals(BOOL block)
3216 int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
3217 |sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
3220 sigblock(block_mask);
3222 sigunblock(block_mask);
3227 /*******************************************************************
3228 my own panic function - not suitable for general use
3229 ********************************************************************/
3230 void ajt_panic(void)
3232 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
3237 #define DIRECT direct
3239 #define DIRECT dirent
3242 /*******************************************************************
3243 a readdir wrapper which just returns the file name
3244 also return the inode number if requested
3245 ********************************************************************/
3246 char *readdirname(void *p)
3251 if (!p) return(NULL);
3253 ptr = (struct DIRECT *)readdir(p);
3254 if (!ptr) return(NULL);
3256 dname = ptr->d_name;
3262 unix_to_dos(buf, True);
3268 if (telldir(p) < 0) return(NULL);
3272 /* this handles a broken compiler setup, causing a mixture
3273 of BSD and SYSV headers and libraries */
3275 static BOOL broken_readdir = False;
3276 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3278 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3279 broken_readdir = True;