bounds check next_token() to prevent possible buffer overflows
[Samba/gbeck.git] / source / lib / util.c
bloba52228c997e94e3fd0c1afc4073ff6136752c61b
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
22 #include "includes.h"
24 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
25 #ifdef WITH_NISPLUS_HOME
26 #include <rpcsvc/nis.h>
27 #else
28 #include "rpcsvc/ypclnt.h"
29 #endif
30 #endif
32 #ifdef WITH_SSL
33 #include <ssl.h>
34 #undef Realloc /* SSLeay defines this and samba has a function of this name */
35 extern SSL *ssl;
36 extern int sslFd;
37 #endif /* WITH_SSL */
39 pstring scope = "";
41 extern int DEBUGLEVEL;
43 BOOL passive = False;
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 /* the client file descriptor */
51 int Client = -1;
53 /* the last IP received from */
54 struct in_addr lastip;
56 /* the last port received from */
57 int lastport=0;
59 /* this is used by the chaining code */
60 int chain_size = 0;
62 int trans_num = 0;
65 case handling on filenames
67 int case_default = CASE_LOWER;
69 /* the following control case operations - they are put here so the
70 client can link easily */
71 BOOL case_sensitive;
72 BOOL case_preserve;
73 BOOL use_mangled_map = False;
74 BOOL short_case_preserve;
75 BOOL case_mangle;
77 fstring remote_machine="";
78 fstring local_machine="";
79 fstring remote_arch="UNKNOWN";
80 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 fstring remote_proto="UNKNOWN";
82 pstring myhostname="";
83 pstring user_socket_options="";
85 pstring sesssetup_user="";
86 pstring samlogon_user="";
88 BOOL sam_logon_in_ssb = False;
90 pstring global_myname = "";
91 fstring global_myworkgroup = "";
92 char **my_netbios_names;
94 int smb_read_error = 0;
96 static char *filename_dos(char *path,char *buf);
100 /****************************************************************************
101 find a suitable temporary directory. The result should be copied immediately
102 as it may be overwritten by a subsequent call
103 ****************************************************************************/
104 char *tmpdir(void)
106 char *p;
107 if ((p = getenv("TMPDIR"))) {
108 return p;
110 return "/tmp";
115 /****************************************************************************
116 determine if a file descriptor is in fact a socket
117 ****************************************************************************/
118 BOOL is_a_socket(int fd)
120 int v,l;
121 l = sizeof(int);
122 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
126 static char *last_ptr=NULL;
128 /****************************************************************************
129 Get the next token from a string, return False if none found
130 handles double-quotes.
131 Based on a routine by GJC@VILLAGE.COM.
132 Extensively modified by Andrew.Tridgell@anu.edu.au
133 ****************************************************************************/
134 BOOL next_token(char **ptr,char *buff,char *sep, int bufsize)
136 char *s;
137 BOOL quoted;
138 int len=1;
140 if (!ptr) ptr = &last_ptr;
141 if (!ptr) return(False);
143 s = *ptr;
145 /* default to simple separators */
146 if (!sep) sep = " \t\n\r";
148 /* find the first non sep char */
149 while(*s && strchr(sep,*s)) s++;
151 /* nothing left? */
152 if (! *s) return(False);
154 /* copy over the token */
155 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
157 if (*s == '\"') {
158 quoted = !quoted;
159 } else {
160 len++;
161 *buff++ = *s;
165 *ptr = (*s) ? s+1 : s;
166 *buff = 0;
167 last_ptr = *ptr;
169 return(True);
172 /****************************************************************************
173 Convert list of tokens to array; dependent on above routine.
174 Uses last_ptr from above - bit of a hack.
175 ****************************************************************************/
176 char **toktocliplist(int *ctok, char *sep)
178 char *s=last_ptr;
179 int ictok=0;
180 char **ret, **iret;
182 if (!sep) sep = " \t\n\r";
184 while(*s && strchr(sep,*s)) s++;
186 /* nothing left? */
187 if (!*s) return(NULL);
189 do {
190 ictok++;
191 while(*s && (!strchr(sep,*s))) s++;
192 while(*s && strchr(sep,*s)) *s++=0;
193 } while(*s);
195 *ctok=ictok;
196 s=last_ptr;
198 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
200 while(ictok--) {
201 *iret++=s;
202 while(*s++);
203 while(!*s) s++;
206 return ret;
210 /* ************************************************************************* **
211 * Duplicate a block of memory.
212 * ************************************************************************* **
214 void *mem_dup( void *from, int size )
216 void *tmp;
218 tmp = malloc( size );
219 if( NULL != tmp )
220 (void)memcpy( tmp, from, size );
221 return( tmp );
222 } /* mem_dup */
224 /****************************************************************************
225 prompte a dptr (to make it recently used)
226 ****************************************************************************/
227 void array_promote(char *array,int elsize,int element)
229 char *p;
230 if (element == 0)
231 return;
233 p = (char *)malloc(elsize);
235 if (!p)
237 DEBUG(5,("Ahh! Can't malloc\n"));
238 return;
240 memcpy(p,array + element * elsize, elsize);
241 memmove(array + elsize,array,elsize*element);
242 memcpy(array,p,elsize);
243 free(p);
246 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
248 struct
250 char *name;
251 int level;
252 int option;
253 int value;
254 int opttype;
255 } socket_options[] = {
256 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
257 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
258 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
259 #ifdef TCP_NODELAY
260 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
261 #endif
262 #ifdef IPTOS_LOWDELAY
263 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
264 #endif
265 #ifdef IPTOS_THROUGHPUT
266 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
267 #endif
268 #ifdef SO_SNDBUF
269 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
270 #endif
271 #ifdef SO_RCVBUF
272 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
273 #endif
274 #ifdef SO_SNDLOWAT
275 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
276 #endif
277 #ifdef SO_RCVLOWAT
278 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
279 #endif
280 #ifdef SO_SNDTIMEO
281 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
282 #endif
283 #ifdef SO_RCVTIMEO
284 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
285 #endif
286 {NULL,0,0,0,0}};
290 /****************************************************************************
291 set user socket options
292 ****************************************************************************/
293 void set_socket_options(int fd, char *options)
295 fstring tok;
297 while (next_token(&options,tok," \t,", sizeof(tok)))
299 int ret=0,i;
300 int value = 1;
301 char *p;
302 BOOL got_value = False;
304 if ((p = strchr(tok,'=')))
306 *p = 0;
307 value = atoi(p+1);
308 got_value = True;
311 for (i=0;socket_options[i].name;i++)
312 if (strequal(socket_options[i].name,tok))
313 break;
315 if (!socket_options[i].name)
317 DEBUG(0,("Unknown socket option %s\n",tok));
318 continue;
321 switch (socket_options[i].opttype)
323 case OPT_BOOL:
324 case OPT_INT:
325 ret = setsockopt(fd,socket_options[i].level,
326 socket_options[i].option,(char *)&value,sizeof(int));
327 break;
329 case OPT_ON:
330 if (got_value)
331 DEBUG(0,("syntax error - %s does not take a value\n",tok));
334 int on = socket_options[i].value;
335 ret = setsockopt(fd,socket_options[i].level,
336 socket_options[i].option,(char *)&on,sizeof(int));
338 break;
341 if (ret != 0)
342 DEBUG(0,("Failed to set socket option %s\n",tok));
348 /****************************************************************************
349 close the socket communication
350 ****************************************************************************/
351 void close_sockets(void )
353 #ifdef WITH_SSL
354 sslutil_disconnect(Client);
355 #endif /* WITH_SSL */
357 close(Client);
358 Client = 0;
361 /****************************************************************************
362 determine whether we are in the specified group
363 ****************************************************************************/
364 BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
366 int i;
368 if (group == current_gid) return(True);
370 for (i=0;i<ngroups;i++)
371 if (group == groups[i])
372 return(True);
374 return(False);
377 /****************************************************************************
378 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
379 ****************************************************************************/
380 char *StrCpy(char *dest,char *src)
382 char *d = dest;
384 /* I don't want to get lazy with these ... */
385 SMB_ASSERT(dest && src);
387 if (!dest) return(NULL);
388 if (!src) {
389 *dest = 0;
390 return(dest);
392 while ((*d++ = *src++)) ;
393 return(dest);
396 /****************************************************************************
397 line strncpy but always null terminates. Make sure there is room!
398 ****************************************************************************/
399 char *StrnCpy(char *dest,char *src,int n)
401 char *d = dest;
402 if (!dest) return(NULL);
403 if (!src) {
404 *dest = 0;
405 return(dest);
407 while (n-- && (*d++ = *src++)) ;
408 *d = 0;
409 return(dest);
413 /*******************************************************************
414 copy an IP address from one buffer to another
415 ********************************************************************/
416 void putip(void *dest,void *src)
418 memcpy(dest,src,4);
422 /****************************************************************************
423 interpret the weird netbios "name". Return the name type
424 ****************************************************************************/
425 static int name_interpret(char *in,char *out)
427 int ret;
428 int len = (*in++) / 2;
430 *out=0;
432 if (len > 30 || len<1) return(0);
434 while (len--)
436 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
437 *out = 0;
438 return(0);
440 *out = ((in[0]-'A')<<4) + (in[1]-'A');
441 in += 2;
442 out++;
444 *out = 0;
445 ret = out[-1];
447 #ifdef NETBIOS_SCOPE
448 /* Handle any scope names */
449 while(*in)
451 *out++ = '.'; /* Scope names are separated by periods */
452 len = *(unsigned char *)in++;
453 StrnCpy(out, in, len);
454 out += len;
455 *out=0;
456 in += len;
458 #endif
459 return(ret);
462 /****************************************************************************
463 mangle a name into netbios format
465 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
466 ****************************************************************************/
467 int name_mangle( char *In, char *Out, char name_type )
469 int i;
470 int c;
471 int len;
472 char buf[20];
473 char *p = Out;
475 /* Safely copy the input string, In, into buf[]. */
476 (void)memset( buf, 0, 20 );
477 if( '*' == In[0] )
478 buf[0] = '*';
479 else
480 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
482 /* Place the length of the first field into the output buffer. */
483 p[0] = 32;
484 p++;
486 /* Now convert the name to the rfc1001/1002 format. */
487 for( i = 0; i < 16; i++ )
489 c = toupper( buf[i] );
490 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
491 p[(i*2)+1] = (c & 0x000F) + 'A';
493 p += 32;
494 p[0] = '\0';
496 /* Add the scope string. */
497 for( i = 0, len = 0; NULL != scope; i++, len++ )
499 switch( scope[i] )
501 case '\0':
502 p[0] = len;
503 if( len > 0 )
504 p[len+1] = 0;
505 return( name_len(Out) );
506 case '.':
507 p[0] = len;
508 p += (len + 1);
509 len = 0;
510 break;
511 default:
512 p[len+1] = scope[i];
513 break;
517 return( name_len(Out) );
518 } /* name_mangle */
520 /*******************************************************************
521 check if a file exists
522 ********************************************************************/
523 BOOL file_exist(char *fname,struct stat *sbuf)
525 struct stat st;
526 if (!sbuf) sbuf = &st;
528 if (sys_stat(fname,sbuf) != 0)
529 return(False);
531 return(S_ISREG(sbuf->st_mode));
534 /*******************************************************************
535 check a files mod time
536 ********************************************************************/
537 time_t file_modtime(char *fname)
539 struct stat st;
541 if (sys_stat(fname,&st) != 0)
542 return(0);
544 return(st.st_mtime);
547 /*******************************************************************
548 check if a directory exists
549 ********************************************************************/
550 BOOL directory_exist(char *dname,struct stat *st)
552 struct stat st2;
553 BOOL ret;
555 if (!st) st = &st2;
557 if (sys_stat(dname,st) != 0)
558 return(False);
560 ret = S_ISDIR(st->st_mode);
561 if(!ret)
562 errno = ENOTDIR;
563 return ret;
566 /*******************************************************************
567 returns the size in bytes of the named file
568 ********************************************************************/
569 uint32 file_size(char *file_name)
571 struct stat buf;
572 buf.st_size = 0;
573 sys_stat(file_name,&buf);
574 return(buf.st_size);
577 /*******************************************************************
578 return a string representing an attribute for a file
579 ********************************************************************/
580 char *attrib_string(int mode)
582 static fstring attrstr;
584 attrstr[0] = 0;
586 if (mode & aVOLID) fstrcat(attrstr,"V");
587 if (mode & aDIR) fstrcat(attrstr,"D");
588 if (mode & aARCH) fstrcat(attrstr,"A");
589 if (mode & aHIDDEN) fstrcat(attrstr,"H");
590 if (mode & aSYSTEM) fstrcat(attrstr,"S");
591 if (mode & aRONLY) fstrcat(attrstr,"R");
593 return(attrstr);
597 /*******************************************************************
598 case insensitive string compararison
599 ********************************************************************/
600 int StrCaseCmp(char *s, char *t)
602 /* compare until we run out of string, either t or s, or find a difference */
603 /* We *must* use toupper rather than tolower here due to the
604 asynchronous upper to lower mapping.
606 #if !defined(KANJI_WIN95_COMPATIBILITY)
608 * For completeness we should put in equivalent code for code pages
609 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
610 * doubt anyone wants Samba to behave differently from Win95 and WinNT
611 * here. They both treat full width ascii characters as case senstive
612 * filenames (ie. they don't do the work we do here).
613 * JRA.
616 if(lp_client_code_page() == KANJI_CODEPAGE)
618 /* Win95 treats full width ascii characters as case sensitive. */
619 int diff;
620 for (;;)
622 if (!*s || !*t)
623 return toupper (*s) - toupper (*t);
624 else if (is_sj_alph (*s) && is_sj_alph (*t))
626 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
627 if (diff)
628 return diff;
629 s += 2;
630 t += 2;
632 else if (is_shift_jis (*s) && is_shift_jis (*t))
634 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
635 if (diff)
636 return diff;
637 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
638 if (diff)
639 return diff;
640 s += 2;
641 t += 2;
643 else if (is_shift_jis (*s))
644 return 1;
645 else if (is_shift_jis (*t))
646 return -1;
647 else
649 diff = toupper (*s) - toupper (*t);
650 if (diff)
651 return diff;
652 s++;
653 t++;
657 else
658 #endif /* KANJI_WIN95_COMPATIBILITY */
660 while (*s && *t && toupper(*s) == toupper(*t))
662 s++;
663 t++;
666 return(toupper(*s) - toupper(*t));
670 /*******************************************************************
671 case insensitive string compararison, length limited
672 ********************************************************************/
673 int StrnCaseCmp(char *s, char *t, int n)
675 /* compare until we run out of string, either t or s, or chars */
676 /* We *must* use toupper rather than tolower here due to the
677 asynchronous upper to lower mapping.
679 #if !defined(KANJI_WIN95_COMPATIBILITY)
681 * For completeness we should put in equivalent code for code pages
682 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
683 * doubt anyone wants Samba to behave differently from Win95 and WinNT
684 * here. They both treat full width ascii characters as case senstive
685 * filenames (ie. they don't do the work we do here).
686 * JRA.
689 if(lp_client_code_page() == KANJI_CODEPAGE)
691 /* Win95 treats full width ascii characters as case sensitive. */
692 int diff;
693 for (;n > 0;)
695 if (!*s || !*t)
696 return toupper (*s) - toupper (*t);
697 else if (is_sj_alph (*s) && is_sj_alph (*t))
699 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
700 if (diff)
701 return diff;
702 s += 2;
703 t += 2;
704 n -= 2;
706 else if (is_shift_jis (*s) && is_shift_jis (*t))
708 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
709 if (diff)
710 return diff;
711 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
712 if (diff)
713 return diff;
714 s += 2;
715 t += 2;
716 n -= 2;
718 else if (is_shift_jis (*s))
719 return 1;
720 else if (is_shift_jis (*t))
721 return -1;
722 else
724 diff = toupper (*s) - toupper (*t);
725 if (diff)
726 return diff;
727 s++;
728 t++;
729 n--;
732 return 0;
734 else
735 #endif /* KANJI_WIN95_COMPATIBILITY */
737 while (n && *s && *t && toupper(*s) == toupper(*t))
739 s++;
740 t++;
741 n--;
744 /* not run out of chars - strings are different lengths */
745 if (n)
746 return(toupper(*s) - toupper(*t));
748 /* identical up to where we run out of chars,
749 and strings are same length */
750 return(0);
754 /*******************************************************************
755 compare 2 strings
756 ********************************************************************/
757 BOOL strequal(char *s1, char *s2)
759 if (s1 == s2) return(True);
760 if (!s1 || !s2) return(False);
762 return(StrCaseCmp(s1,s2)==0);
765 /*******************************************************************
766 compare 2 strings up to and including the nth char.
767 ******************************************************************/
768 BOOL strnequal(char *s1,char *s2,int n)
770 if (s1 == s2) return(True);
771 if (!s1 || !s2 || !n) return(False);
773 return(StrnCaseCmp(s1,s2,n)==0);
776 /*******************************************************************
777 compare 2 strings (case sensitive)
778 ********************************************************************/
779 BOOL strcsequal(char *s1,char *s2)
781 if (s1 == s2) return(True);
782 if (!s1 || !s2) return(False);
784 return(strcmp(s1,s2)==0);
788 /*******************************************************************
789 convert a string to lower case
790 ********************************************************************/
791 void strlower(char *s)
793 while (*s)
795 #if !defined(KANJI_WIN95_COMPATIBILITY)
797 * For completeness we should put in equivalent code for code pages
798 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
799 * doubt anyone wants Samba to behave differently from Win95 and WinNT
800 * here. They both treat full width ascii characters as case senstive
801 * filenames (ie. they don't do the work we do here).
802 * JRA.
805 if(lp_client_code_page() == KANJI_CODEPAGE)
807 /* Win95 treats full width ascii characters as case sensitive. */
808 if (is_shift_jis (*s))
810 if (is_sj_upper (s[0], s[1]))
811 s[1] = sj_tolower2 (s[1]);
812 s += 2;
814 else if (is_kana (*s))
816 s++;
818 else
820 if (isupper(*s))
821 *s = tolower(*s);
822 s++;
825 else
826 #endif /* KANJI_WIN95_COMPATIBILITY */
828 int skip = skip_multibyte_char( *s );
829 if( skip != 0 )
830 s += skip;
831 else
833 if (isupper(*s))
834 *s = tolower(*s);
835 s++;
841 /*******************************************************************
842 convert a string to upper case
843 ********************************************************************/
844 void strupper(char *s)
846 while (*s)
848 #if !defined(KANJI_WIN95_COMPATIBILITY)
850 * For completeness we should put in equivalent code for code pages
851 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
852 * doubt anyone wants Samba to behave differently from Win95 and WinNT
853 * here. They both treat full width ascii characters as case senstive
854 * filenames (ie. they don't do the work we do here).
855 * JRA.
858 if(lp_client_code_page() == KANJI_CODEPAGE)
860 /* Win95 treats full width ascii characters as case sensitive. */
861 if (is_shift_jis (*s))
863 if (is_sj_lower (s[0], s[1]))
864 s[1] = sj_toupper2 (s[1]);
865 s += 2;
867 else if (is_kana (*s))
869 s++;
871 else
873 if (islower(*s))
874 *s = toupper(*s);
875 s++;
878 else
879 #endif /* KANJI_WIN95_COMPATIBILITY */
881 int skip = skip_multibyte_char( *s );
882 if( skip != 0 )
883 s += skip;
884 else
886 if (islower(*s))
887 *s = toupper(*s);
888 s++;
894 /*******************************************************************
895 convert a string to "normal" form
896 ********************************************************************/
897 void strnorm(char *s)
899 if (case_default == CASE_UPPER)
900 strupper(s);
901 else
902 strlower(s);
905 /*******************************************************************
906 check if a string is in "normal" case
907 ********************************************************************/
908 BOOL strisnormal(char *s)
910 if (case_default == CASE_UPPER)
911 return(!strhaslower(s));
913 return(!strhasupper(s));
917 /****************************************************************************
918 string replace
919 ****************************************************************************/
920 void string_replace(char *s,char oldc,char newc)
922 int skip;
923 while (*s)
925 skip = skip_multibyte_char( *s );
926 if( skip != 0 )
927 s += skip;
928 else
930 if (oldc == *s)
931 *s = newc;
932 s++;
937 /****************************************************************************
938 make a file into unix format
939 ****************************************************************************/
940 void unix_format(char *fname)
942 pstring namecopy;
943 string_replace(fname,'\\','/');
945 if (*fname == '/')
947 pstrcpy(namecopy,fname);
948 pstrcpy(fname,".");
949 pstrcat(fname,namecopy);
953 /****************************************************************************
954 make a file into dos format
955 ****************************************************************************/
956 void dos_format(char *fname)
958 string_replace(fname,'/','\\');
961 /*******************************************************************
962 show a smb message structure
963 ********************************************************************/
964 void show_msg(char *buf)
966 int i;
967 int bcc=0;
969 if (DEBUGLEVEL < 5) return;
971 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
972 smb_len(buf),
973 (int)CVAL(buf,smb_com),
974 (int)CVAL(buf,smb_rcls),
975 (int)CVAL(buf,smb_reh),
976 (int)SVAL(buf,smb_err),
977 (int)CVAL(buf,smb_flg),
978 (int)SVAL(buf,smb_flg2)));
979 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
980 (int)SVAL(buf,smb_tid),
981 (int)SVAL(buf,smb_pid),
982 (int)SVAL(buf,smb_uid),
983 (int)SVAL(buf,smb_mid),
984 (int)CVAL(buf,smb_wct)));
986 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
988 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
989 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
992 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
994 DEBUG(5,("smb_bcc=%d\n",bcc));
996 if (DEBUGLEVEL < 10) return;
998 if (DEBUGLEVEL < 50)
1000 bcc = MIN(bcc, 512);
1003 dump_data(10, smb_buf(buf), bcc);
1005 /*******************************************************************
1006 return the length of an smb packet
1007 ********************************************************************/
1008 int smb_len(char *buf)
1010 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1013 /*******************************************************************
1014 set the length of an smb packet
1015 ********************************************************************/
1016 void _smb_setlen(char *buf,int len)
1018 buf[0] = 0;
1019 buf[1] = (len&0x10000)>>16;
1020 buf[2] = (len&0xFF00)>>8;
1021 buf[3] = len&0xFF;
1024 /*******************************************************************
1025 set the length and marker of an smb packet
1026 ********************************************************************/
1027 void smb_setlen(char *buf,int len)
1029 _smb_setlen(buf,len);
1031 CVAL(buf,4) = 0xFF;
1032 CVAL(buf,5) = 'S';
1033 CVAL(buf,6) = 'M';
1034 CVAL(buf,7) = 'B';
1037 /*******************************************************************
1038 setup the word count and byte count for a smb message
1039 ********************************************************************/
1040 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1042 if (zero)
1043 bzero(buf + smb_size,num_words*2 + num_bytes);
1044 CVAL(buf,smb_wct) = num_words;
1045 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1046 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1047 return (smb_size + num_words*2 + num_bytes);
1050 /*******************************************************************
1051 return the number of smb words
1052 ********************************************************************/
1053 int smb_numwords(char *buf)
1055 return (CVAL(buf,smb_wct));
1058 /*******************************************************************
1059 return the size of the smb_buf region of a message
1060 ********************************************************************/
1061 int smb_buflen(char *buf)
1063 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1066 /*******************************************************************
1067 return a pointer to the smb_buf data area
1068 ********************************************************************/
1069 int smb_buf_ofs(char *buf)
1071 return (smb_size + CVAL(buf,smb_wct)*2);
1074 /*******************************************************************
1075 return a pointer to the smb_buf data area
1076 ********************************************************************/
1077 char *smb_buf(char *buf)
1079 return (buf + smb_buf_ofs(buf));
1082 /*******************************************************************
1083 return the SMB offset into an SMB buffer
1084 ********************************************************************/
1085 int smb_offset(char *p,char *buf)
1087 return(PTR_DIFF(p,buf+4) + chain_size);
1091 /*******************************************************************
1092 skip past some strings in a buffer
1093 ********************************************************************/
1094 char *skip_string(char *buf,int n)
1096 while (n--)
1097 buf += strlen(buf) + 1;
1098 return(buf);
1101 /*******************************************************************
1102 trim the specified elements off the front and back of a string
1103 ********************************************************************/
1104 BOOL trim_string(char *s,char *front,char *back)
1106 BOOL ret = False;
1107 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1109 char *p = s;
1110 ret = True;
1111 while (1)
1113 if (!(*p = p[strlen(front)]))
1114 break;
1115 p++;
1118 while (back && *back && strlen(s) >= strlen(back) &&
1119 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1121 ret = True;
1122 s[strlen(s)-strlen(back)] = 0;
1124 return(ret);
1128 /*******************************************************************
1129 reduce a file name, removing .. elements.
1130 ********************************************************************/
1131 void dos_clean_name(char *s)
1133 char *p=NULL;
1135 DEBUG(3,("dos_clean_name [%s]\n",s));
1137 /* remove any double slashes */
1138 string_sub(s, "\\\\", "\\");
1140 while ((p = strstr(s,"\\..\\")) != NULL)
1142 pstring s1;
1144 *p = 0;
1145 pstrcpy(s1,p+3);
1147 if ((p=strrchr(s,'\\')) != NULL)
1148 *p = 0;
1149 else
1150 *s = 0;
1151 pstrcat(s,s1);
1154 trim_string(s,NULL,"\\..");
1156 string_sub(s, "\\.\\", "\\");
1159 /*******************************************************************
1160 reduce a file name, removing .. elements.
1161 ********************************************************************/
1162 void unix_clean_name(char *s)
1164 char *p=NULL;
1166 DEBUG(3,("unix_clean_name [%s]\n",s));
1168 /* remove any double slashes */
1169 string_sub(s, "//","/");
1171 /* Remove leading ./ characters */
1172 if(strncmp(s, "./", 2) == 0) {
1173 trim_string(s, "./", NULL);
1174 if(*s == 0)
1175 pstrcpy(s,"./");
1178 while ((p = strstr(s,"/../")) != NULL)
1180 pstring s1;
1182 *p = 0;
1183 pstrcpy(s1,p+3);
1185 if ((p=strrchr(s,'/')) != NULL)
1186 *p = 0;
1187 else
1188 *s = 0;
1189 pstrcat(s,s1);
1192 trim_string(s,NULL,"/..");
1196 /*******************************************************************
1197 a wrapper for the normal chdir() function
1198 ********************************************************************/
1199 int ChDir(char *path)
1201 int res;
1202 static pstring LastDir="";
1204 if (strcsequal(path,".")) return(0);
1206 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1207 DEBUG(3,("chdir to %s\n",path));
1208 res = sys_chdir(path);
1209 if (!res)
1210 pstrcpy(LastDir,path);
1211 return(res);
1214 /* number of list structures for a caching GetWd function. */
1215 #define MAX_GETWDCACHE (50)
1217 struct
1219 ino_t inode;
1220 dev_t dev;
1221 char *text;
1222 BOOL valid;
1223 } ino_list[MAX_GETWDCACHE];
1225 BOOL use_getwd_cache=True;
1227 /*******************************************************************
1228 return the absolute current directory path
1229 ********************************************************************/
1230 char *GetWd(char *str)
1232 pstring s;
1233 static BOOL getwd_cache_init = False;
1234 struct stat st, st2;
1235 int i;
1237 *s = 0;
1239 if (!use_getwd_cache)
1240 return(sys_getwd(str));
1242 /* init the cache */
1243 if (!getwd_cache_init)
1245 getwd_cache_init = True;
1246 for (i=0;i<MAX_GETWDCACHE;i++)
1248 string_init(&ino_list[i].text,"");
1249 ino_list[i].valid = False;
1253 /* Get the inode of the current directory, if this doesn't work we're
1254 in trouble :-) */
1256 if (stat(".",&st) == -1)
1258 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1259 return(sys_getwd(str));
1263 for (i=0; i<MAX_GETWDCACHE; i++)
1264 if (ino_list[i].valid)
1267 /* If we have found an entry with a matching inode and dev number
1268 then find the inode number for the directory in the cached string.
1269 If this agrees with that returned by the stat for the current
1270 directory then all is o.k. (but make sure it is a directory all
1271 the same...) */
1273 if (st.st_ino == ino_list[i].inode &&
1274 st.st_dev == ino_list[i].dev)
1276 if (stat(ino_list[i].text,&st2) == 0)
1278 if (st.st_ino == st2.st_ino &&
1279 st.st_dev == st2.st_dev &&
1280 (st2.st_mode & S_IFMT) == S_IFDIR)
1282 pstrcpy (str, ino_list[i].text);
1284 /* promote it for future use */
1285 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1286 return (str);
1288 else
1290 /* If the inode is different then something's changed,
1291 scrub the entry and start from scratch. */
1292 ino_list[i].valid = False;
1299 /* We don't have the information to hand so rely on traditional methods.
1300 The very slow getcwd, which spawns a process on some systems, or the
1301 not quite so bad getwd. */
1303 if (!sys_getwd(s))
1305 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1306 return (NULL);
1309 pstrcpy(str,s);
1311 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1313 /* add it to the cache */
1314 i = MAX_GETWDCACHE - 1;
1315 string_set(&ino_list[i].text,s);
1316 ino_list[i].dev = st.st_dev;
1317 ino_list[i].inode = st.st_ino;
1318 ino_list[i].valid = True;
1320 /* put it at the top of the list */
1321 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1323 return (str);
1328 /*******************************************************************
1329 reduce a file name, removing .. elements and checking that
1330 it is below dir in the heirachy. This uses GetWd() and so must be run
1331 on the system that has the referenced file system.
1333 widelinks are allowed if widelinks is true
1334 ********************************************************************/
1335 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1337 #ifndef REDUCE_PATHS
1338 return True;
1339 #else
1340 pstring dir2;
1341 pstring wd;
1342 pstring base_name;
1343 pstring newname;
1344 char *p=NULL;
1345 BOOL relative = (*s != '/');
1347 *dir2 = *wd = *base_name = *newname = 0;
1349 if (widelinks)
1351 unix_clean_name(s);
1352 /* can't have a leading .. */
1353 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1355 DEBUG(3,("Illegal file name? (%s)\n",s));
1356 return(False);
1359 if (strlen(s) == 0)
1360 pstrcpy(s,"./");
1362 return(True);
1365 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1367 /* remove any double slashes */
1368 string_sub(s,"//","/");
1370 pstrcpy(base_name,s);
1371 p = strrchr(base_name,'/');
1373 if (!p)
1374 return(True);
1376 if (!GetWd(wd))
1378 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1379 return(False);
1382 if (ChDir(dir) != 0)
1384 DEBUG(0,("couldn't chdir to %s\n",dir));
1385 return(False);
1388 if (!GetWd(dir2))
1390 DEBUG(0,("couldn't getwd for %s\n",dir));
1391 ChDir(wd);
1392 return(False);
1396 if (p && (p != base_name))
1398 *p = 0;
1399 if (strcmp(p+1,".")==0)
1400 p[1]=0;
1401 if (strcmp(p+1,"..")==0)
1402 *p = '/';
1405 if (ChDir(base_name) != 0)
1407 ChDir(wd);
1408 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1409 return(False);
1412 if (!GetWd(newname))
1414 ChDir(wd);
1415 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1416 return(False);
1419 if (p && (p != base_name))
1421 pstrcat(newname,"/");
1422 pstrcat(newname,p+1);
1426 int l = strlen(dir2);
1427 if (dir2[l-1] == '/')
1428 l--;
1430 if (strncmp(newname,dir2,l) != 0)
1432 ChDir(wd);
1433 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1434 return(False);
1437 if (relative)
1439 if (newname[l] == '/')
1440 pstrcpy(s,newname + l + 1);
1441 else
1442 pstrcpy(s,newname+l);
1444 else
1445 pstrcpy(s,newname);
1448 ChDir(wd);
1450 if (strlen(s) == 0)
1451 pstrcpy(s,"./");
1453 DEBUG(3,("reduced to %s\n",s));
1454 return(True);
1455 #endif
1458 /****************************************************************************
1459 expand some *s
1460 ****************************************************************************/
1461 static void expand_one(char *Mask,int len)
1463 char *p1;
1464 while ((p1 = strchr(Mask,'*')) != NULL)
1466 int lfill = (len+1) - strlen(Mask);
1467 int l1= (p1 - Mask);
1468 pstring tmp;
1469 pstrcpy(tmp,Mask);
1470 memset(tmp+l1,'?',lfill);
1471 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1472 pstrcpy(Mask,tmp);
1476 /****************************************************************************
1477 expand a wildcard expression, replacing *s with ?s
1478 ****************************************************************************/
1479 void expand_mask(char *Mask,BOOL doext)
1481 pstring mbeg,mext;
1482 pstring dirpart;
1483 pstring filepart;
1484 BOOL hasdot = False;
1485 char *p1;
1486 BOOL absolute = (*Mask == '\\');
1488 *mbeg = *mext = *dirpart = *filepart = 0;
1490 /* parse the directory and filename */
1491 if (strchr(Mask,'\\'))
1492 dirname_dos(Mask,dirpart);
1494 filename_dos(Mask,filepart);
1496 pstrcpy(mbeg,filepart);
1497 if ((p1 = strchr(mbeg,'.')) != NULL)
1499 hasdot = True;
1500 *p1 = 0;
1501 p1++;
1502 pstrcpy(mext,p1);
1504 else
1506 pstrcpy(mext,"");
1507 if (strlen(mbeg) > 8)
1509 pstrcpy(mext,mbeg + 8);
1510 mbeg[8] = 0;
1514 if (*mbeg == 0)
1515 pstrcpy(mbeg,"????????");
1516 if ((*mext == 0) && doext && !hasdot)
1517 pstrcpy(mext,"???");
1519 if (strequal(mbeg,"*") && *mext==0)
1520 pstrcpy(mext,"*");
1522 /* expand *'s */
1523 expand_one(mbeg,8);
1524 if (*mext)
1525 expand_one(mext,3);
1527 pstrcpy(Mask,dirpart);
1528 if (*dirpart || absolute) pstrcat(Mask,"\\");
1529 pstrcat(Mask,mbeg);
1530 pstrcat(Mask,".");
1531 pstrcat(Mask,mext);
1533 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1537 /****************************************************************************
1538 does a string have any uppercase chars in it?
1539 ****************************************************************************/
1540 BOOL strhasupper(char *s)
1542 while (*s)
1544 #if !defined(KANJI_WIN95_COMPATIBILITY)
1546 * For completeness we should put in equivalent code for code pages
1547 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1548 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1549 * here. They both treat full width ascii characters as case senstive
1550 * filenames (ie. they don't do the work we do here).
1551 * JRA.
1554 if(lp_client_code_page() == KANJI_CODEPAGE)
1556 /* Win95 treats full width ascii characters as case sensitive. */
1557 if (is_shift_jis (*s))
1558 s += 2;
1559 else if (is_kana (*s))
1560 s++;
1561 else
1563 if (isupper(*s))
1564 return(True);
1565 s++;
1568 else
1569 #endif /* KANJI_WIN95_COMPATIBILITY */
1571 int skip = skip_multibyte_char( *s );
1572 if( skip != 0 )
1573 s += skip;
1574 else {
1575 if (isupper(*s))
1576 return(True);
1577 s++;
1581 return(False);
1584 /****************************************************************************
1585 does a string have any lowercase chars in it?
1586 ****************************************************************************/
1587 BOOL strhaslower(char *s)
1589 while (*s)
1591 #if !defined(KANJI_WIN95_COMPATIBILITY)
1593 * For completeness we should put in equivalent code for code pages
1594 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1595 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1596 * here. They both treat full width ascii characters as case senstive
1597 * filenames (ie. they don't do the work we do here).
1598 * JRA.
1601 if(lp_client_code_page() == KANJI_CODEPAGE)
1603 /* Win95 treats full width ascii characters as case sensitive. */
1604 if (is_shift_jis (*s))
1606 if (is_sj_upper (s[0], s[1]))
1607 return(True);
1608 if (is_sj_lower (s[0], s[1]))
1609 return (True);
1610 s += 2;
1612 else if (is_kana (*s))
1614 s++;
1616 else
1618 if (islower(*s))
1619 return(True);
1620 s++;
1623 else
1624 #endif /* KANJI_WIN95_COMPATIBILITY */
1626 int skip = skip_multibyte_char( *s );
1627 if( skip != 0 )
1628 s += skip;
1629 else {
1630 if (islower(*s))
1631 return(True);
1632 s++;
1636 return(False);
1639 /****************************************************************************
1640 find the number of chars in a string
1641 ****************************************************************************/
1642 int count_chars(char *s,char c)
1644 int count=0;
1646 #if !defined(KANJI_WIN95_COMPATIBILITY)
1648 * For completeness we should put in equivalent code for code pages
1649 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1650 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1651 * here. They both treat full width ascii characters as case senstive
1652 * filenames (ie. they don't do the work we do here).
1653 * JRA.
1656 if(lp_client_code_page() == KANJI_CODEPAGE)
1658 /* Win95 treats full width ascii characters as case sensitive. */
1659 while (*s)
1661 if (is_shift_jis (*s))
1662 s += 2;
1663 else
1665 if (*s == c)
1666 count++;
1667 s++;
1671 else
1672 #endif /* KANJI_WIN95_COMPATIBILITY */
1674 while (*s)
1676 int skip = skip_multibyte_char( *s );
1677 if( skip != 0 )
1678 s += skip;
1679 else {
1680 if (*s == c)
1681 count++;
1682 s++;
1686 return(count);
1690 /****************************************************************************
1691 make a dir struct
1692 ****************************************************************************/
1693 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1695 char *p;
1696 pstring mask2;
1698 pstrcpy(mask2,mask);
1700 if ((mode & aDIR) != 0)
1701 size = 0;
1703 memset(buf+1,' ',11);
1704 if ((p = strchr(mask2,'.')) != NULL)
1706 *p = 0;
1707 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1708 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1709 *p = '.';
1711 else
1712 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1714 bzero(buf+21,DIR_STRUCT_SIZE-21);
1715 CVAL(buf,21) = mode;
1716 put_dos_date(buf,22,date);
1717 SSVAL(buf,26,size & 0xFFFF);
1718 SSVAL(buf,28,size >> 16);
1719 StrnCpy(buf+30,fname,12);
1720 if (!case_sensitive)
1721 strupper(buf+30);
1722 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1726 /*******************************************************************
1727 close the low 3 fd's and open dev/null in their place
1728 ********************************************************************/
1729 void close_low_fds(void)
1731 int fd;
1732 int i;
1733 close(0); close(1); close(2);
1734 /* try and use up these file descriptors, so silly
1735 library routines writing to stdout etc won't cause havoc */
1736 for (i=0;i<3;i++) {
1737 fd = open("/dev/null",O_RDWR,0);
1738 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1739 if (fd < 0) {
1740 DEBUG(0,("Can't open /dev/null\n"));
1741 return;
1743 if (fd != i) {
1744 DEBUG(0,("Didn't get file descriptor %d\n",i));
1745 return;
1750 /****************************************************************************
1751 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1752 else
1753 if SYSV use O_NDELAY
1754 if BSD use FNDELAY
1755 ****************************************************************************/
1756 int set_blocking(int fd, BOOL set)
1758 int val;
1759 #ifdef O_NONBLOCK
1760 #define FLAG_TO_SET O_NONBLOCK
1761 #else
1762 #ifdef SYSV
1763 #define FLAG_TO_SET O_NDELAY
1764 #else /* BSD */
1765 #define FLAG_TO_SET FNDELAY
1766 #endif
1767 #endif
1769 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1770 return -1;
1771 if(set) /* Turn blocking on - ie. clear nonblock flag */
1772 val &= ~FLAG_TO_SET;
1773 else
1774 val |= FLAG_TO_SET;
1775 return fcntl( fd, F_SETFL, val);
1776 #undef FLAG_TO_SET
1780 /****************************************************************************
1781 write to a socket
1782 ****************************************************************************/
1783 int write_socket(int fd,char *buf,int len)
1785 int ret=0;
1787 if (passive)
1788 return(len);
1789 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1790 ret = write_data(fd,buf,len);
1792 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1793 if(ret <= 0)
1794 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
1795 len, fd, strerror(errno) ));
1797 return(ret);
1800 /****************************************************************************
1801 read from a socket
1802 ****************************************************************************/
1803 int read_udp_socket(int fd,char *buf,int len)
1805 int ret;
1806 struct sockaddr_in sock;
1807 int socklen;
1809 socklen = sizeof(sock);
1810 bzero((char *)&sock,socklen);
1811 bzero((char *)&lastip,sizeof(lastip));
1812 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1813 if (ret <= 0) {
1814 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1815 return(0);
1818 lastip = sock.sin_addr;
1819 lastport = ntohs(sock.sin_port);
1821 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1822 inet_ntoa(lastip), lastport, ret));
1824 return(ret);
1827 /****************************************************************************
1828 read data from a device with a timout in msec.
1829 mincount = if timeout, minimum to read before returning
1830 maxcount = number to be read.
1831 ****************************************************************************/
1832 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1834 fd_set fds;
1835 int selrtn;
1836 int readret;
1837 int nread = 0;
1838 struct timeval timeout;
1840 /* just checking .... */
1841 if (maxcnt <= 0) return(0);
1843 smb_read_error = 0;
1845 /* Blocking read */
1846 if (time_out <= 0) {
1847 if (mincnt == 0) mincnt = maxcnt;
1849 while (nread < mincnt) {
1850 #ifdef WITH_SSL
1851 if(fd == sslFd){
1852 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1853 }else{
1854 readret = read(fd, buf + nread, maxcnt - nread);
1856 #else /* WITH_SSL */
1857 readret = read(fd, buf + nread, maxcnt - nread);
1858 #endif /* WITH_SSL */
1860 if (readret == 0) {
1861 smb_read_error = READ_EOF;
1862 return -1;
1865 if (readret == -1) {
1866 smb_read_error = READ_ERROR;
1867 return -1;
1869 nread += readret;
1871 return(nread);
1874 /* Most difficult - timeout read */
1875 /* If this is ever called on a disk file and
1876 mincnt is greater then the filesize then
1877 system performance will suffer severely as
1878 select always return true on disk files */
1880 /* Set initial timeout */
1881 timeout.tv_sec = time_out / 1000;
1882 timeout.tv_usec = 1000 * (time_out % 1000);
1884 for (nread=0; nread<mincnt; )
1886 FD_ZERO(&fds);
1887 FD_SET(fd,&fds);
1889 selrtn = sys_select(fd+1,&fds,&timeout);
1891 /* Check if error */
1892 if(selrtn == -1) {
1893 /* something is wrong. Maybe the socket is dead? */
1894 smb_read_error = READ_ERROR;
1895 return -1;
1898 /* Did we timeout ? */
1899 if (selrtn == 0) {
1900 smb_read_error = READ_TIMEOUT;
1901 return -1;
1904 #ifdef WITH_SSL
1905 if(fd == sslFd){
1906 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1907 }else{
1908 readret = read(fd, buf + nread, maxcnt - nread);
1910 #else /* WITH_SSL */
1911 readret = read(fd, buf+nread, maxcnt-nread);
1912 #endif /* WITH_SSL */
1914 if (readret == 0) {
1915 /* we got EOF on the file descriptor */
1916 smb_read_error = READ_EOF;
1917 return -1;
1920 if (readret == -1) {
1921 /* the descriptor is probably dead */
1922 smb_read_error = READ_ERROR;
1923 return -1;
1926 nread += readret;
1929 /* Return the number we got */
1930 return(nread);
1933 /****************************************************************************
1934 read data from the client. Maxtime is in milliseconds
1935 ****************************************************************************/
1936 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1938 fd_set fds;
1939 int selrtn;
1940 int nread;
1941 struct timeval timeout;
1943 FD_ZERO(&fds);
1944 FD_SET(fd,&fds);
1946 timeout.tv_sec = maxtime / 1000;
1947 timeout.tv_usec = (maxtime % 1000) * 1000;
1949 selrtn = sys_select(fd+1,&fds,maxtime>0?&timeout:NULL);
1951 if (!FD_ISSET(fd,&fds))
1952 return 0;
1954 nread = read_udp_socket(fd, buffer, bufsize);
1956 /* return the number got */
1957 return(nread);
1960 /*******************************************************************
1961 find the difference in milliseconds between two struct timeval
1962 values
1963 ********************************************************************/
1964 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1966 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1967 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1970 /****************************************************************************
1971 send a keepalive packet (rfc1002)
1972 ****************************************************************************/
1973 BOOL send_keepalive(int client)
1975 unsigned char buf[4];
1977 buf[0] = 0x85;
1978 buf[1] = buf[2] = buf[3] = 0;
1980 return(write_data(client,(char *)buf,4) == 4);
1985 /****************************************************************************
1986 read data from the client, reading exactly N bytes.
1987 ****************************************************************************/
1988 int read_data(int fd,char *buffer,int N)
1990 int ret;
1991 int total=0;
1993 smb_read_error = 0;
1995 while (total < N)
1997 #ifdef WITH_SSL
1998 if(fd == sslFd){
1999 ret = SSL_read(ssl, buffer + total, N - total);
2000 }else{
2001 ret = read(fd,buffer + total,N - total);
2003 #else /* WITH_SSL */
2004 ret = read(fd,buffer + total,N - total);
2005 #endif /* WITH_SSL */
2007 if (ret == 0)
2009 smb_read_error = READ_EOF;
2010 return 0;
2012 if (ret == -1)
2014 smb_read_error = READ_ERROR;
2015 return -1;
2017 total += ret;
2019 return total;
2023 /****************************************************************************
2024 write data to a fd
2025 ****************************************************************************/
2026 int write_data(int fd,char *buffer,int N)
2028 int total=0;
2029 int ret;
2031 while (total < N)
2033 #ifdef WITH_SSL
2034 if(fd == sslFd){
2035 ret = SSL_write(ssl,buffer + total,N - total);
2036 }else{
2037 ret = write(fd,buffer + total,N - total);
2039 #else /* WITH_SSL */
2040 ret = write(fd,buffer + total,N - total);
2041 #endif /* WITH_SSL */
2043 if (ret == -1) return -1;
2044 if (ret == 0) return total;
2046 total += ret;
2048 return total;
2052 /****************************************************************************
2053 transfer some data between two fd's
2054 ****************************************************************************/
2055 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2057 static char *buf=NULL;
2058 static int size=0;
2059 char *buf1,*abuf;
2060 int total = 0;
2062 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2064 if (size == 0) {
2065 size = lp_readsize();
2066 size = MAX(size,1024);
2069 while (!buf && size>0) {
2070 buf = (char *)Realloc(buf,size+8);
2071 if (!buf) size /= 2;
2074 if (!buf) {
2075 DEBUG(0,("Can't allocate transfer buffer!\n"));
2076 exit(1);
2079 abuf = buf + (align%8);
2081 if (header)
2082 n += headlen;
2084 while (n > 0)
2086 int s = MIN(n,size);
2087 int ret,ret2=0;
2089 ret = 0;
2091 if (header && (headlen >= MIN(s,1024))) {
2092 buf1 = header;
2093 s = headlen;
2094 ret = headlen;
2095 headlen = 0;
2096 header = NULL;
2097 } else {
2098 buf1 = abuf;
2101 if (header && headlen > 0)
2103 ret = MIN(headlen,size);
2104 memcpy(buf1,header,ret);
2105 headlen -= ret;
2106 header += ret;
2107 if (headlen <= 0) header = NULL;
2110 if (s > ret)
2111 ret += read(infd,buf1+ret,s-ret);
2113 if (ret > 0)
2115 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2116 if (ret2 > 0) total += ret2;
2117 /* if we can't write then dump excess data */
2118 if (ret2 != ret)
2119 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2121 if (ret <= 0 || ret2 != ret)
2122 return(total);
2123 n -= ret;
2125 return(total);
2129 /****************************************************************************
2130 read 4 bytes of a smb packet and return the smb length of the packet
2131 store the result in the buffer
2132 This version of the function will return a length of zero on receiving
2133 a keepalive packet.
2134 ****************************************************************************/
2135 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2137 int len=0, msg_type;
2138 BOOL ok=False;
2140 while (!ok)
2142 if (timeout > 0)
2143 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2144 else
2145 ok = (read_data(fd,inbuf,4) == 4);
2147 if (!ok)
2148 return(-1);
2150 len = smb_len(inbuf);
2151 msg_type = CVAL(inbuf,0);
2153 if (msg_type == 0x85)
2154 DEBUG(5,("Got keepalive packet\n"));
2157 DEBUG(10,("got smb length of %d\n",len));
2159 return(len);
2162 /****************************************************************************
2163 read 4 bytes of a smb packet and return the smb length of the packet
2164 store the result in the buffer. This version of the function will
2165 never return a session keepalive (length of zero).
2166 ****************************************************************************/
2167 int read_smb_length(int fd,char *inbuf,int timeout)
2169 int len;
2171 for(;;)
2173 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2175 if(len < 0)
2176 return len;
2178 /* Ignore session keepalives. */
2179 if(CVAL(inbuf,0) != 0x85)
2180 break;
2183 return len;
2186 /****************************************************************************
2187 read an smb from a fd. Note that the buffer *MUST* be of size
2188 BUFFER_SIZE+SAFETY_MARGIN.
2189 The timeout is in milli seconds.
2191 This function will return on a
2192 receipt of a session keepalive packet.
2193 ****************************************************************************/
2194 BOOL receive_smb(int fd,char *buffer, int timeout)
2196 int len,ret;
2198 smb_read_error = 0;
2200 bzero(buffer,smb_size + 100);
2202 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2203 if (len < 0)
2204 return(False);
2206 if (len > BUFFER_SIZE) {
2207 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2208 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2209 exit(1);
2212 if(len > 0) {
2213 ret = read_data(fd,buffer+4,len);
2214 if (ret != len) {
2215 smb_read_error = READ_ERROR;
2216 return False;
2219 return(True);
2222 /****************************************************************************
2223 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2224 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2225 The timeout is in milli seconds
2227 This is exactly the same as receive_smb except that it never returns
2228 a session keepalive packet (just as receive_smb used to do).
2229 receive_smb was changed to return keepalives as the oplock processing means this call
2230 should never go into a blocking read.
2231 ****************************************************************************/
2233 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2235 BOOL ret;
2237 for(;;)
2239 ret = receive_smb(fd, buffer, timeout);
2241 if(ret == False)
2242 return ret;
2244 /* Ignore session keepalive packets. */
2245 if(CVAL(buffer,0) != 0x85)
2246 break;
2248 return ret;
2251 /****************************************************************************
2252 read a message from a udp fd.
2253 The timeout is in milli seconds
2254 ****************************************************************************/
2255 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2257 struct sockaddr_in from;
2258 int fromlen = sizeof(from);
2259 int32 msg_len = 0;
2261 smb_read_error = 0;
2263 if(timeout != 0)
2265 struct timeval to;
2266 fd_set fds;
2267 int selrtn;
2269 FD_ZERO(&fds);
2270 FD_SET(fd,&fds);
2272 to.tv_sec = timeout / 1000;
2273 to.tv_usec = (timeout % 1000) * 1000;
2275 selrtn = sys_select(fd+1,&fds,&to);
2277 /* Check if error */
2278 if(selrtn == -1)
2280 /* something is wrong. Maybe the socket is dead? */
2281 smb_read_error = READ_ERROR;
2282 return False;
2285 /* Did we timeout ? */
2286 if (selrtn == 0)
2288 smb_read_error = READ_TIMEOUT;
2289 return False;
2294 * Read a loopback udp message.
2296 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2297 buffer_len - UDP_CMD_HEADER_LEN, 0,
2298 (struct sockaddr *)&from, &fromlen);
2300 if(msg_len < 0)
2302 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2303 return False;
2306 /* Validate message length. */
2307 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2309 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2310 msg_len,
2311 buffer_len - UDP_CMD_HEADER_LEN));
2312 return False;
2315 /* Validate message from address (must be localhost). */
2316 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2318 DEBUG(0,("receive_local_message: invalid 'from' address \
2319 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2320 return False;
2323 /* Setup the message header */
2324 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2325 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2327 return True;
2330 /****************************************************************************
2331 structure to hold a linked list of local messages.
2332 for processing.
2333 ****************************************************************************/
2335 typedef struct {
2336 ubi_slNode msg_next;
2337 char *msg_buf;
2338 int msg_len;
2339 } pending_message_list;
2341 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
2343 /****************************************************************************
2344 Function to push a message onto the tail of a linked list of smb messages ready
2345 for processing.
2346 ****************************************************************************/
2348 static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
2350 pending_message_list *msg = (pending_message_list *)
2351 malloc(sizeof(pending_message_list));
2353 if(msg == NULL)
2355 DEBUG(0,("push_local_message: malloc fail (1)\n"));
2356 return False;
2359 msg->msg_buf = (char *)malloc(msg_len);
2360 if(msg->msg_buf == NULL)
2362 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2363 free((char *)msg);
2364 return False;
2367 memcpy(msg->msg_buf, buf, msg_len);
2368 msg->msg_len = msg_len;
2370 ubi_slAddTail( list_head, msg);
2372 return True;
2375 /****************************************************************************
2376 Function to push a smb message onto a linked list of local smb messages ready
2377 for processing.
2378 ****************************************************************************/
2380 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
2382 return push_local_message(&smb_oplock_queue, buf, msg_len);
2385 /****************************************************************************
2386 Do a select on an two fd's - with timeout.
2388 If a local udp message has been pushed onto the
2389 queue (this can only happen during oplock break
2390 processing) return this first.
2392 If a pending smb message has been pushed onto the
2393 queue (this can only happen during oplock break
2394 processing) return this next.
2396 If the first smbfd is ready then read an smb from it.
2397 if the second (loopback UDP) fd is ready then read a message
2398 from it and setup the buffer header to identify the length
2399 and from address.
2400 Returns False on timeout or error.
2401 Else returns True.
2403 The timeout is in milli seconds
2404 ****************************************************************************/
2405 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2406 char *buffer, int buffer_len,
2407 int timeout, BOOL *got_smb)
2409 fd_set fds;
2410 int selrtn;
2411 struct timeval to;
2413 smb_read_error = 0;
2415 *got_smb = False;
2418 * Check to see if we already have a message on the smb queue.
2419 * If so - copy and return it.
2422 if(ubi_slCount(&smb_oplock_queue) != 0)
2424 pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
2425 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2427 /* Free the message we just copied. */
2428 free((char *)msg->msg_buf);
2429 free((char *)msg);
2430 *got_smb = True;
2432 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2433 return True;
2436 FD_ZERO(&fds);
2437 FD_SET(smbfd,&fds);
2438 FD_SET(oplock_fd,&fds);
2440 to.tv_sec = timeout / 1000;
2441 to.tv_usec = (timeout % 1000) * 1000;
2443 selrtn = sys_select(MAX(smbfd,oplock_fd)+1,&fds,timeout>0?&to:NULL);
2445 /* Check if error */
2446 if(selrtn == -1) {
2447 /* something is wrong. Maybe the socket is dead? */
2448 smb_read_error = READ_ERROR;
2449 return False;
2452 /* Did we timeout ? */
2453 if (selrtn == 0) {
2454 smb_read_error = READ_TIMEOUT;
2455 return False;
2458 if (FD_ISSET(smbfd,&fds))
2460 *got_smb = True;
2461 return receive_smb(smbfd, buffer, 0);
2463 else
2465 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2469 /****************************************************************************
2470 send an smb to a fd
2471 ****************************************************************************/
2472 BOOL send_smb(int fd,char *buffer)
2474 int len;
2475 int ret,nwritten=0;
2476 len = smb_len(buffer) + 4;
2478 while (nwritten < len)
2480 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2481 if (ret <= 0)
2483 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2484 close_sockets();
2485 exit(1);
2487 nwritten += ret;
2491 return True;
2495 /****************************************************************************
2496 find a pointer to a netbios name
2497 ****************************************************************************/
2498 char *name_ptr(char *buf,int ofs)
2500 unsigned char c = *(unsigned char *)(buf+ofs);
2502 if ((c & 0xC0) == 0xC0)
2504 uint16 l;
2505 char p[2];
2506 memcpy(p,buf+ofs,2);
2507 p[0] &= ~0xC0;
2508 l = RSVAL(p,0);
2509 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2510 return(buf + l);
2512 else
2513 return(buf+ofs);
2516 /****************************************************************************
2517 extract a netbios name from a buf
2518 ****************************************************************************/
2519 int name_extract(char *buf,int ofs,char *name)
2521 char *p = name_ptr(buf,ofs);
2522 int d = PTR_DIFF(p,buf+ofs);
2523 pstrcpy(name,"");
2524 if (d < -50 || d > 50) return(0);
2525 return(name_interpret(p,name));
2528 /****************************************************************************
2529 return the total storage length of a mangled name
2530 ****************************************************************************/
2531 int name_len( char *s )
2533 int len;
2535 /* If the two high bits of the byte are set, return 2. */
2536 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2537 return(2);
2539 /* Add up the length bytes. */
2540 for( len = 1; (*s); s += (*s) + 1 )
2542 len += *s + 1;
2545 return( len );
2546 } /* name_len */
2548 /****************************************************************************
2549 send a single packet to a port on another machine
2550 ****************************************************************************/
2551 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2553 BOOL ret;
2554 int out_fd;
2555 struct sockaddr_in sock_out;
2557 if (passive)
2558 return(True);
2560 /* create a socket to write to */
2561 out_fd = socket(AF_INET, type, 0);
2562 if (out_fd == -1)
2564 DEBUG(0,("socket failed"));
2565 return False;
2568 /* set the address and port */
2569 bzero((char *)&sock_out,sizeof(sock_out));
2570 putip((char *)&sock_out.sin_addr,(char *)&ip);
2571 sock_out.sin_port = htons( port );
2572 sock_out.sin_family = AF_INET;
2574 if (DEBUGLEVEL > 0)
2575 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2576 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2578 /* send it */
2579 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2581 if (!ret)
2582 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2583 inet_ntoa(ip),port,strerror(errno)));
2585 close(out_fd);
2586 return(ret);
2589 /*******************************************************************
2590 sleep for a specified number of milliseconds
2591 ********************************************************************/
2592 void msleep(int t)
2594 int tdiff=0;
2595 struct timeval tval,t1,t2;
2596 fd_set fds;
2598 GetTimeOfDay(&t1);
2599 GetTimeOfDay(&t2);
2601 while (tdiff < t) {
2602 tval.tv_sec = (t-tdiff)/1000;
2603 tval.tv_usec = 1000*((t-tdiff)%1000);
2605 FD_ZERO(&fds);
2606 errno = 0;
2607 sys_select(0,&fds,&tval);
2609 GetTimeOfDay(&t2);
2610 tdiff = TvalDiff(&t1,&t2);
2614 /****************************************************************************
2615 check if a string is part of a list
2616 ****************************************************************************/
2617 BOOL in_list(char *s,char *list,BOOL casesensitive)
2619 pstring tok;
2620 char *p=list;
2622 if (!list) return(False);
2624 while (next_token(&p,tok,LIST_SEP,sizeof(tok)))
2626 if (casesensitive) {
2627 if (strcmp(tok,s) == 0)
2628 return(True);
2629 } else {
2630 if (StrCaseCmp(tok,s) == 0)
2631 return(True);
2634 return(False);
2637 /* this is used to prevent lots of mallocs of size 1 */
2638 static char *null_string = NULL;
2640 /****************************************************************************
2641 set a string value, allocing the space for the string
2642 ****************************************************************************/
2643 BOOL string_init(char **dest,char *src)
2645 int l;
2646 if (!src)
2647 src = "";
2649 l = strlen(src);
2651 if (l == 0)
2653 if (!null_string)
2654 null_string = (char *)malloc(1);
2656 *null_string = 0;
2657 *dest = null_string;
2659 else
2661 (*dest) = (char *)malloc(l+1);
2662 if ((*dest) == NULL) {
2663 DEBUG(0,("Out of memory in string_init\n"));
2664 return False;
2667 pstrcpy(*dest,src);
2669 return(True);
2672 /****************************************************************************
2673 free a string value
2674 ****************************************************************************/
2675 void string_free(char **s)
2677 if (!s || !(*s)) return;
2678 if (*s == null_string)
2679 *s = NULL;
2680 if (*s) free(*s);
2681 *s = NULL;
2684 /****************************************************************************
2685 set a string value, allocing the space for the string, and deallocating any
2686 existing space
2687 ****************************************************************************/
2688 BOOL string_set(char **dest,char *src)
2690 string_free(dest);
2692 return(string_init(dest,src));
2695 /****************************************************************************
2696 substitute a string for a pattern in another string. Make sure there is
2697 enough room!
2699 This routine looks for pattern in s and replaces it with
2700 insert. It may do multiple replacements.
2702 return True if a substitution was done.
2703 ****************************************************************************/
2704 BOOL string_sub(char *s,char *pattern,char *insert)
2706 BOOL ret = False;
2707 char *p;
2708 int ls,lp,li;
2710 if (!insert || !pattern || !s) return(False);
2712 ls = strlen(s);
2713 lp = strlen(pattern);
2714 li = strlen(insert);
2716 if (!*pattern) return(False);
2718 while (lp <= ls && (p = strstr(s,pattern)))
2720 ret = True;
2721 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2722 memcpy(p,insert,li);
2723 s = p + li;
2724 ls = strlen(s);
2726 return(ret);
2729 /*********************************************************
2730 * Recursive routine that is called by unix_mask_match.
2731 * Does the actual matching. This is the 'original code'
2732 * used by the unix matcher.
2733 *********************************************************/
2734 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2736 char *p;
2738 for( p = regexp; *p && *str; ) {
2739 switch(*p) {
2740 case '?':
2741 str++; p++;
2742 break;
2744 case '*':
2745 /* Look for a character matching
2746 the one after the '*' */
2747 p++;
2748 if(!*p)
2749 return True; /* Automatic match */
2750 while(*str) {
2751 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2752 str++;
2753 if(unix_do_match(str,p,case_sig))
2754 return True;
2755 if(!*str)
2756 return False;
2757 else
2758 str++;
2760 return False;
2762 default:
2763 if(case_sig) {
2764 if(*str != *p)
2765 return False;
2766 } else {
2767 if(toupper(*str) != toupper(*p))
2768 return False;
2770 str++, p++;
2771 break;
2774 if(!*p && !*str)
2775 return True;
2777 if (!*p && str[0] == '.' && str[1] == 0)
2778 return(True);
2780 if (!*str && *p == '?')
2782 while (*p == '?') p++;
2783 return(!*p);
2786 if(!*str && (*p == '*' && p[1] == '\0'))
2787 return True;
2788 return False;
2792 /*********************************************************
2793 * Routine to match a given string with a regexp - uses
2794 * simplified regexp that takes * and ? only. Case can be
2795 * significant or not.
2796 * This is the 'original code' used by the unix matcher.
2797 *********************************************************/
2799 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2801 char *p;
2802 pstring p1, p2;
2803 fstring ebase,eext,sbase,sext;
2805 BOOL matched;
2807 /* Make local copies of str and regexp */
2808 StrnCpy(p1,regexp,sizeof(pstring)-1);
2809 StrnCpy(p2,str,sizeof(pstring)-1);
2811 if (!strchr(p2,'.')) {
2812 pstrcat(p2,".");
2815 /* Remove any *? and ** as they are meaningless */
2816 for(p = p1; *p; p++)
2817 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2818 (void)pstrcpy( &p[1], &p[2]);
2820 if (strequal(p1,"*")) return(True);
2822 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2824 if (trans2) {
2825 fstrcpy(ebase,p1);
2826 fstrcpy(sbase,p2);
2827 } else {
2828 if ((p=strrchr(p1,'.'))) {
2829 *p = 0;
2830 fstrcpy(ebase,p1);
2831 fstrcpy(eext,p+1);
2832 } else {
2833 fstrcpy(ebase,p1);
2834 eext[0] = 0;
2837 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2838 *p = 0;
2839 fstrcpy(sbase,p2);
2840 fstrcpy(sext,p+1);
2841 } else {
2842 fstrcpy(sbase,p2);
2843 fstrcpy(sext,"");
2847 matched = unix_do_match(sbase,ebase,case_sig) &&
2848 (trans2 || unix_do_match(sext,eext,case_sig));
2850 DEBUG(8,("unix_mask_match returning %d\n", matched));
2852 return matched;
2855 /*********************************************************
2856 * Recursive routine that is called by mask_match.
2857 * Does the actual matching. Returns True if matched,
2858 * False if failed. This is the 'new' NT style matcher.
2859 *********************************************************/
2861 BOOL do_match(char *str, char *regexp, int case_sig)
2863 char *p;
2865 for( p = regexp; *p && *str; ) {
2866 switch(*p) {
2867 case '?':
2868 str++; p++;
2869 break;
2871 case '*':
2872 /* Look for a character matching
2873 the one after the '*' */
2874 p++;
2875 if(!*p)
2876 return True; /* Automatic match */
2877 while(*str) {
2878 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2879 str++;
2880 /* Now eat all characters that match, as
2881 we want the *last* character to match. */
2882 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2883 str++;
2884 str--; /* We've eaten the match char after the '*' */
2885 if(do_match(str,p,case_sig)) {
2886 return True;
2888 if(!*str) {
2889 return False;
2890 } else {
2891 str++;
2894 return False;
2896 default:
2897 if(case_sig) {
2898 if(*str != *p) {
2899 return False;
2901 } else {
2902 if(toupper(*str) != toupper(*p)) {
2903 return False;
2906 str++, p++;
2907 break;
2911 if(!*p && !*str)
2912 return True;
2914 if (!*p && str[0] == '.' && str[1] == 0) {
2915 return(True);
2918 if (!*str && *p == '?') {
2919 while (*p == '?')
2920 p++;
2921 return(!*p);
2924 if(!*str && (*p == '*' && p[1] == '\0')) {
2925 return True;
2928 return False;
2932 /*********************************************************
2933 * Routine to match a given string with a regexp - uses
2934 * simplified regexp that takes * and ? only. Case can be
2935 * significant or not.
2936 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2937 * This is the new 'NT style' matcher.
2938 *********************************************************/
2940 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2942 char *p;
2943 pstring t_pattern, t_filename, te_pattern, te_filename;
2944 fstring ebase,eext,sbase,sext;
2946 BOOL matched = False;
2948 /* Make local copies of str and regexp */
2949 pstrcpy(t_pattern,regexp);
2950 pstrcpy(t_filename,str);
2952 #if 0
2954 * Not sure if this is a good idea. JRA.
2956 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2957 trans2 = False;
2958 #endif
2960 #if 0
2961 if (!strchr(t_filename,'.')) {
2962 pstrcat(t_filename,".");
2964 #endif
2966 /* Remove any *? and ** as they are meaningless */
2967 string_sub(t_pattern, "*?", "*");
2968 string_sub(t_pattern, "**", "*");
2970 if (strequal(t_pattern,"*"))
2971 return(True);
2973 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2975 if(trans2) {
2977 * Match each component of the regexp, split up by '.'
2978 * characters.
2980 char *fp, *rp, *cp2, *cp1;
2981 BOOL last_wcard_was_star = False;
2982 int num_path_components, num_regexp_components;
2984 pstrcpy(te_pattern,t_pattern);
2985 pstrcpy(te_filename,t_filename);
2987 * Remove multiple "*." patterns.
2989 string_sub(te_pattern, "*.*.", "*.");
2990 num_regexp_components = count_chars(te_pattern, '.');
2991 num_path_components = count_chars(te_filename, '.');
2994 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2996 if(num_regexp_components == 0)
2997 matched = do_match( te_filename, te_pattern, case_sig);
2998 else {
2999 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
3000 fp = strchr(cp2, '.');
3001 if(fp)
3002 *fp = '\0';
3003 rp = strchr(cp1, '.');
3004 if(rp)
3005 *rp = '\0';
3007 if(cp1[strlen(cp1)-1] == '*')
3008 last_wcard_was_star = True;
3009 else
3010 last_wcard_was_star = False;
3012 if(!do_match(cp2, cp1, case_sig))
3013 break;
3015 cp1 = rp ? rp + 1 : NULL;
3016 cp2 = fp ? fp + 1 : "";
3018 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3019 /* Eat the extra path components. */
3020 int i;
3022 for(i = 0; i < num_path_components - num_regexp_components; i++) {
3023 fp = strchr(cp2, '.');
3024 if(fp)
3025 *fp = '\0';
3027 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3028 cp2 = fp ? fp + 1 : "";
3029 break;
3031 cp2 = fp ? fp + 1 : "";
3033 num_path_components -= i;
3036 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3037 matched = True;
3039 } else {
3041 /* -------------------------------------------------
3042 * Behaviour of Win95
3043 * for 8.3 filenames and 8.3 Wildcards
3044 * -------------------------------------------------
3046 if (strequal (t_filename, ".")) {
3048 * Patterns: *.* *. ?. ? are valid
3051 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3052 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3053 matched = True;
3054 } else if (strequal (t_filename, "..")) {
3056 * Patterns: *.* *. ?. ? *.? are valid
3059 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3060 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3061 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3062 matched = True;
3063 } else {
3065 if ((p = strrchr (t_pattern, '.'))) {
3067 * Wildcard has a suffix.
3069 *p = 0;
3070 fstrcpy (ebase, t_pattern);
3071 if (p[1]) {
3072 fstrcpy (eext, p + 1);
3073 } else {
3074 /* pattern ends in DOT: treat as if there is no DOT */
3075 *eext = 0;
3076 if (strequal (ebase, "*"))
3077 return (True);
3079 } else {
3081 * No suffix for wildcard.
3083 fstrcpy (ebase, t_pattern);
3084 eext[0] = 0;
3087 p = strrchr (t_filename, '.');
3088 if (p && (p[1] == 0) ) {
3090 * Filename has an extension of '.' only.
3092 *p = 0; /* nuke dot at end of string */
3093 p = 0; /* and treat it as if there is no extension */
3096 if (p) {
3098 * Filename has an extension.
3100 *p = 0;
3101 fstrcpy (sbase, t_filename);
3102 fstrcpy (sext, p + 1);
3103 if (*eext) {
3104 matched = do_match(sbase, ebase, case_sig)
3105 && do_match(sext, eext, case_sig);
3106 } else {
3107 /* pattern has no extension */
3108 /* Really: match complete filename with pattern ??? means exactly 3 chars */
3109 matched = do_match(str, ebase, case_sig);
3111 } else {
3113 * Filename has no extension.
3115 fstrcpy (sbase, t_filename);
3116 fstrcpy (sext, "");
3117 if (*eext) {
3118 /* pattern has extension */
3119 matched = do_match(sbase, ebase, case_sig)
3120 && do_match(sext, eext, case_sig);
3121 } else {
3122 matched = do_match(sbase, ebase, case_sig);
3123 #ifdef EMULATE_WEIRD_W95_MATCHING
3125 * Even Microsoft has some problems
3126 * Behaviour Win95 -> local disk
3127 * is different from Win95 -> smb drive from Nt 4.0
3128 * This branch would reflect the Win95 local disk behaviour
3130 if (!matched) {
3131 /* a? matches aa and a in w95 */
3132 fstrcat (sbase, ".");
3133 matched = do_match(sbase, ebase, case_sig);
3135 #endif
3141 DEBUG(8,("mask_match returning %d\n", matched));
3143 return matched;
3146 /****************************************************************************
3147 become a daemon, discarding the controlling terminal
3148 ****************************************************************************/
3149 void become_daemon(void)
3151 if (fork()) {
3152 _exit(0);
3155 /* detach from the terminal */
3156 #ifdef HAVE_SETSID
3157 setsid();
3158 #elif defined(TIOCNOTTY)
3160 int i = open("/dev/tty", O_RDWR);
3161 if (i != -1) {
3162 ioctl(i, (int) TIOCNOTTY, (char *)0);
3163 close(i);
3166 #endif /* HAVE_SETSID */
3168 /* Close fd's 0,1,2. Needed if started by rsh */
3169 close_low_fds();
3173 /****************************************************************************
3174 put up a yes/no prompt
3175 ****************************************************************************/
3176 BOOL yesno(char *p)
3178 pstring ans;
3179 printf("%s",p);
3181 if (!fgets(ans,sizeof(ans)-1,stdin))
3182 return(False);
3184 if (*ans == 'y' || *ans == 'Y')
3185 return(True);
3187 return(False);
3190 /****************************************************************************
3191 read a line from a file with possible \ continuation chars.
3192 Blanks at the start or end of a line are stripped.
3193 The string will be allocated if s2 is NULL
3194 ****************************************************************************/
3195 char *fgets_slash(char *s2,int maxlen,FILE *f)
3197 char *s=s2;
3198 int len = 0;
3199 int c;
3200 BOOL start_of_line = True;
3202 if (feof(f))
3203 return(NULL);
3205 if (!s2)
3207 maxlen = MIN(maxlen,8);
3208 s = (char *)Realloc(s,maxlen);
3211 if (!s || maxlen < 2) return(NULL);
3213 *s = 0;
3215 while (len < maxlen-1)
3217 c = getc(f);
3218 switch (c)
3220 case '\r':
3221 break;
3222 case '\n':
3223 while (len > 0 && s[len-1] == ' ')
3225 s[--len] = 0;
3227 if (len > 0 && s[len-1] == '\\')
3229 s[--len] = 0;
3230 start_of_line = True;
3231 break;
3233 return(s);
3234 case EOF:
3235 if (len <= 0 && !s2)
3236 free(s);
3237 return(len>0?s:NULL);
3238 case ' ':
3239 if (start_of_line)
3240 break;
3241 default:
3242 start_of_line = False;
3243 s[len++] = c;
3244 s[len] = 0;
3246 if (!s2 && len > maxlen-3)
3248 maxlen *= 2;
3249 s = (char *)Realloc(s,maxlen);
3250 if (!s) return(NULL);
3253 return(s);
3258 /****************************************************************************
3259 set the length of a file from a filedescriptor.
3260 Returns 0 on success, -1 on failure.
3261 ****************************************************************************/
3262 int set_filelen(int fd, long len)
3264 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3265 extend a file with ftruncate. Provide alternate implementation
3266 for this */
3268 #ifdef HAVE_FTRUNCATE_EXTEND
3269 return ftruncate(fd, len);
3270 #else
3271 struct stat st;
3272 char c = 0;
3273 long currpos = lseek(fd, 0L, SEEK_CUR);
3275 if(currpos < 0)
3276 return -1;
3277 /* Do an fstat to see if the file is longer than
3278 the requested size (call ftruncate),
3279 or shorter, in which case seek to len - 1 and write 1
3280 byte of zero */
3281 if(fstat(fd, &st)<0)
3282 return -1;
3284 #ifdef S_ISFIFO
3285 if (S_ISFIFO(st.st_mode)) return 0;
3286 #endif
3288 if(st.st_size == len)
3289 return 0;
3290 if(st.st_size > len)
3291 return ftruncate(fd, len);
3293 if(lseek(fd, len-1, SEEK_SET) != len -1)
3294 return -1;
3295 if(write(fd, &c, 1)!=1)
3296 return -1;
3297 /* Seek to where we were */
3298 lseek(fd, currpos, SEEK_SET);
3299 return 0;
3300 #endif
3304 /****************************************************************************
3305 return the byte checksum of some data
3306 ****************************************************************************/
3307 int byte_checksum(char *buf,int len)
3309 unsigned char *p = (unsigned char *)buf;
3310 int ret = 0;
3311 while (len--)
3312 ret += *p++;
3313 return(ret);
3318 #ifdef HPUX
3319 /****************************************************************************
3320 this is a version of setbuffer() for those machines that only have setvbuf
3321 ****************************************************************************/
3322 void setbuffer(FILE *f,char *buf,int bufsize)
3324 setvbuf(f,buf,_IOFBF,bufsize);
3326 #endif
3329 /****************************************************************************
3330 parse out a directory name from a path name. Assumes dos style filenames.
3331 ****************************************************************************/
3332 char *dirname_dos(char *path,char *buf)
3334 char *p = strrchr(path,'\\');
3336 if (!p)
3337 pstrcpy(buf,path);
3338 else
3340 *p = 0;
3341 pstrcpy(buf,path);
3342 *p = '\\';
3345 return(buf);
3349 /****************************************************************************
3350 parse out a filename from a path name. Assumes dos style filenames.
3351 ****************************************************************************/
3352 static char *filename_dos(char *path,char *buf)
3354 char *p = strrchr(path,'\\');
3356 if (!p)
3357 pstrcpy(buf,path);
3358 else
3359 pstrcpy(buf,p+1);
3361 return(buf);
3366 /****************************************************************************
3367 expand a pointer to be a particular size
3368 ****************************************************************************/
3369 void *Realloc(void *p,int size)
3371 void *ret=NULL;
3373 if (size == 0) {
3374 if (p) free(p);
3375 DEBUG(5,("Realloc asked for 0 bytes\n"));
3376 return NULL;
3379 if (!p)
3380 ret = (void *)malloc(size);
3381 else
3382 ret = (void *)realloc(p,size);
3384 if (!ret)
3385 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3387 return(ret);
3391 /****************************************************************************
3392 Signal handler for SIGPIPE (write on a disconnected socket)
3393 ****************************************************************************/
3394 void Abort(void )
3396 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3397 exit(2);
3400 /****************************************************************************
3401 get my own name and IP
3402 ****************************************************************************/
3403 BOOL get_myname(char *my_name,struct in_addr *ip)
3405 struct hostent *hp;
3406 pstring hostname;
3408 *hostname = 0;
3410 /* get my host name */
3411 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3413 DEBUG(0,("gethostname failed\n"));
3414 return False;
3417 /* get host info */
3418 if ((hp = Get_Hostbyname(hostname)) == 0)
3420 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3421 return False;
3424 if (my_name)
3426 /* split off any parts after an initial . */
3427 char *p = strchr(hostname,'.');
3428 if (p) *p = 0;
3430 fstrcpy(my_name,hostname);
3433 if (ip)
3434 putip((char *)ip,(char *)hp->h_addr);
3436 return(True);
3440 /****************************************************************************
3441 true if two IP addresses are equal
3442 ****************************************************************************/
3443 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3445 uint32 a1,a2;
3446 a1 = ntohl(ip1.s_addr);
3447 a2 = ntohl(ip2.s_addr);
3448 return(a1 == a2);
3452 /****************************************************************************
3453 open a socket of the specified type, port and address for incoming data
3454 ****************************************************************************/
3455 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3457 struct hostent *hp;
3458 struct sockaddr_in sock;
3459 pstring host_name;
3460 int res;
3462 /* get my host name */
3463 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3464 { DEBUG(0,("gethostname failed\n")); return -1; }
3466 /* get host info */
3467 if ((hp = Get_Hostbyname(host_name)) == 0)
3469 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3470 return -1;
3473 bzero((char *)&sock,sizeof(sock));
3474 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3476 #ifdef HAVE_SOCK_SIN_LEN
3477 sock.sin_len = sizeof(sock);
3478 #endif
3479 sock.sin_port = htons( port );
3480 sock.sin_family = hp->h_addrtype;
3481 sock.sin_addr.s_addr = socket_addr;
3482 res = socket(hp->h_addrtype, type, 0);
3483 if (res == -1)
3484 { DEBUG(0,("socket failed\n")); return -1; }
3487 int one=1;
3488 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3491 /* now we've got a socket - we need to bind it */
3492 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3494 if (port) {
3495 if (port == SMB_PORT || port == NMB_PORT)
3496 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3497 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3498 close(res);
3500 if (dlevel > 0 && port < 1000)
3501 port = 7999;
3503 if (port >= 1000 && port < 9000)
3504 return(open_socket_in(type,port+1,dlevel,socket_addr));
3507 return(-1);
3509 DEBUG(3,("bind succeeded on port %d\n",port));
3511 return res;
3515 /****************************************************************************
3516 create an outgoing socket
3517 **************************************************************************/
3518 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3520 struct sockaddr_in sock_out;
3521 int res,ret;
3522 int connect_loop = 250; /* 250 milliseconds */
3523 int loops = (timeout * 1000) / connect_loop;
3525 /* create a socket to write to */
3526 res = socket(PF_INET, type, 0);
3527 if (res == -1)
3528 { DEBUG(0,("socket error\n")); return -1; }
3530 if (type != SOCK_STREAM) return(res);
3532 bzero((char *)&sock_out,sizeof(sock_out));
3533 putip((char *)&sock_out.sin_addr,(char *)addr);
3535 sock_out.sin_port = htons( port );
3536 sock_out.sin_family = PF_INET;
3538 /* set it non-blocking */
3539 set_blocking(res,False);
3541 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3543 /* and connect it to the destination */
3544 connect_again:
3545 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3547 /* Some systems return EAGAIN when they mean EINPROGRESS */
3548 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3549 errno == EAGAIN) && loops--) {
3550 msleep(connect_loop);
3551 goto connect_again;
3554 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3555 errno == EAGAIN)) {
3556 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3557 close(res);
3558 return -1;
3561 #ifdef EISCONN
3562 if (ret < 0 && errno == EISCONN) {
3563 errno = 0;
3564 ret = 0;
3566 #endif
3568 if (ret < 0) {
3569 DEBUG(1,("error connecting to %s:%d (%s)\n",
3570 inet_ntoa(*addr),port,strerror(errno)));
3571 close(res);
3572 return -1;
3575 /* set it blocking again */
3576 set_blocking(res,True);
3578 return res;
3582 /****************************************************************************
3583 interpret a protocol description string, with a default
3584 ****************************************************************************/
3585 int interpret_protocol(char *str,int def)
3587 if (strequal(str,"NT1"))
3588 return(PROTOCOL_NT1);
3589 if (strequal(str,"LANMAN2"))
3590 return(PROTOCOL_LANMAN2);
3591 if (strequal(str,"LANMAN1"))
3592 return(PROTOCOL_LANMAN1);
3593 if (strequal(str,"CORE"))
3594 return(PROTOCOL_CORE);
3595 if (strequal(str,"COREPLUS"))
3596 return(PROTOCOL_COREPLUS);
3597 if (strequal(str,"CORE+"))
3598 return(PROTOCOL_COREPLUS);
3600 DEBUG(0,("Unrecognised protocol level %s\n",str));
3602 return(def);
3605 /****************************************************************************
3606 interpret a security level
3607 ****************************************************************************/
3608 int interpret_security(char *str,int def)
3610 if (strequal(str,"SERVER"))
3611 return(SEC_SERVER);
3612 if (strequal(str,"USER"))
3613 return(SEC_USER);
3614 if (strequal(str,"SHARE"))
3615 return(SEC_SHARE);
3617 DEBUG(0,("Unrecognised security level %s\n",str));
3619 return(def);
3623 /****************************************************************************
3624 interpret an internet address or name into an IP address in 4 byte form
3625 ****************************************************************************/
3626 uint32 interpret_addr(char *str)
3628 struct hostent *hp;
3629 uint32 res;
3630 int i;
3631 BOOL pure_address = True;
3633 if (strcmp(str,"0.0.0.0") == 0) return(0);
3634 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3636 for (i=0; pure_address && str[i]; i++)
3637 if (!(isdigit((int)str[i]) || str[i] == '.'))
3638 pure_address = False;
3640 /* if it's in the form of an IP address then get the lib to interpret it */
3641 if (pure_address) {
3642 res = inet_addr(str);
3643 } else {
3644 /* otherwise assume it's a network name of some sort and use
3645 Get_Hostbyname */
3646 if ((hp = Get_Hostbyname(str)) == 0) {
3647 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3648 return 0;
3650 if(hp->h_addr == NULL) {
3651 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3652 return 0;
3654 putip((char *)&res,(char *)hp->h_addr);
3657 if (res == (uint32)-1) return(0);
3659 return(res);
3662 /*******************************************************************
3663 a convenient addition to interpret_addr()
3664 ******************************************************************/
3665 struct in_addr *interpret_addr2(char *str)
3667 static struct in_addr ret;
3668 uint32 a = interpret_addr(str);
3669 ret.s_addr = a;
3670 return(&ret);
3673 /*******************************************************************
3674 check if an IP is the 0.0.0.0
3675 ******************************************************************/
3676 BOOL zero_ip(struct in_addr ip)
3678 uint32 a;
3679 putip((char *)&a,(char *)&ip);
3680 return(a == 0);
3684 /*******************************************************************
3685 matchname - determine if host name matches IP address
3686 ******************************************************************/
3687 static BOOL matchname(char *remotehost,struct in_addr addr)
3689 struct hostent *hp;
3690 int i;
3692 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3693 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3694 return False;
3698 * Make sure that gethostbyname() returns the "correct" host name.
3699 * Unfortunately, gethostbyname("localhost") sometimes yields
3700 * "localhost.domain". Since the latter host name comes from the
3701 * local DNS, we just have to trust it (all bets are off if the local
3702 * DNS is perverted). We always check the address list, though.
3705 if (strcasecmp(remotehost, hp->h_name)
3706 && strcasecmp(remotehost, "localhost")) {
3707 DEBUG(0,("host name/name mismatch: %s != %s",
3708 remotehost, hp->h_name));
3709 return False;
3712 /* Look up the host address in the address list we just got. */
3713 for (i = 0; hp->h_addr_list[i]; i++) {
3714 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3715 return True;
3719 * The host name does not map to the original host address. Perhaps
3720 * someone has compromised a name server. More likely someone botched
3721 * it, but that could be dangerous, too.
3724 DEBUG(0,("host name/address mismatch: %s != %s",
3725 inet_ntoa(addr), hp->h_name));
3726 return False;
3729 /*******************************************************************
3730 Reset the 'done' variables so after a client process is created
3731 from a fork call these calls will be re-done. This should be
3732 expanded if more variables need reseting.
3733 ******************************************************************/
3735 static BOOL global_client_name_done = False;
3736 static BOOL global_client_addr_done = False;
3738 void reset_globals_after_fork(void)
3740 global_client_name_done = False;
3741 global_client_addr_done = False;
3744 * Re-seed the random crypto generator, so all smbd's
3745 * started from the same parent won't generate the same
3746 * sequence.
3749 unsigned char dummy;
3750 generate_random_buffer( &dummy, 1, True);
3754 /*******************************************************************
3755 return the DNS name of the client
3756 ******************************************************************/
3757 char *client_name(int fd)
3759 struct sockaddr sa;
3760 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3761 int length = sizeof(sa);
3762 static pstring name_buf;
3763 struct hostent *hp;
3764 static int last_fd=-1;
3766 if (global_client_name_done && last_fd == fd)
3767 return name_buf;
3769 last_fd = fd;
3770 global_client_name_done = False;
3772 pstrcpy(name_buf,"UNKNOWN");
3774 if (fd == -1) {
3775 return name_buf;
3778 if (getpeername(fd, &sa, &length) < 0) {
3779 DEBUG(0,("getpeername failed\n"));
3780 return name_buf;
3783 /* Look up the remote host name. */
3784 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3785 sizeof(sockin->sin_addr),
3786 AF_INET)) == 0) {
3787 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3788 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3789 } else {
3790 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3791 if (!matchname(name_buf, sockin->sin_addr)) {
3792 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3793 pstrcpy(name_buf,"UNKNOWN");
3796 global_client_name_done = True;
3797 return name_buf;
3800 /*******************************************************************
3801 return the IP addr of the client as a string
3802 ******************************************************************/
3803 char *client_addr(int fd)
3805 struct sockaddr sa;
3806 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3807 int length = sizeof(sa);
3808 static fstring addr_buf;
3809 static int last_fd = -1;
3811 if (global_client_addr_done && fd == last_fd)
3812 return addr_buf;
3814 last_fd = fd;
3815 global_client_addr_done = False;
3817 fstrcpy(addr_buf,"0.0.0.0");
3819 if (fd == -1) {
3820 return addr_buf;
3823 if (getpeername(fd, &sa, &length) < 0) {
3824 DEBUG(0,("getpeername failed\n"));
3825 return addr_buf;
3828 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3830 global_client_addr_done = True;
3831 return addr_buf;
3834 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3835 /******************************************************************
3836 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3837 Based on a fix from <Thomas.Hepper@icem.de>.
3838 *******************************************************************/
3840 static void strip_mount_options( pstring *str)
3842 if (**str == '-')
3844 char *p = *str;
3845 while(*p && !isspace(*p))
3846 p++;
3847 while(*p && isspace(*p))
3848 p++;
3849 if(*p) {
3850 pstring tmp_str;
3852 pstrcpy(tmp_str, p);
3853 pstrcpy(*str, tmp_str);
3858 /*******************************************************************
3859 Patch from jkf@soton.ac.uk
3860 Split Luke's automount_server into YP lookup and string splitter
3861 so can easily implement automount_path().
3862 As we may end up doing both, cache the last YP result.
3863 *******************************************************************/
3865 #ifdef WITH_NISPLUS_HOME
3866 static char *automount_lookup(char *user_name)
3868 static fstring last_key = "";
3869 static pstring last_value = "";
3871 char *nis_map = (char *)lp_nis_home_map_name();
3873 char nis_domain[NIS_MAXNAMELEN + 1];
3874 char buffer[NIS_MAXATTRVAL + 1];
3875 nis_result *result;
3876 nis_object *object;
3877 entry_obj *entry;
3879 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3880 nis_domain[NIS_MAXNAMELEN] = '\0';
3882 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3884 if (strcmp(user_name, last_key))
3886 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3887 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3889 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3891 if (result->status != NIS_SUCCESS)
3893 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3894 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3896 else
3898 object = result->objects.objects_val;
3899 if (object->zo_data.zo_type == ENTRY_OBJ)
3901 entry = &object->zo_data.objdata_u.en_data;
3902 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3903 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3905 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3906 string_sub(last_value, "&", user_name);
3907 fstrcpy(last_key, user_name);
3911 nis_freeresult(result);
3914 strip_mount_options(&last_value);
3916 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3917 return last_value;
3919 #else /* WITH_NISPLUS_HOME */
3920 static char *automount_lookup(char *user_name)
3922 static fstring last_key = "";
3923 static pstring last_value = "";
3925 int nis_error; /* returned by yp all functions */
3926 char *nis_result; /* yp_match inits this */
3927 int nis_result_len; /* and set this */
3928 char *nis_domain; /* yp_get_default_domain inits this */
3929 char *nis_map = (char *)lp_nis_home_map_name();
3931 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3933 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3934 return last_value;
3937 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3939 if (!strcmp(user_name, last_key))
3941 nis_result = last_value;
3942 nis_result_len = strlen(last_value);
3943 nis_error = 0;
3945 else
3947 if ((nis_error = yp_match(nis_domain, nis_map,
3948 user_name, strlen(user_name),
3949 &nis_result, &nis_result_len)) != 0)
3951 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3952 yperr_string(nis_error), user_name, nis_map));
3954 if (!nis_error && nis_result_len >= sizeof(pstring))
3956 nis_result_len = sizeof(pstring)-1;
3958 fstrcpy(last_key, user_name);
3959 strncpy(last_value, nis_result, nis_result_len);
3960 last_value[nis_result_len] = '\0';
3963 strip_mount_options(&last_value);
3965 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3966 return last_value;
3968 #endif /* WITH_NISPLUS_HOME */
3969 #endif
3971 /*******************************************************************
3972 Patch from jkf@soton.ac.uk
3973 This is Luke's original function with the NIS lookup code
3974 moved out to a separate function.
3975 *******************************************************************/
3977 char *automount_server(char *user_name)
3979 static pstring server_name;
3981 /* use the local machine name as the default */
3982 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3983 pstrcpy(server_name, local_machine);
3985 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3987 if (lp_nis_home_map())
3989 int home_server_len;
3990 char *automount_value = automount_lookup(user_name);
3991 home_server_len = strcspn(automount_value,":");
3992 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3993 if (home_server_len > sizeof(pstring))
3995 home_server_len = sizeof(pstring);
3997 strncpy(server_name, automount_value, home_server_len);
3998 server_name[home_server_len] = '\0';
4000 #endif
4002 DEBUG(4,("Home server: %s\n", server_name));
4004 return server_name;
4007 /*******************************************************************
4008 Patch from jkf@soton.ac.uk
4009 Added this to implement %p (NIS auto-map version of %H)
4010 *******************************************************************/
4012 char *automount_path(char *user_name)
4014 static pstring server_path;
4016 /* use the passwd entry as the default */
4017 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
4018 /* pstrcpy() copes with get_home_dir() returning NULL */
4019 pstrcpy(server_path, get_home_dir(user_name));
4021 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
4023 if (lp_nis_home_map())
4025 char *home_path_start;
4026 char *automount_value = automount_lookup(user_name);
4027 home_path_start = strchr(automount_value,':');
4028 if (home_path_start != NULL)
4030 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
4031 home_path_start?(home_path_start+1):""));
4032 pstrcpy(server_path, home_path_start+1);
4035 #endif
4037 DEBUG(4,("Home server path: %s\n", server_path));
4039 return server_path;
4043 /*******************************************************************
4044 sub strings with useful parameters
4045 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4046 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4047 ********************************************************************/
4048 void standard_sub_basic(char *str)
4050 char *s, *p;
4051 char pidstr[10];
4052 struct passwd *pass;
4053 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4055 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4057 switch (*(p+1))
4059 case 'G' :
4061 if ((pass = Get_Pwnam(username,False))!=NULL)
4063 string_sub(p,"%G",gidtoname(pass->pw_gid));
4065 else
4067 p += 2;
4069 break;
4071 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4072 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4073 case 'L' : string_sub(p,"%L", local_machine); break;
4074 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4075 case 'R' : string_sub(p,"%R", remote_proto); break;
4076 case 'T' : string_sub(p,"%T", timestring()); break;
4077 case 'U' : string_sub(p,"%U", username); break;
4078 case 'a' : string_sub(p,"%a", remote_arch); break;
4079 case 'd' :
4081 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4082 string_sub(p,"%d", pidstr);
4083 break;
4085 case 'h' : string_sub(p,"%h", myhostname); break;
4086 case 'm' : string_sub(p,"%m", remote_machine); break;
4087 case 'v' : string_sub(p,"%v", VERSION); break;
4088 case '$' : /* Expand environment variables */
4090 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4091 fstring envname;
4092 char *envval;
4093 char *q, *r;
4094 int copylen;
4096 if (*(p+2) != '(')
4098 p+=2;
4099 break;
4101 if ((q = strchr(p,')')) == NULL)
4103 DEBUG(0,("standard_sub_basic: Unterminated environment \
4104 variable [%s]\n", p));
4105 p+=2;
4106 break;
4109 r = p+3;
4110 copylen = MIN((q-r),(sizeof(envname)-1));
4111 strncpy(envname,r,copylen);
4112 envname[copylen] = '\0';
4114 if ((envval = getenv(envname)) == NULL)
4116 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4117 envname));
4118 p+=2;
4119 break;
4122 copylen = MIN((q+1-p),(sizeof(envname)-1));
4123 strncpy(envname,p,copylen);
4124 envname[copylen] = '\0';
4125 string_sub(p,envname,envval);
4126 break;
4128 case '\0': p++; break; /* don't run off end if last character is % */
4129 default : p+=2; break;
4132 return;
4136 /****************************************************************************
4137 do some standard substitutions in a string
4138 ****************************************************************************/
4139 void standard_sub(connection_struct *conn,char *str)
4141 char *p, *s, *home;
4143 for (s=str; (p=strchr(s, '%'));s=p) {
4144 switch (*(p+1)) {
4145 case 'H':
4146 if ((home = get_home_dir(conn->user))) {
4147 string_sub(p,"%H",home);
4148 } else {
4149 p += 2;
4151 break;
4153 case 'P':
4154 string_sub(p,"%P",conn->connectpath);
4155 break;
4157 case 'S':
4158 string_sub(p,"%S",
4159 lp_servicename(SNUM(conn)));
4160 break;
4162 case 'g':
4163 string_sub(p,"%g",
4164 gidtoname(conn->gid));
4165 break;
4166 case 'u':
4167 string_sub(p,"%u",conn->user);
4168 break;
4170 /* Patch from jkf@soton.ac.uk Left the %N (NIS
4171 * server name) in standard_sub_basic as it is
4172 * a feature for logon servers, hence uses the
4173 * username. The %p (NIS server path) code is
4174 * here as it is used instead of the default
4175 * "path =" string in [homes] and so needs the
4176 * service name, not the username. */
4177 case 'p':
4178 string_sub(p,"%p",
4179 automount_path(lp_servicename(SNUM(conn))));
4180 break;
4181 case '\0':
4182 p++;
4183 break; /* don't run off the end of the string
4186 default: p+=2;
4187 break;
4191 standard_sub_basic(str);
4196 /*******************************************************************
4197 are two IPs on the same subnet?
4198 ********************************************************************/
4199 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4201 uint32 net1,net2,nmask;
4203 nmask = ntohl(mask.s_addr);
4204 net1 = ntohl(ip1.s_addr);
4205 net2 = ntohl(ip2.s_addr);
4207 return((net1 & nmask) == (net2 & nmask));
4211 /*******************************************************************
4212 write a string in unicoode format
4213 ********************************************************************/
4214 int PutUniCode(char *dst,char *src)
4216 int ret = 0;
4217 while (*src) {
4218 dst[ret++] = src[0];
4219 dst[ret++] = 0;
4220 src++;
4222 dst[ret++]=0;
4223 dst[ret++]=0;
4224 return(ret);
4227 /****************************************************************************
4228 a wrapper for gethostbyname() that tries with all lower and all upper case
4229 if the initial name fails
4230 ****************************************************************************/
4231 struct hostent *Get_Hostbyname(char *name)
4233 char *name2 = strdup(name);
4234 struct hostent *ret;
4236 if (!name2)
4238 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4239 exit(0);
4244 * This next test is redundent and causes some systems (with
4245 * broken isalnum() calls) problems.
4246 * JRA.
4249 #if 0
4250 if (!isalnum(*name2))
4252 free(name2);
4253 return(NULL);
4255 #endif /* 0 */
4257 ret = sys_gethostbyname(name2);
4258 if (ret != NULL)
4260 free(name2);
4261 return(ret);
4264 /* try with all lowercase */
4265 strlower(name2);
4266 ret = sys_gethostbyname(name2);
4267 if (ret != NULL)
4269 free(name2);
4270 return(ret);
4273 /* try with all uppercase */
4274 strupper(name2);
4275 ret = sys_gethostbyname(name2);
4276 if (ret != NULL)
4278 free(name2);
4279 return(ret);
4282 /* nothing works :-( */
4283 free(name2);
4284 return(NULL);
4288 /****************************************************************************
4289 check if a process exists. Does this work on all unixes?
4290 ****************************************************************************/
4291 BOOL process_exists(int pid)
4293 return(kill(pid,0) == 0 || errno != ESRCH);
4297 /*******************************************************************
4298 turn a uid into a user name
4299 ********************************************************************/
4300 char *uidtoname(int uid)
4302 static char name[40];
4303 struct passwd *pass = getpwuid(uid);
4304 if (pass) return(pass->pw_name);
4305 slprintf(name, sizeof(name) - 1, "%d",uid);
4306 return(name);
4309 /*******************************************************************
4310 turn a gid into a group name
4311 ********************************************************************/
4312 char *gidtoname(int gid)
4314 static char name[40];
4315 struct group *grp = getgrgid(gid);
4316 if (grp) return(grp->gr_name);
4317 slprintf(name,sizeof(name) - 1, "%d",gid);
4318 return(name);
4321 /*******************************************************************
4322 something really nasty happened - panic!
4323 ********************************************************************/
4324 void smb_panic(char *why)
4326 char *cmd = lp_panic_action();
4327 if (cmd && *cmd) {
4328 system(cmd);
4330 DEBUG(0,("PANIC: %s\n", why));
4331 exit(1);
4335 /*******************************************************************
4336 a readdir wrapper which just returns the file name
4337 also return the inode number if requested
4338 ********************************************************************/
4339 char *readdirname(void *p)
4341 struct dirent *ptr;
4342 char *dname;
4344 if (!p) return(NULL);
4346 ptr = (struct dirent *)readdir(p);
4347 if (!ptr) return(NULL);
4349 dname = ptr->d_name;
4351 #ifdef NEXT2
4352 if (telldir(p) < 0) return(NULL);
4353 #endif
4355 #ifdef HAVE_BROKEN_READDIR
4356 /* using /usr/ucb/cc is BAD */
4357 dname = dname - 2;
4358 #endif
4361 static pstring buf;
4362 memcpy(buf, dname, NAMLEN(ptr)+1);
4363 unix_to_dos(buf, True);
4364 dname = buf;
4367 return(dname);
4370 /*******************************************************************
4371 Utility function used to decide if the last component
4372 of a path matches a (possibly wildcarded) entry in a namelist.
4373 ********************************************************************/
4375 BOOL is_in_path(char *name, name_compare_entry *namelist)
4377 pstring last_component;
4378 char *p;
4380 DEBUG(8, ("is_in_path: %s\n", name));
4382 /* if we have no list it's obviously not in the path */
4383 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4385 DEBUG(8,("is_in_path: no name list.\n"));
4386 return False;
4389 /* Get the last component of the unix name. */
4390 p = strrchr(name, '/');
4391 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4392 last_component[sizeof(last_component)-1] = '\0';
4394 for(; namelist->name != NULL; namelist++)
4396 if(namelist->is_wild)
4399 * Look for a wildcard match. Use the old
4400 * 'unix style' mask match, rather than the
4401 * new NT one.
4403 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4405 DEBUG(8,("is_in_path: mask match succeeded\n"));
4406 return True;
4409 else
4411 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4412 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4414 DEBUG(8,("is_in_path: match succeeded\n"));
4415 return True;
4419 DEBUG(8,("is_in_path: match not found\n"));
4421 return False;
4424 /*******************************************************************
4425 Strip a '/' separated list into an array of
4426 name_compare_enties structures suitable for
4427 passing to is_in_path(). We do this for
4428 speed so we can pre-parse all the names in the list
4429 and don't do it for each call to is_in_path().
4430 namelist is modified here and is assumed to be
4431 a copy owned by the caller.
4432 We also check if the entry contains a wildcard to
4433 remove a potentially expensive call to mask_match
4434 if possible.
4435 ********************************************************************/
4437 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4439 char *name_end;
4440 char *nameptr = namelist;
4441 int num_entries = 0;
4442 int i;
4444 (*ppname_array) = NULL;
4446 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4447 return;
4449 /* We need to make two passes over the string. The
4450 first to count the number of elements, the second
4451 to split it.
4453 while(*nameptr)
4455 if ( *nameptr == '/' )
4457 /* cope with multiple (useless) /s) */
4458 nameptr++;
4459 continue;
4461 /* find the next / */
4462 name_end = strchr(nameptr, '/');
4464 /* oops - the last check for a / didn't find one. */
4465 if (name_end == NULL)
4466 break;
4468 /* next segment please */
4469 nameptr = name_end + 1;
4470 num_entries++;
4473 if(num_entries == 0)
4474 return;
4476 if(( (*ppname_array) = (name_compare_entry *)malloc(
4477 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4479 DEBUG(0,("set_namearray: malloc fail\n"));
4480 return;
4483 /* Now copy out the names */
4484 nameptr = namelist;
4485 i = 0;
4486 while(*nameptr)
4488 if ( *nameptr == '/' )
4490 /* cope with multiple (useless) /s) */
4491 nameptr++;
4492 continue;
4494 /* find the next / */
4495 if ((name_end = strchr(nameptr, '/')) != NULL)
4497 *name_end = 0;
4500 /* oops - the last check for a / didn't find one. */
4501 if(name_end == NULL)
4502 break;
4504 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4505 (strchr( nameptr, '*')!=NULL));
4506 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4508 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4509 return;
4512 /* next segment please */
4513 nameptr = name_end + 1;
4514 i++;
4517 (*ppname_array)[i].name = NULL;
4519 return;
4522 /****************************************************************************
4523 routine to free a namearray.
4524 ****************************************************************************/
4526 void free_namearray(name_compare_entry *name_array)
4528 if(name_array == 0)
4529 return;
4531 if(name_array->name != NULL)
4532 free(name_array->name);
4534 free((char *)name_array);
4537 /****************************************************************************
4538 routine to do file locking
4539 ****************************************************************************/
4540 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4542 #if HAVE_FCNTL_LOCK
4543 struct flock lock;
4544 int ret;
4547 * FIXME.
4548 * NB - this code will need re-writing to cope with large (64bit)
4549 * lock requests. JRA.
4552 if(lp_ole_locking_compat()) {
4553 uint32 mask = 0xC0000000;
4555 /* make sure the count is reasonable, we might kill the lockd otherwise */
4556 count &= ~mask;
4558 /* the offset is often strange - remove 2 of its bits if either of
4559 the top two bits are set. Shift the top ones by two bits. This
4560 still allows OLE2 apps to operate, but should stop lockd from
4561 dieing */
4562 if ((offset & mask) != 0)
4563 offset = (offset & ~mask) | ((offset & mask) >> 2);
4564 } else {
4565 uint32 mask = ((unsigned)1<<31);
4566 int32 s_count = (int32) count; /* Signed count. */
4567 int32 s_offset = (int32)offset; /* Signed offset. */
4569 /* interpret negative counts as large numbers */
4570 if (s_count < 0)
4571 s_count &= ~mask;
4573 /* no negative offsets */
4574 if(s_offset < 0)
4575 s_offset &= ~mask;
4577 /* count + offset must be in range */
4578 while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
4580 s_offset &= ~mask;
4581 mask = mask >> 1;
4584 offset = (uint32)s_offset;
4585 count = (uint32)s_count;
4589 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4591 lock.l_type = type;
4592 lock.l_whence = SEEK_SET;
4593 lock.l_start = (int)offset;
4594 lock.l_len = (int)count;
4595 lock.l_pid = 0;
4597 errno = 0;
4599 ret = fcntl(fd,op,&lock);
4601 if (errno != 0)
4602 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4604 /* a lock query */
4605 if (op == F_GETLK)
4607 if ((ret != -1) &&
4608 (lock.l_type != F_UNLCK) &&
4609 (lock.l_pid != 0) &&
4610 (lock.l_pid != getpid()))
4612 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4613 return(True);
4616 /* it must be not locked or locked by me */
4617 return(False);
4620 /* a lock set or unset */
4621 if (ret == -1)
4623 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4624 offset,count,op,type,strerror(errno)));
4626 /* perhaps it doesn't support this sort of locking?? */
4627 if (errno == EINVAL)
4629 DEBUG(3,("locking not supported? returning True\n"));
4630 return(True);
4633 return(False);
4636 /* everything went OK */
4637 DEBUG(8,("Lock call successful\n"));
4639 return(True);
4640 #else
4641 return(False);
4642 #endif
4645 /*******************************************************************
4646 lock a file - returning a open file descriptor or -1 on failure
4647 The timeout is in seconds. 0 means no timeout
4648 ********************************************************************/
4649 int file_lock(char *name,int timeout)
4651 int fd = open(name,O_RDWR|O_CREAT,0666);
4652 time_t t=0;
4653 if (fd < 0) return(-1);
4655 #if HAVE_FCNTL_LOCK
4656 if (timeout) t = time(NULL);
4657 while (!timeout || (time(NULL)-t < timeout)) {
4658 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4659 msleep(LOCK_RETRY_TIMEOUT);
4661 return(-1);
4662 #else
4663 return(fd);
4664 #endif
4667 /*******************************************************************
4668 unlock a file locked by file_lock
4669 ********************************************************************/
4670 void file_unlock(int fd)
4672 if (fd<0) return;
4673 #if HAVE_FCNTL_LOCK
4674 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4675 #endif
4676 close(fd);
4679 /*******************************************************************
4680 is the name specified one of my netbios names
4681 returns true is it is equal, false otherwise
4682 ********************************************************************/
4683 BOOL is_myname(char *s)
4685 int n;
4686 BOOL ret = False;
4688 for (n=0; my_netbios_names[n]; n++) {
4689 if (strequal(my_netbios_names[n], s))
4690 ret=True;
4692 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4693 return(ret);
4696 /*******************************************************************
4697 set the horrid remote_arch string based on an enum.
4698 ********************************************************************/
4699 void set_remote_arch(enum remote_arch_types type)
4701 ra_type = type;
4702 switch( type )
4704 case RA_WFWG:
4705 fstrcpy(remote_arch, "WfWg");
4706 return;
4707 case RA_OS2:
4708 fstrcpy(remote_arch, "OS2");
4709 return;
4710 case RA_WIN95:
4711 fstrcpy(remote_arch, "Win95");
4712 return;
4713 case RA_WINNT:
4714 fstrcpy(remote_arch, "WinNT");
4715 return;
4716 case RA_SAMBA:
4717 fstrcpy(remote_arch,"Samba");
4718 return;
4719 default:
4720 ra_type = RA_UNKNOWN;
4721 fstrcpy(remote_arch, "UNKNOWN");
4722 break;
4726 /*******************************************************************
4727 Get the remote_arch type.
4728 ********************************************************************/
4729 enum remote_arch_types get_remote_arch(void)
4731 return ra_type;
4735 /*******************************************************************
4736 skip past some unicode strings in a buffer
4737 ********************************************************************/
4738 char *skip_unicode_string(char *buf,int n)
4740 while (n--)
4742 while (*buf)
4743 buf += 2;
4744 buf += 2;
4746 return(buf);
4749 /*******************************************************************
4750 Return a ascii version of a unicode string
4751 Hack alert: uses fixed buffer(s) and only handles ascii strings
4752 ********************************************************************/
4753 #define MAXUNI 1024
4754 char *unistrn2(uint16 *buf, int len)
4756 static char lbufs[8][MAXUNI];
4757 static int nexti;
4758 char *lbuf = lbufs[nexti];
4759 char *p;
4761 nexti = (nexti+1)%8;
4763 DEBUG(10, ("unistrn2: "));
4765 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4767 DEBUG(10, ("%4x ", *buf));
4768 *p = *buf;
4771 DEBUG(10,("\n"));
4773 *p = 0;
4774 return lbuf;
4777 /*******************************************************************
4778 Return a ascii version of a unicode string
4779 Hack alert: uses fixed buffer(s) and only handles ascii strings
4780 ********************************************************************/
4781 #define MAXUNI 1024
4782 char *unistr2(uint16 *buf)
4784 static char lbufs[8][MAXUNI];
4785 static int nexti;
4786 char *lbuf = lbufs[nexti];
4787 char *p;
4789 nexti = (nexti+1)%8;
4791 DEBUG(10, ("unistr2: "));
4793 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4795 DEBUG(10, ("%4x ", *buf));
4796 *p = *buf;
4799 DEBUG(10,("\n"));
4801 *p = 0;
4802 return lbuf;
4805 /*******************************************************************
4806 create a null-terminated unicode string from a null-terminated ascii string.
4807 return number of unicode chars copied, excluding the null character.
4809 only handles ascii strings
4810 ********************************************************************/
4811 #define MAXUNI 1024
4812 int struni2(uint16 *p, char *buf)
4814 int len = 0;
4816 if (p == NULL) return 0;
4818 DEBUG(10, ("struni2: "));
4820 if (buf != NULL)
4822 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4824 DEBUG(10, ("%2x ", *buf));
4825 *p = *buf;
4828 DEBUG(10,("\n"));
4831 *p = 0;
4833 return len;
4836 /*******************************************************************
4837 Return a ascii version of a unicode string
4838 Hack alert: uses fixed buffer(s) and only handles ascii strings
4839 ********************************************************************/
4840 #define MAXUNI 1024
4841 char *unistr(char *buf)
4843 static char lbufs[8][MAXUNI];
4844 static int nexti;
4845 char *lbuf = lbufs[nexti];
4846 char *p;
4848 nexti = (nexti+1)%8;
4850 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4852 *p = *buf;
4854 *p = 0;
4855 return lbuf;
4858 /*******************************************************************
4859 strncpy for unicode strings
4860 ********************************************************************/
4861 int unistrncpy(char *dst, char *src, int len)
4863 int num_wchars = 0;
4865 while (*src && len > 0)
4867 *dst++ = *src++;
4868 *dst++ = *src++;
4869 len--;
4870 num_wchars++;
4872 *dst++ = 0;
4873 *dst++ = 0;
4875 return num_wchars;
4879 /*******************************************************************
4880 strcpy for unicode strings. returns length (in num of wide chars)
4881 ********************************************************************/
4882 int unistrcpy(char *dst, char *src)
4884 int num_wchars = 0;
4886 while (*src)
4888 *dst++ = *src++;
4889 *dst++ = *src++;
4890 num_wchars++;
4892 *dst++ = 0;
4893 *dst++ = 0;
4895 return num_wchars;
4898 /*******************************************************************
4899 safe string copy into a known length string. maxlength does not
4900 include the terminating zero.
4901 ********************************************************************/
4902 char *safe_strcpy(char *dest, char *src, int maxlength)
4904 int len;
4906 if (!dest) {
4907 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4908 return NULL;
4911 if (!src) {
4912 *dest = 0;
4913 return dest;
4916 len = strlen(src);
4918 if (len > maxlength) {
4919 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4920 len-maxlength, src));
4921 len = maxlength;
4924 memcpy(dest, src, len);
4925 dest[len] = 0;
4926 return dest;
4929 /*******************************************************************
4930 safe string cat into a string. maxlength does not
4931 include the terminating zero.
4932 ********************************************************************/
4933 char *safe_strcat(char *dest, char *src, int maxlength)
4935 int src_len, dest_len;
4937 if (!dest) {
4938 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4939 return NULL;
4942 if (!src) {
4943 return dest;
4946 src_len = strlen(src);
4947 dest_len = strlen(dest);
4949 if (src_len + dest_len > maxlength) {
4950 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4951 src_len + dest_len - maxlength, src));
4952 src_len = maxlength - dest_len;
4955 memcpy(&dest[dest_len], src, src_len);
4956 dest[dest_len + src_len] = 0;
4957 return dest;
4960 /*******************************************************************
4961 align a pointer to a multiple of 4 bytes
4962 ********************************************************************/
4963 char *align4(char *q, char *base)
4965 if ((q - base) & 3)
4967 q += 4 - ((q - base) & 3);
4969 return q;
4972 /*******************************************************************
4973 align a pointer to a multiple of 2 bytes
4974 ********************************************************************/
4975 char *align2(char *q, char *base)
4977 if ((q - base) & 1)
4979 q++;
4981 return q;
4984 /*******************************************************************
4985 align a pointer to a multiple of align_offset bytes. looks like it
4986 will work for offsets of 0, 2 and 4...
4987 ********************************************************************/
4988 char *align_offset(char *q, char *base, int align_offset_len)
4990 int mod = ((q - base) & (align_offset_len-1));
4991 if (align_offset_len != 0 && mod != 0)
4993 q += align_offset_len - mod;
4995 return q;
4998 void print_asc(int level, unsigned char *buf,int len)
5000 int i;
5001 for (i=0;i<len;i++)
5002 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
5005 void dump_data(int level,char *buf1,int len)
5007 unsigned char *buf = (unsigned char *)buf1;
5008 int i=0;
5009 if (len<=0) return;
5011 DEBUG(level,("[%03X] ",i));
5012 for (i=0;i<len;) {
5013 DEBUG(level,("%02X ",(int)buf[i]));
5014 i++;
5015 if (i%8 == 0) DEBUG(level,(" "));
5016 if (i%16 == 0) {
5017 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
5018 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
5019 if (i<len) DEBUG(level,("[%03X] ",i));
5022 if (i%16) {
5023 int n;
5025 n = 16 - (i%16);
5026 DEBUG(level,(" "));
5027 if (n>8) DEBUG(level,(" "));
5028 while (n--) DEBUG(level,(" "));
5030 n = MIN(8,i%16);
5031 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
5032 n = (i%16) - n;
5033 if (n>0) print_asc(level,&buf[i-n],n);
5034 DEBUG(level,("\n"));
5038 char *tab_depth(int depth)
5040 static pstring spaces;
5041 memset(spaces, ' ', depth * 4);
5042 spaces[depth * 4] = 0;
5043 return spaces;
5046 /*****************************************************************
5047 Convert a SID to an ascii string.
5048 *****************************************************************/
5050 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
5052 char subauth[16];
5053 int i;
5054 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5055 uint32 ia = (sid->id_auth[5]) +
5056 (sid->id_auth[4] << 8 ) +
5057 (sid->id_auth[3] << 16) +
5058 (sid->id_auth[2] << 24);
5060 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
5062 for (i = 0; i < sid->num_auths; i++)
5064 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
5065 pstrcat(sidstr_out, subauth);
5068 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
5069 return sidstr_out;
5072 /*****************************************************************
5073 Convert a string to a SID. Returns True on success, False on fail.
5074 *****************************************************************/
5076 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
5078 pstring tok;
5079 char *p = sidstr;
5080 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5081 uint32 ia;
5083 memset((char *)sidout, '\0', sizeof(DOM_SID));
5085 if(StrnCaseCmp( sidstr, "S-", 2)) {
5086 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
5087 return False;
5090 p += 2;
5091 if(!next_token(&p, tok, "-", sizeof(tok))) {
5092 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5093 return False;
5096 /* Get the revision number. */
5097 sidout->sid_rev_num = atoi(tok);
5099 if(!next_token(&p, tok, "-", sizeof(tok))) {
5100 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5101 return False;
5104 /* identauth in decimal should be < 2^32 */
5105 ia = atoi(tok);
5107 /* NOTE - the ia value is in big-endian format. */
5108 sidout->id_auth[0] = 0;
5109 sidout->id_auth[1] = 0;
5110 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
5111 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
5112 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
5113 sidout->id_auth[5] = (ia & 0x000000ff);
5115 sidout->num_auths = 0;
5117 while(next_token(&p, tok, "-", sizeof(tok)) &&
5118 sidout->num_auths < MAXSUBAUTHS) {
5120 * NOTE - the subauths are in native machine-endian format. They
5121 * are converted to little-endian when linearized onto the wire.
5123 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
5126 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
5128 return True;
5131 /*****************************************************************************
5132 * Provide a checksum on a string
5134 * Input: s - the nul-terminated character string for which the checksum
5135 * will be calculated.
5137 * Output: The checksum value calculated for s.
5139 * ****************************************************************************
5141 int str_checksum(char *s)
5143 int res = 0;
5144 int c;
5145 int i=0;
5147 while(*s) {
5148 c = *s;
5149 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
5150 s++;
5151 i++;
5153 return(res);
5154 } /* str_checksum */
5158 /*****************************************************************
5159 zero a memory area then free it. Used to catch bugs faster
5160 *****************************************************************/
5161 void zero_free(void *p, int size)
5163 memset(p, 0, size);
5164 free(p);