2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
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);
96 /**************************************************************************** **
97 catch a sigusr2 - decrease the debug log level.
98 **************************************************************************** */
101 BlockSignals( True, SIGUSR2);
108 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
110 BlockSignals( False, SIGUSR2);
111 #ifndef DONT_REINSTALL_SIG
112 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
119 /**************************************************************************** **
120 catch a sigusr1 - increase the debug log level.
121 **************************************************************************** */
124 BlockSignals( True, SIGUSR1);
131 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
133 BlockSignals( False, SIGUSR1);
134 #ifndef DONT_REINSTALL_SIG
135 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
142 /*******************************************************************
143 get ready for syslog stuff
144 ******************************************************************/
145 void setup_logging(char *pname,BOOL interactive)
149 char *p = strrchr(pname,'/');
152 openlog(pname, LOG_PID, SYSLOG_FACILITY);
153 #else /* for old systems that have no facility codes. */
154 openlog(pname, LOG_PID);
159 stdout_logging = True;
165 BOOL append_log=False;
168 /****************************************************************************
170 ****************************************************************************/
171 void reopen_logs(void)
177 strcpy(fname,debugf);
178 if (lp_loaded() && (*lp_logfile()))
179 strcpy(fname,lp_logfile());
181 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
183 int oldumask = umask(022);
184 strcpy(debugf,fname);
185 if (dbf) fclose(dbf);
187 dbf = fopen(debugf,"a");
189 dbf = fopen(debugf,"w");
190 if (dbf) setbuf(dbf,NULL);
205 /*******************************************************************
206 check if the log has grown too big
207 ********************************************************************/
208 static void check_log_size(void)
210 static int debug_count=0;
214 if (debug_count++ < 100 || getuid() != 0) return;
216 maxlog = lp_max_log_size() * 1024;
217 if (!dbf || maxlog <= 0) return;
219 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
220 fclose(dbf); dbf = NULL;
222 if (dbf && file_size(debugf) > maxlog) {
224 fclose(dbf); dbf = NULL;
225 sprintf(name,"%s.old",debugf);
226 sys_rename(debugf,name);
234 /*******************************************************************
235 write an debug message on the debugfile. This is called by the DEBUG
237 ********************************************************************/
239 int Debug1(char *format_str, ...)
248 int old_errno = errno;
250 if (stdout_logging) {
252 va_start(ap, format_str);
255 format_str = va_arg(ap,char *);
257 vfprintf(dbf,format_str,ap);
264 if (!lp_syslog_only())
268 int oldumask = umask(022);
269 dbf = fopen(debugf,"w");
281 if (syslog_level < lp_syslog())
284 * map debug levels to syslog() priorities
285 * note that not all DEBUG(0, ...) calls are
288 static int priority_map[] = {
297 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
299 priority = LOG_DEBUG;
301 priority = priority_map[syslog_level];
304 va_start(ap, format_str);
307 format_str = va_arg(ap,char *);
309 vsprintf(msgbuf, format_str, ap);
313 syslog(priority, "%s", msgbuf);
318 if (!lp_syslog_only())
322 va_start(ap, format_str);
325 format_str = va_arg(ap,char *);
327 vfprintf(dbf,format_str,ap);
339 /****************************************************************************
340 find a suitable temporary directory. The result should be copied immediately
341 as it may be overwritten by a subsequent call
342 ****************************************************************************/
346 if ((p = getenv("TMPDIR"))) {
354 /****************************************************************************
355 determine if a file descriptor is in fact a socket
356 ****************************************************************************/
357 BOOL is_a_socket(int fd)
361 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
365 static char *last_ptr=NULL;
367 /****************************************************************************
368 Get the next token from a string, return False if none found
369 handles double-quotes.
370 Based on a routine by GJC@VILLAGE.COM.
371 Extensively modified by Andrew.Tridgell@anu.edu.au
372 ****************************************************************************/
373 BOOL next_token(char **ptr,char *buff,char *sep)
378 if (!ptr) ptr = &last_ptr;
379 if (!ptr) return(False);
383 /* default to simple separators */
384 if (!sep) sep = " \t\n\r";
386 /* find the first non sep char */
387 while(*s && strchr(sep,*s)) s++;
390 if (! *s) return(False);
392 /* copy over the token */
393 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
401 *ptr = (*s) ? s+1 : s;
408 /****************************************************************************
409 Convert list of tokens to array; dependent on above routine.
410 Uses last_ptr from above - bit of a hack.
411 ****************************************************************************/
412 char **toktocliplist(int *ctok, char *sep)
418 if (!sep) sep = " \t\n\r";
420 while(*s && strchr(sep,*s)) s++;
423 if (!*s) return(NULL);
427 while(*s && (!strchr(sep,*s))) s++;
428 while(*s && strchr(sep,*s)) *s++=0;
434 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
446 /*******************************************************************
447 safely copies memory, ensuring no overlap problems.
448 this is only used if the machine does not have it's own memmove().
449 this is not the fastest algorithm in town, but it will do for our
451 ********************************************************************/
452 void *MemMove(void *dest,void *src,int size)
456 if (dest==src || !size) return(dest);
458 d = (unsigned long)dest;
459 s = (unsigned long)src;
461 if ((d >= (s+size)) || (s >= (d+size))) {
463 memcpy(dest,src,size);
469 /* we can forward copy */
470 if (s-d >= sizeof(int) &&
471 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
472 /* do it all as words */
473 int *idest = (int *)dest;
474 int *isrc = (int *)src;
476 for (i=0;i<size;i++) idest[i] = isrc[i];
479 char *cdest = (char *)dest;
480 char *csrc = (char *)src;
481 for (i=0;i<size;i++) cdest[i] = csrc[i];
486 /* must backward copy */
487 if (d-s >= sizeof(int) &&
488 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
489 /* do it all as words */
490 int *idest = (int *)dest;
491 int *isrc = (int *)src;
493 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
496 char *cdest = (char *)dest;
497 char *csrc = (char *)src;
498 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
506 /****************************************************************************
507 prompte a dptr (to make it recently used)
508 ****************************************************************************/
509 void array_promote(char *array,int elsize,int element)
515 p = (char *)malloc(elsize);
519 DEBUG(5,("Ahh! Can't malloc\n"));
522 memcpy(p,array + element * elsize, elsize);
523 memmove(array + elsize,array,elsize*element);
524 memcpy(array,p,elsize);
528 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
537 } socket_options[] = {
538 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
539 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
540 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
542 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
544 #ifdef IPTOS_LOWDELAY
545 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
547 #ifdef IPTOS_THROUGHPUT
548 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
551 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
554 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
557 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
560 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
563 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
566 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
572 /****************************************************************************
573 set user socket options
574 ****************************************************************************/
575 void set_socket_options(int fd, char *options)
579 while (next_token(&options,tok," \t,"))
584 BOOL got_value = False;
586 if ((p = strchr(tok,'=')))
593 for (i=0;socket_options[i].name;i++)
594 if (strequal(socket_options[i].name,tok))
597 if (!socket_options[i].name)
599 DEBUG(0,("Unknown socket option %s\n",tok));
603 switch (socket_options[i].opttype)
607 ret = setsockopt(fd,socket_options[i].level,
608 socket_options[i].option,(char *)&value,sizeof(int));
613 DEBUG(0,("syntax error - %s does not take a value\n",tok));
616 int on = socket_options[i].value;
617 ret = setsockopt(fd,socket_options[i].level,
618 socket_options[i].option,(char *)&on,sizeof(int));
624 DEBUG(0,("Failed to set socket option %s\n",tok));
630 /****************************************************************************
631 close the socket communication
632 ****************************************************************************/
633 void close_sockets(void )
639 /****************************************************************************
640 determine whether we are in the specified group
641 ****************************************************************************/
642 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
646 if (group == current_gid) return(True);
648 for (i=0;i<ngroups;i++)
649 if (group == groups[i])
655 /****************************************************************************
656 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
657 ****************************************************************************/
658 char *StrCpy(char *dest,char *src)
663 /* I don't want to get lazy with these ... */
665 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
670 if (!dest) return(NULL);
675 while ((*d++ = *src++)) ;
679 /****************************************************************************
680 line strncpy but always null terminates. Make sure there is room!
681 ****************************************************************************/
682 char *StrnCpy(char *dest,char *src,int n)
685 if (!dest) return(NULL);
690 while (n-- && (*d++ = *src++)) ;
696 /*******************************************************************
697 copy an IP address from one buffer to another
698 ********************************************************************/
699 void putip(void *dest,void *src)
705 /****************************************************************************
706 interpret the weird netbios "name". Return the name type
707 ****************************************************************************/
708 static int name_interpret(char *in,char *out)
711 int len = (*in++) / 2;
715 if (len > 30 || len<1) return(0);
719 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
723 *out = ((in[0]-'A')<<4) + (in[1]-'A');
731 /* Handle any scope names */
734 *out++ = '.'; /* Scope names are separated by periods */
735 len = *(unsigned char *)in++;
736 StrnCpy(out, in, len);
745 /****************************************************************************
746 mangle a name into netbios format
748 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
749 ****************************************************************************/
750 int name_mangle( char *In, char *Out, char name_type )
758 /* Safely copy the input string, In, into buf[]. */
759 (void)memset( buf, 0, 20 );
763 (void)sprintf( buf, "%-15.15s%c", In, name_type );
765 /* Place the length of the first field into the output buffer. */
769 /* Now convert the name to the rfc1001/1002 format. */
770 for( i = 0; i < 16; i++ )
772 c = toupper( buf[i] );
773 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
774 p[(i*2)+1] = (c & 0x000F) + 'A';
779 /* Add the scope string. */
780 for( i = 0, len = 0; NULL != scope; i++, len++ )
788 return( name_len(Out) );
800 return( name_len(Out) );
803 /*******************************************************************
804 check if a file exists
805 ********************************************************************/
806 BOOL file_exist(char *fname,struct stat *sbuf)
809 if (!sbuf) sbuf = &st;
811 if (sys_stat(fname,sbuf) != 0)
814 return(S_ISREG(sbuf->st_mode));
817 /*******************************************************************
818 check a files mod time
819 ********************************************************************/
820 time_t file_modtime(char *fname)
824 if (sys_stat(fname,&st) != 0)
830 /*******************************************************************
831 check if a directory exists
832 ********************************************************************/
833 BOOL directory_exist(char *dname,struct stat *st)
840 if (sys_stat(dname,st) != 0)
843 ret = S_ISDIR(st->st_mode);
849 /*******************************************************************
850 returns the size in bytes of the named file
851 ********************************************************************/
852 uint32 file_size(char *file_name)
856 sys_stat(file_name,&buf);
860 /*******************************************************************
861 return a string representing an attribute for a file
862 ********************************************************************/
863 char *attrib_string(int mode)
865 static char attrstr[10];
869 if (mode & aVOLID) strcat(attrstr,"V");
870 if (mode & aDIR) strcat(attrstr,"D");
871 if (mode & aARCH) strcat(attrstr,"A");
872 if (mode & aHIDDEN) strcat(attrstr,"H");
873 if (mode & aSYSTEM) strcat(attrstr,"S");
874 if (mode & aRONLY) strcat(attrstr,"R");
880 /*******************************************************************
881 case insensitive string compararison
882 ********************************************************************/
883 int StrCaseCmp(char *s, char *t)
885 /* compare until we run out of string, either t or s, or find a difference */
886 /* We *must* use toupper rather than tolower here due to the
887 asynchronous upper to lower mapping.
889 #if !defined(KANJI_WIN95_COMPATIBILITY)
891 * For completeness we should put in equivalent code for code pages
892 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
893 * doubt anyone wants Samba to behave differently from Win95 and WinNT
894 * here. They both treat full width ascii characters as case senstive
895 * filenames (ie. they don't do the work we do here).
899 if(lp_client_code_page() == KANJI_CODEPAGE)
901 /* Win95 treats full width ascii characters as case sensitive. */
906 return toupper (*s) - toupper (*t);
907 else if (is_sj_alph (*s) && is_sj_alph (*t))
909 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
915 else if (is_shift_jis (*s) && is_shift_jis (*t))
917 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
920 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
926 else if (is_shift_jis (*s))
928 else if (is_shift_jis (*t))
932 diff = toupper (*s) - toupper (*t);
941 #endif /* KANJI_WIN95_COMPATIBILITY */
943 while (*s && *t && toupper(*s) == toupper(*t))
949 return(toupper(*s) - toupper(*t));
953 /*******************************************************************
954 case insensitive string compararison, length limited
955 ********************************************************************/
956 int StrnCaseCmp(char *s, char *t, int n)
958 /* compare until we run out of string, either t or s, or chars */
959 /* We *must* use toupper rather than tolower here due to the
960 asynchronous upper to lower mapping.
962 #if !defined(KANJI_WIN95_COMPATIBILITY)
964 * For completeness we should put in equivalent code for code pages
965 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
966 * doubt anyone wants Samba to behave differently from Win95 and WinNT
967 * here. They both treat full width ascii characters as case senstive
968 * filenames (ie. they don't do the work we do here).
972 if(lp_client_code_page() == KANJI_CODEPAGE)
974 /* Win95 treats full width ascii characters as case sensitive. */
979 return toupper (*s) - toupper (*t);
980 else if (is_sj_alph (*s) && is_sj_alph (*t))
982 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
989 else if (is_shift_jis (*s) && is_shift_jis (*t))
991 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
994 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1001 else if (is_shift_jis (*s))
1003 else if (is_shift_jis (*t))
1007 diff = toupper (*s) - toupper (*t);
1018 #endif /* KANJI_WIN95_COMPATIBILITY */
1020 while (n && *s && *t && toupper(*s) == toupper(*t))
1027 /* not run out of chars - strings are different lengths */
1029 return(toupper(*s) - toupper(*t));
1031 /* identical up to where we run out of chars,
1032 and strings are same length */
1037 /*******************************************************************
1039 ********************************************************************/
1040 BOOL strequal(char *s1, char *s2)
1042 if (s1 == s2) return(True);
1043 if (!s1 || !s2) return(False);
1045 return(StrCaseCmp(s1,s2)==0);
1048 /*******************************************************************
1049 compare 2 strings up to and including the nth char.
1050 ******************************************************************/
1051 BOOL strnequal(char *s1,char *s2,int n)
1053 if (s1 == s2) return(True);
1054 if (!s1 || !s2 || !n) return(False);
1056 return(StrnCaseCmp(s1,s2,n)==0);
1059 /*******************************************************************
1060 compare 2 strings (case sensitive)
1061 ********************************************************************/
1062 BOOL strcsequal(char *s1,char *s2)
1064 if (s1 == s2) return(True);
1065 if (!s1 || !s2) return(False);
1067 return(strcmp(s1,s2)==0);
1071 /*******************************************************************
1072 convert a string to lower case
1073 ********************************************************************/
1074 void strlower(char *s)
1078 #if !defined(KANJI_WIN95_COMPATIBILITY)
1080 * For completeness we should put in equivalent code for code pages
1081 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1082 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1083 * here. They both treat full width ascii characters as case senstive
1084 * filenames (ie. they don't do the work we do here).
1088 if(lp_client_code_page() == KANJI_CODEPAGE)
1090 /* Win95 treats full width ascii characters as case sensitive. */
1091 if (is_shift_jis (*s))
1093 if (is_sj_upper (s[0], s[1]))
1094 s[1] = sj_tolower2 (s[1]);
1097 else if (is_kana (*s))
1109 #endif /* KANJI_WIN95_COMPATIBILITY */
1118 /*******************************************************************
1119 convert a string to upper case
1120 ********************************************************************/
1121 void strupper(char *s)
1125 #if !defined(KANJI_WIN95_COMPATIBILITY)
1127 * For completeness we should put in equivalent code for code pages
1128 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1129 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1130 * here. They both treat full width ascii characters as case senstive
1131 * filenames (ie. they don't do the work we do here).
1135 if(lp_client_code_page() == KANJI_CODEPAGE)
1137 /* Win95 treats full width ascii characters as case sensitive. */
1138 if (is_shift_jis (*s))
1140 if (is_sj_lower (s[0], s[1]))
1141 s[1] = sj_toupper2 (s[1]);
1144 else if (is_kana (*s))
1156 #endif /* KANJI_WIN95_COMPATIBILITY */
1165 /*******************************************************************
1166 convert a string to "normal" form
1167 ********************************************************************/
1168 void strnorm(char *s)
1170 if (case_default == CASE_UPPER)
1176 /*******************************************************************
1177 check if a string is in "normal" case
1178 ********************************************************************/
1179 BOOL strisnormal(char *s)
1181 if (case_default == CASE_UPPER)
1182 return(!strhaslower(s));
1184 return(!strhasupper(s));
1188 /****************************************************************************
1190 ****************************************************************************/
1191 void string_replace(char *s,char oldc,char newc)
1195 #if !defined(KANJI_WIN95_COMPATIBILITY)
1197 * For completeness we should put in equivalent code for code pages
1198 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1199 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1200 * here. They both treat full width ascii characters as case senstive
1201 * filenames (ie. they don't do the work we do here).
1205 if(lp_client_code_page() == KANJI_CODEPAGE)
1207 /* Win95 treats full width ascii characters as case sensitive. */
1208 if (is_shift_jis (*s))
1210 else if (is_kana (*s))
1220 #endif /* KANJI_WIN95_COMPATIBILITY */
1229 /****************************************************************************
1230 make a file into unix format
1231 ****************************************************************************/
1232 void unix_format(char *fname)
1235 string_replace(fname,'\\','/');
1239 pstrcpy(namecopy,fname);
1241 strcat(fname,namecopy);
1245 /****************************************************************************
1246 make a file into dos format
1247 ****************************************************************************/
1248 void dos_format(char *fname)
1250 string_replace(fname,'/','\\');
1254 /*******************************************************************
1255 show a smb message structure
1256 ********************************************************************/
1257 void show_msg(char *buf)
1262 if (DEBUGLEVEL < 5) return;
1264 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1266 (int)CVAL(buf,smb_com),
1267 (int)CVAL(buf,smb_rcls),
1268 (int)CVAL(buf,smb_reh),
1269 (int)SVAL(buf,smb_err),
1270 (int)CVAL(buf,smb_flg),
1271 (int)SVAL(buf,smb_flg2)));
1272 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1273 (int)SVAL(buf,smb_tid),
1274 (int)SVAL(buf,smb_pid),
1275 (int)SVAL(buf,smb_uid),
1276 (int)SVAL(buf,smb_mid),
1277 (int)CVAL(buf,smb_wct)));
1279 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1280 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1281 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1283 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1284 DEBUG(5,("smb_bcc=%d\n",bcc));
1286 if (DEBUGLEVEL < 10) return;
1288 dump_data(10, smb_buf(buf), MIN(bcc, 512));
1291 /*******************************************************************
1292 return the length of an smb packet
1293 ********************************************************************/
1294 int smb_len(char *buf)
1296 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1299 /*******************************************************************
1300 set the length of an smb packet
1301 ********************************************************************/
1302 void _smb_setlen(char *buf,int len)
1305 buf[1] = (len&0x10000)>>16;
1306 buf[2] = (len&0xFF00)>>8;
1310 /*******************************************************************
1311 set the length and marker of an smb packet
1312 ********************************************************************/
1313 void smb_setlen(char *buf,int len)
1315 _smb_setlen(buf,len);
1323 /*******************************************************************
1324 setup the word count and byte count for a smb message
1325 ********************************************************************/
1326 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1329 bzero(buf + smb_size,num_words*2 + num_bytes);
1330 CVAL(buf,smb_wct) = num_words;
1331 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1332 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1333 return (smb_size + num_words*2 + num_bytes);
1336 /*******************************************************************
1337 return the number of smb words
1338 ********************************************************************/
1339 int smb_numwords(char *buf)
1341 return (CVAL(buf,smb_wct));
1344 /*******************************************************************
1345 return the size of the smb_buf region of a message
1346 ********************************************************************/
1347 int smb_buflen(char *buf)
1349 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1352 /*******************************************************************
1353 return a pointer to the smb_buf data area
1354 ********************************************************************/
1355 int smb_buf_ofs(char *buf)
1357 return (smb_size + CVAL(buf,smb_wct)*2);
1360 /*******************************************************************
1361 return a pointer to the smb_buf data area
1362 ********************************************************************/
1363 char *smb_buf(char *buf)
1365 return (buf + smb_buf_ofs(buf));
1368 /*******************************************************************
1369 return the SMB offset into an SMB buffer
1370 ********************************************************************/
1371 int smb_offset(char *p,char *buf)
1373 return(PTR_DIFF(p,buf+4) + chain_size);
1377 /*******************************************************************
1378 skip past some strings in a buffer
1379 ********************************************************************/
1380 char *skip_string(char *buf,int n)
1383 buf += strlen(buf) + 1;
1387 /*******************************************************************
1388 trim the specified elements off the front and back of a string
1389 ********************************************************************/
1390 BOOL trim_string(char *s,char *front,char *back)
1393 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1399 if (!(*p = p[strlen(front)]))
1404 while (back && *back && strlen(s) >= strlen(back) &&
1405 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1408 s[strlen(s)-strlen(back)] = 0;
1414 /*******************************************************************
1415 reduce a file name, removing .. elements.
1416 ********************************************************************/
1417 void dos_clean_name(char *s)
1421 DEBUG(3,("dos_clean_name [%s]\n",s));
1423 /* remove any double slashes */
1424 string_sub(s, "\\\\", "\\");
1426 while ((p = strstr(s,"\\..\\")) != NULL)
1433 if ((p=strrchr(s,'\\')) != NULL)
1440 trim_string(s,NULL,"\\..");
1442 string_sub(s, "\\.\\", "\\");
1445 /*******************************************************************
1446 reduce a file name, removing .. elements.
1447 ********************************************************************/
1448 void unix_clean_name(char *s)
1452 DEBUG(3,("unix_clean_name [%s]\n",s));
1454 /* remove any double slashes */
1455 string_sub(s, "//","/");
1457 /* Remove leading ./ characters */
1458 if(strncmp(s, "./", 2) == 0) {
1459 trim_string(s, "./", NULL);
1464 while ((p = strstr(s,"/../")) != NULL)
1471 if ((p=strrchr(s,'/')) != NULL)
1478 trim_string(s,NULL,"/..");
1482 /*******************************************************************
1483 a wrapper for the normal chdir() function
1484 ********************************************************************/
1485 int ChDir(char *path)
1488 static pstring LastDir="";
1490 if (strcsequal(path,".")) return(0);
1492 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1493 DEBUG(3,("chdir to %s\n",path));
1494 res = sys_chdir(path);
1496 pstrcpy(LastDir,path);
1500 /* number of list structures for a caching GetWd function. */
1501 #define MAX_GETWDCACHE (50)
1509 } ino_list[MAX_GETWDCACHE];
1511 BOOL use_getwd_cache=True;
1513 /*******************************************************************
1514 return the absolute current directory path
1515 ********************************************************************/
1516 char *GetWd(char *str)
1519 static BOOL getwd_cache_init = False;
1520 struct stat st, st2;
1525 if (!use_getwd_cache)
1526 return(sys_getwd(str));
1528 /* init the cache */
1529 if (!getwd_cache_init)
1531 getwd_cache_init = True;
1532 for (i=0;i<MAX_GETWDCACHE;i++)
1534 string_init(&ino_list[i].text,"");
1535 ino_list[i].valid = False;
1539 /* Get the inode of the current directory, if this doesn't work we're
1542 if (stat(".",&st) == -1)
1544 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1545 return(sys_getwd(str));
1549 for (i=0; i<MAX_GETWDCACHE; i++)
1550 if (ino_list[i].valid)
1553 /* If we have found an entry with a matching inode and dev number
1554 then find the inode number for the directory in the cached string.
1555 If this agrees with that returned by the stat for the current
1556 directory then all is o.k. (but make sure it is a directory all
1559 if (st.st_ino == ino_list[i].inode &&
1560 st.st_dev == ino_list[i].dev)
1562 if (stat(ino_list[i].text,&st2) == 0)
1564 if (st.st_ino == st2.st_ino &&
1565 st.st_dev == st2.st_dev &&
1566 (st2.st_mode & S_IFMT) == S_IFDIR)
1568 strcpy (str, ino_list[i].text);
1570 /* promote it for future use */
1571 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1576 /* If the inode is different then something's changed,
1577 scrub the entry and start from scratch. */
1578 ino_list[i].valid = False;
1585 /* We don't have the information to hand so rely on traditional methods.
1586 The very slow getcwd, which spawns a process on some systems, or the
1587 not quite so bad getwd. */
1591 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1597 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1599 /* add it to the cache */
1600 i = MAX_GETWDCACHE - 1;
1601 string_set(&ino_list[i].text,s);
1602 ino_list[i].dev = st.st_dev;
1603 ino_list[i].inode = st.st_ino;
1604 ino_list[i].valid = True;
1606 /* put it at the top of the list */
1607 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1614 /*******************************************************************
1615 reduce a file name, removing .. elements and checking that
1616 it is below dir in the heirachy. This uses GetWd() and so must be run
1617 on the system that has the referenced file system.
1619 widelinks are allowed if widelinks is true
1620 ********************************************************************/
1621 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1623 #ifndef REDUCE_PATHS
1631 BOOL relative = (*s != '/');
1633 *dir2 = *wd = *base_name = *newname = 0;
1638 /* can't have a leading .. */
1639 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1641 DEBUG(3,("Illegal file name? (%s)\n",s));
1651 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1653 /* remove any double slashes */
1654 string_sub(s,"//","/");
1656 pstrcpy(base_name,s);
1657 p = strrchr(base_name,'/');
1664 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1668 if (ChDir(dir) != 0)
1670 DEBUG(0,("couldn't chdir to %s\n",dir));
1676 DEBUG(0,("couldn't getwd for %s\n",dir));
1682 if (p && (p != base_name))
1685 if (strcmp(p+1,".")==0)
1687 if (strcmp(p+1,"..")==0)
1691 if (ChDir(base_name) != 0)
1694 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1698 if (!GetWd(newname))
1701 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1705 if (p && (p != base_name))
1707 strcat(newname,"/");
1708 strcat(newname,p+1);
1712 int l = strlen(dir2);
1713 if (dir2[l-1] == '/')
1716 if (strncmp(newname,dir2,l) != 0)
1719 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1725 if (newname[l] == '/')
1726 pstrcpy(s,newname + l + 1);
1728 pstrcpy(s,newname+l);
1739 DEBUG(3,("reduced to %s\n",s));
1744 /****************************************************************************
1746 ****************************************************************************/
1747 static void expand_one(char *Mask,int len)
1750 while ((p1 = strchr(Mask,'*')) != NULL)
1752 int lfill = (len+1) - strlen(Mask);
1753 int l1= (p1 - Mask);
1756 memset(tmp+l1,'?',lfill);
1757 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1762 /****************************************************************************
1763 expand a wildcard expression, replacing *s with ?s
1764 ****************************************************************************/
1765 void expand_mask(char *Mask,BOOL doext)
1770 BOOL hasdot = False;
1772 BOOL absolute = (*Mask == '\\');
1774 *mbeg = *mext = *dirpart = *filepart = 0;
1776 /* parse the directory and filename */
1777 if (strchr(Mask,'\\'))
1778 dirname_dos(Mask,dirpart);
1780 filename_dos(Mask,filepart);
1782 pstrcpy(mbeg,filepart);
1783 if ((p1 = strchr(mbeg,'.')) != NULL)
1793 if (strlen(mbeg) > 8)
1795 pstrcpy(mext,mbeg + 8);
1801 strcpy(mbeg,"????????");
1802 if ((*mext == 0) && doext && !hasdot)
1805 if (strequal(mbeg,"*") && *mext==0)
1813 pstrcpy(Mask,dirpart);
1814 if (*dirpart || absolute) strcat(Mask,"\\");
1819 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1823 /****************************************************************************
1824 does a string have any uppercase chars in it?
1825 ****************************************************************************/
1826 BOOL strhasupper(char *s)
1830 #if !defined(KANJI_WIN95_COMPATIBILITY)
1832 * For completeness we should put in equivalent code for code pages
1833 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1834 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1835 * here. They both treat full width ascii characters as case senstive
1836 * filenames (ie. they don't do the work we do here).
1840 if(lp_client_code_page() == KANJI_CODEPAGE)
1842 /* Win95 treats full width ascii characters as case sensitive. */
1843 if (is_shift_jis (*s))
1845 else if (is_kana (*s))
1855 #endif /* KANJI_WIN95_COMPATIBILITY */
1865 /****************************************************************************
1866 does a string have any lowercase chars in it?
1867 ****************************************************************************/
1868 BOOL strhaslower(char *s)
1872 #if !defined(KANJI_WIN95_COMPATIBILITY)
1874 * For completeness we should put in equivalent code for code pages
1875 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1876 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1877 * here. They both treat full width ascii characters as case senstive
1878 * filenames (ie. they don't do the work we do here).
1882 if(lp_client_code_page() == KANJI_CODEPAGE)
1884 /* Win95 treats full width ascii characters as case sensitive. */
1885 if (is_shift_jis (*s))
1887 if (is_sj_upper (s[0], s[1]))
1889 if (is_sj_lower (s[0], s[1]))
1893 else if (is_kana (*s))
1905 #endif /* KANJI_WIN95_COMPATIBILITY */
1915 /****************************************************************************
1916 find the number of chars in a string
1917 ****************************************************************************/
1918 int count_chars(char *s,char c)
1922 #if !defined(KANJI_WIN95_COMPATIBILITY)
1924 * For completeness we should put in equivalent code for code pages
1925 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1926 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1927 * here. They both treat full width ascii characters as case senstive
1928 * filenames (ie. they don't do the work we do here).
1932 if(lp_client_code_page() == KANJI_CODEPAGE)
1934 /* Win95 treats full width ascii characters as case sensitive. */
1937 if (is_shift_jis (*s))
1948 #endif /* KANJI_WIN95_COMPATIBILITY */
1961 /****************************************************************************
1963 ****************************************************************************/
1964 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1969 pstrcpy(mask2,mask);
1971 if ((mode & aDIR) != 0)
1974 memset(buf+1,' ',11);
1975 if ((p = strchr(mask2,'.')) != NULL)
1978 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1979 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1983 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1985 bzero(buf+21,DIR_STRUCT_SIZE-21);
1986 CVAL(buf,21) = mode;
1987 put_dos_date(buf,22,date);
1988 SSVAL(buf,26,size & 0xFFFF);
1989 SSVAL(buf,28,size >> 16);
1990 StrnCpy(buf+30,fname,12);
1991 if (!case_sensitive)
1993 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1997 /*******************************************************************
1998 close the low 3 fd's and open dev/null in their place
1999 ********************************************************************/
2000 void close_low_fds(void)
2004 close(0); close(1); close(2);
2005 /* try and use up these file descriptors, so silly
2006 library routines writing to stdout etc won't cause havoc */
2008 fd = open("/dev/null",O_RDWR,0);
2009 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2011 DEBUG(0,("Can't open /dev/null\n"));
2015 DEBUG(0,("Didn't get file descriptor %d\n",i));
2021 /****************************************************************************
2022 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2024 if SYSV use O_NDELAY
2026 ****************************************************************************/
2027 int set_blocking(int fd, BOOL set)
2031 #define FLAG_TO_SET O_NONBLOCK
2034 #define FLAG_TO_SET O_NDELAY
2036 #define FLAG_TO_SET FNDELAY
2040 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2042 if(set) /* Turn blocking on - ie. clear nonblock flag */
2043 val &= ~FLAG_TO_SET;
2046 return fcntl( fd, F_SETFL, val);
2051 /****************************************************************************
2053 ****************************************************************************/
2054 int write_socket(int fd,char *buf,int len)
2060 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2061 ret = write_data(fd,buf,len);
2063 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2065 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2066 len, fd, strerror(errno) ));
2071 /****************************************************************************
2073 ****************************************************************************/
2074 int read_udp_socket(int fd,char *buf,int len)
2077 struct sockaddr_in sock;
2080 socklen = sizeof(sock);
2081 bzero((char *)&sock,socklen);
2082 bzero((char *)&lastip,sizeof(lastip));
2083 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2085 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2089 lastip = sock.sin_addr;
2090 lastport = ntohs(sock.sin_port);
2092 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2093 inet_ntoa(lastip), lastport, ret));
2098 /****************************************************************************
2099 read data from a device with a timout in msec.
2100 mincount = if timeout, minimum to read before returning
2101 maxcount = number to be read.
2102 ****************************************************************************/
2103 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2109 struct timeval timeout;
2111 /* just checking .... */
2112 if (maxcnt <= 0) return(0);
2117 if (time_out <= 0) {
2118 if (mincnt == 0) mincnt = maxcnt;
2120 while (nread < mincnt) {
2121 readret = read(fd, buf + nread, maxcnt - nread);
2123 smb_read_error = READ_EOF;
2127 if (readret == -1) {
2128 smb_read_error = READ_ERROR;
2136 /* Most difficult - timeout read */
2137 /* If this is ever called on a disk file and
2138 mincnt is greater then the filesize then
2139 system performance will suffer severely as
2140 select always return true on disk files */
2142 /* Set initial timeout */
2143 timeout.tv_sec = time_out / 1000;
2144 timeout.tv_usec = 1000 * (time_out % 1000);
2146 for (nread=0; nread<mincnt; )
2151 selrtn = sys_select(&fds,&timeout);
2153 /* Check if error */
2155 /* something is wrong. Maybe the socket is dead? */
2156 smb_read_error = READ_ERROR;
2160 /* Did we timeout ? */
2162 smb_read_error = READ_TIMEOUT;
2166 readret = read(fd, buf+nread, maxcnt-nread);
2168 /* we got EOF on the file descriptor */
2169 smb_read_error = READ_EOF;
2173 if (readret == -1) {
2174 /* the descriptor is probably dead */
2175 smb_read_error = READ_ERROR;
2182 /* Return the number we got */
2186 /****************************************************************************
2187 read data from the client. Maxtime is in milliseconds
2188 ****************************************************************************/
2189 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2194 struct timeval timeout;
2199 timeout.tv_sec = maxtime / 1000;
2200 timeout.tv_usec = (maxtime % 1000) * 1000;
2202 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2204 if (!FD_ISSET(fd,&fds))
2207 nread = read_udp_socket(fd, buffer, bufsize);
2209 /* return the number got */
2213 /*******************************************************************
2214 find the difference in milliseconds between two struct timeval
2216 ********************************************************************/
2217 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2219 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2220 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2223 /****************************************************************************
2224 send a keepalive packet (rfc1002)
2225 ****************************************************************************/
2226 BOOL send_keepalive(int client)
2228 unsigned char buf[4];
2231 buf[1] = buf[2] = buf[3] = 0;
2233 return(write_data(client,(char *)buf,4) == 4);
2238 /****************************************************************************
2239 read data from the client, reading exactly N bytes.
2240 ****************************************************************************/
2241 int read_data(int fd,char *buffer,int N)
2250 ret = read(fd,buffer + total,N - total);
2252 smb_read_error = READ_EOF;
2256 smb_read_error = READ_ERROR;
2265 /****************************************************************************
2267 ****************************************************************************/
2268 int write_data(int fd,char *buffer,int N)
2275 ret = write(fd,buffer + total,N - total);
2277 if (ret == -1) return -1;
2278 if (ret == 0) return total;
2286 /****************************************************************************
2287 transfer some data between two fd's
2288 ****************************************************************************/
2289 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2291 static char *buf=NULL;
2296 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2299 size = lp_readsize();
2300 size = MAX(size,1024);
2303 while (!buf && size>0) {
2304 buf = (char *)Realloc(buf,size+8);
2305 if (!buf) size /= 2;
2309 DEBUG(0,("Can't allocate transfer buffer!\n"));
2313 abuf = buf + (align%8);
2320 int s = MIN(n,size);
2325 if (header && (headlen >= MIN(s,1024))) {
2335 if (header && headlen > 0)
2337 ret = MIN(headlen,size);
2338 memcpy(buf1,header,ret);
2341 if (headlen <= 0) header = NULL;
2345 ret += read(infd,buf1+ret,s-ret);
2349 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2350 if (ret2 > 0) total += ret2;
2351 /* if we can't write then dump excess data */
2353 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2355 if (ret <= 0 || ret2 != ret)
2363 /****************************************************************************
2364 read 4 bytes of a smb packet and return the smb length of the packet
2365 store the result in the buffer
2366 This version of the function will return a length of zero on receiving
2368 ****************************************************************************/
2369 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2371 int len=0, msg_type;
2377 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2379 ok = (read_data(fd,inbuf,4) == 4);
2384 len = smb_len(inbuf);
2385 msg_type = CVAL(inbuf,0);
2387 if (msg_type == 0x85)
2388 DEBUG(5,("Got keepalive packet\n"));
2391 DEBUG(10,("got smb length of %d\n",len));
2396 /****************************************************************************
2397 read 4 bytes of a smb packet and return the smb length of the packet
2398 store the result in the buffer. This version of the function will
2399 never return a session keepalive (length of zero).
2400 ****************************************************************************/
2401 int read_smb_length(int fd,char *inbuf,int timeout)
2407 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2412 /* Ignore session keepalives. */
2413 if(CVAL(inbuf,0) != 0x85)
2420 /****************************************************************************
2421 read an smb from a fd. Note that the buffer *MUST* be of size
2422 BUFFER_SIZE+SAFETY_MARGIN.
2423 The timeout is in milli seconds.
2425 This function will return on a
2426 receipt of a session keepalive packet.
2427 ****************************************************************************/
2428 BOOL receive_smb(int fd,char *buffer, int timeout)
2434 bzero(buffer,smb_size + 100);
2436 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2440 if (len > BUFFER_SIZE) {
2441 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2442 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2447 ret = read_data(fd,buffer+4,len);
2449 smb_read_error = READ_ERROR;
2456 /****************************************************************************
2457 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2458 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2459 The timeout is in milli seconds
2461 This is exactly the same as receive_smb except that it never returns
2462 a session keepalive packet (just as receive_smb used to do).
2463 receive_smb was changed to return keepalives as the oplock processing means this call
2464 should never go into a blocking read.
2465 ****************************************************************************/
2467 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2473 ret = receive_smb(fd, buffer, timeout);
2478 /* Ignore session keepalive packets. */
2479 if(CVAL(buffer,0) != 0x85)
2485 /****************************************************************************
2486 read a message from a udp fd.
2487 The timeout is in milli seconds
2488 ****************************************************************************/
2489 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2491 struct sockaddr_in from;
2492 int fromlen = sizeof(from);
2504 to.tv_sec = timeout / 1000;
2505 to.tv_usec = (timeout % 1000) * 1000;
2507 selrtn = sys_select(&fds,&to);
2509 /* Check if error */
2512 /* something is wrong. Maybe the socket is dead? */
2513 smb_read_error = READ_ERROR;
2517 /* Did we timeout ? */
2520 smb_read_error = READ_TIMEOUT;
2526 * Read a loopback udp message.
2528 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2529 buffer_len - UDP_CMD_HEADER_LEN, 0,
2530 (struct sockaddr *)&from, &fromlen);
2534 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2538 /* Validate message length. */
2539 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2541 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2543 buffer_len - UDP_CMD_HEADER_LEN));
2547 /* Validate message from address (must be localhost). */
2548 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2550 DEBUG(0,("receive_local_message: invalid 'from' address \
2551 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2555 /* Setup the message header */
2556 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2557 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2562 /****************************************************************************
2563 structure to hold a linked list of local messages.
2565 ****************************************************************************/
2567 typedef struct _message_list {
2568 struct _message_list *msg_next;
2571 } pending_message_list;
2573 static pending_message_list *smb_msg_head = NULL;
2575 /****************************************************************************
2576 Function to push a linked list of local messages ready
2578 ****************************************************************************/
2580 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2582 pending_message_list *msg = (pending_message_list *)
2583 malloc(sizeof(pending_message_list));
2587 DEBUG(0,("push_message: malloc fail (1)\n"));
2591 msg->msg_buf = (char *)malloc(msg_len);
2592 if(msg->msg_buf == NULL)
2594 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2599 memcpy(msg->msg_buf, buf, msg_len);
2600 msg->msg_len = msg_len;
2602 msg->msg_next = *pml;
2608 /****************************************************************************
2609 Function to push a linked list of local smb messages ready
2611 ****************************************************************************/
2613 BOOL push_smb_message(char *buf, int msg_len)
2615 return push_local_message(&smb_msg_head, buf, msg_len);
2618 /****************************************************************************
2619 Do a select on an two fd's - with timeout.
2621 If a local udp message has been pushed onto the
2622 queue (this can only happen during oplock break
2623 processing) return this first.
2625 If a pending smb message has been pushed onto the
2626 queue (this can only happen during oplock break
2627 processing) return this next.
2629 If the first smbfd is ready then read an smb from it.
2630 if the second (loopback UDP) fd is ready then read a message
2631 from it and setup the buffer header to identify the length
2633 Returns False on timeout or error.
2636 The timeout is in milli seconds
2637 ****************************************************************************/
2638 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2639 char *buffer, int buffer_len,
2640 int timeout, BOOL *got_smb)
2649 * Check to see if we already have a message on the smb queue.
2650 * If so - copy and return it.
2655 pending_message_list *msg = smb_msg_head;
2656 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2657 smb_msg_head = msg->msg_next;
2659 /* Free the message we just copied. */
2660 free((char *)msg->msg_buf);
2664 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2670 FD_SET(oplock_fd,&fds);
2672 to.tv_sec = timeout / 1000;
2673 to.tv_usec = (timeout % 1000) * 1000;
2675 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2677 /* Check if error */
2679 /* something is wrong. Maybe the socket is dead? */
2680 smb_read_error = READ_ERROR;
2684 /* Did we timeout ? */
2686 smb_read_error = READ_TIMEOUT;
2690 if (FD_ISSET(smbfd,&fds))
2693 return receive_smb(smbfd, buffer, 0);
2697 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2701 /****************************************************************************
2703 ****************************************************************************/
2704 BOOL send_smb(int fd,char *buffer)
2708 len = smb_len(buffer) + 4;
2710 while (nwritten < len)
2712 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2715 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2727 /****************************************************************************
2728 find a pointer to a netbios name
2729 ****************************************************************************/
2730 char *name_ptr(char *buf,int ofs)
2732 unsigned char c = *(unsigned char *)(buf+ofs);
2734 if ((c & 0xC0) == 0xC0)
2738 memcpy(p,buf+ofs,2);
2741 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2748 /****************************************************************************
2749 extract a netbios name from a buf
2750 ****************************************************************************/
2751 int name_extract(char *buf,int ofs,char *name)
2753 char *p = name_ptr(buf,ofs);
2754 int d = PTR_DIFF(p,buf+ofs);
2756 if (d < -50 || d > 50) return(0);
2757 return(name_interpret(p,name));
2760 /****************************************************************************
2761 return the total storage length of a mangled name
2762 ****************************************************************************/
2763 int name_len( char *s )
2767 /* If the two high bits of the byte are set, return 2. */
2768 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2771 /* Add up the length bytes. */
2772 for( len = 1; (*s); s += (*s) + 1 )
2780 /****************************************************************************
2781 send a single packet to a port on another machine
2782 ****************************************************************************/
2783 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2787 struct sockaddr_in sock_out;
2792 /* create a socket to write to */
2793 out_fd = socket(AF_INET, type, 0);
2796 DEBUG(0,("socket failed"));
2800 /* set the address and port */
2801 bzero((char *)&sock_out,sizeof(sock_out));
2802 putip((char *)&sock_out.sin_addr,(char *)&ip);
2803 sock_out.sin_port = htons( port );
2804 sock_out.sin_family = AF_INET;
2807 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2808 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2811 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2814 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2815 inet_ntoa(ip),port,strerror(errno)));
2821 /*******************************************************************
2822 sleep for a specified number of milliseconds
2823 ********************************************************************/
2827 struct timeval tval,t1,t2;
2834 tval.tv_sec = (t-tdiff)/1000;
2835 tval.tv_usec = 1000*((t-tdiff)%1000);
2839 sys_select(&fds,&tval);
2842 tdiff = TvalDiff(&t1,&t2);
2846 /****************************************************************************
2847 check if a string is part of a list
2848 ****************************************************************************/
2849 BOOL in_list(char *s,char *list,BOOL casesensitive)
2854 if (!list) return(False);
2856 while (next_token(&p,tok,LIST_SEP))
2858 if (casesensitive) {
2859 if (strcmp(tok,s) == 0)
2862 if (StrCaseCmp(tok,s) == 0)
2869 /* this is used to prevent lots of mallocs of size 1 */
2870 static char *null_string = NULL;
2872 /****************************************************************************
2873 set a string value, allocing the space for the string
2874 ****************************************************************************/
2875 BOOL string_init(char **dest,char *src)
2886 null_string = (char *)malloc(1);
2889 *dest = null_string;
2893 (*dest) = (char *)malloc(l+1);
2894 if ((*dest) == NULL) {
2895 DEBUG(0,("Out of memory in string_init\n"));
2904 /****************************************************************************
2906 ****************************************************************************/
2907 void string_free(char **s)
2909 if (!s || !(*s)) return;
2910 if (*s == null_string)
2916 /****************************************************************************
2917 set a string value, allocing the space for the string, and deallocating any
2919 ****************************************************************************/
2920 BOOL string_set(char **dest,char *src)
2924 return(string_init(dest,src));
2927 /****************************************************************************
2928 substitute a string for a pattern in another string. Make sure there is
2931 This routine looks for pattern in s and replaces it with
2932 insert. It may do multiple replacements.
2934 return True if a substitution was done.
2935 ****************************************************************************/
2936 BOOL string_sub(char *s,char *pattern,char *insert)
2942 if (!insert || !pattern || !s) return(False);
2945 lp = strlen(pattern);
2946 li = strlen(insert);
2948 if (!*pattern) return(False);
2950 while (lp <= ls && (p = strstr(s,pattern)))
2953 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2954 memcpy(p,insert,li);
2963 /*********************************************************
2964 * Recursive routine that is called by mask_match.
2965 * Does the actual matching.
2966 *********************************************************/
2967 BOOL do_match(char *str, char *regexp, int case_sig)
2971 for( p = regexp; *p && *str; ) {
2978 /* Look for a character matching
2979 the one after the '*' */
2982 return True; /* Automatic match */
2984 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2986 if(do_match(str,p,case_sig))
3000 if(toupper(*str) != toupper(*p))
3010 if (!*p && str[0] == '.' && str[1] == 0)
3013 if (!*str && *p == '?')
3015 while (*p == '?') p++;
3019 if(!*str && (*p == '*' && p[1] == '\0'))
3025 /*********************************************************
3026 * Routine to match a given string with a regexp - uses
3027 * simplified regexp that takes * and ? only. Case can be
3028 * significant or not.
3029 *********************************************************/
3030 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3034 fstring ebase,eext,sbase,sext;
3038 /* Make local copies of str and regexp */
3039 StrnCpy(p1,regexp,sizeof(pstring)-1);
3040 StrnCpy(p2,str,sizeof(pstring)-1);
3042 if (!strchr(p2,'.')) {
3047 if (!strchr(p1,'.')) {
3055 string_sub(p1,"*.*","*");
3056 string_sub(p1,".*","*");
3060 /* Remove any *? and ** as they are meaningless */
3061 for(p = p1; *p; p++)
3062 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3063 (void)strcpy( &p[1], &p[2]);
3065 if (strequal(p1,"*")) return(True);
3067 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3073 if ((p=strrchr(p1,'.'))) {
3082 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3092 matched = do_match(sbase,ebase,case_sig) &&
3093 (trans2 || do_match(sext,eext,case_sig));
3095 DEBUG(8,("mask_match returning %d\n", matched));
3102 /****************************************************************************
3103 become a daemon, discarding the controlling terminal
3104 ****************************************************************************/
3105 void become_daemon(void)
3107 #ifndef NO_FORK_DEBUG
3111 /* detach from the terminal */
3114 #else /* USE_SETSID */
3117 int i = open("/dev/tty", O_RDWR);
3120 ioctl(i, (int) TIOCNOTTY, (char *)0);
3124 #endif /* TIOCNOTTY */
3125 #endif /* USE_SETSID */
3126 /* Close fd's 0,1,2. Needed if started by rsh */
3128 #endif /* NO_FORK_DEBUG */
3132 /****************************************************************************
3133 put up a yes/no prompt
3134 ****************************************************************************/
3140 if (!fgets(ans,sizeof(ans)-1,stdin))
3143 if (*ans == 'y' || *ans == 'Y')
3149 /****************************************************************************
3150 read a line from a file with possible \ continuation chars.
3151 Blanks at the start or end of a line are stripped.
3152 The string will be allocated if s2 is NULL
3153 ****************************************************************************/
3154 char *fgets_slash(char *s2,int maxlen,FILE *f)
3159 BOOL start_of_line = True;
3166 maxlen = MIN(maxlen,8);
3167 s = (char *)Realloc(s,maxlen);
3170 if (!s || maxlen < 2) return(NULL);
3174 while (len < maxlen-1)
3182 while (len > 0 && s[len-1] == ' ')
3186 if (len > 0 && s[len-1] == '\\')
3189 start_of_line = True;
3194 if (len <= 0 && !s2)
3196 return(len>0?s:NULL);
3201 start_of_line = False;
3205 if (!s2 && len > maxlen-3)
3208 s = (char *)Realloc(s,maxlen);
3209 if (!s) return(NULL);
3217 /****************************************************************************
3218 set the length of a file from a filedescriptor.
3219 Returns 0 on success, -1 on failure.
3220 ****************************************************************************/
3221 int set_filelen(int fd, long len)
3223 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3224 extend a file with ftruncate. Provide alternate implementation
3227 #if FTRUNCATE_CAN_EXTEND
3228 return ftruncate(fd, len);
3232 long currpos = lseek(fd, 0L, SEEK_CUR);
3236 /* Do an fstat to see if the file is longer than
3237 the requested size (call ftruncate),
3238 or shorter, in which case seek to len - 1 and write 1
3240 if(fstat(fd, &st)<0)
3244 if (S_ISFIFO(st.st_mode)) return 0;
3247 if(st.st_size == len)
3249 if(st.st_size > len)
3250 return ftruncate(fd, len);
3252 if(lseek(fd, len-1, SEEK_SET) != len -1)
3254 if(write(fd, &c, 1)!=1)
3256 /* Seek to where we were */
3257 lseek(fd, currpos, SEEK_SET);
3263 /****************************************************************************
3264 return the byte checksum of some data
3265 ****************************************************************************/
3266 int byte_checksum(char *buf,int len)
3268 unsigned char *p = (unsigned char *)buf;
3278 /****************************************************************************
3279 this is a version of setbuffer() for those machines that only have setvbuf
3280 ****************************************************************************/
3281 void setbuffer(FILE *f,char *buf,int bufsize)
3283 setvbuf(f,buf,_IOFBF,bufsize);
3288 /****************************************************************************
3289 parse out a directory name from a path name. Assumes dos style filenames.
3290 ****************************************************************************/
3291 char *dirname_dos(char *path,char *buf)
3293 char *p = strrchr(path,'\\');
3308 /****************************************************************************
3309 parse out a filename from a path name. Assumes dos style filenames.
3310 ****************************************************************************/
3311 static char *filename_dos(char *path,char *buf)
3313 char *p = strrchr(path,'\\');
3325 /****************************************************************************
3326 expand a pointer to be a particular size
3327 ****************************************************************************/
3328 void *Realloc(void *p,int size)
3334 DEBUG(5,("Realloc asked for 0 bytes\n"));
3339 ret = (void *)malloc(size);
3341 ret = (void *)realloc(p,size);
3344 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3350 /****************************************************************************
3352 ****************************************************************************/
3353 char *strdup(char *s)
3356 if (!s) return(NULL);
3357 ret = (char *)malloc(strlen(s)+1);
3358 if (!ret) return(NULL);
3365 /****************************************************************************
3366 Signal handler for SIGPIPE (write on a disconnected socket)
3367 ****************************************************************************/
3370 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3374 /****************************************************************************
3375 get my own name and IP
3376 ****************************************************************************/
3377 BOOL get_myname(char *my_name,struct in_addr *ip)
3384 /* get my host name */
3385 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3387 DEBUG(0,("gethostname failed\n"));
3392 if ((hp = Get_Hostbyname(hostname)) == 0)
3394 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3400 /* split off any parts after an initial . */
3401 char *p = strchr(hostname,'.');
3404 fstrcpy(my_name,hostname);
3408 putip((char *)ip,(char *)hp->h_addr);
3414 /****************************************************************************
3415 true if two IP addresses are equal
3416 ****************************************************************************/
3417 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3420 a1 = ntohl(ip1.s_addr);
3421 a2 = ntohl(ip2.s_addr);
3426 /****************************************************************************
3427 open a socket of the specified type, port and address for incoming data
3428 ****************************************************************************/
3429 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3432 struct sockaddr_in sock;
3436 /* get my host name */
3437 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3438 { DEBUG(0,("gethostname failed\n")); return -1; }
3441 if ((hp = Get_Hostbyname(host_name)) == 0)
3443 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3447 bzero((char *)&sock,sizeof(sock));
3448 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3449 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3450 sock.sin_len = sizeof(sock);
3452 sock.sin_port = htons( port );
3453 sock.sin_family = hp->h_addrtype;
3454 sock.sin_addr.s_addr = socket_addr;
3455 res = socket(hp->h_addrtype, type, 0);
3457 { DEBUG(0,("socket failed\n")); return -1; }
3461 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3464 /* now we've got a socket - we need to bind it */
3465 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3468 if (port == SMB_PORT || port == NMB_PORT)
3469 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3470 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3473 if (dlevel > 0 && port < 1000)
3476 if (port >= 1000 && port < 9000)
3477 return(open_socket_in(type,port+1,dlevel,socket_addr));
3482 DEBUG(3,("bind succeeded on port %d\n",port));
3488 /****************************************************************************
3489 create an outgoing socket
3490 **************************************************************************/
3491 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3493 struct sockaddr_in sock_out;
3495 int connect_loop = 250; /* 250 milliseconds */
3496 int loops = (timeout * 1000) / connect_loop;
3498 /* create a socket to write to */
3499 res = socket(PF_INET, type, 0);
3501 { DEBUG(0,("socket error\n")); return -1; }
3503 if (type != SOCK_STREAM) return(res);
3505 bzero((char *)&sock_out,sizeof(sock_out));
3506 putip((char *)&sock_out.sin_addr,(char *)addr);
3508 sock_out.sin_port = htons( port );
3509 sock_out.sin_family = PF_INET;
3511 /* set it non-blocking */
3512 set_blocking(res,False);
3514 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3516 /* and connect it to the destination */
3518 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3520 /* Some systems return EAGAIN when they mean EINPROGRESS */
3521 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3522 errno == EAGAIN) && loops--) {
3523 msleep(connect_loop);
3527 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3529 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3535 if (ret < 0 && errno == EISCONN) {
3542 DEBUG(1,("error connecting to %s:%d (%s)\n",
3543 inet_ntoa(*addr),port,strerror(errno)));
3547 /* set it blocking again */
3548 set_blocking(res,True);
3554 /****************************************************************************
3555 interpret a protocol description string, with a default
3556 ****************************************************************************/
3557 int interpret_protocol(char *str,int def)
3559 if (strequal(str,"NT1"))
3560 return(PROTOCOL_NT1);
3561 if (strequal(str,"LANMAN2"))
3562 return(PROTOCOL_LANMAN2);
3563 if (strequal(str,"LANMAN1"))
3564 return(PROTOCOL_LANMAN1);
3565 if (strequal(str,"CORE"))
3566 return(PROTOCOL_CORE);
3567 if (strequal(str,"COREPLUS"))
3568 return(PROTOCOL_COREPLUS);
3569 if (strequal(str,"CORE+"))
3570 return(PROTOCOL_COREPLUS);
3572 DEBUG(0,("Unrecognised protocol level %s\n",str));
3577 /****************************************************************************
3578 interpret a security level
3579 ****************************************************************************/
3580 int interpret_security(char *str,int def)
3582 if (strequal(str,"SERVER"))
3584 if (strequal(str,"USER"))
3586 if (strequal(str,"SHARE"))
3589 DEBUG(0,("Unrecognised security level %s\n",str));
3595 /****************************************************************************
3596 interpret an internet address or name into an IP address in 4 byte form
3597 ****************************************************************************/
3598 uint32 interpret_addr(char *str)
3603 BOOL pure_address = True;
3605 if (strcmp(str,"0.0.0.0") == 0) return(0);
3606 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3608 for (i=0; pure_address && str[i]; i++)
3609 if (!(isdigit(str[i]) || str[i] == '.'))
3610 pure_address = False;
3612 /* if it's in the form of an IP address then get the lib to interpret it */
3614 res = inet_addr(str);
3616 /* otherwise assume it's a network name of some sort and use
3618 if ((hp = Get_Hostbyname(str)) == 0) {
3619 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3622 if(hp->h_addr == NULL) {
3623 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3626 putip((char *)&res,(char *)hp->h_addr);
3629 if (res == (uint32)-1) return(0);
3634 /*******************************************************************
3635 a convenient addition to interpret_addr()
3636 ******************************************************************/
3637 struct in_addr *interpret_addr2(char *str)
3639 static struct in_addr ret;
3640 uint32 a = interpret_addr(str);
3645 /*******************************************************************
3646 check if an IP is the 0.0.0.0
3647 ******************************************************************/
3648 BOOL zero_ip(struct in_addr ip)
3651 putip((char *)&a,(char *)&ip);
3656 /*******************************************************************
3657 matchname - determine if host name matches IP address
3658 ******************************************************************/
3659 static BOOL matchname(char *remotehost,struct in_addr addr)
3664 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3665 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3670 * Make sure that gethostbyname() returns the "correct" host name.
3671 * Unfortunately, gethostbyname("localhost") sometimes yields
3672 * "localhost.domain". Since the latter host name comes from the
3673 * local DNS, we just have to trust it (all bets are off if the local
3674 * DNS is perverted). We always check the address list, though.
3677 if (strcasecmp(remotehost, hp->h_name)
3678 && strcasecmp(remotehost, "localhost")) {
3679 DEBUG(0,("host name/name mismatch: %s != %s",
3680 remotehost, hp->h_name));
3684 /* Look up the host address in the address list we just got. */
3685 for (i = 0; hp->h_addr_list[i]; i++) {
3686 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3691 * The host name does not map to the original host address. Perhaps
3692 * someone has compromised a name server. More likely someone botched
3693 * it, but that could be dangerous, too.
3696 DEBUG(0,("host name/address mismatch: %s != %s",
3697 inet_ntoa(addr), hp->h_name));
3701 /*******************************************************************
3702 Reset the 'done' variables so after a client process is created
3703 from a fork call these calls will be re-done. This should be
3704 expanded if more variables need reseting.
3705 ******************************************************************/
3707 static BOOL global_client_name_done = False;
3708 static BOOL global_client_addr_done = False;
3710 void reset_globals_after_fork()
3712 global_client_name_done = False;
3713 global_client_addr_done = False;
3716 /*******************************************************************
3717 return the DNS name of the client
3718 ******************************************************************/
3719 char *client_name(void)
3722 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3723 int length = sizeof(sa);
3724 static pstring name_buf;
3727 if (global_client_name_done)
3730 strcpy(name_buf,"UNKNOWN");
3736 if (getpeername(Client, &sa, &length) < 0) {
3737 DEBUG(0,("getpeername failed\n"));
3741 /* Look up the remote host name. */
3742 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3743 sizeof(sockin->sin_addr),
3745 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3746 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3748 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3749 if (!matchname(name_buf, sockin->sin_addr)) {
3750 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3751 strcpy(name_buf,"UNKNOWN");
3754 global_client_name_done = True;
3758 /*******************************************************************
3759 return the IP addr of the client as a string
3760 ******************************************************************/
3761 char *client_addr(void)
3764 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3765 int length = sizeof(sa);
3766 static fstring addr_buf;
3768 if (global_client_addr_done)
3771 strcpy(addr_buf,"0.0.0.0");
3777 if (getpeername(Client, &sa, &length) < 0) {
3778 DEBUG(0,("getpeername failed\n"));
3782 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3784 global_client_addr_done = True;
3788 /*******************************************************************
3789 Patch from jkf@soton.ac.uk
3790 Split Luke's automount_server into YP lookup and string splitter
3791 so can easily implement automount_path().
3792 As we may end up doing both, cache the last YP result.
3793 *******************************************************************/
3795 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3796 static char *automount_lookup(char *user_name)
3798 static fstring last_key = "";
3799 static pstring last_value = "";
3801 int nis_error; /* returned by yp all functions */
3802 char *nis_result; /* yp_match inits this */
3803 int nis_result_len; /* and set this */
3804 char *nis_domain; /* yp_get_default_domain inits this */
3805 char *nis_map = (char *)lp_nis_home_map_name();
3807 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3809 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3813 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3815 if (!strcmp(user_name, last_key))
3817 nis_result = last_value;
3818 nis_result_len = strlen(last_value);
3823 if ((nis_error = yp_match(nis_domain, nis_map,
3824 user_name, strlen(user_name),
3825 &nis_result, &nis_result_len)) != 0)
3827 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3828 yperr_string(nis_error), user_name, nis_map));
3830 if (!nis_error && nis_result_len >= sizeof(pstring))
3832 nis_result_len = sizeof(pstring)-1;
3834 fstrcpy(last_key, user_name);
3835 strncpy(last_value, nis_result, nis_result_len);
3836 last_value[nis_result_len] = '\0';
3839 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3844 /*******************************************************************
3845 Patch from jkf@soton.ac.uk
3846 This is Luke's original function with the NIS lookup code
3847 moved out to a separate function.
3848 *******************************************************************/
3850 char *automount_server(char *user_name)
3852 static pstring server_name;
3854 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3855 int home_server_len;
3857 /* set to default of local machine */
3858 pstrcpy(server_name, local_machine);
3860 if (lp_nis_home_map())
3862 char *automount_value = automount_lookup(user_name);
3863 home_server_len = strcspn(automount_value,":");
3864 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3865 if (home_server_len > sizeof(pstring))
3867 home_server_len = sizeof(pstring);
3869 strncpy(server_name, automount_value, home_server_len);
3870 server_name[home_server_len] = '\0';
3873 /* use the local machine name instead of the auto-map server */
3874 pstrcpy(server_name, local_machine);
3877 DEBUG(4,("Home server: %s\n", server_name));
3882 /*******************************************************************
3883 Patch from jkf@soton.ac.uk
3884 Added this to implement %p (NIS auto-map version of %H)
3885 *******************************************************************/
3887 char *automount_path(char *user_name)
3889 static pstring server_path;
3891 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3892 char *home_path_start;
3894 /* set to default of no string */
3897 if (lp_nis_home_map())
3899 char *automount_value = automount_lookup(user_name);
3900 home_path_start = strchr(automount_value,':');
3901 if (home_path_start != NULL)
3903 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3904 home_path_start?(home_path_start+1):""));
3905 strcpy(server_path, home_path_start+1);
3909 /* use the passwd entry instead of the auto-map server entry */
3910 /* pstrcpy() copes with get_home_dir() returning NULL */
3911 pstrcpy(server_path, get_home_dir(user_name));
3914 DEBUG(4,("Home server path: %s\n", server_path));
3920 /*******************************************************************
3921 sub strings with useful parameters
3922 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3923 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3924 ********************************************************************/
3925 void standard_sub_basic(char *str)
3929 struct passwd *pass;
3930 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3932 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3938 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3940 string_sub(p,"%G",gidtoname(pass->pw_gid));
3948 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3949 case 'I' : string_sub(p,"%I", client_addr()); break;
3950 case 'L' : string_sub(p,"%L", local_machine); break;
3951 case 'M' : string_sub(p,"%M", client_name()); break;
3952 case 'R' : string_sub(p,"%R", remote_proto); break;
3953 case 'T' : string_sub(p,"%T", timestring()); break;
3954 case 'U' : string_sub(p,"%U", username); break;
3955 case 'a' : string_sub(p,"%a", remote_arch); break;
3958 sprintf(pidstr,"%d",(int)getpid());
3959 string_sub(p,"%d", pidstr);
3962 case 'h' : string_sub(p,"%h", myhostname); break;
3963 case 'm' : string_sub(p,"%m", remote_machine); break;
3964 case 'v' : string_sub(p,"%v", VERSION); break;
3965 case '$' : /* Expand environment variables */
3967 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3973 if (*(p+2) != '(') { p+=2; break; }
3974 if ((q = strchr(p,')')) == NULL)
3976 DEBUG(0,("standard_sub_basic: Unterminated environment \
3977 variable [%s]\n", p));
3982 copylen = MIN((q-r),(sizeof(envname)-1));
3983 strncpy(envname,r,copylen);
3984 envname[copylen] = '\0';
3985 if ((envval = getenv(envname)) == NULL)
3987 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3991 copylen = MIN((q+1-p),(sizeof(envname)-1));
3992 strncpy(envname,p,copylen);
3993 envname[copylen] = '\0';
3994 string_sub(p,envname,envval);
3997 case '\0': p++; break; /* don't run off end if last character is % */
3998 default : p+=2; break;
4004 /*******************************************************************
4005 are two IPs on the same subnet?
4006 ********************************************************************/
4007 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4009 uint32 net1,net2,nmask;
4011 nmask = ntohl(mask.s_addr);
4012 net1 = ntohl(ip1.s_addr);
4013 net2 = ntohl(ip2.s_addr);
4015 return((net1 & nmask) == (net2 & nmask));
4019 /*******************************************************************
4020 write a string in unicoode format
4021 ********************************************************************/
4022 int PutUniCode(char *dst,char *src)
4026 dst[ret++] = src[0];
4035 /****************************************************************************
4036 a wrapper for gethostbyname() that tries with all lower and all upper case
4037 if the initial name fails
4038 ****************************************************************************/
4039 struct hostent *Get_Hostbyname(char *name)
4041 char *name2 = strdup(name);
4042 struct hostent *ret;
4046 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4050 if (!isalnum(*name2))
4056 ret = sys_gethostbyname(name2);
4063 /* try with all lowercase */
4065 ret = sys_gethostbyname(name2);
4072 /* try with all uppercase */
4074 ret = sys_gethostbyname(name2);
4081 /* nothing works :-( */
4087 /****************************************************************************
4088 check if a process exists. Does this work on all unixes?
4089 ****************************************************************************/
4090 BOOL process_exists(int pid)
4092 return(kill(pid,0) == 0 || errno != ESRCH);
4096 /*******************************************************************
4097 turn a uid into a user name
4098 ********************************************************************/
4099 char *uidtoname(int uid)
4101 static char name[40];
4102 struct passwd *pass = getpwuid(uid);
4103 if (pass) return(pass->pw_name);
4104 sprintf(name,"%d",uid);
4108 /*******************************************************************
4109 turn a gid into a group name
4110 ********************************************************************/
4111 char *gidtoname(int gid)
4113 static char name[40];
4114 struct group *grp = getgrgid(gid);
4115 if (grp) return(grp->gr_name);
4116 sprintf(name,"%d",gid);
4120 /*******************************************************************
4122 ********************************************************************/
4123 void BlockSignals(BOOL block,int signum)
4126 int block_mask = sigmask(signum);
4127 static int oldmask = 0;
4129 oldmask = sigblock(block_mask);
4131 sigsetmask(oldmask);
4132 #elif defined(USE_SIGPROCMASK)
4135 sigaddset(&set,signum);
4136 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4141 /*******************************************************************
4142 my own panic function - not suitable for general use
4143 ********************************************************************/
4144 void ajt_panic(void)
4146 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4151 #define DIRECT direct
4153 #define DIRECT dirent
4156 /*******************************************************************
4157 a readdir wrapper which just returns the file name
4158 also return the inode number if requested
4159 ********************************************************************/
4160 char *readdirname(void *p)
4165 if (!p) return(NULL);
4167 ptr = (struct DIRECT *)readdir(p);
4168 if (!ptr) return(NULL);
4170 dname = ptr->d_name;
4173 if (telldir(p) < 0) return(NULL);
4177 /* this handles a broken compiler setup, causing a mixture
4178 of BSD and SYSV headers and libraries */
4180 static BOOL broken_readdir = False;
4181 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4183 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4184 broken_readdir = True;
4193 pstrcpy(buf, dname);
4194 unix_to_dos(buf, True);
4201 /*******************************************************************
4202 Utility function used to decide if the last component
4203 of a path matches a (possibly wildcarded) entry in a namelist.
4204 ********************************************************************/
4206 BOOL is_in_path(char *name, name_compare_entry *namelist)
4208 pstring last_component;
4211 DEBUG(8, ("is_in_path: %s\n", name));
4213 /* if we have no list it's obviously not in the path */
4214 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4216 DEBUG(8,("is_in_path: no name list.\n"));
4220 /* Get the last component of the unix name. */
4221 p = strrchr(name, '/');
4222 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
4223 last_component[sizeof(last_component)-1] = '\0';
4225 for(; namelist->name != NULL; namelist++)
4227 if(namelist->is_wild)
4229 /* look for a wildcard match. */
4230 if (mask_match(last_component, namelist->name, case_sensitive, False))
4232 DEBUG(8,("is_in_path: mask match succeeded\n"));
4238 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4239 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4241 DEBUG(8,("is_in_path: match succeeded\n"));
4246 DEBUG(8,("is_in_path: match not found\n"));
4251 /*******************************************************************
4252 Strip a '/' separated list into an array of
4253 name_compare_enties structures suitable for
4254 passing to is_in_path(). We do this for
4255 speed so we can pre-parse all the names in the list
4256 and don't do it for each call to is_in_path().
4257 namelist is modified here and is assumed to be
4258 a copy owned by the caller.
4259 We also check if the entry contains a wildcard to
4260 remove a potentially expensive call to mask_match
4262 ********************************************************************/
4264 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4267 char *nameptr = namelist;
4268 int num_entries = 0;
4271 (*ppname_array) = NULL;
4273 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4276 /* We need to make two passes over the string. The
4277 first to count the number of elements, the second
4282 if ( *nameptr == '/' )
4284 /* cope with multiple (useless) /s) */
4288 /* find the next / */
4289 name_end = strchr(nameptr, '/');
4291 /* oops - the last check for a / didn't find one. */
4292 if (name_end == NULL)
4295 /* next segment please */
4296 nameptr = name_end + 1;
4300 if(num_entries == 0)
4303 if(( (*ppname_array) = (name_compare_entry *)malloc(
4304 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4306 DEBUG(0,("set_namearray: malloc fail\n"));
4310 /* Now copy out the names */
4315 if ( *nameptr == '/' )
4317 /* cope with multiple (useless) /s) */
4321 /* find the next / */
4322 if ((name_end = strchr(nameptr, '/')) != NULL)
4327 /* oops - the last check for a / didn't find one. */
4328 if(name_end == NULL)
4331 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4332 (strchr( nameptr, '*')!=NULL));
4333 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4335 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4339 /* next segment please */
4340 nameptr = name_end + 1;
4344 (*ppname_array)[i].name = NULL;
4349 /****************************************************************************
4350 routine to free a namearray.
4351 ****************************************************************************/
4353 void free_namearray(name_compare_entry *name_array)
4358 if(name_array->name != NULL)
4359 free(name_array->name);
4361 free((char *)name_array);
4364 /****************************************************************************
4365 routine to do file locking
4366 ****************************************************************************/
4367 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4374 uint32 mask = 0xC0000000;
4376 /* make sure the count is reasonable, we might kill the lockd otherwise */
4379 /* the offset is often strange - remove 2 of its bits if either of
4380 the top two bits are set. Shift the top ones by two bits. This
4381 still allows OLE2 apps to operate, but should stop lockd from
4383 if ((offset & mask) != 0)
4384 offset = (offset & ~mask) | ((offset & mask) >> 2);
4386 uint32 mask = ((unsigned)1<<31);
4388 /* interpret negative counts as large numbers */
4392 /* no negative offsets */
4395 /* count + offset must be in range */
4396 while ((offset < 0 || (offset + count < 0)) && mask)
4404 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4407 lock.l_whence = SEEK_SET;
4408 lock.l_start = (int)offset;
4409 lock.l_len = (int)count;
4414 ret = fcntl(fd,op,&lock);
4417 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4423 (lock.l_type != F_UNLCK) &&
4424 (lock.l_pid != 0) &&
4425 (lock.l_pid != getpid()))
4427 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4431 /* it must be not locked or locked by me */
4435 /* a lock set or unset */
4438 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4439 offset,count,op,type,strerror(errno)));
4441 /* perhaps it doesn't support this sort of locking?? */
4442 if (errno == EINVAL)
4444 DEBUG(3,("locking not supported? returning True\n"));
4451 /* everything went OK */
4452 DEBUG(8,("Lock call successful\n"));
4460 /*******************************************************************
4461 lock a file - returning a open file descriptor or -1 on failure
4462 The timeout is in seconds. 0 means no timeout
4463 ********************************************************************/
4464 int file_lock(char *name,int timeout)
4466 int fd = open(name,O_RDWR|O_CREAT,0666);
4468 if (fd < 0) return(-1);
4471 if (timeout) t = time(NULL);
4472 while (!timeout || (time(NULL)-t < timeout)) {
4473 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4474 msleep(LOCK_RETRY_TIMEOUT);
4482 /*******************************************************************
4483 unlock a file locked by file_lock
4484 ********************************************************************/
4485 void file_unlock(int fd)
4489 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4494 /*******************************************************************
4495 is the name specified one of my netbios names
4496 returns true is it is equal, false otherwise
4497 ********************************************************************/
4498 BOOL is_myname(char *s)
4503 for (n=0; my_netbios_names[n]; n++) {
4504 if (strequal(my_netbios_names[n], s))
4507 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4511 /*******************************************************************
4512 set the horrid remote_arch string based on an enum.
4513 ********************************************************************/
4514 void set_remote_arch(enum remote_arch_types type)
4520 strcpy(remote_arch, "WfWg");
4523 strcpy(remote_arch, "OS2");
4526 strcpy(remote_arch, "Win95");
4529 strcpy(remote_arch, "WinNT");
4532 strcpy(remote_arch,"Samba");
4535 ra_type = RA_UNKNOWN;
4536 strcpy(remote_arch, "UNKNOWN");
4541 /*******************************************************************
4542 Get the remote_arch type.
4543 ********************************************************************/
4544 enum remote_arch_types get_remote_arch()
4550 /*******************************************************************
4551 skip past some unicode strings in a buffer
4552 ********************************************************************/
4553 char *skip_unicode_string(char *buf,int n)
4564 /*******************************************************************
4565 Return a ascii version of a unicode string
4566 Hack alert: uses fixed buffer(s) and only handles ascii strings
4567 ********************************************************************/
4569 char *unistrn2(uint16 *buf, int len)
4571 static char lbufs[8][MAXUNI];
4573 char *lbuf = lbufs[nexti];
4576 nexti = (nexti+1)%8;
4578 DEBUG(10, ("unistrn2: "));
4580 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4582 DEBUG(10, ("%4x ", *buf));
4592 /*******************************************************************
4593 Return a ascii version of a unicode string
4594 Hack alert: uses fixed buffer(s) and only handles ascii strings
4595 ********************************************************************/
4597 char *unistr2(uint16 *buf)
4599 static char lbufs[8][MAXUNI];
4601 char *lbuf = lbufs[nexti];
4604 nexti = (nexti+1)%8;
4606 DEBUG(10, ("unistr2: "));
4608 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4610 DEBUG(10, ("%4x ", *buf));
4620 /*******************************************************************
4621 create a null-terminated unicode string from a null-terminated ascii string.
4622 return number of unicode chars copied, excluding the null character.
4624 only handles ascii strings
4625 ********************************************************************/
4627 int struni2(uint16 *p, char *buf)
4631 if (p == NULL) return 0;
4633 DEBUG(10, ("struni2: "));
4637 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4639 DEBUG(10, ("%2x ", *buf));
4651 /*******************************************************************
4652 Return a ascii version of a unicode string
4653 Hack alert: uses fixed buffer(s) and only handles ascii strings
4654 ********************************************************************/
4656 char *unistr(char *buf)
4658 static char lbufs[8][MAXUNI];
4660 char *lbuf = lbufs[nexti];
4663 nexti = (nexti+1)%8;
4665 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4673 /*******************************************************************
4674 strncpy for unicode strings
4675 ********************************************************************/
4676 int unistrncpy(char *dst, char *src, int len)
4680 while (*src && len > 0)
4694 /*******************************************************************
4695 strcpy for unicode strings. returns length (in num of wide chars)
4696 ********************************************************************/
4697 int unistrcpy(char *dst, char *src)
4714 /*******************************************************************
4715 safe string copy into a fstring
4716 ********************************************************************/
4717 void fstrcpy(char *dest, char *src)
4719 int maxlength = sizeof(fstring) - 1;
4721 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4730 while (maxlength-- && *src)
4734 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4739 /*******************************************************************
4740 safe string copy into a pstring
4741 ********************************************************************/
4742 void pstrcpy(char *dest, char *src)
4744 int maxlength = sizeof(pstring) - 1;
4746 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4755 while (maxlength-- && *src)
4759 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4765 /*******************************************************************
4766 align a pointer to a multiple of 4 bytes
4767 ********************************************************************/
4768 char *align4(char *q, char *base)
4772 q += 4 - ((q - base) & 3);
4777 /*******************************************************************
4778 align a pointer to a multiple of 2 bytes
4779 ********************************************************************/
4780 char *align2(char *q, char *base)
4789 /*******************************************************************
4790 align a pointer to a multiple of align_offset bytes. looks like it
4791 will work for offsets of 0, 2 and 4...
4792 ********************************************************************/
4793 char *align_offset(char *q, char *base, int align_offset_len)
4795 int mod = ((q - base) & (align_offset_len-1));
4796 if (align_offset_len != 0 && mod != 0)
4798 q += align_offset_len - mod;
4803 void print_asc(int level, unsigned char *buf,int len)
4807 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4810 void dump_data(int level,char *buf1,int len)
4812 unsigned char *buf = (unsigned char *)buf1;
4816 DEBUG(level,("[%03X] ",i));
4818 DEBUG(level,("%02X ",(int)buf[i]));
4820 if (i%8 == 0) DEBUG(level,(" "));
4822 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4823 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4824 if (i<len) DEBUG(level,("[%03X] ",i));
4832 if (n>8) DEBUG(level,(" "));
4833 while (n--) DEBUG(level,(" "));
4836 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4838 if (n>0) print_asc(level,&buf[i-n],n);
4839 DEBUG(level,("\n"));
4843 char *tab_depth(int depth)
4845 static pstring spaces;
4846 memset(spaces, ' ', depth * 4);
4847 spaces[depth * 4] = 0;
4851 /*****************************************************************
4852 Convert a domain SID to an ascii string. (non-reentrant).
4853 *****************************************************************/
4855 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4856 char *dom_sid_to_string(DOM_SID *sid)
4858 static pstring sidstr;
4861 uint32 ia = (sid->id_auth[5]) +
4862 (sid->id_auth[4] << 8 ) +
4863 (sid->id_auth[3] << 16) +
4864 (sid->id_auth[2] << 24);
4866 sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
4868 for (i = 0; i < sid->num_auths; i++)
4870 sprintf(subauth, "-%d", sid->sub_auths[i]);
4871 strcat(sidstr, subauth);
4874 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));