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)
1173 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1175 (int)CVAL(buf,smb_com),
1176 (int)CVAL(buf,smb_rcls),
1177 (int)CVAL(buf,smb_reh),
1178 (int)SVAL(buf,smb_err),
1179 (int)CVAL(buf,smb_flg),
1180 (int)SVAL(buf,smb_flg2)));
1181 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1182 (int)SVAL(buf,smb_tid),
1183 (int)SVAL(buf,smb_pid),
1184 (int)SVAL(buf,smb_uid),
1185 (int)SVAL(buf,smb_mid),
1186 (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)));
1190 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1191 DEBUG(5,("smb_bcc=%d\n",bcc));
1192 if (DEBUGLEVEL < 10)
1194 for (i = 0; i < MIN(bcc, 512); i += 16)
1196 for (j = 0; j < 16 && i+j < MIN(bcc,512); j++)
1199 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1200 if (j == 7) DEBUG(10, (" "));
1205 for (j = 0; j < 16 && i+j < MIN(bcc,512); j++)
1207 unsigned char c = CVAL(smb_buf(buf),i+j);
1208 if (c < 32 || c > 128) c = '.';
1211 if (j == 7) DEBUG(10, (" "));
1218 /*******************************************************************
1219 return the length of an smb packet
1220 ********************************************************************/
1221 int smb_len(char *buf)
1223 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1226 /*******************************************************************
1227 set the length of an smb packet
1228 ********************************************************************/
1229 void _smb_setlen(char *buf,int len)
1232 buf[1] = (len&0x10000)>>16;
1233 buf[2] = (len&0xFF00)>>8;
1237 /*******************************************************************
1238 set the length and marker of an smb packet
1239 ********************************************************************/
1240 void smb_setlen(char *buf,int len)
1242 _smb_setlen(buf,len);
1250 /*******************************************************************
1251 setup the word count and byte count for a smb message
1252 ********************************************************************/
1253 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1256 bzero(buf + smb_size,num_words*2 + num_bytes);
1257 CVAL(buf,smb_wct) = num_words;
1258 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1259 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1260 return (smb_size + num_words*2 + num_bytes);
1263 /*******************************************************************
1264 return the number of smb words
1265 ********************************************************************/
1266 int smb_numwords(char *buf)
1268 return (CVAL(buf,smb_wct));
1271 /*******************************************************************
1272 return the size of the smb_buf region of a message
1273 ********************************************************************/
1274 int smb_buflen(char *buf)
1276 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1279 /*******************************************************************
1280 return a pointer to the smb_buf data area
1281 ********************************************************************/
1282 int smb_buf_ofs(char *buf)
1284 return (smb_size + CVAL(buf,smb_wct)*2);
1287 /*******************************************************************
1288 return a pointer to the smb_buf data area
1289 ********************************************************************/
1290 char *smb_buf(char *buf)
1292 return (buf + smb_buf_ofs(buf));
1295 /*******************************************************************
1296 return the SMB offset into an SMB buffer
1297 ********************************************************************/
1298 int smb_offset(char *p,char *buf)
1300 return(PTR_DIFF(p,buf+4) + chain_size);
1304 /*******************************************************************
1305 skip past some strings in a buffer
1306 ********************************************************************/
1307 char *skip_string(char *buf,int n)
1310 buf += strlen(buf) + 1;
1314 /*******************************************************************
1315 trim the specified elements off the front and back of a string
1316 ********************************************************************/
1317 BOOL trim_string(char *s,char *front,char *back)
1320 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1326 if (!(*p = p[strlen(front)]))
1331 while (back && *back && strlen(s) >= strlen(back) &&
1332 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1335 s[strlen(s)-strlen(back)] = 0;
1341 /*******************************************************************
1342 reduce a file name, removing .. elements.
1343 ********************************************************************/
1344 void dos_clean_name(char *s)
1348 DEBUG(3,("dos_clean_name [%s]\n",s));
1350 /* remove any double slashes */
1351 string_sub(s, "\\\\", "\\");
1353 while ((p = strstr(s,"\\..\\")) != NULL)
1360 if ((p=strrchr(s,'\\')) != NULL)
1367 trim_string(s,NULL,"\\..");
1369 string_sub(s, "\\.\\", "\\");
1372 /*******************************************************************
1373 reduce a file name, removing .. elements.
1374 ********************************************************************/
1375 void unix_clean_name(char *s)
1379 DEBUG(3,("unix_clean_name [%s]\n",s));
1381 /* remove any double slashes */
1382 string_sub(s, "//","/");
1384 /* Remove leading ./ characters */
1385 if(strncmp(s, "./", 2) == 0) {
1386 trim_string(s, "./", NULL);
1391 while ((p = strstr(s,"/../")) != NULL)
1398 if ((p=strrchr(s,'/')) != NULL)
1405 trim_string(s,NULL,"/..");
1409 /*******************************************************************
1410 a wrapper for the normal chdir() function
1411 ********************************************************************/
1412 int ChDir(char *path)
1415 static pstring LastDir="";
1417 if (strcsequal(path,".")) return(0);
1419 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1420 DEBUG(3,("chdir to %s\n",path));
1421 res = sys_chdir(path);
1423 pstrcpy(LastDir,path);
1427 /* number of list structures for a caching GetWd function. */
1428 #define MAX_GETWDCACHE (50)
1436 } ino_list[MAX_GETWDCACHE];
1438 BOOL use_getwd_cache=True;
1440 /*******************************************************************
1441 return the absolute current directory path
1442 ********************************************************************/
1443 char *GetWd(char *str)
1446 static BOOL getwd_cache_init = False;
1447 struct stat st, st2;
1452 if (!use_getwd_cache)
1453 return(sys_getwd(str));
1455 /* init the cache */
1456 if (!getwd_cache_init)
1458 getwd_cache_init = True;
1459 for (i=0;i<MAX_GETWDCACHE;i++)
1461 string_init(&ino_list[i].text,"");
1462 ino_list[i].valid = False;
1466 /* Get the inode of the current directory, if this doesn't work we're
1469 if (stat(".",&st) == -1)
1471 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1472 return(sys_getwd(str));
1476 for (i=0; i<MAX_GETWDCACHE; i++)
1477 if (ino_list[i].valid)
1480 /* If we have found an entry with a matching inode and dev number
1481 then find the inode number for the directory in the cached string.
1482 If this agrees with that returned by the stat for the current
1483 directory then all is o.k. (but make sure it is a directory all
1486 if (st.st_ino == ino_list[i].inode &&
1487 st.st_dev == ino_list[i].dev)
1489 if (stat(ino_list[i].text,&st2) == 0)
1491 if (st.st_ino == st2.st_ino &&
1492 st.st_dev == st2.st_dev &&
1493 (st2.st_mode & S_IFMT) == S_IFDIR)
1495 strcpy (str, ino_list[i].text);
1497 /* promote it for future use */
1498 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1503 /* If the inode is different then something's changed,
1504 scrub the entry and start from scratch. */
1505 ino_list[i].valid = False;
1512 /* We don't have the information to hand so rely on traditional methods.
1513 The very slow getcwd, which spawns a process on some systems, or the
1514 not quite so bad getwd. */
1518 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1524 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1526 /* add it to the cache */
1527 i = MAX_GETWDCACHE - 1;
1528 string_set(&ino_list[i].text,s);
1529 ino_list[i].dev = st.st_dev;
1530 ino_list[i].inode = st.st_ino;
1531 ino_list[i].valid = True;
1533 /* put it at the top of the list */
1534 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1541 /*******************************************************************
1542 reduce a file name, removing .. elements and checking that
1543 it is below dir in the heirachy. This uses GetWd() and so must be run
1544 on the system that has the referenced file system.
1546 widelinks are allowed if widelinks is true
1547 ********************************************************************/
1548 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1550 #ifndef REDUCE_PATHS
1558 BOOL relative = (*s != '/');
1560 *dir2 = *wd = *basename = *newname = 0;
1565 /* can't have a leading .. */
1566 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1568 DEBUG(3,("Illegal file name? (%s)\n",s));
1578 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1580 /* remove any double slashes */
1581 string_sub(s,"//","/");
1583 pstrcpy(basename,s);
1584 p = strrchr(basename,'/');
1591 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1595 if (ChDir(dir) != 0)
1597 DEBUG(0,("couldn't chdir to %s\n",dir));
1603 DEBUG(0,("couldn't getwd for %s\n",dir));
1609 if (p && (p != basename))
1612 if (strcmp(p+1,".")==0)
1614 if (strcmp(p+1,"..")==0)
1618 if (ChDir(basename) != 0)
1621 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1625 if (!GetWd(newname))
1628 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1632 if (p && (p != basename))
1634 strcat(newname,"/");
1635 strcat(newname,p+1);
1639 int l = strlen(dir2);
1640 if (dir2[l-1] == '/')
1643 if (strncmp(newname,dir2,l) != 0)
1646 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1652 if (newname[l] == '/')
1653 pstrcpy(s,newname + l + 1);
1655 pstrcpy(s,newname+l);
1666 DEBUG(3,("reduced to %s\n",s));
1671 /****************************************************************************
1673 ****************************************************************************/
1674 static void expand_one(char *Mask,int len)
1677 while ((p1 = strchr(Mask,'*')) != NULL)
1679 int lfill = (len+1) - strlen(Mask);
1680 int l1= (p1 - Mask);
1683 memset(tmp+l1,'?',lfill);
1684 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1689 /****************************************************************************
1690 expand a wildcard expression, replacing *s with ?s
1691 ****************************************************************************/
1692 void expand_mask(char *Mask,BOOL doext)
1697 BOOL hasdot = False;
1699 BOOL absolute = (*Mask == '\\');
1701 *mbeg = *mext = *dirpart = *filepart = 0;
1703 /* parse the directory and filename */
1704 if (strchr(Mask,'\\'))
1705 dirname_dos(Mask,dirpart);
1707 filename_dos(Mask,filepart);
1709 pstrcpy(mbeg,filepart);
1710 if ((p1 = strchr(mbeg,'.')) != NULL)
1720 if (strlen(mbeg) > 8)
1722 pstrcpy(mext,mbeg + 8);
1728 strcpy(mbeg,"????????");
1729 if ((*mext == 0) && doext && !hasdot)
1732 if (strequal(mbeg,"*") && *mext==0)
1740 pstrcpy(Mask,dirpart);
1741 if (*dirpart || absolute) strcat(Mask,"\\");
1746 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1750 /****************************************************************************
1751 does a string have any uppercase chars in it?
1752 ****************************************************************************/
1753 BOOL strhasupper(char *s)
1757 #if !defined(KANJI_WIN95_COMPATIBILITY)
1758 if(lp_client_code_page() == KANJI_CODEPAGE)
1760 /* Win95 treats full width ascii characters as case sensitive. */
1761 if (is_shift_jis (*s))
1763 else if (is_kana (*s))
1773 #endif /* KANJI_WIN95_COMPATIBILITY */
1783 /****************************************************************************
1784 does a string have any lowercase chars in it?
1785 ****************************************************************************/
1786 BOOL strhaslower(char *s)
1790 #if !defined(KANJI_WIN95_COMPATIBILITY)
1791 if(lp_client_code_page() == KANJI_CODEPAGE)
1793 /* Win95 treats full width ascii characters as case sensitive. */
1794 if (is_shift_jis (*s))
1796 if (is_sj_upper (s[0], s[1]))
1798 if (is_sj_lower (s[0], s[1]))
1802 else if (is_kana (*s))
1814 #endif /* KANJI_WIN95_COMPATIBILITY */
1824 /****************************************************************************
1825 find the number of chars in a string
1826 ****************************************************************************/
1827 int count_chars(char *s,char c)
1831 #if !defined(KANJI_WIN95_COMPATIBILITY)
1832 if(lp_client_code_page() == KANJI_CODEPAGE)
1834 /* Win95 treats full width ascii characters as case sensitive. */
1837 if (is_shift_jis (*s))
1848 #endif /* KANJI_WIN95_COMPATIBILITY */
1861 /****************************************************************************
1863 ****************************************************************************/
1864 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1869 pstrcpy(mask2,mask);
1871 if ((mode & aDIR) != 0)
1874 memset(buf+1,' ',11);
1875 if ((p = strchr(mask2,'.')) != NULL)
1878 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1879 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1883 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1885 bzero(buf+21,DIR_STRUCT_SIZE-21);
1886 CVAL(buf,21) = mode;
1887 put_dos_date(buf,22,date);
1888 SSVAL(buf,26,size & 0xFFFF);
1889 SSVAL(buf,28,size >> 16);
1890 StrnCpy(buf+30,fname,12);
1891 if (!case_sensitive)
1893 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1897 /*******************************************************************
1898 close the low 3 fd's and open dev/null in their place
1899 ********************************************************************/
1900 void close_low_fds(void)
1904 close(0); close(1); close(2);
1905 /* try and use up these file descriptors, so silly
1906 library routines writing to stdout etc won't cause havoc */
1908 fd = open("/dev/null",O_RDWR,0);
1909 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1911 DEBUG(0,("Can't open /dev/null\n"));
1915 DEBUG(0,("Didn't get file descriptor %d\n",i));
1921 /****************************************************************************
1922 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1924 if SYSV use O_NDELAY
1926 ****************************************************************************/
1927 int set_blocking(int fd, BOOL set)
1931 #define FLAG_TO_SET O_NONBLOCK
1934 #define FLAG_TO_SET O_NDELAY
1936 #define FLAG_TO_SET FNDELAY
1940 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1942 if(set) /* Turn blocking on - ie. clear nonblock flag */
1943 val &= ~FLAG_TO_SET;
1946 return fcntl( fd, F_SETFL, val);
1951 /****************************************************************************
1953 ****************************************************************************/
1954 int write_socket(int fd,char *buf,int len)
1960 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1961 ret = write_data(fd,buf,len);
1963 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1967 /****************************************************************************
1969 ****************************************************************************/
1970 int read_udp_socket(int fd,char *buf,int len)
1973 struct sockaddr sock;
1976 socklen = sizeof(sock);
1977 bzero((char *)&sock,socklen);
1978 bzero((char *)&lastip,sizeof(lastip));
1979 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1981 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1985 lastip = *(struct in_addr *) &sock.sa_data[2];
1986 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1991 /****************************************************************************
1992 read data from a device with a timout in msec.
1993 mincount = if timeout, minimum to read before returning
1994 maxcount = number to be read.
1995 ****************************************************************************/
1996 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2002 struct timeval timeout;
2004 /* just checking .... */
2005 if (maxcnt <= 0) return(0);
2010 if (time_out <= 0) {
2011 if (mincnt == 0) mincnt = maxcnt;
2013 while (nread < mincnt) {
2014 readret = read(fd, buf + nread, maxcnt - nread);
2016 smb_read_error = READ_EOF;
2020 if (readret == -1) {
2021 smb_read_error = READ_ERROR;
2029 /* Most difficult - timeout read */
2030 /* If this is ever called on a disk file and
2031 mincnt is greater then the filesize then
2032 system performance will suffer severely as
2033 select always return true on disk files */
2035 /* Set initial timeout */
2036 timeout.tv_sec = time_out / 1000;
2037 timeout.tv_usec = 1000 * (time_out % 1000);
2039 for (nread=0; nread<mincnt; )
2044 selrtn = sys_select(&fds,&timeout);
2046 /* Check if error */
2048 /* something is wrong. Maybe the socket is dead? */
2049 smb_read_error = READ_ERROR;
2053 /* Did we timeout ? */
2055 smb_read_error = READ_TIMEOUT;
2059 readret = read(fd, buf+nread, maxcnt-nread);
2061 /* we got EOF on the file descriptor */
2062 smb_read_error = READ_EOF;
2066 if (readret == -1) {
2067 /* the descriptor is probably dead */
2068 smb_read_error = READ_ERROR;
2075 /* Return the number we got */
2079 /****************************************************************************
2080 read data from the client. Maxtime is in milliseconds
2081 ****************************************************************************/
2082 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2087 struct timeval timeout;
2092 timeout.tv_sec = maxtime / 1000;
2093 timeout.tv_usec = (maxtime % 1000) * 1000;
2095 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2097 if (!FD_ISSET(fd,&fds))
2100 nread = read_udp_socket(fd, buffer, bufsize);
2102 /* return the number got */
2106 /*******************************************************************
2107 find the difference in milliseconds between two struct timeval
2109 ********************************************************************/
2110 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2112 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2113 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2116 /****************************************************************************
2117 send a keepalive packet (rfc1002)
2118 ****************************************************************************/
2119 BOOL send_keepalive(int client)
2121 unsigned char buf[4];
2124 buf[1] = buf[2] = buf[3] = 0;
2126 return(write_data(client,(char *)buf,4) == 4);
2131 /****************************************************************************
2132 read data from the client, reading exactly N bytes.
2133 ****************************************************************************/
2134 int read_data(int fd,char *buffer,int N)
2143 ret = read(fd,buffer + total,N - total);
2145 smb_read_error = READ_EOF;
2149 smb_read_error = READ_ERROR;
2158 /****************************************************************************
2160 ****************************************************************************/
2161 int write_data(int fd,char *buffer,int N)
2168 ret = write(fd,buffer + total,N - total);
2170 if (ret == -1) return -1;
2171 if (ret == 0) return total;
2179 /****************************************************************************
2180 transfer some data between two fd's
2181 ****************************************************************************/
2182 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2184 static char *buf=NULL;
2189 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2192 size = lp_readsize();
2193 size = MAX(size,1024);
2196 while (!buf && size>0) {
2197 buf = (char *)Realloc(buf,size+8);
2198 if (!buf) size /= 2;
2202 DEBUG(0,("Can't allocate transfer buffer!\n"));
2206 abuf = buf + (align%8);
2213 int s = MIN(n,size);
2218 if (header && (headlen >= MIN(s,1024))) {
2228 if (header && headlen > 0)
2230 ret = MIN(headlen,size);
2231 memcpy(buf1,header,ret);
2234 if (headlen <= 0) header = NULL;
2238 ret += read(infd,buf1+ret,s-ret);
2242 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2243 if (ret2 > 0) total += ret2;
2244 /* if we can't write then dump excess data */
2246 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2248 if (ret <= 0 || ret2 != ret)
2256 /****************************************************************************
2257 read 4 bytes of a smb packet and return the smb length of the packet
2258 possibly store the result in the buffer
2259 ****************************************************************************/
2260 int read_smb_length(int fd,char *inbuf,int timeout)
2264 int len=0, msg_type;
2275 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2277 ok = (read_data(fd,buffer,4) == 4);
2282 len = smb_len(buffer);
2283 msg_type = CVAL(buffer,0);
2285 if (msg_type == 0x85)
2287 DEBUG(5,("Got keepalive packet\n"));
2292 DEBUG(10,("got smb length of %d\n",len));
2299 /****************************************************************************
2300 read an smb from a fd. Note that the buffer *MUST* be of size
2301 BUFFER_SIZE+SAFETY_MARGIN.
2302 The timeout is in milli seconds
2303 ****************************************************************************/
2304 BOOL receive_smb(int fd,char *buffer, int timeout)
2310 bzero(buffer,smb_size + 100);
2312 len = read_smb_length(fd,buffer,timeout);
2316 if (len > BUFFER_SIZE) {
2317 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2318 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2322 ret = read_data(fd,buffer+4,len);
2324 smb_read_error = READ_ERROR;
2331 /****************************************************************************
2332 read a message from a udp fd.
2333 The timeout is in milli seconds
2334 ****************************************************************************/
2335 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2337 struct sockaddr_in from;
2338 int fromlen = sizeof(from);
2350 to.tv_sec = timeout / 1000;
2351 to.tv_usec = (timeout % 1000) * 1000;
2353 selrtn = sys_select(&fds,&to);
2355 /* Check if error */
2358 /* something is wrong. Maybe the socket is dead? */
2359 smb_read_error = READ_ERROR;
2363 /* Did we timeout ? */
2366 smb_read_error = READ_TIMEOUT;
2372 * Read a loopback udp message.
2374 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2375 buffer_len - UDP_CMD_HEADER_LEN, 0,
2376 (struct sockaddr *)&from, &fromlen);
2380 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2384 /* Validate message length. */
2385 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2387 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2389 buffer_len - UDP_CMD_HEADER_LEN));
2393 /* Validate message from address (must be localhost). */
2394 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2396 DEBUG(0,("receive_local_message: invalid 'from' address \
2397 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2401 /* Setup the message header */
2402 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2403 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2408 /****************************************************************************
2409 structure to hold a linked list of local udp messages.
2411 ****************************************************************************/
2413 typedef struct _udp_message_list {
2414 struct _udp_message_list *msg_next;
2419 static udp_message_list *udp_msg_head = NULL;
2421 /****************************************************************************
2422 Function to push a linked list of local udp messages ready
2424 ****************************************************************************/
2425 BOOL push_local_message(char *buf, int msg_len)
2427 udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
2431 DEBUG(0,("push_local_message: malloc fail (1)\n"));
2435 msg->msg_buf = (char *)malloc(msg_len);
2436 if(msg->msg_buf == NULL)
2438 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2443 memcpy(msg->msg_buf, buf, msg_len);
2444 msg->msg_len = msg_len;
2446 msg->msg_next = udp_msg_head;
2452 /****************************************************************************
2453 Do a select on an two fd's - with timeout.
2455 If a local udp message has been pushed onto the
2456 queue (this can only happen during oplock break
2457 processing) return this first.
2459 If the first smbfd is ready then read an smb from it.
2460 if the second (loopback UDP) fd is ready then read a message
2461 from it and setup the buffer header to identify the length
2463 Returns False on timeout or error.
2466 The timeout is in milli seconds
2467 ****************************************************************************/
2468 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2469 char *buffer, int buffer_len,
2470 int timeout, BOOL *got_smb)
2479 * Check to see if we already have a message on the udp queue.
2480 * If so - copy and return it.
2485 udp_message_list *msg = udp_msg_head;
2486 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2487 udp_msg_head = msg->msg_next;
2489 /* Free the message we just copied. */
2490 free((char *)msg->msg_buf);
2497 FD_SET(oplock_fd,&fds);
2499 to.tv_sec = timeout / 1000;
2500 to.tv_usec = (timeout % 1000) * 1000;
2502 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2504 /* Check if error */
2506 /* something is wrong. Maybe the socket is dead? */
2507 smb_read_error = READ_ERROR;
2511 /* Did we timeout ? */
2513 smb_read_error = READ_TIMEOUT;
2517 if (FD_ISSET(smbfd,&fds))
2520 return receive_smb(smbfd, buffer, 0);
2524 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2528 /****************************************************************************
2530 ****************************************************************************/
2531 BOOL send_smb(int fd,char *buffer)
2535 len = smb_len(buffer) + 4;
2537 while (nwritten < len)
2539 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2542 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2554 /****************************************************************************
2555 find a pointer to a netbios name
2556 ****************************************************************************/
2557 char *name_ptr(char *buf,int ofs)
2559 unsigned char c = *(unsigned char *)(buf+ofs);
2561 if ((c & 0xC0) == 0xC0)
2565 memcpy(p,buf+ofs,2);
2568 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2575 /****************************************************************************
2576 extract a netbios name from a buf
2577 ****************************************************************************/
2578 int name_extract(char *buf,int ofs,char *name)
2580 char *p = name_ptr(buf,ofs);
2581 int d = PTR_DIFF(p,buf+ofs);
2583 if (d < -50 || d > 50) return(0);
2584 return(name_interpret(p,name));
2587 /****************************************************************************
2588 return the total storage length of a mangled name
2589 ****************************************************************************/
2590 int name_len( char *s )
2594 /* If the two high bits of the byte are set, return 2. */
2595 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2598 /* Add up the length bytes. */
2599 for( len = 1; (*s); s += (*s) + 1 )
2607 /****************************************************************************
2608 send a single packet to a port on another machine
2609 ****************************************************************************/
2610 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2614 struct sockaddr_in sock_out;
2619 /* create a socket to write to */
2620 out_fd = socket(AF_INET, type, 0);
2623 DEBUG(0,("socket failed"));
2627 /* set the address and port */
2628 bzero((char *)&sock_out,sizeof(sock_out));
2629 putip((char *)&sock_out.sin_addr,(char *)&ip);
2630 sock_out.sin_port = htons( port );
2631 sock_out.sin_family = AF_INET;
2634 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2635 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2638 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2641 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2642 inet_ntoa(ip),port,strerror(errno)));
2648 /*******************************************************************
2649 sleep for a specified number of milliseconds
2650 ********************************************************************/
2654 struct timeval tval,t1,t2;
2661 tval.tv_sec = (t-tdiff)/1000;
2662 tval.tv_usec = 1000*((t-tdiff)%1000);
2666 sys_select(&fds,&tval);
2669 tdiff = TvalDiff(&t1,&t2);
2673 /****************************************************************************
2674 check if a string is part of a list
2675 ****************************************************************************/
2676 BOOL in_list(char *s,char *list,BOOL casesensitive)
2681 if (!list) return(False);
2683 while (next_token(&p,tok,LIST_SEP))
2685 if (casesensitive) {
2686 if (strcmp(tok,s) == 0)
2689 if (StrCaseCmp(tok,s) == 0)
2696 /* this is used to prevent lots of mallocs of size 1 */
2697 static char *null_string = NULL;
2699 /****************************************************************************
2700 set a string value, allocing the space for the string
2701 ****************************************************************************/
2702 BOOL string_init(char **dest,char *src)
2713 null_string = (char *)malloc(1);
2716 *dest = null_string;
2720 (*dest) = (char *)malloc(l+1);
2721 if ((*dest) == NULL) {
2722 DEBUG(0,("Out of memory in string_init\n"));
2731 /****************************************************************************
2733 ****************************************************************************/
2734 void string_free(char **s)
2736 if (!s || !(*s)) return;
2737 if (*s == null_string)
2743 /****************************************************************************
2744 set a string value, allocing the space for the string, and deallocating any
2746 ****************************************************************************/
2747 BOOL string_set(char **dest,char *src)
2751 return(string_init(dest,src));
2754 /****************************************************************************
2755 substitute a string for a pattern in another string. Make sure there is
2758 This routine looks for pattern in s and replaces it with
2759 insert. It may do multiple replacements.
2761 return True if a substitution was done.
2762 ****************************************************************************/
2763 BOOL string_sub(char *s,char *pattern,char *insert)
2769 if (!insert || !pattern || !s) return(False);
2772 lp = strlen(pattern);
2773 li = strlen(insert);
2775 if (!*pattern) return(False);
2777 while (lp <= ls && (p = strstr(s,pattern)))
2780 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2781 memcpy(p,insert,li);
2790 /*********************************************************
2791 * Recursive routine that is called by mask_match.
2792 * Does the actual matching.
2793 *********************************************************/
2794 BOOL do_match(char *str, char *regexp, int case_sig)
2798 for( p = regexp; *p && *str; ) {
2805 /* Look for a character matching
2806 the one after the '*' */
2809 return True; /* Automatic match */
2811 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2813 if(do_match(str,p,case_sig))
2827 if(toupper(*str) != toupper(*p))
2837 if (!*p && str[0] == '.' && str[1] == 0)
2840 if (!*str && *p == '?')
2842 while (*p == '?') p++;
2846 if(!*str && (*p == '*' && p[1] == '\0'))
2852 /*********************************************************
2853 * Routine to match a given string with a regexp - uses
2854 * simplified regexp that takes * and ? only. Case can be
2855 * significant or not.
2856 *********************************************************/
2857 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2861 fstring ebase,eext,sbase,sext;
2865 /* Make local copies of str and regexp */
2866 StrnCpy(p1,regexp,sizeof(pstring)-1);
2867 StrnCpy(p2,str,sizeof(pstring)-1);
2869 if (!strchr(p2,'.')) {
2874 if (!strchr(p1,'.')) {
2882 string_sub(p1,"*.*","*");
2883 string_sub(p1,".*","*");
2887 /* Remove any *? and ** as they are meaningless */
2888 for(p = p1; *p; p++)
2889 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2890 (void)strcpy( &p[1], &p[2]);
2892 if (strequal(p1,"*")) return(True);
2894 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2900 if ((p=strrchr(p1,'.'))) {
2909 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2919 matched = do_match(sbase,ebase,case_sig) &&
2920 (trans2 || do_match(sext,eext,case_sig));
2922 DEBUG(8,("mask_match returning %d\n", matched));
2929 /****************************************************************************
2930 become a daemon, discarding the controlling terminal
2931 ****************************************************************************/
2932 void become_daemon(void)
2934 #ifndef NO_FORK_DEBUG
2938 /* detach from the terminal */
2941 #else /* USE_SETSID */
2944 int i = open("/dev/tty", O_RDWR);
2947 ioctl(i, (int) TIOCNOTTY, (char *)0);
2951 #endif /* TIOCNOTTY */
2952 #endif /* USE_SETSID */
2953 /* Close fd's 0,1,2. Needed if started by rsh */
2955 #endif /* NO_FORK_DEBUG */
2959 /****************************************************************************
2960 put up a yes/no prompt
2961 ****************************************************************************/
2967 if (!fgets(ans,sizeof(ans)-1,stdin))
2970 if (*ans == 'y' || *ans == 'Y')
2976 /****************************************************************************
2977 read a line from a file with possible \ continuation chars.
2978 Blanks at the start or end of a line are stripped.
2979 The string will be allocated if s2 is NULL
2980 ****************************************************************************/
2981 char *fgets_slash(char *s2,int maxlen,FILE *f)
2986 BOOL start_of_line = True;
2993 maxlen = MIN(maxlen,8);
2994 s = (char *)Realloc(s,maxlen);
2997 if (!s || maxlen < 2) return(NULL);
3001 while (len < maxlen-1)
3009 while (len > 0 && s[len-1] == ' ')
3013 if (len > 0 && s[len-1] == '\\')
3016 start_of_line = True;
3021 if (len <= 0 && !s2)
3023 return(len>0?s:NULL);
3028 start_of_line = False;
3032 if (!s2 && len > maxlen-3)
3035 s = (char *)Realloc(s,maxlen);
3036 if (!s) return(NULL);
3044 /****************************************************************************
3045 set the length of a file from a filedescriptor.
3046 Returns 0 on success, -1 on failure.
3047 ****************************************************************************/
3048 int set_filelen(int fd, long len)
3050 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3051 extend a file with ftruncate. Provide alternate implementation
3054 #if FTRUNCATE_CAN_EXTEND
3055 return ftruncate(fd, len);
3059 long currpos = lseek(fd, 0L, SEEK_CUR);
3063 /* Do an fstat to see if the file is longer than
3064 the requested size (call ftruncate),
3065 or shorter, in which case seek to len - 1 and write 1
3067 if(fstat(fd, &st)<0)
3071 if (S_ISFIFO(st.st_mode)) return 0;
3074 if(st.st_size == len)
3076 if(st.st_size > len)
3077 return ftruncate(fd, len);
3079 if(lseek(fd, len-1, SEEK_SET) != len -1)
3081 if(write(fd, &c, 1)!=1)
3083 /* Seek to where we were */
3084 lseek(fd, currpos, SEEK_SET);
3090 /****************************************************************************
3091 return the byte checksum of some data
3092 ****************************************************************************/
3093 int byte_checksum(char *buf,int len)
3095 unsigned char *p = (unsigned char *)buf;
3105 /****************************************************************************
3106 this is a version of setbuffer() for those machines that only have setvbuf
3107 ****************************************************************************/
3108 void setbuffer(FILE *f,char *buf,int bufsize)
3110 setvbuf(f,buf,_IOFBF,bufsize);
3115 /****************************************************************************
3116 parse out a directory name from a path name. Assumes dos style filenames.
3117 ****************************************************************************/
3118 char *dirname_dos(char *path,char *buf)
3120 char *p = strrchr(path,'\\');
3135 /****************************************************************************
3136 parse out a filename from a path name. Assumes dos style filenames.
3137 ****************************************************************************/
3138 static char *filename_dos(char *path,char *buf)
3140 char *p = strrchr(path,'\\');
3152 /****************************************************************************
3153 expand a pointer to be a particular size
3154 ****************************************************************************/
3155 void *Realloc(void *p,int size)
3161 DEBUG(5,("Realloc asked for 0 bytes\n"));
3166 ret = (void *)malloc(size);
3168 ret = (void *)realloc(p,size);
3171 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3177 /****************************************************************************
3179 ****************************************************************************/
3180 char *strdup(char *s)
3183 if (!s) return(NULL);
3184 ret = (char *)malloc(strlen(s)+1);
3185 if (!ret) return(NULL);
3192 /****************************************************************************
3193 Signal handler for SIGPIPE (write on a disconnected socket)
3194 ****************************************************************************/
3197 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3201 /****************************************************************************
3202 get my own name and IP
3203 ****************************************************************************/
3204 BOOL get_myname(char *my_name,struct in_addr *ip)
3211 /* get my host name */
3212 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3214 DEBUG(0,("gethostname failed\n"));
3219 if ((hp = Get_Hostbyname(hostname)) == 0)
3221 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3227 /* split off any parts after an initial . */
3228 char *p = strchr(hostname,'.');
3231 fstrcpy(my_name,hostname);
3235 putip((char *)ip,(char *)hp->h_addr);
3241 /****************************************************************************
3242 true if two IP addresses are equal
3243 ****************************************************************************/
3244 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3247 a1 = ntohl(ip1.s_addr);
3248 a2 = ntohl(ip2.s_addr);
3253 /****************************************************************************
3254 open a socket of the specified type, port and address for incoming data
3255 ****************************************************************************/
3256 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3259 struct sockaddr_in sock;
3263 /* get my host name */
3264 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3265 { DEBUG(0,("gethostname failed\n")); return -1; }
3268 if ((hp = Get_Hostbyname(host_name)) == 0)
3270 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3274 bzero((char *)&sock,sizeof(sock));
3275 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3276 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3277 sock.sin_len = sizeof(sock);
3279 sock.sin_port = htons( port );
3280 sock.sin_family = hp->h_addrtype;
3281 sock.sin_addr.s_addr = socket_addr;
3282 res = socket(hp->h_addrtype, type, 0);
3284 { DEBUG(0,("socket failed\n")); return -1; }
3288 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3291 /* now we've got a socket - we need to bind it */
3292 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3295 if (port == SMB_PORT || port == NMB_PORT)
3296 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3297 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3300 if (dlevel > 0 && port < 1000)
3303 if (port >= 1000 && port < 9000)
3304 return(open_socket_in(type,port+1,dlevel,socket_addr));
3309 DEBUG(3,("bind succeeded on port %d\n",port));
3315 /****************************************************************************
3316 create an outgoing socket
3317 **************************************************************************/
3318 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3320 struct sockaddr_in sock_out;
3322 int connect_loop = 250; /* 250 milliseconds */
3323 int loops = (timeout * 1000) / connect_loop;
3325 /* create a socket to write to */
3326 res = socket(PF_INET, type, 0);
3328 { DEBUG(0,("socket error\n")); return -1; }
3330 if (type != SOCK_STREAM) return(res);
3332 bzero((char *)&sock_out,sizeof(sock_out));
3333 putip((char *)&sock_out.sin_addr,(char *)addr);
3335 sock_out.sin_port = htons( port );
3336 sock_out.sin_family = PF_INET;
3338 /* set it non-blocking */
3339 set_blocking(res,False);
3341 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3343 /* and connect it to the destination */
3345 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3347 /* Some systems return EAGAIN when they mean EINPROGRESS */
3348 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3349 errno == EAGAIN) && loops--) {
3350 msleep(connect_loop);
3354 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3356 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3362 if (ret < 0 && errno == EISCONN) {
3369 DEBUG(1,("error connecting to %s:%d (%s)\n",
3370 inet_ntoa(*addr),port,strerror(errno)));
3374 /* set it blocking again */
3375 set_blocking(res,True);
3381 /****************************************************************************
3382 interpret a protocol description string, with a default
3383 ****************************************************************************/
3384 int interpret_protocol(char *str,int def)
3386 if (strequal(str,"NT1"))
3387 return(PROTOCOL_NT1);
3388 if (strequal(str,"LANMAN2"))
3389 return(PROTOCOL_LANMAN2);
3390 if (strequal(str,"LANMAN1"))
3391 return(PROTOCOL_LANMAN1);
3392 if (strequal(str,"CORE"))
3393 return(PROTOCOL_CORE);
3394 if (strequal(str,"COREPLUS"))
3395 return(PROTOCOL_COREPLUS);
3396 if (strequal(str,"CORE+"))
3397 return(PROTOCOL_COREPLUS);
3399 DEBUG(0,("Unrecognised protocol level %s\n",str));
3404 /****************************************************************************
3405 interpret a security level
3406 ****************************************************************************/
3407 int interpret_security(char *str,int def)
3409 if (strequal(str,"SERVER"))
3411 if (strequal(str,"USER"))
3413 if (strequal(str,"SHARE"))
3416 DEBUG(0,("Unrecognised security level %s\n",str));
3422 /****************************************************************************
3423 interpret an internet address or name into an IP address in 4 byte form
3424 ****************************************************************************/
3425 uint32 interpret_addr(char *str)
3430 BOOL pure_address = True;
3432 if (strcmp(str,"0.0.0.0") == 0) return(0);
3433 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3435 for (i=0; pure_address && str[i]; i++)
3436 if (!(isdigit(str[i]) || str[i] == '.'))
3437 pure_address = False;
3439 /* if it's in the form of an IP address then get the lib to interpret it */
3441 res = inet_addr(str);
3443 /* otherwise assume it's a network name of some sort and use
3445 if ((hp = Get_Hostbyname(str)) == 0) {
3446 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3449 if(hp->h_addr == NULL) {
3450 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3453 putip((char *)&res,(char *)hp->h_addr);
3456 if (res == (uint32)-1) return(0);
3461 /*******************************************************************
3462 a convenient addition to interpret_addr()
3463 ******************************************************************/
3464 struct in_addr *interpret_addr2(char *str)
3466 static struct in_addr ret;
3467 uint32 a = interpret_addr(str);
3472 /*******************************************************************
3473 check if an IP is the 0.0.0.0
3474 ******************************************************************/
3475 BOOL zero_ip(struct in_addr ip)
3478 putip((char *)&a,(char *)&ip);
3483 /*******************************************************************
3484 matchname - determine if host name matches IP address
3485 ******************************************************************/
3486 static BOOL matchname(char *remotehost,struct in_addr addr)
3491 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3492 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3497 * Make sure that gethostbyname() returns the "correct" host name.
3498 * Unfortunately, gethostbyname("localhost") sometimes yields
3499 * "localhost.domain". Since the latter host name comes from the
3500 * local DNS, we just have to trust it (all bets are off if the local
3501 * DNS is perverted). We always check the address list, though.
3504 if (strcasecmp(remotehost, hp->h_name)
3505 && strcasecmp(remotehost, "localhost")) {
3506 DEBUG(0,("host name/name mismatch: %s != %s",
3507 remotehost, hp->h_name));
3511 /* Look up the host address in the address list we just got. */
3512 for (i = 0; hp->h_addr_list[i]; i++) {
3513 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3518 * The host name does not map to the original host address. Perhaps
3519 * someone has compromised a name server. More likely someone botched
3520 * it, but that could be dangerous, too.
3523 DEBUG(0,("host name/address mismatch: %s != %s",
3524 inet_ntoa(addr), hp->h_name));
3528 /*******************************************************************
3529 Reset the 'done' variables so after a client process is created
3530 from a fork call these calls will be re-done. This should be
3531 expanded if more variables need reseting.
3532 ******************************************************************/
3534 static BOOL global_client_name_done = False;
3535 static BOOL global_client_addr_done = False;
3537 void reset_globals_after_fork()
3539 global_client_name_done = False;
3540 global_client_addr_done = False;
3543 /*******************************************************************
3544 return the DNS name of the client
3545 ******************************************************************/
3546 char *client_name(void)
3550 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3551 int length = sizeof(sa);
3552 static pstring name_buf;
3555 if (global_client_name_done)
3558 strcpy(name_buf,"UNKNOWN");
3560 if (getpeername(Client, &sa, &length) < 0) {
3561 DEBUG(0,("getpeername failed\n"));
3565 /* Look up the remote host name. */
3566 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3567 sizeof(sockin->sin_addr),
3569 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3570 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3572 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3573 if (!matchname(name_buf, sockin->sin_addr)) {
3574 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3575 strcpy(name_buf,"UNKNOWN");
3578 global_client_name_done = True;
3582 /*******************************************************************
3583 return the IP addr of the client as a string
3584 ******************************************************************/
3585 char *client_addr(void)
3589 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3590 int length = sizeof(sa);
3591 static fstring addr_buf;
3593 if (global_client_addr_done)
3596 strcpy(addr_buf,"0.0.0.0");
3598 if (getpeername(Client, &sa, &length) < 0) {
3599 DEBUG(0,("getpeername failed\n"));
3603 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3605 global_client_addr_done = True;
3609 char *automount_server(char *user_name)
3611 static pstring server_name;
3613 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3614 int nis_error; /* returned by yp all functions */
3615 char *nis_result; /* yp_match inits this */
3616 int nis_result_len; /* and set this */
3617 char *nis_domain; /* yp_get_default_domain inits this */
3618 char *nis_map = (char *)lp_nis_home_map_name();
3619 int home_server_len;
3621 /* set to default of no string */
3624 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3626 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3629 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3631 if ((nis_error = yp_match(nis_domain, nis_map,
3632 user_name, strlen(user_name),
3633 &nis_result, &nis_result_len)) != 0)
3635 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3638 if (!nis_error && lp_nis_home_map())
3640 home_server_len = strcspn(nis_result,":");
3641 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3642 if (home_server_len > sizeof(pstring))
3644 home_server_len = sizeof(pstring);
3646 strncpy(server_name, nis_result, home_server_len);
3649 /* use the local machine name instead of the auto-map server */
3650 pstrcpy(server_name, local_machine);
3653 DEBUG(4,("Home server: %s\n", server_name));
3658 /*******************************************************************
3659 sub strings with useful parameters
3660 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3661 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3662 ********************************************************************/
3663 void standard_sub_basic(char *str)
3667 struct passwd *pass;
3668 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3670 for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3676 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3678 string_sub(p,"%G",gidtoname(pass->pw_gid));
3686 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3687 case 'I' : string_sub(p,"%I", client_addr()); break;
3688 case 'L' : string_sub(p,"%L", local_machine); break;
3689 case 'M' : string_sub(p,"%M", client_name()); break;
3690 case 'R' : string_sub(p,"%R", remote_proto); break;
3691 case 'T' : string_sub(p,"%T", timestring()); break;
3692 case 'U' : string_sub(p,"%U", username); break;
3693 case 'a' : string_sub(p,"%a", remote_arch); break;
3696 sprintf(pidstr,"%d",(int)getpid());
3697 string_sub(p,"%d", pidstr);
3700 case 'h' : string_sub(p,"%h", myhostname); break;
3701 case 'm' : string_sub(p,"%m", remote_machine); break;
3702 case 'v' : string_sub(p,"%v", VERSION); break;
3703 case '\0': p++; break; /* don't run off end if last character is % */
3704 default : p+=2; break;
3710 /*******************************************************************
3711 are two IPs on the same subnet?
3712 ********************************************************************/
3713 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3715 uint32 net1,net2,nmask;
3717 nmask = ntohl(mask.s_addr);
3718 net1 = ntohl(ip1.s_addr);
3719 net2 = ntohl(ip2.s_addr);
3721 return((net1 & nmask) == (net2 & nmask));
3725 /*******************************************************************
3726 write a string in unicoode format
3727 ********************************************************************/
3728 int PutUniCode(char *dst,char *src)
3732 dst[ret++] = src[0];
3741 /****************************************************************************
3742 a wrapper for gethostbyname() that tries with all lower and all upper case
3743 if the initial name fails
3744 ****************************************************************************/
3745 struct hostent *Get_Hostbyname(char *name)
3747 char *name2 = strdup(name);
3748 struct hostent *ret;
3752 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3756 if (!isalnum(*name2))
3762 ret = sys_gethostbyname(name2);
3769 /* try with all lowercase */
3771 ret = sys_gethostbyname(name2);
3778 /* try with all uppercase */
3780 ret = sys_gethostbyname(name2);
3787 /* nothing works :-( */
3793 /****************************************************************************
3794 check if a process exists. Does this work on all unixes?
3795 ****************************************************************************/
3796 BOOL process_exists(int pid)
3800 sprintf(s,"/proc/%d",pid);
3801 return(directory_exist(s,NULL));
3804 static BOOL tested=False;
3805 static BOOL ok=False;
3809 sprintf(s,"/proc/%05d",(int)getpid());
3810 ok = file_exist(s,NULL);
3813 sprintf(s,"/proc/%05d",pid);
3814 return(file_exist(s,NULL));
3818 /* CGH 8/16/96 - added ESRCH test */
3819 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3824 /*******************************************************************
3825 turn a uid into a user name
3826 ********************************************************************/
3827 char *uidtoname(int uid)
3829 static char name[40];
3830 struct passwd *pass = getpwuid(uid);
3831 if (pass) return(pass->pw_name);
3832 sprintf(name,"%d",uid);
3836 /*******************************************************************
3837 turn a gid into a group name
3838 ********************************************************************/
3839 char *gidtoname(int gid)
3841 static char name[40];
3842 struct group *grp = getgrgid(gid);
3843 if (grp) return(grp->gr_name);
3844 sprintf(name,"%d",gid);
3848 /*******************************************************************
3850 ********************************************************************/
3851 void BlockSignals(BOOL block,int signum)
3854 int block_mask = sigmask(signum);
3855 static int oldmask = 0;
3857 oldmask = sigblock(block_mask);
3859 sigsetmask(oldmask);
3860 #elif defined(USE_SIGPROCMASK)
3863 sigaddset(&set,signum);
3864 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3869 /*******************************************************************
3870 my own panic function - not suitable for general use
3871 ********************************************************************/
3872 void ajt_panic(void)
3874 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3879 #define DIRECT direct
3881 #define DIRECT dirent
3884 /*******************************************************************
3885 a readdir wrapper which just returns the file name
3886 also return the inode number if requested
3887 ********************************************************************/
3888 char *readdirname(void *p)
3893 if (!p) return(NULL);
3895 ptr = (struct DIRECT *)readdir(p);
3896 if (!ptr) return(NULL);
3898 dname = ptr->d_name;
3901 if (telldir(p) < 0) return(NULL);
3905 /* this handles a broken compiler setup, causing a mixture
3906 of BSD and SYSV headers and libraries */
3908 static BOOL broken_readdir = False;
3909 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3911 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3912 broken_readdir = True;
3921 pstrcpy(buf, dname);
3922 unix_to_dos(buf, True);
3929 /*******************************************************************
3930 Utility function used to decide if the last component
3931 of a path matches a (possibly wildcarded) entry in a namelist.
3932 ********************************************************************/
3934 BOOL is_in_path(char *name, name_compare_entry *namelist)
3936 pstring last_component;
3939 DEBUG(8, ("is_in_path: %s\n", name));
3941 /* if we have no list it's obviously not in the path */
3942 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3944 DEBUG(8,("is_in_path: no name list.\n"));
3948 /* Get the last component of the unix name. */
3949 p = strrchr(name, '/');
3950 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3951 last_component[sizeof(last_component)-1] = '\0';
3953 for(; namelist->name != NULL; namelist++)
3955 if(namelist->is_wild)
3957 /* look for a wildcard match. */
3958 if (mask_match(last_component, namelist->name, case_sensitive, False))
3960 DEBUG(8,("is_in_path: mask match succeeded\n"));
3966 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3967 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3969 DEBUG(8,("is_in_path: match succeeded\n"));
3974 DEBUG(8,("is_in_path: match not found\n"));
3979 /*******************************************************************
3980 Strip a '/' separated list into an array of
3981 name_compare_enties structures suitable for
3982 passing to is_in_path(). We do this for
3983 speed so we can pre-parse all the names in the list
3984 and don't do it for each call to is_in_path().
3985 namelist is modified here and is assumed to be
3986 a copy owned by the caller.
3987 We also check if the entry contains a wildcard to
3988 remove a potentially expensive call to mask_match
3990 ********************************************************************/
3992 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3995 char *nameptr = namelist;
3996 int num_entries = 0;
3999 (*ppname_array) = NULL;
4001 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4004 /* We need to make two passes over the string. The
4005 first to count the number of elements, the second
4010 if ( *nameptr == '/' )
4012 /* cope with multiple (useless) /s) */
4016 /* find the next / */
4017 name_end = strchr(nameptr, '/');
4019 /* oops - the last check for a / didn't find one. */
4020 if (name_end == NULL)
4023 /* next segment please */
4024 nameptr = name_end + 1;
4028 if(num_entries == 0)
4031 if(( (*ppname_array) = (name_compare_entry *)malloc(
4032 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4034 DEBUG(0,("set_namearray: malloc fail\n"));
4038 /* Now copy out the names */
4043 if ( *nameptr == '/' )
4045 /* cope with multiple (useless) /s) */
4049 /* find the next / */
4050 if ((name_end = strchr(nameptr, '/')) != NULL)
4055 /* oops - the last check for a / didn't find one. */
4056 if(name_end == NULL)
4059 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4060 (strchr( nameptr, '*')!=NULL));
4061 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4063 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4067 /* next segment please */
4068 nameptr = name_end + 1;
4072 (*ppname_array)[i].name = NULL;
4077 /****************************************************************************
4078 routine to free a namearray.
4079 ****************************************************************************/
4081 void free_namearray(name_compare_entry *name_array)
4086 if(name_array->name != NULL)
4087 free(name_array->name);
4089 free((char *)name_array);
4092 /****************************************************************************
4093 routine to do file locking
4094 ****************************************************************************/
4095 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4102 uint32 mask = 0xC0000000;
4104 /* make sure the count is reasonable, we might kill the lockd otherwise */
4107 /* the offset is often strange - remove 2 of its bits if either of
4108 the top two bits are set. Shift the top ones by two bits. This
4109 still allows OLE2 apps to operate, but should stop lockd from
4111 if ((offset & mask) != 0)
4112 offset = (offset & ~mask) | ((offset & mask) >> 2);
4114 uint32 mask = ((unsigned)1<<31);
4116 /* interpret negative counts as large numbers */
4120 /* no negative offsets */
4123 /* count + offset must be in range */
4124 while ((offset < 0 || (offset + count < 0)) && mask)
4132 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4135 lock.l_whence = SEEK_SET;
4136 lock.l_start = (int)offset;
4137 lock.l_len = (int)count;
4142 ret = fcntl(fd,op,&lock);
4145 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4151 (lock.l_type != F_UNLCK) &&
4152 (lock.l_pid != 0) &&
4153 (lock.l_pid != getpid()))
4155 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4159 /* it must be not locked or locked by me */
4163 /* a lock set or unset */
4166 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4167 offset,count,op,type,strerror(errno)));
4169 /* perhaps it doesn't support this sort of locking?? */
4170 if (errno == EINVAL)
4172 DEBUG(3,("locking not supported? returning True\n"));
4179 /* everything went OK */
4180 DEBUG(8,("Lock call successful\n"));
4188 /*******************************************************************
4189 lock a file - returning a open file descriptor or -1 on failure
4190 The timeout is in seconds. 0 means no timeout
4191 ********************************************************************/
4192 int file_lock(char *name,int timeout)
4194 int fd = open(name,O_RDWR|O_CREAT,0666);
4196 if (fd < 0) return(-1);
4199 if (timeout) t = time(NULL);
4200 while (!timeout || (time(NULL)-t < timeout)) {
4201 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4202 msleep(LOCK_RETRY_TIMEOUT);
4210 /*******************************************************************
4211 unlock a file locked by file_lock
4212 ********************************************************************/
4213 void file_unlock(int fd)
4217 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4222 /*******************************************************************
4223 is the name specified one of my netbios names
4224 returns true is it is equal, false otherwise
4225 ********************************************************************/
4226 BOOL is_myname(char *s)
4231 for (n=0; my_netbios_names[n]; n++) {
4232 if (strequal(my_netbios_names[n], s))
4235 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4239 /*******************************************************************
4240 set the horrid remote_arch string based on an enum.
4241 ********************************************************************/
4242 void set_remote_arch(enum remote_arch_types type)
4248 strcpy(remote_arch, "WfWg");
4251 strcpy(remote_arch, "OS2");
4254 strcpy(remote_arch, "Win95");
4257 strcpy(remote_arch, "WinNT");
4260 strcpy(remote_arch,"Samba");
4263 ra_type = RA_UNKNOWN;
4264 strcpy(remote_arch, "UNKNOWN");
4269 /*******************************************************************
4270 Get the remote_arch type.
4271 ********************************************************************/
4272 enum remote_arch_types get_remote_arch()
4278 /*******************************************************************
4279 skip past some unicode strings in a buffer
4280 ********************************************************************/
4281 char *skip_unicode_string(char *buf,int n)
4292 /*******************************************************************
4293 Return a ascii version of a unicode string
4294 Hack alert: uses fixed buffer(s) and only handles ascii strings
4295 ********************************************************************/
4297 char *unistr2(uint16 *buf)
4299 static char lbufs[8][MAXUNI];
4301 char *lbuf = lbufs[nexti];
4303 nexti = (nexti+1)%8;
4304 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4312 /*******************************************************************
4313 Return a ascii version of a unicode string
4314 Hack alert: uses fixed buffer(s) and only handles ascii strings
4315 ********************************************************************/
4317 char *unistr(char *buf)
4319 static char lbufs[8][MAXUNI];
4321 char *lbuf = lbufs[nexti];
4324 nexti = (nexti+1)%8;
4326 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4334 /*******************************************************************
4335 strncpy for unicode strings
4336 ********************************************************************/
4337 int unistrncpy(char *dst, char *src, int len)
4341 while (*src && len > 0)
4355 /*******************************************************************
4356 strcpy for unicode strings. returns length (in num of wide chars)
4357 ********************************************************************/
4358 int unistrcpy(char *dst, char *src)
4375 /*******************************************************************
4376 safe string copy into a fstring
4377 ********************************************************************/
4378 void fstrcpy(char *dest, char *src)
4380 int maxlength = sizeof(fstring) - 1;
4382 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4391 while (maxlength-- && *src)
4395 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4400 /*******************************************************************
4401 safe string copy into a pstring
4402 ********************************************************************/
4403 void pstrcpy(char *dest, char *src)
4405 int maxlength = sizeof(pstring) - 1;
4407 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4416 while (maxlength-- && *src)
4420 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4426 /*******************************************************************
4427 align a pointer to a multiple of 4 bytes
4428 ********************************************************************/
4429 char *align4(char *q, char *base)
4433 q += 4 - ((q - base) & 3);
4438 /*******************************************************************
4439 align a pointer to a multiple of 2 bytes
4440 ********************************************************************/
4441 char *align2(char *q, char *base)
4450 /*******************************************************************
4451 align a pointer to a multiple of align_offset bytes. looks like it
4452 will work for offsets of 0, 2 and 4...
4453 ********************************************************************/
4454 char *align_offset(char *q, char *base, int align_offset_len)
4456 int mod = ((q - base) & (align_offset_len-1));
4457 if (align_offset_len != 0 && mod != 0)
4459 q += align_offset_len - mod;
4464 static void print_asc(int level, unsigned char *buf,int len)
4468 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4471 void dump_data(int level,char *buf1,int len)
4473 unsigned char *buf = (unsigned char *)buf1;
4477 DEBUG(level,("[%03X] ",i));
4479 DEBUG(level,("%02X ",(int)buf[i]));
4481 if (i%8 == 0) DEBUG(level,(" "));
4483 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4484 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4485 if (i<len) DEBUG(level,("[%03X] ",i));
4493 if (n>8) DEBUG(level,(" "));
4494 while (n--) DEBUG(level,(" "));
4497 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4499 if (n>0) print_asc(level,&buf[i-n],n);
4500 DEBUG(level,("\n"));
4504 char *tab_depth(int depth)
4506 static pstring spaces;
4507 memset(spaces, ' ', depth * 4);
4508 spaces[depth * 4] = 0;
4513 /* array lookup of well-known RID aliases. the purpose of these escapes me.. */
4521 { DOMAIN_ALIAS_RID_ADMINS , "admins" },
4522 { DOMAIN_ALIAS_RID_USERS , "users" },
4523 { DOMAIN_ALIAS_RID_GUESTS , "guests" },
4524 { DOMAIN_ALIAS_RID_POWER_USERS , "power_users" },
4526 { DOMAIN_ALIAS_RID_ACCOUNT_OPS , "account_ops" },
4527 { DOMAIN_ALIAS_RID_SYSTEM_OPS , "system_ops" },
4528 { DOMAIN_ALIAS_RID_PRINT_OPS , "print_ops" },
4529 { DOMAIN_ALIAS_RID_BACKUP_OPS , "backup_ops" },
4530 { DOMAIN_ALIAS_RID_REPLICATOR , "replicator" },
4534 int make_domain_gids(char *gids_str, DOM_GID *gids)
4540 DEBUG(4,("make_domain_gids: %s\n", gids_str));
4542 if (gids_str == NULL || *gids_str == 0) return 0;
4544 for (count = 0, ptr = gids_str; next_token(&ptr, s2, NULL) && count < LSA_MAX_GROUPS; count++)
4546 /* the entries are of the form GID/ATTR, ATTR being optional.*/
4551 attr = strchr(s2,'/');
4552 if (attr) *attr++ = 0;
4553 if (!attr || !*attr) attr = "7"; /* default value for attribute is 7 */
4555 /* look up the RID string and see if we can turn it into a rid number */
4556 for (i = 0; rid_lookups[i].rid_name != NULL; i++)
4558 if (strequal(rid_lookups[i].rid_name, s2))
4560 rid = rid_lookups[i].rid;
4565 if (rid == 0) rid = atoi(s2);
4567 gids[count].gid = rid;
4568 gids[count].attr = atoi(attr);
4570 DEBUG(5,("group id: %d attr: %d\n", gids[count].gid, gids[count].attr));