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 */
51 /* this is used by the chaining code */
57 case handling on filenames
59 int case_default = CASE_LOWER;
61 pstring debugf = "/tmp/log.samba";
64 /* the following control case operations - they are put here so the
65 client can link easily */
68 BOOL use_mangled_map = False;
69 BOOL short_case_preserve;
72 fstring remote_machine="";
73 fstring local_machine="";
74 fstring remote_arch="UNKNOWN";
75 fstring remote_proto="UNKNOWN";
76 pstring myhostname="";
77 pstring user_socket_options="";
78 pstring sesssetup_user="";
81 int smb_read_error = 0;
83 static char *filename_dos(char *path,char *buf);
85 static BOOL stdout_logging = False;
88 /*******************************************************************
89 get ready for syslog stuff
90 ******************************************************************/
91 void setup_logging(char *pname,BOOL interactive)
95 char *p = strrchr(pname,'/');
97 openlog(pname, LOG_PID, LOG_DAEMON);
101 stdout_logging = True;
107 BOOL append_log=False;
110 /****************************************************************************
112 ****************************************************************************/
113 void reopen_logs(void)
120 strcpy(fname,debugf);
121 if (lp_loaded() && (*lp_logfile()))
122 strcpy(fname,lp_logfile());
124 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
126 strcpy(debugf,fname);
127 if (dbf) fclose(dbf);
129 dbf = fopen(debugf,"a");
131 dbf = fopen(debugf,"w");
132 if (dbf) setbuf(dbf,NULL);
146 /*******************************************************************
147 check if the log has grown too big
148 ********************************************************************/
149 static void check_log_size(void)
151 static int debug_count=0;
155 if (debug_count++ < 100) return;
157 maxlog = lp_max_log_size() * 1024;
158 if (!dbf || maxlog <= 0) return;
160 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
161 fclose(dbf); dbf = NULL;
163 if (dbf && file_size(debugf) > maxlog) {
165 fclose(dbf); dbf = NULL;
166 sprintf(name,"%s.old",debugf);
167 sys_rename(debugf,name);
175 /*******************************************************************
176 write an debug message on the debugfile. This is called by the DEBUG
178 ********************************************************************/
180 int Debug1(char *format_str, ...)
190 if (stdout_logging) {
192 va_start(ap, format_str);
195 format_str = va_arg(ap,char *);
197 vfprintf(dbf,format_str,ap);
203 if (!lp_syslog_only())
208 dbf = fopen(debugf,"w");
217 if (syslog_level < lp_syslog())
220 * map debug levels to syslog() priorities
221 * note that not all DEBUG(0, ...) calls are
224 static int priority_map[] = {
233 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
235 priority = LOG_DEBUG;
237 priority = priority_map[syslog_level];
240 va_start(ap, format_str);
243 format_str = va_arg(ap,char *);
245 vsprintf(msgbuf, format_str, ap);
249 syslog(priority, "%s", msgbuf);
254 if (!lp_syslog_only())
258 va_start(ap, format_str);
261 format_str = va_arg(ap,char *);
263 vfprintf(dbf,format_str,ap);
273 /****************************************************************************
274 determine if a file descriptor is in fact a socket
275 ****************************************************************************/
276 BOOL is_a_socket(int fd)
280 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
284 static char *last_ptr=NULL;
286 /****************************************************************************
287 Get the next token from a string, return False if none found
288 handles double-quotes.
289 Based on a routine by GJC@VILLAGE.COM.
290 Extensively modified by Andrew.Tridgell@anu.edu.au
291 ****************************************************************************/
292 BOOL next_token(char **ptr,char *buff,char *sep)
297 if (!ptr) ptr = &last_ptr;
298 if (!ptr) return(False);
302 /* default to simple separators */
303 if (!sep) sep = " \t\n\r";
305 /* find the first non sep char */
306 while(*s && strchr(sep,*s)) s++;
309 if (! *s) return(False);
311 /* copy over the token */
312 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
320 *ptr = (*s) ? s+1 : s;
327 /****************************************************************************
328 Convert list of tokens to array; dependent on above routine.
329 Uses last_ptr from above - bit of a hack.
330 ****************************************************************************/
331 char **toktocliplist(int *ctok, char *sep)
337 if (!sep) sep = " \t\n\r";
339 while(*s && strchr(sep,*s)) s++;
342 if (!*s) return(NULL);
346 while(*s && (!strchr(sep,*s))) s++;
347 while(*s && strchr(sep,*s)) *s++=0;
353 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
365 /*******************************************************************
366 safely copies memory, ensuring no overlap problems.
367 this is only used if the machine does not have it's own memmove().
368 this is not the fastest algorithm in town, but it will do for our
370 ********************************************************************/
371 void *MemMove(void *dest,void *src,int size)
375 if (dest==src || !size) return(dest);
377 d = (unsigned long)dest;
378 s = (unsigned long)src;
380 if ((d >= (s+size)) || (s >= (d+size))) {
382 memcpy(dest,src,size);
388 /* we can forward copy */
389 if (s-d >= sizeof(int) &&
390 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
391 /* do it all as words */
392 int *idest = (int *)dest;
393 int *isrc = (int *)src;
395 for (i=0;i<size;i++) idest[i] = isrc[i];
398 char *cdest = (char *)dest;
399 char *csrc = (char *)src;
400 for (i=0;i<size;i++) cdest[i] = csrc[i];
405 /* must backward copy */
406 if (d-s >= sizeof(int) &&
407 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
408 /* do it all as words */
409 int *idest = (int *)dest;
410 int *isrc = (int *)src;
412 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
415 char *cdest = (char *)dest;
416 char *csrc = (char *)src;
417 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
425 /****************************************************************************
426 prompte a dptr (to make it recently used)
427 ****************************************************************************/
428 void array_promote(char *array,int elsize,int element)
434 p = (char *)malloc(elsize);
438 DEBUG(5,("Ahh! Can't malloc\n"));
441 memcpy(p,array + element * elsize, elsize);
442 memmove(array + elsize,array,elsize*element);
443 memcpy(array,p,elsize);
447 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
456 } socket_options[] = {
457 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
458 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
459 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
461 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
463 #ifdef IPTOS_LOWDELAY
464 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
466 #ifdef IPTOS_THROUGHPUT
467 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
470 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
473 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
476 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
479 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
482 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
485 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
491 /****************************************************************************
492 set user socket options
493 ****************************************************************************/
494 void set_socket_options(int fd, char *options)
498 while (next_token(&options,tok," \t,"))
503 BOOL got_value = False;
505 if ((p = strchr(tok,'=')))
512 for (i=0;socket_options[i].name;i++)
513 if (strequal(socket_options[i].name,tok))
516 if (!socket_options[i].name)
518 DEBUG(0,("Unknown socket option %s\n",tok));
522 switch (socket_options[i].opttype)
526 ret = setsockopt(fd,socket_options[i].level,
527 socket_options[i].option,(char *)&value,sizeof(int));
532 DEBUG(0,("syntax error - %s does not take a value\n",tok));
535 int on = socket_options[i].value;
536 ret = setsockopt(fd,socket_options[i].level,
537 socket_options[i].option,(char *)&on,sizeof(int));
543 DEBUG(0,("Failed to set socket option %s\n",tok));
549 /****************************************************************************
550 close the socket communication
551 ****************************************************************************/
552 void close_sockets(void )
558 /****************************************************************************
559 determine whether we are in the specified group
560 ****************************************************************************/
561 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
565 if (group == current_gid) return(True);
567 for (i=0;i<ngroups;i++)
568 if (group == groups[i])
574 /****************************************************************************
575 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
576 ****************************************************************************/
577 char *StrCpy(char *dest,char *src)
582 /* I don't want to get lazy with these ... */
584 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
589 if (!dest) return(NULL);
594 while ((*d++ = *src++)) ;
598 /****************************************************************************
599 line strncpy but always null terminates. Make sure there is room!
600 ****************************************************************************/
601 char *StrnCpy(char *dest,const char *src,int n)
604 if (!dest) return(NULL);
609 while (n-- && (*d++ = *src++)) ;
615 /*******************************************************************
616 copy an IP address from one buffer to another
617 ********************************************************************/
618 void putip(void *dest,void *src)
624 /****************************************************************************
625 interpret the weird netbios "name". Return the name type
626 ****************************************************************************/
627 static int name_interpret(char *in,char *out)
630 int len = (*in++) / 2;
634 if (len > 30 || len<1) return(0);
638 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
642 *out = ((in[0]-'A')<<4) + (in[1]-'A');
650 /* Handle any scope names */
653 *out++ = '.'; /* Scope names are separated by periods */
654 len = *(unsigned char *)in++;
655 StrnCpy(out, in, len);
664 /****************************************************************************
665 mangle a name into netbios format
666 ****************************************************************************/
667 int name_mangle(char *In,char *Out,char name_type)
671 char *in = (char *)&buf[0];
672 char *out = (char *)Out;
677 StrnCpy(name,In,sizeof(name)-1);
678 sprintf(buf,"%-15.15s%c",name,name_type);
681 memset(&buf[1],0,16);
686 char c = toupper(in[i]);
687 out[i*2] = (c>>4) + 'A';
688 out[i*2+1] = (c & 0xF) + 'A';
696 p = strchr(label, '.');
698 p = label + strlen(label);
700 memcpy(out, label, p - label);
702 label += p - label + (*p == '.');
705 return(name_len(Out));
709 /*******************************************************************
710 check if a file exists
711 ********************************************************************/
712 BOOL file_exist(char *fname,struct stat *sbuf)
715 if (!sbuf) sbuf = &st;
717 if (sys_stat(fname,sbuf) != 0)
720 return(S_ISREG(sbuf->st_mode));
723 /*******************************************************************
724 check a files mod time
725 ********************************************************************/
726 time_t file_modtime(char *fname)
730 if (sys_stat(fname,&st) != 0)
736 /*******************************************************************
737 check if a directory exists
738 ********************************************************************/
739 BOOL directory_exist(char *dname,struct stat *st)
744 if (sys_stat(dname,st) != 0)
747 return(S_ISDIR(st->st_mode));
750 /*******************************************************************
751 returns the size in bytes of the named file
752 ********************************************************************/
753 uint32 file_size(char *file_name)
757 sys_stat(file_name,&buf);
761 /*******************************************************************
762 return a string representing an attribute for a file
763 ********************************************************************/
764 char *attrib_string(int mode)
766 static char attrstr[10];
770 if (mode & aVOLID) strcat(attrstr,"V");
771 if (mode & aDIR) strcat(attrstr,"D");
772 if (mode & aARCH) strcat(attrstr,"A");
773 if (mode & aHIDDEN) strcat(attrstr,"H");
774 if (mode & aSYSTEM) strcat(attrstr,"S");
775 if (mode & aRONLY) strcat(attrstr,"R");
781 /*******************************************************************
782 case insensitive string compararison
783 ********************************************************************/
784 int StrCaseCmp(char *s, char *t)
786 for (; tolower(*s) == tolower(*t); ++s, ++t)
789 return tolower(*s) - tolower(*t);
792 /*******************************************************************
793 case insensitive string compararison, length limited
794 ********************************************************************/
795 int StrnCaseCmp(char *s, char *t, int n)
797 while (n-- && *s && *t) {
798 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
801 if (n) return(tolower(*s) - tolower(*t));
806 /*******************************************************************
808 ********************************************************************/
809 BOOL strequal(char *s1,char *s2)
811 if (s1 == s2) return(True);
812 if (!s1 || !s2) return(False);
814 return(StrCaseCmp(s1,s2)==0);
817 /*******************************************************************
818 compare 2 strings up to and including the nth char.
819 ******************************************************************/
820 BOOL strnequal(char *s1,char *s2,int n)
822 if (s1 == s2) return(True);
823 if (!s1 || !s2 || !n) return(False);
825 return(StrnCaseCmp(s1,s2,n)==0);
828 /*******************************************************************
829 compare 2 strings (case sensitive)
830 ********************************************************************/
831 BOOL strcsequal(char *s1,char *s2)
833 if (s1 == s2) return(True);
834 if (!s1 || !s2) return(False);
836 return(strcmp(s1,s2)==0);
840 /*******************************************************************
841 convert a string to lower case
842 ********************************************************************/
843 void strlower(char *s)
848 if (is_shift_jis (*s)) {
850 } else if (is_kana (*s)) {
865 /*******************************************************************
866 convert a string to upper case
867 ********************************************************************/
868 void strupper(char *s)
873 if (is_shift_jis (*s)) {
875 } else if (is_kana (*s)) {
890 /*******************************************************************
891 convert a string to "normal" form
892 ********************************************************************/
893 void strnorm(char *s)
895 if (case_default == CASE_UPPER)
901 /*******************************************************************
902 check if a string is in "normal" case
903 ********************************************************************/
904 BOOL strisnormal(char *s)
906 if (case_default == CASE_UPPER)
907 return(!strhaslower(s));
909 return(!strhasupper(s));
913 /****************************************************************************
915 ****************************************************************************/
916 void string_replace(char *s,char oldc,char newc)
921 if (is_shift_jis (*s)) {
923 } else if (is_kana (*s)) {
938 /****************************************************************************
939 make a file into unix format
940 ****************************************************************************/
941 void unix_format(char *fname)
944 string_replace(fname,'\\','/');
946 dos2unix_format(fname, True);
951 strcpy(namecopy,fname);
953 strcat(fname,namecopy);
957 /****************************************************************************
958 make a file into dos format
959 ****************************************************************************/
960 void dos_format(char *fname)
963 unix2dos_format(fname, True);
965 string_replace(fname,'/','\\');
969 /*******************************************************************
970 show a smb message structure
971 ********************************************************************/
972 void show_msg(char *buf)
979 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
981 (int)CVAL(buf,smb_com),
982 (int)CVAL(buf,smb_rcls),
983 (int)CVAL(buf,smb_reh),
984 (int)SVAL(buf,smb_err),
985 (int)CVAL(buf,smb_flg),
986 (int)SVAL(buf,smb_flg2)));
987 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
988 (int)SVAL(buf,smb_tid),
989 (int)SVAL(buf,smb_pid),
990 (int)SVAL(buf,smb_uid),
991 (int)SVAL(buf,smb_mid),
992 (int)CVAL(buf,smb_wct)));
993 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
994 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
995 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
996 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
997 DEBUG(5,("smb_bcc=%d\n",bcc));
1000 for (i=0;i<MIN(bcc,128);i++)
1001 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1005 /*******************************************************************
1006 return the length of an smb packet
1007 ********************************************************************/
1008 int smb_len(char *buf)
1010 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1013 /*******************************************************************
1014 set the length of an smb packet
1015 ********************************************************************/
1016 void _smb_setlen(char *buf,int len)
1019 buf[1] = (len&0x10000)>>16;
1020 buf[2] = (len&0xFF00)>>8;
1024 /*******************************************************************
1025 set the length and marker of an smb packet
1026 ********************************************************************/
1027 void smb_setlen(char *buf,int len)
1029 _smb_setlen(buf,len);
1037 /*******************************************************************
1038 setup the word count and byte count for a smb message
1039 ********************************************************************/
1040 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1043 bzero(buf + smb_size,num_words*2 + num_bytes);
1044 CVAL(buf,smb_wct) = num_words;
1045 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1046 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1047 return (smb_size + num_words*2 + num_bytes);
1050 /*******************************************************************
1051 return the number of smb words
1052 ********************************************************************/
1053 int smb_numwords(char *buf)
1055 return (CVAL(buf,smb_wct));
1058 /*******************************************************************
1059 return the size of the smb_buf region of a message
1060 ********************************************************************/
1061 int smb_buflen(char *buf)
1063 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1066 /*******************************************************************
1067 return a pointer to the smb_buf data area
1068 ********************************************************************/
1069 int smb_buf_ofs(char *buf)
1071 return (smb_size + CVAL(buf,smb_wct)*2);
1074 /*******************************************************************
1075 return a pointer to the smb_buf data area
1076 ********************************************************************/
1077 char *smb_buf(char *buf)
1079 return (buf + smb_buf_ofs(buf));
1082 /*******************************************************************
1083 return the SMB offset into an SMB buffer
1084 ********************************************************************/
1085 int smb_offset(char *p,char *buf)
1087 return(PTR_DIFF(p,buf+4) + chain_size);
1091 /*******************************************************************
1092 skip past some strings in a buffer
1093 ********************************************************************/
1094 char *skip_string(char *buf,int n)
1097 buf += strlen(buf) + 1;
1101 /*******************************************************************
1102 trim the specified elements off the front and back of a string
1103 ********************************************************************/
1104 BOOL trim_string(char *s,char *front,char *back)
1107 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1113 if (!(*p = p[strlen(front)]))
1118 while (back && *back && strlen(s) >= strlen(back) &&
1119 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1122 s[strlen(s)-strlen(back)] = 0;
1128 /*******************************************************************
1129 reduce a file name, removing .. elements.
1130 ********************************************************************/
1131 void dos_clean_name(char *s)
1135 DEBUG(3,("dos_clean_name [%s]\n",s));
1137 /* remove any double slashes */
1138 string_sub(s, "\\\\", "\\");
1140 while ((p = strstr(s,"\\..\\")) != NULL)
1147 if ((p=strrchr(s,'\\')) != NULL)
1154 trim_string(s,NULL,"\\..");
1156 string_sub(s, "\\.\\", "\\");
1159 /*******************************************************************
1160 reduce a file name, removing .. elements.
1161 ********************************************************************/
1162 void unix_clean_name(char *s)
1166 DEBUG(3,("unix_clean_name [%s]\n",s));
1168 /* remove any double slashes */
1169 string_sub(s, "//","/");
1171 while ((p = strstr(s,"/../")) != NULL)
1178 if ((p=strrchr(s,'/')) != NULL)
1185 trim_string(s,NULL,"/..");
1189 /*******************************************************************
1190 a wrapper for the normal chdir() function
1191 ********************************************************************/
1192 int ChDir(char *path)
1195 static pstring LastDir="";
1197 if (strcsequal(path,".")) return(0);
1199 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1200 DEBUG(3,("chdir to %s\n",path));
1201 res = sys_chdir(path);
1203 strcpy(LastDir,path);
1208 /*******************************************************************
1209 return the absolute current directory path. A dumb version.
1210 ********************************************************************/
1211 static char *Dumb_GetWd(char *s)
1214 return ((char *)getcwd(s,sizeof(pstring)));
1216 return ((char *)getwd(s));
1221 /* number of list structures for a caching GetWd function. */
1222 #define MAX_GETWDCACHE (50)
1230 } ino_list[MAX_GETWDCACHE];
1232 BOOL use_getwd_cache=True;
1234 /*******************************************************************
1235 return the absolute current directory path
1236 ********************************************************************/
1237 char *GetWd(char *str)
1240 static BOOL getwd_cache_init = False;
1241 struct stat st, st2;
1246 if (!use_getwd_cache)
1247 return(Dumb_GetWd(str));
1249 /* init the cache */
1250 if (!getwd_cache_init)
1252 getwd_cache_init = True;
1253 for (i=0;i<MAX_GETWDCACHE;i++)
1255 string_init(&ino_list[i].text,"");
1256 ino_list[i].valid = False;
1260 /* Get the inode of the current directory, if this doesn't work we're
1263 if (stat(".",&st) == -1)
1265 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1266 return(Dumb_GetWd(str));
1270 for (i=0; i<MAX_GETWDCACHE; i++)
1271 if (ino_list[i].valid)
1274 /* If we have found an entry with a matching inode and dev number
1275 then find the inode number for the directory in the cached string.
1276 If this agrees with that returned by the stat for the current
1277 directory then all is o.k. (but make sure it is a directory all
1280 if (st.st_ino == ino_list[i].inode &&
1281 st.st_dev == ino_list[i].dev)
1283 if (stat(ino_list[i].text,&st2) == 0)
1285 if (st.st_ino == st2.st_ino &&
1286 st.st_dev == st2.st_dev &&
1287 (st2.st_mode & S_IFMT) == S_IFDIR)
1289 strcpy (str, ino_list[i].text);
1291 /* promote it for future use */
1292 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1297 /* If the inode is different then something's changed,
1298 scrub the entry and start from scratch. */
1299 ino_list[i].valid = False;
1306 /* We don't have the information to hand so rely on traditional methods.
1307 The very slow getcwd, which spawns a process on some systems, or the
1308 not quite so bad getwd. */
1312 DEBUG(0,("Getwd failed, errno %d\n",errno));
1318 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1320 /* add it to the cache */
1321 i = MAX_GETWDCACHE - 1;
1322 string_set(&ino_list[i].text,s);
1323 ino_list[i].dev = st.st_dev;
1324 ino_list[i].inode = st.st_ino;
1325 ino_list[i].valid = True;
1327 /* put it at the top of the list */
1328 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1335 /*******************************************************************
1336 reduce a file name, removing .. elements and checking that
1337 it is below dir in the heirachy. This uses GetWd() and so must be run
1338 on the system that has the referenced file system.
1340 widelinks are allowed if widelinks is true
1341 ********************************************************************/
1342 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1344 #ifndef REDUCE_PATHS
1352 BOOL relative = (*s != '/');
1354 *dir2 = *wd = *basename = *newname = 0;
1359 /* can't have a leading .. */
1360 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1362 DEBUG(3,("Illegal file name? (%s)\n",s));
1368 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1370 /* remove any double slashes */
1371 string_sub(s,"//","/");
1374 p = strrchr(basename,'/');
1381 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1385 if (ChDir(dir) != 0)
1387 DEBUG(0,("couldn't chdir to %s\n",dir));
1393 DEBUG(0,("couldn't getwd for %s\n",dir));
1399 if (p && (p != basename))
1402 if (strcmp(p+1,".")==0)
1404 if (strcmp(p+1,"..")==0)
1408 if (ChDir(basename) != 0)
1411 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1415 if (!GetWd(newname))
1418 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1422 if (p && (p != basename))
1424 strcat(newname,"/");
1425 strcat(newname,p+1);
1429 int l = strlen(dir2);
1430 if (dir2[l-1] == '/')
1433 if (strncmp(newname,dir2,l) != 0)
1436 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1442 if (newname[l] == '/')
1443 strcpy(s,newname + l + 1);
1445 strcpy(s,newname+l);
1456 DEBUG(3,("reduced to %s\n",s));
1461 /****************************************************************************
1463 ****************************************************************************/
1464 static void expand_one(char *Mask,int len)
1467 while ((p1 = strchr(Mask,'*')) != NULL)
1469 int lfill = (len+1) - strlen(Mask);
1470 int l1= (p1 - Mask);
1473 memset(tmp+l1,'?',lfill);
1474 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1479 /****************************************************************************
1480 expand a wildcard expression, replacing *s with ?s
1481 ****************************************************************************/
1482 void expand_mask(char *Mask,BOOL doext)
1487 BOOL hasdot = False;
1489 BOOL absolute = (*Mask == '\\');
1491 *mbeg = *mext = *dirpart = *filepart = 0;
1493 /* parse the directory and filename */
1494 if (strchr(Mask,'\\'))
1495 dirname_dos(Mask,dirpart);
1497 filename_dos(Mask,filepart);
1499 strcpy(mbeg,filepart);
1500 if ((p1 = strchr(mbeg,'.')) != NULL)
1510 if (strlen(mbeg) > 8)
1512 strcpy(mext,mbeg + 8);
1518 strcpy(mbeg,"????????");
1519 if ((*mext == 0) && doext && !hasdot)
1522 if (strequal(mbeg,"*") && *mext==0)
1530 strcpy(Mask,dirpart);
1531 if (*dirpart || absolute) strcat(Mask,"\\");
1536 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1540 /****************************************************************************
1541 does a string have any uppercase chars in it?
1542 ****************************************************************************/
1543 BOOL strhasupper(char *s)
1548 if (is_shift_jis (*s)) {
1550 } else if (is_kana (*s)) {
1553 if (isupper(*s)) return(True);
1557 if (isupper(*s)) return(True);
1564 /****************************************************************************
1565 does a string have any lowercase chars in it?
1566 ****************************************************************************/
1567 BOOL strhaslower(char *s)
1572 if (is_shift_jis (*s)) {
1574 } else if (is_kana (*s)) {
1577 if (islower(*s)) return(True);
1581 if (islower(*s)) return(True);
1588 /****************************************************************************
1589 find the number of chars in a string
1590 ****************************************************************************/
1591 int count_chars(char *s,char c)
1604 /****************************************************************************
1606 ****************************************************************************/
1607 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1614 if ((mode & aDIR) != 0)
1617 memset(buf+1,' ',11);
1618 if ((p = strchr(mask2,'.')) != NULL)
1621 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1622 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1626 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1628 bzero(buf+21,DIR_STRUCT_SIZE-21);
1629 CVAL(buf,21) = mode;
1630 put_dos_date(buf,22,date);
1631 SSVAL(buf,26,size & 0xFFFF);
1632 SSVAL(buf,28,size >> 16);
1633 StrnCpy(buf+30,fname,12);
1634 if (!case_sensitive)
1636 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1640 /*******************************************************************
1641 close the low 3 fd's and open dev/null in their place
1642 ********************************************************************/
1643 void close_low_fds(void)
1647 close(0); close(1); close(2);
1648 /* try and use up these file descriptors, so silly
1649 library routines writing to stdout etc won't cause havoc */
1651 fd = open("/dev/null",O_RDWR,0);
1652 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1654 DEBUG(0,("Can't open /dev/null\n"));
1658 DEBUG(0,("Didn't get file descriptor %d\n",i));
1664 /****************************************************************************
1665 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1667 if SYSV use O_NDELAY
1669 ****************************************************************************/
1670 int set_blocking(int fd, int set)
1674 #define FLAG_TO_SET O_NONBLOCK
1677 #define FLAG_TO_SET O_NDELAY
1679 #define FLAG_TO_SET FNDELAY
1683 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1685 if(set) /* Turn blocking on - ie. clear nonblock flag */
1686 val &= ~FLAG_TO_SET;
1689 return fcntl( fd, F_SETFL, val);
1694 /****************************************************************************
1696 ****************************************************************************/
1697 int write_socket(int fd,char *buf,int len)
1703 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1704 ret = write_data(fd,buf,len);
1706 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1710 /****************************************************************************
1712 ****************************************************************************/
1713 int read_udp_socket(int fd,char *buf,int len)
1716 struct sockaddr sock;
1719 socklen = sizeof(sock);
1720 bzero((char *)&sock,socklen);
1721 bzero((char *)&lastip,sizeof(lastip));
1722 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1724 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1728 lastip = *(struct in_addr *) &sock.sa_data[2];
1729 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1734 /****************************************************************************
1735 read data from a device with a timout in msec.
1736 mincount = if timeout, minimum to read before returning
1737 maxcount = number to be read.
1738 ****************************************************************************/
1739 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1745 struct timeval timeout;
1747 /* just checking .... */
1748 if (maxcnt <= 0) return(0);
1753 if (time_out <= 0) {
1754 if (mincnt == 0) mincnt = maxcnt;
1756 while (nread < mincnt) {
1757 readret = read(fd, buf + nread, maxcnt - nread);
1759 smb_read_error = READ_EOF;
1763 if (readret == -1) {
1764 smb_read_error = READ_ERROR;
1772 /* Most difficult - timeout read */
1773 /* If this is ever called on a disk file and
1774 mincnt is greater then the filesize then
1775 system performance will suffer severely as
1776 select always return true on disk files */
1778 /* Set initial timeout */
1779 timeout.tv_sec = time_out / 1000;
1780 timeout.tv_usec = 1000 * (time_out % 1000);
1782 for (nread=0; nread<mincnt; )
1787 selrtn = sys_select(&fds,&timeout);
1789 /* Check if error */
1791 /* something is wrong. Maybe the socket is dead? */
1792 smb_read_error = READ_ERROR;
1796 /* Did we timeout ? */
1798 smb_read_error = READ_TIMEOUT;
1802 readret = read(fd, buf+nread, maxcnt-nread);
1804 /* we got EOF on the file descriptor */
1805 smb_read_error = READ_EOF;
1809 if (readret == -1) {
1810 /* the descriptor is probably dead */
1811 smb_read_error = READ_ERROR;
1818 /* Return the number we got */
1822 /****************************************************************************
1823 read data from the client. Maxtime is in milliseconds
1824 ****************************************************************************/
1825 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1830 struct timeval timeout;
1835 timeout.tv_sec = maxtime / 1000;
1836 timeout.tv_usec = (maxtime % 1000) * 1000;
1838 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1840 if (!FD_ISSET(fd,&fds))
1843 nread = read_udp_socket(fd, buffer, bufsize);
1845 /* return the number got */
1849 /*******************************************************************
1850 find the difference in milliseconds between two struct timeval
1852 ********************************************************************/
1853 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1855 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1856 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1859 /****************************************************************************
1860 send a keepalive packet (rfc1002)
1861 ****************************************************************************/
1862 BOOL send_keepalive(int client)
1864 unsigned char buf[4];
1867 buf[1] = buf[2] = buf[3] = 0;
1869 return(write_data(client,(char *)buf,4) == 4);
1874 /****************************************************************************
1875 read data from the client, reading exactly N bytes.
1876 ****************************************************************************/
1877 int read_data(int fd,char *buffer,int N)
1886 ret = read(fd,buffer + total,N - total);
1888 smb_read_error = READ_EOF;
1892 smb_read_error = READ_ERROR;
1901 /****************************************************************************
1903 ****************************************************************************/
1904 int write_data(int fd,char *buffer,int N)
1911 ret = write(fd,buffer + total,N - total);
1913 if (ret == -1) return -1;
1914 if (ret == 0) return total;
1922 /****************************************************************************
1923 transfer some data between two fd's
1924 ****************************************************************************/
1925 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1927 static char *buf=NULL;
1932 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1935 size = lp_readsize();
1936 size = MAX(size,1024);
1939 while (!buf && size>0) {
1940 buf = (char *)Realloc(buf,size+8);
1941 if (!buf) size /= 2;
1945 DEBUG(0,("Can't allocate transfer buffer!\n"));
1949 abuf = buf + (align%8);
1956 int s = MIN(n,size);
1961 if (header && (headlen >= MIN(s,1024))) {
1971 if (header && headlen > 0)
1973 ret = MIN(headlen,size);
1974 memcpy(buf1,header,ret);
1977 if (headlen <= 0) header = NULL;
1981 ret += read(infd,buf1+ret,s-ret);
1985 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1986 if (ret2 > 0) total += ret2;
1987 /* if we can't write then dump excess data */
1989 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1991 if (ret <= 0 || ret2 != ret)
1999 /****************************************************************************
2000 read 4 bytes of a smb packet and return the smb length of the packet
2001 possibly store the result in the buffer
2002 ****************************************************************************/
2003 int read_smb_length(int fd,char *inbuf,int timeout)
2007 int len=0, msg_type;
2018 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2020 ok = (read_data(fd,buffer,4) == 4);
2025 len = smb_len(buffer);
2026 msg_type = CVAL(buffer,0);
2028 if (msg_type == 0x85)
2030 DEBUG(5,("Got keepalive packet\n"));
2035 DEBUG(10,("got smb length of %d\n",len));
2042 /****************************************************************************
2043 read an smb from a fd and return it's length
2044 The timeout is in milli seconds
2045 ****************************************************************************/
2046 BOOL receive_smb(int fd,char *buffer,int timeout)
2052 bzero(buffer,smb_size + 100);
2054 len = read_smb_length(fd,buffer,timeout);
2058 if (len > BUFFER_SIZE) {
2059 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2060 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2064 ret = read_data(fd,buffer+4,len);
2066 smb_read_error = READ_ERROR;
2074 /****************************************************************************
2076 ****************************************************************************/
2077 BOOL send_smb(int fd,char *buffer)
2081 len = smb_len(buffer) + 4;
2083 while (nwritten < len)
2085 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2088 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2100 /****************************************************************************
2101 find a pointer to a netbios name
2102 ****************************************************************************/
2103 char *name_ptr(char *buf,int ofs)
2105 unsigned char c = *(unsigned char *)(buf+ofs);
2107 if ((c & 0xC0) == 0xC0)
2111 memcpy(p,buf+ofs,2);
2114 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2121 /****************************************************************************
2122 extract a netbios name from a buf
2123 ****************************************************************************/
2124 int name_extract(char *buf,int ofs,char *name)
2126 char *p = name_ptr(buf,ofs);
2127 int d = PTR_DIFF(p,buf+ofs);
2129 if (d < -50 || d > 50) return(0);
2130 return(name_interpret(p,name));
2134 /****************************************************************************
2135 return the total storage length of a mangled name
2136 ****************************************************************************/
2137 int name_len(char *s)
2140 unsigned char c = *(unsigned char *)s;
2141 if ((c & 0xC0) == 0xC0)
2143 while (*s) s += (*s)+1;
2144 return(PTR_DIFF(s,s0)+1);
2147 /****************************************************************************
2148 send a single packet to a port on another machine
2149 ****************************************************************************/
2150 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2154 struct sockaddr_in sock_out;
2159 /* create a socket to write to */
2160 out_fd = socket(AF_INET, type, 0);
2163 DEBUG(0,("socket failed"));
2167 /* set the address and port */
2168 bzero((char *)&sock_out,sizeof(sock_out));
2169 putip((char *)&sock_out.sin_addr,(char *)&ip);
2170 sock_out.sin_port = htons( port );
2171 sock_out.sin_family = AF_INET;
2174 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2175 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2178 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2181 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2182 inet_ntoa(ip),port,errno));
2188 /*******************************************************************
2189 sleep for a specified number of milliseconds
2190 ********************************************************************/
2194 struct timeval tval,t1,t2;
2201 tval.tv_sec = (t-tdiff)/1000;
2202 tval.tv_usec = 1000*((t-tdiff)%1000);
2206 sys_select(&fds,&tval);
2209 tdiff = TvalDiff(&t1,&t2);
2213 /****************************************************************************
2214 check if a string is part of a list
2215 ****************************************************************************/
2216 BOOL in_list(char *s,char *list,BOOL casesensitive)
2221 if (!list) return(False);
2223 while (next_token(&p,tok,LIST_SEP))
2225 if (casesensitive) {
2226 if (strcmp(tok,s) == 0)
2229 if (StrCaseCmp(tok,s) == 0)
2236 /* this is used to prevent lots of mallocs of size 1 */
2237 static char *null_string = NULL;
2239 /****************************************************************************
2240 set a string value, allocing the space for the string
2241 ****************************************************************************/
2242 BOOL string_init(char **dest,char *src)
2253 null_string = (char *)malloc(1);
2256 *dest = null_string;
2260 *dest = (char *)malloc(l+1);
2266 /****************************************************************************
2268 ****************************************************************************/
2269 void string_free(char **s)
2271 if (!s || !(*s)) return;
2272 if (*s == null_string)
2278 /****************************************************************************
2279 set a string value, allocing the space for the string, and deallocating any
2281 ****************************************************************************/
2282 BOOL string_set(char **dest,char *src)
2286 return(string_init(dest,src));
2289 /****************************************************************************
2290 substitute a string for a pattern in another string. Make sure there is
2293 This routine looks for pattern in s and replaces it with
2294 insert. It may do multiple replacements.
2296 return True if a substitution was done.
2297 ****************************************************************************/
2298 BOOL string_sub(char *s,char *pattern,char *insert)
2304 if (!insert || !pattern || !s) return(False);
2307 lp = strlen(pattern);
2308 li = strlen(insert);
2310 if (!*pattern) return(False);
2312 while (lp <= ls && (p = strstr(s,pattern)))
2315 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2316 memcpy(p,insert,li);
2325 /*********************************************************
2326 * Recursive routine that is called by mask_match.
2327 * Does the actual matching.
2328 *********************************************************/
2329 BOOL do_match(char *str, char *regexp, int case_sig)
2333 for( p = regexp; *p && *str; ) {
2340 /* Look for a character matching
2341 the one after the '*' */
2344 return True; /* Automatic match */
2346 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2348 if(do_match(str,p,case_sig))
2362 if(toupper(*str) != toupper(*p))
2372 if (!*p && str[0] == '.' && str[1] == 0)
2375 if (!*str && *p == '?')
2377 while (*p == '?') p++;
2381 if(!*str && (*p == '*' && p[1] == '\0'))
2387 /*********************************************************
2388 * Routine to match a given string with a regexp - uses
2389 * simplified regexp that takes * and ? only. Case can be
2390 * significant or not.
2391 *********************************************************/
2392 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2396 fstring ebase,eext,sbase,sext;
2400 /* Make local copies of str and regexp */
2401 StrnCpy(p1,regexp,sizeof(pstring)-1);
2402 StrnCpy(p2,str,sizeof(pstring)-1);
2404 if (!strchr(p2,'.')) {
2409 if (!strchr(p1,'.')) {
2417 string_sub(p1,"*.*","*");
2418 string_sub(p1,".*","*");
2422 /* Remove any *? and ** as they are meaningless */
2423 for(p = p1; *p; p++)
2424 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2425 (void)strcpy( &p[1], &p[2]);
2427 if (strequal(p1,"*")) return(True);
2429 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2435 if ((p=strrchr(p1,'.'))) {
2444 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2454 matched = do_match(sbase,ebase,case_sig) &&
2455 (trans2 || do_match(sext,eext,case_sig));
2457 DEBUG(5,("mask_match returning %d\n", matched));
2464 /****************************************************************************
2465 become a daemon, discarding the controlling terminal
2466 ****************************************************************************/
2467 void become_daemon(void)
2469 #ifndef NO_FORK_DEBUG
2473 /* detach from the terminal */
2479 int i = open("/dev/tty", O_RDWR);
2482 ioctl(i, (int) TIOCNOTTY, (char *)0);
2492 /****************************************************************************
2493 put up a yes/no prompt
2494 ****************************************************************************/
2500 if (!fgets(ans,sizeof(ans)-1,stdin))
2503 if (*ans == 'y' || *ans == 'Y')
2509 /****************************************************************************
2510 read a line from a file with possible \ continuation chars.
2511 Blanks at the start or end of a line are stripped.
2512 The string will be allocated if s2 is NULL
2513 ****************************************************************************/
2514 char *fgets_slash(char *s2,int maxlen,FILE *f)
2519 BOOL start_of_line = True;
2526 maxlen = MIN(maxlen,8);
2527 s = (char *)Realloc(s,maxlen);
2530 if (!s || maxlen < 2) return(NULL);
2534 while (len < maxlen-1)
2542 while (len > 0 && s[len-1] == ' ')
2546 if (len > 0 && s[len-1] == '\\')
2549 start_of_line = True;
2554 if (len <= 0 && !s2)
2556 return(len>0?s:NULL);
2561 start_of_line = False;
2565 if (!s2 && len > maxlen-3)
2568 s = (char *)Realloc(s,maxlen);
2569 if (!s) return(NULL);
2577 /****************************************************************************
2578 set the length of a file from a filedescriptor.
2579 Returns 0 on success, -1 on failure.
2580 ****************************************************************************/
2581 int set_filelen(int fd, long len)
2583 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2584 extend a file with ftruncate. Provide alternate implementation
2587 #if FTRUNCATE_CAN_EXTEND
2588 return ftruncate(fd, len);
2592 long currpos = lseek(fd, 0L, SEEK_CUR);
2596 /* Do an fstat to see if the file is longer than
2597 the requested size (call ftruncate),
2598 or shorter, in which case seek to len - 1 and write 1
2600 if(fstat(fd, &st)<0)
2604 if (S_ISFIFO(st.st_mode)) return 0;
2607 if(st.st_size == len)
2609 if(st.st_size > len)
2610 return ftruncate(fd, len);
2612 if(lseek(fd, len-1, SEEK_SET) != len -1)
2614 if(write(fd, &c, 1)!=1)
2616 /* Seek to where we were */
2617 lseek(fd, currpos, SEEK_SET);
2623 /****************************************************************************
2624 return the byte checksum of some data
2625 ****************************************************************************/
2626 int byte_checksum(char *buf,int len)
2628 unsigned char *p = (unsigned char *)buf;
2638 /****************************************************************************
2639 this is a version of setbuffer() for those machines that only have setvbuf
2640 ****************************************************************************/
2641 void setbuffer(FILE *f,char *buf,int bufsize)
2643 setvbuf(f,buf,_IOFBF,bufsize);
2648 /****************************************************************************
2649 parse out a directory name from a path name. Assumes dos style filenames.
2650 ****************************************************************************/
2651 char *dirname_dos(char *path,char *buf)
2653 char *p = strrchr(path,'\\');
2668 /****************************************************************************
2669 parse out a filename from a path name. Assumes dos style filenames.
2670 ****************************************************************************/
2671 static char *filename_dos(char *path,char *buf)
2673 char *p = strrchr(path,'\\');
2685 /****************************************************************************
2686 expand a pointer to be a particular size
2687 ****************************************************************************/
2688 void *Realloc(void *p,int size)
2694 DEBUG(5,("Realloc asked for 0 bytes\n"));
2699 ret = (void *)malloc(size);
2701 ret = (void *)realloc(p,size);
2704 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2710 /****************************************************************************
2712 ****************************************************************************/
2713 char *strdup(char *s)
2716 if (!s) return(NULL);
2717 ret = (char *)malloc(strlen(s)+1);
2718 if (!ret) return(NULL);
2725 /****************************************************************************
2726 Signal handler for SIGPIPE (write on a disconnected socket)
2727 ****************************************************************************/
2730 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2734 /****************************************************************************
2735 get my own name and IP
2736 ****************************************************************************/
2737 BOOL get_myname(char *my_name,struct in_addr *ip)
2744 /* get my host name */
2745 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2747 DEBUG(0,("gethostname failed\n"));
2752 if ((hp = Get_Hostbyname(hostname)) == 0)
2754 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2760 /* split off any parts after an initial . */
2761 char *p = strchr(hostname,'.');
2764 strcpy(my_name,hostname);
2768 putip((char *)ip,(char *)hp->h_addr);
2774 /****************************************************************************
2775 true if two IP addresses are equal
2776 ****************************************************************************/
2777 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2780 a1 = ntohl(ip1.s_addr);
2781 a2 = ntohl(ip2.s_addr);
2786 /****************************************************************************
2787 open a socket of the specified type, port and address for incoming data
2788 ****************************************************************************/
2789 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2792 struct sockaddr_in sock;
2796 /* get my host name */
2797 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2798 { DEBUG(0,("gethostname failed\n")); return -1; }
2801 if ((hp = Get_Hostbyname(host_name)) == 0)
2803 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2807 bzero((char *)&sock,sizeof(sock));
2808 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2809 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2810 sock.sin_len = sizeof(sock);
2812 sock.sin_port = htons( port );
2813 sock.sin_family = hp->h_addrtype;
2814 sock.sin_addr.s_addr = socket_addr;
2815 res = socket(hp->h_addrtype, type, 0);
2817 { DEBUG(0,("socket failed\n")); return -1; }
2821 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2824 /* now we've got a socket - we need to bind it */
2825 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2828 if (port == SMB_PORT || port == NMB_PORT)
2829 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2830 port,socket_addr,strerror(errno)));
2833 if (dlevel > 0 && port < 1000)
2836 if (port >= 1000 && port < 9000)
2837 return(open_socket_in(type,port+1,dlevel,socket_addr));
2842 DEBUG(3,("bind succeeded on port %d\n",port));
2848 /****************************************************************************
2849 create an outgoing socket
2850 **************************************************************************/
2851 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2853 struct sockaddr_in sock_out;
2855 int connect_loop = 250; /* 250 milliseconds */
2856 int loops = (timeout * 1000) / connect_loop;
2858 /* create a socket to write to */
2859 res = socket(PF_INET, type, 0);
2861 { DEBUG(0,("socket error\n")); return -1; }
2863 if (type != SOCK_STREAM) return(res);
2865 bzero((char *)&sock_out,sizeof(sock_out));
2866 putip((char *)&sock_out.sin_addr,(char *)addr);
2868 sock_out.sin_port = htons( port );
2869 sock_out.sin_family = PF_INET;
2871 /* set it non-blocking */
2872 set_blocking(res,0);
2874 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2876 /* and connect it to the destination */
2878 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2880 if (ret < 0 && errno == EINPROGRESS && loops--) {
2881 msleep(connect_loop);
2885 if (ret < 0 && errno == EINPROGRESS) {
2886 DEBUG(2,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2892 if (ret < 0 && errno == EISCONN) {
2899 DEBUG(2,("error connecting to %s:%d (%s)\n",
2900 inet_ntoa(*addr),port,strerror(errno)));
2904 /* set it blocking again */
2905 set_blocking(res,1);
2911 /****************************************************************************
2912 interpret a protocol description string, with a default
2913 ****************************************************************************/
2914 int interpret_protocol(char *str,int def)
2916 if (strequal(str,"NT1"))
2917 return(PROTOCOL_NT1);
2918 if (strequal(str,"LANMAN2"))
2919 return(PROTOCOL_LANMAN2);
2920 if (strequal(str,"LANMAN1"))
2921 return(PROTOCOL_LANMAN1);
2922 if (strequal(str,"CORE"))
2923 return(PROTOCOL_CORE);
2924 if (strequal(str,"COREPLUS"))
2925 return(PROTOCOL_COREPLUS);
2926 if (strequal(str,"CORE+"))
2927 return(PROTOCOL_COREPLUS);
2929 DEBUG(0,("Unrecognised protocol level %s\n",str));
2934 /****************************************************************************
2935 interpret a security level
2936 ****************************************************************************/
2937 int interpret_security(char *str,int def)
2939 if (strequal(str,"SERVER"))
2941 if (strequal(str,"USER"))
2943 if (strequal(str,"SHARE"))
2946 DEBUG(0,("Unrecognised security level %s\n",str));
2952 /****************************************************************************
2953 interpret an internet address or name into an IP address in 4 byte form
2954 ****************************************************************************/
2955 uint32 interpret_addr(char *str)
2960 BOOL pure_address = True;
2962 if (strcmp(str,"0.0.0.0") == 0) return(0);
2963 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2965 for (i=0; pure_address && str[i]; i++)
2966 if (!(isdigit(str[i]) || str[i] == '.'))
2967 pure_address = False;
2969 /* if it's in the form of an IP address then get the lib to interpret it */
2971 res = inet_addr(str);
2973 /* otherwise assume it's a network name of some sort and use
2975 if ((hp = Get_Hostbyname(str)) == 0) {
2976 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2979 putip((char *)&res,(char *)hp->h_addr);
2982 if (res == (uint32)-1) return(0);
2987 /*******************************************************************
2988 a convenient addition to interpret_addr()
2989 ******************************************************************/
2990 struct in_addr *interpret_addr2(char *str)
2992 static struct in_addr ret;
2993 uint32 a = interpret_addr(str);
2998 /*******************************************************************
2999 check if an IP is the 0.0.0.0
3000 ******************************************************************/
3001 BOOL zero_ip(struct in_addr ip)
3004 putip((char *)&a,(char *)&ip);
3008 /*******************************************************************
3009 sub strings with useful parameters
3010 ********************************************************************/
3011 void standard_sub_basic(char *s)
3013 if (!strchr(s,'%')) return;
3015 string_sub(s,"%R",remote_proto);
3016 string_sub(s,"%a",remote_arch);
3017 string_sub(s,"%m",remote_machine);
3018 string_sub(s,"%L",local_machine);
3020 if (!strchr(s,'%')) return;
3022 string_sub(s,"%v",VERSION);
3023 string_sub(s,"%h",myhostname);
3024 string_sub(s,"%U",sesssetup_user);
3026 if (!strchr(s,'%')) return;
3028 string_sub(s,"%I",Client_info.addr);
3029 string_sub(s,"%M",Client_info.name);
3030 string_sub(s,"%T",timestring());
3032 if (!strchr(s,'%')) return;
3036 sprintf(pidstr,"%d",(int)getpid());
3037 string_sub(s,"%d",pidstr);
3040 if (!strchr(s,'%')) return;
3043 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3045 string_sub(s,"%G",gidtoname(pass->pw_gid));
3051 /*******************************************************************
3052 are two IPs on the same subnet?
3053 ********************************************************************/
3054 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3056 uint32 net1,net2,nmask;
3058 nmask = ntohl(mask.s_addr);
3059 net1 = ntohl(ip1.s_addr);
3060 net2 = ntohl(ip2.s_addr);
3062 return((net1 & nmask) == (net2 & nmask));
3066 /*******************************************************************
3067 write a string in unicoode format
3068 ********************************************************************/
3069 int PutUniCode(char *dst,char *src)
3073 dst[ret++] = src[0];
3082 /****************************************************************************
3083 a wrapper for gethostbyname() that tries with all lower and all upper case
3084 if the initial name fails
3085 ****************************************************************************/
3086 struct hostent *Get_Hostbyname(char *name)
3088 char *name2 = strdup(name);
3089 struct hostent *ret;
3093 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3097 if (!isalnum(*name2))
3103 ret = gethostbyname(name2);
3110 /* try with all lowercase */
3112 ret = gethostbyname(name2);
3119 /* try with all uppercase */
3121 ret = gethostbyname(name2);
3128 /* nothing works :-( */
3134 /****************************************************************************
3135 check if a process exists. Does this work on all unixes?
3136 ****************************************************************************/
3137 BOOL process_exists(int pid)
3141 sprintf(s,"/proc/%d",pid);
3142 return(directory_exist(s,NULL));
3145 static BOOL tested=False;
3146 static BOOL ok=False;
3150 sprintf(s,"/proc/%05d",getpid());
3151 ok = file_exist(s,NULL);
3154 sprintf(s,"/proc/%05d",pid);
3155 return(file_exist(s,NULL));
3159 /* CGH 8/16/96 - added ESRCH test */
3160 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3165 /*******************************************************************
3166 turn a uid into a user name
3167 ********************************************************************/
3168 char *uidtoname(int uid)
3170 static char name[40];
3171 struct passwd *pass = getpwuid(uid);
3172 if (pass) return(pass->pw_name);
3173 sprintf(name,"%d",uid);
3177 /*******************************************************************
3178 turn a gid into a group name
3179 ********************************************************************/
3180 char *gidtoname(int gid)
3182 static char name[40];
3183 struct group *grp = getgrgid(gid);
3184 if (grp) return(grp->gr_name);
3185 sprintf(name,"%d",gid);
3189 /*******************************************************************
3191 ********************************************************************/
3192 void BlockSignals(BOOL block,int signum)
3195 int block_mask = sigmask(signum);
3196 static int oldmask = 0;
3198 oldmask = sigblock(block_mask);
3200 sigsetmask(oldmask);
3201 #elif defined(USE_SIGPROCMASK)
3204 sigaddset(&set,signum);
3205 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3210 /*******************************************************************
3211 my own panic function - not suitable for general use
3212 ********************************************************************/
3213 void ajt_panic(void)
3215 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3220 #define DIRECT direct
3222 #define DIRECT dirent
3225 /*******************************************************************
3226 a readdir wrapper which just returns the file name
3227 also return the inode number if requested
3228 ********************************************************************/
3229 char *readdirname(void *p)
3234 if (!p) return(NULL);
3236 ptr = (struct DIRECT *)readdir(p);
3237 if (!ptr) return(NULL);
3239 dname = ptr->d_name;
3245 unix_to_dos(buf, True);
3251 if (telldir(p) < 0) return(NULL);
3255 /* this handles a broken compiler setup, causing a mixture
3256 of BSD and SYSV headers and libraries */
3258 static BOOL broken_readdir = False;
3259 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3261 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3262 broken_readdir = True;