2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1995
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 int Protocol = PROTOCOL_COREPLUS;
32 /* a default finfo structure to ensure all fields are sensible */
33 file_info def_finfo = {-1,0,0,0,0,0,0,""};
35 /* these are some file handles where debug info will be stored */
38 /* the client file descriptor */
41 /* info on the client */
42 struct from_host Client_info=
43 {"UNKNOWN","0.0.0.0",NULL};
45 /* the last IP received from */
46 struct in_addr lastip;
48 /* the last port received from */
54 case handling on filenames
56 int case_default = CASE_LOWER;
58 pstring debugf = "/tmp/log.samba";
61 /* the following control case operations - they are put here so the
62 client can link easily */
65 BOOL use_mangled_map = False;
66 BOOL short_case_preserve;
69 fstring remote_machine="";
70 fstring local_machine="";
71 fstring remote_arch="UNKNOWN";
72 fstring remote_proto="UNKNOWN";
73 pstring myhostname="";
74 pstring user_socket_options="";
75 pstring sesssetup_user="";
78 int smb_read_error = 0;
80 static char *filename_dos(char *path,char *buf);
82 static BOOL stdout_logging = False;
85 /*******************************************************************
86 get ready for syslog stuff
87 ******************************************************************/
88 void setup_logging(char *pname,BOOL interactive)
92 char *p = strrchr(pname,'/');
94 openlog(pname, LOG_PID, LOG_DAEMON);
98 stdout_logging = True;
104 BOOL append_log=False;
107 /****************************************************************************
109 ****************************************************************************/
110 void reopen_logs(void)
117 strcpy(fname,debugf);
118 if (lp_loaded() && (*lp_logfile()))
119 strcpy(fname,lp_logfile());
121 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
123 strcpy(debugf,fname);
124 if (dbf) fclose(dbf);
126 dbf = fopen(debugf,"a");
128 dbf = fopen(debugf,"w");
129 if (dbf) setbuf(dbf,NULL);
143 /*******************************************************************
144 check if the log has grown too big
145 ********************************************************************/
146 static void check_log_size(void)
148 static int debug_count=0;
152 if (debug_count++ < 100) return;
154 maxlog = lp_max_log_size() * 1024;
155 if (!dbf || maxlog <= 0) return;
157 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
158 fclose(dbf); dbf = NULL;
160 if (dbf && file_size(debugf) > maxlog) {
162 fclose(dbf); dbf = NULL;
163 sprintf(name,"%s.old",debugf);
164 sys_rename(debugf,name);
172 /*******************************************************************
173 write an debug message on the debugfile. This is called by the DEBUG
175 ********************************************************************/
177 int Debug1(char *format_str, ...)
187 if (stdout_logging) {
189 va_start(ap, format_str);
192 format_str = va_arg(ap,char *);
194 vfprintf(dbf,format_str,ap);
200 if (!lp_syslog_only())
205 dbf = fopen(debugf,"w");
214 if (syslog_level < lp_syslog())
217 * map debug levels to syslog() priorities
218 * note that not all DEBUG(0, ...) calls are
221 static int priority_map[] = {
230 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
232 priority = LOG_DEBUG;
234 priority = priority_map[syslog_level];
237 va_start(ap, format_str);
240 format_str = va_arg(ap,char *);
242 vsprintf(msgbuf, format_str, ap);
246 syslog(priority, "%s", msgbuf);
251 if (!lp_syslog_only())
255 va_start(ap, format_str);
258 format_str = va_arg(ap,char *);
260 vfprintf(dbf,format_str,ap);
270 /****************************************************************************
271 determine if a file descriptor is in fact a socket
272 ****************************************************************************/
273 BOOL is_a_socket(int fd)
277 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
281 static char *last_ptr=NULL;
283 /****************************************************************************
284 Get the next token from a string, return False if none found
285 handles double-quotes.
286 Based on a routine by GJC@VILLAGE.COM.
287 Extensively modified by Andrew.Tridgell@anu.edu.au
288 ****************************************************************************/
289 BOOL next_token(char **ptr,char *buff,char *sep)
294 if (!ptr) ptr = &last_ptr;
295 if (!ptr) return(False);
299 /* default to simple separators */
300 if (!sep) sep = " \t\n\r";
302 /* find the first non sep char */
303 while(*s && strchr(sep,*s)) s++;
306 if (! *s) return(False);
308 /* copy over the token */
309 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
317 *ptr = (*s) ? s+1 : s;
324 /****************************************************************************
325 Convert list of tokens to array; dependent on above routine.
326 Uses last_ptr from above - bit of a hack.
327 ****************************************************************************/
328 char **toktocliplist(int *ctok, char *sep)
334 if (!sep) sep = " \t\n\r";
336 while(*s && strchr(sep,*s)) s++;
339 if (!*s) return(NULL);
343 while(*s && (!strchr(sep,*s))) s++;
344 while(*s && strchr(sep,*s)) *s++=0;
350 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
362 /*******************************************************************
363 safely copies memory, ensuring no overlap problems.
364 this is only used if the machine does not have it's own memmove().
365 this is not the fastest algorithm in town, but it will do for our
367 ********************************************************************/
368 void *MemMove(void *dest,void *src,int size)
372 if (dest==src || !size) return(dest);
374 d = (unsigned long)dest;
375 s = (unsigned long)src;
377 if ((d >= (s+size)) || (s >= (d+size))) {
379 memcpy(dest,src,size);
385 /* we can forward copy */
386 if (s-d >= sizeof(int) &&
387 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
388 /* do it all as words */
389 int *idest = (int *)dest;
390 int *isrc = (int *)src;
392 for (i=0;i<size;i++) idest[i] = isrc[i];
395 char *cdest = (char *)dest;
396 char *csrc = (char *)src;
397 for (i=0;i<size;i++) cdest[i] = csrc[i];
402 /* must backward copy */
403 if (d-s >= sizeof(int) &&
404 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
405 /* do it all as words */
406 int *idest = (int *)dest;
407 int *isrc = (int *)src;
409 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
412 char *cdest = (char *)dest;
413 char *csrc = (char *)src;
414 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
422 /****************************************************************************
423 prompte a dptr (to make it recently used)
424 ****************************************************************************/
425 void array_promote(char *array,int elsize,int element)
431 p = (char *)malloc(elsize);
435 DEBUG(5,("Ahh! Can't malloc\n"));
438 memcpy(p,array + element * elsize, elsize);
439 memmove(array + elsize,array,elsize*element);
440 memcpy(array,p,elsize);
444 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
453 } socket_options[] = {
454 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
455 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
456 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
458 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
460 #ifdef IPTOS_LOWDELAY
461 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
463 #ifdef IPTOS_THROUGHPUT
464 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
467 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
470 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
473 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
476 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
482 /****************************************************************************
483 set user socket options
484 ****************************************************************************/
485 void set_socket_options(int fd, char *options)
489 while (next_token(&options,tok," \t,"))
494 BOOL got_value = False;
496 if ((p = strchr(tok,'=')))
503 for (i=0;socket_options[i].name;i++)
504 if (strequal(socket_options[i].name,tok))
507 if (!socket_options[i].name)
509 DEBUG(0,("Unknown socket option %s\n",tok));
513 switch (socket_options[i].opttype)
517 ret = setsockopt(fd,socket_options[i].level,
518 socket_options[i].option,(char *)&value,sizeof(int));
523 DEBUG(0,("syntax error - %s does not take a value\n",tok));
526 int on = socket_options[i].value;
527 ret = setsockopt(fd,socket_options[i].level,
528 socket_options[i].option,(char *)&on,sizeof(int));
534 DEBUG(0,("Failed to set socket option %s\n",tok));
540 /****************************************************************************
541 close the socket communication
542 ****************************************************************************/
543 void close_sockets(void )
549 /****************************************************************************
550 determine whether we are in the specified group
551 ****************************************************************************/
552 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
556 if (group == current_gid) return(True);
558 for (i=0;i<ngroups;i++)
559 if (group == groups[i])
565 /****************************************************************************
566 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
567 ****************************************************************************/
568 char *StrCpy(char *dest,char *src)
573 /* I don't want to get lazy with these ... */
575 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
580 if (!dest) return(NULL);
585 while ((*d++ = *src++)) ;
589 /****************************************************************************
590 line strncpy but always null terminates. Make sure there is room!
591 ****************************************************************************/
592 char *StrnCpy(char *dest,const char *src,int n)
595 if (!dest) return(NULL);
600 while (n-- && (*d++ = *src++)) ;
606 /*******************************************************************
607 copy an IP address from one buffer to another
608 ********************************************************************/
609 void putip(void *dest,void *src)
615 /****************************************************************************
616 interpret the weird netbios "name". Return the name type
617 ****************************************************************************/
618 static int name_interpret(char *in,char *out)
621 int len = (*in++) / 2;
625 if (len > 30 || len<1) return(0);
629 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
633 *out = ((in[0]-'A')<<4) + (in[1]-'A');
641 /* Handle any scope names */
644 *out++ = '.'; /* Scope names are separated by periods */
645 len = *(unsigned char *)in++;
646 StrnCpy(out, in, len);
655 /****************************************************************************
656 mangle a name into netbios format
657 ****************************************************************************/
658 int name_mangle(char *In,char *Out,char name_type)
662 char *in = (char *)&buf[0];
663 char *out = (char *)Out;
668 StrnCpy(name,In,sizeof(name)-1);
669 sprintf(buf,"%-15.15s%c",name,name_type);
672 memset(&buf[1],0,16);
677 char c = toupper(in[i]);
678 out[i*2] = (c>>4) + 'A';
679 out[i*2+1] = (c & 0xF) + 'A';
687 p = strchr(label, '.');
689 p = label + strlen(label);
691 memcpy(out, label, p - label);
693 label += p - label + (*p == '.');
696 return(name_len(Out));
700 /*******************************************************************
701 check if a file exists
702 ********************************************************************/
703 BOOL file_exist(char *fname,struct stat *sbuf)
706 if (!sbuf) sbuf = &st;
708 if (sys_stat(fname,sbuf) != 0)
711 return(S_ISREG(sbuf->st_mode));
714 /*******************************************************************
715 check a files mod time
716 ********************************************************************/
717 time_t file_modtime(char *fname)
721 if (sys_stat(fname,&st) != 0)
727 /*******************************************************************
728 check if a directory exists
729 ********************************************************************/
730 BOOL directory_exist(char *dname,struct stat *st)
735 if (sys_stat(dname,st) != 0)
738 return(S_ISDIR(st->st_mode));
741 /*******************************************************************
742 returns the size in bytes of the named file
743 ********************************************************************/
744 uint32 file_size(char *file_name)
748 sys_stat(file_name,&buf);
752 /*******************************************************************
753 return a string representing an attribute for a file
754 ********************************************************************/
755 char *attrib_string(int mode)
757 static char attrstr[10];
761 if (mode & aVOLID) strcat(attrstr,"V");
762 if (mode & aDIR) strcat(attrstr,"D");
763 if (mode & aARCH) strcat(attrstr,"A");
764 if (mode & aHIDDEN) strcat(attrstr,"H");
765 if (mode & aSYSTEM) strcat(attrstr,"S");
766 if (mode & aRONLY) strcat(attrstr,"R");
772 /*******************************************************************
773 case insensitive string compararison
774 ********************************************************************/
775 int StrCaseCmp(char *s, char *t)
777 for (; tolower(*s) == tolower(*t); ++s, ++t)
780 return tolower(*s) - tolower(*t);
783 /*******************************************************************
784 case insensitive string compararison, length limited
785 ********************************************************************/
786 int StrnCaseCmp(char *s, char *t, int n)
788 while (n-- && *s && *t) {
789 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
792 if (n) return(tolower(*s) - tolower(*t));
797 /*******************************************************************
799 ********************************************************************/
800 BOOL strequal(char *s1,char *s2)
802 if (s1 == s2) return(True);
803 if (!s1 || !s2) return(False);
805 return(StrCaseCmp(s1,s2)==0);
808 /*******************************************************************
809 compare 2 strings up to and including the nth char.
810 ******************************************************************/
811 BOOL strnequal(char *s1,char *s2,int n)
813 if (s1 == s2) return(True);
814 if (!s1 || !s2 || !n) return(False);
816 return(StrnCaseCmp(s1,s2,n)==0);
819 /*******************************************************************
820 compare 2 strings (case sensitive)
821 ********************************************************************/
822 BOOL strcsequal(char *s1,char *s2)
824 if (s1 == s2) return(True);
825 if (!s1 || !s2) return(False);
827 return(strcmp(s1,s2)==0);
831 /*******************************************************************
832 convert a string to lower case
833 ********************************************************************/
834 void strlower(char *s)
839 if (is_shift_jis (*s)) {
841 } else if (is_kana (*s)) {
856 /*******************************************************************
857 convert a string to upper case
858 ********************************************************************/
859 void strupper(char *s)
864 if (is_shift_jis (*s)) {
866 } else if (is_kana (*s)) {
881 /*******************************************************************
882 convert a string to "normal" form
883 ********************************************************************/
884 void strnorm(char *s)
886 if (case_default == CASE_UPPER)
892 /*******************************************************************
893 check if a string is in "normal" case
894 ********************************************************************/
895 BOOL strisnormal(char *s)
897 if (case_default == CASE_UPPER)
898 return(!strhaslower(s));
900 return(!strhasupper(s));
904 /****************************************************************************
906 ****************************************************************************/
907 void string_replace(char *s,char oldc,char newc)
912 if (is_shift_jis (*s)) {
914 } else if (is_kana (*s)) {
929 /****************************************************************************
930 make a file into unix format
931 ****************************************************************************/
932 void unix_format(char *fname)
935 string_replace(fname,'\\','/');
937 dos2unix_format(fname, True);
942 strcpy(namecopy,fname);
944 strcat(fname,namecopy);
948 /****************************************************************************
949 make a file into dos format
950 ****************************************************************************/
951 void dos_format(char *fname)
954 unix2dos_format(fname, True);
956 string_replace(fname,'/','\\');
960 /*******************************************************************
961 show a smb message structure
962 ********************************************************************/
963 void show_msg(char *buf)
970 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
972 (int)CVAL(buf,smb_com),
973 (int)CVAL(buf,smb_rcls),
974 (int)CVAL(buf,smb_reh),
975 (int)SVAL(buf,smb_err),
976 (int)CVAL(buf,smb_flg),
977 (int)SVAL(buf,smb_flg2)));
978 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
979 (int)SVAL(buf,smb_tid),
980 (int)SVAL(buf,smb_pid),
981 (int)SVAL(buf,smb_uid),
982 (int)SVAL(buf,smb_mid),
983 (int)CVAL(buf,smb_wct)));
984 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
985 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
986 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
987 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
988 DEBUG(5,("smb_bcc=%d\n",bcc));
991 for (i=0;i<MIN(bcc,128);i++)
992 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
996 /*******************************************************************
997 return the length of an smb packet
998 ********************************************************************/
999 int smb_len(char *buf)
1001 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1004 /*******************************************************************
1005 set the length of an smb packet
1006 ********************************************************************/
1007 void _smb_setlen(char *buf,int len)
1010 buf[1] = (len&0x10000)>>16;
1011 buf[2] = (len&0xFF00)>>8;
1015 /*******************************************************************
1016 set the length and marker of an smb packet
1017 ********************************************************************/
1018 void smb_setlen(char *buf,int len)
1020 _smb_setlen(buf,len);
1028 /*******************************************************************
1029 setup the word count and byte count for a smb message
1030 ********************************************************************/
1031 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1034 bzero(buf + smb_size,num_words*2 + num_bytes);
1035 CVAL(buf,smb_wct) = num_words;
1036 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1037 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1038 return (smb_size + num_words*2 + num_bytes);
1041 /*******************************************************************
1042 return the number of smb words
1043 ********************************************************************/
1044 int smb_numwords(char *buf)
1046 return (CVAL(buf,smb_wct));
1049 /*******************************************************************
1050 return the size of the smb_buf region of a message
1051 ********************************************************************/
1052 int smb_buflen(char *buf)
1054 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1057 /*******************************************************************
1058 return a pointer to the smb_buf data area
1059 ********************************************************************/
1060 int smb_buf_ofs(char *buf)
1062 return (smb_size + CVAL(buf,smb_wct)*2);
1065 /*******************************************************************
1066 return a pointer to the smb_buf data area
1067 ********************************************************************/
1068 char *smb_buf(char *buf)
1070 return (buf + smb_buf_ofs(buf));
1073 /*******************************************************************
1074 return the SMB offset into an SMB buffer
1075 ********************************************************************/
1076 int smb_offset(char *p,char *buf)
1078 return(PTR_DIFF(p,buf+4));
1082 /*******************************************************************
1083 skip past some strings in a buffer
1084 ********************************************************************/
1085 char *skip_string(char *buf,int n)
1088 buf += strlen(buf) + 1;
1092 /*******************************************************************
1093 trim the specified elements off the front and back of a string
1094 ********************************************************************/
1095 BOOL trim_string(char *s,char *front,char *back)
1098 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1104 if (!(*p = p[strlen(front)]))
1109 while (back && *back && strlen(s) >= strlen(back) &&
1110 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1113 s[strlen(s)-strlen(back)] = 0;
1119 /*******************************************************************
1120 reduce a file name, removing .. elements.
1121 ********************************************************************/
1122 void dos_clean_name(char *s)
1126 DEBUG(3,("dos_clean_name [%s]\n",s));
1128 /* remove any double slashes */
1129 string_sub(s, "\\\\", "\\");
1131 while ((p = strstr(s,"\\..\\")) != NULL)
1138 if ((p=strrchr(s,'\\')) != NULL)
1145 trim_string(s,NULL,"\\..");
1147 string_sub(s, "\\.\\", "\\");
1150 /*******************************************************************
1151 reduce a file name, removing .. elements.
1152 ********************************************************************/
1153 void unix_clean_name(char *s)
1157 DEBUG(3,("unix_clean_name [%s]\n",s));
1159 /* remove any double slashes */
1160 string_sub(s, "//","/");
1162 while ((p = strstr(s,"/../")) != NULL)
1169 if ((p=strrchr(s,'/')) != NULL)
1176 trim_string(s,NULL,"/..");
1180 /*******************************************************************
1181 a wrapper for the normal chdir() function
1182 ********************************************************************/
1183 int ChDir(char *path)
1186 static pstring LastDir="";
1188 if (strcsequal(path,".")) return(0);
1190 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1191 DEBUG(3,("chdir to %s\n",path));
1192 res = sys_chdir(path);
1194 strcpy(LastDir,path);
1199 /*******************************************************************
1200 return the absolute current directory path. A dumb version.
1201 ********************************************************************/
1202 static char *Dumb_GetWd(char *s)
1205 return ((char *)getcwd(s,sizeof(pstring)));
1207 return ((char *)getwd(s));
1212 /* number of list structures for a caching GetWd function. */
1213 #define MAX_GETWDCACHE (50)
1221 } ino_list[MAX_GETWDCACHE];
1223 BOOL use_getwd_cache=True;
1225 /*******************************************************************
1226 return the absolute current directory path
1227 ********************************************************************/
1228 char *GetWd(char *str)
1231 static BOOL getwd_cache_init = False;
1232 struct stat st, st2;
1237 if (!use_getwd_cache)
1238 return(Dumb_GetWd(str));
1240 /* init the cache */
1241 if (!getwd_cache_init)
1243 getwd_cache_init = True;
1244 for (i=0;i<MAX_GETWDCACHE;i++)
1246 string_init(&ino_list[i].text,"");
1247 ino_list[i].valid = False;
1251 /* Get the inode of the current directory, if this doesn't work we're
1254 if (stat(".",&st) == -1)
1256 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1257 return(Dumb_GetWd(str));
1261 for (i=0; i<MAX_GETWDCACHE; i++)
1262 if (ino_list[i].valid)
1265 /* If we have found an entry with a matching inode and dev number
1266 then find the inode number for the directory in the cached string.
1267 If this agrees with that returned by the stat for the current
1268 directory then all is o.k. (but make sure it is a directory all
1271 if (st.st_ino == ino_list[i].inode &&
1272 st.st_dev == ino_list[i].dev)
1274 if (stat(ino_list[i].text,&st2) == 0)
1276 if (st.st_ino == st2.st_ino &&
1277 st.st_dev == st2.st_dev &&
1278 (st2.st_mode & S_IFMT) == S_IFDIR)
1280 strcpy (str, ino_list[i].text);
1282 /* promote it for future use */
1283 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1288 /* If the inode is different then something's changed,
1289 scrub the entry and start from scratch. */
1290 ino_list[i].valid = False;
1297 /* We don't have the information to hand so rely on traditional methods.
1298 The very slow getcwd, which spawns a process on some systems, or the
1299 not quite so bad getwd. */
1303 DEBUG(0,("Getwd failed, errno %d\n",errno));
1309 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1311 /* add it to the cache */
1312 i = MAX_GETWDCACHE - 1;
1313 string_set(&ino_list[i].text,s);
1314 ino_list[i].dev = st.st_dev;
1315 ino_list[i].inode = st.st_ino;
1316 ino_list[i].valid = True;
1318 /* put it at the top of the list */
1319 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1326 /*******************************************************************
1327 reduce a file name, removing .. elements and checking that
1328 it is below dir in the heirachy. This uses GetWd() and so must be run
1329 on the system that has the referenced file system.
1331 widelinks are allowed if widelinks is true
1332 ********************************************************************/
1333 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1335 #ifndef REDUCE_PATHS
1343 BOOL relative = (*s != '/');
1345 *dir2 = *wd = *basename = *newname = 0;
1350 /* can't have a leading .. */
1351 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1353 DEBUG(3,("Illegal file name? (%s)\n",s));
1359 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1361 /* remove any double slashes */
1362 string_sub(s,"//","/");
1365 p = strrchr(basename,'/');
1372 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1376 if (ChDir(dir) != 0)
1378 DEBUG(0,("couldn't chdir to %s\n",dir));
1384 DEBUG(0,("couldn't getwd for %s\n",dir));
1390 if (p && (p != basename))
1393 if (strcmp(p+1,".")==0)
1395 if (strcmp(p+1,"..")==0)
1399 if (ChDir(basename) != 0)
1402 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1406 if (!GetWd(newname))
1409 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1413 if (p && (p != basename))
1415 strcat(newname,"/");
1416 strcat(newname,p+1);
1420 int l = strlen(dir2);
1421 if (dir2[l-1] == '/')
1424 if (strncmp(newname,dir2,l) != 0)
1427 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1433 if (newname[l] == '/')
1434 strcpy(s,newname + l + 1);
1436 strcpy(s,newname+l);
1447 DEBUG(3,("reduced to %s\n",s));
1452 /****************************************************************************
1454 ****************************************************************************/
1455 static void expand_one(char *Mask,int len)
1458 while ((p1 = strchr(Mask,'*')) != NULL)
1460 int lfill = (len+1) - strlen(Mask);
1461 int l1= (p1 - Mask);
1464 memset(tmp+l1,'?',lfill);
1465 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1470 /****************************************************************************
1471 expand a wildcard expression, replacing *s with ?s
1472 ****************************************************************************/
1473 void expand_mask(char *Mask,BOOL doext)
1478 BOOL hasdot = False;
1480 BOOL absolute = (*Mask == '\\');
1482 *mbeg = *mext = *dirpart = *filepart = 0;
1484 /* parse the directory and filename */
1485 if (strchr(Mask,'\\'))
1486 dirname_dos(Mask,dirpart);
1488 filename_dos(Mask,filepart);
1490 strcpy(mbeg,filepart);
1491 if ((p1 = strchr(mbeg,'.')) != NULL)
1501 if (strlen(mbeg) > 8)
1503 strcpy(mext,mbeg + 8);
1509 strcpy(mbeg,"????????");
1510 if ((*mext == 0) && doext && !hasdot)
1513 if (strequal(mbeg,"*") && *mext==0)
1521 strcpy(Mask,dirpart);
1522 if (*dirpart || absolute) strcat(Mask,"\\");
1527 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1531 /****************************************************************************
1532 does a string have any uppercase chars in it?
1533 ****************************************************************************/
1534 BOOL strhasupper(char *s)
1539 if (is_shift_jis (*s)) {
1541 } else if (is_kana (*s)) {
1544 if (isupper(*s)) return(True);
1548 if (isupper(*s)) return(True);
1555 /****************************************************************************
1556 does a string have any lowercase chars in it?
1557 ****************************************************************************/
1558 BOOL strhaslower(char *s)
1563 if (is_shift_jis (*s)) {
1565 } else if (is_kana (*s)) {
1568 if (islower(*s)) return(True);
1572 if (islower(*s)) return(True);
1579 /****************************************************************************
1580 find the number of chars in a string
1581 ****************************************************************************/
1582 int count_chars(char *s,char c)
1595 /****************************************************************************
1597 ****************************************************************************/
1598 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1605 if ((mode & aDIR) != 0)
1608 memset(buf+1,' ',11);
1609 if ((p = strchr(mask2,'.')) != NULL)
1612 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1613 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1617 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1619 bzero(buf+21,DIR_STRUCT_SIZE-21);
1620 CVAL(buf,21) = mode;
1621 put_dos_date(buf,22,date);
1622 SSVAL(buf,26,size & 0xFFFF);
1623 SSVAL(buf,28,size >> 16);
1624 StrnCpy(buf+30,fname,12);
1625 if (!case_sensitive)
1627 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1631 /*******************************************************************
1632 close the low 3 fd's and open dev/null in their place
1633 ********************************************************************/
1634 void close_low_fds(void)
1638 close(0); close(1); close(2);
1639 /* try and use up these file descriptors, so silly
1640 library routines writing to stdout etc won't cause havoc */
1642 fd = open("/dev/null",O_RDWR,0);
1643 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1645 DEBUG(0,("Can't open /dev/null\n"));
1649 DEBUG(0,("Didn't get file descriptor %d\n",i));
1656 /****************************************************************************
1658 ****************************************************************************/
1659 int write_socket(int fd,char *buf,int len)
1665 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1666 ret = write_data(fd,buf,len);
1668 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1672 /****************************************************************************
1674 ****************************************************************************/
1675 int read_udp_socket(int fd,char *buf,int len)
1678 struct sockaddr sock;
1681 socklen = sizeof(sock);
1682 bzero((char *)&sock,socklen);
1683 bzero((char *)&lastip,sizeof(lastip));
1684 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1686 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1690 lastip = *(struct in_addr *) &sock.sa_data[2];
1691 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1696 /****************************************************************************
1697 read data from a device with a timout in msec.
1698 mincount = if timeout, minimum to read before returning
1699 maxcount = number to be read.
1700 ****************************************************************************/
1701 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1707 struct timeval timeout;
1709 /* just checking .... */
1710 if (maxcnt <= 0) return(0);
1715 if (time_out <= 0) {
1716 if (mincnt == 0) mincnt = maxcnt;
1718 while (nread < mincnt) {
1719 readret = read(fd, buf + nread, maxcnt - nread);
1721 smb_read_error = READ_EOF;
1725 if (readret == -1) {
1726 smb_read_error = READ_ERROR;
1734 /* Most difficult - timeout read */
1735 /* If this is ever called on a disk file and
1736 mincnt is greater then the filesize then
1737 system performance will suffer severely as
1738 select always return true on disk files */
1740 /* Set initial timeout */
1741 timeout.tv_sec = time_out / 1000;
1742 timeout.tv_usec = 1000 * (time_out % 1000);
1744 for (nread=0; nread<mincnt; )
1749 selrtn = sys_select(&fds,&timeout);
1751 /* Check if error */
1753 /* something is wrong. Maybe the socket is dead? */
1754 smb_read_error = READ_ERROR;
1758 /* Did we timeout ? */
1760 smb_read_error = READ_TIMEOUT;
1764 readret = read(fd, buf+nread, maxcnt-nread);
1766 /* we got EOF on the file descriptor */
1767 smb_read_error = READ_EOF;
1771 if (readret == -1) {
1772 /* the descriptor is probably dead */
1773 smb_read_error = READ_ERROR;
1780 /* Return the number we got */
1784 /****************************************************************************
1785 read data from the client. Maxtime is in milliseconds
1786 ****************************************************************************/
1787 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1792 struct timeval timeout;
1797 timeout.tv_sec = maxtime / 1000;
1798 timeout.tv_usec = (maxtime % 1000) * 1000;
1800 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1802 if (!FD_ISSET(fd,&fds))
1805 nread = read_udp_socket(fd, buffer, bufsize);
1807 /* return the number got */
1811 /*******************************************************************
1812 find the difference in milliseconds between two struct timeval
1814 ********************************************************************/
1815 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1817 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1818 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1821 /****************************************************************************
1822 send a keepalive packet (rfc1002)
1823 ****************************************************************************/
1824 BOOL send_keepalive(int client)
1826 unsigned char buf[4];
1829 buf[1] = buf[2] = buf[3] = 0;
1831 return(write_data(client,(char *)buf,4) == 4);
1836 /****************************************************************************
1837 read data from the client, reading exactly N bytes.
1838 ****************************************************************************/
1839 int read_data(int fd,char *buffer,int N)
1848 ret = read(fd,buffer + total,N - total);
1850 smb_read_error = READ_EOF;
1854 smb_read_error = READ_ERROR;
1863 /****************************************************************************
1865 ****************************************************************************/
1866 int write_data(int fd,char *buffer,int N)
1873 ret = write(fd,buffer + total,N - total);
1875 if (ret == -1) return -1;
1876 if (ret == 0) return total;
1884 /****************************************************************************
1885 transfer some data between two fd's
1886 ****************************************************************************/
1887 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1889 static char *buf=NULL;
1894 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1897 size = lp_readsize();
1898 size = MAX(size,1024);
1901 while (!buf && size>0) {
1902 buf = (char *)Realloc(buf,size+8);
1903 if (!buf) size /= 2;
1907 DEBUG(0,("Can't allocate transfer buffer!\n"));
1911 abuf = buf + (align%8);
1918 int s = MIN(n,size);
1923 if (header && (headlen >= MIN(s,1024))) {
1933 if (header && headlen > 0)
1935 ret = MIN(headlen,size);
1936 memcpy(buf1,header,ret);
1939 if (headlen <= 0) header = NULL;
1943 ret += read(infd,buf1+ret,s-ret);
1947 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1948 if (ret2 > 0) total += ret2;
1949 /* if we can't write then dump excess data */
1951 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1953 if (ret <= 0 || ret2 != ret)
1961 /****************************************************************************
1962 read 4 bytes of a smb packet and return the smb length of the packet
1963 possibly store the result in the buffer
1964 ****************************************************************************/
1965 int read_smb_length(int fd,char *inbuf,int timeout)
1969 int len=0, msg_type;
1980 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
1982 ok = (read_data(fd,buffer,4) == 4);
1987 len = smb_len(buffer);
1988 msg_type = CVAL(buffer,0);
1990 if (msg_type == 0x85)
1992 DEBUG(5,("Got keepalive packet\n"));
1997 DEBUG(10,("got smb length of %d\n",len));
2004 /****************************************************************************
2005 read an smb from a fd and return it's length
2006 The timeout is in milli seconds
2007 ****************************************************************************/
2008 BOOL receive_smb(int fd,char *buffer,int timeout)
2014 bzero(buffer,smb_size + 100);
2016 len = read_smb_length(fd,buffer,timeout);
2020 if (len > BUFFER_SIZE) {
2021 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2022 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2026 ret = read_data(fd,buffer+4,len);
2028 smb_read_error = READ_ERROR;
2036 /****************************************************************************
2038 ****************************************************************************/
2039 BOOL send_smb(int fd,char *buffer)
2043 len = smb_len(buffer) + 4;
2045 while (nwritten < len)
2047 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2050 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2062 /****************************************************************************
2063 find a pointer to a netbios name
2064 ****************************************************************************/
2065 char *name_ptr(char *buf,int ofs)
2067 unsigned char c = *(unsigned char *)(buf+ofs);
2069 if ((c & 0xC0) == 0xC0)
2073 memcpy(p,buf+ofs,2);
2076 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2083 /****************************************************************************
2084 extract a netbios name from a buf
2085 ****************************************************************************/
2086 int name_extract(char *buf,int ofs,char *name)
2088 char *p = name_ptr(buf,ofs);
2089 int d = PTR_DIFF(p,buf+ofs);
2091 if (d < -50 || d > 50) return(0);
2092 return(name_interpret(p,name));
2096 /****************************************************************************
2097 return the total storage length of a mangled name
2098 ****************************************************************************/
2099 int name_len(char *s)
2102 unsigned char c = *(unsigned char *)s;
2103 if ((c & 0xC0) == 0xC0)
2105 while (*s) s += (*s)+1;
2106 return(PTR_DIFF(s,s0)+1);
2109 /****************************************************************************
2110 send a single packet to a port on another machine
2111 ****************************************************************************/
2112 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2116 struct sockaddr_in sock_out;
2121 /* create a socket to write to */
2122 out_fd = socket(AF_INET, type, 0);
2125 DEBUG(0,("socket failed"));
2129 /* set the address and port */
2130 bzero((char *)&sock_out,sizeof(sock_out));
2131 putip((char *)&sock_out.sin_addr,(char *)&ip);
2132 sock_out.sin_port = htons( port );
2133 sock_out.sin_family = AF_INET;
2136 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2137 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2140 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2143 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2144 inet_ntoa(ip),port,errno));
2150 /*******************************************************************
2151 sleep for a specified number of milliseconds
2152 ********************************************************************/
2156 struct timeval tval,t1,t2;
2163 tval.tv_sec = (t-tdiff)/1000;
2164 tval.tv_usec = 1000*((t-tdiff)%1000);
2168 sys_select(&fds,&tval);
2171 tdiff = TvalDiff(&t1,&t2);
2175 /****************************************************************************
2176 check if a string is part of a list
2177 ****************************************************************************/
2178 BOOL in_list(char *s,char *list,BOOL casesensitive)
2183 if (!list) return(False);
2185 while (next_token(&p,tok,LIST_SEP))
2187 if (casesensitive) {
2188 if (strcmp(tok,s) == 0)
2191 if (StrCaseCmp(tok,s) == 0)
2198 /* this is used to prevent lots of mallocs of size 1 */
2199 static char *null_string = NULL;
2201 /****************************************************************************
2202 set a string value, allocing the space for the string
2203 ****************************************************************************/
2204 BOOL string_init(char **dest,char *src)
2215 null_string = (char *)malloc(1);
2218 *dest = null_string;
2222 *dest = (char *)malloc(l+1);
2228 /****************************************************************************
2230 ****************************************************************************/
2231 void string_free(char **s)
2233 if (!s || !(*s)) return;
2234 if (*s == null_string)
2240 /****************************************************************************
2241 set a string value, allocing the space for the string, and deallocating any
2243 ****************************************************************************/
2244 BOOL string_set(char **dest,char *src)
2248 return(string_init(dest,src));
2251 /****************************************************************************
2252 substitute a string for a pattern in another string. Make sure there is
2255 This routine looks for pattern in s and replaces it with
2256 insert. It may do multiple replacements.
2258 return True if a substitution was done.
2259 ****************************************************************************/
2260 BOOL string_sub(char *s,char *pattern,char *insert)
2266 if (!insert || !pattern || !s) return(False);
2269 lp = strlen(pattern);
2270 li = strlen(insert);
2272 if (!*pattern) return(False);
2274 while (lp <= ls && (p = strstr(s,pattern)))
2277 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2278 memcpy(p,insert,li);
2287 /*********************************************************
2288 * Recursive routine that is called by mask_match.
2289 * Does the actual matching.
2290 *********************************************************/
2291 BOOL do_match(char *str, char *regexp, int case_sig)
2295 for( p = regexp; *p && *str; ) {
2302 /* Look for a character matching
2303 the one after the '*' */
2306 return True; /* Automatic match */
2308 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2310 if(do_match(str,p,case_sig))
2324 if(toupper(*str) != toupper(*p))
2334 if (!*p && str[0] == '.' && str[1] == 0)
2337 if (!*str && *p == '?')
2339 while (*p == '?') p++;
2343 if(!*str && (*p == '*' && p[1] == '\0'))
2349 /*********************************************************
2350 * Routine to match a given string with a regexp - uses
2351 * simplified regexp that takes * and ? only. Case can be
2352 * significant or not.
2353 *********************************************************/
2354 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2358 fstring ebase,eext,sbase,sext;
2362 /* Make local copies of str and regexp */
2363 StrnCpy(p1,regexp,sizeof(pstring)-1);
2364 StrnCpy(p2,str,sizeof(pstring)-1);
2366 if (!strchr(p2,'.')) {
2371 if (!strchr(p1,'.')) {
2379 string_sub(p1,"*.*","*");
2380 string_sub(p1,".*","*");
2384 /* Remove any *? and ** as they are meaningless */
2385 for(p = p1; *p; p++)
2386 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2387 (void)strcpy( &p[1], &p[2]);
2389 if (strequal(p1,"*")) return(True);
2391 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2397 if ((p=strrchr(p1,'.'))) {
2406 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2416 matched = do_match(sbase,ebase,case_sig) &&
2417 (trans2 || do_match(sext,eext,case_sig));
2419 DEBUG(5,("mask_match returning %d\n", matched));
2426 /****************************************************************************
2427 become a daemon, discarding the controlling terminal
2428 ****************************************************************************/
2429 void become_daemon(void)
2431 #ifndef NO_FORK_DEBUG
2435 /* detach from the terminal */
2441 int i = open("/dev/tty", O_RDWR);
2444 ioctl(i, (int) TIOCNOTTY, (char *)0);
2454 /****************************************************************************
2455 put up a yes/no prompt
2456 ****************************************************************************/
2462 if (!fgets(ans,sizeof(ans)-1,stdin))
2465 if (*ans == 'y' || *ans == 'Y')
2471 /****************************************************************************
2472 read a line from a file with possible \ continuation chars.
2473 Blanks at the start or end of a line are stripped.
2474 The string will be allocated if s2 is NULL
2475 ****************************************************************************/
2476 char *fgets_slash(char *s2,int maxlen,FILE *f)
2481 BOOL start_of_line = True;
2488 maxlen = MIN(maxlen,8);
2489 s = (char *)Realloc(s,maxlen);
2492 if (!s || maxlen < 2) return(NULL);
2496 while (len < maxlen-1)
2504 while (len > 0 && s[len-1] == ' ')
2508 if (len > 0 && s[len-1] == '\\')
2511 start_of_line = True;
2516 if (len <= 0 && !s2)
2518 return(len>0?s:NULL);
2523 start_of_line = False;
2527 if (!s2 && len > maxlen-3)
2530 s = (char *)Realloc(s,maxlen);
2531 if (!s) return(NULL);
2539 /****************************************************************************
2540 set the length of a file from a filedescriptor.
2541 Returns 0 on success, -1 on failure.
2542 ****************************************************************************/
2543 int set_filelen(int fd, long len)
2545 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2546 extend a file with ftruncate. Provide alternate implementation
2549 #if FTRUNCATE_CAN_EXTEND
2550 return ftruncate(fd, len);
2554 long currpos = lseek(fd, 0L, SEEK_CUR);
2558 /* Do an fstat to see if the file is longer than
2559 the requested size (call ftruncate),
2560 or shorter, in which case seek to len - 1 and write 1
2562 if(fstat(fd, &st)<0)
2566 if (S_ISFIFO(st.st_mode)) return 0;
2569 if(st.st_size == len)
2571 if(st.st_size > len)
2572 return ftruncate(fd, len);
2574 if(lseek(fd, len-1, SEEK_SET) != len -1)
2576 if(write(fd, &c, 1)!=1)
2578 /* Seek to where we were */
2579 lseek(fd, currpos, SEEK_SET);
2585 /****************************************************************************
2586 return the byte checksum of some data
2587 ****************************************************************************/
2588 int byte_checksum(char *buf,int len)
2590 unsigned char *p = (unsigned char *)buf;
2600 /****************************************************************************
2601 this is a version of setbuffer() for those machines that only have setvbuf
2602 ****************************************************************************/
2603 void setbuffer(FILE *f,char *buf,int bufsize)
2605 setvbuf(f,buf,_IOFBF,bufsize);
2610 /****************************************************************************
2611 parse out a directory name from a path name. Assumes dos style filenames.
2612 ****************************************************************************/
2613 char *dirname_dos(char *path,char *buf)
2615 char *p = strrchr(path,'\\');
2630 /****************************************************************************
2631 parse out a filename from a path name. Assumes dos style filenames.
2632 ****************************************************************************/
2633 static char *filename_dos(char *path,char *buf)
2635 char *p = strrchr(path,'\\');
2647 /****************************************************************************
2648 expand a pointer to be a particular size
2649 ****************************************************************************/
2650 void *Realloc(void *p,int size)
2656 DEBUG(5,("Realloc asked for 0 bytes\n"));
2661 ret = (void *)malloc(size);
2663 ret = (void *)realloc(p,size);
2666 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2672 /****************************************************************************
2674 ****************************************************************************/
2675 char *strdup(char *s)
2678 if (!s) return(NULL);
2679 ret = (char *)malloc(strlen(s)+1);
2680 if (!ret) return(NULL);
2687 /****************************************************************************
2688 Signal handler for SIGPIPE (write on a disconnected socket)
2689 ****************************************************************************/
2692 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2696 /****************************************************************************
2697 get my own name and IP
2698 ****************************************************************************/
2699 BOOL get_myname(char *myname,struct in_addr *ip)
2706 /* get my host name */
2707 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2709 DEBUG(0,("gethostname failed\n"));
2714 if ((hp = Get_Hostbyname(hostname)) == 0)
2716 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2722 /* split off any parts after an initial . */
2723 char *p = strchr(hostname,'.');
2726 strcpy(myname,hostname);
2730 putip((char *)ip,(char *)hp->h_addr);
2736 /****************************************************************************
2737 true if two IP addresses are equal
2738 ****************************************************************************/
2739 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2742 a1 = ntohl(ip1.s_addr);
2743 a2 = ntohl(ip2.s_addr);
2748 /****************************************************************************
2749 open a socket of the specified type, port and address for incoming data
2750 ****************************************************************************/
2751 int open_socket_in(int type, int port, int dlevel)
2754 struct sockaddr_in sock;
2758 /* get my host name */
2759 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2760 { DEBUG(0,("gethostname failed\n")); return -1; }
2763 if ((hp = Get_Hostbyname(host_name)) == 0)
2765 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2769 bzero((char *)&sock,sizeof(sock));
2770 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2771 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2772 sock.sin_len = sizeof(sock);
2774 sock.sin_port = htons( port );
2775 sock.sin_family = hp->h_addrtype;
2776 sock.sin_addr.s_addr = INADDR_ANY;
2777 res = socket(hp->h_addrtype, type, 0);
2779 { DEBUG(0,("socket failed\n")); return -1; }
2783 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2786 /* now we've got a socket - we need to bind it */
2787 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2790 if (port == SMB_PORT || port == NMB_PORT)
2791 DEBUG(dlevel,("bind failed on port %d (%s)\n",
2792 port,strerror(errno)));
2795 if (dlevel > 0 && port < 1000)
2798 if (port >= 1000 && port < 9000)
2799 return(open_socket_in(type,port+1,dlevel));
2804 DEBUG(3,("bind succeeded on port %d\n",port));
2810 /****************************************************************************
2811 create an outgoing socket
2812 **************************************************************************/
2813 int open_socket_out(int type, struct in_addr *addr, int port )
2815 struct sockaddr_in sock_out;
2818 /* create a socket to write to */
2819 res = socket(PF_INET, type, 0);
2821 { DEBUG(0,("socket error\n")); return -1; }
2823 if (type != SOCK_STREAM) return(res);
2825 bzero((char *)&sock_out,sizeof(sock_out));
2826 putip((char *)&sock_out.sin_addr,(char *)addr);
2828 sock_out.sin_port = htons( port );
2829 sock_out.sin_family = PF_INET;
2831 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2833 /* and connect it to the destination */
2834 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
2835 DEBUG(0,("connect error: %s\n",strerror(errno)));
2844 /****************************************************************************
2845 interpret a protocol description string, with a default
2846 ****************************************************************************/
2847 int interpret_protocol(char *str,int def)
2849 if (strequal(str,"NT1"))
2850 return(PROTOCOL_NT1);
2851 if (strequal(str,"LANMAN2"))
2852 return(PROTOCOL_LANMAN2);
2853 if (strequal(str,"LANMAN1"))
2854 return(PROTOCOL_LANMAN1);
2855 if (strequal(str,"CORE"))
2856 return(PROTOCOL_CORE);
2857 if (strequal(str,"COREPLUS"))
2858 return(PROTOCOL_COREPLUS);
2859 if (strequal(str,"CORE+"))
2860 return(PROTOCOL_COREPLUS);
2862 DEBUG(0,("Unrecognised protocol level %s\n",str));
2867 /****************************************************************************
2868 interpret a security level
2869 ****************************************************************************/
2870 int interpret_security(char *str,int def)
2872 if (strequal(str,"SERVER"))
2874 if (strequal(str,"USER"))
2876 if (strequal(str,"SHARE"))
2879 DEBUG(0,("Unrecognised security level %s\n",str));
2885 /****************************************************************************
2886 interpret an internet address or name into an IP address in 4 byte form
2887 ****************************************************************************/
2888 uint32 interpret_addr(char *str)
2893 if (strcmp(str,"0.0.0.0") == 0) return(0);
2894 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2896 /* if it's in the form of an IP address then get the lib to interpret it */
2897 if (isdigit(str[0])) {
2898 res = inet_addr(str);
2900 /* otherwise assume it's a network name of some sort and use Get_Hostbyname */
2901 if ((hp = Get_Hostbyname(str)) == 0) {
2902 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2905 putip((char *)&res,(char *)hp->h_addr);
2908 if (res == (uint32)-1) return(0);
2913 /*******************************************************************
2914 a convenient addition to interpret_addr()
2915 ******************************************************************/
2916 struct in_addr *interpret_addr2(char *str)
2918 static struct in_addr ret;
2919 uint32 a = interpret_addr(str);
2924 /*******************************************************************
2925 check if an IP is the 0.0.0.0
2926 ******************************************************************/
2927 BOOL zero_ip(struct in_addr ip)
2930 putip((char *)&a,(char *)&ip);
2934 /*******************************************************************
2935 sub strings with useful parameters
2936 ********************************************************************/
2937 void standard_sub_basic(char *s)
2939 if (!strchr(s,'%')) return;
2941 string_sub(s,"%R",remote_proto);
2942 string_sub(s,"%a",remote_arch);
2943 string_sub(s,"%m",remote_machine);
2944 string_sub(s,"%L",local_machine);
2946 if (!strchr(s,'%')) return;
2948 string_sub(s,"%v",VERSION);
2949 string_sub(s,"%h",myhostname);
2950 string_sub(s,"%U",sesssetup_user);
2952 if (!strchr(s,'%')) return;
2954 string_sub(s,"%I",Client_info.addr);
2955 string_sub(s,"%M",Client_info.name);
2956 string_sub(s,"%T",timestring());
2958 if (!strchr(s,'%')) return;
2962 sprintf(pidstr,"%d",(int)getpid());
2963 string_sub(s,"%d",pidstr);
2966 if (!strchr(s,'%')) return;
2969 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
2971 string_sub(s,"%G",gidtoname(pass->pw_gid));
2977 /*******************************************************************
2978 are two IPs on the same subnet?
2979 ********************************************************************/
2980 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2982 uint32 net1,net2,nmask;
2984 nmask = ntohl(mask.s_addr);
2985 net1 = ntohl(ip1.s_addr);
2986 net2 = ntohl(ip2.s_addr);
2988 return((net1 & nmask) == (net2 & nmask));
2992 /*******************************************************************
2993 write a string in unicoode format
2994 ********************************************************************/
2995 int PutUniCode(char *dst,char *src)
2999 dst[ret++] = src[0];
3008 /****************************************************************************
3009 a wrapper for gethostbyname() that tries with all lower and all upper case
3010 if the initial name fails
3011 ****************************************************************************/
3012 struct hostent *Get_Hostbyname(char *name)
3014 char *name2 = strdup(name);
3015 struct hostent *ret;
3019 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3023 if (!isalnum(*name2))
3029 ret = gethostbyname(name2);
3036 /* try with all lowercase */
3038 ret = gethostbyname(name2);
3045 /* try with all uppercase */
3047 ret = gethostbyname(name2);
3054 /* nothing works :-( */
3060 /****************************************************************************
3061 check if a process exists. Does this work on all unixes?
3062 ****************************************************************************/
3063 BOOL process_exists(int pid)
3067 sprintf(s,"/proc/%d",pid);
3068 return(directory_exist(s,NULL));
3071 static BOOL tested=False;
3072 static BOOL ok=False;
3076 sprintf(s,"/proc/%05d",getpid());
3077 ok = file_exist(s,NULL);
3080 sprintf(s,"/proc/%05d",pid);
3081 return(file_exist(s,NULL));
3085 /* a best guess for non root access */
3086 if (geteuid() != 0) return(True);
3088 /* otherwise use kill */
3089 return(pid == getpid() || kill(pid,0) == 0);
3094 /*******************************************************************
3095 turn a uid into a user name
3096 ********************************************************************/
3097 char *uidtoname(int uid)
3099 static char name[40];
3100 struct passwd *pass = getpwuid(uid);
3101 if (pass) return(pass->pw_name);
3102 sprintf(name,"%d",uid);
3106 /*******************************************************************
3107 turn a gid into a group name
3108 ********************************************************************/
3109 char *gidtoname(int gid)
3111 static char name[40];
3112 struct group *grp = getgrgid(gid);
3113 if (grp) return(grp->gr_name);
3114 sprintf(name,"%d",gid);
3118 /*******************************************************************
3120 ********************************************************************/
3121 void BlockSignals(BOOL block,int signum)
3124 int block_mask = sigmask(signum);
3125 static int oldmask = 0;
3127 oldmask = sigblock(block_mask);
3129 sigsetmask(oldmask);
3130 #elif defined(USE_SIGPROCMASK)
3133 sigaddset(&set,signum);
3134 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3139 /*******************************************************************
3140 my own panic function - not suitable for general use
3141 ********************************************************************/
3142 void ajt_panic(void)
3144 system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT");
3149 #define DIRECT direct
3151 #define DIRECT dirent
3154 /*******************************************************************
3155 a readdir wrapper which just returns the file name
3156 also return the inode number if requested
3157 ********************************************************************/
3158 char *readdirname(void *p)
3163 if (!p) return(NULL);
3165 ptr = (struct DIRECT *)readdir(p);
3166 if (!ptr) return(NULL);
3168 dname = ptr->d_name;
3174 unix_to_dos(buf, True);
3180 if (telldir(p) < 0) return(NULL);
3184 /* this handles a broken compiler setup, causing a mixture
3185 of BSD and SYSV headers and libraries */
3187 static BOOL broken_readdir = False;
3188 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3190 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3191 broken_readdir = True;