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))
26 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
38 int Protocol = PROTOCOL_COREPLUS;
40 /* a default finfo structure to ensure all fields are sensible */
41 file_info def_finfo = {-1,0,0,0,0,0,0,""};
43 /* these are some file handles where debug info will be stored */
46 /* the client file descriptor */
49 /* the last IP received from */
50 struct in_addr lastip;
52 /* the last port received from */
55 /* this is used by the chaining code */
61 case handling on filenames
63 int case_default = CASE_LOWER;
68 /* the following control case operations - they are put here so the
69 client can link easily */
72 BOOL use_mangled_map = False;
73 BOOL short_case_preserve;
76 fstring remote_machine="";
77 fstring local_machine="";
78 fstring remote_arch="UNKNOWN";
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
80 fstring remote_proto="UNKNOWN";
81 pstring myhostname="";
82 pstring user_socket_options="";
84 pstring sesssetup_user="";
85 pstring samlogon_user="";
87 BOOL sam_logon_in_ssb = False;
89 pstring global_myname = "";
90 fstring global_myworkgroup = "";
91 char **my_netbios_names;
93 int smb_read_error = 0;
95 static BOOL stdout_logging = False;
97 static char *filename_dos(char *path,char *buf);
100 /******************************************************************************
101 catch a sigusr2 - decrease the debug log level.
102 *****************************************************************************/
105 BlockSignals( True, SIGUSR2);
112 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
114 BlockSignals( False, SIGUSR2);
115 #ifndef DONT_REINSTALL_SIG
116 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
123 /**************************************************************************** **
124 catch a sigusr1 - increase the debug log level.
125 **************************************************************************** */
128 BlockSignals( True, SIGUSR1);
135 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
137 BlockSignals( False, SIGUSR1);
138 #ifndef DONT_REINSTALL_SIG
139 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
146 /*******************************************************************
147 get ready for syslog stuff
148 ******************************************************************/
149 void setup_logging(char *pname,BOOL interactive)
153 char *p = strrchr(pname,'/');
156 openlog(pname, LOG_PID, SYSLOG_FACILITY);
157 #else /* for old systems that have no facility codes. */
158 openlog(pname, LOG_PID);
163 stdout_logging = True;
169 BOOL append_log=False;
172 /****************************************************************************
174 ****************************************************************************/
175 void reopen_logs(void)
181 pstrcpy(fname,debugf);
182 if (lp_loaded() && (*lp_logfile()))
183 pstrcpy(fname,lp_logfile());
185 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
187 int oldumask = umask(022);
188 pstrcpy(debugf,fname);
189 if (dbf) fclose(dbf);
191 dbf = fopen(debugf,"a");
193 dbf = fopen(debugf,"w");
194 if (dbf) setbuf(dbf,NULL);
209 /*******************************************************************
210 check if the log has grown too big
211 ********************************************************************/
212 static void check_log_size(void)
214 static int debug_count=0;
218 if (debug_count++ < 100 || getuid() != 0) return;
220 maxlog = lp_max_log_size() * 1024;
221 if (!dbf || maxlog <= 0) return;
223 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
224 fclose(dbf); dbf = NULL;
226 if (dbf && file_size(debugf) > maxlog) {
228 fclose(dbf); dbf = NULL;
229 slprintf(name,sizeof(name)-1,"%s.old",debugf);
230 sys_rename(debugf,name);
238 /*******************************************************************
239 write an debug message on the debugfile. This is called by the DEBUG
241 ********************************************************************/
243 int Debug1(char *format_str, ...)
252 int old_errno = errno;
254 if (stdout_logging) {
256 va_start(ap, format_str);
259 format_str = va_arg(ap,char *);
261 vfprintf(dbf,format_str,ap);
268 if (!lp_syslog_only())
272 int oldumask = umask(022);
274 dbf = fopen(debugf,"a");
276 dbf = fopen(debugf,"w");
288 if (syslog_level < lp_syslog())
291 * map debug levels to syslog() priorities
292 * note that not all DEBUG(0, ...) calls are
295 static int priority_map[] = {
304 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
306 priority = LOG_DEBUG;
308 priority = priority_map[syslog_level];
311 va_start(ap, format_str);
314 format_str = va_arg(ap,char *);
316 vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap);
320 syslog(priority, "%s", msgbuf);
325 if (!lp_syslog_only())
329 va_start(ap, format_str);
332 format_str = va_arg(ap,char *);
334 vfprintf(dbf,format_str,ap);
346 /****************************************************************************
347 find a suitable temporary directory. The result should be copied immediately
348 as it may be overwritten by a subsequent call
349 ****************************************************************************/
353 if ((p = getenv("TMPDIR"))) {
361 /****************************************************************************
362 determine if a file descriptor is in fact a socket
363 ****************************************************************************/
364 BOOL is_a_socket(int fd)
368 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
372 static char *last_ptr=NULL;
374 /****************************************************************************
375 Get the next token from a string, return False if none found
376 handles double-quotes.
377 Based on a routine by GJC@VILLAGE.COM.
378 Extensively modified by Andrew.Tridgell@anu.edu.au
379 ****************************************************************************/
380 BOOL next_token(char **ptr,char *buff,char *sep)
385 if (!ptr) ptr = &last_ptr;
386 if (!ptr) return(False);
390 /* default to simple separators */
391 if (!sep) sep = " \t\n\r";
393 /* find the first non sep char */
394 while(*s && strchr(sep,*s)) s++;
397 if (! *s) return(False);
399 /* copy over the token */
400 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
408 *ptr = (*s) ? s+1 : s;
415 /****************************************************************************
416 Convert list of tokens to array; dependent on above routine.
417 Uses last_ptr from above - bit of a hack.
418 ****************************************************************************/
419 char **toktocliplist(int *ctok, char *sep)
425 if (!sep) sep = " \t\n\r";
427 while(*s && strchr(sep,*s)) s++;
430 if (!*s) return(NULL);
434 while(*s && (!strchr(sep,*s))) s++;
435 while(*s && strchr(sep,*s)) *s++=0;
441 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
453 /*******************************************************************
454 safely copies memory, ensuring no overlap problems.
455 this is only used if the machine does not have it's own memmove().
456 this is not the fastest algorithm in town, but it will do for our
458 ********************************************************************/
459 void *MemMove(void *dest,void *src,int size)
463 if (dest==src || !size) return(dest);
465 d = (unsigned long)dest;
466 s = (unsigned long)src;
468 if ((d >= (s+size)) || (s >= (d+size))) {
470 memcpy(dest,src,size);
476 /* we can forward copy */
477 if (s-d >= sizeof(int) &&
478 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
479 /* do it all as words */
480 int *idest = (int *)dest;
481 int *isrc = (int *)src;
483 for (i=0;i<size;i++) idest[i] = isrc[i];
486 char *cdest = (char *)dest;
487 char *csrc = (char *)src;
488 for (i=0;i<size;i++) cdest[i] = csrc[i];
493 /* must backward copy */
494 if (d-s >= sizeof(int) &&
495 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
496 /* do it all as words */
497 int *idest = (int *)dest;
498 int *isrc = (int *)src;
500 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
503 char *cdest = (char *)dest;
504 char *csrc = (char *)src;
505 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
513 /****************************************************************************
514 prompte a dptr (to make it recently used)
515 ****************************************************************************/
516 void array_promote(char *array,int elsize,int element)
522 p = (char *)malloc(elsize);
526 DEBUG(5,("Ahh! Can't malloc\n"));
529 memcpy(p,array + element * elsize, elsize);
530 memmove(array + elsize,array,elsize*element);
531 memcpy(array,p,elsize);
535 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
544 } socket_options[] = {
545 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
546 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
547 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
549 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
551 #ifdef IPTOS_LOWDELAY
552 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
554 #ifdef IPTOS_THROUGHPUT
555 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
558 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
561 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
564 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
567 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
570 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
573 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
579 /****************************************************************************
580 set user socket options
581 ****************************************************************************/
582 void set_socket_options(int fd, char *options)
586 while (next_token(&options,tok," \t,"))
591 BOOL got_value = False;
593 if ((p = strchr(tok,'=')))
600 for (i=0;socket_options[i].name;i++)
601 if (strequal(socket_options[i].name,tok))
604 if (!socket_options[i].name)
606 DEBUG(0,("Unknown socket option %s\n",tok));
610 switch (socket_options[i].opttype)
614 ret = setsockopt(fd,socket_options[i].level,
615 socket_options[i].option,(char *)&value,sizeof(int));
620 DEBUG(0,("syntax error - %s does not take a value\n",tok));
623 int on = socket_options[i].value;
624 ret = setsockopt(fd,socket_options[i].level,
625 socket_options[i].option,(char *)&on,sizeof(int));
631 DEBUG(0,("Failed to set socket option %s\n",tok));
637 /****************************************************************************
638 close the socket communication
639 ****************************************************************************/
640 void close_sockets(void )
646 /****************************************************************************
647 determine whether we are in the specified group
648 ****************************************************************************/
649 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
653 if (group == current_gid) return(True);
655 for (i=0;i<ngroups;i++)
656 if (group == groups[i])
662 /****************************************************************************
663 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
664 ****************************************************************************/
665 char *StrCpy(char *dest,char *src)
670 /* I don't want to get lazy with these ... */
672 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
677 if (!dest) return(NULL);
682 while ((*d++ = *src++)) ;
686 /****************************************************************************
687 line strncpy but always null terminates. Make sure there is room!
688 ****************************************************************************/
689 char *StrnCpy(char *dest,char *src,int n)
692 if (!dest) return(NULL);
697 while (n-- && (*d++ = *src++)) ;
703 /*******************************************************************
704 copy an IP address from one buffer to another
705 ********************************************************************/
706 void putip(void *dest,void *src)
712 /****************************************************************************
713 interpret the weird netbios "name". Return the name type
714 ****************************************************************************/
715 static int name_interpret(char *in,char *out)
718 int len = (*in++) / 2;
722 if (len > 30 || len<1) return(0);
726 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
730 *out = ((in[0]-'A')<<4) + (in[1]-'A');
738 /* Handle any scope names */
741 *out++ = '.'; /* Scope names are separated by periods */
742 len = *(unsigned char *)in++;
743 StrnCpy(out, in, len);
752 /****************************************************************************
753 mangle a name into netbios format
755 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
756 ****************************************************************************/
757 int name_mangle( char *In, char *Out, char name_type )
765 /* Safely copy the input string, In, into buf[]. */
766 (void)memset( buf, 0, 20 );
770 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
772 /* Place the length of the first field into the output buffer. */
776 /* Now convert the name to the rfc1001/1002 format. */
777 for( i = 0; i < 16; i++ )
779 c = toupper( buf[i] );
780 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
781 p[(i*2)+1] = (c & 0x000F) + 'A';
786 /* Add the scope string. */
787 for( i = 0, len = 0; NULL != scope; i++, len++ )
795 return( name_len(Out) );
807 return( name_len(Out) );
810 /*******************************************************************
811 check if a file exists
812 ********************************************************************/
813 BOOL file_exist(char *fname,struct stat *sbuf)
816 if (!sbuf) sbuf = &st;
818 if (sys_stat(fname,sbuf) != 0)
821 return(S_ISREG(sbuf->st_mode));
824 /*******************************************************************
825 check a files mod time
826 ********************************************************************/
827 time_t file_modtime(char *fname)
831 if (sys_stat(fname,&st) != 0)
837 /*******************************************************************
838 check if a directory exists
839 ********************************************************************/
840 BOOL directory_exist(char *dname,struct stat *st)
847 if (sys_stat(dname,st) != 0)
850 ret = S_ISDIR(st->st_mode);
856 /*******************************************************************
857 returns the size in bytes of the named file
858 ********************************************************************/
859 uint32 file_size(char *file_name)
863 sys_stat(file_name,&buf);
867 /*******************************************************************
868 return a string representing an attribute for a file
869 ********************************************************************/
870 char *attrib_string(int mode)
872 static fstring attrstr;
876 if (mode & aVOLID) fstrcat(attrstr,"V");
877 if (mode & aDIR) fstrcat(attrstr,"D");
878 if (mode & aARCH) fstrcat(attrstr,"A");
879 if (mode & aHIDDEN) fstrcat(attrstr,"H");
880 if (mode & aSYSTEM) fstrcat(attrstr,"S");
881 if (mode & aRONLY) fstrcat(attrstr,"R");
887 /*******************************************************************
888 case insensitive string compararison
889 ********************************************************************/
890 int StrCaseCmp(char *s, char *t)
892 /* compare until we run out of string, either t or s, or find a difference */
893 /* We *must* use toupper rather than tolower here due to the
894 asynchronous upper to lower mapping.
896 #if !defined(KANJI_WIN95_COMPATIBILITY)
898 * For completeness we should put in equivalent code for code pages
899 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
900 * doubt anyone wants Samba to behave differently from Win95 and WinNT
901 * here. They both treat full width ascii characters as case senstive
902 * filenames (ie. they don't do the work we do here).
906 if(lp_client_code_page() == KANJI_CODEPAGE)
908 /* Win95 treats full width ascii characters as case sensitive. */
913 return toupper (*s) - toupper (*t);
914 else if (is_sj_alph (*s) && is_sj_alph (*t))
916 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
922 else if (is_shift_jis (*s) && is_shift_jis (*t))
924 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
927 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
933 else if (is_shift_jis (*s))
935 else if (is_shift_jis (*t))
939 diff = toupper (*s) - toupper (*t);
948 #endif /* KANJI_WIN95_COMPATIBILITY */
950 while (*s && *t && toupper(*s) == toupper(*t))
956 return(toupper(*s) - toupper(*t));
960 /*******************************************************************
961 case insensitive string compararison, length limited
962 ********************************************************************/
963 int StrnCaseCmp(char *s, char *t, int n)
965 /* compare until we run out of string, either t or s, or chars */
966 /* We *must* use toupper rather than tolower here due to the
967 asynchronous upper to lower mapping.
969 #if !defined(KANJI_WIN95_COMPATIBILITY)
971 * For completeness we should put in equivalent code for code pages
972 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
973 * doubt anyone wants Samba to behave differently from Win95 and WinNT
974 * here. They both treat full width ascii characters as case senstive
975 * filenames (ie. they don't do the work we do here).
979 if(lp_client_code_page() == KANJI_CODEPAGE)
981 /* Win95 treats full width ascii characters as case sensitive. */
986 return toupper (*s) - toupper (*t);
987 else if (is_sj_alph (*s) && is_sj_alph (*t))
989 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
996 else if (is_shift_jis (*s) && is_shift_jis (*t))
998 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
1001 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1008 else if (is_shift_jis (*s))
1010 else if (is_shift_jis (*t))
1014 diff = toupper (*s) - toupper (*t);
1025 #endif /* KANJI_WIN95_COMPATIBILITY */
1027 while (n && *s && *t && toupper(*s) == toupper(*t))
1034 /* not run out of chars - strings are different lengths */
1036 return(toupper(*s) - toupper(*t));
1038 /* identical up to where we run out of chars,
1039 and strings are same length */
1044 /*******************************************************************
1046 ********************************************************************/
1047 BOOL strequal(char *s1, char *s2)
1049 if (s1 == s2) return(True);
1050 if (!s1 || !s2) return(False);
1052 return(StrCaseCmp(s1,s2)==0);
1055 /*******************************************************************
1056 compare 2 strings up to and including the nth char.
1057 ******************************************************************/
1058 BOOL strnequal(char *s1,char *s2,int n)
1060 if (s1 == s2) return(True);
1061 if (!s1 || !s2 || !n) return(False);
1063 return(StrnCaseCmp(s1,s2,n)==0);
1066 /*******************************************************************
1067 compare 2 strings (case sensitive)
1068 ********************************************************************/
1069 BOOL strcsequal(char *s1,char *s2)
1071 if (s1 == s2) return(True);
1072 if (!s1 || !s2) return(False);
1074 return(strcmp(s1,s2)==0);
1078 /*******************************************************************
1079 convert a string to lower case
1080 ********************************************************************/
1081 void strlower(char *s)
1085 #if !defined(KANJI_WIN95_COMPATIBILITY)
1087 * For completeness we should put in equivalent code for code pages
1088 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1089 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1090 * here. They both treat full width ascii characters as case senstive
1091 * filenames (ie. they don't do the work we do here).
1095 if(lp_client_code_page() == KANJI_CODEPAGE)
1097 /* Win95 treats full width ascii characters as case sensitive. */
1098 if (is_shift_jis (*s))
1100 if (is_sj_upper (s[0], s[1]))
1101 s[1] = sj_tolower2 (s[1]);
1104 else if (is_kana (*s))
1116 #endif /* KANJI_WIN95_COMPATIBILITY */
1125 /*******************************************************************
1126 convert a string to upper case
1127 ********************************************************************/
1128 void strupper(char *s)
1132 #if !defined(KANJI_WIN95_COMPATIBILITY)
1134 * For completeness we should put in equivalent code for code pages
1135 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1136 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1137 * here. They both treat full width ascii characters as case senstive
1138 * filenames (ie. they don't do the work we do here).
1142 if(lp_client_code_page() == KANJI_CODEPAGE)
1144 /* Win95 treats full width ascii characters as case sensitive. */
1145 if (is_shift_jis (*s))
1147 if (is_sj_lower (s[0], s[1]))
1148 s[1] = sj_toupper2 (s[1]);
1151 else if (is_kana (*s))
1163 #endif /* KANJI_WIN95_COMPATIBILITY */
1172 /*******************************************************************
1173 convert a string to "normal" form
1174 ********************************************************************/
1175 void strnorm(char *s)
1177 if (case_default == CASE_UPPER)
1183 /*******************************************************************
1184 check if a string is in "normal" case
1185 ********************************************************************/
1186 BOOL strisnormal(char *s)
1188 if (case_default == CASE_UPPER)
1189 return(!strhaslower(s));
1191 return(!strhasupper(s));
1195 /****************************************************************************
1197 ****************************************************************************/
1198 void string_replace(char *s,char oldc,char newc)
1202 #if !defined(KANJI_WIN95_COMPATIBILITY)
1204 * For completeness we should put in equivalent code for code pages
1205 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1206 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1207 * here. They both treat full width ascii characters as case senstive
1208 * filenames (ie. they don't do the work we do here).
1212 if(lp_client_code_page() == KANJI_CODEPAGE)
1214 /* Win95 treats full width ascii characters as case sensitive. */
1215 if (is_shift_jis (*s))
1217 else if (is_kana (*s))
1227 #endif /* KANJI_WIN95_COMPATIBILITY */
1236 /****************************************************************************
1237 make a file into unix format
1238 ****************************************************************************/
1239 void unix_format(char *fname)
1242 string_replace(fname,'\\','/');
1246 pstrcpy(namecopy,fname);
1248 pstrcat(fname,namecopy);
1252 /****************************************************************************
1253 make a file into dos format
1254 ****************************************************************************/
1255 void dos_format(char *fname)
1257 string_replace(fname,'/','\\');
1260 /*******************************************************************
1261 show a smb message structure
1262 ********************************************************************/
1263 void show_msg(char *buf)
1268 if (DEBUGLEVEL < 5) return;
1270 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1272 (int)CVAL(buf,smb_com),
1273 (int)CVAL(buf,smb_rcls),
1274 (int)CVAL(buf,smb_reh),
1275 (int)SVAL(buf,smb_err),
1276 (int)CVAL(buf,smb_flg),
1277 (int)SVAL(buf,smb_flg2)));
1278 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1279 (int)SVAL(buf,smb_tid),
1280 (int)SVAL(buf,smb_pid),
1281 (int)SVAL(buf,smb_uid),
1282 (int)SVAL(buf,smb_mid),
1283 (int)CVAL(buf,smb_wct)));
1285 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1287 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1288 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1291 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1293 DEBUG(5,("smb_bcc=%d\n",bcc));
1295 if (DEBUGLEVEL < 10) return;
1297 if (DEBUGLEVEL < 50)
1299 bcc = MIN(bcc, 512);
1302 dump_data(10, smb_buf(buf), bcc);
1304 /*******************************************************************
1305 return the length of an smb packet
1306 ********************************************************************/
1307 int smb_len(char *buf)
1309 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1312 /*******************************************************************
1313 set the length of an smb packet
1314 ********************************************************************/
1315 void _smb_setlen(char *buf,int len)
1318 buf[1] = (len&0x10000)>>16;
1319 buf[2] = (len&0xFF00)>>8;
1323 /*******************************************************************
1324 set the length and marker of an smb packet
1325 ********************************************************************/
1326 void smb_setlen(char *buf,int len)
1328 _smb_setlen(buf,len);
1336 /*******************************************************************
1337 setup the word count and byte count for a smb message
1338 ********************************************************************/
1339 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1342 bzero(buf + smb_size,num_words*2 + num_bytes);
1343 CVAL(buf,smb_wct) = num_words;
1344 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1345 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1346 return (smb_size + num_words*2 + num_bytes);
1349 /*******************************************************************
1350 return the number of smb words
1351 ********************************************************************/
1352 int smb_numwords(char *buf)
1354 return (CVAL(buf,smb_wct));
1357 /*******************************************************************
1358 return the size of the smb_buf region of a message
1359 ********************************************************************/
1360 int smb_buflen(char *buf)
1362 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1365 /*******************************************************************
1366 return a pointer to the smb_buf data area
1367 ********************************************************************/
1368 int smb_buf_ofs(char *buf)
1370 return (smb_size + CVAL(buf,smb_wct)*2);
1373 /*******************************************************************
1374 return a pointer to the smb_buf data area
1375 ********************************************************************/
1376 char *smb_buf(char *buf)
1378 return (buf + smb_buf_ofs(buf));
1381 /*******************************************************************
1382 return the SMB offset into an SMB buffer
1383 ********************************************************************/
1384 int smb_offset(char *p,char *buf)
1386 return(PTR_DIFF(p,buf+4) + chain_size);
1390 /*******************************************************************
1391 skip past some strings in a buffer
1392 ********************************************************************/
1393 char *skip_string(char *buf,int n)
1396 buf += strlen(buf) + 1;
1400 /*******************************************************************
1401 trim the specified elements off the front and back of a string
1402 ********************************************************************/
1403 BOOL trim_string(char *s,char *front,char *back)
1406 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1412 if (!(*p = p[strlen(front)]))
1417 while (back && *back && strlen(s) >= strlen(back) &&
1418 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1421 s[strlen(s)-strlen(back)] = 0;
1427 /*******************************************************************
1428 reduce a file name, removing .. elements.
1429 ********************************************************************/
1430 void dos_clean_name(char *s)
1434 DEBUG(3,("dos_clean_name [%s]\n",s));
1436 /* remove any double slashes */
1437 string_sub(s, "\\\\", "\\");
1439 while ((p = strstr(s,"\\..\\")) != NULL)
1446 if ((p=strrchr(s,'\\')) != NULL)
1453 trim_string(s,NULL,"\\..");
1455 string_sub(s, "\\.\\", "\\");
1458 /*******************************************************************
1459 reduce a file name, removing .. elements.
1460 ********************************************************************/
1461 void unix_clean_name(char *s)
1465 DEBUG(3,("unix_clean_name [%s]\n",s));
1467 /* remove any double slashes */
1468 string_sub(s, "//","/");
1470 /* Remove leading ./ characters */
1471 if(strncmp(s, "./", 2) == 0) {
1472 trim_string(s, "./", NULL);
1477 while ((p = strstr(s,"/../")) != NULL)
1484 if ((p=strrchr(s,'/')) != NULL)
1491 trim_string(s,NULL,"/..");
1495 /*******************************************************************
1496 a wrapper for the normal chdir() function
1497 ********************************************************************/
1498 int ChDir(char *path)
1501 static pstring LastDir="";
1503 if (strcsequal(path,".")) return(0);
1505 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1506 DEBUG(3,("chdir to %s\n",path));
1507 res = sys_chdir(path);
1509 pstrcpy(LastDir,path);
1513 /* number of list structures for a caching GetWd function. */
1514 #define MAX_GETWDCACHE (50)
1522 } ino_list[MAX_GETWDCACHE];
1524 BOOL use_getwd_cache=True;
1526 /*******************************************************************
1527 return the absolute current directory path
1528 ********************************************************************/
1529 char *GetWd(char *str)
1532 static BOOL getwd_cache_init = False;
1533 struct stat st, st2;
1538 if (!use_getwd_cache)
1539 return(sys_getwd(str));
1541 /* init the cache */
1542 if (!getwd_cache_init)
1544 getwd_cache_init = True;
1545 for (i=0;i<MAX_GETWDCACHE;i++)
1547 string_init(&ino_list[i].text,"");
1548 ino_list[i].valid = False;
1552 /* Get the inode of the current directory, if this doesn't work we're
1555 if (stat(".",&st) == -1)
1557 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1558 return(sys_getwd(str));
1562 for (i=0; i<MAX_GETWDCACHE; i++)
1563 if (ino_list[i].valid)
1566 /* If we have found an entry with a matching inode and dev number
1567 then find the inode number for the directory in the cached string.
1568 If this agrees with that returned by the stat for the current
1569 directory then all is o.k. (but make sure it is a directory all
1572 if (st.st_ino == ino_list[i].inode &&
1573 st.st_dev == ino_list[i].dev)
1575 if (stat(ino_list[i].text,&st2) == 0)
1577 if (st.st_ino == st2.st_ino &&
1578 st.st_dev == st2.st_dev &&
1579 (st2.st_mode & S_IFMT) == S_IFDIR)
1581 pstrcpy (str, ino_list[i].text);
1583 /* promote it for future use */
1584 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1589 /* If the inode is different then something's changed,
1590 scrub the entry and start from scratch. */
1591 ino_list[i].valid = False;
1598 /* We don't have the information to hand so rely on traditional methods.
1599 The very slow getcwd, which spawns a process on some systems, or the
1600 not quite so bad getwd. */
1604 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1610 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1612 /* add it to the cache */
1613 i = MAX_GETWDCACHE - 1;
1614 string_set(&ino_list[i].text,s);
1615 ino_list[i].dev = st.st_dev;
1616 ino_list[i].inode = st.st_ino;
1617 ino_list[i].valid = True;
1619 /* put it at the top of the list */
1620 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1627 /*******************************************************************
1628 reduce a file name, removing .. elements and checking that
1629 it is below dir in the heirachy. This uses GetWd() and so must be run
1630 on the system that has the referenced file system.
1632 widelinks are allowed if widelinks is true
1633 ********************************************************************/
1634 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1636 #ifndef REDUCE_PATHS
1644 BOOL relative = (*s != '/');
1646 *dir2 = *wd = *base_name = *newname = 0;
1651 /* can't have a leading .. */
1652 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1654 DEBUG(3,("Illegal file name? (%s)\n",s));
1664 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1666 /* remove any double slashes */
1667 string_sub(s,"//","/");
1669 pstrcpy(base_name,s);
1670 p = strrchr(base_name,'/');
1677 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1681 if (ChDir(dir) != 0)
1683 DEBUG(0,("couldn't chdir to %s\n",dir));
1689 DEBUG(0,("couldn't getwd for %s\n",dir));
1695 if (p && (p != base_name))
1698 if (strcmp(p+1,".")==0)
1700 if (strcmp(p+1,"..")==0)
1704 if (ChDir(base_name) != 0)
1707 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1711 if (!GetWd(newname))
1714 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1718 if (p && (p != base_name))
1720 pstrcat(newname,"/");
1721 pstrcat(newname,p+1);
1725 int l = strlen(dir2);
1726 if (dir2[l-1] == '/')
1729 if (strncmp(newname,dir2,l) != 0)
1732 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1738 if (newname[l] == '/')
1739 pstrcpy(s,newname + l + 1);
1741 pstrcpy(s,newname+l);
1752 DEBUG(3,("reduced to %s\n",s));
1757 /****************************************************************************
1759 ****************************************************************************/
1760 static void expand_one(char *Mask,int len)
1763 while ((p1 = strchr(Mask,'*')) != NULL)
1765 int lfill = (len+1) - strlen(Mask);
1766 int l1= (p1 - Mask);
1769 memset(tmp+l1,'?',lfill);
1770 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1775 /****************************************************************************
1776 expand a wildcard expression, replacing *s with ?s
1777 ****************************************************************************/
1778 void expand_mask(char *Mask,BOOL doext)
1783 BOOL hasdot = False;
1785 BOOL absolute = (*Mask == '\\');
1787 *mbeg = *mext = *dirpart = *filepart = 0;
1789 /* parse the directory and filename */
1790 if (strchr(Mask,'\\'))
1791 dirname_dos(Mask,dirpart);
1793 filename_dos(Mask,filepart);
1795 pstrcpy(mbeg,filepart);
1796 if ((p1 = strchr(mbeg,'.')) != NULL)
1806 if (strlen(mbeg) > 8)
1808 pstrcpy(mext,mbeg + 8);
1814 pstrcpy(mbeg,"????????");
1815 if ((*mext == 0) && doext && !hasdot)
1816 pstrcpy(mext,"???");
1818 if (strequal(mbeg,"*") && *mext==0)
1826 pstrcpy(Mask,dirpart);
1827 if (*dirpart || absolute) pstrcat(Mask,"\\");
1832 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1836 /****************************************************************************
1837 does a string have any uppercase chars in it?
1838 ****************************************************************************/
1839 BOOL strhasupper(char *s)
1843 #if !defined(KANJI_WIN95_COMPATIBILITY)
1845 * For completeness we should put in equivalent code for code pages
1846 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1847 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1848 * here. They both treat full width ascii characters as case senstive
1849 * filenames (ie. they don't do the work we do here).
1853 if(lp_client_code_page() == KANJI_CODEPAGE)
1855 /* Win95 treats full width ascii characters as case sensitive. */
1856 if (is_shift_jis (*s))
1858 else if (is_kana (*s))
1868 #endif /* KANJI_WIN95_COMPATIBILITY */
1878 /****************************************************************************
1879 does a string have any lowercase chars in it?
1880 ****************************************************************************/
1881 BOOL strhaslower(char *s)
1885 #if !defined(KANJI_WIN95_COMPATIBILITY)
1887 * For completeness we should put in equivalent code for code pages
1888 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1889 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1890 * here. They both treat full width ascii characters as case senstive
1891 * filenames (ie. they don't do the work we do here).
1895 if(lp_client_code_page() == KANJI_CODEPAGE)
1897 /* Win95 treats full width ascii characters as case sensitive. */
1898 if (is_shift_jis (*s))
1900 if (is_sj_upper (s[0], s[1]))
1902 if (is_sj_lower (s[0], s[1]))
1906 else if (is_kana (*s))
1918 #endif /* KANJI_WIN95_COMPATIBILITY */
1928 /****************************************************************************
1929 find the number of chars in a string
1930 ****************************************************************************/
1931 int count_chars(char *s,char c)
1935 #if !defined(KANJI_WIN95_COMPATIBILITY)
1937 * For completeness we should put in equivalent code for code pages
1938 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1939 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1940 * here. They both treat full width ascii characters as case senstive
1941 * filenames (ie. they don't do the work we do here).
1945 if(lp_client_code_page() == KANJI_CODEPAGE)
1947 /* Win95 treats full width ascii characters as case sensitive. */
1950 if (is_shift_jis (*s))
1961 #endif /* KANJI_WIN95_COMPATIBILITY */
1974 /****************************************************************************
1976 ****************************************************************************/
1977 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1982 pstrcpy(mask2,mask);
1984 if ((mode & aDIR) != 0)
1987 memset(buf+1,' ',11);
1988 if ((p = strchr(mask2,'.')) != NULL)
1991 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1992 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1996 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1998 bzero(buf+21,DIR_STRUCT_SIZE-21);
1999 CVAL(buf,21) = mode;
2000 put_dos_date(buf,22,date);
2001 SSVAL(buf,26,size & 0xFFFF);
2002 SSVAL(buf,28,size >> 16);
2003 StrnCpy(buf+30,fname,12);
2004 if (!case_sensitive)
2006 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2010 /*******************************************************************
2011 close the low 3 fd's and open dev/null in their place
2012 ********************************************************************/
2013 void close_low_fds(void)
2017 close(0); close(1); close(2);
2018 /* try and use up these file descriptors, so silly
2019 library routines writing to stdout etc won't cause havoc */
2021 fd = open("/dev/null",O_RDWR,0);
2022 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2024 DEBUG(0,("Can't open /dev/null\n"));
2028 DEBUG(0,("Didn't get file descriptor %d\n",i));
2034 /****************************************************************************
2035 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2037 if SYSV use O_NDELAY
2039 ****************************************************************************/
2040 int set_blocking(int fd, BOOL set)
2044 #define FLAG_TO_SET O_NONBLOCK
2047 #define FLAG_TO_SET O_NDELAY
2049 #define FLAG_TO_SET FNDELAY
2053 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2055 if(set) /* Turn blocking on - ie. clear nonblock flag */
2056 val &= ~FLAG_TO_SET;
2059 return fcntl( fd, F_SETFL, val);
2064 /****************************************************************************
2066 ****************************************************************************/
2067 int write_socket(int fd,char *buf,int len)
2073 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2074 ret = write_data(fd,buf,len);
2076 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2078 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2079 len, fd, strerror(errno) ));
2084 /****************************************************************************
2086 ****************************************************************************/
2087 int read_udp_socket(int fd,char *buf,int len)
2090 struct sockaddr_in sock;
2093 socklen = sizeof(sock);
2094 bzero((char *)&sock,socklen);
2095 bzero((char *)&lastip,sizeof(lastip));
2096 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2098 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2102 lastip = sock.sin_addr;
2103 lastport = ntohs(sock.sin_port);
2105 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2106 inet_ntoa(lastip), lastport, ret));
2111 /****************************************************************************
2112 read data from a device with a timout in msec.
2113 mincount = if timeout, minimum to read before returning
2114 maxcount = number to be read.
2115 ****************************************************************************/
2116 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2122 struct timeval timeout;
2124 /* just checking .... */
2125 if (maxcnt <= 0) return(0);
2130 if (time_out <= 0) {
2131 if (mincnt == 0) mincnt = maxcnt;
2133 while (nread < mincnt) {
2134 readret = read(fd, buf + nread, maxcnt - nread);
2136 smb_read_error = READ_EOF;
2140 if (readret == -1) {
2141 smb_read_error = READ_ERROR;
2149 /* Most difficult - timeout read */
2150 /* If this is ever called on a disk file and
2151 mincnt is greater then the filesize then
2152 system performance will suffer severely as
2153 select always return true on disk files */
2155 /* Set initial timeout */
2156 timeout.tv_sec = time_out / 1000;
2157 timeout.tv_usec = 1000 * (time_out % 1000);
2159 for (nread=0; nread<mincnt; )
2164 selrtn = sys_select(&fds,&timeout);
2166 /* Check if error */
2168 /* something is wrong. Maybe the socket is dead? */
2169 smb_read_error = READ_ERROR;
2173 /* Did we timeout ? */
2175 smb_read_error = READ_TIMEOUT;
2179 readret = read(fd, buf+nread, maxcnt-nread);
2181 /* we got EOF on the file descriptor */
2182 smb_read_error = READ_EOF;
2186 if (readret == -1) {
2187 /* the descriptor is probably dead */
2188 smb_read_error = READ_ERROR;
2195 /* Return the number we got */
2199 /****************************************************************************
2200 read data from the client. Maxtime is in milliseconds
2201 ****************************************************************************/
2202 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2207 struct timeval timeout;
2212 timeout.tv_sec = maxtime / 1000;
2213 timeout.tv_usec = (maxtime % 1000) * 1000;
2215 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2217 if (!FD_ISSET(fd,&fds))
2220 nread = read_udp_socket(fd, buffer, bufsize);
2222 /* return the number got */
2226 /*******************************************************************
2227 find the difference in milliseconds between two struct timeval
2229 ********************************************************************/
2230 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2232 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2233 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2236 /****************************************************************************
2237 send a keepalive packet (rfc1002)
2238 ****************************************************************************/
2239 BOOL send_keepalive(int client)
2241 unsigned char buf[4];
2244 buf[1] = buf[2] = buf[3] = 0;
2246 return(write_data(client,(char *)buf,4) == 4);
2251 /****************************************************************************
2252 read data from the client, reading exactly N bytes.
2253 ****************************************************************************/
2254 int read_data(int fd,char *buffer,int N)
2263 ret = read(fd,buffer + total,N - total);
2265 smb_read_error = READ_EOF;
2269 smb_read_error = READ_ERROR;
2278 /****************************************************************************
2280 ****************************************************************************/
2281 int write_data(int fd,char *buffer,int N)
2288 ret = write(fd,buffer + total,N - total);
2290 if (ret == -1) return -1;
2291 if (ret == 0) return total;
2299 /****************************************************************************
2300 transfer some data between two fd's
2301 ****************************************************************************/
2302 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2304 static char *buf=NULL;
2309 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2312 size = lp_readsize();
2313 size = MAX(size,1024);
2316 while (!buf && size>0) {
2317 buf = (char *)Realloc(buf,size+8);
2318 if (!buf) size /= 2;
2322 DEBUG(0,("Can't allocate transfer buffer!\n"));
2326 abuf = buf + (align%8);
2333 int s = MIN(n,size);
2338 if (header && (headlen >= MIN(s,1024))) {
2348 if (header && headlen > 0)
2350 ret = MIN(headlen,size);
2351 memcpy(buf1,header,ret);
2354 if (headlen <= 0) header = NULL;
2358 ret += read(infd,buf1+ret,s-ret);
2362 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2363 if (ret2 > 0) total += ret2;
2364 /* if we can't write then dump excess data */
2366 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2368 if (ret <= 0 || ret2 != ret)
2376 /****************************************************************************
2377 read 4 bytes of a smb packet and return the smb length of the packet
2378 store the result in the buffer
2379 This version of the function will return a length of zero on receiving
2381 ****************************************************************************/
2382 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2384 int len=0, msg_type;
2390 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2392 ok = (read_data(fd,inbuf,4) == 4);
2397 len = smb_len(inbuf);
2398 msg_type = CVAL(inbuf,0);
2400 if (msg_type == 0x85)
2401 DEBUG(5,("Got keepalive packet\n"));
2404 DEBUG(10,("got smb length of %d\n",len));
2409 /****************************************************************************
2410 read 4 bytes of a smb packet and return the smb length of the packet
2411 store the result in the buffer. This version of the function will
2412 never return a session keepalive (length of zero).
2413 ****************************************************************************/
2414 int read_smb_length(int fd,char *inbuf,int timeout)
2420 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2425 /* Ignore session keepalives. */
2426 if(CVAL(inbuf,0) != 0x85)
2433 /****************************************************************************
2434 read an smb from a fd. Note that the buffer *MUST* be of size
2435 BUFFER_SIZE+SAFETY_MARGIN.
2436 The timeout is in milli seconds.
2438 This function will return on a
2439 receipt of a session keepalive packet.
2440 ****************************************************************************/
2441 BOOL receive_smb(int fd,char *buffer, int timeout)
2447 bzero(buffer,smb_size + 100);
2449 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2453 if (len > BUFFER_SIZE) {
2454 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2455 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2460 ret = read_data(fd,buffer+4,len);
2462 smb_read_error = READ_ERROR;
2469 /****************************************************************************
2470 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2471 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2472 The timeout is in milli seconds
2474 This is exactly the same as receive_smb except that it never returns
2475 a session keepalive packet (just as receive_smb used to do).
2476 receive_smb was changed to return keepalives as the oplock processing means this call
2477 should never go into a blocking read.
2478 ****************************************************************************/
2480 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2486 ret = receive_smb(fd, buffer, timeout);
2491 /* Ignore session keepalive packets. */
2492 if(CVAL(buffer,0) != 0x85)
2498 /****************************************************************************
2499 read a message from a udp fd.
2500 The timeout is in milli seconds
2501 ****************************************************************************/
2502 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2504 struct sockaddr_in from;
2505 int fromlen = sizeof(from);
2519 to.tv_sec = timeout / 1000;
2520 to.tv_usec = (timeout % 1000) * 1000;
2522 selrtn = sys_select(&fds,&to);
2524 /* Check if error */
2527 /* something is wrong. Maybe the socket is dead? */
2528 smb_read_error = READ_ERROR;
2532 /* Did we timeout ? */
2535 smb_read_error = READ_TIMEOUT;
2541 * Read a loopback udp message.
2543 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2544 buffer_len - UDP_CMD_HEADER_LEN, 0,
2545 (struct sockaddr *)&from, &fromlen);
2549 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2553 /* Validate message length. */
2554 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2556 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2558 buffer_len - UDP_CMD_HEADER_LEN));
2562 /* Validate message from address (must be localhost). */
2563 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2565 DEBUG(0,("receive_local_message: invalid 'from' address \
2566 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2570 /* Setup the message header */
2571 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2572 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2577 /****************************************************************************
2578 structure to hold a linked list of local messages.
2580 ****************************************************************************/
2582 typedef struct _message_list {
2583 struct _message_list *msg_next;
2586 } pending_message_list;
2588 static pending_message_list *smb_msg_head = NULL;
2590 /****************************************************************************
2591 Function to push a linked list of local messages ready
2593 ****************************************************************************/
2595 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2597 pending_message_list *msg = (pending_message_list *)
2598 malloc(sizeof(pending_message_list));
2602 DEBUG(0,("push_message: malloc fail (1)\n"));
2606 msg->msg_buf = (char *)malloc(msg_len);
2607 if(msg->msg_buf == NULL)
2609 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2614 memcpy(msg->msg_buf, buf, msg_len);
2615 msg->msg_len = msg_len;
2617 msg->msg_next = *pml;
2623 /****************************************************************************
2624 Function to push a linked list of local smb messages ready
2626 ****************************************************************************/
2628 BOOL push_smb_message(char *buf, int msg_len)
2630 return push_local_message(&smb_msg_head, buf, msg_len);
2633 /****************************************************************************
2634 Do a select on an two fd's - with timeout.
2636 If a local udp message has been pushed onto the
2637 queue (this can only happen during oplock break
2638 processing) return this first.
2640 If a pending smb message has been pushed onto the
2641 queue (this can only happen during oplock break
2642 processing) return this next.
2644 If the first smbfd is ready then read an smb from it.
2645 if the second (loopback UDP) fd is ready then read a message
2646 from it and setup the buffer header to identify the length
2648 Returns False on timeout or error.
2651 The timeout is in milli seconds
2652 ****************************************************************************/
2653 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2654 char *buffer, int buffer_len,
2655 int timeout, BOOL *got_smb)
2666 * Check to see if we already have a message on the smb queue.
2667 * If so - copy and return it.
2672 pending_message_list *msg = smb_msg_head;
2673 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2674 smb_msg_head = msg->msg_next;
2676 /* Free the message we just copied. */
2677 free((char *)msg->msg_buf);
2681 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2687 FD_SET(oplock_fd,&fds);
2689 to.tv_sec = timeout / 1000;
2690 to.tv_usec = (timeout % 1000) * 1000;
2692 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2694 /* Check if error */
2696 /* something is wrong. Maybe the socket is dead? */
2697 smb_read_error = READ_ERROR;
2701 /* Did we timeout ? */
2703 smb_read_error = READ_TIMEOUT;
2707 if (FD_ISSET(smbfd,&fds))
2710 return receive_smb(smbfd, buffer, 0);
2714 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2718 /****************************************************************************
2720 ****************************************************************************/
2721 BOOL send_smb(int fd,char *buffer)
2725 len = smb_len(buffer) + 4;
2727 while (nwritten < len)
2729 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2732 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2744 /****************************************************************************
2745 find a pointer to a netbios name
2746 ****************************************************************************/
2747 char *name_ptr(char *buf,int ofs)
2749 unsigned char c = *(unsigned char *)(buf+ofs);
2751 if ((c & 0xC0) == 0xC0)
2755 memcpy(p,buf+ofs,2);
2758 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2765 /****************************************************************************
2766 extract a netbios name from a buf
2767 ****************************************************************************/
2768 int name_extract(char *buf,int ofs,char *name)
2770 char *p = name_ptr(buf,ofs);
2771 int d = PTR_DIFF(p,buf+ofs);
2773 if (d < -50 || d > 50) return(0);
2774 return(name_interpret(p,name));
2777 /****************************************************************************
2778 return the total storage length of a mangled name
2779 ****************************************************************************/
2780 int name_len( char *s )
2784 /* If the two high bits of the byte are set, return 2. */
2785 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2788 /* Add up the length bytes. */
2789 for( len = 1; (*s); s += (*s) + 1 )
2797 /****************************************************************************
2798 send a single packet to a port on another machine
2799 ****************************************************************************/
2800 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2804 struct sockaddr_in sock_out;
2809 /* create a socket to write to */
2810 out_fd = socket(AF_INET, type, 0);
2813 DEBUG(0,("socket failed"));
2817 /* set the address and port */
2818 bzero((char *)&sock_out,sizeof(sock_out));
2819 putip((char *)&sock_out.sin_addr,(char *)&ip);
2820 sock_out.sin_port = htons( port );
2821 sock_out.sin_family = AF_INET;
2824 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2825 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2828 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2831 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2832 inet_ntoa(ip),port,strerror(errno)));
2838 /*******************************************************************
2839 sleep for a specified number of milliseconds
2840 ********************************************************************/
2844 struct timeval tval,t1,t2;
2851 tval.tv_sec = (t-tdiff)/1000;
2852 tval.tv_usec = 1000*((t-tdiff)%1000);
2856 sys_select(&fds,&tval);
2859 tdiff = TvalDiff(&t1,&t2);
2863 /****************************************************************************
2864 check if a string is part of a list
2865 ****************************************************************************/
2866 BOOL in_list(char *s,char *list,BOOL casesensitive)
2871 if (!list) return(False);
2873 while (next_token(&p,tok,LIST_SEP))
2875 if (casesensitive) {
2876 if (strcmp(tok,s) == 0)
2879 if (StrCaseCmp(tok,s) == 0)
2886 /* this is used to prevent lots of mallocs of size 1 */
2887 static char *null_string = NULL;
2889 /****************************************************************************
2890 set a string value, allocing the space for the string
2891 ****************************************************************************/
2892 BOOL string_init(char **dest,char *src)
2903 null_string = (char *)malloc(1);
2906 *dest = null_string;
2910 (*dest) = (char *)malloc(l+1);
2911 if ((*dest) == NULL) {
2912 DEBUG(0,("Out of memory in string_init\n"));
2921 /****************************************************************************
2923 ****************************************************************************/
2924 void string_free(char **s)
2926 if (!s || !(*s)) return;
2927 if (*s == null_string)
2933 /****************************************************************************
2934 set a string value, allocing the space for the string, and deallocating any
2936 ****************************************************************************/
2937 BOOL string_set(char **dest,char *src)
2941 return(string_init(dest,src));
2944 /****************************************************************************
2945 substitute a string for a pattern in another string. Make sure there is
2948 This routine looks for pattern in s and replaces it with
2949 insert. It may do multiple replacements.
2951 return True if a substitution was done.
2952 ****************************************************************************/
2953 BOOL string_sub(char *s,char *pattern,char *insert)
2959 if (!insert || !pattern || !s) return(False);
2962 lp = strlen(pattern);
2963 li = strlen(insert);
2965 if (!*pattern) return(False);
2967 while (lp <= ls && (p = strstr(s,pattern)))
2970 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2971 memcpy(p,insert,li);
2980 /*********************************************************
2981 * Recursive routine that is called by mask_match.
2982 * Does the actual matching.
2983 *********************************************************/
2984 BOOL do_match(char *str, char *regexp, int case_sig)
2988 for( p = regexp; *p && *str; ) {
2995 /* Look for a character matching
2996 the one after the '*' */
2999 return True; /* Automatic match */
3001 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
3003 if(do_match(str,p,case_sig))
3017 if(toupper(*str) != toupper(*p))
3027 if (!*p && str[0] == '.' && str[1] == 0)
3030 if (!*str && *p == '?')
3032 while (*p == '?') p++;
3036 if(!*str && (*p == '*' && p[1] == '\0'))
3042 /*********************************************************
3043 * Routine to match a given string with a regexp - uses
3044 * simplified regexp that takes * and ? only. Case can be
3045 * significant or not.
3046 *********************************************************/
3047 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3051 fstring ebase,eext,sbase,sext;
3055 /* Make local copies of str and regexp */
3056 StrnCpy(p1,regexp,sizeof(pstring)-1);
3057 StrnCpy(p2,str,sizeof(pstring)-1);
3059 if (!strchr(p2,'.')) {
3064 if (!strchr(p1,'.')) {
3072 string_sub(p1,"*.*","*");
3073 string_sub(p1,".*","*");
3077 /* Remove any *? and ** as they are meaningless */
3078 for(p = p1; *p; p++)
3079 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3080 (void)pstrcpy( &p[1], &p[2]);
3082 if (strequal(p1,"*")) return(True);
3084 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3090 if ((p=strrchr(p1,'.'))) {
3099 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3109 matched = do_match(sbase,ebase,case_sig) &&
3110 (trans2 || do_match(sext,eext,case_sig));
3112 DEBUG(8,("mask_match returning %d\n", matched));
3119 /****************************************************************************
3120 become a daemon, discarding the controlling terminal
3121 ****************************************************************************/
3122 void become_daemon(void)
3124 #ifndef NO_FORK_DEBUG
3128 /* detach from the terminal */
3131 #else /* USE_SETSID */
3134 int i = open("/dev/tty", O_RDWR);
3137 ioctl(i, (int) TIOCNOTTY, (char *)0);
3141 #endif /* TIOCNOTTY */
3142 #endif /* USE_SETSID */
3143 /* Close fd's 0,1,2. Needed if started by rsh */
3145 #endif /* NO_FORK_DEBUG */
3149 /****************************************************************************
3150 put up a yes/no prompt
3151 ****************************************************************************/
3157 if (!fgets(ans,sizeof(ans)-1,stdin))
3160 if (*ans == 'y' || *ans == 'Y')
3166 /****************************************************************************
3167 read a line from a file with possible \ continuation chars.
3168 Blanks at the start or end of a line are stripped.
3169 The string will be allocated if s2 is NULL
3170 ****************************************************************************/
3171 char *fgets_slash(char *s2,int maxlen,FILE *f)
3176 BOOL start_of_line = True;
3183 maxlen = MIN(maxlen,8);
3184 s = (char *)Realloc(s,maxlen);
3187 if (!s || maxlen < 2) return(NULL);
3191 while (len < maxlen-1)
3199 while (len > 0 && s[len-1] == ' ')
3203 if (len > 0 && s[len-1] == '\\')
3206 start_of_line = True;
3211 if (len <= 0 && !s2)
3213 return(len>0?s:NULL);
3218 start_of_line = False;
3222 if (!s2 && len > maxlen-3)
3225 s = (char *)Realloc(s,maxlen);
3226 if (!s) return(NULL);
3234 /****************************************************************************
3235 set the length of a file from a filedescriptor.
3236 Returns 0 on success, -1 on failure.
3237 ****************************************************************************/
3238 int set_filelen(int fd, long len)
3240 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3241 extend a file with ftruncate. Provide alternate implementation
3244 #if FTRUNCATE_CAN_EXTEND
3245 return ftruncate(fd, len);
3249 long currpos = lseek(fd, 0L, SEEK_CUR);
3253 /* Do an fstat to see if the file is longer than
3254 the requested size (call ftruncate),
3255 or shorter, in which case seek to len - 1 and write 1
3257 if(fstat(fd, &st)<0)
3261 if (S_ISFIFO(st.st_mode)) return 0;
3264 if(st.st_size == len)
3266 if(st.st_size > len)
3267 return ftruncate(fd, len);
3269 if(lseek(fd, len-1, SEEK_SET) != len -1)
3271 if(write(fd, &c, 1)!=1)
3273 /* Seek to where we were */
3274 lseek(fd, currpos, SEEK_SET);
3280 /****************************************************************************
3281 return the byte checksum of some data
3282 ****************************************************************************/
3283 int byte_checksum(char *buf,int len)
3285 unsigned char *p = (unsigned char *)buf;
3295 /****************************************************************************
3296 this is a version of setbuffer() for those machines that only have setvbuf
3297 ****************************************************************************/
3298 void setbuffer(FILE *f,char *buf,int bufsize)
3300 setvbuf(f,buf,_IOFBF,bufsize);
3305 /****************************************************************************
3306 parse out a directory name from a path name. Assumes dos style filenames.
3307 ****************************************************************************/
3308 char *dirname_dos(char *path,char *buf)
3310 char *p = strrchr(path,'\\');
3325 /****************************************************************************
3326 parse out a filename from a path name. Assumes dos style filenames.
3327 ****************************************************************************/
3328 static char *filename_dos(char *path,char *buf)
3330 char *p = strrchr(path,'\\');
3342 /****************************************************************************
3343 expand a pointer to be a particular size
3344 ****************************************************************************/
3345 void *Realloc(void *p,int size)
3351 DEBUG(5,("Realloc asked for 0 bytes\n"));
3356 ret = (void *)malloc(size);
3358 ret = (void *)realloc(p,size);
3361 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3367 /****************************************************************************
3369 ****************************************************************************/
3370 char *strdup(char *s)
3374 if (!s) return(NULL);
3375 ret = (char *)malloc((len = strlen(s))+1);
3376 if (!ret) return(NULL);
3377 safe_strcpy(ret,s,len);
3383 /****************************************************************************
3384 Signal handler for SIGPIPE (write on a disconnected socket)
3385 ****************************************************************************/
3388 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3392 /****************************************************************************
3393 get my own name and IP
3394 ****************************************************************************/
3395 BOOL get_myname(char *my_name,struct in_addr *ip)
3402 /* get my host name */
3403 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3405 DEBUG(0,("gethostname failed\n"));
3410 if ((hp = Get_Hostbyname(hostname)) == 0)
3412 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3418 /* split off any parts after an initial . */
3419 char *p = strchr(hostname,'.');
3422 fstrcpy(my_name,hostname);
3426 putip((char *)ip,(char *)hp->h_addr);
3432 /****************************************************************************
3433 true if two IP addresses are equal
3434 ****************************************************************************/
3435 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3438 a1 = ntohl(ip1.s_addr);
3439 a2 = ntohl(ip2.s_addr);
3444 /****************************************************************************
3445 open a socket of the specified type, port and address for incoming data
3446 ****************************************************************************/
3447 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3450 struct sockaddr_in sock;
3454 /* get my host name */
3455 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3456 { DEBUG(0,("gethostname failed\n")); return -1; }
3459 if ((hp = Get_Hostbyname(host_name)) == 0)
3461 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3465 bzero((char *)&sock,sizeof(sock));
3466 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3467 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3468 sock.sin_len = sizeof(sock);
3470 sock.sin_port = htons( port );
3471 sock.sin_family = hp->h_addrtype;
3472 sock.sin_addr.s_addr = socket_addr;
3473 res = socket(hp->h_addrtype, type, 0);
3475 { DEBUG(0,("socket failed\n")); return -1; }
3479 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3482 /* now we've got a socket - we need to bind it */
3483 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3486 if (port == SMB_PORT || port == NMB_PORT)
3487 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3488 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3491 if (dlevel > 0 && port < 1000)
3494 if (port >= 1000 && port < 9000)
3495 return(open_socket_in(type,port+1,dlevel,socket_addr));
3500 DEBUG(3,("bind succeeded on port %d\n",port));
3506 /****************************************************************************
3507 create an outgoing socket
3508 **************************************************************************/
3509 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3511 struct sockaddr_in sock_out;
3513 int connect_loop = 250; /* 250 milliseconds */
3514 int loops = (timeout * 1000) / connect_loop;
3516 /* create a socket to write to */
3517 res = socket(PF_INET, type, 0);
3519 { DEBUG(0,("socket error\n")); return -1; }
3521 if (type != SOCK_STREAM) return(res);
3523 bzero((char *)&sock_out,sizeof(sock_out));
3524 putip((char *)&sock_out.sin_addr,(char *)addr);
3526 sock_out.sin_port = htons( port );
3527 sock_out.sin_family = PF_INET;
3529 /* set it non-blocking */
3530 set_blocking(res,False);
3532 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3534 /* and connect it to the destination */
3536 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3538 /* Some systems return EAGAIN when they mean EINPROGRESS */
3539 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3540 errno == EAGAIN) && loops--) {
3541 msleep(connect_loop);
3545 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3547 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3553 if (ret < 0 && errno == EISCONN) {
3560 DEBUG(1,("error connecting to %s:%d (%s)\n",
3561 inet_ntoa(*addr),port,strerror(errno)));
3565 /* set it blocking again */
3566 set_blocking(res,True);
3572 /****************************************************************************
3573 interpret a protocol description string, with a default
3574 ****************************************************************************/
3575 int interpret_protocol(char *str,int def)
3577 if (strequal(str,"NT1"))
3578 return(PROTOCOL_NT1);
3579 if (strequal(str,"LANMAN2"))
3580 return(PROTOCOL_LANMAN2);
3581 if (strequal(str,"LANMAN1"))
3582 return(PROTOCOL_LANMAN1);
3583 if (strequal(str,"CORE"))
3584 return(PROTOCOL_CORE);
3585 if (strequal(str,"COREPLUS"))
3586 return(PROTOCOL_COREPLUS);
3587 if (strequal(str,"CORE+"))
3588 return(PROTOCOL_COREPLUS);
3590 DEBUG(0,("Unrecognised protocol level %s\n",str));
3595 /****************************************************************************
3596 interpret a security level
3597 ****************************************************************************/
3598 int interpret_security(char *str,int def)
3600 if (strequal(str,"SERVER"))
3602 if (strequal(str,"USER"))
3604 if (strequal(str,"SHARE"))
3607 DEBUG(0,("Unrecognised security level %s\n",str));
3613 /****************************************************************************
3614 interpret an internet address or name into an IP address in 4 byte form
3615 ****************************************************************************/
3616 uint32 interpret_addr(char *str)
3621 BOOL pure_address = True;
3623 if (strcmp(str,"0.0.0.0") == 0) return(0);
3624 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3626 for (i=0; pure_address && str[i]; i++)
3627 if (!(isdigit(str[i]) || str[i] == '.'))
3628 pure_address = False;
3630 /* if it's in the form of an IP address then get the lib to interpret it */
3632 res = inet_addr(str);
3634 /* otherwise assume it's a network name of some sort and use
3636 if ((hp = Get_Hostbyname(str)) == 0) {
3637 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3640 if(hp->h_addr == NULL) {
3641 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3644 putip((char *)&res,(char *)hp->h_addr);
3647 if (res == (uint32)-1) return(0);
3652 /*******************************************************************
3653 a convenient addition to interpret_addr()
3654 ******************************************************************/
3655 struct in_addr *interpret_addr2(char *str)
3657 static struct in_addr ret;
3658 uint32 a = interpret_addr(str);
3663 /*******************************************************************
3664 check if an IP is the 0.0.0.0
3665 ******************************************************************/
3666 BOOL zero_ip(struct in_addr ip)
3669 putip((char *)&a,(char *)&ip);
3674 /*******************************************************************
3675 matchname - determine if host name matches IP address
3676 ******************************************************************/
3677 static BOOL matchname(char *remotehost,struct in_addr addr)
3682 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3683 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3688 * Make sure that gethostbyname() returns the "correct" host name.
3689 * Unfortunately, gethostbyname("localhost") sometimes yields
3690 * "localhost.domain". Since the latter host name comes from the
3691 * local DNS, we just have to trust it (all bets are off if the local
3692 * DNS is perverted). We always check the address list, though.
3695 if (strcasecmp(remotehost, hp->h_name)
3696 && strcasecmp(remotehost, "localhost")) {
3697 DEBUG(0,("host name/name mismatch: %s != %s",
3698 remotehost, hp->h_name));
3702 /* Look up the host address in the address list we just got. */
3703 for (i = 0; hp->h_addr_list[i]; i++) {
3704 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3709 * The host name does not map to the original host address. Perhaps
3710 * someone has compromised a name server. More likely someone botched
3711 * it, but that could be dangerous, too.
3714 DEBUG(0,("host name/address mismatch: %s != %s",
3715 inet_ntoa(addr), hp->h_name));
3719 /*******************************************************************
3720 Reset the 'done' variables so after a client process is created
3721 from a fork call these calls will be re-done. This should be
3722 expanded if more variables need reseting.
3723 ******************************************************************/
3725 static BOOL global_client_name_done = False;
3726 static BOOL global_client_addr_done = False;
3728 void reset_globals_after_fork(void)
3730 global_client_name_done = False;
3731 global_client_addr_done = False;
3734 /*******************************************************************
3735 return the DNS name of the client
3736 ******************************************************************/
3737 char *client_name(int fd)
3740 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3741 int length = sizeof(sa);
3742 static pstring name_buf;
3744 static int last_fd=-1;
3746 if (global_client_name_done && last_fd == fd)
3750 global_client_name_done = False;
3752 pstrcpy(name_buf,"UNKNOWN");
3758 if (getpeername(fd, &sa, &length) < 0) {
3759 DEBUG(0,("getpeername failed\n"));
3763 /* Look up the remote host name. */
3764 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3765 sizeof(sockin->sin_addr),
3767 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3768 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3770 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3771 if (!matchname(name_buf, sockin->sin_addr)) {
3772 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3773 pstrcpy(name_buf,"UNKNOWN");
3776 global_client_name_done = True;
3780 /*******************************************************************
3781 return the IP addr of the client as a string
3782 ******************************************************************/
3783 char *client_addr(int fd)
3786 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3787 int length = sizeof(sa);
3788 static fstring addr_buf;
3789 static int last_fd = -1;
3791 if (global_client_addr_done && fd == last_fd)
3795 global_client_addr_done = False;
3797 fstrcpy(addr_buf,"0.0.0.0");
3803 if (getpeername(fd, &sa, &length) < 0) {
3804 DEBUG(0,("getpeername failed\n"));
3808 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3810 global_client_addr_done = True;
3814 /*******************************************************************
3815 Patch from jkf@soton.ac.uk
3816 Split Luke's automount_server into YP lookup and string splitter
3817 so can easily implement automount_path().
3818 As we may end up doing both, cache the last YP result.
3819 *******************************************************************/
3821 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3823 static char *automount_lookup(char *user_name)
3825 static fstring last_key = "";
3826 static pstring last_value = "";
3828 char *nis_map = (char *)lp_nis_home_map_name();
3830 char nis_domain[NIS_MAXNAMELEN + 1];
3831 char buffer[NIS_MAXATTRVAL + 1];
3836 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3837 nis_domain[NIS_MAXNAMELEN] = '\0';
3839 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3841 if (strcmp(user_name, last_key))
3843 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3844 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3846 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3848 if (result->status != NIS_SUCCESS)
3850 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3851 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3855 object = result->objects.objects_val;
3856 if (object->zo_data.zo_type == ENTRY_OBJ)
3858 entry = &object->zo_data.objdata_u.en_data;
3859 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3860 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3862 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3863 string_sub(last_value, "&", user_name);
3864 fstrcpy(last_key, user_name);
3868 nis_freeresult(result);
3870 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3874 static char *automount_lookup(char *user_name)
3876 static fstring last_key = "";
3877 static pstring last_value = "";
3879 int nis_error; /* returned by yp all functions */
3880 char *nis_result; /* yp_match inits this */
3881 int nis_result_len; /* and set this */
3882 char *nis_domain; /* yp_get_default_domain inits this */
3883 char *nis_map = (char *)lp_nis_home_map_name();
3885 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3887 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3891 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3893 if (!strcmp(user_name, last_key))
3895 nis_result = last_value;
3896 nis_result_len = strlen(last_value);
3901 if ((nis_error = yp_match(nis_domain, nis_map,
3902 user_name, strlen(user_name),
3903 &nis_result, &nis_result_len)) != 0)
3905 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3906 yperr_string(nis_error), user_name, nis_map));
3908 if (!nis_error && nis_result_len >= sizeof(pstring))
3910 nis_result_len = sizeof(pstring)-1;
3912 fstrcpy(last_key, user_name);
3913 strncpy(last_value, nis_result, nis_result_len);
3914 last_value[nis_result_len] = '\0';
3917 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3920 #endif /* NISPLUS */
3923 /*******************************************************************
3924 Patch from jkf@soton.ac.uk
3925 This is Luke's original function with the NIS lookup code
3926 moved out to a separate function.
3927 *******************************************************************/
3929 char *automount_server(char *user_name)
3931 static pstring server_name;
3933 /* use the local machine name as the default */
3934 /* this will be the default if AUTOMOUNT is not used or fails */
3935 pstrcpy(server_name, local_machine);
3937 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3939 if (lp_nis_home_map())
3941 int home_server_len;
3942 char *automount_value = automount_lookup(user_name);
3943 home_server_len = strcspn(automount_value,":");
3944 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3945 if (home_server_len > sizeof(pstring))
3947 home_server_len = sizeof(pstring);
3949 strncpy(server_name, automount_value, home_server_len);
3950 server_name[home_server_len] = '\0';
3954 DEBUG(4,("Home server: %s\n", server_name));
3959 /*******************************************************************
3960 Patch from jkf@soton.ac.uk
3961 Added this to implement %p (NIS auto-map version of %H)
3962 *******************************************************************/
3964 char *automount_path(char *user_name)
3966 static pstring server_path;
3968 /* use the passwd entry as the default */
3969 /* this will be the default if AUTOMOUNT is not used or fails */
3970 /* pstrcpy() copes with get_home_dir() returning NULL */
3971 pstrcpy(server_path, get_home_dir(user_name));
3973 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3975 if (lp_nis_home_map())
3977 char *home_path_start;
3978 char *automount_value = automount_lookup(user_name);
3979 home_path_start = strchr(automount_value,':');
3980 if (home_path_start != NULL)
3982 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3983 home_path_start?(home_path_start+1):""));
3984 pstrcpy(server_path, home_path_start+1);
3989 DEBUG(4,("Home server path: %s\n", server_path));
3995 /*******************************************************************
3996 sub strings with useful parameters
3997 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3998 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3999 ********************************************************************/
4000 void standard_sub_basic(char *str)
4004 struct passwd *pass;
4005 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4007 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4013 if ((pass = Get_Pwnam(username,False))!=NULL)
4015 string_sub(p,"%G",gidtoname(pass->pw_gid));
4023 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4024 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4025 case 'L' : string_sub(p,"%L", local_machine); break;
4026 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4027 case 'R' : string_sub(p,"%R", remote_proto); break;
4028 case 'T' : string_sub(p,"%T", timestring()); break;
4029 case 'U' : string_sub(p,"%U", username); break;
4030 case 'a' : string_sub(p,"%a", remote_arch); break;
4033 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4034 string_sub(p,"%d", pidstr);
4037 case 'h' : string_sub(p,"%h", myhostname); break;
4038 case 'm' : string_sub(p,"%m", remote_machine); break;
4039 case 'v' : string_sub(p,"%v", VERSION); break;
4040 case '$' : /* Expand environment variables */
4042 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4048 if (*(p+2) != '(') { p+=2; break; }
4049 if ((q = strchr(p,')')) == NULL)
4051 DEBUG(0,("standard_sub_basic: Unterminated environment \
4052 variable [%s]\n", p));
4057 copylen = MIN((q-r),(sizeof(envname)-1));
4058 strncpy(envname,r,copylen);
4059 envname[copylen] = '\0';
4060 if ((envval = getenv(envname)) == NULL)
4062 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4066 copylen = MIN((q+1-p),(sizeof(envname)-1));
4067 strncpy(envname,p,copylen);
4068 envname[copylen] = '\0';
4069 string_sub(p,envname,envval);
4072 case '\0': p++; break; /* don't run off end if last character is % */
4073 default : p+=2; break;
4079 /*******************************************************************
4080 are two IPs on the same subnet?
4081 ********************************************************************/
4082 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4084 uint32 net1,net2,nmask;
4086 nmask = ntohl(mask.s_addr);
4087 net1 = ntohl(ip1.s_addr);
4088 net2 = ntohl(ip2.s_addr);
4090 return((net1 & nmask) == (net2 & nmask));
4094 /*******************************************************************
4095 write a string in unicoode format
4096 ********************************************************************/
4097 int PutUniCode(char *dst,char *src)
4101 dst[ret++] = src[0];
4110 /****************************************************************************
4111 a wrapper for gethostbyname() that tries with all lower and all upper case
4112 if the initial name fails
4113 ****************************************************************************/
4114 struct hostent *Get_Hostbyname(char *name)
4116 char *name2 = strdup(name);
4117 struct hostent *ret;
4121 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4127 * This next test is redundent and causes some systems (with
4128 * broken isalnum() calls) problems.
4133 if (!isalnum(*name2))
4140 ret = sys_gethostbyname(name2);
4147 /* try with all lowercase */
4149 ret = sys_gethostbyname(name2);
4156 /* try with all uppercase */
4158 ret = sys_gethostbyname(name2);
4165 /* nothing works :-( */
4171 /****************************************************************************
4172 check if a process exists. Does this work on all unixes?
4173 ****************************************************************************/
4174 BOOL process_exists(int pid)
4176 return(kill(pid,0) == 0 || errno != ESRCH);
4180 /*******************************************************************
4181 turn a uid into a user name
4182 ********************************************************************/
4183 char *uidtoname(int uid)
4185 static char name[40];
4186 struct passwd *pass = getpwuid(uid);
4187 if (pass) return(pass->pw_name);
4188 slprintf(name, sizeof(name) - 1, "%d",uid);
4192 /*******************************************************************
4193 turn a gid into a group name
4194 ********************************************************************/
4195 char *gidtoname(int gid)
4197 static char name[40];
4198 struct group *grp = getgrgid(gid);
4199 if (grp) return(grp->gr_name);
4200 slprintf(name,sizeof(name) - 1, "%d",gid);
4204 /*******************************************************************
4206 ********************************************************************/
4207 void BlockSignals(BOOL block,int signum)
4210 int block_mask = sigmask(signum);
4211 static int oldmask = 0;
4213 oldmask = sigblock(block_mask);
4215 sigsetmask(oldmask);
4216 #elif defined(USE_SIGPROCMASK)
4219 sigaddset(&set,signum);
4220 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4225 /*******************************************************************
4226 my own panic function - not suitable for general use
4227 ********************************************************************/
4228 void ajt_panic(void)
4230 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4235 #define DIRECT direct
4237 #define DIRECT dirent
4240 /*******************************************************************
4241 a readdir wrapper which just returns the file name
4242 also return the inode number if requested
4243 ********************************************************************/
4244 char *readdirname(void *p)
4249 if (!p) return(NULL);
4251 ptr = (struct DIRECT *)readdir(p);
4252 if (!ptr) return(NULL);
4254 dname = ptr->d_name;
4257 if (telldir(p) < 0) return(NULL);
4261 /* this handles a broken compiler setup, causing a mixture
4262 of BSD and SYSV headers and libraries */
4264 static BOOL broken_readdir = False;
4265 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4267 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4268 broken_readdir = True;
4277 pstrcpy(buf, dname);
4278 unix_to_dos(buf, True);
4285 /*******************************************************************
4286 Utility function used to decide if the last component
4287 of a path matches a (possibly wildcarded) entry in a namelist.
4288 ********************************************************************/
4290 BOOL is_in_path(char *name, name_compare_entry *namelist)
4292 pstring last_component;
4295 DEBUG(8, ("is_in_path: %s\n", name));
4297 /* if we have no list it's obviously not in the path */
4298 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4300 DEBUG(8,("is_in_path: no name list.\n"));
4304 /* Get the last component of the unix name. */
4305 p = strrchr(name, '/');
4306 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4307 last_component[sizeof(last_component)-1] = '\0';
4309 for(; namelist->name != NULL; namelist++)
4311 if(namelist->is_wild)
4313 /* look for a wildcard match. */
4314 if (mask_match(last_component, namelist->name, case_sensitive, False))
4316 DEBUG(8,("is_in_path: mask match succeeded\n"));
4322 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4323 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4325 DEBUG(8,("is_in_path: match succeeded\n"));
4330 DEBUG(8,("is_in_path: match not found\n"));
4335 /*******************************************************************
4336 Strip a '/' separated list into an array of
4337 name_compare_enties structures suitable for
4338 passing to is_in_path(). We do this for
4339 speed so we can pre-parse all the names in the list
4340 and don't do it for each call to is_in_path().
4341 namelist is modified here and is assumed to be
4342 a copy owned by the caller.
4343 We also check if the entry contains a wildcard to
4344 remove a potentially expensive call to mask_match
4346 ********************************************************************/
4348 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4351 char *nameptr = namelist;
4352 int num_entries = 0;
4355 (*ppname_array) = NULL;
4357 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4360 /* We need to make two passes over the string. The
4361 first to count the number of elements, the second
4366 if ( *nameptr == '/' )
4368 /* cope with multiple (useless) /s) */
4372 /* find the next / */
4373 name_end = strchr(nameptr, '/');
4375 /* oops - the last check for a / didn't find one. */
4376 if (name_end == NULL)
4379 /* next segment please */
4380 nameptr = name_end + 1;
4384 if(num_entries == 0)
4387 if(( (*ppname_array) = (name_compare_entry *)malloc(
4388 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4390 DEBUG(0,("set_namearray: malloc fail\n"));
4394 /* Now copy out the names */
4399 if ( *nameptr == '/' )
4401 /* cope with multiple (useless) /s) */
4405 /* find the next / */
4406 if ((name_end = strchr(nameptr, '/')) != NULL)
4411 /* oops - the last check for a / didn't find one. */
4412 if(name_end == NULL)
4415 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4416 (strchr( nameptr, '*')!=NULL));
4417 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4419 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4423 /* next segment please */
4424 nameptr = name_end + 1;
4428 (*ppname_array)[i].name = NULL;
4433 /****************************************************************************
4434 routine to free a namearray.
4435 ****************************************************************************/
4437 void free_namearray(name_compare_entry *name_array)
4442 if(name_array->name != NULL)
4443 free(name_array->name);
4445 free((char *)name_array);
4448 /****************************************************************************
4449 routine to do file locking
4450 ****************************************************************************/
4451 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4458 uint32 mask = 0xC0000000;
4460 /* make sure the count is reasonable, we might kill the lockd otherwise */
4463 /* the offset is often strange - remove 2 of its bits if either of
4464 the top two bits are set. Shift the top ones by two bits. This
4465 still allows OLE2 apps to operate, but should stop lockd from
4467 if ((offset & mask) != 0)
4468 offset = (offset & ~mask) | ((offset & mask) >> 2);
4470 uint32 mask = ((unsigned)1<<31);
4472 /* interpret negative counts as large numbers */
4476 /* no negative offsets */
4479 /* count + offset must be in range */
4480 while ((offset < 0 || (offset + count < 0)) && mask)
4488 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4491 lock.l_whence = SEEK_SET;
4492 lock.l_start = (int)offset;
4493 lock.l_len = (int)count;
4498 ret = fcntl(fd,op,&lock);
4501 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4507 (lock.l_type != F_UNLCK) &&
4508 (lock.l_pid != 0) &&
4509 (lock.l_pid != getpid()))
4511 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4515 /* it must be not locked or locked by me */
4519 /* a lock set or unset */
4522 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4523 offset,count,op,type,strerror(errno)));
4525 /* perhaps it doesn't support this sort of locking?? */
4526 if (errno == EINVAL)
4528 DEBUG(3,("locking not supported? returning True\n"));
4535 /* everything went OK */
4536 DEBUG(8,("Lock call successful\n"));
4544 /*******************************************************************
4545 lock a file - returning a open file descriptor or -1 on failure
4546 The timeout is in seconds. 0 means no timeout
4547 ********************************************************************/
4548 int file_lock(char *name,int timeout)
4550 int fd = open(name,O_RDWR|O_CREAT,0666);
4552 if (fd < 0) return(-1);
4555 if (timeout) t = time(NULL);
4556 while (!timeout || (time(NULL)-t < timeout)) {
4557 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4558 msleep(LOCK_RETRY_TIMEOUT);
4566 /*******************************************************************
4567 unlock a file locked by file_lock
4568 ********************************************************************/
4569 void file_unlock(int fd)
4573 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4578 /*******************************************************************
4579 is the name specified one of my netbios names
4580 returns true is it is equal, false otherwise
4581 ********************************************************************/
4582 BOOL is_myname(char *s)
4587 for (n=0; my_netbios_names[n]; n++) {
4588 if (strequal(my_netbios_names[n], s))
4591 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4595 /*******************************************************************
4596 set the horrid remote_arch string based on an enum.
4597 ********************************************************************/
4598 void set_remote_arch(enum remote_arch_types type)
4604 fstrcpy(remote_arch, "WfWg");
4607 fstrcpy(remote_arch, "OS2");
4610 fstrcpy(remote_arch, "Win95");
4613 fstrcpy(remote_arch, "WinNT");
4616 fstrcpy(remote_arch,"Samba");
4619 ra_type = RA_UNKNOWN;
4620 fstrcpy(remote_arch, "UNKNOWN");
4625 /*******************************************************************
4626 Get the remote_arch type.
4627 ********************************************************************/
4628 enum remote_arch_types get_remote_arch(void)
4634 /*******************************************************************
4635 skip past some unicode strings in a buffer
4636 ********************************************************************/
4637 char *skip_unicode_string(char *buf,int n)
4648 /*******************************************************************
4649 Return a ascii version of a unicode string
4650 Hack alert: uses fixed buffer(s) and only handles ascii strings
4651 ********************************************************************/
4653 char *unistrn2(uint16 *buf, int len)
4655 static char lbufs[8][MAXUNI];
4657 char *lbuf = lbufs[nexti];
4660 nexti = (nexti+1)%8;
4662 DEBUG(10, ("unistrn2: "));
4664 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4666 DEBUG(10, ("%4x ", *buf));
4676 /*******************************************************************
4677 Return a ascii version of a unicode string
4678 Hack alert: uses fixed buffer(s) and only handles ascii strings
4679 ********************************************************************/
4681 char *unistr2(uint16 *buf)
4683 static char lbufs[8][MAXUNI];
4685 char *lbuf = lbufs[nexti];
4688 nexti = (nexti+1)%8;
4690 DEBUG(10, ("unistr2: "));
4692 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4694 DEBUG(10, ("%4x ", *buf));
4704 /*******************************************************************
4705 create a null-terminated unicode string from a null-terminated ascii string.
4706 return number of unicode chars copied, excluding the null character.
4708 only handles ascii strings
4709 ********************************************************************/
4711 int struni2(uint16 *p, char *buf)
4715 if (p == NULL) return 0;
4717 DEBUG(10, ("struni2: "));
4721 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4723 DEBUG(10, ("%2x ", *buf));
4735 /*******************************************************************
4736 Return a ascii version of a unicode string
4737 Hack alert: uses fixed buffer(s) and only handles ascii strings
4738 ********************************************************************/
4740 char *unistr(char *buf)
4742 static char lbufs[8][MAXUNI];
4744 char *lbuf = lbufs[nexti];
4747 nexti = (nexti+1)%8;
4749 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4757 /*******************************************************************
4758 strncpy for unicode strings
4759 ********************************************************************/
4760 int unistrncpy(char *dst, char *src, int len)
4764 while (*src && len > 0)
4778 /*******************************************************************
4779 strcpy for unicode strings. returns length (in num of wide chars)
4780 ********************************************************************/
4781 int unistrcpy(char *dst, char *src)
4797 /*******************************************************************
4798 safe string copy into a known length string. maxlength does not
4799 include the terminating zero.
4800 ********************************************************************/
4801 char *safe_strcpy(char *dest, char *src, int maxlength)
4806 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4817 if (len > maxlength) {
4818 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4819 len-maxlength, src));
4823 memcpy(dest, src, len);
4828 /*******************************************************************
4829 safe string cat into a string. maxlength does not
4830 include the terminating zero.
4831 ********************************************************************/
4832 char *safe_strcat(char *dest, char *src, int maxlength)
4834 int src_len, dest_len;
4837 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4845 src_len = strlen(src);
4846 dest_len = strlen(dest);
4848 if (src_len + dest_len > maxlength) {
4849 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4850 src_len + dest_len - maxlength, src));
4851 src_len = maxlength - dest_len;
4854 memcpy(&dest[dest_len], src, src_len);
4855 dest[dest_len + src_len] = 0;
4859 /*******************************************************************
4860 align a pointer to a multiple of 4 bytes
4861 ********************************************************************/
4862 char *align4(char *q, char *base)
4866 q += 4 - ((q - base) & 3);
4871 /*******************************************************************
4872 align a pointer to a multiple of 2 bytes
4873 ********************************************************************/
4874 char *align2(char *q, char *base)
4883 /*******************************************************************
4884 align a pointer to a multiple of align_offset bytes. looks like it
4885 will work for offsets of 0, 2 and 4...
4886 ********************************************************************/
4887 char *align_offset(char *q, char *base, int align_offset_len)
4889 int mod = ((q - base) & (align_offset_len-1));
4890 if (align_offset_len != 0 && mod != 0)
4892 q += align_offset_len - mod;
4897 void print_asc(int level, unsigned char *buf,int len)
4901 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4904 void dump_data(int level,char *buf1,int len)
4906 unsigned char *buf = (unsigned char *)buf1;
4910 DEBUG(level,("[%03X] ",i));
4912 DEBUG(level,("%02X ",(int)buf[i]));
4914 if (i%8 == 0) DEBUG(level,(" "));
4916 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4917 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4918 if (i<len) DEBUG(level,("[%03X] ",i));
4926 if (n>8) DEBUG(level,(" "));
4927 while (n--) DEBUG(level,(" "));
4930 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4932 if (n>0) print_asc(level,&buf[i-n],n);
4933 DEBUG(level,("\n"));
4937 char *tab_depth(int depth)
4939 static pstring spaces;
4940 memset(spaces, ' ', depth * 4);
4941 spaces[depth * 4] = 0;
4945 /*****************************************************************
4946 Convert a domain SID to an ascii string. (non-reentrant).
4947 *****************************************************************/
4949 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4950 char *dom_sid_to_string(DOM_SID *sid)
4952 static pstring sidstr;
4955 uint32 ia = (sid->id_auth[5]) +
4956 (sid->id_auth[4] << 8 ) +
4957 (sid->id_auth[3] << 16) +
4958 (sid->id_auth[2] << 24);
4960 slprintf(sidstr, sizeof(sidstr) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4962 for (i = 0; i < sid->num_auths; i++)
4964 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4965 pstrcat(sidstr, subauth);
4968 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));