2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #if (defined(NETGROUP) && defined (AUTOMOUNT))
26 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
38 int Protocol = PROTOCOL_COREPLUS;
40 /* a default finfo structure to ensure all fields are sensible */
41 file_info def_finfo = {-1,0,0,0,0,0,0,""};
43 /* these are some file handles where debug info will be stored */
46 /* the client file descriptor */
49 /* the last IP received from */
50 struct in_addr lastip;
52 /* the last port received from */
55 /* this is used by the chaining code */
61 case handling on filenames
63 int case_default = CASE_LOWER;
68 /* the following control case operations - they are put here so the
69 client can link easily */
72 BOOL use_mangled_map = False;
73 BOOL short_case_preserve;
76 fstring remote_machine="";
77 fstring local_machine="";
78 fstring remote_arch="UNKNOWN";
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
80 fstring remote_proto="UNKNOWN";
81 pstring myhostname="";
82 pstring user_socket_options="";
84 pstring sesssetup_user="";
85 pstring samlogon_user="";
87 BOOL sam_logon_in_ssb = False;
89 pstring global_myname = "";
90 fstring global_myworkgroup = "";
91 char **my_netbios_names;
93 int smb_read_error = 0;
95 static BOOL stdout_logging = False;
97 static char *filename_dos(char *path,char *buf);
100 /******************************************************************************
101 catch a sigusr2 - decrease the debug log level.
102 *****************************************************************************/
105 BlockSignals( True, SIGUSR2);
112 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
114 BlockSignals( False, SIGUSR2);
115 #ifndef DONT_REINSTALL_SIG
116 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
123 /**************************************************************************** **
124 catch a sigusr1 - increase the debug log level.
125 **************************************************************************** */
128 BlockSignals( True, SIGUSR1);
135 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
137 BlockSignals( False, SIGUSR1);
138 #ifndef DONT_REINSTALL_SIG
139 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
146 /*******************************************************************
147 get ready for syslog stuff
148 ******************************************************************/
149 void setup_logging(char *pname,BOOL interactive)
153 char *p = strrchr(pname,'/');
156 openlog(pname, LOG_PID, SYSLOG_FACILITY);
157 #else /* for old systems that have no facility codes. */
158 openlog(pname, LOG_PID);
163 stdout_logging = True;
169 BOOL append_log=False;
172 /****************************************************************************
174 ****************************************************************************/
175 void reopen_logs(void)
181 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);
274 dbf = fopen(debugf,"a");
276 dbf = fopen(debugf,"w");
288 if (syslog_level < lp_syslog())
291 * map debug levels to syslog() priorities
292 * note that not all DEBUG(0, ...) calls are
295 static int priority_map[] = {
304 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
306 priority = LOG_DEBUG;
308 priority = priority_map[syslog_level];
311 va_start(ap, format_str);
314 format_str = va_arg(ap,char *);
316 vsprintf(msgbuf, format_str, ap);
320 syslog(priority, "%s", msgbuf);
325 if (!lp_syslog_only())
329 va_start(ap, format_str);
332 format_str = va_arg(ap,char *);
334 vfprintf(dbf,format_str,ap);
346 /****************************************************************************
347 find a suitable temporary directory. The result should be copied immediately
348 as it may be overwritten by a subsequent call
349 ****************************************************************************/
353 if ((p = getenv("TMPDIR"))) {
361 /****************************************************************************
362 determine if a file descriptor is in fact a socket
363 ****************************************************************************/
364 BOOL is_a_socket(int fd)
368 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
372 static char *last_ptr=NULL;
374 /****************************************************************************
375 Get the next token from a string, return False if none found
376 handles double-quotes.
377 Based on a routine by GJC@VILLAGE.COM.
378 Extensively modified by Andrew.Tridgell@anu.edu.au
379 ****************************************************************************/
380 BOOL next_token(char **ptr,char *buff,char *sep)
385 if (!ptr) ptr = &last_ptr;
386 if (!ptr) return(False);
390 /* default to simple separators */
391 if (!sep) sep = " \t\n\r";
393 /* find the first non sep char */
394 while(*s && strchr(sep,*s)) s++;
397 if (! *s) return(False);
399 /* copy over the token */
400 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
408 *ptr = (*s) ? s+1 : s;
415 /****************************************************************************
416 Convert list of tokens to array; dependent on above routine.
417 Uses last_ptr from above - bit of a hack.
418 ****************************************************************************/
419 char **toktocliplist(int *ctok, char *sep)
425 if (!sep) sep = " \t\n\r";
427 while(*s && strchr(sep,*s)) s++;
430 if (!*s) return(NULL);
434 while(*s && (!strchr(sep,*s))) s++;
435 while(*s && strchr(sep,*s)) *s++=0;
441 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
453 /*******************************************************************
454 safely copies memory, ensuring no overlap problems.
455 this is only used if the machine does not have it's own memmove().
456 this is not the fastest algorithm in town, but it will do for our
458 ********************************************************************/
459 void *MemMove(void *dest,void *src,int size)
463 if (dest==src || !size) return(dest);
465 d = (unsigned long)dest;
466 s = (unsigned long)src;
468 if ((d >= (s+size)) || (s >= (d+size))) {
470 memcpy(dest,src,size);
476 /* we can forward copy */
477 if (s-d >= sizeof(int) &&
478 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
479 /* do it all as words */
480 int *idest = (int *)dest;
481 int *isrc = (int *)src;
483 for (i=0;i<size;i++) idest[i] = isrc[i];
486 char *cdest = (char *)dest;
487 char *csrc = (char *)src;
488 for (i=0;i<size;i++) cdest[i] = csrc[i];
493 /* must backward copy */
494 if (d-s >= sizeof(int) &&
495 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
496 /* do it all as words */
497 int *idest = (int *)dest;
498 int *isrc = (int *)src;
500 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
503 char *cdest = (char *)dest;
504 char *csrc = (char *)src;
505 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
513 /****************************************************************************
514 prompte a dptr (to make it recently used)
515 ****************************************************************************/
516 void array_promote(char *array,int elsize,int element)
522 p = (char *)malloc(elsize);
526 DEBUG(5,("Ahh! Can't malloc\n"));
529 memcpy(p,array + element * elsize, elsize);
530 memmove(array + elsize,array,elsize*element);
531 memcpy(array,p,elsize);
535 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
544 } socket_options[] = {
545 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
546 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
547 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
549 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
551 #ifdef IPTOS_LOWDELAY
552 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
554 #ifdef IPTOS_THROUGHPUT
555 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
558 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
561 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
564 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
567 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
570 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
573 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
579 /****************************************************************************
580 set user socket options
581 ****************************************************************************/
582 void set_socket_options(int fd, char *options)
586 while (next_token(&options,tok," \t,"))
591 BOOL got_value = False;
593 if ((p = strchr(tok,'=')))
600 for (i=0;socket_options[i].name;i++)
601 if (strequal(socket_options[i].name,tok))
604 if (!socket_options[i].name)
606 DEBUG(0,("Unknown socket option %s\n",tok));
610 switch (socket_options[i].opttype)
614 ret = setsockopt(fd,socket_options[i].level,
615 socket_options[i].option,(char *)&value,sizeof(int));
620 DEBUG(0,("syntax error - %s does not take a value\n",tok));
623 int on = socket_options[i].value;
624 ret = setsockopt(fd,socket_options[i].level,
625 socket_options[i].option,(char *)&on,sizeof(int));
631 DEBUG(0,("Failed to set socket option %s\n",tok));
637 /****************************************************************************
638 close the socket communication
639 ****************************************************************************/
640 void close_sockets(void )
646 /****************************************************************************
647 determine whether we are in the specified group
648 ****************************************************************************/
649 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
653 if (group == current_gid) return(True);
655 for (i=0;i<ngroups;i++)
656 if (group == groups[i])
662 /****************************************************************************
663 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
664 ****************************************************************************/
665 char *StrCpy(char *dest,char *src)
670 /* I don't want to get lazy with these ... */
672 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
677 if (!dest) return(NULL);
682 while ((*d++ = *src++)) ;
686 /****************************************************************************
687 line strncpy but always null terminates. Make sure there is room!
688 ****************************************************************************/
689 char *StrnCpy(char *dest,char *src,int n)
692 if (!dest) return(NULL);
697 while (n-- && (*d++ = *src++)) ;
703 /*******************************************************************
704 copy an IP address from one buffer to another
705 ********************************************************************/
706 void putip(void *dest,void *src)
712 /****************************************************************************
713 interpret the weird netbios "name". Return the name type
714 ****************************************************************************/
715 static int name_interpret(char *in,char *out)
718 int len = (*in++) / 2;
722 if (len > 30 || len<1) return(0);
726 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
730 *out = ((in[0]-'A')<<4) + (in[1]-'A');
738 /* Handle any scope names */
741 *out++ = '.'; /* Scope names are separated by periods */
742 len = *(unsigned char *)in++;
743 StrnCpy(out, in, len);
752 /****************************************************************************
753 mangle a name into netbios format
755 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
756 ****************************************************************************/
757 int name_mangle( char *In, char *Out, char name_type )
765 /* Safely copy the input string, In, into buf[]. */
766 (void)memset( buf, 0, 20 );
770 (void)sprintf( buf, "%-15.15s%c", In, name_type );
772 /* Place the length of the first field into the output buffer. */
776 /* Now convert the name to the rfc1001/1002 format. */
777 for( i = 0; i < 16; i++ )
779 c = toupper( buf[i] );
780 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
781 p[(i*2)+1] = (c & 0x000F) + 'A';
786 /* Add the scope string. */
787 for( i = 0, len = 0; NULL != scope; i++, len++ )
795 return( name_len(Out) );
807 return( name_len(Out) );
810 /*******************************************************************
811 check if a file exists
812 ********************************************************************/
813 BOOL file_exist(char *fname,struct stat *sbuf)
816 if (!sbuf) sbuf = &st;
818 if (sys_stat(fname,sbuf) != 0)
821 return(S_ISREG(sbuf->st_mode));
824 /*******************************************************************
825 check a files mod time
826 ********************************************************************/
827 time_t file_modtime(char *fname)
831 if (sys_stat(fname,&st) != 0)
837 /*******************************************************************
838 check if a directory exists
839 ********************************************************************/
840 BOOL directory_exist(char *dname,struct stat *st)
847 if (sys_stat(dname,st) != 0)
850 ret = S_ISDIR(st->st_mode);
856 /*******************************************************************
857 returns the size in bytes of the named file
858 ********************************************************************/
859 uint32 file_size(char *file_name)
863 sys_stat(file_name,&buf);
867 /*******************************************************************
868 return a string representing an attribute for a file
869 ********************************************************************/
870 char *attrib_string(int mode)
872 static char attrstr[10];
876 if (mode & aVOLID) strcat(attrstr,"V");
877 if (mode & aDIR) strcat(attrstr,"D");
878 if (mode & aARCH) strcat(attrstr,"A");
879 if (mode & aHIDDEN) strcat(attrstr,"H");
880 if (mode & aSYSTEM) strcat(attrstr,"S");
881 if (mode & aRONLY) strcat(attrstr,"R");
887 /*******************************************************************
888 case insensitive string compararison
889 ********************************************************************/
890 int StrCaseCmp(char *s, char *t)
892 /* compare until we run out of string, either t or s, or find a difference */
893 /* We *must* use toupper rather than tolower here due to the
894 asynchronous upper to lower mapping.
896 #if !defined(KANJI_WIN95_COMPATIBILITY)
898 * For completeness we should put in equivalent code for code pages
899 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
900 * doubt anyone wants Samba to behave differently from Win95 and WinNT
901 * here. They both treat full width ascii characters as case senstive
902 * filenames (ie. they don't do the work we do here).
906 if(lp_client_code_page() == KANJI_CODEPAGE)
908 /* Win95 treats full width ascii characters as case sensitive. */
913 return toupper (*s) - toupper (*t);
914 else if (is_sj_alph (*s) && is_sj_alph (*t))
916 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
922 else if (is_shift_jis (*s) && is_shift_jis (*t))
924 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
927 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
933 else if (is_shift_jis (*s))
935 else if (is_shift_jis (*t))
939 diff = toupper (*s) - toupper (*t);
948 #endif /* KANJI_WIN95_COMPATIBILITY */
950 while (*s && *t && toupper(*s) == toupper(*t))
956 return(toupper(*s) - toupper(*t));
960 /*******************************************************************
961 case insensitive string compararison, length limited
962 ********************************************************************/
963 int StrnCaseCmp(char *s, char *t, int n)
965 /* compare until we run out of string, either t or s, or chars */
966 /* We *must* use toupper rather than tolower here due to the
967 asynchronous upper to lower mapping.
969 #if !defined(KANJI_WIN95_COMPATIBILITY)
971 * For completeness we should put in equivalent code for code pages
972 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
973 * doubt anyone wants Samba to behave differently from Win95 and WinNT
974 * here. They both treat full width ascii characters as case senstive
975 * filenames (ie. they don't do the work we do here).
979 if(lp_client_code_page() == KANJI_CODEPAGE)
981 /* Win95 treats full width ascii characters as case sensitive. */
986 return toupper (*s) - toupper (*t);
987 else if (is_sj_alph (*s) && is_sj_alph (*t))
989 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
996 else if (is_shift_jis (*s) && is_shift_jis (*t))
998 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
1001 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1008 else if (is_shift_jis (*s))
1010 else if (is_shift_jis (*t))
1014 diff = toupper (*s) - toupper (*t);
1025 #endif /* KANJI_WIN95_COMPATIBILITY */
1027 while (n && *s && *t && toupper(*s) == toupper(*t))
1034 /* not run out of chars - strings are different lengths */
1036 return(toupper(*s) - toupper(*t));
1038 /* identical up to where we run out of chars,
1039 and strings are same length */
1044 /*******************************************************************
1046 ********************************************************************/
1047 BOOL strequal(char *s1, char *s2)
1049 if (s1 == s2) return(True);
1050 if (!s1 || !s2) return(False);
1052 return(StrCaseCmp(s1,s2)==0);
1055 /*******************************************************************
1056 compare 2 strings up to and including the nth char.
1057 ******************************************************************/
1058 BOOL strnequal(char *s1,char *s2,int n)
1060 if (s1 == s2) return(True);
1061 if (!s1 || !s2 || !n) return(False);
1063 return(StrnCaseCmp(s1,s2,n)==0);
1066 /*******************************************************************
1067 compare 2 strings (case sensitive)
1068 ********************************************************************/
1069 BOOL strcsequal(char *s1,char *s2)
1071 if (s1 == s2) return(True);
1072 if (!s1 || !s2) return(False);
1074 return(strcmp(s1,s2)==0);
1078 /*******************************************************************
1079 convert a string to lower case
1080 ********************************************************************/
1081 void strlower(char *s)
1085 #if !defined(KANJI_WIN95_COMPATIBILITY)
1087 * For completeness we should put in equivalent code for code pages
1088 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1089 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1090 * here. They both treat full width ascii characters as case senstive
1091 * filenames (ie. they don't do the work we do here).
1095 if(lp_client_code_page() == KANJI_CODEPAGE)
1097 /* Win95 treats full width ascii characters as case sensitive. */
1098 if (is_shift_jis (*s))
1100 if (is_sj_upper (s[0], s[1]))
1101 s[1] = sj_tolower2 (s[1]);
1104 else if (is_kana (*s))
1116 #endif /* KANJI_WIN95_COMPATIBILITY */
1125 /*******************************************************************
1126 convert a string to upper case
1127 ********************************************************************/
1128 void strupper(char *s)
1132 #if !defined(KANJI_WIN95_COMPATIBILITY)
1134 * For completeness we should put in equivalent code for code pages
1135 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1136 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1137 * here. They both treat full width ascii characters as case senstive
1138 * filenames (ie. they don't do the work we do here).
1142 if(lp_client_code_page() == KANJI_CODEPAGE)
1144 /* Win95 treats full width ascii characters as case sensitive. */
1145 if (is_shift_jis (*s))
1147 if (is_sj_lower (s[0], s[1]))
1148 s[1] = sj_toupper2 (s[1]);
1151 else if (is_kana (*s))
1163 #endif /* KANJI_WIN95_COMPATIBILITY */
1172 /*******************************************************************
1173 convert a string to "normal" form
1174 ********************************************************************/
1175 void strnorm(char *s)
1177 if (case_default == CASE_UPPER)
1183 /*******************************************************************
1184 check if a string is in "normal" case
1185 ********************************************************************/
1186 BOOL strisnormal(char *s)
1188 if (case_default == CASE_UPPER)
1189 return(!strhaslower(s));
1191 return(!strhasupper(s));
1195 /****************************************************************************
1197 ****************************************************************************/
1198 void string_replace(char *s,char oldc,char newc)
1202 #if !defined(KANJI_WIN95_COMPATIBILITY)
1204 * For completeness we should put in equivalent code for code pages
1205 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1206 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1207 * here. They both treat full width ascii characters as case senstive
1208 * filenames (ie. they don't do the work we do here).
1212 if(lp_client_code_page() == KANJI_CODEPAGE)
1214 /* Win95 treats full width ascii characters as case sensitive. */
1215 if (is_shift_jis (*s))
1217 else if (is_kana (*s))
1227 #endif /* KANJI_WIN95_COMPATIBILITY */
1236 /****************************************************************************
1237 make a file into unix format
1238 ****************************************************************************/
1239 void unix_format(char *fname)
1242 string_replace(fname,'\\','/');
1246 pstrcpy(namecopy,fname);
1248 strcat(fname,namecopy);
1252 /****************************************************************************
1253 make a file into dos format
1254 ****************************************************************************/
1255 void dos_format(char *fname)
1257 string_replace(fname,'/','\\');
1260 /*******************************************************************
1261 show a smb message structure
1262 ********************************************************************/
1263 void show_msg(char *buf)
1268 if (DEBUGLEVEL < 5) return;
1270 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1272 (int)CVAL(buf,smb_com),
1273 (int)CVAL(buf,smb_rcls),
1274 (int)CVAL(buf,smb_reh),
1275 (int)SVAL(buf,smb_err),
1276 (int)CVAL(buf,smb_flg),
1277 (int)SVAL(buf,smb_flg2)));
1278 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1279 (int)SVAL(buf,smb_tid),
1280 (int)SVAL(buf,smb_pid),
1281 (int)SVAL(buf,smb_uid),
1282 (int)SVAL(buf,smb_mid),
1283 (int)CVAL(buf,smb_wct)));
1285 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1287 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1288 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1291 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1293 DEBUG(5,("smb_bcc=%d\n",bcc));
1295 if (DEBUGLEVEL < 10) return;
1297 if (DEBUGLEVEL < 50)
1299 bcc = MIN(bcc, 512);
1302 dump_data(10, smb_buf(buf), bcc);
1304 /*******************************************************************
1305 return the length of an smb packet
1306 ********************************************************************/
1307 int smb_len(char *buf)
1309 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1312 /*******************************************************************
1313 set the length of an smb packet
1314 ********************************************************************/
1315 void _smb_setlen(char *buf,int len)
1318 buf[1] = (len&0x10000)>>16;
1319 buf[2] = (len&0xFF00)>>8;
1323 /*******************************************************************
1324 set the length and marker of an smb packet
1325 ********************************************************************/
1326 void smb_setlen(char *buf,int len)
1328 _smb_setlen(buf,len);
1336 /*******************************************************************
1337 setup the word count and byte count for a smb message
1338 ********************************************************************/
1339 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1342 bzero(buf + smb_size,num_words*2 + num_bytes);
1343 CVAL(buf,smb_wct) = num_words;
1344 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1345 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1346 return (smb_size + num_words*2 + num_bytes);
1349 /*******************************************************************
1350 return the number of smb words
1351 ********************************************************************/
1352 int smb_numwords(char *buf)
1354 return (CVAL(buf,smb_wct));
1357 /*******************************************************************
1358 return the size of the smb_buf region of a message
1359 ********************************************************************/
1360 int smb_buflen(char *buf)
1362 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1365 /*******************************************************************
1366 return a pointer to the smb_buf data area
1367 ********************************************************************/
1368 int smb_buf_ofs(char *buf)
1370 return (smb_size + CVAL(buf,smb_wct)*2);
1373 /*******************************************************************
1374 return a pointer to the smb_buf data area
1375 ********************************************************************/
1376 char *smb_buf(char *buf)
1378 return (buf + smb_buf_ofs(buf));
1381 /*******************************************************************
1382 return the SMB offset into an SMB buffer
1383 ********************************************************************/
1384 int smb_offset(char *p,char *buf)
1386 return(PTR_DIFF(p,buf+4) + chain_size);
1390 /*******************************************************************
1391 skip past some strings in a buffer
1392 ********************************************************************/
1393 char *skip_string(char *buf,int n)
1396 buf += strlen(buf) + 1;
1400 /*******************************************************************
1401 trim the specified elements off the front and back of a string
1402 ********************************************************************/
1403 BOOL trim_string(char *s,char *front,char *back)
1406 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1412 if (!(*p = p[strlen(front)]))
1417 while (back && *back && strlen(s) >= strlen(back) &&
1418 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1421 s[strlen(s)-strlen(back)] = 0;
1427 /*******************************************************************
1428 reduce a file name, removing .. elements.
1429 ********************************************************************/
1430 void dos_clean_name(char *s)
1434 DEBUG(3,("dos_clean_name [%s]\n",s));
1436 /* remove any double slashes */
1437 string_sub(s, "\\\\", "\\");
1439 while ((p = strstr(s,"\\..\\")) != NULL)
1446 if ((p=strrchr(s,'\\')) != NULL)
1453 trim_string(s,NULL,"\\..");
1455 string_sub(s, "\\.\\", "\\");
1458 /*******************************************************************
1459 reduce a file name, removing .. elements.
1460 ********************************************************************/
1461 void unix_clean_name(char *s)
1465 DEBUG(3,("unix_clean_name [%s]\n",s));
1467 /* remove any double slashes */
1468 string_sub(s, "//","/");
1470 /* Remove leading ./ characters */
1471 if(strncmp(s, "./", 2) == 0) {
1472 trim_string(s, "./", NULL);
1477 while ((p = strstr(s,"/../")) != NULL)
1484 if ((p=strrchr(s,'/')) != NULL)
1491 trim_string(s,NULL,"/..");
1495 /*******************************************************************
1496 a wrapper for the normal chdir() function
1497 ********************************************************************/
1498 int ChDir(char *path)
1501 static pstring LastDir="";
1503 if (strcsequal(path,".")) return(0);
1505 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1506 DEBUG(3,("chdir to %s\n",path));
1507 res = sys_chdir(path);
1509 pstrcpy(LastDir,path);
1513 /* number of list structures for a caching GetWd function. */
1514 #define MAX_GETWDCACHE (50)
1522 } ino_list[MAX_GETWDCACHE];
1524 BOOL use_getwd_cache=True;
1526 /*******************************************************************
1527 return the absolute current directory path
1528 ********************************************************************/
1529 char *GetWd(char *str)
1532 static BOOL getwd_cache_init = False;
1533 struct stat st, st2;
1538 if (!use_getwd_cache)
1539 return(sys_getwd(str));
1541 /* init the cache */
1542 if (!getwd_cache_init)
1544 getwd_cache_init = True;
1545 for (i=0;i<MAX_GETWDCACHE;i++)
1547 string_init(&ino_list[i].text,"");
1548 ino_list[i].valid = False;
1552 /* Get the inode of the current directory, if this doesn't work we're
1555 if (stat(".",&st) == -1)
1557 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1558 return(sys_getwd(str));
1562 for (i=0; i<MAX_GETWDCACHE; i++)
1563 if (ino_list[i].valid)
1566 /* If we have found an entry with a matching inode and dev number
1567 then find the inode number for the directory in the cached string.
1568 If this agrees with that returned by the stat for the current
1569 directory then all is o.k. (but make sure it is a directory all
1572 if (st.st_ino == ino_list[i].inode &&
1573 st.st_dev == ino_list[i].dev)
1575 if (stat(ino_list[i].text,&st2) == 0)
1577 if (st.st_ino == st2.st_ino &&
1578 st.st_dev == st2.st_dev &&
1579 (st2.st_mode & S_IFMT) == S_IFDIR)
1581 strcpy (str, ino_list[i].text);
1583 /* promote it for future use */
1584 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1589 /* If the inode is different then something's changed,
1590 scrub the entry and start from scratch. */
1591 ino_list[i].valid = False;
1598 /* We don't have the information to hand so rely on traditional methods.
1599 The very slow getcwd, which spawns a process on some systems, or the
1600 not quite so bad getwd. */
1604 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1610 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1612 /* add it to the cache */
1613 i = MAX_GETWDCACHE - 1;
1614 string_set(&ino_list[i].text,s);
1615 ino_list[i].dev = st.st_dev;
1616 ino_list[i].inode = st.st_ino;
1617 ino_list[i].valid = True;
1619 /* put it at the top of the list */
1620 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1627 /*******************************************************************
1628 reduce a file name, removing .. elements and checking that
1629 it is below dir in the heirachy. This uses GetWd() and so must be run
1630 on the system that has the referenced file system.
1632 widelinks are allowed if widelinks is true
1633 ********************************************************************/
1634 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1636 #ifndef REDUCE_PATHS
1644 BOOL relative = (*s != '/');
1646 *dir2 = *wd = *base_name = *newname = 0;
1651 /* can't have a leading .. */
1652 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1654 DEBUG(3,("Illegal file name? (%s)\n",s));
1664 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1666 /* remove any double slashes */
1667 string_sub(s,"//","/");
1669 pstrcpy(base_name,s);
1670 p = strrchr(base_name,'/');
1677 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1681 if (ChDir(dir) != 0)
1683 DEBUG(0,("couldn't chdir to %s\n",dir));
1689 DEBUG(0,("couldn't getwd for %s\n",dir));
1695 if (p && (p != base_name))
1698 if (strcmp(p+1,".")==0)
1700 if (strcmp(p+1,"..")==0)
1704 if (ChDir(base_name) != 0)
1707 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1711 if (!GetWd(newname))
1714 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1718 if (p && (p != base_name))
1720 strcat(newname,"/");
1721 strcat(newname,p+1);
1725 int l = strlen(dir2);
1726 if (dir2[l-1] == '/')
1729 if (strncmp(newname,dir2,l) != 0)
1732 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1738 if (newname[l] == '/')
1739 pstrcpy(s,newname + l + 1);
1741 pstrcpy(s,newname+l);
1752 DEBUG(3,("reduced to %s\n",s));
1757 /****************************************************************************
1759 ****************************************************************************/
1760 static void expand_one(char *Mask,int len)
1763 while ((p1 = strchr(Mask,'*')) != NULL)
1765 int lfill = (len+1) - strlen(Mask);
1766 int l1= (p1 - Mask);
1769 memset(tmp+l1,'?',lfill);
1770 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1775 /****************************************************************************
1776 expand a wildcard expression, replacing *s with ?s
1777 ****************************************************************************/
1778 void expand_mask(char *Mask,BOOL doext)
1783 BOOL hasdot = False;
1785 BOOL absolute = (*Mask == '\\');
1787 *mbeg = *mext = *dirpart = *filepart = 0;
1789 /* parse the directory and filename */
1790 if (strchr(Mask,'\\'))
1791 dirname_dos(Mask,dirpart);
1793 filename_dos(Mask,filepart);
1795 pstrcpy(mbeg,filepart);
1796 if ((p1 = strchr(mbeg,'.')) != NULL)
1806 if (strlen(mbeg) > 8)
1808 pstrcpy(mext,mbeg + 8);
1814 strcpy(mbeg,"????????");
1815 if ((*mext == 0) && doext && !hasdot)
1818 if (strequal(mbeg,"*") && *mext==0)
1826 pstrcpy(Mask,dirpart);
1827 if (*dirpart || absolute) strcat(Mask,"\\");
1832 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1836 /****************************************************************************
1837 does a string have any uppercase chars in it?
1838 ****************************************************************************/
1839 BOOL strhasupper(char *s)
1843 #if !defined(KANJI_WIN95_COMPATIBILITY)
1845 * For completeness we should put in equivalent code for code pages
1846 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1847 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1848 * here. They both treat full width ascii characters as case senstive
1849 * filenames (ie. they don't do the work we do here).
1853 if(lp_client_code_page() == KANJI_CODEPAGE)
1855 /* Win95 treats full width ascii characters as case sensitive. */
1856 if (is_shift_jis (*s))
1858 else if (is_kana (*s))
1868 #endif /* KANJI_WIN95_COMPATIBILITY */
1878 /****************************************************************************
1879 does a string have any lowercase chars in it?
1880 ****************************************************************************/
1881 BOOL strhaslower(char *s)
1885 #if !defined(KANJI_WIN95_COMPATIBILITY)
1887 * For completeness we should put in equivalent code for code pages
1888 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1889 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1890 * here. They both treat full width ascii characters as case senstive
1891 * filenames (ie. they don't do the work we do here).
1895 if(lp_client_code_page() == KANJI_CODEPAGE)
1897 /* Win95 treats full width ascii characters as case sensitive. */
1898 if (is_shift_jis (*s))
1900 if (is_sj_upper (s[0], s[1]))
1902 if (is_sj_lower (s[0], s[1]))
1906 else if (is_kana (*s))
1918 #endif /* KANJI_WIN95_COMPATIBILITY */
1928 /****************************************************************************
1929 find the number of chars in a string
1930 ****************************************************************************/
1931 int count_chars(char *s,char c)
1935 #if !defined(KANJI_WIN95_COMPATIBILITY)
1937 * For completeness we should put in equivalent code for code pages
1938 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1939 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1940 * here. They both treat full width ascii characters as case senstive
1941 * filenames (ie. they don't do the work we do here).
1945 if(lp_client_code_page() == KANJI_CODEPAGE)
1947 /* Win95 treats full width ascii characters as case sensitive. */
1950 if (is_shift_jis (*s))
1961 #endif /* KANJI_WIN95_COMPATIBILITY */
1974 /****************************************************************************
1976 ****************************************************************************/
1977 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1982 pstrcpy(mask2,mask);
1984 if ((mode & aDIR) != 0)
1987 memset(buf+1,' ',11);
1988 if ((p = strchr(mask2,'.')) != NULL)
1991 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1992 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1996 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1998 bzero(buf+21,DIR_STRUCT_SIZE-21);
1999 CVAL(buf,21) = mode;
2000 put_dos_date(buf,22,date);
2001 SSVAL(buf,26,size & 0xFFFF);
2002 SSVAL(buf,28,size >> 16);
2003 StrnCpy(buf+30,fname,12);
2004 if (!case_sensitive)
2006 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2010 /*******************************************************************
2011 close the low 3 fd's and open dev/null in their place
2012 ********************************************************************/
2013 void close_low_fds(void)
2017 close(0); close(1); close(2);
2018 /* try and use up these file descriptors, so silly
2019 library routines writing to stdout etc won't cause havoc */
2021 fd = open("/dev/null",O_RDWR,0);
2022 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2024 DEBUG(0,("Can't open /dev/null\n"));
2028 DEBUG(0,("Didn't get file descriptor %d\n",i));
2034 /****************************************************************************
2035 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2037 if SYSV use O_NDELAY
2039 ****************************************************************************/
2040 int set_blocking(int fd, BOOL set)
2044 #define FLAG_TO_SET O_NONBLOCK
2047 #define FLAG_TO_SET O_NDELAY
2049 #define FLAG_TO_SET FNDELAY
2053 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2055 if(set) /* Turn blocking on - ie. clear nonblock flag */
2056 val &= ~FLAG_TO_SET;
2059 return fcntl( fd, F_SETFL, val);
2064 /****************************************************************************
2066 ****************************************************************************/
2067 int write_socket(int fd,char *buf,int len)
2073 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2074 ret = write_data(fd,buf,len);
2076 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2078 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2079 len, fd, strerror(errno) ));
2084 /****************************************************************************
2086 ****************************************************************************/
2087 int read_udp_socket(int fd,char *buf,int len)
2090 struct sockaddr_in sock;
2093 socklen = sizeof(sock);
2094 bzero((char *)&sock,socklen);
2095 bzero((char *)&lastip,sizeof(lastip));
2096 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2098 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2102 lastip = sock.sin_addr;
2103 lastport = ntohs(sock.sin_port);
2105 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2106 inet_ntoa(lastip), lastport, ret));
2111 /****************************************************************************
2112 read data from a device with a timout in msec.
2113 mincount = if timeout, minimum to read before returning
2114 maxcount = number to be read.
2115 ****************************************************************************/
2116 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2122 struct timeval timeout;
2124 /* just checking .... */
2125 if (maxcnt <= 0) return(0);
2130 if (time_out <= 0) {
2131 if (mincnt == 0) mincnt = maxcnt;
2133 while (nread < mincnt) {
2134 readret = read(fd, buf + nread, maxcnt - nread);
2136 smb_read_error = READ_EOF;
2140 if (readret == -1) {
2141 smb_read_error = READ_ERROR;
2149 /* Most difficult - timeout read */
2150 /* If this is ever called on a disk file and
2151 mincnt is greater then the filesize then
2152 system performance will suffer severely as
2153 select always return true on disk files */
2155 /* Set initial timeout */
2156 timeout.tv_sec = time_out / 1000;
2157 timeout.tv_usec = 1000 * (time_out % 1000);
2159 for (nread=0; nread<mincnt; )
2164 selrtn = sys_select(&fds,&timeout);
2166 /* Check if error */
2168 /* something is wrong. Maybe the socket is dead? */
2169 smb_read_error = READ_ERROR;
2173 /* Did we timeout ? */
2175 smb_read_error = READ_TIMEOUT;
2179 readret = read(fd, buf+nread, maxcnt-nread);
2181 /* we got EOF on the file descriptor */
2182 smb_read_error = READ_EOF;
2186 if (readret == -1) {
2187 /* the descriptor is probably dead */
2188 smb_read_error = READ_ERROR;
2195 /* Return the number we got */
2199 /****************************************************************************
2200 read data from the client. Maxtime is in milliseconds
2201 ****************************************************************************/
2202 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2207 struct timeval timeout;
2212 timeout.tv_sec = maxtime / 1000;
2213 timeout.tv_usec = (maxtime % 1000) * 1000;
2215 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2217 if (!FD_ISSET(fd,&fds))
2220 nread = read_udp_socket(fd, buffer, bufsize);
2222 /* return the number got */
2226 /*******************************************************************
2227 find the difference in milliseconds between two struct timeval
2229 ********************************************************************/
2230 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2232 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2233 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2236 /****************************************************************************
2237 send a keepalive packet (rfc1002)
2238 ****************************************************************************/
2239 BOOL send_keepalive(int client)
2241 unsigned char buf[4];
2244 buf[1] = buf[2] = buf[3] = 0;
2246 return(write_data(client,(char *)buf,4) == 4);
2251 /****************************************************************************
2252 read data from the client, reading exactly N bytes.
2253 ****************************************************************************/
2254 int read_data(int fd,char *buffer,int N)
2263 ret = read(fd,buffer + total,N - total);
2265 smb_read_error = READ_EOF;
2269 smb_read_error = READ_ERROR;
2278 /****************************************************************************
2280 ****************************************************************************/
2281 int write_data(int fd,char *buffer,int N)
2288 ret = write(fd,buffer + total,N - total);
2290 if (ret == -1) return -1;
2291 if (ret == 0) return total;
2299 /****************************************************************************
2300 transfer some data between two fd's
2301 ****************************************************************************/
2302 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2304 static char *buf=NULL;
2309 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2312 size = lp_readsize();
2313 size = MAX(size,1024);
2316 while (!buf && size>0) {
2317 buf = (char *)Realloc(buf,size+8);
2318 if (!buf) size /= 2;
2322 DEBUG(0,("Can't allocate transfer buffer!\n"));
2326 abuf = buf + (align%8);
2333 int s = MIN(n,size);
2338 if (header && (headlen >= MIN(s,1024))) {
2348 if (header && headlen > 0)
2350 ret = MIN(headlen,size);
2351 memcpy(buf1,header,ret);
2354 if (headlen <= 0) header = NULL;
2358 ret += read(infd,buf1+ret,s-ret);
2362 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2363 if (ret2 > 0) total += ret2;
2364 /* if we can't write then dump excess data */
2366 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2368 if (ret <= 0 || ret2 != ret)
2376 /****************************************************************************
2377 read 4 bytes of a smb packet and return the smb length of the packet
2378 store the result in the buffer
2379 This version of the function will return a length of zero on receiving
2381 ****************************************************************************/
2382 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2384 int len=0, msg_type;
2390 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2392 ok = (read_data(fd,inbuf,4) == 4);
2397 len = smb_len(inbuf);
2398 msg_type = CVAL(inbuf,0);
2400 if (msg_type == 0x85)
2401 DEBUG(5,("Got keepalive packet\n"));
2404 DEBUG(10,("got smb length of %d\n",len));
2409 /****************************************************************************
2410 read 4 bytes of a smb packet and return the smb length of the packet
2411 store the result in the buffer. This version of the function will
2412 never return a session keepalive (length of zero).
2413 ****************************************************************************/
2414 int read_smb_length(int fd,char *inbuf,int timeout)
2420 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2425 /* Ignore session keepalives. */
2426 if(CVAL(inbuf,0) != 0x85)
2433 /****************************************************************************
2434 read an smb from a fd. Note that the buffer *MUST* be of size
2435 BUFFER_SIZE+SAFETY_MARGIN.
2436 The timeout is in milli seconds.
2438 This function will return on a
2439 receipt of a session keepalive packet.
2440 ****************************************************************************/
2441 BOOL receive_smb(int fd,char *buffer, int timeout)
2447 bzero(buffer,smb_size + 100);
2449 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2453 if (len > BUFFER_SIZE) {
2454 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2455 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2460 ret = read_data(fd,buffer+4,len);
2462 smb_read_error = READ_ERROR;
2469 /****************************************************************************
2470 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2471 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2472 The timeout is in milli seconds
2474 This is exactly the same as receive_smb except that it never returns
2475 a session keepalive packet (just as receive_smb used to do).
2476 receive_smb was changed to return keepalives as the oplock processing means this call
2477 should never go into a blocking read.
2478 ****************************************************************************/
2480 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2486 ret = receive_smb(fd, buffer, timeout);
2491 /* Ignore session keepalive packets. */
2492 if(CVAL(buffer,0) != 0x85)
2498 /****************************************************************************
2499 read a message from a udp fd.
2500 The timeout is in milli seconds
2501 ****************************************************************************/
2502 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2504 struct sockaddr_in from;
2505 int fromlen = sizeof(from);
2519 to.tv_sec = timeout / 1000;
2520 to.tv_usec = (timeout % 1000) * 1000;
2522 selrtn = sys_select(&fds,&to);
2524 /* Check if error */
2527 /* something is wrong. Maybe the socket is dead? */
2528 smb_read_error = READ_ERROR;
2532 /* Did we timeout ? */
2535 smb_read_error = READ_TIMEOUT;
2541 * Read a loopback udp message.
2543 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2544 buffer_len - UDP_CMD_HEADER_LEN, 0,
2545 (struct sockaddr *)&from, &fromlen);
2549 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2553 /* Validate message length. */
2554 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2556 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2558 buffer_len - UDP_CMD_HEADER_LEN));
2562 /* Validate message from address (must be localhost). */
2563 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2565 DEBUG(0,("receive_local_message: invalid 'from' address \
2566 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2570 /* Setup the message header */
2571 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2572 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2577 /****************************************************************************
2578 structure to hold a linked list of local messages.
2580 ****************************************************************************/
2582 typedef struct _message_list {
2583 struct _message_list *msg_next;
2586 } pending_message_list;
2588 static pending_message_list *smb_msg_head = NULL;
2590 /****************************************************************************
2591 Function to push a linked list of local messages ready
2593 ****************************************************************************/
2595 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2597 pending_message_list *msg = (pending_message_list *)
2598 malloc(sizeof(pending_message_list));
2602 DEBUG(0,("push_message: malloc fail (1)\n"));
2606 msg->msg_buf = (char *)malloc(msg_len);
2607 if(msg->msg_buf == NULL)
2609 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2614 memcpy(msg->msg_buf, buf, msg_len);
2615 msg->msg_len = msg_len;
2617 msg->msg_next = *pml;
2623 /****************************************************************************
2624 Function to push a linked list of local smb messages ready
2626 ****************************************************************************/
2628 BOOL push_smb_message(char *buf, int msg_len)
2630 return push_local_message(&smb_msg_head, buf, msg_len);
2633 /****************************************************************************
2634 Do a select on an two fd's - with timeout.
2636 If a local udp message has been pushed onto the
2637 queue (this can only happen during oplock break
2638 processing) return this first.
2640 If a pending smb message has been pushed onto the
2641 queue (this can only happen during oplock break
2642 processing) return this next.
2644 If the first smbfd is ready then read an smb from it.
2645 if the second (loopback UDP) fd is ready then read a message
2646 from it and setup the buffer header to identify the length
2648 Returns False on timeout or error.
2651 The timeout is in milli seconds
2652 ****************************************************************************/
2653 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2654 char *buffer, int buffer_len,
2655 int timeout, BOOL *got_smb)
2666 * Check to see if we already have a message on the smb queue.
2667 * If so - copy and return it.
2672 pending_message_list *msg = smb_msg_head;
2673 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2674 smb_msg_head = msg->msg_next;
2676 /* Free the message we just copied. */
2677 free((char *)msg->msg_buf);
2681 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2687 FD_SET(oplock_fd,&fds);
2689 to.tv_sec = timeout / 1000;
2690 to.tv_usec = (timeout % 1000) * 1000;
2692 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2694 /* Check if error */
2696 /* something is wrong. Maybe the socket is dead? */
2697 smb_read_error = READ_ERROR;
2701 /* Did we timeout ? */
2703 smb_read_error = READ_TIMEOUT;
2707 if (FD_ISSET(smbfd,&fds))
2710 return receive_smb(smbfd, buffer, 0);
2714 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2718 /****************************************************************************
2720 ****************************************************************************/
2721 BOOL send_smb(int fd,char *buffer)
2725 len = smb_len(buffer) + 4;
2727 while (nwritten < len)
2729 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2732 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2744 /****************************************************************************
2745 find a pointer to a netbios name
2746 ****************************************************************************/
2747 char *name_ptr(char *buf,int ofs)
2749 unsigned char c = *(unsigned char *)(buf+ofs);
2751 if ((c & 0xC0) == 0xC0)
2755 memcpy(p,buf+ofs,2);
2758 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2765 /****************************************************************************
2766 extract a netbios name from a buf
2767 ****************************************************************************/
2768 int name_extract(char *buf,int ofs,char *name)
2770 char *p = name_ptr(buf,ofs);
2771 int d = PTR_DIFF(p,buf+ofs);
2773 if (d < -50 || d > 50) return(0);
2774 return(name_interpret(p,name));
2777 /****************************************************************************
2778 return the total storage length of a mangled name
2779 ****************************************************************************/
2780 int name_len( char *s )
2784 /* If the two high bits of the byte are set, return 2. */
2785 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2788 /* Add up the length bytes. */
2789 for( len = 1; (*s); s += (*s) + 1 )
2797 /****************************************************************************
2798 send a single packet to a port on another machine
2799 ****************************************************************************/
2800 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2804 struct sockaddr_in sock_out;
2809 /* create a socket to write to */
2810 out_fd = socket(AF_INET, type, 0);
2813 DEBUG(0,("socket failed"));
2817 /* set the address and port */
2818 bzero((char *)&sock_out,sizeof(sock_out));
2819 putip((char *)&sock_out.sin_addr,(char *)&ip);
2820 sock_out.sin_port = htons( port );
2821 sock_out.sin_family = AF_INET;
2824 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2825 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2828 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2831 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2832 inet_ntoa(ip),port,strerror(errno)));
2838 /*******************************************************************
2839 sleep for a specified number of milliseconds
2840 ********************************************************************/
2844 struct timeval tval,t1,t2;
2851 tval.tv_sec = (t-tdiff)/1000;
2852 tval.tv_usec = 1000*((t-tdiff)%1000);
2856 sys_select(&fds,&tval);
2859 tdiff = TvalDiff(&t1,&t2);
2863 /****************************************************************************
2864 check if a string is part of a list
2865 ****************************************************************************/
2866 BOOL in_list(char *s,char *list,BOOL casesensitive)
2871 if (!list) return(False);
2873 while (next_token(&p,tok,LIST_SEP))
2875 if (casesensitive) {
2876 if (strcmp(tok,s) == 0)
2879 if (StrCaseCmp(tok,s) == 0)
2886 /* this is used to prevent lots of mallocs of size 1 */
2887 static char *null_string = NULL;
2889 /****************************************************************************
2890 set a string value, allocing the space for the string
2891 ****************************************************************************/
2892 BOOL string_init(char **dest,char *src)
2903 null_string = (char *)malloc(1);
2906 *dest = null_string;
2910 (*dest) = (char *)malloc(l+1);
2911 if ((*dest) == NULL) {
2912 DEBUG(0,("Out of memory in string_init\n"));
2921 /****************************************************************************
2923 ****************************************************************************/
2924 void string_free(char **s)
2926 if (!s || !(*s)) return;
2927 if (*s == null_string)
2933 /****************************************************************************
2934 set a string value, allocing the space for the string, and deallocating any
2936 ****************************************************************************/
2937 BOOL string_set(char **dest,char *src)
2941 return(string_init(dest,src));
2944 /****************************************************************************
2945 substitute a string for a pattern in another string. Make sure there is
2948 This routine looks for pattern in s and replaces it with
2949 insert. It may do multiple replacements.
2951 return True if a substitution was done.
2952 ****************************************************************************/
2953 BOOL string_sub(char *s,char *pattern,char *insert)
2959 if (!insert || !pattern || !s) return(False);
2962 lp = strlen(pattern);
2963 li = strlen(insert);
2965 if (!*pattern) return(False);
2967 while (lp <= ls && (p = strstr(s,pattern)))
2970 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2971 memcpy(p,insert,li);
2980 /*********************************************************
2981 * Recursive routine that is called by mask_match.
2982 * Does the actual matching.
2983 *********************************************************/
2984 BOOL do_match(char *str, char *regexp, int case_sig)
2988 for( p = regexp; *p && *str; ) {
2995 /* Look for a character matching
2996 the one after the '*' */
2999 return True; /* Automatic match */
3001 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
3003 if(do_match(str,p,case_sig))
3017 if(toupper(*str) != toupper(*p))
3027 if (!*p && str[0] == '.' && str[1] == 0)
3030 if (!*str && *p == '?')
3032 while (*p == '?') p++;
3036 if(!*str && (*p == '*' && p[1] == '\0'))
3042 /*********************************************************
3043 * Routine to match a given string with a regexp - uses
3044 * simplified regexp that takes * and ? only. Case can be
3045 * significant or not.
3046 *********************************************************/
3047 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3051 fstring ebase,eext,sbase,sext;
3055 /* Make local copies of str and regexp */
3056 StrnCpy(p1,regexp,sizeof(pstring)-1);
3057 StrnCpy(p2,str,sizeof(pstring)-1);
3059 if (!strchr(p2,'.')) {
3064 if (!strchr(p1,'.')) {
3072 string_sub(p1,"*.*","*");
3073 string_sub(p1,".*","*");
3077 /* Remove any *? and ** as they are meaningless */
3078 for(p = p1; *p; p++)
3079 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3080 (void)strcpy( &p[1], &p[2]);
3082 if (strequal(p1,"*")) return(True);
3084 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3090 if ((p=strrchr(p1,'.'))) {
3099 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3109 matched = do_match(sbase,ebase,case_sig) &&
3110 (trans2 || do_match(sext,eext,case_sig));
3112 DEBUG(8,("mask_match returning %d\n", matched));
3119 /****************************************************************************
3120 become a daemon, discarding the controlling terminal
3121 ****************************************************************************/
3122 void become_daemon(void)
3124 #ifndef NO_FORK_DEBUG
3128 /* detach from the terminal */
3131 #else /* USE_SETSID */
3134 int i = open("/dev/tty", O_RDWR);
3137 ioctl(i, (int) TIOCNOTTY, (char *)0);
3141 #endif /* TIOCNOTTY */
3142 #endif /* USE_SETSID */
3143 /* Close fd's 0,1,2. Needed if started by rsh */
3145 #endif /* NO_FORK_DEBUG */
3149 /****************************************************************************
3150 put up a yes/no prompt
3151 ****************************************************************************/
3157 if (!fgets(ans,sizeof(ans)-1,stdin))
3160 if (*ans == 'y' || *ans == 'Y')
3166 /****************************************************************************
3167 read a line from a file with possible \ continuation chars.
3168 Blanks at the start or end of a line are stripped.
3169 The string will be allocated if s2 is NULL
3170 ****************************************************************************/
3171 char *fgets_slash(char *s2,int maxlen,FILE *f)
3176 BOOL start_of_line = True;
3183 maxlen = MIN(maxlen,8);
3184 s = (char *)Realloc(s,maxlen);
3187 if (!s || maxlen < 2) return(NULL);
3191 while (len < maxlen-1)
3199 while (len > 0 && s[len-1] == ' ')
3203 if (len > 0 && s[len-1] == '\\')
3206 start_of_line = True;
3211 if (len <= 0 && !s2)
3213 return(len>0?s:NULL);
3218 start_of_line = False;
3222 if (!s2 && len > maxlen-3)
3225 s = (char *)Realloc(s,maxlen);
3226 if (!s) return(NULL);
3234 /****************************************************************************
3235 set the length of a file from a filedescriptor.
3236 Returns 0 on success, -1 on failure.
3237 ****************************************************************************/
3238 int set_filelen(int fd, long len)
3240 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3241 extend a file with ftruncate. Provide alternate implementation
3244 #if FTRUNCATE_CAN_EXTEND
3245 return ftruncate(fd, len);
3249 long currpos = lseek(fd, 0L, SEEK_CUR);
3253 /* Do an fstat to see if the file is longer than
3254 the requested size (call ftruncate),
3255 or shorter, in which case seek to len - 1 and write 1
3257 if(fstat(fd, &st)<0)
3261 if (S_ISFIFO(st.st_mode)) return 0;
3264 if(st.st_size == len)
3266 if(st.st_size > len)
3267 return ftruncate(fd, len);
3269 if(lseek(fd, len-1, SEEK_SET) != len -1)
3271 if(write(fd, &c, 1)!=1)
3273 /* Seek to where we were */
3274 lseek(fd, currpos, SEEK_SET);
3280 /****************************************************************************
3281 return the byte checksum of some data
3282 ****************************************************************************/
3283 int byte_checksum(char *buf,int len)
3285 unsigned char *p = (unsigned char *)buf;
3295 /****************************************************************************
3296 this is a version of setbuffer() for those machines that only have setvbuf
3297 ****************************************************************************/
3298 void setbuffer(FILE *f,char *buf,int bufsize)
3300 setvbuf(f,buf,_IOFBF,bufsize);
3305 /****************************************************************************
3306 parse out a directory name from a path name. Assumes dos style filenames.
3307 ****************************************************************************/
3308 char *dirname_dos(char *path,char *buf)
3310 char *p = strrchr(path,'\\');
3325 /****************************************************************************
3326 parse out a filename from a path name. Assumes dos style filenames.
3327 ****************************************************************************/
3328 static char *filename_dos(char *path,char *buf)
3330 char *p = strrchr(path,'\\');
3342 /****************************************************************************
3343 expand a pointer to be a particular size
3344 ****************************************************************************/
3345 void *Realloc(void *p,int size)
3351 DEBUG(5,("Realloc asked for 0 bytes\n"));
3356 ret = (void *)malloc(size);
3358 ret = (void *)realloc(p,size);
3361 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3367 /****************************************************************************
3369 ****************************************************************************/
3370 char *strdup(char *s)
3373 if (!s) return(NULL);
3374 ret = (char *)malloc(strlen(s)+1);
3375 if (!ret) return(NULL);
3382 /****************************************************************************
3383 Signal handler for SIGPIPE (write on a disconnected socket)
3384 ****************************************************************************/
3387 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3391 /****************************************************************************
3392 get my own name and IP
3393 ****************************************************************************/
3394 BOOL get_myname(char *my_name,struct in_addr *ip)
3401 /* get my host name */
3402 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3404 DEBUG(0,("gethostname failed\n"));
3409 if ((hp = Get_Hostbyname(hostname)) == 0)
3411 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3417 /* split off any parts after an initial . */
3418 char *p = strchr(hostname,'.');
3421 fstrcpy(my_name,hostname);
3425 putip((char *)ip,(char *)hp->h_addr);
3431 /****************************************************************************
3432 true if two IP addresses are equal
3433 ****************************************************************************/
3434 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3437 a1 = ntohl(ip1.s_addr);
3438 a2 = ntohl(ip2.s_addr);
3443 /****************************************************************************
3444 open a socket of the specified type, port and address for incoming data
3445 ****************************************************************************/
3446 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3449 struct sockaddr_in sock;
3453 /* get my host name */
3454 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3455 { DEBUG(0,("gethostname failed\n")); return -1; }
3458 if ((hp = Get_Hostbyname(host_name)) == 0)
3460 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3464 bzero((char *)&sock,sizeof(sock));
3465 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3466 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3467 sock.sin_len = sizeof(sock);
3469 sock.sin_port = htons( port );
3470 sock.sin_family = hp->h_addrtype;
3471 sock.sin_addr.s_addr = socket_addr;
3472 res = socket(hp->h_addrtype, type, 0);
3474 { DEBUG(0,("socket failed\n")); return -1; }
3478 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3481 /* now we've got a socket - we need to bind it */
3482 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3485 if (port == SMB_PORT || port == NMB_PORT)
3486 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3487 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3490 if (dlevel > 0 && port < 1000)
3493 if (port >= 1000 && port < 9000)
3494 return(open_socket_in(type,port+1,dlevel,socket_addr));
3499 DEBUG(3,("bind succeeded on port %d\n",port));
3505 /****************************************************************************
3506 create an outgoing socket
3507 **************************************************************************/
3508 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3510 struct sockaddr_in sock_out;
3512 int connect_loop = 250; /* 250 milliseconds */
3513 int loops = (timeout * 1000) / connect_loop;
3515 /* create a socket to write to */
3516 res = socket(PF_INET, type, 0);
3518 { DEBUG(0,("socket error\n")); return -1; }
3520 if (type != SOCK_STREAM) return(res);
3522 bzero((char *)&sock_out,sizeof(sock_out));
3523 putip((char *)&sock_out.sin_addr,(char *)addr);
3525 sock_out.sin_port = htons( port );
3526 sock_out.sin_family = PF_INET;
3528 /* set it non-blocking */
3529 set_blocking(res,False);
3531 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3533 /* and connect it to the destination */
3535 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3537 /* Some systems return EAGAIN when they mean EINPROGRESS */
3538 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3539 errno == EAGAIN) && loops--) {
3540 msleep(connect_loop);
3544 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3546 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3552 if (ret < 0 && errno == EISCONN) {
3559 DEBUG(1,("error connecting to %s:%d (%s)\n",
3560 inet_ntoa(*addr),port,strerror(errno)));
3564 /* set it blocking again */
3565 set_blocking(res,True);
3571 /****************************************************************************
3572 interpret a protocol description string, with a default
3573 ****************************************************************************/
3574 int interpret_protocol(char *str,int def)
3576 if (strequal(str,"NT1"))
3577 return(PROTOCOL_NT1);
3578 if (strequal(str,"LANMAN2"))
3579 return(PROTOCOL_LANMAN2);
3580 if (strequal(str,"LANMAN1"))
3581 return(PROTOCOL_LANMAN1);
3582 if (strequal(str,"CORE"))
3583 return(PROTOCOL_CORE);
3584 if (strequal(str,"COREPLUS"))
3585 return(PROTOCOL_COREPLUS);
3586 if (strequal(str,"CORE+"))
3587 return(PROTOCOL_COREPLUS);
3589 DEBUG(0,("Unrecognised protocol level %s\n",str));
3594 /****************************************************************************
3595 interpret a security level
3596 ****************************************************************************/
3597 int interpret_security(char *str,int def)
3599 if (strequal(str,"SERVER"))
3601 if (strequal(str,"USER"))
3603 if (strequal(str,"SHARE"))
3606 DEBUG(0,("Unrecognised security level %s\n",str));
3612 /****************************************************************************
3613 interpret an internet address or name into an IP address in 4 byte form
3614 ****************************************************************************/
3615 uint32 interpret_addr(char *str)
3620 BOOL pure_address = True;
3622 if (strcmp(str,"0.0.0.0") == 0) return(0);
3623 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3625 for (i=0; pure_address && str[i]; i++)
3626 if (!(isdigit(str[i]) || str[i] == '.'))
3627 pure_address = False;
3629 /* if it's in the form of an IP address then get the lib to interpret it */
3631 res = inet_addr(str);
3633 /* otherwise assume it's a network name of some sort and use
3635 if ((hp = Get_Hostbyname(str)) == 0) {
3636 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3639 if(hp->h_addr == NULL) {
3640 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3643 putip((char *)&res,(char *)hp->h_addr);
3646 if (res == (uint32)-1) return(0);
3651 /*******************************************************************
3652 a convenient addition to interpret_addr()
3653 ******************************************************************/
3654 struct in_addr *interpret_addr2(char *str)
3656 static struct in_addr ret;
3657 uint32 a = interpret_addr(str);
3662 /*******************************************************************
3663 check if an IP is the 0.0.0.0
3664 ******************************************************************/
3665 BOOL zero_ip(struct in_addr ip)
3668 putip((char *)&a,(char *)&ip);
3673 /*******************************************************************
3674 matchname - determine if host name matches IP address
3675 ******************************************************************/
3676 static BOOL matchname(char *remotehost,struct in_addr addr)
3681 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3682 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3687 * Make sure that gethostbyname() returns the "correct" host name.
3688 * Unfortunately, gethostbyname("localhost") sometimes yields
3689 * "localhost.domain". Since the latter host name comes from the
3690 * local DNS, we just have to trust it (all bets are off if the local
3691 * DNS is perverted). We always check the address list, though.
3694 if (strcasecmp(remotehost, hp->h_name)
3695 && strcasecmp(remotehost, "localhost")) {
3696 DEBUG(0,("host name/name mismatch: %s != %s",
3697 remotehost, hp->h_name));
3701 /* Look up the host address in the address list we just got. */
3702 for (i = 0; hp->h_addr_list[i]; i++) {
3703 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3708 * The host name does not map to the original host address. Perhaps
3709 * someone has compromised a name server. More likely someone botched
3710 * it, but that could be dangerous, too.
3713 DEBUG(0,("host name/address mismatch: %s != %s",
3714 inet_ntoa(addr), hp->h_name));
3718 /*******************************************************************
3719 Reset the 'done' variables so after a client process is created
3720 from a fork call these calls will be re-done. This should be
3721 expanded if more variables need reseting.
3722 ******************************************************************/
3724 static BOOL global_client_name_done = False;
3725 static BOOL global_client_addr_done = False;
3727 void reset_globals_after_fork(void)
3729 global_client_name_done = False;
3730 global_client_addr_done = False;
3733 /*******************************************************************
3734 return the DNS name of the client
3735 ******************************************************************/
3736 char *client_name(int fd)
3739 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3740 int length = sizeof(sa);
3741 static pstring name_buf;
3743 static int last_fd=-1;
3745 if (global_client_name_done && last_fd == fd)
3749 global_client_name_done = False;
3751 strcpy(name_buf,"UNKNOWN");
3757 if (getpeername(fd, &sa, &length) < 0) {
3758 DEBUG(0,("getpeername failed\n"));
3762 /* Look up the remote host name. */
3763 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3764 sizeof(sockin->sin_addr),
3766 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3767 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3769 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3770 if (!matchname(name_buf, sockin->sin_addr)) {
3771 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3772 strcpy(name_buf,"UNKNOWN");
3775 global_client_name_done = True;
3779 /*******************************************************************
3780 return the IP addr of the client as a string
3781 ******************************************************************/
3782 char *client_addr(int fd)
3785 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3786 int length = sizeof(sa);
3787 static fstring addr_buf;
3788 static int last_fd = -1;
3790 if (global_client_addr_done && fd == last_fd)
3794 global_client_addr_done = False;
3796 strcpy(addr_buf,"0.0.0.0");
3802 if (getpeername(fd, &sa, &length) < 0) {
3803 DEBUG(0,("getpeername failed\n"));
3807 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3809 global_client_addr_done = True;
3813 /*******************************************************************
3814 Patch from jkf@soton.ac.uk
3815 Split Luke's automount_server into YP lookup and string splitter
3816 so can easily implement automount_path().
3817 As we may end up doing both, cache the last YP result.
3818 *******************************************************************/
3820 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3822 static char *automount_lookup(char *user_name)
3824 static fstring last_key = "";
3825 static pstring last_value = "";
3827 char *nis_map = (char *)lp_nis_home_map_name();
3829 char nis_domain[NIS_MAXNAMELEN + 1];
3830 char buffer[NIS_MAXATTRVAL + 1];
3835 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3836 nis_domain[NIS_MAXNAMELEN] = '\0';
3838 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3840 if (strcmp(user_name, last_key))
3842 sprintf(buffer, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3843 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3845 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3847 if (result->status != NIS_SUCCESS)
3849 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3850 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3854 object = result->objects.objects_val;
3855 if (object->zo_data.zo_type == ENTRY_OBJ)
3857 entry = &object->zo_data.objdata_u.en_data;
3858 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3859 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3861 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3862 string_sub(last_value, "&", user_name);
3863 fstrcpy(last_key, user_name);
3867 nis_freeresult(result);
3869 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3873 static char *automount_lookup(char *user_name)
3875 static fstring last_key = "";
3876 static pstring last_value = "";
3878 int nis_error; /* returned by yp all functions */
3879 char *nis_result; /* yp_match inits this */
3880 int nis_result_len; /* and set this */
3881 char *nis_domain; /* yp_get_default_domain inits this */
3882 char *nis_map = (char *)lp_nis_home_map_name();
3884 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3886 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3890 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3892 if (!strcmp(user_name, last_key))
3894 nis_result = last_value;
3895 nis_result_len = strlen(last_value);
3900 if ((nis_error = yp_match(nis_domain, nis_map,
3901 user_name, strlen(user_name),
3902 &nis_result, &nis_result_len)) != 0)
3904 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3905 yperr_string(nis_error), user_name, nis_map));
3907 if (!nis_error && nis_result_len >= sizeof(pstring))
3909 nis_result_len = sizeof(pstring)-1;
3911 fstrcpy(last_key, user_name);
3912 strncpy(last_value, nis_result, nis_result_len);
3913 last_value[nis_result_len] = '\0';
3916 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3919 #endif /* NISPLUS */
3922 /*******************************************************************
3923 Patch from jkf@soton.ac.uk
3924 This is Luke's original function with the NIS lookup code
3925 moved out to a separate function.
3926 *******************************************************************/
3928 char *automount_server(char *user_name)
3930 static pstring server_name;
3932 /* use the local machine name as the default */
3933 /* this will be the default if AUTOMOUNT is not used or fails */
3934 pstrcpy(server_name, local_machine);
3936 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3938 if (lp_nis_home_map())
3940 int home_server_len;
3941 char *automount_value = automount_lookup(user_name);
3942 home_server_len = strcspn(automount_value,":");
3943 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3944 if (home_server_len > sizeof(pstring))
3946 home_server_len = sizeof(pstring);
3948 strncpy(server_name, automount_value, home_server_len);
3949 server_name[home_server_len] = '\0';
3953 DEBUG(4,("Home server: %s\n", server_name));
3958 /*******************************************************************
3959 Patch from jkf@soton.ac.uk
3960 Added this to implement %p (NIS auto-map version of %H)
3961 *******************************************************************/
3963 char *automount_path(char *user_name)
3965 static pstring server_path;
3967 /* use the passwd entry as the default */
3968 /* this will be the default if AUTOMOUNT is not used or fails */
3969 /* pstrcpy() copes with get_home_dir() returning NULL */
3970 pstrcpy(server_path, get_home_dir(user_name));
3972 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3974 if (lp_nis_home_map())
3976 char *home_path_start;
3977 char *automount_value = automount_lookup(user_name);
3978 home_path_start = strchr(automount_value,':');
3979 if (home_path_start != NULL)
3981 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3982 home_path_start?(home_path_start+1):""));
3983 strcpy(server_path, home_path_start+1);
3988 DEBUG(4,("Home server path: %s\n", server_path));
3994 /*******************************************************************
3995 sub strings with useful parameters
3996 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3997 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3998 ********************************************************************/
3999 void standard_sub_basic(char *str)
4003 struct passwd *pass;
4004 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4006 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4012 if ((pass = Get_Pwnam(username,False))!=NULL)
4014 string_sub(p,"%G",gidtoname(pass->pw_gid));
4022 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4023 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4024 case 'L' : string_sub(p,"%L", local_machine); break;
4025 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4026 case 'R' : string_sub(p,"%R", remote_proto); break;
4027 case 'T' : string_sub(p,"%T", timestring()); break;
4028 case 'U' : string_sub(p,"%U", username); break;
4029 case 'a' : string_sub(p,"%a", remote_arch); break;
4032 sprintf(pidstr,"%d",(int)getpid());
4033 string_sub(p,"%d", pidstr);
4036 case 'h' : string_sub(p,"%h", myhostname); break;
4037 case 'm' : string_sub(p,"%m", remote_machine); break;
4038 case 'v' : string_sub(p,"%v", VERSION); break;
4039 case '$' : /* Expand environment variables */
4041 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4047 if (*(p+2) != '(') { p+=2; break; }
4048 if ((q = strchr(p,')')) == NULL)
4050 DEBUG(0,("standard_sub_basic: Unterminated environment \
4051 variable [%s]\n", p));
4056 copylen = MIN((q-r),(sizeof(envname)-1));
4057 strncpy(envname,r,copylen);
4058 envname[copylen] = '\0';
4059 if ((envval = getenv(envname)) == NULL)
4061 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4065 copylen = MIN((q+1-p),(sizeof(envname)-1));
4066 strncpy(envname,p,copylen);
4067 envname[copylen] = '\0';
4068 string_sub(p,envname,envval);
4071 case '\0': p++; break; /* don't run off end if last character is % */
4072 default : p+=2; break;
4078 /*******************************************************************
4079 are two IPs on the same subnet?
4080 ********************************************************************/
4081 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4083 uint32 net1,net2,nmask;
4085 nmask = ntohl(mask.s_addr);
4086 net1 = ntohl(ip1.s_addr);
4087 net2 = ntohl(ip2.s_addr);
4089 return((net1 & nmask) == (net2 & nmask));
4093 /*******************************************************************
4094 write a string in unicoode format
4095 ********************************************************************/
4096 int PutUniCode(char *dst,char *src)
4100 dst[ret++] = src[0];
4109 /****************************************************************************
4110 a wrapper for gethostbyname() that tries with all lower and all upper case
4111 if the initial name fails
4112 ****************************************************************************/
4113 struct hostent *Get_Hostbyname(char *name)
4115 char *name2 = strdup(name);
4116 struct hostent *ret;
4120 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4126 * This next test is redundent and causes some systems (with
4127 * broken isalnum() calls) problems.
4132 if (!isalnum(*name2))
4139 ret = sys_gethostbyname(name2);
4146 /* try with all lowercase */
4148 ret = sys_gethostbyname(name2);
4155 /* try with all uppercase */
4157 ret = sys_gethostbyname(name2);
4164 /* nothing works :-( */
4170 /****************************************************************************
4171 check if a process exists. Does this work on all unixes?
4172 ****************************************************************************/
4173 BOOL process_exists(int pid)
4175 return(kill(pid,0) == 0 || errno != ESRCH);
4179 /*******************************************************************
4180 turn a uid into a user name
4181 ********************************************************************/
4182 char *uidtoname(int uid)
4184 static char name[40];
4185 struct passwd *pass = getpwuid(uid);
4186 if (pass) return(pass->pw_name);
4187 sprintf(name,"%d",uid);
4191 /*******************************************************************
4192 turn a gid into a group name
4193 ********************************************************************/
4194 char *gidtoname(int gid)
4196 static char name[40];
4197 struct group *grp = getgrgid(gid);
4198 if (grp) return(grp->gr_name);
4199 sprintf(name,"%d",gid);
4203 /*******************************************************************
4205 ********************************************************************/
4206 void BlockSignals(BOOL block,int signum)
4209 int block_mask = sigmask(signum);
4210 static int oldmask = 0;
4212 oldmask = sigblock(block_mask);
4214 sigsetmask(oldmask);
4215 #elif defined(USE_SIGPROCMASK)
4218 sigaddset(&set,signum);
4219 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4224 /*******************************************************************
4225 my own panic function - not suitable for general use
4226 ********************************************************************/
4227 void ajt_panic(void)
4229 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4234 #define DIRECT direct
4236 #define DIRECT dirent
4239 /*******************************************************************
4240 a readdir wrapper which just returns the file name
4241 also return the inode number if requested
4242 ********************************************************************/
4243 char *readdirname(void *p)
4248 if (!p) return(NULL);
4250 ptr = (struct DIRECT *)readdir(p);
4251 if (!ptr) return(NULL);
4253 dname = ptr->d_name;
4256 if (telldir(p) < 0) return(NULL);
4260 /* this handles a broken compiler setup, causing a mixture
4261 of BSD and SYSV headers and libraries */
4263 static BOOL broken_readdir = False;
4264 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4266 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4267 broken_readdir = True;
4276 pstrcpy(buf, dname);
4277 unix_to_dos(buf, True);
4284 /*******************************************************************
4285 Utility function used to decide if the last component
4286 of a path matches a (possibly wildcarded) entry in a namelist.
4287 ********************************************************************/
4289 BOOL is_in_path(char *name, name_compare_entry *namelist)
4291 pstring last_component;
4294 DEBUG(8, ("is_in_path: %s\n", name));
4296 /* if we have no list it's obviously not in the path */
4297 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4299 DEBUG(8,("is_in_path: no name list.\n"));
4303 /* Get the last component of the unix name. */
4304 p = strrchr(name, '/');
4305 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4306 last_component[sizeof(last_component)-1] = '\0';
4308 for(; namelist->name != NULL; namelist++)
4310 if(namelist->is_wild)
4312 /* look for a wildcard match. */
4313 if (mask_match(last_component, namelist->name, case_sensitive, False))
4315 DEBUG(8,("is_in_path: mask match succeeded\n"));
4321 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4322 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4324 DEBUG(8,("is_in_path: match succeeded\n"));
4329 DEBUG(8,("is_in_path: match not found\n"));
4334 /*******************************************************************
4335 Strip a '/' separated list into an array of
4336 name_compare_enties structures suitable for
4337 passing to is_in_path(). We do this for
4338 speed so we can pre-parse all the names in the list
4339 and don't do it for each call to is_in_path().
4340 namelist is modified here and is assumed to be
4341 a copy owned by the caller.
4342 We also check if the entry contains a wildcard to
4343 remove a potentially expensive call to mask_match
4345 ********************************************************************/
4347 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4350 char *nameptr = namelist;
4351 int num_entries = 0;
4354 (*ppname_array) = NULL;
4356 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4359 /* We need to make two passes over the string. The
4360 first to count the number of elements, the second
4365 if ( *nameptr == '/' )
4367 /* cope with multiple (useless) /s) */
4371 /* find the next / */
4372 name_end = strchr(nameptr, '/');
4374 /* oops - the last check for a / didn't find one. */
4375 if (name_end == NULL)
4378 /* next segment please */
4379 nameptr = name_end + 1;
4383 if(num_entries == 0)
4386 if(( (*ppname_array) = (name_compare_entry *)malloc(
4387 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4389 DEBUG(0,("set_namearray: malloc fail\n"));
4393 /* Now copy out the names */
4398 if ( *nameptr == '/' )
4400 /* cope with multiple (useless) /s) */
4404 /* find the next / */
4405 if ((name_end = strchr(nameptr, '/')) != NULL)
4410 /* oops - the last check for a / didn't find one. */
4411 if(name_end == NULL)
4414 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4415 (strchr( nameptr, '*')!=NULL));
4416 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4418 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4422 /* next segment please */
4423 nameptr = name_end + 1;
4427 (*ppname_array)[i].name = NULL;
4432 /****************************************************************************
4433 routine to free a namearray.
4434 ****************************************************************************/
4436 void free_namearray(name_compare_entry *name_array)
4441 if(name_array->name != NULL)
4442 free(name_array->name);
4444 free((char *)name_array);
4447 /****************************************************************************
4448 routine to do file locking
4449 ****************************************************************************/
4450 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4457 uint32 mask = 0xC0000000;
4459 /* make sure the count is reasonable, we might kill the lockd otherwise */
4462 /* the offset is often strange - remove 2 of its bits if either of
4463 the top two bits are set. Shift the top ones by two bits. This
4464 still allows OLE2 apps to operate, but should stop lockd from
4466 if ((offset & mask) != 0)
4467 offset = (offset & ~mask) | ((offset & mask) >> 2);
4469 uint32 mask = ((unsigned)1<<31);
4471 /* interpret negative counts as large numbers */
4475 /* no negative offsets */
4478 /* count + offset must be in range */
4479 while ((offset < 0 || (offset + count < 0)) && mask)
4487 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4490 lock.l_whence = SEEK_SET;
4491 lock.l_start = (int)offset;
4492 lock.l_len = (int)count;
4497 ret = fcntl(fd,op,&lock);
4500 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4506 (lock.l_type != F_UNLCK) &&
4507 (lock.l_pid != 0) &&
4508 (lock.l_pid != getpid()))
4510 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4514 /* it must be not locked or locked by me */
4518 /* a lock set or unset */
4521 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4522 offset,count,op,type,strerror(errno)));
4524 /* perhaps it doesn't support this sort of locking?? */
4525 if (errno == EINVAL)
4527 DEBUG(3,("locking not supported? returning True\n"));
4534 /* everything went OK */
4535 DEBUG(8,("Lock call successful\n"));
4543 /*******************************************************************
4544 lock a file - returning a open file descriptor or -1 on failure
4545 The timeout is in seconds. 0 means no timeout
4546 ********************************************************************/
4547 int file_lock(char *name,int timeout)
4549 int fd = open(name,O_RDWR|O_CREAT,0666);
4551 if (fd < 0) return(-1);
4554 if (timeout) t = time(NULL);
4555 while (!timeout || (time(NULL)-t < timeout)) {
4556 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4557 msleep(LOCK_RETRY_TIMEOUT);
4565 /*******************************************************************
4566 unlock a file locked by file_lock
4567 ********************************************************************/
4568 void file_unlock(int fd)
4572 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4577 /*******************************************************************
4578 is the name specified one of my netbios names
4579 returns true is it is equal, false otherwise
4580 ********************************************************************/
4581 BOOL is_myname(char *s)
4586 for (n=0; my_netbios_names[n]; n++) {
4587 if (strequal(my_netbios_names[n], s))
4590 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4594 /*******************************************************************
4595 set the horrid remote_arch string based on an enum.
4596 ********************************************************************/
4597 void set_remote_arch(enum remote_arch_types type)
4603 strcpy(remote_arch, "WfWg");
4606 strcpy(remote_arch, "OS2");
4609 strcpy(remote_arch, "Win95");
4612 strcpy(remote_arch, "WinNT");
4615 strcpy(remote_arch,"Samba");
4618 ra_type = RA_UNKNOWN;
4619 strcpy(remote_arch, "UNKNOWN");
4624 /*******************************************************************
4625 Get the remote_arch type.
4626 ********************************************************************/
4627 enum remote_arch_types get_remote_arch(void)
4633 /*******************************************************************
4634 skip past some unicode strings in a buffer
4635 ********************************************************************/
4636 char *skip_unicode_string(char *buf,int n)
4647 /*******************************************************************
4648 Return a ascii version of a unicode string
4649 Hack alert: uses fixed buffer(s) and only handles ascii strings
4650 ********************************************************************/
4652 char *unistrn2(uint16 *buf, int len)
4654 static char lbufs[8][MAXUNI];
4656 char *lbuf = lbufs[nexti];
4659 nexti = (nexti+1)%8;
4661 DEBUG(10, ("unistrn2: "));
4663 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4665 DEBUG(10, ("%4x ", *buf));
4675 /*******************************************************************
4676 Return a ascii version of a unicode string
4677 Hack alert: uses fixed buffer(s) and only handles ascii strings
4678 ********************************************************************/
4680 char *unistr2(uint16 *buf)
4682 static char lbufs[8][MAXUNI];
4684 char *lbuf = lbufs[nexti];
4687 nexti = (nexti+1)%8;
4689 DEBUG(10, ("unistr2: "));
4691 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4693 DEBUG(10, ("%4x ", *buf));
4703 /*******************************************************************
4704 create a null-terminated unicode string from a null-terminated ascii string.
4705 return number of unicode chars copied, excluding the null character.
4707 only handles ascii strings
4708 ********************************************************************/
4710 int struni2(uint16 *p, char *buf)
4714 if (p == NULL) return 0;
4716 DEBUG(10, ("struni2: "));
4720 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4722 DEBUG(10, ("%2x ", *buf));
4734 /*******************************************************************
4735 Return a ascii version of a unicode string
4736 Hack alert: uses fixed buffer(s) and only handles ascii strings
4737 ********************************************************************/
4739 char *unistr(char *buf)
4741 static char lbufs[8][MAXUNI];
4743 char *lbuf = lbufs[nexti];
4746 nexti = (nexti+1)%8;
4748 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4756 /*******************************************************************
4757 strncpy for unicode strings
4758 ********************************************************************/
4759 int unistrncpy(char *dst, char *src, int len)
4763 while (*src && len > 0)
4777 /*******************************************************************
4778 strcpy for unicode strings. returns length (in num of wide chars)
4779 ********************************************************************/
4780 int unistrcpy(char *dst, char *src)
4797 /*******************************************************************
4798 safe string copy into a fstring
4799 ********************************************************************/
4800 void fstrcpy(char *dest, char *src)
4802 int maxlength = sizeof(fstring) - 1;
4805 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4816 if (len > maxlength) {
4817 DEBUG(0,("ERROR: string overflow by %d in fstrcpy [%.50s]\n",
4818 len-maxlength, src));
4822 memcpy(dest, src, len);
4826 /*******************************************************************
4827 safe string copy into a pstring
4828 ********************************************************************/
4829 void pstrcpy(char *dest, char *src)
4831 int maxlength = sizeof(pstring) - 1;
4834 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4845 if (len > maxlength) {
4846 DEBUG(0,("ERROR: string overflow by %d in pstrcpy [%.50s]\n",
4847 len-maxlength, src));
4851 memcpy(dest, src, len);
4856 /*******************************************************************
4857 align a pointer to a multiple of 4 bytes
4858 ********************************************************************/
4859 char *align4(char *q, char *base)
4863 q += 4 - ((q - base) & 3);
4868 /*******************************************************************
4869 align a pointer to a multiple of 2 bytes
4870 ********************************************************************/
4871 char *align2(char *q, char *base)
4880 /*******************************************************************
4881 align a pointer to a multiple of align_offset bytes. looks like it
4882 will work for offsets of 0, 2 and 4...
4883 ********************************************************************/
4884 char *align_offset(char *q, char *base, int align_offset_len)
4886 int mod = ((q - base) & (align_offset_len-1));
4887 if (align_offset_len != 0 && mod != 0)
4889 q += align_offset_len - mod;
4894 void print_asc(int level, unsigned char *buf,int len)
4898 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4901 void dump_data(int level,char *buf1,int len)
4903 unsigned char *buf = (unsigned char *)buf1;
4907 DEBUG(level,("[%03X] ",i));
4909 DEBUG(level,("%02X ",(int)buf[i]));
4911 if (i%8 == 0) DEBUG(level,(" "));
4913 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4914 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4915 if (i<len) DEBUG(level,("[%03X] ",i));
4923 if (n>8) DEBUG(level,(" "));
4924 while (n--) DEBUG(level,(" "));
4927 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4929 if (n>0) print_asc(level,&buf[i-n],n);
4930 DEBUG(level,("\n"));
4934 char *tab_depth(int depth)
4936 static pstring spaces;
4937 memset(spaces, ' ', depth * 4);
4938 spaces[depth * 4] = 0;
4942 /*****************************************************************
4943 Convert a domain SID to an ascii string. (non-reentrant).
4944 *****************************************************************/
4946 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4947 char *dom_sid_to_string(DOM_SID *sid)
4949 static pstring sidstr;
4952 uint32 ia = (sid->id_auth[5]) +
4953 (sid->id_auth[4] << 8 ) +
4954 (sid->id_auth[3] << 16) +
4955 (sid->id_auth[2] << 24);
4957 sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
4959 for (i = 0; i < sid->num_auths; i++)
4961 sprintf(subauth, "-%d", sid->sub_auths[i]);
4962 strcat(sidstr, subauth);
4965 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));
4969 /*************************************************************
4970 Routine to get the next 32 hex characters and turn them
4971 into a 16 byte array.
4972 **************************************************************/
4973 int gethexpwd(char *p, char *pwd)
4976 unsigned char lonybble, hinybble;
4977 char *hexchars = "0123456789ABCDEF";
4980 for (i = 0; i < 32; i += 2) {
4981 hinybble = toupper(p[i]);
4982 lonybble = toupper(p[i + 1]);
4984 p1 = strchr(hexchars, hinybble);
4985 p2 = strchr(hexchars, lonybble);
4988 hinybble = PTR_DIFF(p1, hexchars);
4989 lonybble = PTR_DIFF(p2, hexchars);
4991 pwd[i / 2] = (hinybble << 4) | lonybble;