2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1997
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.
24 #if (defined(NETGROUP) && defined (AUTOMOUNT))
25 #include "rpcsvc/ypclnt.h"
34 int Protocol = PROTOCOL_COREPLUS;
36 /* a default finfo structure to ensure all fields are sensible */
37 file_info def_finfo = {-1,0,0,0,0,0,0,""};
39 /* these are some file handles where debug info will be stored */
42 /* the client file descriptor */
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;
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 static enum remote_arch_types ra_type = RA_UNKNOWN;
76 fstring remote_proto="UNKNOWN";
77 pstring myhostname="";
78 pstring user_socket_options="";
80 pstring sesssetup_user="";
81 pstring samlogon_user="";
83 BOOL sam_logon_in_ssb = False;
86 fstring myworkgroup = "";
87 char **my_netbios_names;
89 int smb_read_error = 0;
91 static BOOL stdout_logging = False;
93 static char *filename_dos(char *path,char *buf);
95 /*******************************************************************
96 get ready for syslog stuff
97 ******************************************************************/
98 void setup_logging(char *pname,BOOL interactive)
102 char *p = strrchr(pname,'/');
105 openlog(pname, LOG_PID, LOG_DAEMON);
106 #else /* LOG_DAEMON - for old systems that have no facility codes. */
107 openlog(pname, LOG_PID);
108 #endif /* LOG_DAEMON */
112 stdout_logging = True;
118 BOOL append_log=False;
121 /****************************************************************************
123 ****************************************************************************/
124 void reopen_logs(void)
131 strcpy(fname,debugf);
132 if (lp_loaded() && (*lp_logfile()))
133 strcpy(fname,lp_logfile());
135 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
137 int oldumask = umask(022);
138 strcpy(debugf,fname);
139 if (dbf) fclose(dbf);
141 dbf = fopen(debugf,"a");
143 dbf = fopen(debugf,"w");
144 if (dbf) setbuf(dbf,NULL);
159 /*******************************************************************
160 check if the log has grown too big
161 ********************************************************************/
162 static void check_log_size(void)
164 static int debug_count=0;
168 if (debug_count++ < 100 || getuid() != 0) return;
170 maxlog = lp_max_log_size() * 1024;
171 if (!dbf || maxlog <= 0) return;
173 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
174 fclose(dbf); dbf = NULL;
176 if (dbf && file_size(debugf) > maxlog) {
178 fclose(dbf); dbf = NULL;
179 sprintf(name,"%s.old",debugf);
180 sys_rename(debugf,name);
188 /*******************************************************************
189 write an debug message on the debugfile. This is called by the DEBUG
191 ********************************************************************/
193 int Debug1(char *format_str, ...)
202 int old_errno = errno;
204 if (stdout_logging) {
206 va_start(ap, format_str);
209 format_str = va_arg(ap,char *);
211 vfprintf(dbf,format_str,ap);
218 if (!lp_syslog_only())
222 int oldumask = umask(022);
223 dbf = fopen(debugf,"w");
235 if (syslog_level < lp_syslog())
238 * map debug levels to syslog() priorities
239 * note that not all DEBUG(0, ...) calls are
242 static int priority_map[] = {
251 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
253 priority = LOG_DEBUG;
255 priority = priority_map[syslog_level];
258 va_start(ap, format_str);
261 format_str = va_arg(ap,char *);
263 vsprintf(msgbuf, format_str, ap);
267 syslog(priority, "%s", msgbuf);
272 if (!lp_syslog_only())
276 va_start(ap, format_str);
279 format_str = va_arg(ap,char *);
281 vfprintf(dbf,format_str,ap);
293 /****************************************************************************
294 find a suitable temporary directory. The result should be copied immediately
295 as it may be overwritten by a subsequent call
296 ****************************************************************************/
300 if ((p = getenv("TMPDIR"))) {
308 /****************************************************************************
309 determine if a file descriptor is in fact a socket
310 ****************************************************************************/
311 BOOL is_a_socket(int fd)
315 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
319 static char *last_ptr=NULL;
321 /****************************************************************************
322 Get the next token from a string, return False if none found
323 handles double-quotes.
324 Based on a routine by GJC@VILLAGE.COM.
325 Extensively modified by Andrew.Tridgell@anu.edu.au
326 ****************************************************************************/
327 BOOL next_token(char **ptr,char *buff,char *sep)
332 if (!ptr) ptr = &last_ptr;
333 if (!ptr) return(False);
337 /* default to simple separators */
338 if (!sep) sep = " \t\n\r";
340 /* find the first non sep char */
341 while(*s && strchr(sep,*s)) s++;
344 if (! *s) return(False);
346 /* copy over the token */
347 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
355 *ptr = (*s) ? s+1 : s;
362 /****************************************************************************
363 Convert list of tokens to array; dependent on above routine.
364 Uses last_ptr from above - bit of a hack.
365 ****************************************************************************/
366 char **toktocliplist(int *ctok, char *sep)
372 if (!sep) sep = " \t\n\r";
374 while(*s && strchr(sep,*s)) s++;
377 if (!*s) return(NULL);
381 while(*s && (!strchr(sep,*s))) s++;
382 while(*s && strchr(sep,*s)) *s++=0;
388 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
400 /*******************************************************************
401 safely copies memory, ensuring no overlap problems.
402 this is only used if the machine does not have it's own memmove().
403 this is not the fastest algorithm in town, but it will do for our
405 ********************************************************************/
406 void *MemMove(void *dest,void *src,int size)
410 if (dest==src || !size) return(dest);
412 d = (unsigned long)dest;
413 s = (unsigned long)src;
415 if ((d >= (s+size)) || (s >= (d+size))) {
417 memcpy(dest,src,size);
423 /* we can forward copy */
424 if (s-d >= sizeof(int) &&
425 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
426 /* do it all as words */
427 int *idest = (int *)dest;
428 int *isrc = (int *)src;
430 for (i=0;i<size;i++) idest[i] = isrc[i];
433 char *cdest = (char *)dest;
434 char *csrc = (char *)src;
435 for (i=0;i<size;i++) cdest[i] = csrc[i];
440 /* must backward copy */
441 if (d-s >= sizeof(int) &&
442 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
443 /* do it all as words */
444 int *idest = (int *)dest;
445 int *isrc = (int *)src;
447 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
450 char *cdest = (char *)dest;
451 char *csrc = (char *)src;
452 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
460 /****************************************************************************
461 prompte a dptr (to make it recently used)
462 ****************************************************************************/
463 void array_promote(char *array,int elsize,int element)
469 p = (char *)malloc(elsize);
473 DEBUG(5,("Ahh! Can't malloc\n"));
476 memcpy(p,array + element * elsize, elsize);
477 memmove(array + elsize,array,elsize*element);
478 memcpy(array,p,elsize);
482 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
491 } socket_options[] = {
492 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
493 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
494 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
496 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
498 #ifdef IPTOS_LOWDELAY
499 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
501 #ifdef IPTOS_THROUGHPUT
502 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
505 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
508 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
511 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
514 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
517 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
520 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
526 /****************************************************************************
527 set user socket options
528 ****************************************************************************/
529 void set_socket_options(int fd, char *options)
533 while (next_token(&options,tok," \t,"))
538 BOOL got_value = False;
540 if ((p = strchr(tok,'=')))
547 for (i=0;socket_options[i].name;i++)
548 if (strequal(socket_options[i].name,tok))
551 if (!socket_options[i].name)
553 DEBUG(0,("Unknown socket option %s\n",tok));
557 switch (socket_options[i].opttype)
561 ret = setsockopt(fd,socket_options[i].level,
562 socket_options[i].option,(char *)&value,sizeof(int));
567 DEBUG(0,("syntax error - %s does not take a value\n",tok));
570 int on = socket_options[i].value;
571 ret = setsockopt(fd,socket_options[i].level,
572 socket_options[i].option,(char *)&on,sizeof(int));
578 DEBUG(0,("Failed to set socket option %s\n",tok));
584 /****************************************************************************
585 close the socket communication
586 ****************************************************************************/
587 void close_sockets(void )
593 /****************************************************************************
594 determine whether we are in the specified group
595 ****************************************************************************/
596 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
600 if (group == current_gid) return(True);
602 for (i=0;i<ngroups;i++)
603 if (group == groups[i])
609 /****************************************************************************
610 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
611 ****************************************************************************/
612 char *StrCpy(char *dest,char *src)
617 /* I don't want to get lazy with these ... */
619 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
624 if (!dest) return(NULL);
629 while ((*d++ = *src++)) ;
633 /****************************************************************************
634 line strncpy but always null terminates. Make sure there is room!
635 ****************************************************************************/
636 char *StrnCpy(char *dest,char *src,int n)
639 if (!dest) return(NULL);
644 while (n-- && (*d++ = *src++)) ;
650 /*******************************************************************
651 copy an IP address from one buffer to another
652 ********************************************************************/
653 void putip(void *dest,void *src)
659 /****************************************************************************
660 interpret the weird netbios "name". Return the name type
661 ****************************************************************************/
662 static int name_interpret(char *in,char *out)
665 int len = (*in++) / 2;
669 if (len > 30 || len<1) return(0);
673 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
677 *out = ((in[0]-'A')<<4) + (in[1]-'A');
685 /* Handle any scope names */
688 *out++ = '.'; /* Scope names are separated by periods */
689 len = *(unsigned char *)in++;
690 StrnCpy(out, in, len);
699 /****************************************************************************
700 mangle a name into netbios format
702 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
703 ****************************************************************************/
704 int name_mangle( char *In, char *Out, char name_type )
712 /* Safely copy the input string, In, into buf[]. */
713 (void)memset( buf, 0, 20 );
717 (void)sprintf( buf, "%-15.15s%c", In, name_type );
719 /* Place the length of the first field into the output buffer. */
723 /* Now convert the name to the rfc1001/1002 format. */
724 for( i = 0; i < 16; i++ )
726 c = toupper( buf[i] );
727 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
728 p[(i*2)+1] = (c & 0x000F) + 'A';
733 /* Add the scope string. */
734 for( i = 0, len = 0; NULL != scope; i++, len++ )
742 return( name_len(Out) );
754 return( name_len(Out) );
757 /*******************************************************************
758 check if a file exists
759 ********************************************************************/
760 BOOL file_exist(char *fname,struct stat *sbuf)
763 if (!sbuf) sbuf = &st;
765 if (sys_stat(fname,sbuf) != 0)
768 return(S_ISREG(sbuf->st_mode));
771 /*******************************************************************
772 check a files mod time
773 ********************************************************************/
774 time_t file_modtime(char *fname)
778 if (sys_stat(fname,&st) != 0)
784 /*******************************************************************
785 check if a directory exists
786 ********************************************************************/
787 BOOL directory_exist(char *dname,struct stat *st)
794 if (sys_stat(dname,st) != 0)
797 ret = S_ISDIR(st->st_mode);
803 /*******************************************************************
804 returns the size in bytes of the named file
805 ********************************************************************/
806 uint32 file_size(char *file_name)
810 sys_stat(file_name,&buf);
814 /*******************************************************************
815 return a string representing an attribute for a file
816 ********************************************************************/
817 char *attrib_string(int mode)
819 static char attrstr[10];
823 if (mode & aVOLID) strcat(attrstr,"V");
824 if (mode & aDIR) strcat(attrstr,"D");
825 if (mode & aARCH) strcat(attrstr,"A");
826 if (mode & aHIDDEN) strcat(attrstr,"H");
827 if (mode & aSYSTEM) strcat(attrstr,"S");
828 if (mode & aRONLY) strcat(attrstr,"R");
834 /*******************************************************************
835 case insensitive string compararison
836 ********************************************************************/
837 int StrCaseCmp(char *s, char *t)
839 /* compare until we run out of string, either t or s, or find a difference */
840 /* We *must* use toupper rather than tolower here due to the
841 asynchronous upper to lower mapping.
843 #if !defined(KANJI_WIN95_COMPATIBILITY)
844 if(lp_client_code_page() == KANJI_CODEPAGE)
846 /* Win95 treats full width ascii characters as case sensitive. */
851 return toupper (*s) - toupper (*t);
852 else if (is_sj_alph (*s) && is_sj_alph (*t))
854 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
860 else if (is_shift_jis (*s) && is_shift_jis (*t))
862 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
865 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
871 else if (is_shift_jis (*s))
873 else if (is_shift_jis (*t))
877 diff = toupper (*s) - toupper (*t);
886 #endif /* KANJI_WIN95_COMPATIBILITY */
888 while (*s && *t && toupper(*s) == toupper(*t))
894 return(toupper(*s) - toupper(*t));
898 /*******************************************************************
899 case insensitive string compararison, length limited
900 ********************************************************************/
901 int StrnCaseCmp(char *s, char *t, int n)
903 /* compare until we run out of string, either t or s, or chars */
904 /* We *must* use toupper rather than tolower here due to the
905 asynchronous upper to lower mapping.
907 #if !defined(KANJI_WIN95_COMPATIBILITY)
908 if(lp_client_code_page() == KANJI_CODEPAGE)
910 /* Win95 treats full width ascii characters as case sensitive. */
915 return toupper (*s) - toupper (*t);
916 else if (is_sj_alph (*s) && is_sj_alph (*t))
918 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
925 else if (is_shift_jis (*s) && is_shift_jis (*t))
927 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
930 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
937 else if (is_shift_jis (*s))
939 else if (is_shift_jis (*t))
943 diff = toupper (*s) - toupper (*t);
954 #endif /* KANJI_WIN95_COMPATIBILITY */
956 while (n-- && *s && *t && toupper(*s) == toupper(*t))
962 /* not run out of chars - strings are different lengths */
964 return(toupper(*s) - toupper(*t));
966 /* identical up to where we run out of chars,
967 and strings are same length */
972 /*******************************************************************
974 ********************************************************************/
975 BOOL strequal(char *s1, char *s2)
977 if (s1 == s2) return(True);
978 if (!s1 || !s2) return(False);
980 return(StrCaseCmp(s1,s2)==0);
983 /*******************************************************************
984 compare 2 strings up to and including the nth char.
985 ******************************************************************/
986 BOOL strnequal(char *s1,char *s2,int n)
988 if (s1 == s2) return(True);
989 if (!s1 || !s2 || !n) return(False);
991 return(StrnCaseCmp(s1,s2,n)==0);
994 /*******************************************************************
995 compare 2 strings (case sensitive)
996 ********************************************************************/
997 BOOL strcsequal(char *s1,char *s2)
999 if (s1 == s2) return(True);
1000 if (!s1 || !s2) return(False);
1002 return(strcmp(s1,s2)==0);
1006 /*******************************************************************
1007 convert a string to lower case
1008 ********************************************************************/
1009 void strlower(char *s)
1013 #if !defined(KANJI_WIN95_COMPATIBILITY)
1014 if(lp_client_code_page() == KANJI_CODEPAGE)
1016 /* Win95 treats full width ascii characters as case sensitive. */
1017 if (is_shift_jis (*s))
1019 if (is_sj_upper (s[0], s[1]))
1020 s[1] = sj_tolower2 (s[1]);
1023 else if (is_kana (*s))
1035 #endif /* KANJI_WIN95_COMPATIBILITY */
1044 /*******************************************************************
1045 convert a string to upper case
1046 ********************************************************************/
1047 void strupper(char *s)
1051 #if !defined(KANJI_WIN95_COMPATIBILITY)
1052 if(lp_client_code_page() == KANJI_CODEPAGE)
1054 /* Win95 treats full width ascii characters as case sensitive. */
1055 if (is_shift_jis (*s))
1057 if (is_sj_lower (s[0], s[1]))
1058 s[1] = sj_toupper2 (s[1]);
1061 else if (is_kana (*s))
1073 #endif /* KANJI_WIN95_COMPATIBILITY */
1082 /*******************************************************************
1083 convert a string to "normal" form
1084 ********************************************************************/
1085 void strnorm(char *s)
1087 if (case_default == CASE_UPPER)
1093 /*******************************************************************
1094 check if a string is in "normal" case
1095 ********************************************************************/
1096 BOOL strisnormal(char *s)
1098 if (case_default == CASE_UPPER)
1099 return(!strhaslower(s));
1101 return(!strhasupper(s));
1105 /****************************************************************************
1107 ****************************************************************************/
1108 void string_replace(char *s,char oldc,char newc)
1112 #if !defined(KANJI_WIN95_COMPATIBILITY)
1113 if(lp_client_code_page() == KANJI_CODEPAGE)
1115 /* Win95 treats full width ascii characters as case sensitive. */
1116 if (is_shift_jis (*s))
1118 else if (is_kana (*s))
1128 #endif /* KANJI_WIN95_COMPATIBILITY */
1137 /****************************************************************************
1138 make a file into unix format
1139 ****************************************************************************/
1140 void unix_format(char *fname)
1143 string_replace(fname,'\\','/');
1147 pstrcpy(namecopy,fname);
1149 strcat(fname,namecopy);
1153 /****************************************************************************
1154 make a file into dos format
1155 ****************************************************************************/
1156 void dos_format(char *fname)
1158 string_replace(fname,'/','\\');
1162 /*******************************************************************
1163 show a smb message structure
1164 ********************************************************************/
1165 void show_msg(char *buf)
1170 if (DEBUGLEVEL < 5) return;
1172 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1174 (int)CVAL(buf,smb_com),
1175 (int)CVAL(buf,smb_rcls),
1176 (int)CVAL(buf,smb_reh),
1177 (int)SVAL(buf,smb_err),
1178 (int)CVAL(buf,smb_flg),
1179 (int)SVAL(buf,smb_flg2)));
1180 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1181 (int)SVAL(buf,smb_tid),
1182 (int)SVAL(buf,smb_pid),
1183 (int)SVAL(buf,smb_uid),
1184 (int)SVAL(buf,smb_mid),
1185 (int)CVAL(buf,smb_wct)));
1187 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1188 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1189 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1191 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1192 DEBUG(5,("smb_bcc=%d\n",bcc));
1194 if (DEBUGLEVEL < 10) return;
1196 dump_data(10, smb_buf(buf), MIN(bcc, 512));
1199 /*******************************************************************
1200 return the length of an smb packet
1201 ********************************************************************/
1202 int smb_len(char *buf)
1204 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1207 /*******************************************************************
1208 set the length of an smb packet
1209 ********************************************************************/
1210 void _smb_setlen(char *buf,int len)
1213 buf[1] = (len&0x10000)>>16;
1214 buf[2] = (len&0xFF00)>>8;
1218 /*******************************************************************
1219 set the length and marker of an smb packet
1220 ********************************************************************/
1221 void smb_setlen(char *buf,int len)
1223 _smb_setlen(buf,len);
1231 /*******************************************************************
1232 setup the word count and byte count for a smb message
1233 ********************************************************************/
1234 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1237 bzero(buf + smb_size,num_words*2 + num_bytes);
1238 CVAL(buf,smb_wct) = num_words;
1239 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1240 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1241 return (smb_size + num_words*2 + num_bytes);
1244 /*******************************************************************
1245 return the number of smb words
1246 ********************************************************************/
1247 int smb_numwords(char *buf)
1249 return (CVAL(buf,smb_wct));
1252 /*******************************************************************
1253 return the size of the smb_buf region of a message
1254 ********************************************************************/
1255 int smb_buflen(char *buf)
1257 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1260 /*******************************************************************
1261 return a pointer to the smb_buf data area
1262 ********************************************************************/
1263 int smb_buf_ofs(char *buf)
1265 return (smb_size + CVAL(buf,smb_wct)*2);
1268 /*******************************************************************
1269 return a pointer to the smb_buf data area
1270 ********************************************************************/
1271 char *smb_buf(char *buf)
1273 return (buf + smb_buf_ofs(buf));
1276 /*******************************************************************
1277 return the SMB offset into an SMB buffer
1278 ********************************************************************/
1279 int smb_offset(char *p,char *buf)
1281 return(PTR_DIFF(p,buf+4) + chain_size);
1285 /*******************************************************************
1286 skip past some strings in a buffer
1287 ********************************************************************/
1288 char *skip_string(char *buf,int n)
1291 buf += strlen(buf) + 1;
1295 /*******************************************************************
1296 trim the specified elements off the front and back of a string
1297 ********************************************************************/
1298 BOOL trim_string(char *s,char *front,char *back)
1301 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1307 if (!(*p = p[strlen(front)]))
1312 while (back && *back && strlen(s) >= strlen(back) &&
1313 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1316 s[strlen(s)-strlen(back)] = 0;
1322 /*******************************************************************
1323 reduce a file name, removing .. elements.
1324 ********************************************************************/
1325 void dos_clean_name(char *s)
1329 DEBUG(3,("dos_clean_name [%s]\n",s));
1331 /* remove any double slashes */
1332 string_sub(s, "\\\\", "\\");
1334 while ((p = strstr(s,"\\..\\")) != NULL)
1341 if ((p=strrchr(s,'\\')) != NULL)
1348 trim_string(s,NULL,"\\..");
1350 string_sub(s, "\\.\\", "\\");
1353 /*******************************************************************
1354 reduce a file name, removing .. elements.
1355 ********************************************************************/
1356 void unix_clean_name(char *s)
1360 DEBUG(3,("unix_clean_name [%s]\n",s));
1362 /* remove any double slashes */
1363 string_sub(s, "//","/");
1365 /* Remove leading ./ characters */
1366 if(strncmp(s, "./", 2) == 0) {
1367 trim_string(s, "./", NULL);
1372 while ((p = strstr(s,"/../")) != NULL)
1379 if ((p=strrchr(s,'/')) != NULL)
1386 trim_string(s,NULL,"/..");
1390 /*******************************************************************
1391 a wrapper for the normal chdir() function
1392 ********************************************************************/
1393 int ChDir(char *path)
1396 static pstring LastDir="";
1398 if (strcsequal(path,".")) return(0);
1400 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1401 DEBUG(3,("chdir to %s\n",path));
1402 res = sys_chdir(path);
1404 pstrcpy(LastDir,path);
1408 /* number of list structures for a caching GetWd function. */
1409 #define MAX_GETWDCACHE (50)
1417 } ino_list[MAX_GETWDCACHE];
1419 BOOL use_getwd_cache=True;
1421 /*******************************************************************
1422 return the absolute current directory path
1423 ********************************************************************/
1424 char *GetWd(char *str)
1427 static BOOL getwd_cache_init = False;
1428 struct stat st, st2;
1433 if (!use_getwd_cache)
1434 return(sys_getwd(str));
1436 /* init the cache */
1437 if (!getwd_cache_init)
1439 getwd_cache_init = True;
1440 for (i=0;i<MAX_GETWDCACHE;i++)
1442 string_init(&ino_list[i].text,"");
1443 ino_list[i].valid = False;
1447 /* Get the inode of the current directory, if this doesn't work we're
1450 if (stat(".",&st) == -1)
1452 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1453 return(sys_getwd(str));
1457 for (i=0; i<MAX_GETWDCACHE; i++)
1458 if (ino_list[i].valid)
1461 /* If we have found an entry with a matching inode and dev number
1462 then find the inode number for the directory in the cached string.
1463 If this agrees with that returned by the stat for the current
1464 directory then all is o.k. (but make sure it is a directory all
1467 if (st.st_ino == ino_list[i].inode &&
1468 st.st_dev == ino_list[i].dev)
1470 if (stat(ino_list[i].text,&st2) == 0)
1472 if (st.st_ino == st2.st_ino &&
1473 st.st_dev == st2.st_dev &&
1474 (st2.st_mode & S_IFMT) == S_IFDIR)
1476 strcpy (str, ino_list[i].text);
1478 /* promote it for future use */
1479 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1484 /* If the inode is different then something's changed,
1485 scrub the entry and start from scratch. */
1486 ino_list[i].valid = False;
1493 /* We don't have the information to hand so rely on traditional methods.
1494 The very slow getcwd, which spawns a process on some systems, or the
1495 not quite so bad getwd. */
1499 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1505 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1507 /* add it to the cache */
1508 i = MAX_GETWDCACHE - 1;
1509 string_set(&ino_list[i].text,s);
1510 ino_list[i].dev = st.st_dev;
1511 ino_list[i].inode = st.st_ino;
1512 ino_list[i].valid = True;
1514 /* put it at the top of the list */
1515 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1522 /*******************************************************************
1523 reduce a file name, removing .. elements and checking that
1524 it is below dir in the heirachy. This uses GetWd() and so must be run
1525 on the system that has the referenced file system.
1527 widelinks are allowed if widelinks is true
1528 ********************************************************************/
1529 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1531 #ifndef REDUCE_PATHS
1539 BOOL relative = (*s != '/');
1541 *dir2 = *wd = *basename = *newname = 0;
1546 /* can't have a leading .. */
1547 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1549 DEBUG(3,("Illegal file name? (%s)\n",s));
1559 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1561 /* remove any double slashes */
1562 string_sub(s,"//","/");
1564 pstrcpy(basename,s);
1565 p = strrchr(basename,'/');
1572 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1576 if (ChDir(dir) != 0)
1578 DEBUG(0,("couldn't chdir to %s\n",dir));
1584 DEBUG(0,("couldn't getwd for %s\n",dir));
1590 if (p && (p != basename))
1593 if (strcmp(p+1,".")==0)
1595 if (strcmp(p+1,"..")==0)
1599 if (ChDir(basename) != 0)
1602 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1606 if (!GetWd(newname))
1609 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1613 if (p && (p != basename))
1615 strcat(newname,"/");
1616 strcat(newname,p+1);
1620 int l = strlen(dir2);
1621 if (dir2[l-1] == '/')
1624 if (strncmp(newname,dir2,l) != 0)
1627 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1633 if (newname[l] == '/')
1634 pstrcpy(s,newname + l + 1);
1636 pstrcpy(s,newname+l);
1647 DEBUG(3,("reduced to %s\n",s));
1652 /****************************************************************************
1654 ****************************************************************************/
1655 static void expand_one(char *Mask,int len)
1658 while ((p1 = strchr(Mask,'*')) != NULL)
1660 int lfill = (len+1) - strlen(Mask);
1661 int l1= (p1 - Mask);
1664 memset(tmp+l1,'?',lfill);
1665 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1670 /****************************************************************************
1671 expand a wildcard expression, replacing *s with ?s
1672 ****************************************************************************/
1673 void expand_mask(char *Mask,BOOL doext)
1678 BOOL hasdot = False;
1680 BOOL absolute = (*Mask == '\\');
1682 *mbeg = *mext = *dirpart = *filepart = 0;
1684 /* parse the directory and filename */
1685 if (strchr(Mask,'\\'))
1686 dirname_dos(Mask,dirpart);
1688 filename_dos(Mask,filepart);
1690 pstrcpy(mbeg,filepart);
1691 if ((p1 = strchr(mbeg,'.')) != NULL)
1701 if (strlen(mbeg) > 8)
1703 pstrcpy(mext,mbeg + 8);
1709 strcpy(mbeg,"????????");
1710 if ((*mext == 0) && doext && !hasdot)
1713 if (strequal(mbeg,"*") && *mext==0)
1721 pstrcpy(Mask,dirpart);
1722 if (*dirpart || absolute) strcat(Mask,"\\");
1727 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1731 /****************************************************************************
1732 does a string have any uppercase chars in it?
1733 ****************************************************************************/
1734 BOOL strhasupper(char *s)
1738 #if !defined(KANJI_WIN95_COMPATIBILITY)
1739 if(lp_client_code_page() == KANJI_CODEPAGE)
1741 /* Win95 treats full width ascii characters as case sensitive. */
1742 if (is_shift_jis (*s))
1744 else if (is_kana (*s))
1754 #endif /* KANJI_WIN95_COMPATIBILITY */
1764 /****************************************************************************
1765 does a string have any lowercase chars in it?
1766 ****************************************************************************/
1767 BOOL strhaslower(char *s)
1771 #if !defined(KANJI_WIN95_COMPATIBILITY)
1772 if(lp_client_code_page() == KANJI_CODEPAGE)
1774 /* Win95 treats full width ascii characters as case sensitive. */
1775 if (is_shift_jis (*s))
1777 if (is_sj_upper (s[0], s[1]))
1779 if (is_sj_lower (s[0], s[1]))
1783 else if (is_kana (*s))
1795 #endif /* KANJI_WIN95_COMPATIBILITY */
1805 /****************************************************************************
1806 find the number of chars in a string
1807 ****************************************************************************/
1808 int count_chars(char *s,char c)
1812 #if !defined(KANJI_WIN95_COMPATIBILITY)
1813 if(lp_client_code_page() == KANJI_CODEPAGE)
1815 /* Win95 treats full width ascii characters as case sensitive. */
1818 if (is_shift_jis (*s))
1829 #endif /* KANJI_WIN95_COMPATIBILITY */
1842 /****************************************************************************
1844 ****************************************************************************/
1845 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1850 pstrcpy(mask2,mask);
1852 if ((mode & aDIR) != 0)
1855 memset(buf+1,' ',11);
1856 if ((p = strchr(mask2,'.')) != NULL)
1859 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1860 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1864 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1866 bzero(buf+21,DIR_STRUCT_SIZE-21);
1867 CVAL(buf,21) = mode;
1868 put_dos_date(buf,22,date);
1869 SSVAL(buf,26,size & 0xFFFF);
1870 SSVAL(buf,28,size >> 16);
1871 StrnCpy(buf+30,fname,12);
1872 if (!case_sensitive)
1874 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1878 /*******************************************************************
1879 close the low 3 fd's and open dev/null in their place
1880 ********************************************************************/
1881 void close_low_fds(void)
1885 close(0); close(1); close(2);
1886 /* try and use up these file descriptors, so silly
1887 library routines writing to stdout etc won't cause havoc */
1889 fd = open("/dev/null",O_RDWR,0);
1890 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1892 DEBUG(0,("Can't open /dev/null\n"));
1896 DEBUG(0,("Didn't get file descriptor %d\n",i));
1902 /****************************************************************************
1903 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1905 if SYSV use O_NDELAY
1907 ****************************************************************************/
1908 int set_blocking(int fd, BOOL set)
1912 #define FLAG_TO_SET O_NONBLOCK
1915 #define FLAG_TO_SET O_NDELAY
1917 #define FLAG_TO_SET FNDELAY
1921 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1923 if(set) /* Turn blocking on - ie. clear nonblock flag */
1924 val &= ~FLAG_TO_SET;
1927 return fcntl( fd, F_SETFL, val);
1932 /****************************************************************************
1934 ****************************************************************************/
1935 int write_socket(int fd,char *buf,int len)
1941 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1942 ret = write_data(fd,buf,len);
1944 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1948 /****************************************************************************
1950 ****************************************************************************/
1951 int read_udp_socket(int fd,char *buf,int len)
1954 struct sockaddr sock;
1957 socklen = sizeof(sock);
1958 bzero((char *)&sock,socklen);
1959 bzero((char *)&lastip,sizeof(lastip));
1960 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1962 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1966 lastip = *(struct in_addr *) &sock.sa_data[2];
1967 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1969 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1970 inet_ntoa(lastip), lastport, ret));
1975 /****************************************************************************
1976 read data from a device with a timout in msec.
1977 mincount = if timeout, minimum to read before returning
1978 maxcount = number to be read.
1979 ****************************************************************************/
1980 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1986 struct timeval timeout;
1988 /* just checking .... */
1989 if (maxcnt <= 0) return(0);
1994 if (time_out <= 0) {
1995 if (mincnt == 0) mincnt = maxcnt;
1997 while (nread < mincnt) {
1998 readret = read(fd, buf + nread, maxcnt - nread);
2000 smb_read_error = READ_EOF;
2004 if (readret == -1) {
2005 smb_read_error = READ_ERROR;
2013 /* Most difficult - timeout read */
2014 /* If this is ever called on a disk file and
2015 mincnt is greater then the filesize then
2016 system performance will suffer severely as
2017 select always return true on disk files */
2019 /* Set initial timeout */
2020 timeout.tv_sec = time_out / 1000;
2021 timeout.tv_usec = 1000 * (time_out % 1000);
2023 for (nread=0; nread<mincnt; )
2028 selrtn = sys_select(&fds,&timeout);
2030 /* Check if error */
2032 /* something is wrong. Maybe the socket is dead? */
2033 smb_read_error = READ_ERROR;
2037 /* Did we timeout ? */
2039 smb_read_error = READ_TIMEOUT;
2043 readret = read(fd, buf+nread, maxcnt-nread);
2045 /* we got EOF on the file descriptor */
2046 smb_read_error = READ_EOF;
2050 if (readret == -1) {
2051 /* the descriptor is probably dead */
2052 smb_read_error = READ_ERROR;
2059 /* Return the number we got */
2063 /****************************************************************************
2064 read data from the client. Maxtime is in milliseconds
2065 ****************************************************************************/
2066 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2071 struct timeval timeout;
2076 timeout.tv_sec = maxtime / 1000;
2077 timeout.tv_usec = (maxtime % 1000) * 1000;
2079 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2081 if (!FD_ISSET(fd,&fds))
2084 nread = read_udp_socket(fd, buffer, bufsize);
2086 /* return the number got */
2090 /*******************************************************************
2091 find the difference in milliseconds between two struct timeval
2093 ********************************************************************/
2094 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2096 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2097 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2100 /****************************************************************************
2101 send a keepalive packet (rfc1002)
2102 ****************************************************************************/
2103 BOOL send_keepalive(int client)
2105 unsigned char buf[4];
2108 buf[1] = buf[2] = buf[3] = 0;
2110 return(write_data(client,(char *)buf,4) == 4);
2115 /****************************************************************************
2116 read data from the client, reading exactly N bytes.
2117 ****************************************************************************/
2118 int read_data(int fd,char *buffer,int N)
2127 ret = read(fd,buffer + total,N - total);
2129 smb_read_error = READ_EOF;
2133 smb_read_error = READ_ERROR;
2142 /****************************************************************************
2144 ****************************************************************************/
2145 int write_data(int fd,char *buffer,int N)
2152 ret = write(fd,buffer + total,N - total);
2154 if (ret == -1) return -1;
2155 if (ret == 0) return total;
2163 /****************************************************************************
2164 transfer some data between two fd's
2165 ****************************************************************************/
2166 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2168 static char *buf=NULL;
2173 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2176 size = lp_readsize();
2177 size = MAX(size,1024);
2180 while (!buf && size>0) {
2181 buf = (char *)Realloc(buf,size+8);
2182 if (!buf) size /= 2;
2186 DEBUG(0,("Can't allocate transfer buffer!\n"));
2190 abuf = buf + (align%8);
2197 int s = MIN(n,size);
2202 if (header && (headlen >= MIN(s,1024))) {
2212 if (header && headlen > 0)
2214 ret = MIN(headlen,size);
2215 memcpy(buf1,header,ret);
2218 if (headlen <= 0) header = NULL;
2222 ret += read(infd,buf1+ret,s-ret);
2226 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2227 if (ret2 > 0) total += ret2;
2228 /* if we can't write then dump excess data */
2230 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2232 if (ret <= 0 || ret2 != ret)
2240 /****************************************************************************
2241 read 4 bytes of a smb packet and return the smb length of the packet
2242 possibly store the result in the buffer
2243 ****************************************************************************/
2244 int read_smb_length(int fd,char *inbuf,int timeout)
2248 int len=0, msg_type;
2259 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2261 ok = (read_data(fd,buffer,4) == 4);
2266 len = smb_len(buffer);
2267 msg_type = CVAL(buffer,0);
2269 if (msg_type == 0x85)
2271 DEBUG(5,("Got keepalive packet\n"));
2276 DEBUG(10,("got smb length of %d\n",len));
2283 /****************************************************************************
2284 read an smb from a fd. Note that the buffer *MUST* be of size
2285 BUFFER_SIZE+SAFETY_MARGIN.
2286 The timeout is in milli seconds
2287 ****************************************************************************/
2288 BOOL receive_smb(int fd,char *buffer, int timeout)
2294 bzero(buffer,smb_size + 100);
2296 len = read_smb_length(fd,buffer,timeout);
2300 if (len > BUFFER_SIZE) {
2301 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2302 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2306 ret = read_data(fd,buffer+4,len);
2308 smb_read_error = READ_ERROR;
2315 /****************************************************************************
2316 read a message from a udp fd.
2317 The timeout is in milli seconds
2318 ****************************************************************************/
2319 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2321 struct sockaddr_in from;
2322 int fromlen = sizeof(from);
2334 to.tv_sec = timeout / 1000;
2335 to.tv_usec = (timeout % 1000) * 1000;
2337 selrtn = sys_select(&fds,&to);
2339 /* Check if error */
2342 /* something is wrong. Maybe the socket is dead? */
2343 smb_read_error = READ_ERROR;
2347 /* Did we timeout ? */
2350 smb_read_error = READ_TIMEOUT;
2356 * Read a loopback udp message.
2358 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2359 buffer_len - UDP_CMD_HEADER_LEN, 0,
2360 (struct sockaddr *)&from, &fromlen);
2364 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2368 /* Validate message length. */
2369 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2371 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2373 buffer_len - UDP_CMD_HEADER_LEN));
2377 /* Validate message from address (must be localhost). */
2378 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2380 DEBUG(0,("receive_local_message: invalid 'from' address \
2381 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2385 /* Setup the message header */
2386 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2387 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2392 /****************************************************************************
2393 structure to hold a linked list of local udp messages.
2395 ****************************************************************************/
2397 typedef struct _udp_message_list {
2398 struct _udp_message_list *msg_next;
2403 static udp_message_list *udp_msg_head = NULL;
2405 /****************************************************************************
2406 Function to push a linked list of local udp messages ready
2408 ****************************************************************************/
2409 BOOL push_local_message(char *buf, int msg_len)
2411 udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
2415 DEBUG(0,("push_local_message: malloc fail (1)\n"));
2419 msg->msg_buf = (char *)malloc(msg_len);
2420 if(msg->msg_buf == NULL)
2422 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2427 memcpy(msg->msg_buf, buf, msg_len);
2428 msg->msg_len = msg_len;
2430 msg->msg_next = udp_msg_head;
2436 /****************************************************************************
2437 Do a select on an two fd's - with timeout.
2439 If a local udp message has been pushed onto the
2440 queue (this can only happen during oplock break
2441 processing) return this first.
2443 If the first smbfd is ready then read an smb from it.
2444 if the second (loopback UDP) fd is ready then read a message
2445 from it and setup the buffer header to identify the length
2447 Returns False on timeout or error.
2450 The timeout is in milli seconds
2451 ****************************************************************************/
2452 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2453 char *buffer, int buffer_len,
2454 int timeout, BOOL *got_smb)
2463 * Check to see if we already have a message on the udp queue.
2464 * If so - copy and return it.
2469 udp_message_list *msg = udp_msg_head;
2470 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2471 udp_msg_head = msg->msg_next;
2473 /* Free the message we just copied. */
2474 free((char *)msg->msg_buf);
2481 FD_SET(oplock_fd,&fds);
2483 to.tv_sec = timeout / 1000;
2484 to.tv_usec = (timeout % 1000) * 1000;
2486 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2488 /* Check if error */
2490 /* something is wrong. Maybe the socket is dead? */
2491 smb_read_error = READ_ERROR;
2495 /* Did we timeout ? */
2497 smb_read_error = READ_TIMEOUT;
2501 if (FD_ISSET(smbfd,&fds))
2504 return receive_smb(smbfd, buffer, 0);
2508 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2512 /****************************************************************************
2514 ****************************************************************************/
2515 BOOL send_smb(int fd,char *buffer)
2519 len = smb_len(buffer) + 4;
2521 while (nwritten < len)
2523 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2526 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2538 /****************************************************************************
2539 find a pointer to a netbios name
2540 ****************************************************************************/
2541 char *name_ptr(char *buf,int ofs)
2543 unsigned char c = *(unsigned char *)(buf+ofs);
2545 if ((c & 0xC0) == 0xC0)
2549 memcpy(p,buf+ofs,2);
2552 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2559 /****************************************************************************
2560 extract a netbios name from a buf
2561 ****************************************************************************/
2562 int name_extract(char *buf,int ofs,char *name)
2564 char *p = name_ptr(buf,ofs);
2565 int d = PTR_DIFF(p,buf+ofs);
2567 if (d < -50 || d > 50) return(0);
2568 return(name_interpret(p,name));
2571 /****************************************************************************
2572 return the total storage length of a mangled name
2573 ****************************************************************************/
2574 int name_len( char *s )
2578 /* If the two high bits of the byte are set, return 2. */
2579 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2582 /* Add up the length bytes. */
2583 for( len = 1; (*s); s += (*s) + 1 )
2591 /****************************************************************************
2592 send a single packet to a port on another machine
2593 ****************************************************************************/
2594 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2598 struct sockaddr_in sock_out;
2603 /* create a socket to write to */
2604 out_fd = socket(AF_INET, type, 0);
2607 DEBUG(0,("socket failed"));
2611 /* set the address and port */
2612 bzero((char *)&sock_out,sizeof(sock_out));
2613 putip((char *)&sock_out.sin_addr,(char *)&ip);
2614 sock_out.sin_port = htons( port );
2615 sock_out.sin_family = AF_INET;
2618 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2619 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2622 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2625 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2626 inet_ntoa(ip),port,strerror(errno)));
2632 /*******************************************************************
2633 sleep for a specified number of milliseconds
2634 ********************************************************************/
2638 struct timeval tval,t1,t2;
2645 tval.tv_sec = (t-tdiff)/1000;
2646 tval.tv_usec = 1000*((t-tdiff)%1000);
2650 sys_select(&fds,&tval);
2653 tdiff = TvalDiff(&t1,&t2);
2657 /****************************************************************************
2658 check if a string is part of a list
2659 ****************************************************************************/
2660 BOOL in_list(char *s,char *list,BOOL casesensitive)
2665 if (!list) return(False);
2667 while (next_token(&p,tok,LIST_SEP))
2669 if (casesensitive) {
2670 if (strcmp(tok,s) == 0)
2673 if (StrCaseCmp(tok,s) == 0)
2680 /* this is used to prevent lots of mallocs of size 1 */
2681 static char *null_string = NULL;
2683 /****************************************************************************
2684 set a string value, allocing the space for the string
2685 ****************************************************************************/
2686 BOOL string_init(char **dest,char *src)
2697 null_string = (char *)malloc(1);
2700 *dest = null_string;
2704 (*dest) = (char *)malloc(l+1);
2705 if ((*dest) == NULL) {
2706 DEBUG(0,("Out of memory in string_init\n"));
2715 /****************************************************************************
2717 ****************************************************************************/
2718 void string_free(char **s)
2720 if (!s || !(*s)) return;
2721 if (*s == null_string)
2727 /****************************************************************************
2728 set a string value, allocing the space for the string, and deallocating any
2730 ****************************************************************************/
2731 BOOL string_set(char **dest,char *src)
2735 return(string_init(dest,src));
2738 /****************************************************************************
2739 substitute a string for a pattern in another string. Make sure there is
2742 This routine looks for pattern in s and replaces it with
2743 insert. It may do multiple replacements.
2745 return True if a substitution was done.
2746 ****************************************************************************/
2747 BOOL string_sub(char *s,char *pattern,char *insert)
2753 if (!insert || !pattern || !s) return(False);
2756 lp = strlen(pattern);
2757 li = strlen(insert);
2759 if (!*pattern) return(False);
2761 while (lp <= ls && (p = strstr(s,pattern)))
2764 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2765 memcpy(p,insert,li);
2774 /*********************************************************
2775 * Recursive routine that is called by mask_match.
2776 * Does the actual matching.
2777 *********************************************************/
2778 BOOL do_match(char *str, char *regexp, int case_sig)
2782 for( p = regexp; *p && *str; ) {
2789 /* Look for a character matching
2790 the one after the '*' */
2793 return True; /* Automatic match */
2795 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2797 if(do_match(str,p,case_sig))
2811 if(toupper(*str) != toupper(*p))
2821 if (!*p && str[0] == '.' && str[1] == 0)
2824 if (!*str && *p == '?')
2826 while (*p == '?') p++;
2830 if(!*str && (*p == '*' && p[1] == '\0'))
2836 /*********************************************************
2837 * Routine to match a given string with a regexp - uses
2838 * simplified regexp that takes * and ? only. Case can be
2839 * significant or not.
2840 *********************************************************/
2841 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2845 fstring ebase,eext,sbase,sext;
2849 /* Make local copies of str and regexp */
2850 StrnCpy(p1,regexp,sizeof(pstring)-1);
2851 StrnCpy(p2,str,sizeof(pstring)-1);
2853 if (!strchr(p2,'.')) {
2858 if (!strchr(p1,'.')) {
2866 string_sub(p1,"*.*","*");
2867 string_sub(p1,".*","*");
2871 /* Remove any *? and ** as they are meaningless */
2872 for(p = p1; *p; p++)
2873 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2874 (void)strcpy( &p[1], &p[2]);
2876 if (strequal(p1,"*")) return(True);
2878 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2884 if ((p=strrchr(p1,'.'))) {
2893 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2903 matched = do_match(sbase,ebase,case_sig) &&
2904 (trans2 || do_match(sext,eext,case_sig));
2906 DEBUG(8,("mask_match returning %d\n", matched));
2913 /****************************************************************************
2914 become a daemon, discarding the controlling terminal
2915 ****************************************************************************/
2916 void become_daemon(void)
2918 #ifndef NO_FORK_DEBUG
2922 /* detach from the terminal */
2925 #else /* USE_SETSID */
2928 int i = open("/dev/tty", O_RDWR);
2931 ioctl(i, (int) TIOCNOTTY, (char *)0);
2935 #endif /* TIOCNOTTY */
2936 #endif /* USE_SETSID */
2937 /* Close fd's 0,1,2. Needed if started by rsh */
2939 #endif /* NO_FORK_DEBUG */
2943 /****************************************************************************
2944 put up a yes/no prompt
2945 ****************************************************************************/
2951 if (!fgets(ans,sizeof(ans)-1,stdin))
2954 if (*ans == 'y' || *ans == 'Y')
2960 /****************************************************************************
2961 read a line from a file with possible \ continuation chars.
2962 Blanks at the start or end of a line are stripped.
2963 The string will be allocated if s2 is NULL
2964 ****************************************************************************/
2965 char *fgets_slash(char *s2,int maxlen,FILE *f)
2970 BOOL start_of_line = True;
2977 maxlen = MIN(maxlen,8);
2978 s = (char *)Realloc(s,maxlen);
2981 if (!s || maxlen < 2) return(NULL);
2985 while (len < maxlen-1)
2993 while (len > 0 && s[len-1] == ' ')
2997 if (len > 0 && s[len-1] == '\\')
3000 start_of_line = True;
3005 if (len <= 0 && !s2)
3007 return(len>0?s:NULL);
3012 start_of_line = False;
3016 if (!s2 && len > maxlen-3)
3019 s = (char *)Realloc(s,maxlen);
3020 if (!s) return(NULL);
3028 /****************************************************************************
3029 set the length of a file from a filedescriptor.
3030 Returns 0 on success, -1 on failure.
3031 ****************************************************************************/
3032 int set_filelen(int fd, long len)
3034 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3035 extend a file with ftruncate. Provide alternate implementation
3038 #if FTRUNCATE_CAN_EXTEND
3039 return ftruncate(fd, len);
3043 long currpos = lseek(fd, 0L, SEEK_CUR);
3047 /* Do an fstat to see if the file is longer than
3048 the requested size (call ftruncate),
3049 or shorter, in which case seek to len - 1 and write 1
3051 if(fstat(fd, &st)<0)
3055 if (S_ISFIFO(st.st_mode)) return 0;
3058 if(st.st_size == len)
3060 if(st.st_size > len)
3061 return ftruncate(fd, len);
3063 if(lseek(fd, len-1, SEEK_SET) != len -1)
3065 if(write(fd, &c, 1)!=1)
3067 /* Seek to where we were */
3068 lseek(fd, currpos, SEEK_SET);
3074 /****************************************************************************
3075 return the byte checksum of some data
3076 ****************************************************************************/
3077 int byte_checksum(char *buf,int len)
3079 unsigned char *p = (unsigned char *)buf;
3089 /****************************************************************************
3090 this is a version of setbuffer() for those machines that only have setvbuf
3091 ****************************************************************************/
3092 void setbuffer(FILE *f,char *buf,int bufsize)
3094 setvbuf(f,buf,_IOFBF,bufsize);
3099 /****************************************************************************
3100 parse out a directory name from a path name. Assumes dos style filenames.
3101 ****************************************************************************/
3102 char *dirname_dos(char *path,char *buf)
3104 char *p = strrchr(path,'\\');
3119 /****************************************************************************
3120 parse out a filename from a path name. Assumes dos style filenames.
3121 ****************************************************************************/
3122 static char *filename_dos(char *path,char *buf)
3124 char *p = strrchr(path,'\\');
3136 /****************************************************************************
3137 expand a pointer to be a particular size
3138 ****************************************************************************/
3139 void *Realloc(void *p,int size)
3145 DEBUG(5,("Realloc asked for 0 bytes\n"));
3150 ret = (void *)malloc(size);
3152 ret = (void *)realloc(p,size);
3155 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3161 /****************************************************************************
3163 ****************************************************************************/
3164 char *strdup(char *s)
3167 if (!s) return(NULL);
3168 ret = (char *)malloc(strlen(s)+1);
3169 if (!ret) return(NULL);
3176 /****************************************************************************
3177 Signal handler for SIGPIPE (write on a disconnected socket)
3178 ****************************************************************************/
3181 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3185 /****************************************************************************
3186 get my own name and IP
3187 ****************************************************************************/
3188 BOOL get_myname(char *my_name,struct in_addr *ip)
3195 /* get my host name */
3196 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3198 DEBUG(0,("gethostname failed\n"));
3203 if ((hp = Get_Hostbyname(hostname)) == 0)
3205 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3211 /* split off any parts after an initial . */
3212 char *p = strchr(hostname,'.');
3215 fstrcpy(my_name,hostname);
3219 putip((char *)ip,(char *)hp->h_addr);
3225 /****************************************************************************
3226 true if two IP addresses are equal
3227 ****************************************************************************/
3228 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3231 a1 = ntohl(ip1.s_addr);
3232 a2 = ntohl(ip2.s_addr);
3237 /****************************************************************************
3238 open a socket of the specified type, port and address for incoming data
3239 ****************************************************************************/
3240 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3243 struct sockaddr_in sock;
3247 /* get my host name */
3248 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3249 { DEBUG(0,("gethostname failed\n")); return -1; }
3252 if ((hp = Get_Hostbyname(host_name)) == 0)
3254 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3258 bzero((char *)&sock,sizeof(sock));
3259 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3260 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3261 sock.sin_len = sizeof(sock);
3263 sock.sin_port = htons( port );
3264 sock.sin_family = hp->h_addrtype;
3265 sock.sin_addr.s_addr = socket_addr;
3266 res = socket(hp->h_addrtype, type, 0);
3268 { DEBUG(0,("socket failed\n")); return -1; }
3272 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3275 /* now we've got a socket - we need to bind it */
3276 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3279 if (port == SMB_PORT || port == NMB_PORT)
3280 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3281 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3284 if (dlevel > 0 && port < 1000)
3287 if (port >= 1000 && port < 9000)
3288 return(open_socket_in(type,port+1,dlevel,socket_addr));
3293 DEBUG(3,("bind succeeded on port %d\n",port));
3299 /****************************************************************************
3300 create an outgoing socket
3301 **************************************************************************/
3302 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3304 struct sockaddr_in sock_out;
3306 int connect_loop = 250; /* 250 milliseconds */
3307 int loops = (timeout * 1000) / connect_loop;
3309 /* create a socket to write to */
3310 res = socket(PF_INET, type, 0);
3312 { DEBUG(0,("socket error\n")); return -1; }
3314 if (type != SOCK_STREAM) return(res);
3316 bzero((char *)&sock_out,sizeof(sock_out));
3317 putip((char *)&sock_out.sin_addr,(char *)addr);
3319 sock_out.sin_port = htons( port );
3320 sock_out.sin_family = PF_INET;
3322 /* set it non-blocking */
3323 set_blocking(res,False);
3325 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3327 /* and connect it to the destination */
3329 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3331 /* Some systems return EAGAIN when they mean EINPROGRESS */
3332 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3333 errno == EAGAIN) && loops--) {
3334 msleep(connect_loop);
3338 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3340 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3346 if (ret < 0 && errno == EISCONN) {
3353 DEBUG(1,("error connecting to %s:%d (%s)\n",
3354 inet_ntoa(*addr),port,strerror(errno)));
3358 /* set it blocking again */
3359 set_blocking(res,True);
3365 /****************************************************************************
3366 interpret a protocol description string, with a default
3367 ****************************************************************************/
3368 int interpret_protocol(char *str,int def)
3370 if (strequal(str,"NT1"))
3371 return(PROTOCOL_NT1);
3372 if (strequal(str,"LANMAN2"))
3373 return(PROTOCOL_LANMAN2);
3374 if (strequal(str,"LANMAN1"))
3375 return(PROTOCOL_LANMAN1);
3376 if (strequal(str,"CORE"))
3377 return(PROTOCOL_CORE);
3378 if (strequal(str,"COREPLUS"))
3379 return(PROTOCOL_COREPLUS);
3380 if (strequal(str,"CORE+"))
3381 return(PROTOCOL_COREPLUS);
3383 DEBUG(0,("Unrecognised protocol level %s\n",str));
3388 /****************************************************************************
3389 interpret a security level
3390 ****************************************************************************/
3391 int interpret_security(char *str,int def)
3393 if (strequal(str,"SERVER"))
3395 if (strequal(str,"USER"))
3397 if (strequal(str,"SHARE"))
3400 DEBUG(0,("Unrecognised security level %s\n",str));
3406 /****************************************************************************
3407 interpret an internet address or name into an IP address in 4 byte form
3408 ****************************************************************************/
3409 uint32 interpret_addr(char *str)
3414 BOOL pure_address = True;
3416 if (strcmp(str,"0.0.0.0") == 0) return(0);
3417 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3419 for (i=0; pure_address && str[i]; i++)
3420 if (!(isdigit(str[i]) || str[i] == '.'))
3421 pure_address = False;
3423 /* if it's in the form of an IP address then get the lib to interpret it */
3425 res = inet_addr(str);
3427 /* otherwise assume it's a network name of some sort and use
3429 if ((hp = Get_Hostbyname(str)) == 0) {
3430 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3433 if(hp->h_addr == NULL) {
3434 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3437 putip((char *)&res,(char *)hp->h_addr);
3440 if (res == (uint32)-1) return(0);
3445 /*******************************************************************
3446 a convenient addition to interpret_addr()
3447 ******************************************************************/
3448 struct in_addr *interpret_addr2(char *str)
3450 static struct in_addr ret;
3451 uint32 a = interpret_addr(str);
3456 /*******************************************************************
3457 check if an IP is the 0.0.0.0
3458 ******************************************************************/
3459 BOOL zero_ip(struct in_addr ip)
3462 putip((char *)&a,(char *)&ip);
3467 /*******************************************************************
3468 matchname - determine if host name matches IP address
3469 ******************************************************************/
3470 static BOOL matchname(char *remotehost,struct in_addr addr)
3475 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3476 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3481 * Make sure that gethostbyname() returns the "correct" host name.
3482 * Unfortunately, gethostbyname("localhost") sometimes yields
3483 * "localhost.domain". Since the latter host name comes from the
3484 * local DNS, we just have to trust it (all bets are off if the local
3485 * DNS is perverted). We always check the address list, though.
3488 if (strcasecmp(remotehost, hp->h_name)
3489 && strcasecmp(remotehost, "localhost")) {
3490 DEBUG(0,("host name/name mismatch: %s != %s",
3491 remotehost, hp->h_name));
3495 /* Look up the host address in the address list we just got. */
3496 for (i = 0; hp->h_addr_list[i]; i++) {
3497 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3502 * The host name does not map to the original host address. Perhaps
3503 * someone has compromised a name server. More likely someone botched
3504 * it, but that could be dangerous, too.
3507 DEBUG(0,("host name/address mismatch: %s != %s",
3508 inet_ntoa(addr), hp->h_name));
3512 /*******************************************************************
3513 Reset the 'done' variables so after a client process is created
3514 from a fork call these calls will be re-done. This should be
3515 expanded if more variables need reseting.
3516 ******************************************************************/
3518 static BOOL global_client_name_done = False;
3519 static BOOL global_client_addr_done = False;
3521 void reset_globals_after_fork()
3523 global_client_name_done = False;
3524 global_client_addr_done = False;
3527 /*******************************************************************
3528 return the DNS name of the client
3529 ******************************************************************/
3530 char *client_name(void)
3534 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3535 int length = sizeof(sa);
3536 static pstring name_buf;
3539 if (global_client_name_done)
3542 strcpy(name_buf,"UNKNOWN");
3544 if (getpeername(Client, &sa, &length) < 0) {
3545 DEBUG(0,("getpeername failed\n"));
3549 /* Look up the remote host name. */
3550 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3551 sizeof(sockin->sin_addr),
3553 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3554 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3556 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3557 if (!matchname(name_buf, sockin->sin_addr)) {
3558 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3559 strcpy(name_buf,"UNKNOWN");
3562 global_client_name_done = True;
3566 /*******************************************************************
3567 return the IP addr of the client as a string
3568 ******************************************************************/
3569 char *client_addr(void)
3573 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3574 int length = sizeof(sa);
3575 static fstring addr_buf;
3577 if (global_client_addr_done)
3580 strcpy(addr_buf,"0.0.0.0");
3582 if (getpeername(Client, &sa, &length) < 0) {
3583 DEBUG(0,("getpeername failed\n"));
3587 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3589 global_client_addr_done = True;
3593 char *automount_server(char *user_name)
3595 static pstring server_name;
3597 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3598 int nis_error; /* returned by yp all functions */
3599 char *nis_result; /* yp_match inits this */
3600 int nis_result_len; /* and set this */
3601 char *nis_domain; /* yp_get_default_domain inits this */
3602 char *nis_map = (char *)lp_nis_home_map_name();
3603 int home_server_len;
3605 /* set to default of local machine */
3606 pstrcpy(server_name, local_machine);
3608 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3610 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3613 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3615 if ((nis_error = yp_match(nis_domain, nis_map,
3616 user_name, strlen(user_name),
3617 &nis_result, &nis_result_len)) != 0)
3619 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3622 if (!nis_error && lp_nis_home_map())
3624 home_server_len = strcspn(nis_result,":");
3625 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3626 if (home_server_len > sizeof(pstring))
3628 home_server_len = sizeof(pstring);
3630 strncpy(server_name, nis_result, home_server_len);
3633 /* use the local machine name instead of the auto-map server */
3634 pstrcpy(server_name, local_machine);
3637 DEBUG(4,("Home server: %s\n", server_name));
3642 /*******************************************************************
3643 sub strings with useful parameters
3644 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3645 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3646 ********************************************************************/
3647 void standard_sub_basic(char *str)
3651 struct passwd *pass;
3652 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3654 for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3660 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3662 string_sub(p,"%G",gidtoname(pass->pw_gid));
3670 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3671 case 'I' : string_sub(p,"%I", client_addr()); break;
3672 case 'L' : string_sub(p,"%L", local_machine); break;
3673 case 'M' : string_sub(p,"%M", client_name()); break;
3674 case 'R' : string_sub(p,"%R", remote_proto); break;
3675 case 'T' : string_sub(p,"%T", timestring()); break;
3676 case 'U' : string_sub(p,"%U", username); break;
3677 case 'a' : string_sub(p,"%a", remote_arch); break;
3680 sprintf(pidstr,"%d",(int)getpid());
3681 string_sub(p,"%d", pidstr);
3684 case 'h' : string_sub(p,"%h", myhostname); break;
3685 case 'm' : string_sub(p,"%m", remote_machine); break;
3686 case 'v' : string_sub(p,"%v", VERSION); break;
3687 case '\0': p++; break; /* don't run off end if last character is % */
3688 default : p+=2; break;
3694 /*******************************************************************
3695 are two IPs on the same subnet?
3696 ********************************************************************/
3697 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3699 uint32 net1,net2,nmask;
3701 nmask = ntohl(mask.s_addr);
3702 net1 = ntohl(ip1.s_addr);
3703 net2 = ntohl(ip2.s_addr);
3705 return((net1 & nmask) == (net2 & nmask));
3709 /*******************************************************************
3710 write a string in unicoode format
3711 ********************************************************************/
3712 int PutUniCode(char *dst,char *src)
3716 dst[ret++] = src[0];
3725 /****************************************************************************
3726 a wrapper for gethostbyname() that tries with all lower and all upper case
3727 if the initial name fails
3728 ****************************************************************************/
3729 struct hostent *Get_Hostbyname(char *name)
3731 char *name2 = strdup(name);
3732 struct hostent *ret;
3736 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3740 if (!isalnum(*name2))
3746 ret = sys_gethostbyname(name2);
3753 /* try with all lowercase */
3755 ret = sys_gethostbyname(name2);
3762 /* try with all uppercase */
3764 ret = sys_gethostbyname(name2);
3771 /* nothing works :-( */
3777 /****************************************************************************
3778 check if a process exists. Does this work on all unixes?
3779 ****************************************************************************/
3780 BOOL process_exists(int pid)
3784 sprintf(s,"/proc/%d",pid);
3785 return(directory_exist(s,NULL));
3788 static BOOL tested=False;
3789 static BOOL ok=False;
3793 sprintf(s,"/proc/%05d",(int)getpid());
3794 ok = file_exist(s,NULL);
3797 sprintf(s,"/proc/%05d",pid);
3798 return(file_exist(s,NULL));
3802 /* CGH 8/16/96 - added ESRCH test */
3803 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3808 /*******************************************************************
3809 turn a uid into a user name
3810 ********************************************************************/
3811 char *uidtoname(int uid)
3813 static char name[40];
3814 struct passwd *pass = getpwuid(uid);
3815 if (pass) return(pass->pw_name);
3816 sprintf(name,"%d",uid);
3820 /*******************************************************************
3821 turn a gid into a group name
3822 ********************************************************************/
3823 char *gidtoname(int gid)
3825 static char name[40];
3826 struct group *grp = getgrgid(gid);
3827 if (grp) return(grp->gr_name);
3828 sprintf(name,"%d",gid);
3832 /*******************************************************************
3834 ********************************************************************/
3835 void BlockSignals(BOOL block,int signum)
3838 int block_mask = sigmask(signum);
3839 static int oldmask = 0;
3841 oldmask = sigblock(block_mask);
3843 sigsetmask(oldmask);
3844 #elif defined(USE_SIGPROCMASK)
3847 sigaddset(&set,signum);
3848 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3853 /*******************************************************************
3854 my own panic function - not suitable for general use
3855 ********************************************************************/
3856 void ajt_panic(void)
3858 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3863 #define DIRECT direct
3865 #define DIRECT dirent
3868 /*******************************************************************
3869 a readdir wrapper which just returns the file name
3870 also return the inode number if requested
3871 ********************************************************************/
3872 char *readdirname(void *p)
3877 if (!p) return(NULL);
3879 ptr = (struct DIRECT *)readdir(p);
3880 if (!ptr) return(NULL);
3882 dname = ptr->d_name;
3885 if (telldir(p) < 0) return(NULL);
3889 /* this handles a broken compiler setup, causing a mixture
3890 of BSD and SYSV headers and libraries */
3892 static BOOL broken_readdir = False;
3893 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3895 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3896 broken_readdir = True;
3905 pstrcpy(buf, dname);
3906 unix_to_dos(buf, True);
3913 /*******************************************************************
3914 Utility function used to decide if the last component
3915 of a path matches a (possibly wildcarded) entry in a namelist.
3916 ********************************************************************/
3918 BOOL is_in_path(char *name, name_compare_entry *namelist)
3920 pstring last_component;
3923 DEBUG(8, ("is_in_path: %s\n", name));
3925 /* if we have no list it's obviously not in the path */
3926 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3928 DEBUG(8,("is_in_path: no name list.\n"));
3932 /* Get the last component of the unix name. */
3933 p = strrchr(name, '/');
3934 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3935 last_component[sizeof(last_component)-1] = '\0';
3937 for(; namelist->name != NULL; namelist++)
3939 if(namelist->is_wild)
3941 /* look for a wildcard match. */
3942 if (mask_match(last_component, namelist->name, case_sensitive, False))
3944 DEBUG(8,("is_in_path: mask match succeeded\n"));
3950 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3951 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3953 DEBUG(8,("is_in_path: match succeeded\n"));
3958 DEBUG(8,("is_in_path: match not found\n"));
3963 /*******************************************************************
3964 Strip a '/' separated list into an array of
3965 name_compare_enties structures suitable for
3966 passing to is_in_path(). We do this for
3967 speed so we can pre-parse all the names in the list
3968 and don't do it for each call to is_in_path().
3969 namelist is modified here and is assumed to be
3970 a copy owned by the caller.
3971 We also check if the entry contains a wildcard to
3972 remove a potentially expensive call to mask_match
3974 ********************************************************************/
3976 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3979 char *nameptr = namelist;
3980 int num_entries = 0;
3983 (*ppname_array) = NULL;
3985 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3988 /* We need to make two passes over the string. The
3989 first to count the number of elements, the second
3994 if ( *nameptr == '/' )
3996 /* cope with multiple (useless) /s) */
4000 /* find the next / */
4001 name_end = strchr(nameptr, '/');
4003 /* oops - the last check for a / didn't find one. */
4004 if (name_end == NULL)
4007 /* next segment please */
4008 nameptr = name_end + 1;
4012 if(num_entries == 0)
4015 if(( (*ppname_array) = (name_compare_entry *)malloc(
4016 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4018 DEBUG(0,("set_namearray: malloc fail\n"));
4022 /* Now copy out the names */
4027 if ( *nameptr == '/' )
4029 /* cope with multiple (useless) /s) */
4033 /* find the next / */
4034 if ((name_end = strchr(nameptr, '/')) != NULL)
4039 /* oops - the last check for a / didn't find one. */
4040 if(name_end == NULL)
4043 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4044 (strchr( nameptr, '*')!=NULL));
4045 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4047 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4051 /* next segment please */
4052 nameptr = name_end + 1;
4056 (*ppname_array)[i].name = NULL;
4061 /****************************************************************************
4062 routine to free a namearray.
4063 ****************************************************************************/
4065 void free_namearray(name_compare_entry *name_array)
4070 if(name_array->name != NULL)
4071 free(name_array->name);
4073 free((char *)name_array);
4076 /****************************************************************************
4077 routine to do file locking
4078 ****************************************************************************/
4079 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4086 uint32 mask = 0xC0000000;
4088 /* make sure the count is reasonable, we might kill the lockd otherwise */
4091 /* the offset is often strange - remove 2 of its bits if either of
4092 the top two bits are set. Shift the top ones by two bits. This
4093 still allows OLE2 apps to operate, but should stop lockd from
4095 if ((offset & mask) != 0)
4096 offset = (offset & ~mask) | ((offset & mask) >> 2);
4098 uint32 mask = ((unsigned)1<<31);
4100 /* interpret negative counts as large numbers */
4104 /* no negative offsets */
4107 /* count + offset must be in range */
4108 while ((offset < 0 || (offset + count < 0)) && mask)
4116 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4119 lock.l_whence = SEEK_SET;
4120 lock.l_start = (int)offset;
4121 lock.l_len = (int)count;
4126 ret = fcntl(fd,op,&lock);
4129 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4135 (lock.l_type != F_UNLCK) &&
4136 (lock.l_pid != 0) &&
4137 (lock.l_pid != getpid()))
4139 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4143 /* it must be not locked or locked by me */
4147 /* a lock set or unset */
4150 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4151 offset,count,op,type,strerror(errno)));
4153 /* perhaps it doesn't support this sort of locking?? */
4154 if (errno == EINVAL)
4156 DEBUG(3,("locking not supported? returning True\n"));
4163 /* everything went OK */
4164 DEBUG(8,("Lock call successful\n"));
4172 /*******************************************************************
4173 lock a file - returning a open file descriptor or -1 on failure
4174 The timeout is in seconds. 0 means no timeout
4175 ********************************************************************/
4176 int file_lock(char *name,int timeout)
4178 int fd = open(name,O_RDWR|O_CREAT,0666);
4180 if (fd < 0) return(-1);
4183 if (timeout) t = time(NULL);
4184 while (!timeout || (time(NULL)-t < timeout)) {
4185 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4186 msleep(LOCK_RETRY_TIMEOUT);
4194 /*******************************************************************
4195 unlock a file locked by file_lock
4196 ********************************************************************/
4197 void file_unlock(int fd)
4201 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4206 /*******************************************************************
4207 is the name specified one of my netbios names
4208 returns true is it is equal, false otherwise
4209 ********************************************************************/
4210 BOOL is_myname(char *s)
4215 for (n=0; my_netbios_names[n]; n++) {
4216 if (strequal(my_netbios_names[n], s))
4219 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4223 /*******************************************************************
4224 set the horrid remote_arch string based on an enum.
4225 ********************************************************************/
4226 void set_remote_arch(enum remote_arch_types type)
4232 strcpy(remote_arch, "WfWg");
4235 strcpy(remote_arch, "OS2");
4238 strcpy(remote_arch, "Win95");
4241 strcpy(remote_arch, "WinNT");
4244 strcpy(remote_arch,"Samba");
4247 ra_type = RA_UNKNOWN;
4248 strcpy(remote_arch, "UNKNOWN");
4253 /*******************************************************************
4254 Get the remote_arch type.
4255 ********************************************************************/
4256 enum remote_arch_types get_remote_arch()
4262 /*******************************************************************
4263 skip past some unicode strings in a buffer
4264 ********************************************************************/
4265 char *skip_unicode_string(char *buf,int n)
4276 /*******************************************************************
4277 Return a ascii version of a unicode string
4278 Hack alert: uses fixed buffer(s) and only handles ascii strings
4279 ********************************************************************/
4281 char *unistrn2(uint16 *buf, int len)
4283 static char lbufs[8][MAXUNI];
4285 char *lbuf = lbufs[nexti];
4288 nexti = (nexti+1)%8;
4290 DEBUG(10, ("unistrn2: "));
4292 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4294 DEBUG(10, ("%4x ", *buf));
4304 /*******************************************************************
4305 Return a ascii version of a unicode string
4306 Hack alert: uses fixed buffer(s) and only handles ascii strings
4307 ********************************************************************/
4309 char *unistr2(uint16 *buf)
4311 static char lbufs[8][MAXUNI];
4313 char *lbuf = lbufs[nexti];
4316 nexti = (nexti+1)%8;
4318 DEBUG(10, ("unistr2: "));
4320 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4322 DEBUG(10, ("%4x ", *buf));
4332 /*******************************************************************
4333 create a null-terminated unicode string from a null-terminated ascii string.
4334 return number of unicode chars copied, excluding the null character.
4336 only handles ascii strings
4337 ********************************************************************/
4339 int struni2(uint16 *p, char *buf)
4343 if (p == NULL) return 0;
4345 DEBUG(10, ("struni2: "));
4349 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4351 DEBUG(10, ("%2x ", *buf));
4363 /*******************************************************************
4364 Return a ascii version of a unicode string
4365 Hack alert: uses fixed buffer(s) and only handles ascii strings
4366 ********************************************************************/
4368 char *unistr(char *buf)
4370 static char lbufs[8][MAXUNI];
4372 char *lbuf = lbufs[nexti];
4375 nexti = (nexti+1)%8;
4377 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4385 /*******************************************************************
4386 strncpy for unicode strings
4387 ********************************************************************/
4388 int unistrncpy(char *dst, char *src, int len)
4392 while (*src && len > 0)
4406 /*******************************************************************
4407 strcpy for unicode strings. returns length (in num of wide chars)
4408 ********************************************************************/
4409 int unistrcpy(char *dst, char *src)
4426 /*******************************************************************
4427 safe string copy into a fstring
4428 ********************************************************************/
4429 void fstrcpy(char *dest, char *src)
4431 int maxlength = sizeof(fstring) - 1;
4433 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4442 while (maxlength-- && *src)
4446 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4451 /*******************************************************************
4452 safe string copy into a pstring
4453 ********************************************************************/
4454 void pstrcpy(char *dest, char *src)
4456 int maxlength = sizeof(pstring) - 1;
4458 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4467 while (maxlength-- && *src)
4471 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4477 /*******************************************************************
4478 align a pointer to a multiple of 4 bytes
4479 ********************************************************************/
4480 char *align4(char *q, char *base)
4484 q += 4 - ((q - base) & 3);
4489 /*******************************************************************
4490 align a pointer to a multiple of 2 bytes
4491 ********************************************************************/
4492 char *align2(char *q, char *base)
4501 /*******************************************************************
4502 align a pointer to a multiple of align_offset bytes. looks like it
4503 will work for offsets of 0, 2 and 4...
4504 ********************************************************************/
4505 char *align_offset(char *q, char *base, int align_offset_len)
4507 int mod = ((q - base) & (align_offset_len-1));
4508 if (align_offset_len != 0 && mod != 0)
4510 q += align_offset_len - mod;
4515 void print_asc(int level, unsigned char *buf,int len)
4519 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4522 void dump_data(int level,char *buf1,int len)
4524 unsigned char *buf = (unsigned char *)buf1;
4528 DEBUG(level,("[%03X] ",i));
4530 DEBUG(level,("%02X ",(int)buf[i]));
4532 if (i%8 == 0) DEBUG(level,(" "));
4534 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4535 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4536 if (i<len) DEBUG(level,("[%03X] ",i));
4544 if (n>8) DEBUG(level,(" "));
4545 while (n--) DEBUG(level,(" "));
4548 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4550 if (n>0) print_asc(level,&buf[i-n],n);
4551 DEBUG(level,("\n"));
4555 char *tab_depth(int depth)
4557 static pstring spaces;
4558 memset(spaces, ' ', depth * 4);
4559 spaces[depth * 4] = 0;