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"
34 #undef Realloc /* SSLeay defines this and samba has a function of this name */
45 int Protocol = PROTOCOL_COREPLUS;
47 /* a default finfo structure to ensure all fields are sensible */
48 file_info def_finfo = {-1,0,0,0,0,0,0,""};
50 /* these are some file handles where debug info will be stored */
53 /* the client file descriptor */
56 /* the last IP received from */
57 struct in_addr lastip;
59 /* the last port received from */
62 /* this is used by the chaining code */
68 case handling on filenames
70 int case_default = CASE_LOWER;
75 /* the following control case operations - they are put here so the
76 client can link easily */
79 BOOL use_mangled_map = False;
80 BOOL short_case_preserve;
83 fstring remote_machine="";
84 fstring local_machine="";
85 fstring remote_arch="UNKNOWN";
86 static enum remote_arch_types ra_type = RA_UNKNOWN;
87 fstring remote_proto="UNKNOWN";
88 pstring myhostname="";
89 pstring user_socket_options="";
91 pstring sesssetup_user="";
92 pstring samlogon_user="";
94 BOOL sam_logon_in_ssb = False;
96 pstring global_myname = "";
97 fstring global_myworkgroup = "";
98 char **my_netbios_names;
100 int smb_read_error = 0;
102 static BOOL stdout_logging = False;
104 static char *filename_dos(char *path,char *buf);
107 /******************************************************************************
108 catch a sigusr2 - decrease the debug log level.
109 *****************************************************************************/
112 BlockSignals( True, SIGUSR2);
119 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
121 BlockSignals( False, SIGUSR2);
122 #ifndef DONT_REINSTALL_SIG
123 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
130 /**************************************************************************** **
131 catch a sigusr1 - increase the debug log level.
132 **************************************************************************** */
135 BlockSignals( True, SIGUSR1);
142 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
144 BlockSignals( False, SIGUSR1);
145 #ifndef DONT_REINSTALL_SIG
146 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
153 /*******************************************************************
154 get ready for syslog stuff
155 ******************************************************************/
156 void setup_logging(char *pname,BOOL interactive)
160 char *p = strrchr(pname,'/');
163 openlog(pname, LOG_PID, SYSLOG_FACILITY);
164 #else /* for old systems that have no facility codes. */
165 openlog(pname, LOG_PID);
170 stdout_logging = True;
176 BOOL append_log=False;
179 /****************************************************************************
181 ****************************************************************************/
182 void reopen_logs(void)
188 pstrcpy(fname,debugf);
189 if (lp_loaded() && (*lp_logfile()))
190 pstrcpy(fname,lp_logfile());
192 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
194 int oldumask = umask(022);
195 pstrcpy(debugf,fname);
196 if (dbf) fclose(dbf);
198 dbf = fopen(debugf,"a");
200 dbf = fopen(debugf,"w");
201 if (dbf) setbuf(dbf,NULL);
216 /*******************************************************************
217 check if the log has grown too big
218 ********************************************************************/
219 static void check_log_size(void)
221 static int debug_count=0;
225 if (debug_count++ < 100 || getuid() != 0) return;
227 maxlog = lp_max_log_size() * 1024;
228 if (!dbf || maxlog <= 0) return;
230 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
231 fclose(dbf); dbf = NULL;
233 if (dbf && file_size(debugf) > maxlog) {
235 fclose(dbf); dbf = NULL;
236 slprintf(name,sizeof(name)-1,"%s.old",debugf);
245 /*******************************************************************
246 write an debug message on the debugfile. This is called by the DEBUG
248 ********************************************************************/
250 int Debug1(char *format_str, ...)
259 int old_errno = errno;
261 if (stdout_logging) {
263 va_start(ap, format_str);
266 format_str = va_arg(ap,char *);
268 vfprintf(dbf,format_str,ap);
275 if (!lp_syslog_only())
279 int oldumask = umask(022);
281 dbf = fopen(debugf,"a");
283 dbf = fopen(debugf,"w");
295 if (syslog_level < lp_syslog())
298 * map debug levels to syslog() priorities
299 * note that not all DEBUG(0, ...) calls are
302 static int priority_map[] = {
311 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
313 priority = LOG_DEBUG;
315 priority = priority_map[syslog_level];
318 va_start(ap, format_str);
321 format_str = va_arg(ap,char *);
323 vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap);
327 syslog(priority, "%s", msgbuf);
332 if (!lp_syslog_only())
336 va_start(ap, format_str);
339 format_str = va_arg(ap,char *);
341 vfprintf(dbf,format_str,ap);
353 /****************************************************************************
354 find a suitable temporary directory. The result should be copied immediately
355 as it may be overwritten by a subsequent call
356 ****************************************************************************/
360 if ((p = getenv("TMPDIR"))) {
368 /****************************************************************************
369 determine if a file descriptor is in fact a socket
370 ****************************************************************************/
371 BOOL is_a_socket(int fd)
375 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
379 static char *last_ptr=NULL;
381 /****************************************************************************
382 Get the next token from a string, return False if none found
383 handles double-quotes.
384 Based on a routine by GJC@VILLAGE.COM.
385 Extensively modified by Andrew.Tridgell@anu.edu.au
386 ****************************************************************************/
387 BOOL next_token(char **ptr,char *buff,char *sep)
392 if (!ptr) ptr = &last_ptr;
393 if (!ptr) return(False);
397 /* default to simple separators */
398 if (!sep) sep = " \t\n\r";
400 /* find the first non sep char */
401 while(*s && strchr(sep,*s)) s++;
404 if (! *s) return(False);
406 /* copy over the token */
407 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
415 *ptr = (*s) ? s+1 : s;
422 /****************************************************************************
423 Convert list of tokens to array; dependent on above routine.
424 Uses last_ptr from above - bit of a hack.
425 ****************************************************************************/
426 char **toktocliplist(int *ctok, char *sep)
432 if (!sep) sep = " \t\n\r";
434 while(*s && strchr(sep,*s)) s++;
437 if (!*s) return(NULL);
441 while(*s && (!strchr(sep,*s))) s++;
442 while(*s && strchr(sep,*s)) *s++=0;
448 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
460 /*******************************************************************
461 safely copies memory, ensuring no overlap problems.
462 this is only used if the machine does not have it's own memmove().
463 this is not the fastest algorithm in town, but it will do for our
465 ********************************************************************/
466 void *MemMove(void *dest,void *src,int size)
470 if (dest==src || !size) return(dest);
472 d = (unsigned long)dest;
473 s = (unsigned long)src;
475 if ((d >= (s+size)) || (s >= (d+size))) {
477 memcpy(dest,src,size);
483 /* we can forward copy */
484 if (s-d >= sizeof(int) &&
485 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
486 /* do it all as words */
487 int *idest = (int *)dest;
488 int *isrc = (int *)src;
490 for (i=0;i<size;i++) idest[i] = isrc[i];
493 char *cdest = (char *)dest;
494 char *csrc = (char *)src;
495 for (i=0;i<size;i++) cdest[i] = csrc[i];
500 /* must backward copy */
501 if (d-s >= sizeof(int) &&
502 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
503 /* do it all as words */
504 int *idest = (int *)dest;
505 int *isrc = (int *)src;
507 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
510 char *cdest = (char *)dest;
511 char *csrc = (char *)src;
512 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
519 /* ************************************************************************* **
520 * Duplicate a block of memory.
521 * ************************************************************************* **
523 void *mem_dup( void *from, int size )
527 tmp = malloc( size );
529 (void)memcpy( tmp, from, size );
533 /****************************************************************************
534 prompte a dptr (to make it recently used)
535 ****************************************************************************/
536 void array_promote(char *array,int elsize,int element)
542 p = (char *)malloc(elsize);
546 DEBUG(5,("Ahh! Can't malloc\n"));
549 memcpy(p,array + element * elsize, elsize);
550 memmove(array + elsize,array,elsize*element);
551 memcpy(array,p,elsize);
555 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
564 } socket_options[] = {
565 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
566 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
567 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
569 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
571 #ifdef IPTOS_LOWDELAY
572 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
574 #ifdef IPTOS_THROUGHPUT
575 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
578 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
581 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
584 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
587 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
590 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
593 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
599 /****************************************************************************
600 set user socket options
601 ****************************************************************************/
602 void set_socket_options(int fd, char *options)
606 while (next_token(&options,tok," \t,"))
611 BOOL got_value = False;
613 if ((p = strchr(tok,'=')))
620 for (i=0;socket_options[i].name;i++)
621 if (strequal(socket_options[i].name,tok))
624 if (!socket_options[i].name)
626 DEBUG(0,("Unknown socket option %s\n",tok));
630 switch (socket_options[i].opttype)
634 ret = setsockopt(fd,socket_options[i].level,
635 socket_options[i].option,(char *)&value,sizeof(int));
640 DEBUG(0,("syntax error - %s does not take a value\n",tok));
643 int on = socket_options[i].value;
644 ret = setsockopt(fd,socket_options[i].level,
645 socket_options[i].option,(char *)&on,sizeof(int));
651 DEBUG(0,("Failed to set socket option %s\n",tok));
657 /****************************************************************************
658 close the socket communication
659 ****************************************************************************/
660 void close_sockets(void )
663 sslutil_disconnect(Client);
670 /****************************************************************************
671 determine whether we are in the specified group
672 ****************************************************************************/
673 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
677 if (group == current_gid) return(True);
679 for (i=0;i<ngroups;i++)
680 if (group == groups[i])
686 /****************************************************************************
687 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
688 ****************************************************************************/
689 char *StrCpy(char *dest,char *src)
694 /* I don't want to get lazy with these ... */
696 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
701 if (!dest) return(NULL);
706 while ((*d++ = *src++)) ;
710 /****************************************************************************
711 line strncpy but always null terminates. Make sure there is room!
712 ****************************************************************************/
713 char *StrnCpy(char *dest,char *src,int n)
716 if (!dest) return(NULL);
721 while (n-- && (*d++ = *src++)) ;
727 /*******************************************************************
728 copy an IP address from one buffer to another
729 ********************************************************************/
730 void putip(void *dest,void *src)
736 /****************************************************************************
737 interpret the weird netbios "name". Return the name type
738 ****************************************************************************/
739 static int name_interpret(char *in,char *out)
742 int len = (*in++) / 2;
746 if (len > 30 || len<1) return(0);
750 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
754 *out = ((in[0]-'A')<<4) + (in[1]-'A');
762 /* Handle any scope names */
765 *out++ = '.'; /* Scope names are separated by periods */
766 len = *(unsigned char *)in++;
767 StrnCpy(out, in, len);
776 /****************************************************************************
777 mangle a name into netbios format
779 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
780 ****************************************************************************/
781 int name_mangle( char *In, char *Out, char name_type )
789 /* Safely copy the input string, In, into buf[]. */
790 (void)memset( buf, 0, 20 );
794 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
796 /* Place the length of the first field into the output buffer. */
800 /* Now convert the name to the rfc1001/1002 format. */
801 for( i = 0; i < 16; i++ )
803 c = toupper( buf[i] );
804 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
805 p[(i*2)+1] = (c & 0x000F) + 'A';
810 /* Add the scope string. */
811 for( i = 0, len = 0; NULL != scope; i++, len++ )
819 return( name_len(Out) );
831 return( name_len(Out) );
834 /*******************************************************************
835 check if a file exists
836 ********************************************************************/
837 BOOL file_exist(char *fname,struct stat *sbuf)
840 if (!sbuf) sbuf = &st;
842 if (sys_stat(fname,sbuf) != 0)
845 return(S_ISREG(sbuf->st_mode));
848 /*******************************************************************
849 check a files mod time
850 ********************************************************************/
851 time_t file_modtime(char *fname)
855 if (sys_stat(fname,&st) != 0)
861 /*******************************************************************
862 check if a directory exists
863 ********************************************************************/
864 BOOL directory_exist(char *dname,struct stat *st)
871 if (sys_stat(dname,st) != 0)
874 ret = S_ISDIR(st->st_mode);
880 /*******************************************************************
881 returns the size in bytes of the named file
882 ********************************************************************/
883 uint32 file_size(char *file_name)
887 sys_stat(file_name,&buf);
891 /*******************************************************************
892 return a string representing an attribute for a file
893 ********************************************************************/
894 char *attrib_string(int mode)
896 static fstring attrstr;
900 if (mode & aVOLID) fstrcat(attrstr,"V");
901 if (mode & aDIR) fstrcat(attrstr,"D");
902 if (mode & aARCH) fstrcat(attrstr,"A");
903 if (mode & aHIDDEN) fstrcat(attrstr,"H");
904 if (mode & aSYSTEM) fstrcat(attrstr,"S");
905 if (mode & aRONLY) fstrcat(attrstr,"R");
911 /*******************************************************************
912 case insensitive string compararison
913 ********************************************************************/
914 int StrCaseCmp(char *s, char *t)
916 /* compare until we run out of string, either t or s, or find a difference */
917 /* We *must* use toupper rather than tolower here due to the
918 asynchronous upper to lower mapping.
920 #if !defined(KANJI_WIN95_COMPATIBILITY)
922 * For completeness we should put in equivalent code for code pages
923 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
924 * doubt anyone wants Samba to behave differently from Win95 and WinNT
925 * here. They both treat full width ascii characters as case senstive
926 * filenames (ie. they don't do the work we do here).
930 if(lp_client_code_page() == KANJI_CODEPAGE)
932 /* Win95 treats full width ascii characters as case sensitive. */
937 return toupper (*s) - toupper (*t);
938 else if (is_sj_alph (*s) && is_sj_alph (*t))
940 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
946 else if (is_shift_jis (*s) && is_shift_jis (*t))
948 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
951 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
957 else if (is_shift_jis (*s))
959 else if (is_shift_jis (*t))
963 diff = toupper (*s) - toupper (*t);
972 #endif /* KANJI_WIN95_COMPATIBILITY */
974 while (*s && *t && toupper(*s) == toupper(*t))
980 return(toupper(*s) - toupper(*t));
984 /*******************************************************************
985 case insensitive string compararison, length limited
986 ********************************************************************/
987 int StrnCaseCmp(char *s, char *t, int n)
989 /* compare until we run out of string, either t or s, or chars */
990 /* We *must* use toupper rather than tolower here due to the
991 asynchronous upper to lower mapping.
993 #if !defined(KANJI_WIN95_COMPATIBILITY)
995 * For completeness we should put in equivalent code for code pages
996 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
997 * doubt anyone wants Samba to behave differently from Win95 and WinNT
998 * here. They both treat full width ascii characters as case senstive
999 * filenames (ie. they don't do the work we do here).
1003 if(lp_client_code_page() == KANJI_CODEPAGE)
1005 /* Win95 treats full width ascii characters as case sensitive. */
1010 return toupper (*s) - toupper (*t);
1011 else if (is_sj_alph (*s) && is_sj_alph (*t))
1013 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
1020 else if (is_shift_jis (*s) && is_shift_jis (*t))
1022 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
1025 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1032 else if (is_shift_jis (*s))
1034 else if (is_shift_jis (*t))
1038 diff = toupper (*s) - toupper (*t);
1049 #endif /* KANJI_WIN95_COMPATIBILITY */
1051 while (n && *s && *t && toupper(*s) == toupper(*t))
1058 /* not run out of chars - strings are different lengths */
1060 return(toupper(*s) - toupper(*t));
1062 /* identical up to where we run out of chars,
1063 and strings are same length */
1068 /*******************************************************************
1070 ********************************************************************/
1071 BOOL strequal(char *s1, char *s2)
1073 if (s1 == s2) return(True);
1074 if (!s1 || !s2) return(False);
1076 return(StrCaseCmp(s1,s2)==0);
1079 /*******************************************************************
1080 compare 2 strings up to and including the nth char.
1081 ******************************************************************/
1082 BOOL strnequal(char *s1,char *s2,int n)
1084 if (s1 == s2) return(True);
1085 if (!s1 || !s2 || !n) return(False);
1087 return(StrnCaseCmp(s1,s2,n)==0);
1090 /*******************************************************************
1091 compare 2 strings (case sensitive)
1092 ********************************************************************/
1093 BOOL strcsequal(char *s1,char *s2)
1095 if (s1 == s2) return(True);
1096 if (!s1 || !s2) return(False);
1098 return(strcmp(s1,s2)==0);
1102 /*******************************************************************
1103 convert a string to lower case
1104 ********************************************************************/
1105 void strlower(char *s)
1109 #if !defined(KANJI_WIN95_COMPATIBILITY)
1111 * For completeness we should put in equivalent code for code pages
1112 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1113 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1114 * here. They both treat full width ascii characters as case senstive
1115 * filenames (ie. they don't do the work we do here).
1119 if(lp_client_code_page() == KANJI_CODEPAGE)
1121 /* Win95 treats full width ascii characters as case sensitive. */
1122 if (is_shift_jis (*s))
1124 if (is_sj_upper (s[0], s[1]))
1125 s[1] = sj_tolower2 (s[1]);
1128 else if (is_kana (*s))
1140 #endif /* KANJI_WIN95_COMPATIBILITY */
1142 int skip = skip_multibyte_char( *s );
1155 /*******************************************************************
1156 convert a string to upper case
1157 ********************************************************************/
1158 void strupper(char *s)
1162 #if !defined(KANJI_WIN95_COMPATIBILITY)
1164 * For completeness we should put in equivalent code for code pages
1165 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1166 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1167 * here. They both treat full width ascii characters as case senstive
1168 * filenames (ie. they don't do the work we do here).
1172 if(lp_client_code_page() == KANJI_CODEPAGE)
1174 /* Win95 treats full width ascii characters as case sensitive. */
1175 if (is_shift_jis (*s))
1177 if (is_sj_lower (s[0], s[1]))
1178 s[1] = sj_toupper2 (s[1]);
1181 else if (is_kana (*s))
1193 #endif /* KANJI_WIN95_COMPATIBILITY */
1195 int skip = skip_multibyte_char( *s );
1208 /*******************************************************************
1209 convert a string to "normal" form
1210 ********************************************************************/
1211 void strnorm(char *s)
1213 if (case_default == CASE_UPPER)
1219 /*******************************************************************
1220 check if a string is in "normal" case
1221 ********************************************************************/
1222 BOOL strisnormal(char *s)
1224 if (case_default == CASE_UPPER)
1225 return(!strhaslower(s));
1227 return(!strhasupper(s));
1231 /****************************************************************************
1233 ****************************************************************************/
1234 void string_replace(char *s,char oldc,char newc)
1239 skip = skip_multibyte_char( *s );
1251 /****************************************************************************
1252 make a file into unix format
1253 ****************************************************************************/
1254 void unix_format(char *fname)
1257 string_replace(fname,'\\','/');
1261 pstrcpy(namecopy,fname);
1263 pstrcat(fname,namecopy);
1267 /****************************************************************************
1268 make a file into dos format
1269 ****************************************************************************/
1270 void dos_format(char *fname)
1272 string_replace(fname,'/','\\');
1275 /*******************************************************************
1276 show a smb message structure
1277 ********************************************************************/
1278 void show_msg(char *buf)
1283 if (DEBUGLEVEL < 5) return;
1285 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1287 (int)CVAL(buf,smb_com),
1288 (int)CVAL(buf,smb_rcls),
1289 (int)CVAL(buf,smb_reh),
1290 (int)SVAL(buf,smb_err),
1291 (int)CVAL(buf,smb_flg),
1292 (int)SVAL(buf,smb_flg2)));
1293 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1294 (int)SVAL(buf,smb_tid),
1295 (int)SVAL(buf,smb_pid),
1296 (int)SVAL(buf,smb_uid),
1297 (int)SVAL(buf,smb_mid),
1298 (int)CVAL(buf,smb_wct)));
1300 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1302 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1303 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1306 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1308 DEBUG(5,("smb_bcc=%d\n",bcc));
1310 if (DEBUGLEVEL < 10) return;
1312 if (DEBUGLEVEL < 50)
1314 bcc = MIN(bcc, 512);
1317 dump_data(10, smb_buf(buf), bcc);
1319 /*******************************************************************
1320 return the length of an smb packet
1321 ********************************************************************/
1322 int smb_len(char *buf)
1324 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1327 /*******************************************************************
1328 set the length of an smb packet
1329 ********************************************************************/
1330 void _smb_setlen(char *buf,int len)
1333 buf[1] = (len&0x10000)>>16;
1334 buf[2] = (len&0xFF00)>>8;
1338 /*******************************************************************
1339 set the length and marker of an smb packet
1340 ********************************************************************/
1341 void smb_setlen(char *buf,int len)
1343 _smb_setlen(buf,len);
1351 /*******************************************************************
1352 setup the word count and byte count for a smb message
1353 ********************************************************************/
1354 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1357 bzero(buf + smb_size,num_words*2 + num_bytes);
1358 CVAL(buf,smb_wct) = num_words;
1359 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1360 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1361 return (smb_size + num_words*2 + num_bytes);
1364 /*******************************************************************
1365 return the number of smb words
1366 ********************************************************************/
1367 int smb_numwords(char *buf)
1369 return (CVAL(buf,smb_wct));
1372 /*******************************************************************
1373 return the size of the smb_buf region of a message
1374 ********************************************************************/
1375 int smb_buflen(char *buf)
1377 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1380 /*******************************************************************
1381 return a pointer to the smb_buf data area
1382 ********************************************************************/
1383 int smb_buf_ofs(char *buf)
1385 return (smb_size + CVAL(buf,smb_wct)*2);
1388 /*******************************************************************
1389 return a pointer to the smb_buf data area
1390 ********************************************************************/
1391 char *smb_buf(char *buf)
1393 return (buf + smb_buf_ofs(buf));
1396 /*******************************************************************
1397 return the SMB offset into an SMB buffer
1398 ********************************************************************/
1399 int smb_offset(char *p,char *buf)
1401 return(PTR_DIFF(p,buf+4) + chain_size);
1405 /*******************************************************************
1406 skip past some strings in a buffer
1407 ********************************************************************/
1408 char *skip_string(char *buf,int n)
1411 buf += strlen(buf) + 1;
1415 /*******************************************************************
1416 trim the specified elements off the front and back of a string
1417 ********************************************************************/
1418 BOOL trim_string(char *s,char *front,char *back)
1421 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1427 if (!(*p = p[strlen(front)]))
1432 while (back && *back && strlen(s) >= strlen(back) &&
1433 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1436 s[strlen(s)-strlen(back)] = 0;
1442 /*******************************************************************
1443 reduce a file name, removing .. elements.
1444 ********************************************************************/
1445 void dos_clean_name(char *s)
1449 DEBUG(3,("dos_clean_name [%s]\n",s));
1451 /* remove any double slashes */
1452 string_sub(s, "\\\\", "\\");
1454 while ((p = strstr(s,"\\..\\")) != NULL)
1461 if ((p=strrchr(s,'\\')) != NULL)
1468 trim_string(s,NULL,"\\..");
1470 string_sub(s, "\\.\\", "\\");
1473 /*******************************************************************
1474 reduce a file name, removing .. elements.
1475 ********************************************************************/
1476 void unix_clean_name(char *s)
1480 DEBUG(3,("unix_clean_name [%s]\n",s));
1482 /* remove any double slashes */
1483 string_sub(s, "//","/");
1485 /* Remove leading ./ characters */
1486 if(strncmp(s, "./", 2) == 0) {
1487 trim_string(s, "./", NULL);
1492 while ((p = strstr(s,"/../")) != NULL)
1499 if ((p=strrchr(s,'/')) != NULL)
1506 trim_string(s,NULL,"/..");
1510 /*******************************************************************
1511 a wrapper for the normal chdir() function
1512 ********************************************************************/
1513 int ChDir(char *path)
1516 static pstring LastDir="";
1518 if (strcsequal(path,".")) return(0);
1520 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1521 DEBUG(3,("chdir to %s\n",path));
1522 res = sys_chdir(path);
1524 pstrcpy(LastDir,path);
1528 /* number of list structures for a caching GetWd function. */
1529 #define MAX_GETWDCACHE (50)
1537 } ino_list[MAX_GETWDCACHE];
1539 BOOL use_getwd_cache=True;
1541 /*******************************************************************
1542 return the absolute current directory path
1543 ********************************************************************/
1544 char *GetWd(char *str)
1547 static BOOL getwd_cache_init = False;
1548 struct stat st, st2;
1553 if (!use_getwd_cache)
1554 return(sys_getwd(str));
1556 /* init the cache */
1557 if (!getwd_cache_init)
1559 getwd_cache_init = True;
1560 for (i=0;i<MAX_GETWDCACHE;i++)
1562 string_init(&ino_list[i].text,"");
1563 ino_list[i].valid = False;
1567 /* Get the inode of the current directory, if this doesn't work we're
1570 if (stat(".",&st) == -1)
1572 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1573 return(sys_getwd(str));
1577 for (i=0; i<MAX_GETWDCACHE; i++)
1578 if (ino_list[i].valid)
1581 /* If we have found an entry with a matching inode and dev number
1582 then find the inode number for the directory in the cached string.
1583 If this agrees with that returned by the stat for the current
1584 directory then all is o.k. (but make sure it is a directory all
1587 if (st.st_ino == ino_list[i].inode &&
1588 st.st_dev == ino_list[i].dev)
1590 if (stat(ino_list[i].text,&st2) == 0)
1592 if (st.st_ino == st2.st_ino &&
1593 st.st_dev == st2.st_dev &&
1594 (st2.st_mode & S_IFMT) == S_IFDIR)
1596 pstrcpy (str, ino_list[i].text);
1598 /* promote it for future use */
1599 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1604 /* If the inode is different then something's changed,
1605 scrub the entry and start from scratch. */
1606 ino_list[i].valid = False;
1613 /* We don't have the information to hand so rely on traditional methods.
1614 The very slow getcwd, which spawns a process on some systems, or the
1615 not quite so bad getwd. */
1619 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1625 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1627 /* add it to the cache */
1628 i = MAX_GETWDCACHE - 1;
1629 string_set(&ino_list[i].text,s);
1630 ino_list[i].dev = st.st_dev;
1631 ino_list[i].inode = st.st_ino;
1632 ino_list[i].valid = True;
1634 /* put it at the top of the list */
1635 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1642 /*******************************************************************
1643 reduce a file name, removing .. elements and checking that
1644 it is below dir in the heirachy. This uses GetWd() and so must be run
1645 on the system that has the referenced file system.
1647 widelinks are allowed if widelinks is true
1648 ********************************************************************/
1649 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1651 #ifndef REDUCE_PATHS
1659 BOOL relative = (*s != '/');
1661 *dir2 = *wd = *base_name = *newname = 0;
1666 /* can't have a leading .. */
1667 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1669 DEBUG(3,("Illegal file name? (%s)\n",s));
1679 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1681 /* remove any double slashes */
1682 string_sub(s,"//","/");
1684 pstrcpy(base_name,s);
1685 p = strrchr(base_name,'/');
1692 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1696 if (ChDir(dir) != 0)
1698 DEBUG(0,("couldn't chdir to %s\n",dir));
1704 DEBUG(0,("couldn't getwd for %s\n",dir));
1710 if (p && (p != base_name))
1713 if (strcmp(p+1,".")==0)
1715 if (strcmp(p+1,"..")==0)
1719 if (ChDir(base_name) != 0)
1722 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1726 if (!GetWd(newname))
1729 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1733 if (p && (p != base_name))
1735 pstrcat(newname,"/");
1736 pstrcat(newname,p+1);
1740 int l = strlen(dir2);
1741 if (dir2[l-1] == '/')
1744 if (strncmp(newname,dir2,l) != 0)
1747 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1753 if (newname[l] == '/')
1754 pstrcpy(s,newname + l + 1);
1756 pstrcpy(s,newname+l);
1767 DEBUG(3,("reduced to %s\n",s));
1772 /****************************************************************************
1774 ****************************************************************************/
1775 static void expand_one(char *Mask,int len)
1778 while ((p1 = strchr(Mask,'*')) != NULL)
1780 int lfill = (len+1) - strlen(Mask);
1781 int l1= (p1 - Mask);
1784 memset(tmp+l1,'?',lfill);
1785 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1790 /****************************************************************************
1791 expand a wildcard expression, replacing *s with ?s
1792 ****************************************************************************/
1793 void expand_mask(char *Mask,BOOL doext)
1798 BOOL hasdot = False;
1800 BOOL absolute = (*Mask == '\\');
1802 *mbeg = *mext = *dirpart = *filepart = 0;
1804 /* parse the directory and filename */
1805 if (strchr(Mask,'\\'))
1806 dirname_dos(Mask,dirpart);
1808 filename_dos(Mask,filepart);
1810 pstrcpy(mbeg,filepart);
1811 if ((p1 = strchr(mbeg,'.')) != NULL)
1821 if (strlen(mbeg) > 8)
1823 pstrcpy(mext,mbeg + 8);
1829 pstrcpy(mbeg,"????????");
1830 if ((*mext == 0) && doext && !hasdot)
1831 pstrcpy(mext,"???");
1833 if (strequal(mbeg,"*") && *mext==0)
1841 pstrcpy(Mask,dirpart);
1842 if (*dirpart || absolute) pstrcat(Mask,"\\");
1847 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1851 /****************************************************************************
1852 does a string have any uppercase chars in it?
1853 ****************************************************************************/
1854 BOOL strhasupper(char *s)
1858 #if !defined(KANJI_WIN95_COMPATIBILITY)
1860 * For completeness we should put in equivalent code for code pages
1861 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1862 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1863 * here. They both treat full width ascii characters as case senstive
1864 * filenames (ie. they don't do the work we do here).
1868 if(lp_client_code_page() == KANJI_CODEPAGE)
1870 /* Win95 treats full width ascii characters as case sensitive. */
1871 if (is_shift_jis (*s))
1873 else if (is_kana (*s))
1883 #endif /* KANJI_WIN95_COMPATIBILITY */
1885 int skip = skip_multibyte_char( *s );
1898 /****************************************************************************
1899 does a string have any lowercase chars in it?
1900 ****************************************************************************/
1901 BOOL strhaslower(char *s)
1905 #if !defined(KANJI_WIN95_COMPATIBILITY)
1907 * For completeness we should put in equivalent code for code pages
1908 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1909 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1910 * here. They both treat full width ascii characters as case senstive
1911 * filenames (ie. they don't do the work we do here).
1915 if(lp_client_code_page() == KANJI_CODEPAGE)
1917 /* Win95 treats full width ascii characters as case sensitive. */
1918 if (is_shift_jis (*s))
1920 if (is_sj_upper (s[0], s[1]))
1922 if (is_sj_lower (s[0], s[1]))
1926 else if (is_kana (*s))
1938 #endif /* KANJI_WIN95_COMPATIBILITY */
1940 int skip = skip_multibyte_char( *s );
1953 /****************************************************************************
1954 find the number of chars in a string
1955 ****************************************************************************/
1956 int count_chars(char *s,char c)
1960 #if !defined(KANJI_WIN95_COMPATIBILITY)
1962 * For completeness we should put in equivalent code for code pages
1963 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1964 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1965 * here. They both treat full width ascii characters as case senstive
1966 * filenames (ie. they don't do the work we do here).
1970 if(lp_client_code_page() == KANJI_CODEPAGE)
1972 /* Win95 treats full width ascii characters as case sensitive. */
1975 if (is_shift_jis (*s))
1986 #endif /* KANJI_WIN95_COMPATIBILITY */
1990 int skip = skip_multibyte_char( *s );
2004 /****************************************************************************
2006 ****************************************************************************/
2007 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
2012 pstrcpy(mask2,mask);
2014 if ((mode & aDIR) != 0)
2017 memset(buf+1,' ',11);
2018 if ((p = strchr(mask2,'.')) != NULL)
2021 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
2022 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
2026 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
2028 bzero(buf+21,DIR_STRUCT_SIZE-21);
2029 CVAL(buf,21) = mode;
2030 put_dos_date(buf,22,date);
2031 SSVAL(buf,26,size & 0xFFFF);
2032 SSVAL(buf,28,size >> 16);
2033 StrnCpy(buf+30,fname,12);
2034 if (!case_sensitive)
2036 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2040 /*******************************************************************
2041 close the low 3 fd's and open dev/null in their place
2042 ********************************************************************/
2043 void close_low_fds(void)
2047 close(0); close(1); close(2);
2048 /* try and use up these file descriptors, so silly
2049 library routines writing to stdout etc won't cause havoc */
2051 fd = open("/dev/null",O_RDWR,0);
2052 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2054 DEBUG(0,("Can't open /dev/null\n"));
2058 DEBUG(0,("Didn't get file descriptor %d\n",i));
2064 /****************************************************************************
2065 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2067 if SYSV use O_NDELAY
2069 ****************************************************************************/
2070 int set_blocking(int fd, BOOL set)
2074 #define FLAG_TO_SET O_NONBLOCK
2077 #define FLAG_TO_SET O_NDELAY
2079 #define FLAG_TO_SET FNDELAY
2083 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2085 if(set) /* Turn blocking on - ie. clear nonblock flag */
2086 val &= ~FLAG_TO_SET;
2089 return fcntl( fd, F_SETFL, val);
2094 /****************************************************************************
2096 ****************************************************************************/
2097 int write_socket(int fd,char *buf,int len)
2103 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2104 ret = write_data(fd,buf,len);
2106 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2108 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2109 len, fd, strerror(errno) ));
2114 /****************************************************************************
2116 ****************************************************************************/
2117 int read_udp_socket(int fd,char *buf,int len)
2120 struct sockaddr_in sock;
2123 socklen = sizeof(sock);
2124 bzero((char *)&sock,socklen);
2125 bzero((char *)&lastip,sizeof(lastip));
2126 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2128 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2132 lastip = sock.sin_addr;
2133 lastport = ntohs(sock.sin_port);
2135 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2136 inet_ntoa(lastip), lastport, ret));
2141 /****************************************************************************
2142 read data from a device with a timout in msec.
2143 mincount = if timeout, minimum to read before returning
2144 maxcount = number to be read.
2145 ****************************************************************************/
2146 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2152 struct timeval timeout;
2154 /* just checking .... */
2155 if (maxcnt <= 0) return(0);
2160 if (time_out <= 0) {
2161 if (mincnt == 0) mincnt = maxcnt;
2163 while (nread < mincnt) {
2166 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
2168 readret = read(fd, buf + nread, maxcnt - nread);
2171 readret = read(fd, buf + nread, maxcnt - nread);
2172 #endif /* USE_SSL */
2175 smb_read_error = READ_EOF;
2179 if (readret == -1) {
2180 smb_read_error = READ_ERROR;
2188 /* Most difficult - timeout read */
2189 /* If this is ever called on a disk file and
2190 mincnt is greater then the filesize then
2191 system performance will suffer severely as
2192 select always return true on disk files */
2194 /* Set initial timeout */
2195 timeout.tv_sec = time_out / 1000;
2196 timeout.tv_usec = 1000 * (time_out % 1000);
2198 for (nread=0; nread<mincnt; )
2203 selrtn = sys_select(&fds,&timeout);
2205 /* Check if error */
2207 /* something is wrong. Maybe the socket is dead? */
2208 smb_read_error = READ_ERROR;
2212 /* Did we timeout ? */
2214 smb_read_error = READ_TIMEOUT;
2220 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
2222 readret = read(fd, buf + nread, maxcnt - nread);
2225 readret = read(fd, buf+nread, maxcnt-nread);
2226 #endif /* USE_SSL */
2229 /* we got EOF on the file descriptor */
2230 smb_read_error = READ_EOF;
2234 if (readret == -1) {
2235 /* the descriptor is probably dead */
2236 smb_read_error = READ_ERROR;
2243 /* Return the number we got */
2247 /****************************************************************************
2248 read data from the client. Maxtime is in milliseconds
2249 ****************************************************************************/
2250 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2255 struct timeval timeout;
2260 timeout.tv_sec = maxtime / 1000;
2261 timeout.tv_usec = (maxtime % 1000) * 1000;
2263 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2265 if (!FD_ISSET(fd,&fds))
2268 nread = read_udp_socket(fd, buffer, bufsize);
2270 /* return the number got */
2274 /*******************************************************************
2275 find the difference in milliseconds between two struct timeval
2277 ********************************************************************/
2278 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2280 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2281 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2284 /****************************************************************************
2285 send a keepalive packet (rfc1002)
2286 ****************************************************************************/
2287 BOOL send_keepalive(int client)
2289 unsigned char buf[4];
2292 buf[1] = buf[2] = buf[3] = 0;
2294 return(write_data(client,(char *)buf,4) == 4);
2299 /****************************************************************************
2300 read data from the client, reading exactly N bytes.
2301 ****************************************************************************/
2302 int read_data(int fd,char *buffer,int N)
2313 ret = SSL_read(ssl, buffer + total, N - total);
2315 ret = read(fd,buffer + total,N - total);
2318 ret = read(fd,buffer + total,N - total);
2319 #endif /* USE_SSL */
2323 smb_read_error = READ_EOF;
2328 smb_read_error = READ_ERROR;
2337 /****************************************************************************
2339 ****************************************************************************/
2340 int write_data(int fd,char *buffer,int N)
2349 ret = SSL_write(ssl,buffer + total,N - total);
2351 ret = write(fd,buffer + total,N - total);
2354 ret = write(fd,buffer + total,N - total);
2355 #endif /* USE_SSL */
2357 if (ret == -1) return -1;
2358 if (ret == 0) return total;
2366 /****************************************************************************
2367 transfer some data between two fd's
2368 ****************************************************************************/
2369 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2371 static char *buf=NULL;
2376 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2379 size = lp_readsize();
2380 size = MAX(size,1024);
2383 while (!buf && size>0) {
2384 buf = (char *)Realloc(buf,size+8);
2385 if (!buf) size /= 2;
2389 DEBUG(0,("Can't allocate transfer buffer!\n"));
2393 abuf = buf + (align%8);
2400 int s = MIN(n,size);
2405 if (header && (headlen >= MIN(s,1024))) {
2415 if (header && headlen > 0)
2417 ret = MIN(headlen,size);
2418 memcpy(buf1,header,ret);
2421 if (headlen <= 0) header = NULL;
2425 ret += read(infd,buf1+ret,s-ret);
2429 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2430 if (ret2 > 0) total += ret2;
2431 /* if we can't write then dump excess data */
2433 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2435 if (ret <= 0 || ret2 != ret)
2443 /****************************************************************************
2444 read 4 bytes of a smb packet and return the smb length of the packet
2445 store the result in the buffer
2446 This version of the function will return a length of zero on receiving
2448 ****************************************************************************/
2449 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2451 int len=0, msg_type;
2457 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2459 ok = (read_data(fd,inbuf,4) == 4);
2464 len = smb_len(inbuf);
2465 msg_type = CVAL(inbuf,0);
2467 if (msg_type == 0x85)
2468 DEBUG(5,("Got keepalive packet\n"));
2471 DEBUG(10,("got smb length of %d\n",len));
2476 /****************************************************************************
2477 read 4 bytes of a smb packet and return the smb length of the packet
2478 store the result in the buffer. This version of the function will
2479 never return a session keepalive (length of zero).
2480 ****************************************************************************/
2481 int read_smb_length(int fd,char *inbuf,int timeout)
2487 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2492 /* Ignore session keepalives. */
2493 if(CVAL(inbuf,0) != 0x85)
2500 /****************************************************************************
2501 read an smb from a fd. Note that the buffer *MUST* be of size
2502 BUFFER_SIZE+SAFETY_MARGIN.
2503 The timeout is in milli seconds.
2505 This function will return on a
2506 receipt of a session keepalive packet.
2507 ****************************************************************************/
2508 BOOL receive_smb(int fd,char *buffer, int timeout)
2514 bzero(buffer,smb_size + 100);
2516 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2520 if (len > BUFFER_SIZE) {
2521 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2522 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2527 ret = read_data(fd,buffer+4,len);
2529 smb_read_error = READ_ERROR;
2536 /****************************************************************************
2537 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2538 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2539 The timeout is in milli seconds
2541 This is exactly the same as receive_smb except that it never returns
2542 a session keepalive packet (just as receive_smb used to do).
2543 receive_smb was changed to return keepalives as the oplock processing means this call
2544 should never go into a blocking read.
2545 ****************************************************************************/
2547 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2553 ret = receive_smb(fd, buffer, timeout);
2558 /* Ignore session keepalive packets. */
2559 if(CVAL(buffer,0) != 0x85)
2565 /****************************************************************************
2566 read a message from a udp fd.
2567 The timeout is in milli seconds
2568 ****************************************************************************/
2569 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2571 struct sockaddr_in from;
2572 int fromlen = sizeof(from);
2586 to.tv_sec = timeout / 1000;
2587 to.tv_usec = (timeout % 1000) * 1000;
2589 selrtn = sys_select(&fds,&to);
2591 /* Check if error */
2594 /* something is wrong. Maybe the socket is dead? */
2595 smb_read_error = READ_ERROR;
2599 /* Did we timeout ? */
2602 smb_read_error = READ_TIMEOUT;
2608 * Read a loopback udp message.
2610 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2611 buffer_len - UDP_CMD_HEADER_LEN, 0,
2612 (struct sockaddr *)&from, &fromlen);
2616 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2620 /* Validate message length. */
2621 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2623 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2625 buffer_len - UDP_CMD_HEADER_LEN));
2629 /* Validate message from address (must be localhost). */
2630 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2632 DEBUG(0,("receive_local_message: invalid 'from' address \
2633 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2637 /* Setup the message header */
2638 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2639 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2644 /****************************************************************************
2645 structure to hold a linked list of local messages.
2647 ****************************************************************************/
2649 typedef struct _message_list {
2650 struct _message_list *msg_next;
2653 } pending_message_list;
2655 static pending_message_list *smb_msg_head = NULL;
2657 /****************************************************************************
2658 Function to push a linked list of local messages ready
2660 ****************************************************************************/
2662 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2664 pending_message_list *msg = (pending_message_list *)
2665 malloc(sizeof(pending_message_list));
2669 DEBUG(0,("push_message: malloc fail (1)\n"));
2673 msg->msg_buf = (char *)malloc(msg_len);
2674 if(msg->msg_buf == NULL)
2676 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2681 memcpy(msg->msg_buf, buf, msg_len);
2682 msg->msg_len = msg_len;
2684 msg->msg_next = *pml;
2690 /****************************************************************************
2691 Function to push a linked list of local smb messages ready
2693 ****************************************************************************/
2695 BOOL push_smb_message(char *buf, int msg_len)
2697 return push_local_message(&smb_msg_head, buf, msg_len);
2700 /****************************************************************************
2701 Do a select on an two fd's - with timeout.
2703 If a local udp message has been pushed onto the
2704 queue (this can only happen during oplock break
2705 processing) return this first.
2707 If a pending smb message has been pushed onto the
2708 queue (this can only happen during oplock break
2709 processing) return this next.
2711 If the first smbfd is ready then read an smb from it.
2712 if the second (loopback UDP) fd is ready then read a message
2713 from it and setup the buffer header to identify the length
2715 Returns False on timeout or error.
2718 The timeout is in milli seconds
2719 ****************************************************************************/
2720 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2721 char *buffer, int buffer_len,
2722 int timeout, BOOL *got_smb)
2733 * Check to see if we already have a message on the smb queue.
2734 * If so - copy and return it.
2739 pending_message_list *msg = smb_msg_head;
2740 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2741 smb_msg_head = msg->msg_next;
2743 /* Free the message we just copied. */
2744 free((char *)msg->msg_buf);
2748 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2754 FD_SET(oplock_fd,&fds);
2756 to.tv_sec = timeout / 1000;
2757 to.tv_usec = (timeout % 1000) * 1000;
2759 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2761 /* Check if error */
2763 /* something is wrong. Maybe the socket is dead? */
2764 smb_read_error = READ_ERROR;
2768 /* Did we timeout ? */
2770 smb_read_error = READ_TIMEOUT;
2774 if (FD_ISSET(smbfd,&fds))
2777 return receive_smb(smbfd, buffer, 0);
2781 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2785 /****************************************************************************
2787 ****************************************************************************/
2788 BOOL send_smb(int fd,char *buffer)
2792 len = smb_len(buffer) + 4;
2794 while (nwritten < len)
2796 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2799 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2811 /****************************************************************************
2812 find a pointer to a netbios name
2813 ****************************************************************************/
2814 char *name_ptr(char *buf,int ofs)
2816 unsigned char c = *(unsigned char *)(buf+ofs);
2818 if ((c & 0xC0) == 0xC0)
2822 memcpy(p,buf+ofs,2);
2825 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2832 /****************************************************************************
2833 extract a netbios name from a buf
2834 ****************************************************************************/
2835 int name_extract(char *buf,int ofs,char *name)
2837 char *p = name_ptr(buf,ofs);
2838 int d = PTR_DIFF(p,buf+ofs);
2840 if (d < -50 || d > 50) return(0);
2841 return(name_interpret(p,name));
2844 /****************************************************************************
2845 return the total storage length of a mangled name
2846 ****************************************************************************/
2847 int name_len( char *s )
2851 /* If the two high bits of the byte are set, return 2. */
2852 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2855 /* Add up the length bytes. */
2856 for( len = 1; (*s); s += (*s) + 1 )
2864 /****************************************************************************
2865 send a single packet to a port on another machine
2866 ****************************************************************************/
2867 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2871 struct sockaddr_in sock_out;
2876 /* create a socket to write to */
2877 out_fd = socket(AF_INET, type, 0);
2880 DEBUG(0,("socket failed"));
2884 /* set the address and port */
2885 bzero((char *)&sock_out,sizeof(sock_out));
2886 putip((char *)&sock_out.sin_addr,(char *)&ip);
2887 sock_out.sin_port = htons( port );
2888 sock_out.sin_family = AF_INET;
2891 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2892 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2895 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2898 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2899 inet_ntoa(ip),port,strerror(errno)));
2905 /*******************************************************************
2906 sleep for a specified number of milliseconds
2907 ********************************************************************/
2911 struct timeval tval,t1,t2;
2918 tval.tv_sec = (t-tdiff)/1000;
2919 tval.tv_usec = 1000*((t-tdiff)%1000);
2923 sys_select(&fds,&tval);
2926 tdiff = TvalDiff(&t1,&t2);
2930 /****************************************************************************
2931 check if a string is part of a list
2932 ****************************************************************************/
2933 BOOL in_list(char *s,char *list,BOOL casesensitive)
2938 if (!list) return(False);
2940 while (next_token(&p,tok,LIST_SEP))
2942 if (casesensitive) {
2943 if (strcmp(tok,s) == 0)
2946 if (StrCaseCmp(tok,s) == 0)
2953 /* this is used to prevent lots of mallocs of size 1 */
2954 static char *null_string = NULL;
2956 /****************************************************************************
2957 set a string value, allocing the space for the string
2958 ****************************************************************************/
2959 BOOL string_init(char **dest,char *src)
2970 null_string = (char *)malloc(1);
2973 *dest = null_string;
2977 (*dest) = (char *)malloc(l+1);
2978 if ((*dest) == NULL) {
2979 DEBUG(0,("Out of memory in string_init\n"));
2988 /****************************************************************************
2990 ****************************************************************************/
2991 void string_free(char **s)
2993 if (!s || !(*s)) return;
2994 if (*s == null_string)
3000 /****************************************************************************
3001 set a string value, allocing the space for the string, and deallocating any
3003 ****************************************************************************/
3004 BOOL string_set(char **dest,char *src)
3008 return(string_init(dest,src));
3011 /****************************************************************************
3012 substitute a string for a pattern in another string. Make sure there is
3015 This routine looks for pattern in s and replaces it with
3016 insert. It may do multiple replacements.
3018 return True if a substitution was done.
3019 ****************************************************************************/
3020 BOOL string_sub(char *s,char *pattern,char *insert)
3026 if (!insert || !pattern || !s) return(False);
3029 lp = strlen(pattern);
3030 li = strlen(insert);
3032 if (!*pattern) return(False);
3034 while (lp <= ls && (p = strstr(s,pattern)))
3037 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
3038 memcpy(p,insert,li);
3045 /*********************************************************
3046 * Recursive routine that is called by mask_match.
3047 * Does the actual matching. Returns True if matched,
3049 *********************************************************/
3051 BOOL do_match(char *str, char *regexp, int case_sig)
3055 for( p = regexp; *p && *str; ) {
3062 /* Look for a character matching
3063 the one after the '*' */
3066 return True; /* Automatic match */
3068 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
3070 /* Now eat all characters that match, as
3071 we want the *last* character to match. */
3072 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
3074 str--; /* We've eaten the match char after the '*' */
3075 if(do_match(str,p,case_sig)) {
3092 if(toupper(*str) != toupper(*p)) {
3104 if (!*p && str[0] == '.' && str[1] == 0) {
3108 if (!*str && *p == '?') {
3114 if(!*str && (*p == '*' && p[1] == '\0')) {
3122 /*********************************************************
3123 * Routine to match a given string with a regexp - uses
3124 * simplified regexp that takes * and ? only. Case can be
3125 * significant or not.
3126 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
3127 *********************************************************/
3129 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3132 pstring t_pattern, t_filename, te_pattern, te_filename;
3133 fstring ebase,eext,sbase,sext;
3135 BOOL matched = False;
3137 /* Make local copies of str and regexp */
3138 pstrcpy(t_pattern,regexp);
3139 pstrcpy(t_filename,str);
3143 * Not sure if this is a good idea. JRA.
3145 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
3150 if (!strchr(t_filename,'.')) {
3151 pstrcat(t_filename,".");
3155 /* Remove any *? and ** as they are meaningless */
3156 string_sub(t_pattern, "*?", "*");
3157 string_sub(t_pattern, "**", "*");
3159 if (strequal(t_pattern,"*"))
3162 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
3166 * Match each component of the regexp, split up by '.'
3169 char *fp, *rp, *cp2, *cp1;
3170 BOOL last_wcard_was_star = False;
3171 int num_path_components, num_regexp_components;
3173 pstrcpy(te_pattern,t_pattern);
3174 pstrcpy(te_filename,t_filename);
3176 * Remove multiple "*." patterns.
3178 string_sub(te_pattern, "*.*.", "*.");
3179 num_regexp_components = count_chars(te_pattern, '.');
3180 num_path_components = count_chars(te_filename, '.');
3183 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
3185 if(num_regexp_components == 0)
3186 matched = do_match( te_filename, te_pattern, case_sig);
3188 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
3189 fp = strchr(cp2, '.');
3192 rp = strchr(cp1, '.');
3196 if(cp1[strlen(cp1)-1] == '*')
3197 last_wcard_was_star = True;
3199 last_wcard_was_star = False;
3201 if(!do_match(cp2, cp1, case_sig))
3204 cp1 = rp ? rp + 1 : NULL;
3205 cp2 = fp ? fp + 1 : "";
3207 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3208 /* Eat the extra path components. */
3211 for(i = 0; i < num_path_components - num_regexp_components; i++) {
3212 fp = strchr(cp2, '.');
3216 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3217 cp2 = fp ? fp + 1 : "";
3220 cp2 = fp ? fp + 1 : "";
3222 num_path_components -= i;
3225 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3230 /* -------------------------------------------------
3231 * Behaviour of Win95
3232 * for 8.3 filenames and 8.3 Wildcards
3233 * -------------------------------------------------
3235 if (strequal (t_filename, ".")) {
3237 * Patterns: *.* *. ?. ? are valid
3240 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3241 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3243 } else if (strequal (t_filename, "..")) {
3245 * Patterns: *.* *. ?. ? *.? are valid
3248 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3249 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3250 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3254 if ((p = strrchr (t_pattern, '.'))) {
3256 * Wildcard has a suffix.
3259 fstrcpy (ebase, t_pattern);
3261 fstrcpy (eext, p + 1);
3263 /* pattern ends in DOT: treat as if there is no DOT */
3265 if (strequal (ebase, "*"))
3270 * No suffix for wildcard.
3272 fstrcpy (ebase, t_pattern);
3276 p = strrchr (t_filename, '.');
3277 if (p && (p[1] == 0) ) {
3279 * Filename has an extension of '.' only.
3281 *p = 0; /* nuke dot at end of string */
3282 p = 0; /* and treat it as if there is no extension */
3287 * Filename has an extension.
3290 fstrcpy (sbase, t_filename);
3291 fstrcpy (sext, p + 1);
3293 matched = do_match(sbase, ebase, case_sig)
3294 && do_match(sext, eext, case_sig);
3296 /* pattern has no extension */
3297 /* Really: match complete filename with pattern ??? means exactly 3 chars */
3298 matched = do_match(str, ebase, case_sig);
3302 * Filename has no extension.
3304 fstrcpy (sbase, t_filename);
3307 /* pattern has extension */
3308 matched = do_match(sbase, ebase, case_sig)
3309 && do_match(sext, eext, case_sig);
3311 matched = do_match(sbase, ebase, case_sig);
3312 #ifdef EMULATE_WEIRD_W95_MATCHING
3314 * Even Microsoft has some problems
3315 * Behaviour Win95 -> local disk
3316 * is different from Win95 -> smb drive from Nt 4.0
3317 * This branch would reflect the Win95 local disk behaviour
3320 /* a? matches aa and a in w95 */
3321 fstrcat (sbase, ".");
3322 matched = do_match(sbase, ebase, case_sig);
3330 DEBUG(8,("mask_match returning %d\n", matched));
3335 /****************************************************************************
3336 become a daemon, discarding the controlling terminal
3337 ****************************************************************************/
3338 void become_daemon(void)
3340 #ifndef NO_FORK_DEBUG
3344 /* detach from the terminal */
3347 #else /* USE_SETSID */
3350 int i = open("/dev/tty", O_RDWR);
3353 ioctl(i, (int) TIOCNOTTY, (char *)0);
3357 #endif /* TIOCNOTTY */
3358 #endif /* USE_SETSID */
3359 /* Close fd's 0,1,2. Needed if started by rsh */
3361 #endif /* NO_FORK_DEBUG */
3365 /****************************************************************************
3366 put up a yes/no prompt
3367 ****************************************************************************/
3373 if (!fgets(ans,sizeof(ans)-1,stdin))
3376 if (*ans == 'y' || *ans == 'Y')
3382 /****************************************************************************
3383 read a line from a file with possible \ continuation chars.
3384 Blanks at the start or end of a line are stripped.
3385 The string will be allocated if s2 is NULL
3386 ****************************************************************************/
3387 char *fgets_slash(char *s2,int maxlen,FILE *f)
3392 BOOL start_of_line = True;
3399 maxlen = MIN(maxlen,8);
3400 s = (char *)Realloc(s,maxlen);
3403 if (!s || maxlen < 2) return(NULL);
3407 while (len < maxlen-1)
3415 while (len > 0 && s[len-1] == ' ')
3419 if (len > 0 && s[len-1] == '\\')
3422 start_of_line = True;
3427 if (len <= 0 && !s2)
3429 return(len>0?s:NULL);
3434 start_of_line = False;
3438 if (!s2 && len > maxlen-3)
3441 s = (char *)Realloc(s,maxlen);
3442 if (!s) return(NULL);
3450 /****************************************************************************
3451 set the length of a file from a filedescriptor.
3452 Returns 0 on success, -1 on failure.
3453 ****************************************************************************/
3454 int set_filelen(int fd, long len)
3456 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3457 extend a file with ftruncate. Provide alternate implementation
3460 #if FTRUNCATE_CAN_EXTEND
3461 return ftruncate(fd, len);
3465 long currpos = lseek(fd, 0L, SEEK_CUR);
3469 /* Do an fstat to see if the file is longer than
3470 the requested size (call ftruncate),
3471 or shorter, in which case seek to len - 1 and write 1
3473 if(fstat(fd, &st)<0)
3477 if (S_ISFIFO(st.st_mode)) return 0;
3480 if(st.st_size == len)
3482 if(st.st_size > len)
3483 return ftruncate(fd, len);
3485 if(lseek(fd, len-1, SEEK_SET) != len -1)
3487 if(write(fd, &c, 1)!=1)
3489 /* Seek to where we were */
3490 lseek(fd, currpos, SEEK_SET);
3496 /****************************************************************************
3497 return the byte checksum of some data
3498 ****************************************************************************/
3499 int byte_checksum(char *buf,int len)
3501 unsigned char *p = (unsigned char *)buf;
3511 /****************************************************************************
3512 this is a version of setbuffer() for those machines that only have setvbuf
3513 ****************************************************************************/
3514 void setbuffer(FILE *f,char *buf,int bufsize)
3516 setvbuf(f,buf,_IOFBF,bufsize);
3521 /****************************************************************************
3522 parse out a directory name from a path name. Assumes dos style filenames.
3523 ****************************************************************************/
3524 char *dirname_dos(char *path,char *buf)
3526 char *p = strrchr(path,'\\');
3541 /****************************************************************************
3542 parse out a filename from a path name. Assumes dos style filenames.
3543 ****************************************************************************/
3544 static char *filename_dos(char *path,char *buf)
3546 char *p = strrchr(path,'\\');
3558 /****************************************************************************
3559 expand a pointer to be a particular size
3560 ****************************************************************************/
3561 void *Realloc(void *p,int size)
3567 DEBUG(5,("Realloc asked for 0 bytes\n"));
3572 ret = (void *)malloc(size);
3574 ret = (void *)realloc(p,size);
3577 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3583 /****************************************************************************
3585 ****************************************************************************/
3586 char *strdup(char *s)
3590 if (!s) return(NULL);
3591 ret = (char *)malloc((len = strlen(s))+1);
3592 if (!ret) return(NULL);
3593 safe_strcpy(ret,s,len);
3599 /****************************************************************************
3600 Signal handler for SIGPIPE (write on a disconnected socket)
3601 ****************************************************************************/
3604 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3608 /****************************************************************************
3609 get my own name and IP
3610 ****************************************************************************/
3611 BOOL get_myname(char *my_name,struct in_addr *ip)
3618 /* get my host name */
3619 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3621 DEBUG(0,("gethostname failed\n"));
3626 if ((hp = Get_Hostbyname(hostname)) == 0)
3628 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3634 /* split off any parts after an initial . */
3635 char *p = strchr(hostname,'.');
3638 fstrcpy(my_name,hostname);
3642 putip((char *)ip,(char *)hp->h_addr);
3648 /****************************************************************************
3649 true if two IP addresses are equal
3650 ****************************************************************************/
3651 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3654 a1 = ntohl(ip1.s_addr);
3655 a2 = ntohl(ip2.s_addr);
3660 /****************************************************************************
3661 open a socket of the specified type, port and address for incoming data
3662 ****************************************************************************/
3663 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3666 struct sockaddr_in sock;
3670 /* get my host name */
3671 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3672 { DEBUG(0,("gethostname failed\n")); return -1; }
3675 if ((hp = Get_Hostbyname(host_name)) == 0)
3677 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3681 bzero((char *)&sock,sizeof(sock));
3682 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3683 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3684 sock.sin_len = sizeof(sock);
3686 sock.sin_port = htons( port );
3687 sock.sin_family = hp->h_addrtype;
3688 sock.sin_addr.s_addr = socket_addr;
3689 res = socket(hp->h_addrtype, type, 0);
3691 { DEBUG(0,("socket failed\n")); return -1; }
3695 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3698 /* now we've got a socket - we need to bind it */
3699 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3702 if (port == SMB_PORT || port == NMB_PORT)
3703 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3704 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3707 if (dlevel > 0 && port < 1000)
3710 if (port >= 1000 && port < 9000)
3711 return(open_socket_in(type,port+1,dlevel,socket_addr));
3716 DEBUG(3,("bind succeeded on port %d\n",port));
3722 /****************************************************************************
3723 create an outgoing socket
3724 **************************************************************************/
3725 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3727 struct sockaddr_in sock_out;
3729 int connect_loop = 250; /* 250 milliseconds */
3730 int loops = (timeout * 1000) / connect_loop;
3732 /* create a socket to write to */
3733 res = socket(PF_INET, type, 0);
3735 { DEBUG(0,("socket error\n")); return -1; }
3737 if (type != SOCK_STREAM) return(res);
3739 bzero((char *)&sock_out,sizeof(sock_out));
3740 putip((char *)&sock_out.sin_addr,(char *)addr);
3742 sock_out.sin_port = htons( port );
3743 sock_out.sin_family = PF_INET;
3745 /* set it non-blocking */
3746 set_blocking(res,False);
3748 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3750 /* and connect it to the destination */
3752 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3754 /* Some systems return EAGAIN when they mean EINPROGRESS */
3755 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3756 errno == EAGAIN) && loops--) {
3757 msleep(connect_loop);
3761 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3763 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3769 if (ret < 0 && errno == EISCONN) {
3776 DEBUG(1,("error connecting to %s:%d (%s)\n",
3777 inet_ntoa(*addr),port,strerror(errno)));
3782 /* set it blocking again */
3783 set_blocking(res,True);
3789 /****************************************************************************
3790 interpret a protocol description string, with a default
3791 ****************************************************************************/
3792 int interpret_protocol(char *str,int def)
3794 if (strequal(str,"NT1"))
3795 return(PROTOCOL_NT1);
3796 if (strequal(str,"LANMAN2"))
3797 return(PROTOCOL_LANMAN2);
3798 if (strequal(str,"LANMAN1"))
3799 return(PROTOCOL_LANMAN1);
3800 if (strequal(str,"CORE"))
3801 return(PROTOCOL_CORE);
3802 if (strequal(str,"COREPLUS"))
3803 return(PROTOCOL_COREPLUS);
3804 if (strequal(str,"CORE+"))
3805 return(PROTOCOL_COREPLUS);
3807 DEBUG(0,("Unrecognised protocol level %s\n",str));
3812 /****************************************************************************
3813 interpret a security level
3814 ****************************************************************************/
3815 int interpret_security(char *str,int def)
3817 if (strequal(str,"SERVER"))
3819 if (strequal(str,"USER"))
3821 if (strequal(str,"SHARE"))
3824 DEBUG(0,("Unrecognised security level %s\n",str));
3830 /****************************************************************************
3831 interpret an internet address or name into an IP address in 4 byte form
3832 ****************************************************************************/
3833 uint32 interpret_addr(char *str)
3838 BOOL pure_address = True;
3840 if (strcmp(str,"0.0.0.0") == 0) return(0);
3841 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3843 for (i=0; pure_address && str[i]; i++)
3844 if (!(isdigit(str[i]) || str[i] == '.'))
3845 pure_address = False;
3847 /* if it's in the form of an IP address then get the lib to interpret it */
3849 res = inet_addr(str);
3851 /* otherwise assume it's a network name of some sort and use
3853 if ((hp = Get_Hostbyname(str)) == 0) {
3854 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3857 if(hp->h_addr == NULL) {
3858 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3861 putip((char *)&res,(char *)hp->h_addr);
3864 if (res == (uint32)-1) return(0);
3869 /*******************************************************************
3870 a convenient addition to interpret_addr()
3871 ******************************************************************/
3872 struct in_addr *interpret_addr2(char *str)
3874 static struct in_addr ret;
3875 uint32 a = interpret_addr(str);
3880 /*******************************************************************
3881 check if an IP is the 0.0.0.0
3882 ******************************************************************/
3883 BOOL zero_ip(struct in_addr ip)
3886 putip((char *)&a,(char *)&ip);
3891 /*******************************************************************
3892 matchname - determine if host name matches IP address
3893 ******************************************************************/
3894 static BOOL matchname(char *remotehost,struct in_addr addr)
3899 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3900 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3905 * Make sure that gethostbyname() returns the "correct" host name.
3906 * Unfortunately, gethostbyname("localhost") sometimes yields
3907 * "localhost.domain". Since the latter host name comes from the
3908 * local DNS, we just have to trust it (all bets are off if the local
3909 * DNS is perverted). We always check the address list, though.
3912 if (strcasecmp(remotehost, hp->h_name)
3913 && strcasecmp(remotehost, "localhost")) {
3914 DEBUG(0,("host name/name mismatch: %s != %s",
3915 remotehost, hp->h_name));
3919 /* Look up the host address in the address list we just got. */
3920 for (i = 0; hp->h_addr_list[i]; i++) {
3921 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3926 * The host name does not map to the original host address. Perhaps
3927 * someone has compromised a name server. More likely someone botched
3928 * it, but that could be dangerous, too.
3931 DEBUG(0,("host name/address mismatch: %s != %s",
3932 inet_ntoa(addr), hp->h_name));
3936 /*******************************************************************
3937 Reset the 'done' variables so after a client process is created
3938 from a fork call these calls will be re-done. This should be
3939 expanded if more variables need reseting.
3940 ******************************************************************/
3942 static BOOL global_client_name_done = False;
3943 static BOOL global_client_addr_done = False;
3945 void reset_globals_after_fork(void)
3947 global_client_name_done = False;
3948 global_client_addr_done = False;
3951 * Re-seed the random crypto generator, so all smbd's
3952 * started from the same parent won't generate the same
3956 unsigned char dummy;
3957 generate_random_buffer( &dummy, 1, True);
3961 /*******************************************************************
3962 return the DNS name of the client
3963 ******************************************************************/
3964 char *client_name(int fd)
3967 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3968 int length = sizeof(sa);
3969 static pstring name_buf;
3971 static int last_fd=-1;
3973 if (global_client_name_done && last_fd == fd)
3977 global_client_name_done = False;
3979 pstrcpy(name_buf,"UNKNOWN");
3985 if (getpeername(fd, &sa, &length) < 0) {
3986 DEBUG(0,("getpeername failed\n"));
3990 /* Look up the remote host name. */
3991 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3992 sizeof(sockin->sin_addr),
3994 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3995 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3997 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3998 if (!matchname(name_buf, sockin->sin_addr)) {
3999 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
4000 pstrcpy(name_buf,"UNKNOWN");
4003 global_client_name_done = True;
4007 /*******************************************************************
4008 return the IP addr of the client as a string
4009 ******************************************************************/
4010 char *client_addr(int fd)
4013 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
4014 int length = sizeof(sa);
4015 static fstring addr_buf;
4016 static int last_fd = -1;
4018 if (global_client_addr_done && fd == last_fd)
4022 global_client_addr_done = False;
4024 fstrcpy(addr_buf,"0.0.0.0");
4030 if (getpeername(fd, &sa, &length) < 0) {
4031 DEBUG(0,("getpeername failed\n"));
4035 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
4037 global_client_addr_done = True;
4041 /*******************************************************************
4042 Patch from jkf@soton.ac.uk
4043 Split Luke's automount_server into YP lookup and string splitter
4044 so can easily implement automount_path().
4045 As we may end up doing both, cache the last YP result.
4046 *******************************************************************/
4048 #if (defined(NETGROUP) && defined(AUTOMOUNT))
4050 static char *automount_lookup(char *user_name)
4052 static fstring last_key = "";
4053 static pstring last_value = "";
4055 char *nis_map = (char *)lp_nis_home_map_name();
4057 char nis_domain[NIS_MAXNAMELEN + 1];
4058 char buffer[NIS_MAXATTRVAL + 1];
4063 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
4064 nis_domain[NIS_MAXNAMELEN] = '\0';
4066 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
4068 if (strcmp(user_name, last_key))
4070 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
4071 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
4073 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
4075 if (result->status != NIS_SUCCESS)
4077 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
4078 fstrcpy(last_key, ""); pstrcpy(last_value, "");
4082 object = result->objects.objects_val;
4083 if (object->zo_data.zo_type == ENTRY_OBJ)
4085 entry = &object->zo_data.objdata_u.en_data;
4086 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
4087 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
4089 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
4090 string_sub(last_value, "&", user_name);
4091 fstrcpy(last_key, user_name);
4095 nis_freeresult(result);
4097 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
4100 #else /* NISPLUS_HOME */
4101 static char *automount_lookup(char *user_name)
4103 static fstring last_key = "";
4104 static pstring last_value = "";
4106 int nis_error; /* returned by yp all functions */
4107 char *nis_result; /* yp_match inits this */
4108 int nis_result_len; /* and set this */
4109 char *nis_domain; /* yp_get_default_domain inits this */
4110 char *nis_map = (char *)lp_nis_home_map_name();
4112 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
4114 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
4118 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
4120 if (!strcmp(user_name, last_key))
4122 nis_result = last_value;
4123 nis_result_len = strlen(last_value);
4128 if ((nis_error = yp_match(nis_domain, nis_map,
4129 user_name, strlen(user_name),
4130 &nis_result, &nis_result_len)) != 0)
4132 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
4133 yperr_string(nis_error), user_name, nis_map));
4135 if (!nis_error && nis_result_len >= sizeof(pstring))
4137 nis_result_len = sizeof(pstring)-1;
4139 fstrcpy(last_key, user_name);
4140 strncpy(last_value, nis_result, nis_result_len);
4141 last_value[nis_result_len] = '\0';
4144 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
4147 #endif /* NISPLUS_HOME */
4150 /*******************************************************************
4151 Patch from jkf@soton.ac.uk
4152 This is Luke's original function with the NIS lookup code
4153 moved out to a separate function.
4154 *******************************************************************/
4156 char *automount_server(char *user_name)
4158 static pstring server_name;
4160 /* use the local machine name as the default */
4161 /* this will be the default if AUTOMOUNT is not used or fails */
4162 pstrcpy(server_name, local_machine);
4164 #if (defined(NETGROUP) && defined (AUTOMOUNT))
4166 if (lp_nis_home_map())
4168 int home_server_len;
4169 char *automount_value = automount_lookup(user_name);
4170 home_server_len = strcspn(automount_value,":");
4171 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
4172 if (home_server_len > sizeof(pstring))
4174 home_server_len = sizeof(pstring);
4176 strncpy(server_name, automount_value, home_server_len);
4177 server_name[home_server_len] = '\0';
4181 DEBUG(4,("Home server: %s\n", server_name));
4186 /*******************************************************************
4187 Patch from jkf@soton.ac.uk
4188 Added this to implement %p (NIS auto-map version of %H)
4189 *******************************************************************/
4191 char *automount_path(char *user_name)
4193 static pstring server_path;
4195 /* use the passwd entry as the default */
4196 /* this will be the default if AUTOMOUNT is not used or fails */
4197 /* pstrcpy() copes with get_home_dir() returning NULL */
4198 pstrcpy(server_path, get_home_dir(user_name));
4200 #if (defined(NETGROUP) && defined (AUTOMOUNT))
4202 if (lp_nis_home_map())
4204 char *home_path_start;
4205 char *automount_value = automount_lookup(user_name);
4206 home_path_start = strchr(automount_value,':');
4207 if (home_path_start != NULL)
4209 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
4210 home_path_start?(home_path_start+1):""));
4211 pstrcpy(server_path, home_path_start+1);
4216 DEBUG(4,("Home server path: %s\n", server_path));
4222 /*******************************************************************
4223 sub strings with useful parameters
4224 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4225 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4226 ********************************************************************/
4227 void standard_sub_basic(char *str)
4231 struct passwd *pass;
4232 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4234 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4240 if ((pass = Get_Pwnam(username,False))!=NULL)
4242 string_sub(p,"%G",gidtoname(pass->pw_gid));
4250 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4251 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4252 case 'L' : string_sub(p,"%L", local_machine); break;
4253 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4254 case 'R' : string_sub(p,"%R", remote_proto); break;
4255 case 'T' : string_sub(p,"%T", timestring()); break;
4256 case 'U' : string_sub(p,"%U", username); break;
4257 case 'a' : string_sub(p,"%a", remote_arch); break;
4260 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4261 string_sub(p,"%d", pidstr);
4264 case 'h' : string_sub(p,"%h", myhostname); break;
4265 case 'm' : string_sub(p,"%m", remote_machine); break;
4266 case 'v' : string_sub(p,"%v", VERSION); break;
4267 case '$' : /* Expand environment variables */
4269 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4280 if ((q = strchr(p,')')) == NULL)
4282 DEBUG(0,("standard_sub_basic: Unterminated environment \
4283 variable [%s]\n", p));
4289 copylen = MIN((q-r),(sizeof(envname)-1));
4290 strncpy(envname,r,copylen);
4291 envname[copylen] = '\0';
4293 if ((envval = getenv(envname)) == NULL)
4295 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4301 copylen = MIN((q+1-p),(sizeof(envname)-1));
4302 strncpy(envname,p,copylen);
4303 envname[copylen] = '\0';
4304 string_sub(p,envname,envval);
4307 case '\0': p++; break; /* don't run off end if last character is % */
4308 default : p+=2; break;
4314 /*******************************************************************
4315 are two IPs on the same subnet?
4316 ********************************************************************/
4317 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4319 uint32 net1,net2,nmask;
4321 nmask = ntohl(mask.s_addr);
4322 net1 = ntohl(ip1.s_addr);
4323 net2 = ntohl(ip2.s_addr);
4325 return((net1 & nmask) == (net2 & nmask));
4329 /*******************************************************************
4330 write a string in unicoode format
4331 ********************************************************************/
4332 int PutUniCode(char *dst,char *src)
4336 dst[ret++] = src[0];
4345 /****************************************************************************
4346 a wrapper for gethostbyname() that tries with all lower and all upper case
4347 if the initial name fails
4348 ****************************************************************************/
4349 struct hostent *Get_Hostbyname(char *name)
4351 char *name2 = strdup(name);
4352 struct hostent *ret;
4356 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4362 * This next test is redundent and causes some systems (with
4363 * broken isalnum() calls) problems.
4368 if (!isalnum(*name2))
4375 ret = sys_gethostbyname(name2);
4382 /* try with all lowercase */
4384 ret = sys_gethostbyname(name2);
4391 /* try with all uppercase */
4393 ret = sys_gethostbyname(name2);
4400 /* nothing works :-( */
4406 /****************************************************************************
4407 check if a process exists. Does this work on all unixes?
4408 ****************************************************************************/
4409 BOOL process_exists(int pid)
4411 return(kill(pid,0) == 0 || errno != ESRCH);
4415 /*******************************************************************
4416 turn a uid into a user name
4417 ********************************************************************/
4418 char *uidtoname(int uid)
4420 static char name[40];
4421 struct passwd *pass = getpwuid(uid);
4422 if (pass) return(pass->pw_name);
4423 slprintf(name, sizeof(name) - 1, "%d",uid);
4427 /*******************************************************************
4428 turn a gid into a group name
4429 ********************************************************************/
4430 char *gidtoname(int gid)
4432 static char name[40];
4433 struct group *grp = getgrgid(gid);
4434 if (grp) return(grp->gr_name);
4435 slprintf(name,sizeof(name) - 1, "%d",gid);
4439 /*******************************************************************
4441 ********************************************************************/
4442 void BlockSignals(BOOL block,int signum)
4445 int block_mask = sigmask(signum);
4446 static int oldmask = 0;
4448 oldmask = sigblock(block_mask);
4450 sigsetmask(oldmask);
4451 #elif defined(USE_SIGPROCMASK)
4454 sigaddset(&set,signum);
4455 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4460 /*******************************************************************
4461 my own panic function - not suitable for general use
4462 ********************************************************************/
4463 void ajt_panic(void)
4465 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4470 #define DIRECT direct
4472 #define DIRECT dirent
4475 /*******************************************************************
4476 a readdir wrapper which just returns the file name
4477 also return the inode number if requested
4478 ********************************************************************/
4479 char *readdirname(void *p)
4484 if (!p) return(NULL);
4486 ptr = (struct DIRECT *)readdir(p);
4487 if (!ptr) return(NULL);
4489 dname = ptr->d_name;
4492 if (telldir(p) < 0) return(NULL);
4496 /* this handles a broken compiler setup, causing a mixture
4497 of BSD and SYSV headers and libraries */
4499 static BOOL broken_readdir = False;
4500 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4502 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4503 broken_readdir = True;
4512 pstrcpy(buf, dname);
4513 unix_to_dos(buf, True);
4520 /*******************************************************************
4521 Utility function used to decide if the last component
4522 of a path matches a (possibly wildcarded) entry in a namelist.
4523 ********************************************************************/
4525 BOOL is_in_path(char *name, name_compare_entry *namelist)
4527 pstring last_component;
4530 DEBUG(8, ("is_in_path: %s\n", name));
4532 /* if we have no list it's obviously not in the path */
4533 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4535 DEBUG(8,("is_in_path: no name list.\n"));
4539 /* Get the last component of the unix name. */
4540 p = strrchr(name, '/');
4541 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4542 last_component[sizeof(last_component)-1] = '\0';
4544 for(; namelist->name != NULL; namelist++)
4546 if(namelist->is_wild)
4548 /* look for a wildcard match. */
4549 if (mask_match(last_component, namelist->name, case_sensitive, False))
4551 DEBUG(8,("is_in_path: mask match succeeded\n"));
4557 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4558 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4560 DEBUG(8,("is_in_path: match succeeded\n"));
4565 DEBUG(8,("is_in_path: match not found\n"));
4570 /*******************************************************************
4571 Strip a '/' separated list into an array of
4572 name_compare_enties structures suitable for
4573 passing to is_in_path(). We do this for
4574 speed so we can pre-parse all the names in the list
4575 and don't do it for each call to is_in_path().
4576 namelist is modified here and is assumed to be
4577 a copy owned by the caller.
4578 We also check if the entry contains a wildcard to
4579 remove a potentially expensive call to mask_match
4581 ********************************************************************/
4583 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4586 char *nameptr = namelist;
4587 int num_entries = 0;
4590 (*ppname_array) = NULL;
4592 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4595 /* We need to make two passes over the string. The
4596 first to count the number of elements, the second
4601 if ( *nameptr == '/' )
4603 /* cope with multiple (useless) /s) */
4607 /* find the next / */
4608 name_end = strchr(nameptr, '/');
4610 /* oops - the last check for a / didn't find one. */
4611 if (name_end == NULL)
4614 /* next segment please */
4615 nameptr = name_end + 1;
4619 if(num_entries == 0)
4622 if(( (*ppname_array) = (name_compare_entry *)malloc(
4623 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4625 DEBUG(0,("set_namearray: malloc fail\n"));
4629 /* Now copy out the names */
4634 if ( *nameptr == '/' )
4636 /* cope with multiple (useless) /s) */
4640 /* find the next / */
4641 if ((name_end = strchr(nameptr, '/')) != NULL)
4646 /* oops - the last check for a / didn't find one. */
4647 if(name_end == NULL)
4650 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4651 (strchr( nameptr, '*')!=NULL));
4652 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4654 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4658 /* next segment please */
4659 nameptr = name_end + 1;
4663 (*ppname_array)[i].name = NULL;
4668 /****************************************************************************
4669 routine to free a namearray.
4670 ****************************************************************************/
4672 void free_namearray(name_compare_entry *name_array)
4677 if(name_array->name != NULL)
4678 free(name_array->name);
4680 free((char *)name_array);
4683 /****************************************************************************
4684 routine to do file locking
4685 ****************************************************************************/
4686 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4693 uint32 mask = 0xC0000000;
4695 /* make sure the count is reasonable, we might kill the lockd otherwise */
4698 /* the offset is often strange - remove 2 of its bits if either of
4699 the top two bits are set. Shift the top ones by two bits. This
4700 still allows OLE2 apps to operate, but should stop lockd from
4702 if ((offset & mask) != 0)
4703 offset = (offset & ~mask) | ((offset & mask) >> 2);
4705 uint32 mask = ((unsigned)1<<31);
4707 /* interpret negative counts as large numbers */
4711 /* no negative offsets */
4714 /* count + offset must be in range */
4715 while ((offset < 0 || (offset + count < 0)) && mask)
4723 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4726 lock.l_whence = SEEK_SET;
4727 lock.l_start = (int)offset;
4728 lock.l_len = (int)count;
4733 ret = fcntl(fd,op,&lock);
4736 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4742 (lock.l_type != F_UNLCK) &&
4743 (lock.l_pid != 0) &&
4744 (lock.l_pid != getpid()))
4746 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4750 /* it must be not locked or locked by me */
4754 /* a lock set or unset */
4757 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4758 offset,count,op,type,strerror(errno)));
4760 /* perhaps it doesn't support this sort of locking?? */
4761 if (errno == EINVAL)
4763 DEBUG(3,("locking not supported? returning True\n"));
4770 /* everything went OK */
4771 DEBUG(8,("Lock call successful\n"));
4779 /*******************************************************************
4780 lock a file - returning a open file descriptor or -1 on failure
4781 The timeout is in seconds. 0 means no timeout
4782 ********************************************************************/
4783 int file_lock(char *name,int timeout)
4785 int fd = open(name,O_RDWR|O_CREAT,0666);
4787 if (fd < 0) return(-1);
4790 if (timeout) t = time(NULL);
4791 while (!timeout || (time(NULL)-t < timeout)) {
4792 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4793 msleep(LOCK_RETRY_TIMEOUT);
4801 /*******************************************************************
4802 unlock a file locked by file_lock
4803 ********************************************************************/
4804 void file_unlock(int fd)
4808 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4813 /*******************************************************************
4814 is the name specified one of my netbios names
4815 returns true is it is equal, false otherwise
4816 ********************************************************************/
4817 BOOL is_myname(char *s)
4822 for (n=0; my_netbios_names[n]; n++) {
4823 if (strequal(my_netbios_names[n], s))
4826 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4830 /*******************************************************************
4831 set the horrid remote_arch string based on an enum.
4832 ********************************************************************/
4833 void set_remote_arch(enum remote_arch_types type)
4839 fstrcpy(remote_arch, "WfWg");
4842 fstrcpy(remote_arch, "OS2");
4845 fstrcpy(remote_arch, "Win95");
4848 fstrcpy(remote_arch, "WinNT");
4851 fstrcpy(remote_arch,"Samba");
4854 ra_type = RA_UNKNOWN;
4855 fstrcpy(remote_arch, "UNKNOWN");
4860 /*******************************************************************
4861 Get the remote_arch type.
4862 ********************************************************************/
4863 enum remote_arch_types get_remote_arch(void)
4869 /*******************************************************************
4870 skip past some unicode strings in a buffer
4871 ********************************************************************/
4872 char *skip_unicode_string(char *buf,int n)
4883 /*******************************************************************
4884 Return a ascii version of a unicode string
4885 Hack alert: uses fixed buffer(s) and only handles ascii strings
4886 ********************************************************************/
4888 char *unistrn2(uint16 *buf, int len)
4890 static char lbufs[8][MAXUNI];
4892 char *lbuf = lbufs[nexti];
4895 nexti = (nexti+1)%8;
4897 DEBUG(10, ("unistrn2: "));
4899 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4901 DEBUG(10, ("%4x ", *buf));
4911 /*******************************************************************
4912 Return a ascii version of a unicode string
4913 Hack alert: uses fixed buffer(s) and only handles ascii strings
4914 ********************************************************************/
4916 char *unistr2(uint16 *buf)
4918 static char lbufs[8][MAXUNI];
4920 char *lbuf = lbufs[nexti];
4923 nexti = (nexti+1)%8;
4925 DEBUG(10, ("unistr2: "));
4927 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4929 DEBUG(10, ("%4x ", *buf));
4939 /*******************************************************************
4940 create a null-terminated unicode string from a null-terminated ascii string.
4941 return number of unicode chars copied, excluding the null character.
4943 only handles ascii strings
4944 ********************************************************************/
4946 int struni2(uint16 *p, char *buf)
4950 if (p == NULL) return 0;
4952 DEBUG(10, ("struni2: "));
4956 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4958 DEBUG(10, ("%2x ", *buf));
4970 /*******************************************************************
4971 Return a ascii version of a unicode string
4972 Hack alert: uses fixed buffer(s) and only handles ascii strings
4973 ********************************************************************/
4975 char *unistr(char *buf)
4977 static char lbufs[8][MAXUNI];
4979 char *lbuf = lbufs[nexti];
4982 nexti = (nexti+1)%8;
4984 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4992 /*******************************************************************
4993 strncpy for unicode strings
4994 ********************************************************************/
4995 int unistrncpy(char *dst, char *src, int len)
4999 while (*src && len > 0)
5013 /*******************************************************************
5014 strcpy for unicode strings. returns length (in num of wide chars)
5015 ********************************************************************/
5016 int unistrcpy(char *dst, char *src)
5032 /*******************************************************************
5033 safe string copy into a known length string. maxlength does not
5034 include the terminating zero.
5035 ********************************************************************/
5036 char *safe_strcpy(char *dest, char *src, int maxlength)
5041 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
5052 if (len > maxlength) {
5053 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
5054 len-maxlength, src));
5058 memcpy(dest, src, len);
5063 /*******************************************************************
5064 safe string cat into a string. maxlength does not
5065 include the terminating zero.
5066 ********************************************************************/
5067 char *safe_strcat(char *dest, char *src, int maxlength)
5069 int src_len, dest_len;
5072 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
5080 src_len = strlen(src);
5081 dest_len = strlen(dest);
5083 if (src_len + dest_len > maxlength) {
5084 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
5085 src_len + dest_len - maxlength, src));
5086 src_len = maxlength - dest_len;
5089 memcpy(&dest[dest_len], src, src_len);
5090 dest[dest_len + src_len] = 0;
5094 /*******************************************************************
5095 align a pointer to a multiple of 4 bytes
5096 ********************************************************************/
5097 char *align4(char *q, char *base)
5101 q += 4 - ((q - base) & 3);
5106 /*******************************************************************
5107 align a pointer to a multiple of 2 bytes
5108 ********************************************************************/
5109 char *align2(char *q, char *base)
5118 /*******************************************************************
5119 align a pointer to a multiple of align_offset bytes. looks like it
5120 will work for offsets of 0, 2 and 4...
5121 ********************************************************************/
5122 char *align_offset(char *q, char *base, int align_offset_len)
5124 int mod = ((q - base) & (align_offset_len-1));
5125 if (align_offset_len != 0 && mod != 0)
5127 q += align_offset_len - mod;
5132 void print_asc(int level, unsigned char *buf,int len)
5136 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
5139 void dump_data(int level,char *buf1,int len)
5141 unsigned char *buf = (unsigned char *)buf1;
5145 DEBUG(level,("[%03X] ",i));
5147 DEBUG(level,("%02X ",(int)buf[i]));
5149 if (i%8 == 0) DEBUG(level,(" "));
5151 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
5152 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
5153 if (i<len) DEBUG(level,("[%03X] ",i));
5161 if (n>8) DEBUG(level,(" "));
5162 while (n--) DEBUG(level,(" "));
5165 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
5167 if (n>0) print_asc(level,&buf[i-n],n);
5168 DEBUG(level,("\n"));
5172 char *tab_depth(int depth)
5174 static pstring spaces;
5175 memset(spaces, ' ', depth * 4);
5176 spaces[depth * 4] = 0;
5180 /*****************************************************************
5181 Convert a SID to an ascii string.
5182 *****************************************************************/
5184 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
5188 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5189 uint32 ia = (sid->id_auth[5]) +
5190 (sid->id_auth[4] << 8 ) +
5191 (sid->id_auth[3] << 16) +
5192 (sid->id_auth[2] << 24);
5194 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
5196 for (i = 0; i < sid->num_auths; i++)
5198 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
5199 pstrcat(sidstr_out, subauth);
5202 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
5206 /*****************************************************************
5207 Convert a string to a SID. Returns True on success, False on fail.
5208 *****************************************************************/
5210 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
5214 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5217 memset((char *)sidout, '\0', sizeof(DOM_SID));
5219 if(StrnCaseCmp( sidstr, "S-", 2)) {
5220 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
5225 if(!next_token(&p, tok, "-")) {
5226 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5230 /* Get the revision number. */
5231 sidout->sid_rev_num = atoi(tok);
5233 if(!next_token(&p, tok, "-")) {
5234 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5238 /* identauth in decimal should be < 2^32 */
5241 /* NOTE - the ia value is in big-endian format. */
5242 sidout->id_auth[0] = 0;
5243 sidout->id_auth[1] = 0;
5244 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
5245 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
5246 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
5247 sidout->id_auth[5] = (ia & 0x000000ff);
5249 sidout->num_auths = 0;
5251 while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) {
5253 * NOTE - the subauths are in native machine-endian format. They
5254 * are converted to little-endian when linearized onto the wire.
5256 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
5259 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));