8b10939a97957d4338fef2d2b4dd7a4ba671e613
[ira/wip.git] / source3 / lib / util.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
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
31
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 */
38
39 pstring scope = "";
40
41 extern int DEBUGLEVEL;
42
43 BOOL passive = False;
44
45 int Protocol = PROTOCOL_COREPLUS;
46
47 /* a default finfo structure to ensure all fields are sensible */
48 file_info def_finfo = {-1,0,0,0,0,0,0,""};
49
50 /* the client file descriptor */
51 int Client = -1;
52
53 /* the last IP received from */
54 struct in_addr lastip;
55
56 /* the last port received from */
57 int lastport=0;
58
59 /* this is used by the chaining code */
60 int chain_size = 0;
61
62 int trans_num = 0;
63
64 /*
65    case handling on filenames 
66 */
67 int case_default = CASE_LOWER;
68
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;
76
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="";   
84
85 pstring sesssetup_user="";
86 pstring samlogon_user="";
87
88 BOOL sam_logon_in_ssb = False;
89
90 pstring global_myname = "";
91 fstring global_myworkgroup = "";
92 char **my_netbios_names;
93
94 int smb_read_error = 0;
95
96 static char *filename_dos(char *path,char *buf);
97
98
99
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)
105 {
106   char *p;
107   if ((p = getenv("TMPDIR"))) {
108     return p;
109   }
110   return "/tmp";
111 }
112
113
114
115 /****************************************************************************
116 determine if a file descriptor is in fact a socket
117 ****************************************************************************/
118 BOOL is_a_socket(int fd)
119 {
120   int v,l;
121   l = sizeof(int);
122   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
123 }
124
125
126 static char *last_ptr=NULL;
127
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)
135 {
136   char *s;
137   BOOL quoted;
138   int len=1;
139
140   if (!ptr) ptr = &last_ptr;
141   if (!ptr) return(False);
142
143   s = *ptr;
144
145   /* default to simple separators */
146   if (!sep) sep = " \t\n\r";
147
148   /* find the first non sep char */
149   while(*s && strchr(sep,*s)) s++;
150
151   /* nothing left? */
152   if (! *s) return(False);
153
154   /* copy over the token */
155   for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
156     {
157             if (*s == '\"') {
158                     quoted = !quoted;
159             } else {
160                     len++;
161                     *buff++ = *s;
162             }
163     }
164
165   *ptr = (*s) ? s+1 : s;  
166   *buff = 0;
167   last_ptr = *ptr;
168
169   return(True);
170 }
171
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)
177 {
178   char *s=last_ptr;
179   int ictok=0;
180   char **ret, **iret;
181
182   if (!sep) sep = " \t\n\r";
183
184   while(*s && strchr(sep,*s)) s++;
185
186   /* nothing left? */
187   if (!*s) return(NULL);
188
189   do {
190     ictok++;
191     while(*s && (!strchr(sep,*s))) s++;
192     while(*s && strchr(sep,*s)) *s++=0;
193   } while(*s);
194
195   *ctok=ictok;
196   s=last_ptr;
197
198   if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
199   
200   while(ictok--) {    
201     *iret++=s;
202     while(*s++);
203     while(!*s) s++;
204   }
205
206   return ret;
207 }
208
209
210 /* ************************************************************************* **
211  * Duplicate a block of memory.
212  * ************************************************************************* **
213  */
214 void *mem_dup( void *from, int size )
215   {
216   void *tmp;
217
218   tmp = malloc( size );
219   if( NULL != tmp )
220     (void)memcpy( tmp, from, size );
221   return( tmp );
222   } /* mem_dup */
223
224 /****************************************************************************
225 prompte a dptr (to make it recently used)
226 ****************************************************************************/
227 void array_promote(char *array,int elsize,int element)
228 {
229   char *p;
230   if (element == 0)
231     return;
232
233   p = (char *)malloc(elsize);
234
235   if (!p)
236     {
237       DEBUG(5,("Ahh! Can't malloc\n"));
238       return;
239     }
240   memcpy(p,array + element * elsize, elsize);
241   memmove(array + elsize,array,elsize*element);
242   memcpy(array,p,elsize);
243   free(p);
244 }
245
246 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
247
248 struct
249 {
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}};
287
288         
289
290 /****************************************************************************
291 set user socket options
292 ****************************************************************************/
293 void set_socket_options(int fd, char *options)
294 {
295   fstring tok;
296
297   while (next_token(&options,tok," \t,", sizeof(tok)))
298     {
299       int ret=0,i;
300       int value = 1;
301       char *p;
302       BOOL got_value = False;
303
304       if ((p = strchr(tok,'=')))
305         {
306           *p = 0;
307           value = atoi(p+1);
308           got_value = True;
309         }
310
311       for (i=0;socket_options[i].name;i++)
312         if (strequal(socket_options[i].name,tok))
313           break;
314
315       if (!socket_options[i].name)
316         {
317           DEBUG(0,("Unknown socket option %s\n",tok));
318           continue;
319         }
320
321       switch (socket_options[i].opttype)
322         {
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;
328
329         case OPT_ON:
330           if (got_value)
331             DEBUG(0,("syntax error - %s does not take a value\n",tok));
332
333           {
334             int on = socket_options[i].value;
335             ret = setsockopt(fd,socket_options[i].level,
336                              socket_options[i].option,(char *)&on,sizeof(int));
337           }
338           break;          
339         }
340       
341       if (ret != 0)
342         DEBUG(0,("Failed to set socket option %s\n",tok));
343     }
344 }
345
346
347
348 /****************************************************************************
349   close the socket communication
350 ****************************************************************************/
351 void close_sockets(void )
352 {
353 #ifdef WITH_SSL
354   sslutil_disconnect(Client);
355 #endif /* WITH_SSL */
356
357   close(Client);
358   Client = 0;
359 }
360
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)
365 {
366         int i;
367
368         if (group == current_gid) return(True);
369
370         for (i=0;i<ngroups;i++)
371                 if (group == groups[i])
372                         return(True);
373
374         return(False);
375 }
376
377 /****************************************************************************
378 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
379 ****************************************************************************/
380 char *StrCpy(char *dest,char *src)
381 {
382   char *d = dest;
383
384   /* I don't want to get lazy with these ... */
385   SMB_ASSERT(dest && src);
386
387   if (!dest) return(NULL);
388   if (!src) {
389     *dest = 0;
390     return(dest);
391   }
392   while ((*d++ = *src++)) ;
393   return(dest);
394 }
395
396 /****************************************************************************
397 line strncpy but always null terminates. Make sure there is room!
398 ****************************************************************************/
399 char *StrnCpy(char *dest,char *src,int n)
400 {
401   char *d = dest;
402   if (!dest) return(NULL);
403   if (!src) {
404     *dest = 0;
405     return(dest);
406   }
407   while (n-- && (*d++ = *src++)) ;
408   *d = 0;
409   return(dest);
410 }
411
412
413 /*******************************************************************
414 copy an IP address from one buffer to another
415 ********************************************************************/
416 void putip(void *dest,void *src)
417 {
418   memcpy(dest,src,4);
419 }
420
421
422 /****************************************************************************
423 interpret the weird netbios "name". Return the name type
424 ****************************************************************************/
425 static int name_interpret(char *in,char *out)
426 {
427   int ret;
428   int len = (*in++) / 2;
429
430   *out=0;
431
432   if (len > 30 || len<1) return(0);
433
434   while (len--)
435     {
436       if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
437         *out = 0;
438         return(0);
439       }
440       *out = ((in[0]-'A')<<4) + (in[1]-'A');
441       in += 2;
442       out++;
443     }
444   *out = 0;
445   ret = out[-1];
446
447 #ifdef NETBIOS_SCOPE
448   /* Handle any scope names */
449   while(*in) 
450     {
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;
457     }
458 #endif
459   return(ret);
460 }
461
462 /****************************************************************************
463 mangle a name into netbios format
464
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 )
468   {
469   int   i;
470   int   c;
471   int   len;
472   char  buf[20];
473   char *p = Out;
474
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 );
481
482   /* Place the length of the first field into the output buffer. */
483   p[0] = 32;
484   p++;
485
486   /* Now convert the name to the rfc1001/1002 format. */
487   for( i = 0; i < 16; i++ )
488     {
489     c = toupper( buf[i] );
490     p[i*2]     = ( (c >> 4) & 0x000F ) + 'A';
491     p[(i*2)+1] = (c & 0x000F) + 'A';
492     }
493   p += 32;
494   p[0] = '\0';
495
496   /* Add the scope string. */
497   for( i = 0, len = 0; NULL != scope; i++, len++ )
498     {
499     switch( scope[i] )
500       {
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;
514       }
515     }
516
517   return( name_len(Out) );
518   } /* name_mangle */
519
520 /*******************************************************************
521   check if a file exists
522 ********************************************************************/
523 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
524 {
525   SMB_STRUCT_STAT st;
526   if (!sbuf) sbuf = &st;
527   
528   if (dos_stat(fname,sbuf) != 0) 
529     return(False);
530
531   return(S_ISREG(sbuf->st_mode));
532 }
533
534 /*******************************************************************
535 check a files mod time
536 ********************************************************************/
537 time_t file_modtime(char *fname)
538 {
539   SMB_STRUCT_STAT st;
540   
541   if (dos_stat(fname,&st) != 0) 
542     return(0);
543
544   return(st.st_mtime);
545 }
546
547 /*******************************************************************
548   check if a directory exists
549 ********************************************************************/
550 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
551 {
552   SMB_STRUCT_STAT st2;
553   BOOL ret;
554
555   if (!st) st = &st2;
556
557   if (dos_stat(dname,st) != 0) 
558     return(False);
559
560   ret = S_ISDIR(st->st_mode);
561   if(!ret)
562     errno = ENOTDIR;
563   return ret;
564 }
565
566 /*******************************************************************
567 returns the size in bytes of the named file
568 ********************************************************************/
569 uint32 file_size(char *file_name)
570 {
571   SMB_STRUCT_STAT buf;
572   buf.st_size = 0;
573   dos_stat(file_name,&buf);
574   return(buf.st_size);
575 }
576
577 /*******************************************************************
578 return a string representing an attribute for a file
579 ********************************************************************/
580 char *attrib_string(int mode)
581 {
582   static fstring attrstr;
583
584   attrstr[0] = 0;
585
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");        
592
593   return(attrstr);
594 }
595
596
597 /*******************************************************************
598   case insensitive string compararison
599 ********************************************************************/
600 int StrCaseCmp(char *s, char *t)
601 {
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.
605    */
606 #if !defined(KANJI_WIN95_COMPATIBILITY)
607   /*
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.
614    */
615
616   if(lp_client_code_page() == KANJI_CODEPAGE)
617   {
618     /* Win95 treats full width ascii characters as case sensitive. */
619     int diff;
620     for (;;)
621     {
622       if (!*s || !*t)
623             return toupper (*s) - toupper (*t);
624       else if (is_sj_alph (*s) && is_sj_alph (*t))
625       {
626         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
627         if (diff)
628           return diff;
629         s += 2;
630         t += 2;
631       }
632       else if (is_shift_jis (*s) && is_shift_jis (*t))
633       {
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;
642       }
643       else if (is_shift_jis (*s))
644         return 1;
645       else if (is_shift_jis (*t))
646         return -1;
647       else 
648       {
649         diff = toupper (*s) - toupper (*t);
650         if (diff)
651           return diff;
652         s++;
653         t++;
654       }
655     }
656   }
657   else
658 #endif /* KANJI_WIN95_COMPATIBILITY */
659   {
660     while (*s && *t && toupper(*s) == toupper(*t))
661     {
662       s++;
663       t++;
664     }
665
666     return(toupper(*s) - toupper(*t));
667   }
668 }
669
670 /*******************************************************************
671   case insensitive string compararison, length limited
672 ********************************************************************/
673 int StrnCaseCmp(char *s, char *t, int n)
674 {
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.
678    */
679 #if !defined(KANJI_WIN95_COMPATIBILITY)
680   /*
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. 
687    */
688
689   if(lp_client_code_page() == KANJI_CODEPAGE)
690   {
691     /* Win95 treats full width ascii characters as case sensitive. */
692     int diff;
693     for (;n > 0;)
694     {
695       if (!*s || !*t)
696         return toupper (*s) - toupper (*t);
697       else if (is_sj_alph (*s) && is_sj_alph (*t))
698       {
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;
705       }
706       else if (is_shift_jis (*s) && is_shift_jis (*t))
707       {
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;
717       }
718       else if (is_shift_jis (*s))
719         return 1;
720       else if (is_shift_jis (*t))
721         return -1;
722       else 
723       {
724         diff = toupper (*s) - toupper (*t);
725         if (diff)
726           return diff;
727         s++;
728         t++;
729         n--;
730       }
731     }
732     return 0;
733   }
734   else
735 #endif /* KANJI_WIN95_COMPATIBILITY */
736   {
737     while (n && *s && *t && toupper(*s) == toupper(*t))
738     {
739       s++;
740       t++;
741       n--;
742     }
743
744     /* not run out of chars - strings are different lengths */
745     if (n) 
746       return(toupper(*s) - toupper(*t));
747
748     /* identical up to where we run out of chars, 
749        and strings are same length */
750     return(0);
751   }
752 }
753
754 /*******************************************************************
755   compare 2 strings 
756 ********************************************************************/
757 BOOL strequal(char *s1, char *s2)
758 {
759   if (s1 == s2) return(True);
760   if (!s1 || !s2) return(False);
761   
762   return(StrCaseCmp(s1,s2)==0);
763 }
764
765 /*******************************************************************
766   compare 2 strings up to and including the nth char.
767   ******************************************************************/
768 BOOL strnequal(char *s1,char *s2,int n)
769 {
770   if (s1 == s2) return(True);
771   if (!s1 || !s2 || !n) return(False);
772   
773   return(StrnCaseCmp(s1,s2,n)==0);
774 }
775
776 /*******************************************************************
777   compare 2 strings (case sensitive)
778 ********************************************************************/
779 BOOL strcsequal(char *s1,char *s2)
780 {
781   if (s1 == s2) return(True);
782   if (!s1 || !s2) return(False);
783   
784   return(strcmp(s1,s2)==0);
785 }
786
787
788 /*******************************************************************
789   convert a string to lower case
790 ********************************************************************/
791 void strlower(char *s)
792 {
793   while (*s)
794   {
795 #if !defined(KANJI_WIN95_COMPATIBILITY)
796   /*
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. 
803    */
804
805     if(lp_client_code_page() == KANJI_CODEPAGE)
806     {
807       /* Win95 treats full width ascii characters as case sensitive. */
808       if (is_shift_jis (*s))
809       {
810         if (is_sj_upper (s[0], s[1]))
811           s[1] = sj_tolower2 (s[1]);
812         s += 2;
813       }
814       else if (is_kana (*s))
815       {
816         s++;
817       }
818       else
819       {
820         if (isupper(*s))
821           *s = tolower(*s);
822         s++;
823       }
824     }
825     else
826 #endif /* KANJI_WIN95_COMPATIBILITY */
827     {
828       int skip = skip_multibyte_char( *s );
829       if( skip != 0 )
830         s += skip;
831       else
832       {
833         if (isupper(*s))
834           *s = tolower(*s);
835         s++;
836       }
837     }
838   }
839 }
840
841 /*******************************************************************
842   convert a string to upper case
843 ********************************************************************/
844 void strupper(char *s)
845 {
846   while (*s)
847   {
848 #if !defined(KANJI_WIN95_COMPATIBILITY)
849   /*
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. 
856    */
857
858     if(lp_client_code_page() == KANJI_CODEPAGE)
859     {
860       /* Win95 treats full width ascii characters as case sensitive. */
861       if (is_shift_jis (*s))
862       {
863         if (is_sj_lower (s[0], s[1]))
864           s[1] = sj_toupper2 (s[1]);
865         s += 2;
866       }
867       else if (is_kana (*s))
868       {
869         s++;
870       }
871       else
872       {
873         if (islower(*s))
874           *s = toupper(*s);
875         s++;
876       }
877     }
878     else
879 #endif /* KANJI_WIN95_COMPATIBILITY */
880     {
881       int skip = skip_multibyte_char( *s );
882       if( skip != 0 )
883         s += skip;
884       else
885       {
886         if (islower(*s))
887           *s = toupper(*s);
888         s++;
889       }
890     }
891   }
892 }
893
894 /*******************************************************************
895   convert a string to "normal" form
896 ********************************************************************/
897 void strnorm(char *s)
898 {
899   if (case_default == CASE_UPPER)
900     strupper(s);
901   else
902     strlower(s);
903 }
904
905 /*******************************************************************
906 check if a string is in "normal" case
907 ********************************************************************/
908 BOOL strisnormal(char *s)
909 {
910   if (case_default == CASE_UPPER)
911     return(!strhaslower(s));
912
913   return(!strhasupper(s));
914 }
915
916
917 /****************************************************************************
918   string replace
919 ****************************************************************************/
920 void string_replace(char *s,char oldc,char newc)
921 {
922   int skip;
923   while (*s)
924   {
925     skip = skip_multibyte_char( *s );
926     if( skip != 0 )
927       s += skip;
928     else
929     {
930       if (oldc == *s)
931         *s = newc;
932       s++;
933     }
934   }
935 }
936
937 /****************************************************************************
938   make a file into unix format
939 ****************************************************************************/
940 void unix_format(char *fname)
941 {
942   pstring namecopy;
943   string_replace(fname,'\\','/');
944
945   if (*fname == '/')
946     {
947       pstrcpy(namecopy,fname);
948       pstrcpy(fname,".");
949       pstrcat(fname,namecopy);
950     }  
951 }
952
953 /****************************************************************************
954   make a file into dos format
955 ****************************************************************************/
956 void dos_format(char *fname)
957 {
958   string_replace(fname,'/','\\');
959 }
960
961 /*******************************************************************
962   show a smb message structure
963 ********************************************************************/
964 void show_msg(char *buf)
965 {
966         int i;
967         int bcc=0;
968
969         if (DEBUGLEVEL < 5) return;
970
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)));
985
986         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
987         {
988                 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
989                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
990         }
991
992         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
993
994         DEBUG(5,("smb_bcc=%d\n",bcc));
995
996         if (DEBUGLEVEL < 10) return;
997
998         if (DEBUGLEVEL < 50)
999         {
1000                 bcc = MIN(bcc, 512);
1001         }
1002
1003         dump_data(10, smb_buf(buf), bcc);
1004 }
1005 /*******************************************************************
1006   return the length of an smb packet
1007 ********************************************************************/
1008 int smb_len(char *buf)
1009 {
1010   return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1011 }
1012
1013 /*******************************************************************
1014   set the length of an smb packet
1015 ********************************************************************/
1016 void _smb_setlen(char *buf,int len)
1017 {
1018   buf[0] = 0;
1019   buf[1] = (len&0x10000)>>16;
1020   buf[2] = (len&0xFF00)>>8;
1021   buf[3] = len&0xFF;
1022 }
1023
1024 /*******************************************************************
1025   set the length and marker of an smb packet
1026 ********************************************************************/
1027 void smb_setlen(char *buf,int len)
1028 {
1029   _smb_setlen(buf,len);
1030
1031   CVAL(buf,4) = 0xFF;
1032   CVAL(buf,5) = 'S';
1033   CVAL(buf,6) = 'M';
1034   CVAL(buf,7) = 'B';
1035 }
1036
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)
1041 {
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);
1048 }
1049
1050 /*******************************************************************
1051 return the number of smb words
1052 ********************************************************************/
1053 int smb_numwords(char *buf)
1054 {
1055   return (CVAL(buf,smb_wct));
1056 }
1057
1058 /*******************************************************************
1059 return the size of the smb_buf region of a message
1060 ********************************************************************/
1061 int smb_buflen(char *buf)
1062 {
1063   return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1064 }
1065
1066 /*******************************************************************
1067   return a pointer to the smb_buf data area
1068 ********************************************************************/
1069 int smb_buf_ofs(char *buf)
1070 {
1071   return (smb_size + CVAL(buf,smb_wct)*2);
1072 }
1073
1074 /*******************************************************************
1075   return a pointer to the smb_buf data area
1076 ********************************************************************/
1077 char *smb_buf(char *buf)
1078 {
1079   return (buf + smb_buf_ofs(buf));
1080 }
1081
1082 /*******************************************************************
1083 return the SMB offset into an SMB buffer
1084 ********************************************************************/
1085 int smb_offset(char *p,char *buf)
1086 {
1087   return(PTR_DIFF(p,buf+4) + chain_size);
1088 }
1089
1090
1091 /*******************************************************************
1092 skip past some strings in a buffer
1093 ********************************************************************/
1094 char *skip_string(char *buf,int n)
1095 {
1096   while (n--)
1097     buf += strlen(buf) + 1;
1098   return(buf);
1099 }
1100
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)
1105 {
1106   BOOL ret = False;
1107   while (front && *front && strncmp(s,front,strlen(front)) == 0)
1108     {
1109       char *p = s;
1110       ret = True;
1111       while (1)
1112         {
1113           if (!(*p = p[strlen(front)]))
1114             break;
1115           p++;
1116         }
1117     }
1118   while (back && *back && strlen(s) >= strlen(back) && 
1119          (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
1120     {
1121       ret = True;
1122       s[strlen(s)-strlen(back)] = 0;
1123     }
1124   return(ret);
1125 }
1126
1127
1128 /*******************************************************************
1129 reduce a file name, removing .. elements.
1130 ********************************************************************/
1131 void dos_clean_name(char *s)
1132 {
1133   char *p=NULL;
1134
1135   DEBUG(3,("dos_clean_name [%s]\n",s));
1136
1137   /* remove any double slashes */
1138   string_sub(s, "\\\\", "\\");
1139
1140   while ((p = strstr(s,"\\..\\")) != NULL)
1141     {
1142       pstring s1;
1143
1144       *p = 0;
1145       pstrcpy(s1,p+3);
1146
1147       if ((p=strrchr(s,'\\')) != NULL)
1148         *p = 0;
1149       else
1150         *s = 0;
1151       pstrcat(s,s1);
1152     }  
1153
1154   trim_string(s,NULL,"\\..");
1155
1156   string_sub(s, "\\.\\", "\\");
1157 }
1158
1159 /*******************************************************************
1160 reduce a file name, removing .. elements. 
1161 ********************************************************************/
1162 void unix_clean_name(char *s)
1163 {
1164   char *p=NULL;
1165
1166   DEBUG(3,("unix_clean_name [%s]\n",s));
1167
1168   /* remove any double slashes */
1169   string_sub(s, "//","/");
1170
1171   /* Remove leading ./ characters */
1172   if(strncmp(s, "./", 2) == 0) {
1173     trim_string(s, "./", NULL);
1174     if(*s == 0)
1175       pstrcpy(s,"./");
1176   }
1177
1178   while ((p = strstr(s,"/../")) != NULL)
1179     {
1180       pstring s1;
1181
1182       *p = 0;
1183       pstrcpy(s1,p+3);
1184
1185       if ((p=strrchr(s,'/')) != NULL)
1186         *p = 0;
1187       else
1188         *s = 0;
1189       pstrcat(s,s1);
1190     }  
1191
1192   trim_string(s,NULL,"/..");
1193 }
1194
1195
1196 /*******************************************************************
1197 a wrapper for the normal chdir() function
1198 ********************************************************************/
1199 int ChDir(char *path)
1200 {
1201   int res;
1202   static pstring LastDir="";
1203
1204   if (strcsequal(path,".")) return(0);
1205
1206   if (*path == '/' && strcsequal(LastDir,path)) return(0);
1207   DEBUG(3,("chdir to %s\n",path));
1208   res = dos_chdir(path);
1209   if (!res)
1210     pstrcpy(LastDir,path);
1211   return(res);
1212 }
1213
1214 /* number of list structures for a caching GetWd function. */
1215 #define MAX_GETWDCACHE (50)
1216
1217 struct
1218 {
1219   SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
1220   SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
1221   char *text;
1222   BOOL valid;
1223 } ino_list[MAX_GETWDCACHE];
1224
1225 BOOL use_getwd_cache=True;
1226
1227 /*******************************************************************
1228   return the absolute current directory path
1229   Note that this path is returned in UNIX format, not DOS
1230   format.
1231 ********************************************************************/
1232 char *GetWd(char *str)
1233 {
1234   pstring s;
1235   static BOOL getwd_cache_init = False;
1236   SMB_STRUCT_STAT st, st2;
1237   int i;
1238
1239   *s = 0;
1240
1241   if (!use_getwd_cache)
1242     return(sys_getwd(str));
1243
1244   /* init the cache */
1245   if (!getwd_cache_init)
1246   {
1247     getwd_cache_init = True;
1248     for (i=0;i<MAX_GETWDCACHE;i++)
1249     {
1250       string_init(&ino_list[i].text,"");
1251       ino_list[i].valid = False;
1252     }
1253   }
1254
1255   /*  Get the inode of the current directory, if this doesn't work we're
1256       in trouble :-) */
1257
1258   if (stat(".",&st) == -1) 
1259   {
1260     DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1261     return(sys_getwd(str));
1262   }
1263
1264
1265   for (i=0; i<MAX_GETWDCACHE; i++)
1266     if (ino_list[i].valid)
1267     {
1268
1269       /*  If we have found an entry with a matching inode and dev number
1270           then find the inode number for the directory in the cached string.
1271           If this agrees with that returned by the stat for the current
1272           directory then all is o.k. (but make sure it is a directory all
1273           the same...) */
1274       
1275       if (st.st_ino == ino_list[i].inode &&
1276           st.st_dev == ino_list[i].dev)
1277       {
1278         if (stat(ino_list[i].text,&st2) == 0)
1279         {
1280           if (st.st_ino == st2.st_ino &&
1281               st.st_dev == st2.st_dev &&
1282               (st2.st_mode & S_IFMT) == S_IFDIR)
1283           {
1284             pstrcpy (str, ino_list[i].text);
1285
1286             /* promote it for future use */
1287             array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1288             return (str);
1289           }
1290           else
1291           {
1292             /*  If the inode is different then something's changed, 
1293                 scrub the entry and start from scratch. */
1294             ino_list[i].valid = False;
1295           }
1296         }
1297       }
1298     }
1299
1300
1301   /*  We don't have the information to hand so rely on traditional methods.
1302       The very slow getcwd, which spawns a process on some systems, or the
1303       not quite so bad getwd. */
1304
1305   if (!sys_getwd(s))
1306   {
1307     DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1308     return (NULL);
1309   }
1310
1311   pstrcpy(str,s);
1312
1313   DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1314
1315   /* add it to the cache */
1316   i = MAX_GETWDCACHE - 1;
1317   string_set(&ino_list[i].text,s);
1318   ino_list[i].dev = st.st_dev;
1319   ino_list[i].inode = st.st_ino;
1320   ino_list[i].valid = True;
1321
1322   /* put it at the top of the list */
1323   array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1324
1325   return (str);
1326 }
1327
1328
1329
1330 /*******************************************************************
1331 reduce a file name, removing .. elements and checking that 
1332 it is below dir in the heirachy. This uses GetWd() and so must be run
1333 on the system that has the referenced file system.
1334
1335 widelinks are allowed if widelinks is true
1336 ********************************************************************/
1337 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1338 {
1339 #ifndef REDUCE_PATHS
1340   return True;
1341 #else
1342   pstring dir2;
1343   pstring wd;
1344   pstring base_name;
1345   pstring newname;
1346   char *p=NULL;
1347   BOOL relative = (*s != '/');
1348
1349   *dir2 = *wd = *base_name = *newname = 0;
1350
1351   if (widelinks)
1352     {
1353       unix_clean_name(s);
1354       /* can't have a leading .. */
1355       if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1356         {
1357           DEBUG(3,("Illegal file name? (%s)\n",s));
1358           return(False);
1359         }
1360
1361       if (strlen(s) == 0)
1362         pstrcpy(s,"./");
1363
1364       return(True);
1365     }
1366   
1367   DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1368
1369   /* remove any double slashes */
1370   string_sub(s,"//","/");
1371
1372   pstrcpy(base_name,s);
1373   p = strrchr(base_name,'/');
1374
1375   if (!p)
1376     return(True);
1377
1378   if (!GetWd(wd))
1379     {
1380       DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1381       return(False);
1382     }
1383
1384   if (ChDir(dir) != 0)
1385     {
1386       DEBUG(0,("couldn't chdir to %s\n",dir));
1387       return(False);
1388     }
1389
1390   if (!GetWd(dir2))
1391     {
1392       DEBUG(0,("couldn't getwd for %s\n",dir));
1393       ChDir(wd);
1394       return(False);
1395     }
1396
1397
1398     if (p && (p != base_name))
1399       {
1400         *p = 0;
1401         if (strcmp(p+1,".")==0)
1402           p[1]=0;
1403         if (strcmp(p+1,"..")==0)
1404           *p = '/';
1405       }
1406
1407   if (ChDir(base_name) != 0)
1408     {
1409       ChDir(wd);
1410       DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1411       return(False);
1412     }
1413
1414   if (!GetWd(newname))
1415     {
1416       ChDir(wd);
1417       DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1418       return(False);
1419     }
1420
1421   if (p && (p != base_name))
1422     {
1423       pstrcat(newname,"/");
1424       pstrcat(newname,p+1);
1425     }
1426
1427   {
1428     int l = strlen(dir2);    
1429     if (dir2[l-1] == '/')
1430       l--;
1431
1432     if (strncmp(newname,dir2,l) != 0)
1433       {
1434         ChDir(wd);
1435         DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1436         return(False);
1437       }
1438
1439     if (relative)
1440       {
1441         if (newname[l] == '/')
1442           pstrcpy(s,newname + l + 1);
1443         else
1444           pstrcpy(s,newname+l);
1445       }
1446     else
1447       pstrcpy(s,newname);
1448   }
1449
1450   ChDir(wd);
1451
1452   if (strlen(s) == 0)
1453     pstrcpy(s,"./");
1454
1455   DEBUG(3,("reduced to %s\n",s));
1456   return(True);
1457 #endif
1458 }
1459
1460 /****************************************************************************
1461 expand some *s 
1462 ****************************************************************************/
1463 static void expand_one(char *Mask,int len)
1464 {
1465   char *p1;
1466   while ((p1 = strchr(Mask,'*')) != NULL)
1467     {
1468       int lfill = (len+1) - strlen(Mask);
1469       int l1= (p1 - Mask);
1470       pstring tmp;
1471       pstrcpy(tmp,Mask);  
1472       memset(tmp+l1,'?',lfill);
1473       pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);  
1474       pstrcpy(Mask,tmp);      
1475     }
1476 }
1477
1478 /****************************************************************************
1479 expand a wildcard expression, replacing *s with ?s
1480 ****************************************************************************/
1481 void expand_mask(char *Mask,BOOL doext)
1482 {
1483   pstring mbeg,mext;
1484   pstring dirpart;
1485   pstring filepart;
1486   BOOL hasdot = False;
1487   char *p1;
1488   BOOL absolute = (*Mask == '\\');
1489
1490   *mbeg = *mext = *dirpart = *filepart = 0;
1491
1492   /* parse the directory and filename */
1493   if (strchr(Mask,'\\'))
1494     dirname_dos(Mask,dirpart);
1495
1496   filename_dos(Mask,filepart);
1497
1498   pstrcpy(mbeg,filepart);
1499   if ((p1 = strchr(mbeg,'.')) != NULL)
1500     {
1501       hasdot = True;
1502       *p1 = 0;
1503       p1++;
1504       pstrcpy(mext,p1);
1505     }
1506   else
1507     {
1508       pstrcpy(mext,"");
1509       if (strlen(mbeg) > 8)
1510         {
1511           pstrcpy(mext,mbeg + 8);
1512           mbeg[8] = 0;
1513         }
1514     }
1515
1516   if (*mbeg == 0)
1517     pstrcpy(mbeg,"????????");
1518   if ((*mext == 0) && doext && !hasdot)
1519     pstrcpy(mext,"???");
1520
1521   if (strequal(mbeg,"*") && *mext==0) 
1522     pstrcpy(mext,"*");
1523
1524   /* expand *'s */
1525   expand_one(mbeg,8);
1526   if (*mext)
1527     expand_one(mext,3);
1528
1529   pstrcpy(Mask,dirpart);
1530   if (*dirpart || absolute) pstrcat(Mask,"\\");
1531   pstrcat(Mask,mbeg);
1532   pstrcat(Mask,".");
1533   pstrcat(Mask,mext);
1534
1535   DEBUG(6,("Mask expanded to [%s]\n",Mask));
1536 }  
1537
1538
1539 /****************************************************************************
1540 does a string have any uppercase chars in it?
1541 ****************************************************************************/
1542 BOOL strhasupper(char *s)
1543 {
1544   while (*s) 
1545   {
1546 #if !defined(KANJI_WIN95_COMPATIBILITY)
1547   /*
1548    * For completeness we should put in equivalent code for code pages
1549    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1550    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1551    * here. They both treat full width ascii characters as case senstive
1552    * filenames (ie. they don't do the work we do here).
1553    * JRA. 
1554    */
1555
1556     if(lp_client_code_page() == KANJI_CODEPAGE)
1557     {
1558       /* Win95 treats full width ascii characters as case sensitive. */
1559       if (is_shift_jis (*s))
1560         s += 2;
1561       else if (is_kana (*s))
1562         s++;
1563       else
1564       {
1565         if (isupper(*s))
1566           return(True);
1567         s++;
1568       }
1569     }
1570     else
1571 #endif /* KANJI_WIN95_COMPATIBILITY */
1572     {
1573       int skip = skip_multibyte_char( *s );
1574       if( skip != 0 )
1575         s += skip;
1576       else {
1577         if (isupper(*s))
1578           return(True);
1579         s++;
1580       }
1581     }
1582   }
1583   return(False);
1584 }
1585
1586 /****************************************************************************
1587 does a string have any lowercase chars in it?
1588 ****************************************************************************/
1589 BOOL strhaslower(char *s)
1590 {
1591   while (*s) 
1592   {
1593 #if !defined(KANJI_WIN95_COMPATIBILITY)
1594   /*
1595    * For completeness we should put in equivalent code for code pages
1596    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1597    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1598    * here. They both treat full width ascii characters as case senstive
1599    * filenames (ie. they don't do the work we do here).
1600    * JRA. 
1601    */
1602
1603     if(lp_client_code_page() == KANJI_CODEPAGE)
1604     {
1605       /* Win95 treats full width ascii characters as case sensitive. */
1606       if (is_shift_jis (*s))
1607       {
1608         if (is_sj_upper (s[0], s[1]))
1609           return(True);
1610         if (is_sj_lower (s[0], s[1]))
1611           return (True);
1612         s += 2;
1613       }
1614       else if (is_kana (*s))
1615       {
1616         s++;
1617       }
1618       else
1619       {
1620         if (islower(*s))
1621           return(True);
1622         s++;
1623       }
1624     }
1625     else
1626 #endif /* KANJI_WIN95_COMPATIBILITY */
1627     {
1628       int skip = skip_multibyte_char( *s );
1629       if( skip != 0 )
1630         s += skip;
1631       else {
1632         if (islower(*s))
1633           return(True);
1634         s++;
1635       }
1636     }
1637   }
1638   return(False);
1639 }
1640
1641 /****************************************************************************
1642 find the number of chars in a string
1643 ****************************************************************************/
1644 int count_chars(char *s,char c)
1645 {
1646   int count=0;
1647
1648 #if !defined(KANJI_WIN95_COMPATIBILITY)
1649   /*
1650    * For completeness we should put in equivalent code for code pages
1651    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1652    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1653    * here. They both treat full width ascii characters as case senstive
1654    * filenames (ie. they don't do the work we do here).
1655    * JRA. 
1656    */
1657
1658   if(lp_client_code_page() == KANJI_CODEPAGE)
1659   {
1660     /* Win95 treats full width ascii characters as case sensitive. */
1661     while (*s) 
1662     {
1663       if (is_shift_jis (*s))
1664         s += 2;
1665       else 
1666       {
1667         if (*s == c)
1668           count++;
1669         s++;
1670       }
1671     }
1672   }
1673   else
1674 #endif /* KANJI_WIN95_COMPATIBILITY */
1675   {
1676     while (*s) 
1677     {
1678       int skip = skip_multibyte_char( *s );
1679       if( skip != 0 )
1680         s += skip;
1681       else {
1682         if (*s == c)
1683           count++;
1684         s++;
1685       }
1686     }
1687   }
1688   return(count);
1689 }
1690
1691
1692 /****************************************************************************
1693   make a dir struct
1694 ****************************************************************************/
1695 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1696 {  
1697   char *p;
1698   pstring mask2;
1699
1700   pstrcpy(mask2,mask);
1701
1702   if ((mode & aDIR) != 0)
1703     size = 0;
1704
1705   memset(buf+1,' ',11);
1706   if ((p = strchr(mask2,'.')) != NULL)
1707     {
1708       *p = 0;
1709       memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1710       memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1711       *p = '.';
1712     }
1713   else
1714     memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1715
1716   bzero(buf+21,DIR_STRUCT_SIZE-21);
1717   CVAL(buf,21) = mode;
1718   put_dos_date(buf,22,date);
1719   SSVAL(buf,26,size & 0xFFFF);
1720   SSVAL(buf,28,size >> 16);
1721   StrnCpy(buf+30,fname,12);
1722   if (!case_sensitive)
1723     strupper(buf+30);
1724   DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1725 }
1726
1727
1728 /*******************************************************************
1729 close the low 3 fd's and open dev/null in their place
1730 ********************************************************************/
1731 void close_low_fds(void)
1732 {
1733   int fd;
1734   int i;
1735   close(0); close(1); close(2);
1736   /* try and use up these file descriptors, so silly
1737      library routines writing to stdout etc won't cause havoc */
1738   for (i=0;i<3;i++) {
1739     fd = open("/dev/null",O_RDWR,0);
1740     if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1741     if (fd < 0) {
1742       DEBUG(0,("Can't open /dev/null\n"));
1743       return;
1744     }
1745     if (fd != i) {
1746       DEBUG(0,("Didn't get file descriptor %d\n",i));
1747       return;
1748     }
1749   }
1750 }
1751
1752 /****************************************************************************
1753 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1754 else
1755 if SYSV use O_NDELAY
1756 if BSD use FNDELAY
1757 ****************************************************************************/
1758 int set_blocking(int fd, BOOL set)
1759 {
1760   int val;
1761 #ifdef O_NONBLOCK
1762 #define FLAG_TO_SET O_NONBLOCK
1763 #else
1764 #ifdef SYSV
1765 #define FLAG_TO_SET O_NDELAY
1766 #else /* BSD */
1767 #define FLAG_TO_SET FNDELAY
1768 #endif
1769 #endif
1770
1771   if((val = fcntl(fd, F_GETFL, 0)) == -1)
1772         return -1;
1773   if(set) /* Turn blocking on - ie. clear nonblock flag */
1774         val &= ~FLAG_TO_SET;
1775   else
1776     val |= FLAG_TO_SET;
1777   return fcntl( fd, F_SETFL, val);
1778 #undef FLAG_TO_SET
1779 }
1780
1781
1782 /****************************************************************************
1783 write to a socket
1784 ****************************************************************************/
1785 int write_socket(int fd,char *buf,int len)
1786 {
1787   int ret=0;
1788
1789   if (passive)
1790     return(len);
1791   DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1792   ret = write_data(fd,buf,len);
1793       
1794   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1795   if(ret <= 0)
1796     DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
1797        len, fd, strerror(errno) ));
1798
1799   return(ret);
1800 }
1801
1802 /****************************************************************************
1803 read from a socket
1804 ****************************************************************************/
1805 int read_udp_socket(int fd,char *buf,int len)
1806 {
1807   int ret;
1808   struct sockaddr_in sock;
1809   int socklen;
1810   
1811   socklen = sizeof(sock);
1812   bzero((char *)&sock,socklen);
1813   bzero((char *)&lastip,sizeof(lastip));
1814   ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1815   if (ret <= 0) {
1816     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1817     return(0);
1818   }
1819
1820   lastip = sock.sin_addr;
1821   lastport = ntohs(sock.sin_port);
1822
1823   DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1824              inet_ntoa(lastip), lastport, ret));
1825
1826   return(ret);
1827 }
1828
1829 /****************************************************************************
1830 read data from a device with a timout in msec.
1831 mincount = if timeout, minimum to read before returning
1832 maxcount = number to be read.
1833 ****************************************************************************/
1834 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1835 {
1836   fd_set fds;
1837   int selrtn;
1838   int readret;
1839   int nread = 0;
1840   struct timeval timeout;
1841
1842   /* just checking .... */
1843   if (maxcnt <= 0) return(0);
1844
1845   smb_read_error = 0;
1846
1847   /* Blocking read */
1848   if (time_out <= 0) {
1849     if (mincnt == 0) mincnt = maxcnt;
1850
1851     while (nread < mincnt) {
1852 #ifdef WITH_SSL
1853       if(fd == sslFd){
1854         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1855       }else{
1856         readret = read(fd, buf + nread, maxcnt - nread);
1857       }
1858 #else /* WITH_SSL */
1859       readret = read(fd, buf + nread, maxcnt - nread);
1860 #endif /* WITH_SSL */
1861
1862       if (readret == 0) {
1863         smb_read_error = READ_EOF;
1864         return -1;
1865       }
1866
1867       if (readret == -1) {
1868         smb_read_error = READ_ERROR;
1869         return -1;
1870       }
1871       nread += readret;
1872     }
1873     return(nread);
1874   }
1875   
1876   /* Most difficult - timeout read */
1877   /* If this is ever called on a disk file and 
1878          mincnt is greater then the filesize then
1879          system performance will suffer severely as 
1880          select always return true on disk files */
1881
1882   /* Set initial timeout */
1883   timeout.tv_sec = time_out / 1000;
1884   timeout.tv_usec = 1000 * (time_out % 1000);
1885
1886   for (nread=0; nread<mincnt; ) 
1887     {      
1888       FD_ZERO(&fds);
1889       FD_SET(fd,&fds);
1890       
1891       selrtn = sys_select(fd+1,&fds,&timeout);
1892
1893       /* Check if error */
1894       if(selrtn == -1) {
1895         /* something is wrong. Maybe the socket is dead? */
1896         smb_read_error = READ_ERROR;
1897         return -1;
1898       }
1899       
1900       /* Did we timeout ? */
1901       if (selrtn == 0) {
1902         smb_read_error = READ_TIMEOUT;
1903         return -1;
1904       }
1905       
1906 #ifdef WITH_SSL
1907     if(fd == sslFd){
1908       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1909     }else{
1910       readret = read(fd, buf + nread, maxcnt - nread);
1911     }
1912 #else /* WITH_SSL */
1913     readret = read(fd, buf+nread, maxcnt-nread);
1914 #endif /* WITH_SSL */
1915
1916       if (readret == 0) {
1917         /* we got EOF on the file descriptor */
1918         smb_read_error = READ_EOF;
1919         return -1;
1920       }
1921
1922       if (readret == -1) {
1923         /* the descriptor is probably dead */
1924         smb_read_error = READ_ERROR;
1925         return -1;
1926       }
1927       
1928       nread += readret;
1929     }
1930
1931   /* Return the number we got */
1932   return(nread);
1933 }
1934
1935 /****************************************************************************
1936 read data from the client. Maxtime is in milliseconds
1937 ****************************************************************************/
1938 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1939 {
1940   fd_set fds;
1941   int selrtn;
1942   int nread;
1943   struct timeval timeout;
1944  
1945   FD_ZERO(&fds);
1946   FD_SET(fd,&fds);
1947
1948   timeout.tv_sec = maxtime / 1000;
1949   timeout.tv_usec = (maxtime % 1000) * 1000;
1950
1951   selrtn = sys_select(fd+1,&fds,maxtime>0?&timeout:NULL);
1952
1953   if (!FD_ISSET(fd,&fds))
1954     return 0;
1955
1956   nread = read_udp_socket(fd, buffer, bufsize);
1957
1958   /* return the number got */
1959   return(nread);
1960 }
1961
1962 /*******************************************************************
1963 find the difference in milliseconds between two struct timeval
1964 values
1965 ********************************************************************/
1966 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1967 {
1968   return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
1969          ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
1970 }
1971
1972 /****************************************************************************
1973 send a keepalive packet (rfc1002)
1974 ****************************************************************************/
1975 BOOL send_keepalive(int client)
1976 {
1977   unsigned char buf[4];
1978
1979   buf[0] = 0x85;
1980   buf[1] = buf[2] = buf[3] = 0;
1981
1982   return(write_data(client,(char *)buf,4) == 4);
1983 }
1984
1985
1986
1987 /****************************************************************************
1988   read data from the client, reading exactly N bytes. 
1989 ****************************************************************************/
1990 int read_data(int fd,char *buffer,int N)
1991 {
1992   int  ret;
1993   int total=0;  
1994  
1995   smb_read_error = 0;
1996
1997   while (total < N)
1998   {
1999 #ifdef WITH_SSL
2000     if(fd == sslFd){
2001       ret = SSL_read(ssl, buffer + total, N - total);
2002     }else{
2003       ret = read(fd,buffer + total,N - total);
2004     }
2005 #else /* WITH_SSL */
2006     ret = read(fd,buffer + total,N - total);
2007 #endif /* WITH_SSL */
2008
2009     if (ret == 0)
2010     {
2011       smb_read_error = READ_EOF;
2012       return 0;
2013     }
2014     if (ret == -1)
2015     {
2016       smb_read_error = READ_ERROR;
2017       return -1;
2018     }
2019     total += ret;
2020   }
2021   return total;
2022 }
2023
2024
2025 /****************************************************************************
2026   write data to a fd 
2027 ****************************************************************************/
2028 int write_data(int fd,char *buffer,int N)
2029 {
2030   int total=0;
2031   int ret;
2032
2033   while (total < N)
2034   {
2035 #ifdef WITH_SSL
2036     if(fd == sslFd){
2037       ret = SSL_write(ssl,buffer + total,N - total);
2038     }else{
2039       ret = write(fd,buffer + total,N - total);
2040     }
2041 #else /* WITH_SSL */
2042     ret = write(fd,buffer + total,N - total);
2043 #endif /* WITH_SSL */
2044
2045     if (ret == -1) return -1;
2046     if (ret == 0) return total;
2047
2048     total += ret;
2049   }
2050   return total;
2051 }
2052
2053
2054 /****************************************************************************
2055 transfer some data between two fd's
2056 ****************************************************************************/
2057 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2058 {
2059   static char *buf=NULL;  
2060   static int size=0;
2061   char *buf1,*abuf;
2062   int total = 0;
2063
2064   DEBUG(4,("transfer_file %d  (head=%d) called\n",n,headlen));
2065
2066   if (size == 0) {
2067     size = lp_readsize();
2068     size = MAX(size,1024);
2069   }
2070
2071   while (!buf && size>0) {
2072     buf = (char *)Realloc(buf,size+8);
2073     if (!buf) size /= 2;
2074   }
2075
2076   if (!buf) {
2077     DEBUG(0,("Can't allocate transfer buffer!\n"));
2078     exit(1);
2079   }
2080
2081   abuf = buf + (align%8);
2082
2083   if (header)
2084     n += headlen;
2085
2086   while (n > 0)
2087     {
2088       int s = MIN(n,size);
2089       int ret,ret2=0;
2090
2091       ret = 0;
2092
2093       if (header && (headlen >= MIN(s,1024))) {
2094         buf1 = header;
2095         s = headlen;
2096         ret = headlen;
2097         headlen = 0;
2098         header = NULL;
2099       } else {
2100         buf1 = abuf;
2101       }
2102
2103       if (header && headlen > 0)
2104         {
2105           ret = MIN(headlen,size);
2106           memcpy(buf1,header,ret);
2107           headlen -= ret;
2108           header += ret;
2109           if (headlen <= 0) header = NULL;
2110         }
2111
2112       if (s > ret)
2113         ret += read(infd,buf1+ret,s-ret);
2114
2115       if (ret > 0)
2116         {
2117           ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2118           if (ret2 > 0) total += ret2;
2119           /* if we can't write then dump excess data */
2120           if (ret2 != ret)
2121             transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2122         }
2123       if (ret <= 0 || ret2 != ret)
2124         return(total);
2125       n -= ret;
2126     }
2127   return(total);
2128 }
2129
2130
2131 /****************************************************************************
2132 read 4 bytes of a smb packet and return the smb length of the packet
2133 store the result in the buffer
2134 This version of the function will return a length of zero on receiving
2135 a keepalive packet.
2136 ****************************************************************************/
2137 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2138 {
2139   int len=0, msg_type;
2140   BOOL ok=False;
2141
2142   while (!ok)
2143     {
2144       if (timeout > 0)
2145         ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2146       else 
2147         ok = (read_data(fd,inbuf,4) == 4);
2148
2149       if (!ok)
2150         return(-1);
2151
2152       len = smb_len(inbuf);
2153       msg_type = CVAL(inbuf,0);
2154
2155       if (msg_type == 0x85) 
2156         DEBUG(5,("Got keepalive packet\n"));
2157     }
2158
2159   DEBUG(10,("got smb length of %d\n",len));
2160
2161   return(len);
2162 }
2163
2164 /****************************************************************************
2165 read 4 bytes of a smb packet and return the smb length of the packet
2166 store the result in the buffer. This version of the function will
2167 never return a session keepalive (length of zero).
2168 ****************************************************************************/
2169 int read_smb_length(int fd,char *inbuf,int timeout)
2170 {
2171   int len;
2172
2173   for(;;)
2174   {
2175     len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2176
2177     if(len < 0)
2178       return len;
2179
2180     /* Ignore session keepalives. */
2181     if(CVAL(inbuf,0) != 0x85)
2182       break;
2183   }
2184
2185   return len;
2186 }
2187
2188 /****************************************************************************
2189   read an smb from a fd. Note that the buffer *MUST* be of size
2190   BUFFER_SIZE+SAFETY_MARGIN.
2191   The timeout is in milli seconds. 
2192
2193   This function will return on a
2194   receipt of a session keepalive packet.
2195 ****************************************************************************/
2196 BOOL receive_smb(int fd,char *buffer, int timeout)
2197 {
2198   int len,ret;
2199
2200   smb_read_error = 0;
2201
2202   bzero(buffer,smb_size + 100);
2203
2204   len = read_smb_length_return_keepalive(fd,buffer,timeout);
2205   if (len < 0)
2206     return(False);
2207
2208   if (len > BUFFER_SIZE) {
2209     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2210     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2211       exit(1);
2212   }
2213
2214   if(len > 0) {
2215     ret = read_data(fd,buffer+4,len);
2216     if (ret != len) {
2217       smb_read_error = READ_ERROR;
2218       return False;
2219     }
2220   }
2221   return(True);
2222 }
2223
2224 /****************************************************************************
2225   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
2226   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2227   The timeout is in milli seconds
2228
2229   This is exactly the same as receive_smb except that it never returns
2230   a session keepalive packet (just as receive_smb used to do).
2231   receive_smb was changed to return keepalives as the oplock processing means this call
2232   should never go into a blocking read.
2233 ****************************************************************************/
2234
2235 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2236 {
2237   BOOL ret;
2238
2239   for(;;)
2240   {
2241     ret = receive_smb(fd, buffer, timeout);
2242
2243     if(ret == False)
2244       return ret;
2245
2246     /* Ignore session keepalive packets. */
2247     if(CVAL(buffer,0) != 0x85)
2248       break;
2249   }
2250   return ret;
2251 }
2252
2253 /****************************************************************************
2254   read a message from a udp fd.
2255 The timeout is in milli seconds
2256 ****************************************************************************/
2257 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2258 {
2259   struct sockaddr_in from;
2260   int fromlen = sizeof(from);
2261   int32 msg_len = 0;
2262
2263   smb_read_error = 0;
2264
2265   if(timeout != 0)
2266   {
2267     struct timeval to;
2268     fd_set fds;
2269     int selrtn;
2270
2271     FD_ZERO(&fds);
2272     FD_SET(fd,&fds);
2273
2274     to.tv_sec = timeout / 1000;
2275     to.tv_usec = (timeout % 1000) * 1000;
2276
2277     selrtn = sys_select(fd+1,&fds,&to);
2278
2279     /* Check if error */
2280     if(selrtn == -1) 
2281     {
2282       /* something is wrong. Maybe the socket is dead? */
2283       smb_read_error = READ_ERROR;
2284       return False;
2285     } 
2286     
2287     /* Did we timeout ? */
2288     if (selrtn == 0) 
2289     {
2290       smb_read_error = READ_TIMEOUT;
2291       return False;
2292     }
2293   }
2294
2295   /*
2296    * Read a loopback udp message.
2297    */
2298   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2299                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2300                      (struct sockaddr *)&from, &fromlen);
2301
2302   if(msg_len < 0)
2303   {
2304     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2305     return False;
2306   }
2307
2308   /* Validate message length. */
2309   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2310   {
2311     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2312               msg_len, 
2313               buffer_len  - UDP_CMD_HEADER_LEN));
2314     return False;
2315   }
2316
2317   /* Validate message from address (must be localhost). */
2318   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2319   {
2320     DEBUG(0,("receive_local_message: invalid 'from' address \
2321 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2322    return False;
2323   }
2324
2325   /* Setup the message header */
2326   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2327   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2328
2329   return True;
2330 }
2331
2332 /****************************************************************************
2333  structure to hold a linked list of local messages.
2334  for processing.
2335 ****************************************************************************/
2336
2337 typedef struct {
2338    ubi_slNode msg_next;
2339    char *msg_buf;
2340    int msg_len;
2341 } pending_message_list;
2342
2343 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
2344
2345 /****************************************************************************
2346  Function to push a message onto the tail of a linked list of smb messages ready
2347  for processing.
2348 ****************************************************************************/
2349
2350 static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
2351 {
2352   pending_message_list *msg = (pending_message_list *)
2353                                malloc(sizeof(pending_message_list));
2354
2355   if(msg == NULL)
2356   {
2357     DEBUG(0,("push_local_message: malloc fail (1)\n"));
2358     return False;
2359   }
2360
2361   msg->msg_buf = (char *)malloc(msg_len);
2362   if(msg->msg_buf == NULL)
2363   {
2364     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2365     free((char *)msg);
2366     return False;
2367   }
2368
2369   memcpy(msg->msg_buf, buf, msg_len);
2370   msg->msg_len = msg_len;
2371
2372   ubi_slAddTail( list_head, msg);
2373
2374   return True;
2375 }
2376
2377 /****************************************************************************
2378  Function to push a smb message onto a linked list of local smb messages ready
2379  for processing.
2380 ****************************************************************************/
2381
2382 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
2383 {
2384   return push_local_message(&smb_oplock_queue, buf, msg_len);
2385 }
2386
2387 /****************************************************************************
2388   Do a select on an two fd's - with timeout. 
2389
2390   If a local udp message has been pushed onto the
2391   queue (this can only happen during oplock break
2392   processing) return this first.
2393
2394   If a pending smb message has been pushed onto the
2395   queue (this can only happen during oplock break
2396   processing) return this next.
2397
2398   If the first smbfd is ready then read an smb from it.
2399   if the second (loopback UDP) fd is ready then read a message
2400   from it and setup the buffer header to identify the length
2401   and from address.
2402   Returns False on timeout or error.
2403   Else returns True.
2404
2405 The timeout is in milli seconds
2406 ****************************************************************************/
2407 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2408                            char *buffer, int buffer_len, 
2409                            int timeout, BOOL *got_smb)
2410 {
2411   fd_set fds;
2412   int selrtn;
2413   struct timeval to;
2414
2415   smb_read_error = 0;
2416
2417   *got_smb = False;
2418
2419   /*
2420    * Check to see if we already have a message on the smb queue.
2421    * If so - copy and return it.
2422    */
2423   
2424   if(ubi_slCount(&smb_oplock_queue) != 0)
2425   {
2426     pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
2427     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2428   
2429     /* Free the message we just copied. */
2430     free((char *)msg->msg_buf);
2431     free((char *)msg);
2432     *got_smb = True;
2433
2434     DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2435     return True;
2436   }
2437
2438   FD_ZERO(&fds);
2439   FD_SET(smbfd,&fds);
2440   FD_SET(oplock_fd,&fds);
2441
2442   to.tv_sec = timeout / 1000;
2443   to.tv_usec = (timeout % 1000) * 1000;
2444
2445   selrtn = sys_select(MAX(smbfd,oplock_fd)+1,&fds,timeout>0?&to:NULL);
2446
2447   /* Check if error */
2448   if(selrtn == -1) {
2449     /* something is wrong. Maybe the socket is dead? */
2450     smb_read_error = READ_ERROR;
2451     return False;
2452   } 
2453     
2454   /* Did we timeout ? */
2455   if (selrtn == 0) {
2456     smb_read_error = READ_TIMEOUT;
2457     return False;
2458   }
2459
2460   if (FD_ISSET(smbfd,&fds))
2461   {
2462     *got_smb = True;
2463     return receive_smb(smbfd, buffer, 0);
2464   }
2465   else
2466   {
2467     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2468   }
2469 }
2470
2471 /****************************************************************************
2472   send an smb to a fd 
2473 ****************************************************************************/
2474 BOOL send_smb(int fd,char *buffer)
2475 {
2476   int len;
2477   int ret,nwritten=0;
2478   len = smb_len(buffer) + 4;
2479
2480   while (nwritten < len)
2481     {
2482       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2483       if (ret <= 0)
2484         {
2485           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2486           close_sockets();
2487           exit(1);
2488         }
2489       nwritten += ret;
2490     }
2491
2492
2493   return True;
2494 }
2495
2496
2497 /****************************************************************************
2498 find a pointer to a netbios name
2499 ****************************************************************************/
2500 char *name_ptr(char *buf,int ofs)
2501 {
2502   unsigned char c = *(unsigned char *)(buf+ofs);
2503
2504   if ((c & 0xC0) == 0xC0)
2505     {
2506       uint16 l;
2507       char p[2];
2508       memcpy(p,buf+ofs,2);
2509       p[0] &= ~0xC0;
2510       l = RSVAL(p,0);
2511       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2512       return(buf + l);
2513     }
2514   else
2515     return(buf+ofs);
2516 }  
2517
2518 /****************************************************************************
2519 extract a netbios name from a buf
2520 ****************************************************************************/
2521 int name_extract(char *buf,int ofs,char *name)
2522 {
2523   char *p = name_ptr(buf,ofs);
2524   int d = PTR_DIFF(p,buf+ofs);
2525   pstrcpy(name,"");
2526   if (d < -50 || d > 50) return(0);
2527   return(name_interpret(p,name));
2528 }
2529   
2530 /****************************************************************************
2531 return the total storage length of a mangled name
2532 ****************************************************************************/
2533 int name_len( char *s )
2534   {
2535   int len;
2536
2537   /* If the two high bits of the byte are set, return 2. */
2538   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2539     return(2);
2540
2541   /* Add up the length bytes. */
2542   for( len = 1; (*s); s += (*s) + 1 )
2543     {
2544     len += *s + 1;
2545     }
2546
2547   return( len );
2548   } /* name_len */
2549
2550 /****************************************************************************
2551 send a single packet to a port on another machine
2552 ****************************************************************************/
2553 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2554 {
2555   BOOL ret;
2556   int out_fd;
2557   struct sockaddr_in sock_out;
2558
2559   if (passive)
2560     return(True);
2561
2562   /* create a socket to write to */
2563   out_fd = socket(AF_INET, type, 0);
2564   if (out_fd == -1) 
2565     {
2566       DEBUG(0,("socket failed"));
2567       return False;
2568     }
2569
2570   /* set the address and port */
2571   bzero((char *)&sock_out,sizeof(sock_out));
2572   putip((char *)&sock_out.sin_addr,(char *)&ip);
2573   sock_out.sin_port = htons( port );
2574   sock_out.sin_family = AF_INET;
2575   
2576   if (DEBUGLEVEL > 0)
2577     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2578              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2579         
2580   /* send it */
2581   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2582
2583   if (!ret)
2584     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2585              inet_ntoa(ip),port,strerror(errno)));
2586
2587   close(out_fd);
2588   return(ret);
2589 }
2590
2591 /*******************************************************************
2592 sleep for a specified number of milliseconds
2593 ********************************************************************/
2594 void msleep(int t)
2595 {
2596   int tdiff=0;
2597   struct timeval tval,t1,t2;  
2598   fd_set fds;
2599
2600   GetTimeOfDay(&t1);
2601   GetTimeOfDay(&t2);
2602   
2603   while (tdiff < t) {
2604     tval.tv_sec = (t-tdiff)/1000;
2605     tval.tv_usec = 1000*((t-tdiff)%1000);
2606  
2607     FD_ZERO(&fds);
2608     errno = 0;
2609     sys_select(0,&fds,&tval);
2610
2611     GetTimeOfDay(&t2);
2612     tdiff = TvalDiff(&t1,&t2);
2613   }
2614 }
2615
2616 /****************************************************************************
2617 check if a string is part of a list
2618 ****************************************************************************/
2619 BOOL in_list(char *s,char *list,BOOL casesensitive)
2620 {
2621   pstring tok;
2622   char *p=list;
2623
2624   if (!list) return(False);
2625
2626   while (next_token(&p,tok,LIST_SEP,sizeof(tok)))
2627     {
2628       if (casesensitive) {
2629         if (strcmp(tok,s) == 0)
2630           return(True);
2631       } else {
2632         if (StrCaseCmp(tok,s) == 0)
2633           return(True);
2634       }
2635     }
2636   return(False);
2637 }
2638
2639 /* this is used to prevent lots of mallocs of size 1 */
2640 static char *null_string = NULL;
2641
2642 /****************************************************************************
2643 set a string value, allocing the space for the string
2644 ****************************************************************************/
2645 BOOL string_init(char **dest,char *src)
2646 {
2647   int l;
2648   if (!src)     
2649     src = "";
2650
2651   l = strlen(src);
2652
2653   if (l == 0)
2654     {
2655       if (!null_string)
2656         null_string = (char *)malloc(1);
2657
2658       *null_string = 0;
2659       *dest = null_string;
2660     }
2661   else
2662     {
2663       (*dest) = (char *)malloc(l+1);
2664       if ((*dest) == NULL) {
2665               DEBUG(0,("Out of memory in string_init\n"));
2666               return False;
2667       }
2668
2669       pstrcpy(*dest,src);
2670     }
2671   return(True);
2672 }
2673
2674 /****************************************************************************
2675 free a string value
2676 ****************************************************************************/
2677 void string_free(char **s)
2678 {
2679   if (!s || !(*s)) return;
2680   if (*s == null_string)
2681     *s = NULL;
2682   if (*s) free(*s);
2683   *s = NULL;
2684 }
2685
2686 /****************************************************************************
2687 set a string value, allocing the space for the string, and deallocating any 
2688 existing space
2689 ****************************************************************************/
2690 BOOL string_set(char **dest,char *src)
2691 {
2692   string_free(dest);
2693
2694   return(string_init(dest,src));
2695 }
2696
2697 /****************************************************************************
2698 substitute a string for a pattern in another string. Make sure there is 
2699 enough room!
2700
2701 This routine looks for pattern in s and replaces it with 
2702 insert. It may do multiple replacements.
2703
2704 return True if a substitution was done.
2705 ****************************************************************************/
2706 BOOL string_sub(char *s,char *pattern,char *insert)
2707 {
2708   BOOL ret = False;
2709   char *p;
2710   int ls,lp,li;
2711
2712   if (!insert || !pattern || !s) return(False);
2713
2714   ls = strlen(s);
2715   lp = strlen(pattern);
2716   li = strlen(insert);
2717
2718   if (!*pattern) return(False);
2719
2720   while (lp <= ls && (p = strstr(s,pattern)))
2721     {
2722       ret = True;
2723       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2724       memcpy(p,insert,li);
2725       s = p + li;
2726       ls = strlen(s);
2727     }
2728   return(ret);
2729 }
2730
2731 /*********************************************************
2732 * Recursive routine that is called by unix_mask_match.
2733 * Does the actual matching. This is the 'original code' 
2734 * used by the unix matcher.
2735 *********************************************************/
2736 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2737 {
2738   char *p;
2739
2740   for( p = regexp; *p && *str; ) {
2741     switch(*p) {
2742     case '?':
2743       str++; p++;
2744       break;
2745
2746     case '*':
2747       /* Look for a character matching 
2748          the one after the '*' */
2749       p++;
2750       if(!*p)
2751         return True; /* Automatic match */
2752       while(*str) {
2753         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2754           str++;
2755         if(unix_do_match(str,p,case_sig))
2756           return True;
2757         if(!*str)
2758           return False;
2759         else
2760           str++;
2761       }
2762       return False;
2763
2764     default:
2765       if(case_sig) {
2766         if(*str != *p)
2767           return False;
2768       } else {
2769         if(toupper(*str) != toupper(*p))
2770           return False;
2771       }
2772       str++, p++;
2773       break;
2774     }
2775   }
2776   if(!*p && !*str)
2777     return True;
2778
2779   if (!*p && str[0] == '.' && str[1] == 0)
2780     return(True);
2781   
2782   if (!*str && *p == '?')
2783     {
2784       while (*p == '?') p++;
2785       return(!*p);
2786     }
2787
2788   if(!*str && (*p == '*' && p[1] == '\0'))
2789     return True;
2790   return False;
2791 }
2792
2793
2794 /*********************************************************
2795 * Routine to match a given string with a regexp - uses
2796 * simplified regexp that takes * and ? only. Case can be
2797 * significant or not.
2798 * This is the 'original code' used by the unix matcher.
2799 *********************************************************/
2800
2801 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2802 {
2803   char *p;
2804   pstring p1, p2;
2805   fstring ebase,eext,sbase,sext;
2806
2807   BOOL matched;
2808
2809   /* Make local copies of str and regexp */
2810   StrnCpy(p1,regexp,sizeof(pstring)-1);
2811   StrnCpy(p2,str,sizeof(pstring)-1);
2812
2813   if (!strchr(p2,'.')) {
2814     pstrcat(p2,".");
2815   }
2816
2817   /* Remove any *? and ** as they are meaningless */
2818   for(p = p1; *p; p++)
2819     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2820       (void)pstrcpy( &p[1], &p[2]);
2821
2822   if (strequal(p1,"*")) return(True);
2823
2824   DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2825
2826   if (trans2) {
2827     fstrcpy(ebase,p1);
2828     fstrcpy(sbase,p2);
2829   } else {
2830     if ((p=strrchr(p1,'.'))) {
2831       *p = 0;
2832       fstrcpy(ebase,p1);
2833       fstrcpy(eext,p+1);
2834     } else {
2835       fstrcpy(ebase,p1);
2836       eext[0] = 0;
2837     }
2838
2839   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2840     *p = 0;
2841     fstrcpy(sbase,p2);
2842     fstrcpy(sext,p+1);
2843   } else {
2844     fstrcpy(sbase,p2);
2845     fstrcpy(sext,"");
2846   }
2847   }
2848
2849   matched = unix_do_match(sbase,ebase,case_sig) && 
2850     (trans2 || unix_do_match(sext,eext,case_sig));
2851
2852   DEBUG(8,("unix_mask_match returning %d\n", matched));
2853
2854   return matched;
2855 }
2856
2857 /*********************************************************
2858 * Recursive routine that is called by mask_match.
2859 * Does the actual matching. Returns True if matched,
2860 * False if failed. This is the 'new' NT style matcher.
2861 *********************************************************/
2862
2863 BOOL do_match(char *str, char *regexp, int case_sig)
2864 {
2865   char *p;
2866
2867   for( p = regexp; *p && *str; ) {
2868     switch(*p) {
2869     case '?':
2870       str++; p++;
2871       break;
2872
2873     case '*':
2874       /* Look for a character matching 
2875          the one after the '*' */
2876       p++;
2877       if(!*p)
2878         return True; /* Automatic match */
2879       while(*str) {
2880         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2881           str++;
2882         /* Now eat all characters that match, as
2883            we want the *last* character to match. */
2884         while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2885           str++;
2886         str--; /* We've eaten the match char after the '*' */
2887         if(do_match(str,p,case_sig)) {
2888           return True;
2889         }
2890         if(!*str) {
2891           return False;
2892         } else {
2893           str++;
2894         }
2895       }
2896       return False;
2897
2898     default:
2899       if(case_sig) {
2900         if(*str != *p) {
2901           return False;
2902         }
2903       } else {
2904         if(toupper(*str) != toupper(*p)) {
2905           return False;
2906         }
2907       }
2908       str++, p++;
2909       break;
2910     }
2911   }
2912
2913   if(!*p && !*str)
2914     return True;
2915
2916   if (!*p && str[0] == '.' && str[1] == 0) {
2917     return(True);
2918   }
2919   
2920   if (!*str && *p == '?') {
2921     while (*p == '?')
2922       p++;
2923     return(!*p);
2924   }
2925
2926   if(!*str && (*p == '*' && p[1] == '\0')) {
2927     return True;
2928   }
2929  
2930   return False;
2931 }
2932
2933
2934 /*********************************************************
2935 * Routine to match a given string with a regexp - uses
2936 * simplified regexp that takes * and ? only. Case can be
2937 * significant or not.
2938 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2939 * This is the new 'NT style' matcher.
2940 *********************************************************/
2941
2942 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2943 {
2944   char *p;
2945   pstring t_pattern, t_filename, te_pattern, te_filename;
2946   fstring ebase,eext,sbase,sext;
2947
2948   BOOL matched = False;
2949
2950   /* Make local copies of str and regexp */
2951   pstrcpy(t_pattern,regexp);
2952   pstrcpy(t_filename,str);
2953
2954 #if 0
2955   /* 
2956    * Not sure if this is a good idea. JRA.
2957    */
2958   if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2959     trans2 = False;
2960 #endif
2961
2962 #if 0
2963   if (!strchr(t_filename,'.')) {
2964     pstrcat(t_filename,".");
2965   }
2966 #endif
2967
2968   /* Remove any *? and ** as they are meaningless */
2969   string_sub(t_pattern, "*?", "*");
2970   string_sub(t_pattern, "**", "*");
2971
2972   if (strequal(t_pattern,"*"))
2973     return(True);
2974
2975   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2976
2977   if(trans2) {
2978     /*
2979      * Match each component of the regexp, split up by '.'
2980      * characters.
2981      */
2982     char *fp, *rp, *cp2, *cp1;
2983     BOOL last_wcard_was_star = False;
2984     int num_path_components, num_regexp_components;
2985
2986     pstrcpy(te_pattern,t_pattern);
2987     pstrcpy(te_filename,t_filename);
2988     /*
2989      * Remove multiple "*." patterns.
2990      */
2991     string_sub(te_pattern, "*.*.", "*.");
2992     num_regexp_components = count_chars(te_pattern, '.');
2993     num_path_components = count_chars(te_filename, '.');
2994
2995     /* 
2996      * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2997      */
2998     if(num_regexp_components == 0)
2999       matched = do_match( te_filename, te_pattern, case_sig);
3000     else {
3001       for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
3002         fp = strchr(cp2, '.');
3003         if(fp)
3004           *fp = '\0';
3005         rp = strchr(cp1, '.');
3006         if(rp)
3007           *rp = '\0';
3008
3009         if(cp1[strlen(cp1)-1] == '*')
3010           last_wcard_was_star = True;
3011         else
3012           last_wcard_was_star = False;
3013
3014         if(!do_match(cp2, cp1, case_sig))
3015           break;
3016
3017         cp1 = rp ? rp + 1 : NULL;
3018         cp2 = fp ? fp + 1 : "";
3019
3020         if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3021           /* Eat the extra path components. */
3022           int i;
3023
3024           for(i = 0; i < num_path_components - num_regexp_components; i++) {
3025             fp = strchr(cp2, '.');
3026             if(fp)
3027               *fp = '\0';
3028
3029             if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3030               cp2 = fp ? fp + 1 : "";
3031               break;
3032             }
3033             cp2 = fp ? fp + 1 : "";
3034           }
3035           num_path_components -= i;
3036         }
3037       } 
3038       if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3039         matched = True;
3040     }
3041   } else {
3042
3043     /* -------------------------------------------------
3044      * Behaviour of Win95
3045      * for 8.3 filenames and 8.3 Wildcards
3046      * -------------------------------------------------
3047      */
3048     if (strequal (t_filename, ".")) {
3049       /*
3050        *  Patterns:  *.*  *. ?. ?  are valid
3051        *
3052        */
3053       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3054          strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3055         matched = True;
3056     } else if (strequal (t_filename, "..")) {
3057       /*
3058        *  Patterns:  *.*  *. ?. ? *.? are valid
3059        *
3060        */
3061       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3062          strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3063          strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3064         matched = True;
3065     } else {
3066
3067       if ((p = strrchr (t_pattern, '.'))) {
3068         /*
3069          * Wildcard has a suffix.
3070          */
3071         *p = 0;
3072         fstrcpy (ebase, t_pattern);
3073         if (p[1]) {
3074           fstrcpy (eext, p + 1);
3075         } else {
3076           /* pattern ends in DOT: treat as if there is no DOT */
3077           *eext = 0;
3078           if (strequal (ebase, "*"))
3079             return (True);
3080         }
3081       } else {
3082         /*
3083          * No suffix for wildcard.
3084          */
3085         fstrcpy (ebase, t_pattern);
3086         eext[0] = 0;
3087       }
3088
3089       p = strrchr (t_filename, '.');
3090       if (p && (p[1] == 0)      ) {
3091         /*
3092          * Filename has an extension of '.' only.
3093          */
3094         *p = 0; /* nuke dot at end of string */
3095         p = 0;  /* and treat it as if there is no extension */
3096       }
3097
3098       if (p) {
3099         /*
3100          * Filename has an extension.
3101          */
3102         *p = 0;
3103         fstrcpy (sbase, t_filename);
3104         fstrcpy (sext, p + 1);
3105         if (*eext) {
3106           matched = do_match(sbase, ebase, case_sig)
3107                     && do_match(sext, eext, case_sig);
3108         } else {
3109           /* pattern has no extension */
3110           /* Really: match complete filename with pattern ??? means exactly 3 chars */
3111           matched = do_match(str, ebase, case_sig);
3112         }
3113       } else {
3114         /* 
3115          * Filename has no extension.
3116          */
3117         fstrcpy (sbase, t_filename);
3118         fstrcpy (sext, "");
3119         if (*eext) {
3120           /* pattern has extension */
3121           matched = do_match(sbase, ebase, case_sig)
3122                     && do_match(sext, eext, case_sig);
3123         } else {
3124           matched = do_match(sbase, ebase, case_sig);
3125 #ifdef EMULATE_WEIRD_W95_MATCHING
3126           /*
3127            * Even Microsoft has some problems
3128            * Behaviour Win95 -> local disk 
3129            * is different from Win95 -> smb drive from Nt 4.0
3130            * This branch would reflect the Win95 local disk behaviour
3131            */
3132           if (!matched) {
3133             /* a? matches aa and a in w95 */
3134             fstrcat (sbase, ".");
3135             matched = do_match(sbase, ebase, case_sig);
3136           }
3137 #endif
3138         }
3139       }
3140     }
3141   }
3142
3143   DEBUG(8,("mask_match returning %d\n", matched));
3144
3145   return matched;
3146 }
3147
3148 /****************************************************************************
3149 become a daemon, discarding the controlling terminal
3150 ****************************************************************************/
3151 void become_daemon(void)
3152 {
3153         if (fork()) {
3154                 _exit(0);
3155         }
3156
3157   /* detach from the terminal */
3158 #ifdef HAVE_SETSID
3159         setsid();
3160 #elif defined(TIOCNOTTY)
3161         {
3162                 int i = open("/dev/tty", O_RDWR);
3163                 if (i != -1) {
3164                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
3165                         close(i);
3166                 }
3167         }
3168 #endif /* HAVE_SETSID */
3169
3170         /* Close fd's 0,1,2. Needed if started by rsh */
3171         close_low_fds();
3172 }
3173
3174
3175 /****************************************************************************
3176 put up a yes/no prompt
3177 ****************************************************************************/
3178 BOOL yesno(char *p)
3179 {
3180   pstring ans;
3181   printf("%s",p);
3182
3183   if (!fgets(ans,sizeof(ans)-1,stdin))
3184     return(False);
3185
3186   if (*ans == 'y' || *ans == 'Y')
3187     return(True);
3188
3189   return(False);
3190 }
3191
3192 /****************************************************************************
3193 read a line from a file with possible \ continuation chars. 
3194 Blanks at the start or end of a line are stripped.
3195 The string will be allocated if s2 is NULL
3196 ****************************************************************************/
3197 char *fgets_slash(char *s2,int maxlen,FILE *f)
3198 {
3199   char *s=s2;
3200   int len = 0;
3201   int c;
3202   BOOL start_of_line = True;
3203
3204   if (feof(f))
3205     return(NULL);
3206
3207   if (!s2)
3208     {
3209       maxlen = MIN(maxlen,8);
3210       s = (char *)Realloc(s,maxlen);
3211     }
3212
3213   if (!s || maxlen < 2) return(NULL);
3214
3215   *s = 0;
3216
3217   while (len < maxlen-1)
3218     {
3219       c = getc(f);
3220       switch (c)
3221         {
3222         case '\r':
3223           break;
3224         case '\n':
3225           while (len > 0 && s[len-1] == ' ')
3226             {
3227               s[--len] = 0;
3228             }
3229           if (len > 0 && s[len-1] == '\\')
3230             {
3231               s[--len] = 0;
3232               start_of_line = True;
3233               break;
3234             }
3235           return(s);
3236         case EOF:
3237           if (len <= 0 && !s2) 
3238             free(s);
3239           return(len>0?s:NULL);
3240         case ' ':
3241           if (start_of_line)
3242             break;
3243         default:
3244           start_of_line = False;
3245           s[len++] = c;
3246           s[len] = 0;
3247         }
3248       if (!s2 && len > maxlen-3)
3249         {
3250           maxlen *= 2;
3251           s = (char *)Realloc(s,maxlen);
3252           if (!s) return(NULL);
3253         }
3254     }
3255   return(s);
3256 }
3257
3258
3259
3260 /****************************************************************************
3261 set the length of a file from a filedescriptor.
3262 Returns 0 on success, -1 on failure.
3263 ****************************************************************************/
3264 int set_filelen(int fd, long len)
3265 {
3266 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3267    extend a file with ftruncate. Provide alternate implementation
3268    for this */
3269
3270 #ifdef HAVE_FTRUNCATE_EXTEND
3271   return ftruncate(fd, len);
3272 #else
3273   SMB_STRUCT_STAT st;
3274   char c = 0;
3275   long currpos = lseek(fd, 0L, SEEK_CUR);
3276
3277   if(currpos < 0)
3278     return -1;
3279   /* Do an fstat to see if the file is longer than
3280      the requested size (call ftruncate),
3281      or shorter, in which case seek to len - 1 and write 1
3282      byte of zero */
3283   if(fstat(fd, &st)<0)
3284     return -1;
3285
3286 #ifdef S_ISFIFO
3287   if (S_ISFIFO(st.st_mode)) return 0;
3288 #endif
3289
3290   if(st.st_size == len)
3291     return 0;
3292   if(st.st_size > len)
3293     return ftruncate(fd, len);
3294
3295   if(lseek(fd, len-1, SEEK_SET) != len -1)
3296     return -1;
3297   if(write(fd, &c, 1)!=1)
3298     return -1;
3299   /* Seek to where we were */
3300   lseek(fd, currpos, SEEK_SET);
3301   return 0;
3302 #endif
3303 }
3304
3305
3306 /****************************************************************************
3307 return the byte checksum of some data
3308 ****************************************************************************/
3309 int byte_checksum(char *buf,int len)
3310 {
3311   unsigned char *p = (unsigned char *)buf;
3312   int ret = 0;
3313   while (len--)
3314     ret += *p++;
3315   return(ret);
3316 }
3317
3318
3319
3320 #ifdef HPUX
3321 /****************************************************************************
3322 this is a version of setbuffer() for those machines that only have setvbuf
3323 ****************************************************************************/
3324  void setbuffer(FILE *f,char *buf,int bufsize)
3325 {
3326   setvbuf(f,buf,_IOFBF,bufsize);
3327 }
3328 #endif
3329
3330
3331 /****************************************************************************
3332 parse out a directory name from a path name. Assumes dos style filenames.
3333 ****************************************************************************/
3334 char *dirname_dos(char *path,char *buf)
3335 {
3336   char *p = strrchr(path,'\\');
3337
3338   if (!p)
3339     pstrcpy(buf,path);
3340   else
3341     {
3342       *p = 0;
3343       pstrcpy(buf,path);
3344       *p = '\\';
3345     }
3346
3347   return(buf);
3348 }
3349
3350
3351 /****************************************************************************
3352 parse out a filename from a path name. Assumes dos style filenames.
3353 ****************************************************************************/
3354 static char *filename_dos(char *path,char *buf)
3355 {
3356   char *p = strrchr(path,'\\');
3357
3358   if (!p)
3359     pstrcpy(buf,path);
3360   else
3361     pstrcpy(buf,p+1);
3362
3363   return(buf);
3364 }
3365
3366
3367
3368 /****************************************************************************
3369 expand a pointer to be a particular size
3370 ****************************************************************************/
3371 void *Realloc(void *p,int size)
3372 {
3373   void *ret=NULL;
3374
3375   if (size == 0) {
3376     if (p) free(p);
3377     DEBUG(5,("Realloc asked for 0 bytes\n"));
3378     return NULL;
3379   }
3380
3381   if (!p)
3382     ret = (void *)malloc(size);
3383   else
3384     ret = (void *)realloc(p,size);
3385
3386   if (!ret)
3387     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3388
3389   return(ret);
3390 }
3391
3392
3393 /****************************************************************************
3394 get my own name and IP
3395 ****************************************************************************/
3396 BOOL get_myname(char *my_name,struct in_addr *ip)
3397 {
3398   struct hostent *hp;
3399   pstring hostname;
3400
3401   *hostname = 0;
3402
3403   /* get my host name */
3404   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
3405     {
3406       DEBUG(0,("gethostname failed\n"));
3407       return False;
3408     } 
3409
3410   /* get host info */
3411   if ((hp = Get_Hostbyname(hostname)) == 0) 
3412     {
3413       DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3414       return False;
3415     }
3416
3417   if (my_name)
3418     {
3419       /* split off any parts after an initial . */
3420       char *p = strchr(hostname,'.');
3421       if (p) *p = 0;
3422
3423       fstrcpy(my_name,hostname);
3424     }
3425
3426   if (ip)
3427     putip((char *)ip,(char *)hp->h_addr);
3428
3429   return(True);
3430 }
3431
3432
3433 /****************************************************************************
3434 true if two IP addresses are equal
3435 ****************************************************************************/
3436 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3437 {
3438   uint32 a1,a2;
3439   a1 = ntohl(ip1.s_addr);
3440   a2 = ntohl(ip2.s_addr);
3441   return(a1 == a2);
3442 }
3443
3444
3445 /****************************************************************************
3446 open a socket of the specified type, port and address for incoming data
3447 ****************************************************************************/
3448 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3449 {
3450   struct hostent *hp;
3451   struct sockaddr_in sock;
3452   pstring host_name;
3453   int res;
3454
3455   /* get my host name */
3456   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
3457     { DEBUG(0,("gethostname failed\n")); return -1; } 
3458
3459   /* get host info */
3460   if ((hp = Get_Hostbyname(host_name)) == 0) 
3461     {
3462       DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3463       return -1;
3464     }
3465   
3466   bzero((char *)&sock,sizeof(sock));
3467   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3468
3469 #ifdef HAVE_SOCK_SIN_LEN
3470   sock.sin_len = sizeof(sock);
3471 #endif
3472   sock.sin_port = htons( port );
3473   sock.sin_family = hp->h_addrtype;
3474   sock.sin_addr.s_addr = socket_addr;
3475   res = socket(hp->h_addrtype, type, 0);
3476   if (res == -1) 
3477     { DEBUG(0,("socket failed\n")); return -1; }
3478
3479   {
3480     int one=1;
3481     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3482   }
3483
3484   /* now we've got a socket - we need to bind it */
3485   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
3486     { 
3487       if (port) {
3488         if (port == SMB_PORT || port == NMB_PORT)
3489           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3490                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
3491         close(res); 
3492
3493         if (dlevel > 0 && port < 1000)
3494           port = 7999;
3495
3496         if (port >= 1000 && port < 9000)
3497           return(open_socket_in(type,port+1,dlevel,socket_addr));
3498       }
3499
3500       return(-1); 
3501     }
3502   DEBUG(3,("bind succeeded on port %d\n",port));
3503
3504   return res;
3505 }
3506
3507
3508 /****************************************************************************
3509   create an outgoing socket
3510   **************************************************************************/
3511 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3512 {
3513   struct sockaddr_in sock_out;
3514   int res,ret;
3515   int connect_loop = 250; /* 250 milliseconds */
3516   int loops = (timeout * 1000) / connect_loop;
3517
3518   /* create a socket to write to */
3519   res = socket(PF_INET, type, 0);
3520   if (res == -1) 
3521     { DEBUG(0,("socket error\n")); return -1; }
3522
3523   if (type != SOCK_STREAM) return(res);
3524   
3525   bzero((char *)&sock_out,sizeof(sock_out));
3526   putip((char *)&sock_out.sin_addr,(char *)addr);
3527   
3528   sock_out.sin_port = htons( port );
3529   sock_out.sin_family = PF_INET;
3530
3531   /* set it non-blocking */
3532   set_blocking(res,False);
3533
3534   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3535   
3536   /* and connect it to the destination */
3537 connect_again:
3538   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3539
3540   /* Some systems return EAGAIN when they mean EINPROGRESS */
3541   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3542         errno == EAGAIN) && loops--) {
3543     msleep(connect_loop);
3544     goto connect_again;
3545   }
3546
3547   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3548          errno == EAGAIN)) {
3549       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3550       close(res);
3551       return -1;
3552   }
3553
3554 #ifdef EISCONN
3555   if (ret < 0 && errno == EISCONN) {
3556     errno = 0;
3557     ret = 0;
3558   }
3559 #endif
3560
3561   if (ret < 0) {
3562     DEBUG(1,("error connecting to %s:%d (%s)\n",
3563              inet_ntoa(*addr),port,strerror(errno)));
3564     close(res);
3565     return -1;
3566   }
3567
3568   /* set it blocking again */
3569   set_blocking(res,True);
3570
3571   return res;
3572 }
3573
3574
3575 /****************************************************************************
3576 interpret a protocol description string, with a default
3577 ****************************************************************************/
3578 int interpret_protocol(char *str,int def)
3579 {
3580   if (strequal(str,"NT1"))
3581     return(PROTOCOL_NT1);
3582   if (strequal(str,"LANMAN2"))
3583     return(PROTOCOL_LANMAN2);
3584   if (strequal(str,"LANMAN1"))
3585     return(PROTOCOL_LANMAN1);
3586   if (strequal(str,"CORE"))
3587     return(PROTOCOL_CORE);
3588   if (strequal(str,"COREPLUS"))
3589     return(PROTOCOL_COREPLUS);
3590   if (strequal(str,"CORE+"))
3591     return(PROTOCOL_COREPLUS);
3592   
3593   DEBUG(0,("Unrecognised protocol level %s\n",str));
3594   
3595   return(def);
3596 }
3597
3598 /****************************************************************************
3599 interpret a security level
3600 ****************************************************************************/
3601 int interpret_security(char *str,int def)
3602 {
3603   if (strequal(str,"SERVER"))
3604     return(SEC_SERVER);
3605   if (strequal(str,"USER"))
3606     return(SEC_USER);
3607   if (strequal(str,"SHARE"))
3608     return(SEC_SHARE);
3609   
3610   DEBUG(0,("Unrecognised security level %s\n",str));
3611   
3612   return(def);
3613 }
3614
3615
3616 /****************************************************************************
3617 interpret an internet address or name into an IP address in 4 byte form
3618 ****************************************************************************/
3619 uint32 interpret_addr(char *str)
3620 {
3621   struct hostent *hp;
3622   uint32 res;
3623   int i;
3624   BOOL pure_address = True;
3625
3626   if (strcmp(str,"0.0.0.0") == 0) return(0);
3627   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3628
3629   for (i=0; pure_address && str[i]; i++)
3630     if (!(isdigit((int)str[i]) || str[i] == '.')) 
3631       pure_address = False;
3632
3633   /* if it's in the form of an IP address then get the lib to interpret it */
3634   if (pure_address) {
3635     res = inet_addr(str);
3636   } else {
3637     /* otherwise assume it's a network name of some sort and use 
3638        Get_Hostbyname */
3639     if ((hp = Get_Hostbyname(str)) == 0) {
3640       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3641       return 0;
3642     }
3643     if(hp->h_addr == NULL) {
3644       DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3645       return 0;
3646     }
3647     putip((char *)&res,(char *)hp->h_addr);
3648   }
3649
3650   if (res == (uint32)-1) return(0);
3651
3652   return(res);
3653 }
3654
3655 /*******************************************************************
3656   a convenient addition to interpret_addr()
3657   ******************************************************************/
3658 struct in_addr *interpret_addr2(char *str)
3659 {
3660   static struct in_addr ret;
3661   uint32 a = interpret_addr(str);
3662   ret.s_addr = a;
3663   return(&ret);
3664 }
3665
3666 /*******************************************************************
3667   check if an IP is the 0.0.0.0
3668   ******************************************************************/
3669 BOOL zero_ip(struct in_addr ip)
3670 {
3671   uint32 a;
3672   putip((char *)&a,(char *)&ip);
3673   return(a == 0);
3674 }
3675
3676
3677 /*******************************************************************
3678  matchname - determine if host name matches IP address 
3679  ******************************************************************/
3680 static BOOL matchname(char *remotehost,struct in_addr  addr)
3681 {
3682   struct hostent *hp;
3683   int     i;
3684   
3685   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3686     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3687     return False;
3688   } 
3689
3690   /*
3691    * Make sure that gethostbyname() returns the "correct" host name.
3692    * Unfortunately, gethostbyname("localhost") sometimes yields
3693    * "localhost.domain". Since the latter host name comes from the
3694    * local DNS, we just have to trust it (all bets are off if the local
3695    * DNS is perverted). We always check the address list, though.
3696    */
3697   
3698   if (strcasecmp(remotehost, hp->h_name)
3699       && strcasecmp(remotehost, "localhost")) {
3700     DEBUG(0,("host name/name mismatch: %s != %s",
3701              remotehost, hp->h_name));
3702     return False;
3703   }
3704         
3705   /* Look up the host address in the address list we just got. */
3706   for (i = 0; hp->h_addr_list[i]; i++) {
3707     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3708       return True;
3709   }
3710
3711   /*
3712    * The host name does not map to the original host address. Perhaps
3713    * someone has compromised a name server. More likely someone botched
3714    * it, but that could be dangerous, too.
3715    */
3716   
3717   DEBUG(0,("host name/address mismatch: %s != %s",
3718            inet_ntoa(addr), hp->h_name));
3719   return False;
3720 }
3721
3722 /*******************************************************************
3723  Reset the 'done' variables so after a client process is created
3724  from a fork call these calls will be re-done. This should be
3725  expanded if more variables need reseting.
3726  ******************************************************************/
3727
3728 static BOOL global_client_name_done = False;
3729 static BOOL global_client_addr_done = False;
3730
3731 void reset_globals_after_fork(void)
3732 {
3733   global_client_name_done = False;
3734   global_client_addr_done = False;
3735
3736   /*
3737    * Re-seed the random crypto generator, so all smbd's
3738    * started from the same parent won't generate the same
3739    * sequence.
3740    */
3741   {
3742     unsigned char dummy;
3743     generate_random_buffer( &dummy, 1, True);
3744   } 
3745 }
3746  
3747 /*******************************************************************
3748  return the DNS name of the client 
3749  ******************************************************************/
3750 char *client_name(int fd)
3751 {
3752         struct sockaddr sa;
3753         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3754         int     length = sizeof(sa);
3755         static pstring name_buf;
3756         struct hostent *hp;
3757         static int last_fd=-1;
3758         
3759         if (global_client_name_done && last_fd == fd) 
3760                 return name_buf;
3761         
3762         last_fd = fd;
3763         global_client_name_done = False;
3764         
3765         pstrcpy(name_buf,"UNKNOWN");
3766         
3767         if (fd == -1) {
3768                 return name_buf;
3769         }
3770         
3771         if (getpeername(fd, &sa, &length) < 0) {
3772                 DEBUG(0,("getpeername failed\n"));
3773                 return name_buf;
3774         }
3775         
3776         /* Look up the remote host name. */
3777         if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3778                                 sizeof(sockin->sin_addr),
3779                                 AF_INET)) == 0) {
3780                 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3781                 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3782         } else {
3783                 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3784                 if (!matchname(name_buf, sockin->sin_addr)) {
3785                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3786                         pstrcpy(name_buf,"UNKNOWN");
3787                 }
3788         }
3789         global_client_name_done = True;
3790         return name_buf;
3791 }
3792
3793 /*******************************************************************
3794  return the IP addr of the client as a string 
3795  ******************************************************************/
3796 char *client_addr(int fd)
3797 {
3798         struct sockaddr sa;
3799         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3800         int     length = sizeof(sa);
3801         static fstring addr_buf;
3802         static int last_fd = -1;
3803
3804         if (global_client_addr_done && fd == last_fd) 
3805                 return addr_buf;
3806
3807         last_fd = fd;
3808         global_client_addr_done = False;
3809
3810         fstrcpy(addr_buf,"0.0.0.0");
3811
3812         if (fd == -1) {
3813                 return addr_buf;
3814         }
3815         
3816         if (getpeername(fd, &sa, &length) < 0) {
3817                 DEBUG(0,("getpeername failed\n"));
3818                 return addr_buf;
3819         }
3820         
3821         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3822         
3823         global_client_addr_done = True;
3824         return addr_buf;
3825 }
3826
3827 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3828 /******************************************************************
3829  Remove any mount options such as -rsize=2048,wsize=2048 etc.
3830  Based on a fix from <Thomas.Hepper@icem.de>.
3831 *******************************************************************/
3832
3833 static void strip_mount_options( pstring *str)
3834 {
3835   if (**str == '-')
3836   { 
3837     char *p = *str;
3838     while(*p && !isspace(*p))
3839       p++;
3840     while(*p && isspace(*p))
3841       p++;
3842     if(*p) {
3843       pstring tmp_str;
3844
3845       pstrcpy(tmp_str, p);
3846       pstrcpy(*str, tmp_str);
3847     }
3848   }
3849 }
3850
3851 /*******************************************************************
3852  Patch from jkf@soton.ac.uk
3853  Split Luke's automount_server into YP lookup and string splitter
3854  so can easily implement automount_path(). 
3855  As we may end up doing both, cache the last YP result. 
3856 *******************************************************************/
3857
3858 #ifdef WITH_NISPLUS_HOME
3859 static char *automount_lookup(char *user_name)
3860 {
3861   static fstring last_key = "";
3862   static pstring last_value = "";
3863  
3864   char *nis_map = (char *)lp_nis_home_map_name();
3865  
3866   char nis_domain[NIS_MAXNAMELEN + 1];
3867   char buffer[NIS_MAXATTRVAL + 1];
3868   nis_result *result;
3869   nis_object *object;
3870   entry_obj  *entry;
3871  
3872   strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3873   nis_domain[NIS_MAXNAMELEN] = '\0';
3874  
3875   DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3876  
3877   if (strcmp(user_name, last_key))
3878   {
3879     slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3880     DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3881  
3882     if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3883     {
3884        if (result->status != NIS_SUCCESS)
3885       {
3886         DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3887         fstrcpy(last_key, ""); pstrcpy(last_value, "");
3888       }
3889       else
3890       {
3891         object = result->objects.objects_val;
3892         if (object->zo_data.zo_type == ENTRY_OBJ)
3893         {
3894            entry = &object->zo_data.objdata_u.en_data;
3895            DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3896            DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3897  
3898            pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3899            string_sub(last_value, "&", user_name);
3900            fstrcpy(last_key, user_name);
3901         }
3902       }
3903     }
3904     nis_freeresult(result);
3905   }
3906
3907   strip_mount_options(&last_value);
3908
3909   DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3910   return last_value;
3911 }
3912 #else /* WITH_NISPLUS_HOME */
3913 static char *automount_lookup(char *user_name)
3914 {
3915   static fstring last_key = "";
3916   static pstring last_value = "";
3917
3918   int nis_error;        /* returned by yp all functions */
3919   char *nis_result;     /* yp_match inits this */
3920   int nis_result_len;  /* and set this */
3921   char *nis_domain;     /* yp_get_default_domain inits this */
3922   char *nis_map = (char *)lp_nis_home_map_name();
3923
3924   if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3925   {
3926     DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3927     return last_value;
3928   }
3929
3930   DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3931
3932   if (!strcmp(user_name, last_key))
3933   {
3934     nis_result = last_value;
3935     nis_result_len = strlen(last_value);
3936     nis_error = 0;
3937   }
3938   else
3939   {
3940     if ((nis_error = yp_match(nis_domain, nis_map,
3941                               user_name, strlen(user_name),
3942                               &nis_result, &nis_result_len)) != 0)
3943     {
3944       DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
3945                yperr_string(nis_error), user_name, nis_map));
3946     }
3947     if (!nis_error && nis_result_len >= sizeof(pstring))
3948     {
3949       nis_result_len = sizeof(pstring)-1;
3950     }
3951     fstrcpy(last_key, user_name);
3952     strncpy(last_value, nis_result, nis_result_len);
3953     last_value[nis_result_len] = '\0';
3954   }
3955
3956   strip_mount_options(&last_value);
3957
3958   DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3959   return last_value;
3960 }
3961 #endif /* WITH_NISPLUS_HOME */
3962 #endif
3963
3964 /*******************************************************************
3965  Patch from jkf@soton.ac.uk
3966  This is Luke's original function with the NIS lookup code
3967  moved out to a separate function.
3968 *******************************************************************/
3969
3970 char *automount_server(char *user_name)
3971 {
3972         static pstring server_name;
3973
3974         /* use the local machine name as the default */
3975         /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3976         pstrcpy(server_name, local_machine);
3977
3978 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3979
3980         if (lp_nis_home_map())
3981         {
3982                 int home_server_len;
3983                 char *automount_value = automount_lookup(user_name);
3984                 home_server_len = strcspn(automount_value,":");
3985                 DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
3986                 if (home_server_len > sizeof(pstring))
3987                 {
3988                         home_server_len = sizeof(pstring);
3989                 }
3990                 strncpy(server_name, automount_value, home_server_len);
3991                 server_name[home_server_len] = '\0';
3992         }
3993 #endif
3994
3995         DEBUG(4,("Home server: %s\n", server_name));
3996
3997         return server_name;
3998 }
3999
4000 /*******************************************************************
4001  Patch from jkf@soton.ac.uk
4002  Added this to implement %p (NIS auto-map version of %H)
4003 *******************************************************************/
4004
4005 char *automount_path(char *user_name)
4006 {
4007         static pstring server_path;
4008
4009         /* use the passwd entry as the default */
4010         /* this will be the default if WITH_AUTOMOUNT is not used or fails */
4011         /* pstrcpy() copes with get_home_dir() returning NULL */
4012         pstrcpy(server_path, get_home_dir(user_name));
4013
4014 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
4015
4016         if (lp_nis_home_map())
4017         {
4018                 char *home_path_start;
4019                 char *automount_value = automount_lookup(user_name);
4020                 home_path_start = strchr(automount_value,':');
4021                 if (home_path_start != NULL)
4022                 {
4023                   DEBUG(5, ("NIS lookup succeeded.  Home path is: %s\n",
4024                         home_path_start?(home_path_start+1):""));
4025                   pstrcpy(server_path, home_path_start+1);
4026                 }
4027         }
4028 #endif
4029
4030         DEBUG(4,("Home server path: %s\n", server_path));
4031
4032         return server_path;
4033 }
4034
4035
4036 /*******************************************************************
4037 sub strings with useful parameters
4038 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4039 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4040 ********************************************************************/
4041 void standard_sub_basic(char *str)
4042 {
4043         char *s, *p;
4044         char pidstr[10];
4045         struct passwd *pass;
4046         char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4047
4048         for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4049         {
4050                 switch (*(p+1))
4051                 {
4052                         case 'G' :
4053                         {
4054                                 if ((pass = Get_Pwnam(username,False))!=NULL)
4055                                 {
4056                                         string_sub(p,"%G",gidtoname(pass->pw_gid));
4057                                 }
4058                                 else
4059                                 {
4060                                         p += 2;
4061                                 }
4062                                 break;
4063                         }
4064                         case 'N' : string_sub(p,"%N", automount_server(username)); break;
4065                         case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4066                         case 'L' : string_sub(p,"%L", local_machine); break;
4067                         case 'M' : string_sub(p,"%M", client_name(Client)); break;
4068                         case 'R' : string_sub(p,"%R", remote_proto); break;
4069                         case 'T' : string_sub(p,"%T", timestring()); break;
4070                         case 'U' : string_sub(p,"%U", username); break;
4071                         case 'a' : string_sub(p,"%a", remote_arch); break;
4072                         case 'd' :
4073                         {
4074                                 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4075                                 string_sub(p,"%d", pidstr);
4076                                 break;
4077                         }
4078                         case 'h' : string_sub(p,"%h", myhostname); break;
4079                         case 'm' : string_sub(p,"%m", remote_machine); break;
4080                         case 'v' : string_sub(p,"%v", VERSION); break;
4081                         case '$' : /* Expand environment variables */
4082                         {
4083                                 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4084                                 fstring envname;
4085                                 char *envval;
4086                                 char *q, *r;
4087                                 int copylen;
4088
4089                                 if (*(p+2) != '(')
4090                                 {
4091                                         p+=2;
4092                                         break;
4093                                 }
4094                                 if ((q = strchr(p,')')) == NULL)
4095                                 {
4096                                         DEBUG(0,("standard_sub_basic: Unterminated environment \
4097                                         variable [%s]\n", p));
4098                                         p+=2;
4099                                         break;
4100                                 }
4101
4102                                 r = p+3;
4103                                 copylen = MIN((q-r),(sizeof(envname)-1));
4104                                 strncpy(envname,r,copylen);
4105                                 envname[copylen] = '\0';
4106
4107                                 if ((envval = getenv(envname)) == NULL)
4108                                 {
4109                                         DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4110                                         envname));
4111                                         p+=2;
4112                                         break;
4113                                 }
4114
4115                                 copylen = MIN((q+1-p),(sizeof(envname)-1));
4116                                 strncpy(envname,p,copylen);
4117                                 envname[copylen] = '\0';
4118                                 string_sub(p,envname,envval);
4119                                 break;
4120                         }
4121                         case '\0': p++; break; /* don't run off end if last character is % */
4122                         default  : p+=2; break;
4123                 }
4124         }
4125         return;
4126 }
4127
4128
4129 /****************************************************************************
4130 do some standard substitutions in a string
4131 ****************************************************************************/
4132 void standard_sub(connection_struct *conn,char *str)
4133 {
4134         char *p, *s, *home;
4135
4136         for (s=str; (p=strchr(s, '%'));s=p) {
4137                 switch (*(p+1)) {
4138                 case 'H': 
4139                         if ((home = get_home_dir(conn->user))) {
4140                                 string_sub(p,"%H",home);
4141                         } else {
4142                                 p += 2;
4143                         }
4144                         break;
4145                         
4146                 case 'P': 
4147                         string_sub(p,"%P",conn->connectpath); 
4148                         break;
4149                         
4150                 case 'S': 
4151                         string_sub(p,"%S",
4152                                    lp_servicename(SNUM(conn))); 
4153                         break;
4154                         
4155                 case 'g': 
4156                         string_sub(p,"%g",
4157                                    gidtoname(conn->gid)); 
4158                         break;
4159                 case 'u': 
4160                         string_sub(p,"%u",conn->user); 
4161                         break;
4162                         
4163                         /* Patch from jkf@soton.ac.uk Left the %N (NIS
4164                          * server name) in standard_sub_basic as it is
4165                          * a feature for logon servers, hence uses the
4166                          * username.  The %p (NIS server path) code is
4167                          * here as it is used instead of the default
4168                          * "path =" string in [homes] and so needs the
4169                          * service name, not the username.  */
4170                 case 'p': 
4171                         string_sub(p,"%p",
4172                                    automount_path(lp_servicename(SNUM(conn)))); 
4173                         break;
4174                 case '\0': 
4175                         p++; 
4176                         break; /* don't run off the end of the string 
4177                                 */
4178                         
4179                 default: p+=2; 
4180                         break;
4181                 }
4182         }
4183         
4184         standard_sub_basic(str);
4185 }
4186
4187
4188
4189 /*******************************************************************
4190 are two IPs on the same subnet?
4191 ********************************************************************/
4192 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4193 {
4194   uint32 net1,net2,nmask;
4195
4196   nmask = ntohl(mask.s_addr);
4197   net1  = ntohl(ip1.s_addr);
4198   net2  = ntohl(ip2.s_addr);
4199             
4200   return((net1 & nmask) == (net2 & nmask));
4201 }
4202
4203
4204 /*******************************************************************
4205 write a string in unicoode format
4206 ********************************************************************/
4207 int PutUniCode(char *dst,char *src)
4208 {
4209   int ret = 0;
4210   while (*src) {
4211     dst[ret++] = src[0];
4212     dst[ret++] = 0;    
4213     src++;
4214   }
4215   dst[ret++]=0;
4216   dst[ret++]=0;
4217   return(ret);
4218 }
4219
4220 /****************************************************************************
4221 a wrapper for gethostbyname() that tries with all lower and all upper case 
4222 if the initial name fails
4223 ****************************************************************************/
4224 struct hostent *Get_Hostbyname(char *name)
4225 {
4226   char *name2 = strdup(name);
4227   struct hostent *ret;
4228
4229   if (!name2)
4230     {
4231       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4232       exit(0);
4233     }
4234
4235    
4236   /* 
4237    * This next test is redundent and causes some systems (with
4238    * broken isalnum() calls) problems.
4239    * JRA.
4240    */
4241
4242 #if 0
4243   if (!isalnum(*name2))
4244     {
4245       free(name2);
4246       return(NULL);
4247     }
4248 #endif /* 0 */
4249
4250   ret = sys_gethostbyname(name2);
4251   if (ret != NULL)
4252     {
4253       free(name2);
4254       return(ret);
4255     }
4256
4257   /* try with all lowercase */
4258   strlower(name2);
4259   ret = sys_gethostbyname(name2);
4260   if (ret != NULL)
4261     {
4262       free(name2);
4263       return(ret);
4264     }
4265
4266   /* try with all uppercase */
4267   strupper(name2);
4268   ret = sys_gethostbyname(name2);
4269   if (ret != NULL)
4270     {
4271       free(name2);
4272       return(ret);
4273     }
4274   
4275   /* nothing works :-( */
4276   free(name2);
4277   return(NULL);
4278 }
4279
4280
4281 /****************************************************************************
4282 check if a process exists. Does this work on all unixes?
4283 ****************************************************************************/
4284 BOOL process_exists(int pid)
4285 {
4286         return(kill(pid,0) == 0 || errno != ESRCH);
4287 }
4288
4289
4290 /*******************************************************************
4291 turn a uid into a user name
4292 ********************************************************************/
4293 char *uidtoname(int uid)
4294 {
4295   static char name[40];
4296   struct passwd *pass = getpwuid(uid);
4297   if (pass) return(pass->pw_name);
4298   slprintf(name, sizeof(name) - 1, "%d",uid);
4299   return(name);
4300 }
4301
4302 /*******************************************************************
4303 turn a gid into a group name
4304 ********************************************************************/
4305 char *gidtoname(int gid)
4306 {
4307         static char name[40];
4308         struct group *grp = getgrgid(gid);
4309         if (grp) return(grp->gr_name);
4310         slprintf(name,sizeof(name) - 1, "%d",gid);
4311         return(name);
4312 }
4313
4314 /*******************************************************************
4315 something really nasty happened - panic!
4316 ********************************************************************/
4317 void smb_panic(char *why)
4318 {
4319         char *cmd = lp_panic_action();
4320         if (cmd && *cmd) {
4321                 system(cmd);
4322         }
4323         DEBUG(0,("PANIC: %s\n", why));
4324         exit(1);
4325 }
4326
4327
4328 /*******************************************************************
4329 a readdir wrapper which just returns the file name
4330 ********************************************************************/
4331 char *readdirname(void *p)
4332 {
4333         struct dirent *ptr;
4334         char *dname;
4335
4336         if (!p) return(NULL);
4337   
4338         ptr = (struct dirent *)readdir(p);
4339         if (!ptr) return(NULL);
4340
4341         dname = ptr->d_name;
4342
4343 #ifdef NEXT2
4344         if (telldir(p) < 0) return(NULL);
4345 #endif
4346
4347 #ifdef HAVE_BROKEN_READDIR
4348         /* using /usr/ucb/cc is BAD */
4349         dname = dname - 2;
4350 #endif
4351
4352         {
4353                 static pstring buf;
4354                 memcpy(buf, dname, NAMLEN(ptr)+1);
4355                 unix_to_dos(buf, True);
4356                 dname = buf;
4357         }
4358
4359         return(dname);
4360 }
4361
4362 /*******************************************************************
4363  Utility function used to decide if the last component 
4364  of a path matches a (possibly wildcarded) entry in a namelist.
4365 ********************************************************************/
4366
4367 BOOL is_in_path(char *name, name_compare_entry *namelist)
4368 {
4369   pstring last_component;
4370   char *p;
4371
4372   DEBUG(8, ("is_in_path: %s\n", name));
4373
4374   /* if we have no list it's obviously not in the path */
4375   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
4376   {
4377     DEBUG(8,("is_in_path: no name list.\n"));
4378     return False;
4379   }
4380
4381   /* Get the last component of the unix name. */
4382   p = strrchr(name, '/');
4383   strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4384   last_component[sizeof(last_component)-1] = '\0'; 
4385
4386   for(; namelist->name != NULL; namelist++)
4387   {
4388     if(namelist->is_wild)
4389     {
4390       /* 
4391        * Look for a wildcard match. Use the old
4392        * 'unix style' mask match, rather than the
4393        * new NT one.
4394        */
4395       if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4396       {
4397          DEBUG(8,("is_in_path: mask match succeeded\n"));
4398          return True;
4399       }
4400     }
4401     else
4402     {
4403       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4404        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4405         {
4406          DEBUG(8,("is_in_path: match succeeded\n"));
4407          return True;
4408         }
4409     }
4410   }
4411   DEBUG(8,("is_in_path: match not found\n"));
4412  
4413   return False;
4414 }
4415
4416 /*******************************************************************
4417  Strip a '/' separated list into an array of 
4418  name_compare_enties structures suitable for 
4419  passing to is_in_path(). We do this for
4420  speed so we can pre-parse all the names in the list 
4421  and don't do it for each call to is_in_path().
4422  namelist is modified here and is assumed to be 
4423  a copy owned by the caller.
4424  We also check if the entry contains a wildcard to
4425  remove a potentially expensive call to mask_match
4426  if possible.
4427 ********************************************************************/
4428  
4429 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4430 {
4431   char *name_end;
4432   char *nameptr = namelist;
4433   int num_entries = 0;
4434   int i;
4435
4436   (*ppname_array) = NULL;
4437
4438   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
4439     return;
4440
4441   /* We need to make two passes over the string. The
4442      first to count the number of elements, the second
4443      to split it.
4444    */
4445   while(*nameptr) 
4446     {
4447       if ( *nameptr == '/' ) 
4448         {
4449           /* cope with multiple (useless) /s) */
4450           nameptr++;
4451           continue;
4452         }
4453       /* find the next / */
4454       name_end = strchr(nameptr, '/');
4455
4456       /* oops - the last check for a / didn't find one. */
4457       if (name_end == NULL)
4458         break;
4459
4460       /* next segment please */
4461       nameptr = name_end + 1;
4462       num_entries++;
4463     }
4464
4465   if(num_entries == 0)
4466     return;
4467
4468   if(( (*ppname_array) = (name_compare_entry *)malloc( 
4469            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4470         {
4471     DEBUG(0,("set_namearray: malloc fail\n"));
4472     return;
4473         }
4474
4475   /* Now copy out the names */
4476   nameptr = namelist;
4477   i = 0;
4478   while(*nameptr)
4479              {
4480       if ( *nameptr == '/' ) 
4481       {
4482           /* cope with multiple (useless) /s) */
4483           nameptr++;
4484           continue;
4485       }
4486       /* find the next / */
4487       if ((name_end = strchr(nameptr, '/')) != NULL) 
4488       {
4489           *name_end = 0;
4490          }
4491
4492       /* oops - the last check for a / didn't find one. */
4493       if(name_end == NULL) 
4494         break;
4495
4496       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4497                                 (strchr( nameptr, '*')!=NULL));
4498       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4499       {
4500         DEBUG(0,("set_namearray: malloc fail (1)\n"));
4501         return;
4502       }
4503
4504       /* next segment please */
4505       nameptr = name_end + 1;
4506       i++;
4507     }
4508   
4509   (*ppname_array)[i].name = NULL;
4510
4511   return;
4512 }
4513
4514 /****************************************************************************
4515 routine to free a namearray.
4516 ****************************************************************************/
4517
4518 void free_namearray(name_compare_entry *name_array)
4519 {
4520   if(name_array == 0)
4521     return;
4522
4523   if(name_array->name != NULL)
4524     free(name_array->name);
4525
4526   free((char *)name_array);
4527 }
4528
4529 /****************************************************************************
4530 routine to do file locking
4531 ****************************************************************************/
4532 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4533 {
4534 #if HAVE_FCNTL_LOCK
4535   struct flock lock;
4536   int ret;
4537
4538   /*
4539    * FIXME.
4540    * NB - this code will need re-writing to cope with large (64bit)
4541    * lock requests. JRA.
4542    */
4543
4544   if(lp_ole_locking_compat()) {
4545     uint32 mask = 0xC0000000;
4546
4547     /* make sure the count is reasonable, we might kill the lockd otherwise */
4548     count &= ~mask;
4549
4550     /* the offset is often strange - remove 2 of its bits if either of
4551        the top two bits are set. Shift the top ones by two bits. This
4552        still allows OLE2 apps to operate, but should stop lockd from
4553        dieing */
4554     if ((offset & mask) != 0)
4555       offset = (offset & ~mask) | ((offset & mask) >> 2);
4556   } else {
4557     uint32 mask = ((unsigned)1<<31);
4558     int32 s_count = (int32) count; /* Signed count. */
4559     int32 s_offset = (int32)offset; /* Signed offset. */
4560
4561     /* interpret negative counts as large numbers */
4562     if (s_count < 0)
4563       s_count &= ~mask;
4564
4565     /* no negative offsets */
4566     if(s_offset < 0)
4567       s_offset &= ~mask;
4568
4569     /* count + offset must be in range */
4570     while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
4571     {
4572       s_offset &= ~mask;
4573       mask = mask >> 1;
4574     }
4575
4576     offset = (uint32)s_offset;
4577     count = (uint32)s_count;
4578   }
4579
4580
4581   DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4582
4583   lock.l_type = type;
4584   lock.l_whence = SEEK_SET;
4585   lock.l_start = (int)offset;
4586   lock.l_len = (int)count;
4587   lock.l_pid = 0;
4588
4589   errno = 0;
4590
4591   ret = fcntl(fd,op,&lock);
4592
4593   if (errno != 0)
4594     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));