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;
90 fstring 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 strcpy(fname,debugf);
182 if (lp_loaded() && (*lp_logfile()))
183 strcpy(fname,lp_logfile());
185 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
187 int oldumask = umask(022);
188 strcpy(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 sprintf(name,"%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);
273 dbf = fopen(debugf,"w");
285 if (syslog_level < lp_syslog())
288 * map debug levels to syslog() priorities
289 * note that not all DEBUG(0, ...) calls are
292 static int priority_map[] = {
301 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
303 priority = LOG_DEBUG;
305 priority = priority_map[syslog_level];
308 va_start(ap, format_str);
311 format_str = va_arg(ap,char *);
313 vsprintf(msgbuf, format_str, ap);
317 syslog(priority, "%s", msgbuf);
322 if (!lp_syslog_only())
326 va_start(ap, format_str);
329 format_str = va_arg(ap,char *);
331 vfprintf(dbf,format_str,ap);
343 /****************************************************************************
344 find a suitable temporary directory. The result should be copied immediately
345 as it may be overwritten by a subsequent call
346 ****************************************************************************/
350 if ((p = getenv("TMPDIR"))) {
358 /****************************************************************************
359 determine if a file descriptor is in fact a socket
360 ****************************************************************************/
361 BOOL is_a_socket(int fd)
365 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
369 static char *last_ptr=NULL;
371 /****************************************************************************
372 Get the next token from a string, return False if none found
373 handles double-quotes.
374 Based on a routine by GJC@VILLAGE.COM.
375 Extensively modified by Andrew.Tridgell@anu.edu.au
376 ****************************************************************************/
377 BOOL next_token(char **ptr,char *buff,char *sep)
382 if (!ptr) ptr = &last_ptr;
383 if (!ptr) return(False);
387 /* default to simple separators */
388 if (!sep) sep = " \t\n\r";
390 /* find the first non sep char */
391 while(*s && strchr(sep,*s)) s++;
394 if (! *s) return(False);
396 /* copy over the token */
397 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
405 *ptr = (*s) ? s+1 : s;
412 /****************************************************************************
413 Convert list of tokens to array; dependent on above routine.
414 Uses last_ptr from above - bit of a hack.
415 ****************************************************************************/
416 char **toktocliplist(int *ctok, char *sep)
422 if (!sep) sep = " \t\n\r";
424 while(*s && strchr(sep,*s)) s++;
427 if (!*s) return(NULL);
431 while(*s && (!strchr(sep,*s))) s++;
432 while(*s && strchr(sep,*s)) *s++=0;
438 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
450 /*******************************************************************
451 safely copies memory, ensuring no overlap problems.
452 this is only used if the machine does not have it's own memmove().
453 this is not the fastest algorithm in town, but it will do for our
455 ********************************************************************/
456 void *MemMove(void *dest,void *src,int size)
460 if (dest==src || !size) return(dest);
462 d = (unsigned long)dest;
463 s = (unsigned long)src;
465 if ((d >= (s+size)) || (s >= (d+size))) {
467 memcpy(dest,src,size);
473 /* we can forward copy */
474 if (s-d >= sizeof(int) &&
475 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
476 /* do it all as words */
477 int *idest = (int *)dest;
478 int *isrc = (int *)src;
480 for (i=0;i<size;i++) idest[i] = isrc[i];
483 char *cdest = (char *)dest;
484 char *csrc = (char *)src;
485 for (i=0;i<size;i++) cdest[i] = csrc[i];
490 /* must backward copy */
491 if (d-s >= sizeof(int) &&
492 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
493 /* do it all as words */
494 int *idest = (int *)dest;
495 int *isrc = (int *)src;
497 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
500 char *cdest = (char *)dest;
501 char *csrc = (char *)src;
502 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
510 /****************************************************************************
511 prompte a dptr (to make it recently used)
512 ****************************************************************************/
513 void array_promote(char *array,int elsize,int element)
519 p = (char *)malloc(elsize);
523 DEBUG(5,("Ahh! Can't malloc\n"));
526 memcpy(p,array + element * elsize, elsize);
527 memmove(array + elsize,array,elsize*element);
528 memcpy(array,p,elsize);
532 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
541 } socket_options[] = {
542 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
543 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
544 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
546 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
548 #ifdef IPTOS_LOWDELAY
549 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
551 #ifdef IPTOS_THROUGHPUT
552 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
555 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
558 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
561 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
564 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
567 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
570 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
576 /****************************************************************************
577 set user socket options
578 ****************************************************************************/
579 void set_socket_options(int fd, char *options)
583 while (next_token(&options,tok," \t,"))
588 BOOL got_value = False;
590 if ((p = strchr(tok,'=')))
597 for (i=0;socket_options[i].name;i++)
598 if (strequal(socket_options[i].name,tok))
601 if (!socket_options[i].name)
603 DEBUG(0,("Unknown socket option %s\n",tok));
607 switch (socket_options[i].opttype)
611 ret = setsockopt(fd,socket_options[i].level,
612 socket_options[i].option,(char *)&value,sizeof(int));
617 DEBUG(0,("syntax error - %s does not take a value\n",tok));
620 int on = socket_options[i].value;
621 ret = setsockopt(fd,socket_options[i].level,
622 socket_options[i].option,(char *)&on,sizeof(int));
628 DEBUG(0,("Failed to set socket option %s\n",tok));
634 /****************************************************************************
635 close the socket communication
636 ****************************************************************************/
637 void close_sockets(void )
643 /****************************************************************************
644 determine whether we are in the specified group
645 ****************************************************************************/
646 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
650 if (group == current_gid) return(True);
652 for (i=0;i<ngroups;i++)
653 if (group == groups[i])
659 /****************************************************************************
660 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
661 ****************************************************************************/
662 char *StrCpy(char *dest,char *src)
667 /* I don't want to get lazy with these ... */
669 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
674 if (!dest) return(NULL);
679 while ((*d++ = *src++)) ;
683 /****************************************************************************
684 line strncpy but always null terminates. Make sure there is room!
685 ****************************************************************************/
686 char *StrnCpy(char *dest,char *src,int n)
689 if (!dest) return(NULL);
694 while (n-- && (*d++ = *src++)) ;
700 /*******************************************************************
701 copy an IP address from one buffer to another
702 ********************************************************************/
703 void putip(void *dest,void *src)
709 /****************************************************************************
710 interpret the weird netbios "name". Return the name type
711 ****************************************************************************/
712 static int name_interpret(char *in,char *out)
715 int len = (*in++) / 2;
719 if (len > 30 || len<1) return(0);
723 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
727 *out = ((in[0]-'A')<<4) + (in[1]-'A');
735 /* Handle any scope names */
738 *out++ = '.'; /* Scope names are separated by periods */
739 len = *(unsigned char *)in++;
740 StrnCpy(out, in, len);
749 /****************************************************************************
750 mangle a name into netbios format
752 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
753 ****************************************************************************/
754 int name_mangle( char *In, char *Out, char name_type )
762 /* Safely copy the input string, In, into buf[]. */
763 (void)memset( buf, 0, 20 );
767 (void)sprintf( buf, "%-15.15s%c", In, name_type );
769 /* Place the length of the first field into the output buffer. */
773 /* Now convert the name to the rfc1001/1002 format. */
774 for( i = 0; i < 16; i++ )
776 c = toupper( buf[i] );
777 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
778 p[(i*2)+1] = (c & 0x000F) + 'A';
783 /* Add the scope string. */
784 for( i = 0, len = 0; NULL != scope; i++, len++ )
792 return( name_len(Out) );
804 return( name_len(Out) );
807 /*******************************************************************
808 check if a file exists
809 ********************************************************************/
810 BOOL file_exist(char *fname,struct stat *sbuf)
813 if (!sbuf) sbuf = &st;
815 if (sys_stat(fname,sbuf) != 0)
818 return(S_ISREG(sbuf->st_mode));
821 /*******************************************************************
822 check a files mod time
823 ********************************************************************/
824 time_t file_modtime(char *fname)
828 if (sys_stat(fname,&st) != 0)
834 /*******************************************************************
835 check if a directory exists
836 ********************************************************************/
837 BOOL directory_exist(char *dname,struct stat *st)
844 if (sys_stat(dname,st) != 0)
847 ret = S_ISDIR(st->st_mode);
853 /*******************************************************************
854 returns the size in bytes of the named file
855 ********************************************************************/
856 uint32 file_size(char *file_name)
860 sys_stat(file_name,&buf);
864 /*******************************************************************
865 return a string representing an attribute for a file
866 ********************************************************************/
867 char *attrib_string(int mode)
869 static char attrstr[10];
873 if (mode & aVOLID) strcat(attrstr,"V");
874 if (mode & aDIR) strcat(attrstr,"D");
875 if (mode & aARCH) strcat(attrstr,"A");
876 if (mode & aHIDDEN) strcat(attrstr,"H");
877 if (mode & aSYSTEM) strcat(attrstr,"S");
878 if (mode & aRONLY) strcat(attrstr,"R");
884 /*******************************************************************
885 case insensitive string compararison
886 ********************************************************************/
887 int StrCaseCmp(char *s, char *t)
889 /* compare until we run out of string, either t or s, or find a difference */
890 /* We *must* use toupper rather than tolower here due to the
891 asynchronous upper to lower mapping.
893 #if !defined(KANJI_WIN95_COMPATIBILITY)
895 * For completeness we should put in equivalent code for code pages
896 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
897 * doubt anyone wants Samba to behave differently from Win95 and WinNT
898 * here. They both treat full width ascii characters as case senstive
899 * filenames (ie. they don't do the work we do here).
903 if(lp_client_code_page() == KANJI_CODEPAGE)
905 /* Win95 treats full width ascii characters as case sensitive. */
910 return toupper (*s) - toupper (*t);
911 else if (is_sj_alph (*s) && is_sj_alph (*t))
913 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
919 else if (is_shift_jis (*s) && is_shift_jis (*t))
921 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
924 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
930 else if (is_shift_jis (*s))
932 else if (is_shift_jis (*t))
936 diff = toupper (*s) - toupper (*t);
945 #endif /* KANJI_WIN95_COMPATIBILITY */
947 while (*s && *t && toupper(*s) == toupper(*t))
953 return(toupper(*s) - toupper(*t));
957 /*******************************************************************
958 case insensitive string compararison, length limited
959 ********************************************************************/
960 int StrnCaseCmp(char *s, char *t, int n)
962 /* compare until we run out of string, either t or s, or chars */
963 /* We *must* use toupper rather than tolower here due to the
964 asynchronous upper to lower mapping.
966 #if !defined(KANJI_WIN95_COMPATIBILITY)
968 * For completeness we should put in equivalent code for code pages
969 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
970 * doubt anyone wants Samba to behave differently from Win95 and WinNT
971 * here. They both treat full width ascii characters as case senstive
972 * filenames (ie. they don't do the work we do here).
976 if(lp_client_code_page() == KANJI_CODEPAGE)
978 /* Win95 treats full width ascii characters as case sensitive. */
983 return toupper (*s) - toupper (*t);
984 else if (is_sj_alph (*s) && is_sj_alph (*t))
986 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
993 else if (is_shift_jis (*s) && is_shift_jis (*t))
995 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
998 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1005 else if (is_shift_jis (*s))
1007 else if (is_shift_jis (*t))
1011 diff = toupper (*s) - toupper (*t);
1022 #endif /* KANJI_WIN95_COMPATIBILITY */
1024 while (n && *s && *t && toupper(*s) == toupper(*t))
1031 /* not run out of chars - strings are different lengths */
1033 return(toupper(*s) - toupper(*t));
1035 /* identical up to where we run out of chars,
1036 and strings are same length */
1041 /*******************************************************************
1043 ********************************************************************/
1044 BOOL strequal(char *s1, char *s2)
1046 if (s1 == s2) return(True);
1047 if (!s1 || !s2) return(False);
1049 return(StrCaseCmp(s1,s2)==0);
1052 /*******************************************************************
1053 compare 2 strings up to and including the nth char.
1054 ******************************************************************/
1055 BOOL strnequal(char *s1,char *s2,int n)
1057 if (s1 == s2) return(True);
1058 if (!s1 || !s2 || !n) return(False);
1060 return(StrnCaseCmp(s1,s2,n)==0);
1063 /*******************************************************************
1064 compare 2 strings (case sensitive)
1065 ********************************************************************/
1066 BOOL strcsequal(char *s1,char *s2)
1068 if (s1 == s2) return(True);
1069 if (!s1 || !s2) return(False);
1071 return(strcmp(s1,s2)==0);
1075 /*******************************************************************
1076 convert a string to lower case
1077 ********************************************************************/
1078 void strlower(char *s)
1082 #if !defined(KANJI_WIN95_COMPATIBILITY)
1084 * For completeness we should put in equivalent code for code pages
1085 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1086 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1087 * here. They both treat full width ascii characters as case senstive
1088 * filenames (ie. they don't do the work we do here).
1092 if(lp_client_code_page() == KANJI_CODEPAGE)
1094 /* Win95 treats full width ascii characters as case sensitive. */
1095 if (is_shift_jis (*s))
1097 if (is_sj_upper (s[0], s[1]))
1098 s[1] = sj_tolower2 (s[1]);
1101 else if (is_kana (*s))
1113 #endif /* KANJI_WIN95_COMPATIBILITY */
1122 /*******************************************************************
1123 convert a string to upper case
1124 ********************************************************************/
1125 void strupper(char *s)
1129 #if !defined(KANJI_WIN95_COMPATIBILITY)
1131 * For completeness we should put in equivalent code for code pages
1132 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1133 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1134 * here. They both treat full width ascii characters as case senstive
1135 * filenames (ie. they don't do the work we do here).
1139 if(lp_client_code_page() == KANJI_CODEPAGE)
1141 /* Win95 treats full width ascii characters as case sensitive. */
1142 if (is_shift_jis (*s))
1144 if (is_sj_lower (s[0], s[1]))
1145 s[1] = sj_toupper2 (s[1]);
1148 else if (is_kana (*s))
1160 #endif /* KANJI_WIN95_COMPATIBILITY */
1169 /*******************************************************************
1170 convert a string to "normal" form
1171 ********************************************************************/
1172 void strnorm(char *s)
1174 if (case_default == CASE_UPPER)
1180 /*******************************************************************
1181 check if a string is in "normal" case
1182 ********************************************************************/
1183 BOOL strisnormal(char *s)
1185 if (case_default == CASE_UPPER)
1186 return(!strhaslower(s));
1188 return(!strhasupper(s));
1192 /****************************************************************************
1194 ****************************************************************************/
1195 void string_replace(char *s,char oldc,char newc)
1199 #if !defined(KANJI_WIN95_COMPATIBILITY)
1201 * For completeness we should put in equivalent code for code pages
1202 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1203 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1204 * here. They both treat full width ascii characters as case senstive
1205 * filenames (ie. they don't do the work we do here).
1209 if(lp_client_code_page() == KANJI_CODEPAGE)
1211 /* Win95 treats full width ascii characters as case sensitive. */
1212 if (is_shift_jis (*s))
1214 else if (is_kana (*s))
1224 #endif /* KANJI_WIN95_COMPATIBILITY */
1233 /****************************************************************************
1234 make a file into unix format
1235 ****************************************************************************/
1236 void unix_format(char *fname)
1239 string_replace(fname,'\\','/');
1243 pstrcpy(namecopy,fname);
1245 strcat(fname,namecopy);
1249 /****************************************************************************
1250 make a file into dos format
1251 ****************************************************************************/
1252 void dos_format(char *fname)
1254 string_replace(fname,'/','\\');
1257 /*******************************************************************
1258 show a smb message structure
1259 ********************************************************************/
1260 void show_msg(char *buf)
1265 if (DEBUGLEVEL < 5) return;
1267 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1269 (int)CVAL(buf,smb_com),
1270 (int)CVAL(buf,smb_rcls),
1271 (int)CVAL(buf,smb_reh),
1272 (int)SVAL(buf,smb_err),
1273 (int)CVAL(buf,smb_flg),
1274 (int)SVAL(buf,smb_flg2)));
1275 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1276 (int)SVAL(buf,smb_tid),
1277 (int)SVAL(buf,smb_pid),
1278 (int)SVAL(buf,smb_uid),
1279 (int)SVAL(buf,smb_mid),
1280 (int)CVAL(buf,smb_wct)));
1282 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1284 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1285 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1288 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1290 DEBUG(5,("smb_bcc=%d\n",bcc));
1292 if (DEBUGLEVEL < 10) return;
1294 if (DEBUGLEVEL < 50)
1296 bcc = MIN(bcc, 512);
1299 dump_data(10, smb_buf(buf), bcc);
1301 /*******************************************************************
1302 return the length of an smb packet
1303 ********************************************************************/
1304 int smb_len(char *buf)
1306 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1309 /*******************************************************************
1310 set the length of an smb packet
1311 ********************************************************************/
1312 void _smb_setlen(char *buf,int len)
1315 buf[1] = (len&0x10000)>>16;
1316 buf[2] = (len&0xFF00)>>8;
1320 /*******************************************************************
1321 set the length and marker of an smb packet
1322 ********************************************************************/
1323 void smb_setlen(char *buf,int len)
1325 _smb_setlen(buf,len);
1333 /*******************************************************************
1334 setup the word count and byte count for a smb message
1335 ********************************************************************/
1336 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1339 bzero(buf + smb_size,num_words*2 + num_bytes);
1340 CVAL(buf,smb_wct) = num_words;
1341 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1342 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1343 return (smb_size + num_words*2 + num_bytes);
1346 /*******************************************************************
1347 return the number of smb words
1348 ********************************************************************/
1349 int smb_numwords(char *buf)
1351 return (CVAL(buf,smb_wct));
1354 /*******************************************************************
1355 return the size of the smb_buf region of a message
1356 ********************************************************************/
1357 int smb_buflen(char *buf)
1359 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1362 /*******************************************************************
1363 return a pointer to the smb_buf data area
1364 ********************************************************************/
1365 int smb_buf_ofs(char *buf)
1367 return (smb_size + CVAL(buf,smb_wct)*2);
1370 /*******************************************************************
1371 return a pointer to the smb_buf data area
1372 ********************************************************************/
1373 char *smb_buf(char *buf)
1375 return (buf + smb_buf_ofs(buf));
1378 /*******************************************************************
1379 return the SMB offset into an SMB buffer
1380 ********************************************************************/
1381 int smb_offset(char *p,char *buf)
1383 return(PTR_DIFF(p,buf+4) + chain_size);
1387 /*******************************************************************
1388 skip past some strings in a buffer
1389 ********************************************************************/
1390 char *skip_string(char *buf,int n)
1393 buf += strlen(buf) + 1;
1397 /*******************************************************************
1398 trim the specified elements off the front and back of a string
1399 ********************************************************************/
1400 BOOL trim_string(char *s,char *front,char *back)
1403 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1409 if (!(*p = p[strlen(front)]))
1414 while (back && *back && strlen(s) >= strlen(back) &&
1415 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1418 s[strlen(s)-strlen(back)] = 0;
1424 /*******************************************************************
1425 reduce a file name, removing .. elements.
1426 ********************************************************************/
1427 void dos_clean_name(char *s)
1431 DEBUG(3,("dos_clean_name [%s]\n",s));
1433 /* remove any double slashes */
1434 string_sub(s, "\\\\", "\\");
1436 while ((p = strstr(s,"\\..\\")) != NULL)
1443 if ((p=strrchr(s,'\\')) != NULL)
1450 trim_string(s,NULL,"\\..");
1452 string_sub(s, "\\.\\", "\\");
1455 /*******************************************************************
1456 reduce a file name, removing .. elements.
1457 ********************************************************************/
1458 void unix_clean_name(char *s)
1462 DEBUG(3,("unix_clean_name [%s]\n",s));
1464 /* remove any double slashes */
1465 string_sub(s, "//","/");
1467 /* Remove leading ./ characters */
1468 if(strncmp(s, "./", 2) == 0) {
1469 trim_string(s, "./", NULL);
1474 while ((p = strstr(s,"/../")) != NULL)
1481 if ((p=strrchr(s,'/')) != NULL)
1488 trim_string(s,NULL,"/..");
1492 /*******************************************************************
1493 a wrapper for the normal chdir() function
1494 ********************************************************************/
1495 int ChDir(char *path)
1498 static pstring LastDir="";
1500 if (strcsequal(path,".")) return(0);
1502 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1503 DEBUG(3,("chdir to %s\n",path));
1504 res = sys_chdir(path);
1506 pstrcpy(LastDir,path);
1510 /* number of list structures for a caching GetWd function. */
1511 #define MAX_GETWDCACHE (50)
1519 } ino_list[MAX_GETWDCACHE];
1521 BOOL use_getwd_cache=True;
1523 /*******************************************************************
1524 return the absolute current directory path
1525 ********************************************************************/
1526 char *GetWd(char *str)
1529 static BOOL getwd_cache_init = False;
1530 struct stat st, st2;
1535 if (!use_getwd_cache)
1536 return(sys_getwd(str));
1538 /* init the cache */
1539 if (!getwd_cache_init)
1541 getwd_cache_init = True;
1542 for (i=0;i<MAX_GETWDCACHE;i++)
1544 string_init(&ino_list[i].text,"");
1545 ino_list[i].valid = False;
1549 /* Get the inode of the current directory, if this doesn't work we're
1552 if (stat(".",&st) == -1)
1554 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1555 return(sys_getwd(str));
1559 for (i=0; i<MAX_GETWDCACHE; i++)
1560 if (ino_list[i].valid)
1563 /* If we have found an entry with a matching inode and dev number
1564 then find the inode number for the directory in the cached string.
1565 If this agrees with that returned by the stat for the current
1566 directory then all is o.k. (but make sure it is a directory all
1569 if (st.st_ino == ino_list[i].inode &&
1570 st.st_dev == ino_list[i].dev)
1572 if (stat(ino_list[i].text,&st2) == 0)
1574 if (st.st_ino == st2.st_ino &&
1575 st.st_dev == st2.st_dev &&
1576 (st2.st_mode & S_IFMT) == S_IFDIR)
1578 strcpy (str, ino_list[i].text);
1580 /* promote it for future use */
1581 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1586 /* If the inode is different then something's changed,
1587 scrub the entry and start from scratch. */
1588 ino_list[i].valid = False;
1595 /* We don't have the information to hand so rely on traditional methods.
1596 The very slow getcwd, which spawns a process on some systems, or the
1597 not quite so bad getwd. */
1601 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1607 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1609 /* add it to the cache */
1610 i = MAX_GETWDCACHE - 1;
1611 string_set(&ino_list[i].text,s);
1612 ino_list[i].dev = st.st_dev;
1613 ino_list[i].inode = st.st_ino;
1614 ino_list[i].valid = True;
1616 /* put it at the top of the list */
1617 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1624 /*******************************************************************
1625 reduce a file name, removing .. elements and checking that
1626 it is below dir in the heirachy. This uses GetWd() and so must be run
1627 on the system that has the referenced file system.
1629 widelinks are allowed if widelinks is true
1630 ********************************************************************/
1631 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1633 #ifndef REDUCE_PATHS
1641 BOOL relative = (*s != '/');
1643 *dir2 = *wd = *base_name = *newname = 0;
1648 /* can't have a leading .. */
1649 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1651 DEBUG(3,("Illegal file name? (%s)\n",s));
1661 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1663 /* remove any double slashes */
1664 string_sub(s,"//","/");
1666 pstrcpy(base_name,s);
1667 p = strrchr(base_name,'/');
1674 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1678 if (ChDir(dir) != 0)
1680 DEBUG(0,("couldn't chdir to %s\n",dir));
1686 DEBUG(0,("couldn't getwd for %s\n",dir));
1692 if (p && (p != base_name))
1695 if (strcmp(p+1,".")==0)
1697 if (strcmp(p+1,"..")==0)
1701 if (ChDir(base_name) != 0)
1704 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1708 if (!GetWd(newname))
1711 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1715 if (p && (p != base_name))
1717 strcat(newname,"/");
1718 strcat(newname,p+1);
1722 int l = strlen(dir2);
1723 if (dir2[l-1] == '/')
1726 if (strncmp(newname,dir2,l) != 0)
1729 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1735 if (newname[l] == '/')
1736 pstrcpy(s,newname + l + 1);
1738 pstrcpy(s,newname+l);
1749 DEBUG(3,("reduced to %s\n",s));
1754 /****************************************************************************
1756 ****************************************************************************/
1757 static void expand_one(char *Mask,int len)
1760 while ((p1 = strchr(Mask,'*')) != NULL)
1762 int lfill = (len+1) - strlen(Mask);
1763 int l1= (p1 - Mask);
1766 memset(tmp+l1,'?',lfill);
1767 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1772 /****************************************************************************
1773 expand a wildcard expression, replacing *s with ?s
1774 ****************************************************************************/
1775 void expand_mask(char *Mask,BOOL doext)
1780 BOOL hasdot = False;
1782 BOOL absolute = (*Mask == '\\');
1784 *mbeg = *mext = *dirpart = *filepart = 0;
1786 /* parse the directory and filename */
1787 if (strchr(Mask,'\\'))
1788 dirname_dos(Mask,dirpart);
1790 filename_dos(Mask,filepart);
1792 pstrcpy(mbeg,filepart);
1793 if ((p1 = strchr(mbeg,'.')) != NULL)
1803 if (strlen(mbeg) > 8)
1805 pstrcpy(mext,mbeg + 8);
1811 strcpy(mbeg,"????????");
1812 if ((*mext == 0) && doext && !hasdot)
1815 if (strequal(mbeg,"*") && *mext==0)
1823 pstrcpy(Mask,dirpart);
1824 if (*dirpart || absolute) strcat(Mask,"\\");
1829 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1833 /****************************************************************************
1834 does a string have any uppercase chars in it?
1835 ****************************************************************************/
1836 BOOL strhasupper(char *s)
1840 #if !defined(KANJI_WIN95_COMPATIBILITY)
1842 * For completeness we should put in equivalent code for code pages
1843 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1844 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1845 * here. They both treat full width ascii characters as case senstive
1846 * filenames (ie. they don't do the work we do here).
1850 if(lp_client_code_page() == KANJI_CODEPAGE)
1852 /* Win95 treats full width ascii characters as case sensitive. */
1853 if (is_shift_jis (*s))
1855 else if (is_kana (*s))
1865 #endif /* KANJI_WIN95_COMPATIBILITY */
1875 /****************************************************************************
1876 does a string have any lowercase chars in it?
1877 ****************************************************************************/
1878 BOOL strhaslower(char *s)
1882 #if !defined(KANJI_WIN95_COMPATIBILITY)
1884 * For completeness we should put in equivalent code for code pages
1885 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1886 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1887 * here. They both treat full width ascii characters as case senstive
1888 * filenames (ie. they don't do the work we do here).
1892 if(lp_client_code_page() == KANJI_CODEPAGE)
1894 /* Win95 treats full width ascii characters as case sensitive. */
1895 if (is_shift_jis (*s))
1897 if (is_sj_upper (s[0], s[1]))
1899 if (is_sj_lower (s[0], s[1]))
1903 else if (is_kana (*s))
1915 #endif /* KANJI_WIN95_COMPATIBILITY */
1925 /****************************************************************************
1926 find the number of chars in a string
1927 ****************************************************************************/
1928 int count_chars(char *s,char c)
1932 #if !defined(KANJI_WIN95_COMPATIBILITY)
1934 * For completeness we should put in equivalent code for code pages
1935 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1936 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1937 * here. They both treat full width ascii characters as case senstive
1938 * filenames (ie. they don't do the work we do here).
1942 if(lp_client_code_page() == KANJI_CODEPAGE)
1944 /* Win95 treats full width ascii characters as case sensitive. */
1947 if (is_shift_jis (*s))
1958 #endif /* KANJI_WIN95_COMPATIBILITY */
1971 /****************************************************************************
1973 ****************************************************************************/
1974 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1979 pstrcpy(mask2,mask);
1981 if ((mode & aDIR) != 0)
1984 memset(buf+1,' ',11);
1985 if ((p = strchr(mask2,'.')) != NULL)
1988 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1989 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1993 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1995 bzero(buf+21,DIR_STRUCT_SIZE-21);
1996 CVAL(buf,21) = mode;
1997 put_dos_date(buf,22,date);
1998 SSVAL(buf,26,size & 0xFFFF);
1999 SSVAL(buf,28,size >> 16);
2000 StrnCpy(buf+30,fname,12);
2001 if (!case_sensitive)
2003 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2007 /*******************************************************************
2008 close the low 3 fd's and open dev/null in their place
2009 ********************************************************************/
2010 void close_low_fds(void)
2014 close(0); close(1); close(2);
2015 /* try and use up these file descriptors, so silly
2016 library routines writing to stdout etc won't cause havoc */
2018 fd = open("/dev/null",O_RDWR,0);
2019 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2021 DEBUG(0,("Can't open /dev/null\n"));
2025 DEBUG(0,("Didn't get file descriptor %d\n",i));
2031 /****************************************************************************
2032 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2034 if SYSV use O_NDELAY
2036 ****************************************************************************/
2037 int set_blocking(int fd, BOOL set)
2041 #define FLAG_TO_SET O_NONBLOCK
2044 #define FLAG_TO_SET O_NDELAY
2046 #define FLAG_TO_SET FNDELAY
2050 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2052 if(set) /* Turn blocking on - ie. clear nonblock flag */
2053 val &= ~FLAG_TO_SET;
2056 return fcntl( fd, F_SETFL, val);
2061 /****************************************************************************
2063 ****************************************************************************/
2064 int write_socket(int fd,char *buf,int len)
2070 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2071 ret = write_data(fd,buf,len);
2073 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2075 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2076 len, fd, strerror(errno) ));
2081 /****************************************************************************
2083 ****************************************************************************/
2084 int read_udp_socket(int fd,char *buf,int len)
2087 struct sockaddr_in sock;
2090 socklen = sizeof(sock);
2091 bzero((char *)&sock,socklen);
2092 bzero((char *)&lastip,sizeof(lastip));
2093 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2095 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2099 lastip = sock.sin_addr;
2100 lastport = ntohs(sock.sin_port);
2102 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2103 inet_ntoa(lastip), lastport, ret));
2108 /****************************************************************************
2109 read data from a device with a timout in msec.
2110 mincount = if timeout, minimum to read before returning
2111 maxcount = number to be read.
2112 ****************************************************************************/
2113 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2119 struct timeval timeout;
2121 /* just checking .... */
2122 if (maxcnt <= 0) return(0);
2127 if (time_out <= 0) {
2128 if (mincnt == 0) mincnt = maxcnt;
2130 while (nread < mincnt) {
2131 readret = read(fd, buf + nread, maxcnt - nread);
2133 smb_read_error = READ_EOF;
2137 if (readret == -1) {
2138 smb_read_error = READ_ERROR;
2146 /* Most difficult - timeout read */
2147 /* If this is ever called on a disk file and
2148 mincnt is greater then the filesize then
2149 system performance will suffer severely as
2150 select always return true on disk files */
2152 /* Set initial timeout */
2153 timeout.tv_sec = time_out / 1000;
2154 timeout.tv_usec = 1000 * (time_out % 1000);
2156 for (nread=0; nread<mincnt; )
2161 selrtn = sys_select(&fds,&timeout);
2163 /* Check if error */
2165 /* something is wrong. Maybe the socket is dead? */
2166 smb_read_error = READ_ERROR;
2170 /* Did we timeout ? */
2172 smb_read_error = READ_TIMEOUT;
2176 readret = read(fd, buf+nread, maxcnt-nread);
2178 /* we got EOF on the file descriptor */
2179 smb_read_error = READ_EOF;
2183 if (readret == -1) {
2184 /* the descriptor is probably dead */
2185 smb_read_error = READ_ERROR;
2192 /* Return the number we got */
2196 /****************************************************************************
2197 read data from the client. Maxtime is in milliseconds
2198 ****************************************************************************/
2199 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2204 struct timeval timeout;
2209 timeout.tv_sec = maxtime / 1000;
2210 timeout.tv_usec = (maxtime % 1000) * 1000;
2212 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2214 if (!FD_ISSET(fd,&fds))
2217 nread = read_udp_socket(fd, buffer, bufsize);
2219 /* return the number got */
2223 /*******************************************************************
2224 find the difference in milliseconds between two struct timeval
2226 ********************************************************************/
2227 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2229 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2230 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2233 /****************************************************************************
2234 send a keepalive packet (rfc1002)
2235 ****************************************************************************/
2236 BOOL send_keepalive(int client)
2238 unsigned char buf[4];
2241 buf[1] = buf[2] = buf[3] = 0;
2243 return(write_data(client,(char *)buf,4) == 4);
2248 /****************************************************************************
2249 read data from the client, reading exactly N bytes.
2250 ****************************************************************************/
2251 int read_data(int fd,char *buffer,int N)
2260 ret = read(fd,buffer + total,N - total);
2262 smb_read_error = READ_EOF;
2266 smb_read_error = READ_ERROR;
2275 /****************************************************************************
2277 ****************************************************************************/
2278 int write_data(int fd,char *buffer,int N)
2285 ret = write(fd,buffer + total,N - total);
2287 if (ret == -1) return -1;
2288 if (ret == 0) return total;
2296 /****************************************************************************
2297 transfer some data between two fd's
2298 ****************************************************************************/
2299 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2301 static char *buf=NULL;
2306 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2309 size = lp_readsize();
2310 size = MAX(size,1024);
2313 while (!buf && size>0) {
2314 buf = (char *)Realloc(buf,size+8);
2315 if (!buf) size /= 2;
2319 DEBUG(0,("Can't allocate transfer buffer!\n"));
2323 abuf = buf + (align%8);
2330 int s = MIN(n,size);
2335 if (header && (headlen >= MIN(s,1024))) {
2345 if (header && headlen > 0)
2347 ret = MIN(headlen,size);
2348 memcpy(buf1,header,ret);
2351 if (headlen <= 0) header = NULL;
2355 ret += read(infd,buf1+ret,s-ret);
2359 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2360 if (ret2 > 0) total += ret2;
2361 /* if we can't write then dump excess data */
2363 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2365 if (ret <= 0 || ret2 != ret)
2373 /****************************************************************************
2374 read 4 bytes of a smb packet and return the smb length of the packet
2375 store the result in the buffer
2376 This version of the function will return a length of zero on receiving
2378 ****************************************************************************/
2379 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2381 int len=0, msg_type;
2387 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2389 ok = (read_data(fd,inbuf,4) == 4);
2394 len = smb_len(inbuf);
2395 msg_type = CVAL(inbuf,0);
2397 if (msg_type == 0x85)
2398 DEBUG(5,("Got keepalive packet\n"));
2401 DEBUG(10,("got smb length of %d\n",len));
2406 /****************************************************************************
2407 read 4 bytes of a smb packet and return the smb length of the packet
2408 store the result in the buffer. This version of the function will
2409 never return a session keepalive (length of zero).
2410 ****************************************************************************/
2411 int read_smb_length(int fd,char *inbuf,int timeout)
2417 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2422 /* Ignore session keepalives. */
2423 if(CVAL(inbuf,0) != 0x85)
2430 /****************************************************************************
2431 read an smb from a fd. Note that the buffer *MUST* be of size
2432 BUFFER_SIZE+SAFETY_MARGIN.
2433 The timeout is in milli seconds.
2435 This function will return on a
2436 receipt of a session keepalive packet.
2437 ****************************************************************************/
2438 BOOL receive_smb(int fd,char *buffer, int timeout)
2444 bzero(buffer,smb_size + 100);
2446 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2450 if (len > BUFFER_SIZE) {
2451 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2452 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2457 ret = read_data(fd,buffer+4,len);
2459 smb_read_error = READ_ERROR;
2466 /****************************************************************************
2467 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2468 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2469 The timeout is in milli seconds
2471 This is exactly the same as receive_smb except that it never returns
2472 a session keepalive packet (just as receive_smb used to do).
2473 receive_smb was changed to return keepalives as the oplock processing means this call
2474 should never go into a blocking read.
2475 ****************************************************************************/
2477 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2483 ret = receive_smb(fd, buffer, timeout);
2488 /* Ignore session keepalive packets. */
2489 if(CVAL(buffer,0) != 0x85)
2495 /****************************************************************************
2496 read a message from a udp fd.
2497 The timeout is in milli seconds
2498 ****************************************************************************/
2499 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2501 struct sockaddr_in from;
2502 int fromlen = sizeof(from);
2516 to.tv_sec = timeout / 1000;
2517 to.tv_usec = (timeout % 1000) * 1000;
2519 selrtn = sys_select(&fds,&to);
2521 /* Check if error */
2524 /* something is wrong. Maybe the socket is dead? */
2525 smb_read_error = READ_ERROR;
2529 /* Did we timeout ? */
2532 smb_read_error = READ_TIMEOUT;
2538 * Read a loopback udp message.
2540 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2541 buffer_len - UDP_CMD_HEADER_LEN, 0,
2542 (struct sockaddr *)&from, &fromlen);
2546 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2550 /* Validate message length. */
2551 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2553 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2555 buffer_len - UDP_CMD_HEADER_LEN));
2559 /* Validate message from address (must be localhost). */
2560 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2562 DEBUG(0,("receive_local_message: invalid 'from' address \
2563 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2567 /* Setup the message header */
2568 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2569 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2574 /****************************************************************************
2575 structure to hold a linked list of local messages.
2577 ****************************************************************************/
2579 typedef struct _message_list {
2580 struct _message_list *msg_next;
2583 } pending_message_list;
2585 static pending_message_list *smb_msg_head = NULL;
2587 /****************************************************************************
2588 Function to push a linked list of local messages ready
2590 ****************************************************************************/
2592 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2594 pending_message_list *msg = (pending_message_list *)
2595 malloc(sizeof(pending_message_list));
2599 DEBUG(0,("push_message: malloc fail (1)\n"));
2603 msg->msg_buf = (char *)malloc(msg_len);
2604 if(msg->msg_buf == NULL)
2606 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2611 memcpy(msg->msg_buf, buf, msg_len);
2612 msg->msg_len = msg_len;
2614 msg->msg_next = *pml;
2620 /****************************************************************************
2621 Function to push a linked list of local smb messages ready
2623 ****************************************************************************/
2625 BOOL push_smb_message(char *buf, int msg_len)
2627 return push_local_message(&smb_msg_head, buf, msg_len);
2630 /****************************************************************************
2631 Do a select on an two fd's - with timeout.
2633 If a local udp message has been pushed onto the
2634 queue (this can only happen during oplock break
2635 processing) return this first.
2637 If a pending smb message has been pushed onto the
2638 queue (this can only happen during oplock break
2639 processing) return this next.
2641 If the first smbfd is ready then read an smb from it.
2642 if the second (loopback UDP) fd is ready then read a message
2643 from it and setup the buffer header to identify the length
2645 Returns False on timeout or error.
2648 The timeout is in milli seconds
2649 ****************************************************************************/
2650 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2651 char *buffer, int buffer_len,
2652 int timeout, BOOL *got_smb)
2663 * Check to see if we already have a message on the smb queue.
2664 * If so - copy and return it.
2669 pending_message_list *msg = smb_msg_head;
2670 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2671 smb_msg_head = msg->msg_next;
2673 /* Free the message we just copied. */
2674 free((char *)msg->msg_buf);
2678 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2684 FD_SET(oplock_fd,&fds);
2686 to.tv_sec = timeout / 1000;
2687 to.tv_usec = (timeout % 1000) * 1000;
2689 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2691 /* Check if error */
2693 /* something is wrong. Maybe the socket is dead? */
2694 smb_read_error = READ_ERROR;
2698 /* Did we timeout ? */
2700 smb_read_error = READ_TIMEOUT;
2704 if (FD_ISSET(smbfd,&fds))
2707 return receive_smb(smbfd, buffer, 0);
2711 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2715 /****************************************************************************
2717 ****************************************************************************/
2718 BOOL send_smb(int fd,char *buffer)
2722 len = smb_len(buffer) + 4;
2724 while (nwritten < len)
2726 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2729 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2741 /****************************************************************************
2742 find a pointer to a netbios name
2743 ****************************************************************************/
2744 char *name_ptr(char *buf,int ofs)
2746 unsigned char c = *(unsigned char *)(buf+ofs);
2748 if ((c & 0xC0) == 0xC0)
2752 memcpy(p,buf+ofs,2);
2755 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2762 /****************************************************************************
2763 extract a netbios name from a buf
2764 ****************************************************************************/
2765 int name_extract(char *buf,int ofs,char *name)
2767 char *p = name_ptr(buf,ofs);
2768 int d = PTR_DIFF(p,buf+ofs);
2770 if (d < -50 || d > 50) return(0);
2771 return(name_interpret(p,name));
2774 /****************************************************************************
2775 return the total storage length of a mangled name
2776 ****************************************************************************/
2777 int name_len( char *s )
2781 /* If the two high bits of the byte are set, return 2. */
2782 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2785 /* Add up the length bytes. */
2786 for( len = 1; (*s); s += (*s) + 1 )
2794 /****************************************************************************
2795 send a single packet to a port on another machine
2796 ****************************************************************************/
2797 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2801 struct sockaddr_in sock_out;
2806 /* create a socket to write to */
2807 out_fd = socket(AF_INET, type, 0);
2810 DEBUG(0,("socket failed"));
2814 /* set the address and port */
2815 bzero((char *)&sock_out,sizeof(sock_out));
2816 putip((char *)&sock_out.sin_addr,(char *)&ip);
2817 sock_out.sin_port = htons( port );
2818 sock_out.sin_family = AF_INET;
2821 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2822 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2825 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2828 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2829 inet_ntoa(ip),port,strerror(errno)));
2835 /*******************************************************************
2836 sleep for a specified number of milliseconds
2837 ********************************************************************/
2841 struct timeval tval,t1,t2;
2848 tval.tv_sec = (t-tdiff)/1000;
2849 tval.tv_usec = 1000*((t-tdiff)%1000);
2853 sys_select(&fds,&tval);
2856 tdiff = TvalDiff(&t1,&t2);
2860 /****************************************************************************
2861 check if a string is part of a list
2862 ****************************************************************************/
2863 BOOL in_list(char *s,char *list,BOOL casesensitive)
2868 if (!list) return(False);
2870 while (next_token(&p,tok,LIST_SEP))
2872 if (casesensitive) {
2873 if (strcmp(tok,s) == 0)
2876 if (StrCaseCmp(tok,s) == 0)
2883 /* this is used to prevent lots of mallocs of size 1 */
2884 static char *null_string = NULL;
2886 /****************************************************************************
2887 set a string value, allocing the space for the string
2888 ****************************************************************************/
2889 BOOL string_init(char **dest,char *src)
2900 null_string = (char *)malloc(1);
2903 *dest = null_string;
2907 (*dest) = (char *)malloc(l+1);
2908 if ((*dest) == NULL) {
2909 DEBUG(0,("Out of memory in string_init\n"));
2918 /****************************************************************************
2920 ****************************************************************************/
2921 void string_free(char **s)
2923 if (!s || !(*s)) return;
2924 if (*s == null_string)
2930 /****************************************************************************
2931 set a string value, allocing the space for the string, and deallocating any
2933 ****************************************************************************/
2934 BOOL string_set(char **dest,char *src)
2938 return(string_init(dest,src));
2941 /****************************************************************************
2942 substitute a string for a pattern in another string. Make sure there is
2945 This routine looks for pattern in s and replaces it with
2946 insert. It may do multiple replacements.
2948 return True if a substitution was done.
2949 ****************************************************************************/
2950 BOOL string_sub(char *s,char *pattern,char *insert)
2956 if (!insert || !pattern || !s) return(False);
2959 lp = strlen(pattern);
2960 li = strlen(insert);
2962 if (!*pattern) return(False);
2964 while (lp <= ls && (p = strstr(s,pattern)))
2967 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2968 memcpy(p,insert,li);
2977 /*********************************************************
2978 * Recursive routine that is called by mask_match.
2979 * Does the actual matching.
2980 *********************************************************/
2981 BOOL do_match(char *str, char *regexp, int case_sig)
2985 for( p = regexp; *p && *str; ) {
2992 /* Look for a character matching
2993 the one after the '*' */
2996 return True; /* Automatic match */
2998 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
3000 if(do_match(str,p,case_sig))
3014 if(toupper(*str) != toupper(*p))
3024 if (!*p && str[0] == '.' && str[1] == 0)
3027 if (!*str && *p == '?')
3029 while (*p == '?') p++;
3033 if(!*str && (*p == '*' && p[1] == '\0'))
3039 /*********************************************************
3040 * Routine to match a given string with a regexp - uses
3041 * simplified regexp that takes * and ? only. Case can be
3042 * significant or not.
3043 *********************************************************/
3044 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3048 fstring ebase,eext,sbase,sext;
3052 /* Make local copies of str and regexp */
3053 StrnCpy(p1,regexp,sizeof(pstring)-1);
3054 StrnCpy(p2,str,sizeof(pstring)-1);
3056 if (!strchr(p2,'.')) {
3061 if (!strchr(p1,'.')) {
3069 string_sub(p1,"*.*","*");
3070 string_sub(p1,".*","*");
3074 /* Remove any *? and ** as they are meaningless */
3075 for(p = p1; *p; p++)
3076 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3077 (void)strcpy( &p[1], &p[2]);
3079 if (strequal(p1,"*")) return(True);
3081 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3087 if ((p=strrchr(p1,'.'))) {
3096 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3106 matched = do_match(sbase,ebase,case_sig) &&
3107 (trans2 || do_match(sext,eext,case_sig));
3109 DEBUG(8,("mask_match returning %d\n", matched));
3116 /****************************************************************************
3117 become a daemon, discarding the controlling terminal
3118 ****************************************************************************/
3119 void become_daemon(void)
3121 #ifndef NO_FORK_DEBUG
3125 /* detach from the terminal */
3128 #else /* USE_SETSID */
3131 int i = open("/dev/tty", O_RDWR);
3134 ioctl(i, (int) TIOCNOTTY, (char *)0);
3138 #endif /* TIOCNOTTY */
3139 #endif /* USE_SETSID */
3140 /* Close fd's 0,1,2. Needed if started by rsh */
3142 #endif /* NO_FORK_DEBUG */
3146 /****************************************************************************
3147 put up a yes/no prompt
3148 ****************************************************************************/
3154 if (!fgets(ans,sizeof(ans)-1,stdin))
3157 if (*ans == 'y' || *ans == 'Y')
3163 /****************************************************************************
3164 read a line from a file with possible \ continuation chars.
3165 Blanks at the start or end of a line are stripped.
3166 The string will be allocated if s2 is NULL
3167 ****************************************************************************/
3168 char *fgets_slash(char *s2,int maxlen,FILE *f)
3173 BOOL start_of_line = True;
3180 maxlen = MIN(maxlen,8);
3181 s = (char *)Realloc(s,maxlen);
3184 if (!s || maxlen < 2) return(NULL);
3188 while (len < maxlen-1)
3196 while (len > 0 && s[len-1] == ' ')
3200 if (len > 0 && s[len-1] == '\\')
3203 start_of_line = True;
3208 if (len <= 0 && !s2)
3210 return(len>0?s:NULL);
3215 start_of_line = False;
3219 if (!s2 && len > maxlen-3)
3222 s = (char *)Realloc(s,maxlen);
3223 if (!s) return(NULL);
3231 /****************************************************************************
3232 set the length of a file from a filedescriptor.
3233 Returns 0 on success, -1 on failure.
3234 ****************************************************************************/
3235 int set_filelen(int fd, long len)
3237 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3238 extend a file with ftruncate. Provide alternate implementation
3241 #if FTRUNCATE_CAN_EXTEND
3242 return ftruncate(fd, len);
3246 long currpos = lseek(fd, 0L, SEEK_CUR);
3250 /* Do an fstat to see if the file is longer than
3251 the requested size (call ftruncate),
3252 or shorter, in which case seek to len - 1 and write 1
3254 if(fstat(fd, &st)<0)
3258 if (S_ISFIFO(st.st_mode)) return 0;
3261 if(st.st_size == len)
3263 if(st.st_size > len)
3264 return ftruncate(fd, len);
3266 if(lseek(fd, len-1, SEEK_SET) != len -1)
3268 if(write(fd, &c, 1)!=1)
3270 /* Seek to where we were */
3271 lseek(fd, currpos, SEEK_SET);
3277 /****************************************************************************
3278 return the byte checksum of some data
3279 ****************************************************************************/
3280 int byte_checksum(char *buf,int len)
3282 unsigned char *p = (unsigned char *)buf;
3292 /****************************************************************************
3293 this is a version of setbuffer() for those machines that only have setvbuf
3294 ****************************************************************************/
3295 void setbuffer(FILE *f,char *buf,int bufsize)
3297 setvbuf(f,buf,_IOFBF,bufsize);
3302 /****************************************************************************
3303 parse out a directory name from a path name. Assumes dos style filenames.
3304 ****************************************************************************/
3305 char *dirname_dos(char *path,char *buf)
3307 char *p = strrchr(path,'\\');
3322 /****************************************************************************
3323 parse out a filename from a path name. Assumes dos style filenames.
3324 ****************************************************************************/
3325 static char *filename_dos(char *path,char *buf)
3327 char *p = strrchr(path,'\\');
3339 /****************************************************************************
3340 expand a pointer to be a particular size
3341 ****************************************************************************/
3342 void *Realloc(void *p,int size)
3348 DEBUG(5,("Realloc asked for 0 bytes\n"));
3353 ret = (void *)malloc(size);
3355 ret = (void *)realloc(p,size);
3358 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3364 /****************************************************************************
3366 ****************************************************************************/
3367 char *strdup(char *s)
3370 if (!s) return(NULL);
3371 ret = (char *)malloc(strlen(s)+1);
3372 if (!ret) return(NULL);
3379 /****************************************************************************
3380 Signal handler for SIGPIPE (write on a disconnected socket)
3381 ****************************************************************************/
3384 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3388 /****************************************************************************
3389 get my own name and IP
3390 ****************************************************************************/
3391 BOOL get_myname(char *my_name,struct in_addr *ip)
3398 /* get my host name */
3399 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3401 DEBUG(0,("gethostname failed\n"));
3406 if ((hp = Get_Hostbyname(hostname)) == 0)
3408 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3414 /* split off any parts after an initial . */
3415 char *p = strchr(hostname,'.');
3418 fstrcpy(my_name,hostname);
3422 putip((char *)ip,(char *)hp->h_addr);
3428 /****************************************************************************
3429 true if two IP addresses are equal
3430 ****************************************************************************/
3431 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3434 a1 = ntohl(ip1.s_addr);
3435 a2 = ntohl(ip2.s_addr);
3440 /****************************************************************************
3441 open a socket of the specified type, port and address for incoming data
3442 ****************************************************************************/
3443 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3446 struct sockaddr_in sock;
3450 /* get my host name */
3451 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3452 { DEBUG(0,("gethostname failed\n")); return -1; }
3455 if ((hp = Get_Hostbyname(host_name)) == 0)
3457 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3461 bzero((char *)&sock,sizeof(sock));
3462 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3463 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3464 sock.sin_len = sizeof(sock);
3466 sock.sin_port = htons( port );
3467 sock.sin_family = hp->h_addrtype;
3468 sock.sin_addr.s_addr = socket_addr;
3469 res = socket(hp->h_addrtype, type, 0);
3471 { DEBUG(0,("socket failed\n")); return -1; }
3475 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3478 /* now we've got a socket - we need to bind it */
3479 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3482 if (port == SMB_PORT || port == NMB_PORT)
3483 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3484 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3487 if (dlevel > 0 && port < 1000)
3490 if (port >= 1000 && port < 9000)
3491 return(open_socket_in(type,port+1,dlevel,socket_addr));
3496 DEBUG(3,("bind succeeded on port %d\n",port));
3502 /****************************************************************************
3503 create an outgoing socket
3504 **************************************************************************/
3505 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3507 struct sockaddr_in sock_out;
3509 int connect_loop = 250; /* 250 milliseconds */
3510 int loops = (timeout * 1000) / connect_loop;
3512 /* create a socket to write to */
3513 res = socket(PF_INET, type, 0);
3515 { DEBUG(0,("socket error\n")); return -1; }
3517 if (type != SOCK_STREAM) return(res);
3519 bzero((char *)&sock_out,sizeof(sock_out));
3520 putip((char *)&sock_out.sin_addr,(char *)addr);
3522 sock_out.sin_port = htons( port );
3523 sock_out.sin_family = PF_INET;
3525 /* set it non-blocking */
3526 set_blocking(res,False);
3528 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3530 /* and connect it to the destination */
3532 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3534 /* Some systems return EAGAIN when they mean EINPROGRESS */
3535 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3536 errno == EAGAIN) && loops--) {
3537 msleep(connect_loop);
3541 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3543 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3549 if (ret < 0 && errno == EISCONN) {
3556 DEBUG(1,("error connecting to %s:%d (%s)\n",
3557 inet_ntoa(*addr),port,strerror(errno)));
3561 /* set it blocking again */
3562 set_blocking(res,True);
3568 /****************************************************************************
3569 interpret a protocol description string, with a default
3570 ****************************************************************************/
3571 int interpret_protocol(char *str,int def)
3573 if (strequal(str,"NT1"))
3574 return(PROTOCOL_NT1);
3575 if (strequal(str,"LANMAN2"))
3576 return(PROTOCOL_LANMAN2);
3577 if (strequal(str,"LANMAN1"))
3578 return(PROTOCOL_LANMAN1);
3579 if (strequal(str,"CORE"))
3580 return(PROTOCOL_CORE);
3581 if (strequal(str,"COREPLUS"))
3582 return(PROTOCOL_COREPLUS);
3583 if (strequal(str,"CORE+"))
3584 return(PROTOCOL_COREPLUS);
3586 DEBUG(0,("Unrecognised protocol level %s\n",str));
3591 /****************************************************************************
3592 interpret a security level
3593 ****************************************************************************/
3594 int interpret_security(char *str,int def)
3596 if (strequal(str,"SERVER"))
3598 if (strequal(str,"USER"))
3600 if (strequal(str,"SHARE"))
3603 DEBUG(0,("Unrecognised security level %s\n",str));
3609 /****************************************************************************
3610 interpret an internet address or name into an IP address in 4 byte form
3611 ****************************************************************************/
3612 uint32 interpret_addr(char *str)
3617 BOOL pure_address = True;
3619 if (strcmp(str,"0.0.0.0") == 0) return(0);
3620 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3622 for (i=0; pure_address && str[i]; i++)
3623 if (!(isdigit(str[i]) || str[i] == '.'))
3624 pure_address = False;
3626 /* if it's in the form of an IP address then get the lib to interpret it */
3628 res = inet_addr(str);
3630 /* otherwise assume it's a network name of some sort and use
3632 if ((hp = Get_Hostbyname(str)) == 0) {
3633 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3636 if(hp->h_addr == NULL) {
3637 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3640 putip((char *)&res,(char *)hp->h_addr);
3643 if (res == (uint32)-1) return(0);
3648 /*******************************************************************
3649 a convenient addition to interpret_addr()
3650 ******************************************************************/
3651 struct in_addr *interpret_addr2(char *str)
3653 static struct in_addr ret;
3654 uint32 a = interpret_addr(str);
3659 /*******************************************************************
3660 check if an IP is the 0.0.0.0
3661 ******************************************************************/
3662 BOOL zero_ip(struct in_addr ip)
3665 putip((char *)&a,(char *)&ip);
3670 /*******************************************************************
3671 matchname - determine if host name matches IP address
3672 ******************************************************************/
3673 static BOOL matchname(char *remotehost,struct in_addr addr)
3678 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3679 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3684 * Make sure that gethostbyname() returns the "correct" host name.
3685 * Unfortunately, gethostbyname("localhost") sometimes yields
3686 * "localhost.domain". Since the latter host name comes from the
3687 * local DNS, we just have to trust it (all bets are off if the local
3688 * DNS is perverted). We always check the address list, though.
3691 if (strcasecmp(remotehost, hp->h_name)
3692 && strcasecmp(remotehost, "localhost")) {
3693 DEBUG(0,("host name/name mismatch: %s != %s",
3694 remotehost, hp->h_name));
3698 /* Look up the host address in the address list we just got. */
3699 for (i = 0; hp->h_addr_list[i]; i++) {
3700 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3705 * The host name does not map to the original host address. Perhaps
3706 * someone has compromised a name server. More likely someone botched
3707 * it, but that could be dangerous, too.
3710 DEBUG(0,("host name/address mismatch: %s != %s",
3711 inet_ntoa(addr), hp->h_name));
3715 /*******************************************************************
3716 Reset the 'done' variables so after a client process is created
3717 from a fork call these calls will be re-done. This should be
3718 expanded if more variables need reseting.
3719 ******************************************************************/
3721 static BOOL global_client_name_done = False;
3722 static BOOL global_client_addr_done = False;
3724 void reset_globals_after_fork()
3726 global_client_name_done = False;
3727 global_client_addr_done = False;
3730 /*******************************************************************
3731 return the DNS name of the client
3732 ******************************************************************/
3733 char *client_name(int fd)
3736 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3737 int length = sizeof(sa);
3738 static pstring name_buf;
3740 static int last_fd=-1;
3742 if (global_client_name_done && last_fd == fd)
3746 global_client_name_done = False;
3748 strcpy(name_buf,"UNKNOWN");
3754 if (getpeername(fd, &sa, &length) < 0) {
3755 DEBUG(0,("getpeername failed\n"));
3759 /* Look up the remote host name. */
3760 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3761 sizeof(sockin->sin_addr),
3763 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3764 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3766 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3767 if (!matchname(name_buf, sockin->sin_addr)) {
3768 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3769 strcpy(name_buf,"UNKNOWN");
3772 global_client_name_done = True;
3776 /*******************************************************************
3777 return the IP addr of the client as a string
3778 ******************************************************************/
3779 char *client_addr(int fd)
3782 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3783 int length = sizeof(sa);
3784 static fstring addr_buf;
3785 static int last_fd = -1;
3787 if (global_client_addr_done && fd == last_fd)
3791 global_client_addr_done = False;
3793 strcpy(addr_buf,"0.0.0.0");
3799 if (getpeername(fd, &sa, &length) < 0) {
3800 DEBUG(0,("getpeername failed\n"));
3804 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3806 global_client_addr_done = True;
3810 /*******************************************************************
3811 Patch from jkf@soton.ac.uk
3812 Split Luke's automount_server into YP lookup and string splitter
3813 so can easily implement automount_path().
3814 As we may end up doing both, cache the last YP result.
3815 *******************************************************************/
3817 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3819 static char *automount_lookup(char *user_name)
3821 static fstring last_key = "";
3822 static pstring last_value = "";
3824 char *nis_map = (char *)lp_nis_home_map_name();
3826 char nis_domain[NIS_MAXNAMELEN + 1];
3827 char buffer[NIS_MAXATTRVAL + 1];
3832 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3833 nis_domain[NIS_MAXNAMELEN] = '\0';
3835 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3837 if (strcmp(user_name, last_key))
3839 sprintf(buffer, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3840 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3842 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3844 if (result->status != NIS_SUCCESS)
3846 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3847 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3851 object = result->objects.objects_val;
3852 if (object->zo_data.zo_type == ENTRY_OBJ)
3854 entry = &object->zo_data.objdata_u.en_data;
3855 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3856 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3858 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3859 string_sub(last_value, "&", user_name);
3860 fstrcpy(last_key, user_name);
3864 nis_freeresult(result);
3866 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3870 static char *automount_lookup(char *user_name)
3872 static fstring last_key = "";
3873 static pstring last_value = "";
3875 int nis_error; /* returned by yp all functions */
3876 char *nis_result; /* yp_match inits this */
3877 int nis_result_len; /* and set this */
3878 char *nis_domain; /* yp_get_default_domain inits this */
3879 char *nis_map = (char *)lp_nis_home_map_name();
3881 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3883 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3887 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3889 if (!strcmp(user_name, last_key))
3891 nis_result = last_value;
3892 nis_result_len = strlen(last_value);
3897 if ((nis_error = yp_match(nis_domain, nis_map,
3898 user_name, strlen(user_name),
3899 &nis_result, &nis_result_len)) != 0)
3901 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3902 yperr_string(nis_error), user_name, nis_map));
3904 if (!nis_error && nis_result_len >= sizeof(pstring))
3906 nis_result_len = sizeof(pstring)-1;
3908 fstrcpy(last_key, user_name);
3909 strncpy(last_value, nis_result, nis_result_len);
3910 last_value[nis_result_len] = '\0';
3913 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3916 #endif /* NISPLUS */
3919 /*******************************************************************
3920 Patch from jkf@soton.ac.uk
3921 This is Luke's original function with the NIS lookup code
3922 moved out to a separate function.
3923 *******************************************************************/
3925 char *automount_server(char *user_name)
3927 static pstring server_name;
3929 /* use the local machine name as the default */
3930 /* this will be the default if AUTOMOUNT is not used or fails */
3931 pstrcpy(server_name, local_machine);
3933 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3935 if (lp_nis_home_map())
3937 int home_server_len;
3938 char *automount_value = automount_lookup(user_name);
3939 home_server_len = strcspn(automount_value,":");
3940 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3941 if (home_server_len > sizeof(pstring))
3943 home_server_len = sizeof(pstring);
3945 strncpy(server_name, automount_value, home_server_len);
3946 server_name[home_server_len] = '\0';
3950 DEBUG(4,("Home server: %s\n", server_name));
3955 /*******************************************************************
3956 Patch from jkf@soton.ac.uk
3957 Added this to implement %p (NIS auto-map version of %H)
3958 *******************************************************************/
3960 char *automount_path(char *user_name)
3962 static pstring server_path;
3964 /* use the passwd entry as the default */
3965 /* this will be the default if AUTOMOUNT is not used or fails */
3966 /* pstrcpy() copes with get_home_dir() returning NULL */
3967 pstrcpy(server_path, get_home_dir(user_name));
3969 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3971 if (lp_nis_home_map())
3973 char *home_path_start;
3974 char *automount_value = automount_lookup(user_name);
3975 home_path_start = strchr(automount_value,':');
3976 if (home_path_start != NULL)
3978 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3979 home_path_start?(home_path_start+1):""));
3980 strcpy(server_path, home_path_start+1);
3985 DEBUG(4,("Home server path: %s\n", server_path));
3991 /*******************************************************************
3992 sub strings with useful parameters
3993 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3994 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3995 ********************************************************************/
3996 void standard_sub_basic(char *str)
4000 struct passwd *pass;
4001 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4003 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4009 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
4011 string_sub(p,"%G",gidtoname(pass->pw_gid));
4019 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4020 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4021 case 'L' : string_sub(p,"%L", local_machine); break;
4022 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4023 case 'R' : string_sub(p,"%R", remote_proto); break;
4024 case 'T' : string_sub(p,"%T", timestring()); break;
4025 case 'U' : string_sub(p,"%U", username); break;
4026 case 'a' : string_sub(p,"%a", remote_arch); break;
4029 sprintf(pidstr,"%d",(int)getpid());
4030 string_sub(p,"%d", pidstr);
4033 case 'h' : string_sub(p,"%h", myhostname); break;
4034 case 'm' : string_sub(p,"%m", remote_machine); break;
4035 case 'v' : string_sub(p,"%v", VERSION); break;
4036 case '$' : /* Expand environment variables */
4038 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4044 if (*(p+2) != '(') { p+=2; break; }
4045 if ((q = strchr(p,')')) == NULL)
4047 DEBUG(0,("standard_sub_basic: Unterminated environment \
4048 variable [%s]\n", p));
4053 copylen = MIN((q-r),(sizeof(envname)-1));
4054 strncpy(envname,r,copylen);
4055 envname[copylen] = '\0';
4056 if ((envval = getenv(envname)) == NULL)
4058 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4062 copylen = MIN((q+1-p),(sizeof(envname)-1));
4063 strncpy(envname,p,copylen);
4064 envname[copylen] = '\0';
4065 string_sub(p,envname,envval);
4068 case '\0': p++; break; /* don't run off end if last character is % */
4069 default : p+=2; break;
4075 /*******************************************************************
4076 are two IPs on the same subnet?
4077 ********************************************************************/
4078 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4080 uint32 net1,net2,nmask;
4082 nmask = ntohl(mask.s_addr);
4083 net1 = ntohl(ip1.s_addr);
4084 net2 = ntohl(ip2.s_addr);
4086 return((net1 & nmask) == (net2 & nmask));
4090 /*******************************************************************
4091 write a string in unicoode format
4092 ********************************************************************/
4093 int PutUniCode(char *dst,char *src)
4097 dst[ret++] = src[0];
4106 /****************************************************************************
4107 a wrapper for gethostbyname() that tries with all lower and all upper case
4108 if the initial name fails
4109 ****************************************************************************/
4110 struct hostent *Get_Hostbyname(char *name)
4112 char *name2 = strdup(name);
4113 struct hostent *ret;
4117 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4123 * This next test is redundent and causes some systems (with
4124 * broken isalnum() calls) problems.
4129 if (!isalnum(*name2))
4136 ret = sys_gethostbyname(name2);
4143 /* try with all lowercase */
4145 ret = sys_gethostbyname(name2);
4152 /* try with all uppercase */
4154 ret = sys_gethostbyname(name2);
4161 /* nothing works :-( */
4167 /****************************************************************************
4168 check if a process exists. Does this work on all unixes?
4169 ****************************************************************************/
4170 BOOL process_exists(int pid)
4172 return(kill(pid,0) == 0 || errno != ESRCH);
4176 /*******************************************************************
4177 turn a uid into a user name
4178 ********************************************************************/
4179 char *uidtoname(int uid)
4181 static char name[40];
4182 struct passwd *pass = getpwuid(uid);
4183 if (pass) return(pass->pw_name);
4184 sprintf(name,"%d",uid);
4188 /*******************************************************************
4189 turn a gid into a group name
4190 ********************************************************************/
4191 char *gidtoname(int gid)
4193 static char name[40];
4194 struct group *grp = getgrgid(gid);
4195 if (grp) return(grp->gr_name);
4196 sprintf(name,"%d",gid);
4200 /*******************************************************************
4202 ********************************************************************/
4203 void BlockSignals(BOOL block,int signum)
4206 int block_mask = sigmask(signum);
4207 static int oldmask = 0;
4209 oldmask = sigblock(block_mask);
4211 sigsetmask(oldmask);
4212 #elif defined(USE_SIGPROCMASK)
4215 sigaddset(&set,signum);
4216 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4221 /*******************************************************************
4222 my own panic function - not suitable for general use
4223 ********************************************************************/
4224 void ajt_panic(void)
4226 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4231 #define DIRECT direct
4233 #define DIRECT dirent
4236 /*******************************************************************
4237 a readdir wrapper which just returns the file name
4238 also return the inode number if requested
4239 ********************************************************************/
4240 char *readdirname(void *p)
4245 if (!p) return(NULL);
4247 ptr = (struct DIRECT *)readdir(p);
4248 if (!ptr) return(NULL);
4250 dname = ptr->d_name;
4253 if (telldir(p) < 0) return(NULL);
4257 /* this handles a broken compiler setup, causing a mixture
4258 of BSD and SYSV headers and libraries */
4260 static BOOL broken_readdir = False;
4261 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4263 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4264 broken_readdir = True;
4273 pstrcpy(buf, dname);
4274 unix_to_dos(buf, True);
4281 /*******************************************************************
4282 Utility function used to decide if the last component
4283 of a path matches a (possibly wildcarded) entry in a namelist.
4284 ********************************************************************/
4286 BOOL is_in_path(char *name, name_compare_entry *namelist)
4288 pstring last_component;
4291 DEBUG(8, ("is_in_path: %s\n", name));
4293 /* if we have no list it's obviously not in the path */
4294 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4296 DEBUG(8,("is_in_path: no name list.\n"));
4300 /* Get the last component of the unix name. */
4301 p = strrchr(name, '/');
4302 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4303 last_component[sizeof(last_component)-1] = '\0';
4305 for(; namelist->name != NULL; namelist++)
4307 if(namelist->is_wild)
4309 /* look for a wildcard match. */
4310 if (mask_match(last_component, namelist->name, case_sensitive, False))
4312 DEBUG(8,("is_in_path: mask match succeeded\n"));
4318 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4319 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4321 DEBUG(8,("is_in_path: match succeeded\n"));
4326 DEBUG(8,("is_in_path: match not found\n"));
4331 /*******************************************************************
4332 Strip a '/' separated list into an array of
4333 name_compare_enties structures suitable for
4334 passing to is_in_path(). We do this for
4335 speed so we can pre-parse all the names in the list
4336 and don't do it for each call to is_in_path().
4337 namelist is modified here and is assumed to be
4338 a copy owned by the caller.
4339 We also check if the entry contains a wildcard to
4340 remove a potentially expensive call to mask_match
4342 ********************************************************************/
4344 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4347 char *nameptr = namelist;
4348 int num_entries = 0;
4351 (*ppname_array) = NULL;
4353 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4356 /* We need to make two passes over the string. The
4357 first to count the number of elements, the second
4362 if ( *nameptr == '/' )
4364 /* cope with multiple (useless) /s) */
4368 /* find the next / */
4369 name_end = strchr(nameptr, '/');
4371 /* oops - the last check for a / didn't find one. */
4372 if (name_end == NULL)
4375 /* next segment please */
4376 nameptr = name_end + 1;
4380 if(num_entries == 0)
4383 if(( (*ppname_array) = (name_compare_entry *)malloc(
4384 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4386 DEBUG(0,("set_namearray: malloc fail\n"));
4390 /* Now copy out the names */
4395 if ( *nameptr == '/' )
4397 /* cope with multiple (useless) /s) */
4401 /* find the next / */
4402 if ((name_end = strchr(nameptr, '/')) != NULL)
4407 /* oops - the last check for a / didn't find one. */
4408 if(name_end == NULL)
4411 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4412 (strchr( nameptr, '*')!=NULL));
4413 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4415 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4419 /* next segment please */
4420 nameptr = name_end + 1;
4424 (*ppname_array)[i].name = NULL;
4429 /****************************************************************************
4430 routine to free a namearray.
4431 ****************************************************************************/
4433 void free_namearray(name_compare_entry *name_array)
4438 if(name_array->name != NULL)
4439 free(name_array->name);
4441 free((char *)name_array);
4444 /****************************************************************************
4445 routine to do file locking
4446 ****************************************************************************/
4447 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4454 uint32 mask = 0xC0000000;
4456 /* make sure the count is reasonable, we might kill the lockd otherwise */
4459 /* the offset is often strange - remove 2 of its bits if either of
4460 the top two bits are set. Shift the top ones by two bits. This
4461 still allows OLE2 apps to operate, but should stop lockd from
4463 if ((offset & mask) != 0)
4464 offset = (offset & ~mask) | ((offset & mask) >> 2);
4466 uint32 mask = ((unsigned)1<<31);
4468 /* interpret negative counts as large numbers */
4472 /* no negative offsets */
4475 /* count + offset must be in range */
4476 while ((offset < 0 || (offset + count < 0)) && mask)
4484 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4487 lock.l_whence = SEEK_SET;
4488 lock.l_start = (int)offset;
4489 lock.l_len = (int)count;
4494 ret = fcntl(fd,op,&lock);
4497 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4503 (lock.l_type != F_UNLCK) &&
4504 (lock.l_pid != 0) &&
4505 (lock.l_pid != getpid()))
4507 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4511 /* it must be not locked or locked by me */
4515 /* a lock set or unset */
4518 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4519 offset,count,op,type,strerror(errno)));
4521 /* perhaps it doesn't support this sort of locking?? */
4522 if (errno == EINVAL)
4524 DEBUG(3,("locking not supported? returning True\n"));
4531 /* everything went OK */
4532 DEBUG(8,("Lock call successful\n"));
4540 /*******************************************************************
4541 lock a file - returning a open file descriptor or -1 on failure
4542 The timeout is in seconds. 0 means no timeout
4543 ********************************************************************/
4544 int file_lock(char *name,int timeout)
4546 int fd = open(name,O_RDWR|O_CREAT,0666);
4548 if (fd < 0) return(-1);
4551 if (timeout) t = time(NULL);
4552 while (!timeout || (time(NULL)-t < timeout)) {
4553 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4554 msleep(LOCK_RETRY_TIMEOUT);
4562 /*******************************************************************
4563 unlock a file locked by file_lock
4564 ********************************************************************/
4565 void file_unlock(int fd)
4569 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4574 /*******************************************************************
4575 is the name specified one of my netbios names
4576 returns true is it is equal, false otherwise
4577 ********************************************************************/
4578 BOOL is_myname(char *s)
4583 for (n=0; my_netbios_names[n]; n++) {
4584 if (strequal(my_netbios_names[n], s))
4587 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4591 /*******************************************************************
4592 set the horrid remote_arch string based on an enum.
4593 ********************************************************************/
4594 void set_remote_arch(enum remote_arch_types type)
4600 strcpy(remote_arch, "WfWg");
4603 strcpy(remote_arch, "OS2");
4606 strcpy(remote_arch, "Win95");
4609 strcpy(remote_arch, "WinNT");
4612 strcpy(remote_arch,"Samba");
4615 ra_type = RA_UNKNOWN;
4616 strcpy(remote_arch, "UNKNOWN");
4621 /*******************************************************************
4622 Get the remote_arch type.
4623 ********************************************************************/
4624 enum remote_arch_types get_remote_arch()
4630 /*******************************************************************
4631 skip past some unicode strings in a buffer
4632 ********************************************************************/
4633 char *skip_unicode_string(char *buf,int n)
4644 /*******************************************************************
4645 Return a ascii version of a unicode string
4646 Hack alert: uses fixed buffer(s) and only handles ascii strings
4647 ********************************************************************/
4649 char *unistrn2(uint16 *buf, int len)
4651 static char lbufs[8][MAXUNI];
4653 char *lbuf = lbufs[nexti];
4656 nexti = (nexti+1)%8;
4658 DEBUG(10, ("unistrn2: "));
4660 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4662 DEBUG(10, ("%4x ", *buf));
4672 /*******************************************************************
4673 Return a ascii version of a unicode string
4674 Hack alert: uses fixed buffer(s) and only handles ascii strings
4675 ********************************************************************/
4677 char *unistr2(uint16 *buf)
4679 static char lbufs[8][MAXUNI];
4681 char *lbuf = lbufs[nexti];
4684 nexti = (nexti+1)%8;
4686 DEBUG(10, ("unistr2: "));
4688 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4690 DEBUG(10, ("%4x ", *buf));
4700 /*******************************************************************
4701 create a null-terminated unicode string from a null-terminated ascii string.
4702 return number of unicode chars copied, excluding the null character.
4704 only handles ascii strings
4705 ********************************************************************/
4707 int struni2(uint16 *p, char *buf)
4711 if (p == NULL) return 0;
4713 DEBUG(10, ("struni2: "));
4717 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4719 DEBUG(10, ("%2x ", *buf));
4731 /*******************************************************************
4732 Return a ascii version of a unicode string
4733 Hack alert: uses fixed buffer(s) and only handles ascii strings
4734 ********************************************************************/
4736 char *unistr(char *buf)
4738 static char lbufs[8][MAXUNI];
4740 char *lbuf = lbufs[nexti];
4743 nexti = (nexti+1)%8;
4745 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4753 /*******************************************************************
4754 strncpy for unicode strings
4755 ********************************************************************/
4756 int unistrncpy(char *dst, char *src, int len)
4760 while (*src && len > 0)
4774 /*******************************************************************
4775 strcpy for unicode strings. returns length (in num of wide chars)
4776 ********************************************************************/
4777 int unistrcpy(char *dst, char *src)
4794 /*******************************************************************
4795 safe string copy into a fstring
4796 ********************************************************************/
4797 void fstrcpy(char *dest, char *src)
4799 int maxlength = sizeof(fstring) - 1;
4801 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4810 while (maxlength-- && *src)
4814 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4819 /*******************************************************************
4820 safe string copy into a pstring
4821 ********************************************************************/
4822 void pstrcpy(char *dest, char *src)
4824 int maxlength = sizeof(pstring) - 1;
4826 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4835 while (maxlength-- && *src)
4839 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4845 /*******************************************************************
4846 align a pointer to a multiple of 4 bytes
4847 ********************************************************************/
4848 char *align4(char *q, char *base)
4852 q += 4 - ((q - base) & 3);
4857 /*******************************************************************
4858 align a pointer to a multiple of 2 bytes
4859 ********************************************************************/
4860 char *align2(char *q, char *base)
4869 /*******************************************************************
4870 align a pointer to a multiple of align_offset bytes. looks like it
4871 will work for offsets of 0, 2 and 4...
4872 ********************************************************************/
4873 char *align_offset(char *q, char *base, int align_offset_len)
4875 int mod = ((q - base) & (align_offset_len-1));
4876 if (align_offset_len != 0 && mod != 0)
4878 q += align_offset_len - mod;
4883 void print_asc(int level, unsigned char *buf,int len)
4887 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4890 void dump_data(int level,char *buf1,int len)
4892 unsigned char *buf = (unsigned char *)buf1;
4896 DEBUG(level,("[%03X] ",i));
4898 DEBUG(level,("%02X ",(int)buf[i]));
4900 if (i%8 == 0) DEBUG(level,(" "));
4902 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4903 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4904 if (i<len) DEBUG(level,("[%03X] ",i));
4912 if (n>8) DEBUG(level,(" "));
4913 while (n--) DEBUG(level,(" "));
4916 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4918 if (n>0) print_asc(level,&buf[i-n],n);
4919 DEBUG(level,("\n"));
4923 char *tab_depth(int depth)
4925 static pstring spaces;
4926 memset(spaces, ' ', depth * 4);
4927 spaces[depth * 4] = 0;
4931 /*****************************************************************
4932 Convert a domain SID to an ascii string. (non-reentrant).
4933 *****************************************************************/
4935 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4936 char *dom_sid_to_string(DOM_SID *sid)
4938 static pstring sidstr;
4941 uint32 ia = (sid->id_auth[5]) +
4942 (sid->id_auth[4] << 8 ) +
4943 (sid->id_auth[3] << 16) +
4944 (sid->id_auth[2] << 24);
4946 sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
4948 for (i = 0; i < sid->num_auths; i++)
4950 sprintf(subauth, "-%d", sid->sub_auths[i]);
4951 strcat(sidstr, subauth);
4954 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));