Ok - this is the 64 bit widening check in. It changes the configure
[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 SMB_OFF_T 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; /* The pathname in DOS format. */
1222   BOOL valid;
1223 } ino_list[MAX_GETWDCACHE];
1224
1225 BOOL use_getwd_cache=True;
1226
1227 /*******************************************************************
1228   return the absolute current directory path - given a UNIX pathname.
1229   Note that this path is returned in DOS format, not UNIX
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(dos_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 (dos_stat(".",&st) == -1) 
1259   {
1260     DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1261     return(dos_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 (dos_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 (!dos_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,SMB_OFF_T 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)&0xFFFF);
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 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
2058 {
2059   static char *buf=NULL;  
2060   static int size=0;
2061   char *buf1,*abuf;
2062   SMB_OFF_T total = 0;
2063
2064 #ifdef LARGE_SMB_OFF_T
2065   DEBUG(4,("transfer_file n=%.0f  (head=%d) called\n",(double)n,headlen));
2066 #else /* LARGE_SMB_OFF_T */
2067   DEBUG(4,("transfer_file n=%d  (head=%d) called\n",n,headlen));
2068 #endif /* LARGE_SMB_OFF_T */
2069
2070   if (size == 0) {
2071     size = lp_readsize();
2072     size = MAX(size,1024);
2073   }
2074
2075   while (!buf && size>0) {
2076     buf = (char *)Realloc(buf,size+8);
2077     if (!buf) size /= 2;
2078   }
2079
2080   if (!buf) {
2081     DEBUG(0,("Can't allocate transfer buffer!\n"));
2082     exit(1);
2083   }
2084
2085   abuf = buf + (align%8);
2086
2087   if (header)
2088     n += headlen;
2089
2090   while (n > 0)
2091   {
2092     int s = (int)MIN(n,(SMB_OFF_T)size);
2093     int ret,ret2=0;
2094
2095     ret = 0;
2096
2097     if (header && (headlen >= MIN(s,1024))) {
2098       buf1 = header;
2099       s = headlen;
2100       ret = headlen;
2101       headlen = 0;
2102       header = NULL;
2103     } else {
2104       buf1 = abuf;
2105     }
2106
2107     if (header && headlen > 0)
2108     {
2109       ret = MIN(headlen,size);
2110       memcpy(buf1,header,ret);
2111       headlen -= ret;
2112       header += ret;
2113       if (headlen <= 0) header = NULL;
2114     }
2115
2116     if (s > ret)
2117       ret += read(infd,buf1+ret,s-ret);
2118
2119     if (ret > 0)
2120     {
2121       ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2122       if (ret2 > 0) total += ret2;
2123       /* if we can't write then dump excess data */
2124       if (ret2 != ret)
2125         transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2126     }
2127     if (ret <= 0 || ret2 != ret)
2128       return(total);
2129     n -= ret;
2130   }
2131   return(total);
2132 }
2133
2134
2135 /****************************************************************************
2136 read 4 bytes of a smb packet and return the smb length of the packet
2137 store the result in the buffer
2138 This version of the function will return a length of zero on receiving
2139 a keepalive packet.
2140 ****************************************************************************/
2141 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2142 {
2143   int len=0, msg_type;
2144   BOOL ok=False;
2145
2146   while (!ok)
2147     {
2148       if (timeout > 0)
2149         ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2150       else 
2151         ok = (read_data(fd,inbuf,4) == 4);
2152
2153       if (!ok)
2154         return(-1);
2155
2156       len = smb_len(inbuf);
2157       msg_type = CVAL(inbuf,0);
2158
2159       if (msg_type == 0x85) 
2160         DEBUG(5,("Got keepalive packet\n"));
2161     }
2162
2163   DEBUG(10,("got smb length of %d\n",len));
2164
2165   return(len);
2166 }
2167
2168 /****************************************************************************
2169 read 4 bytes of a smb packet and return the smb length of the packet
2170 store the result in the buffer. This version of the function will
2171 never return a session keepalive (length of zero).
2172 ****************************************************************************/
2173 int read_smb_length(int fd,char *inbuf,int timeout)
2174 {
2175   int len;
2176
2177   for(;;)
2178   {
2179     len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2180
2181     if(len < 0)
2182       return len;
2183
2184     /* Ignore session keepalives. */
2185     if(CVAL(inbuf,0) != 0x85)
2186       break;
2187   }
2188
2189   return len;
2190 }
2191
2192 /****************************************************************************
2193   read an smb from a fd. Note that the buffer *MUST* be of size
2194   BUFFER_SIZE+SAFETY_MARGIN.
2195   The timeout is in milli seconds. 
2196
2197   This function will return on a
2198   receipt of a session keepalive packet.
2199 ****************************************************************************/
2200 BOOL receive_smb(int fd,char *buffer, int timeout)
2201 {
2202   int len,ret;
2203
2204   smb_read_error = 0;
2205
2206   bzero(buffer,smb_size + 100);
2207
2208   len = read_smb_length_return_keepalive(fd,buffer,timeout);
2209   if (len < 0)
2210     return(False);
2211
2212   if (len > BUFFER_SIZE) {
2213     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2214     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2215       exit(1);
2216   }
2217
2218   if(len > 0) {
2219     ret = read_data(fd,buffer+4,len);
2220     if (ret != len) {
2221       smb_read_error = READ_ERROR;
2222       return False;
2223     }
2224   }
2225   return(True);
2226 }
2227
2228 /****************************************************************************
2229   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
2230   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2231   The timeout is in milli seconds
2232
2233   This is exactly the same as receive_smb except that it never returns
2234   a session keepalive packet (just as receive_smb used to do).
2235   receive_smb was changed to return keepalives as the oplock processing means this call
2236   should never go into a blocking read.
2237 ****************************************************************************/
2238
2239 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2240 {
2241   BOOL ret;
2242
2243   for(;;)
2244   {
2245     ret = receive_smb(fd, buffer, timeout);
2246
2247     if(ret == False)
2248       return ret;
2249
2250     /* Ignore session keepalive packets. */
2251     if(CVAL(buffer,0) != 0x85)
2252       break;
2253   }
2254   return ret;
2255 }
2256
2257 /****************************************************************************
2258   read a message from a udp fd.
2259 The timeout is in milli seconds
2260 ****************************************************************************/
2261 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2262 {
2263   struct sockaddr_in from;
2264   int fromlen = sizeof(from);
2265   int32 msg_len = 0;
2266
2267   smb_read_error = 0;
2268
2269   if(timeout != 0)
2270   {
2271     struct timeval to;
2272     fd_set fds;
2273     int selrtn;
2274
2275     FD_ZERO(&fds);
2276     FD_SET(fd,&fds);
2277
2278     to.tv_sec = timeout / 1000;
2279     to.tv_usec = (timeout % 1000) * 1000;
2280
2281     selrtn = sys_select(fd+1,&fds,&to);
2282
2283     /* Check if error */
2284     if(selrtn == -1) 
2285     {
2286       /* something is wrong. Maybe the socket is dead? */
2287       smb_read_error = READ_ERROR;
2288       return False;
2289     } 
2290     
2291     /* Did we timeout ? */
2292     if (selrtn == 0) 
2293     {
2294       smb_read_error = READ_TIMEOUT;
2295       return False;
2296     }
2297   }
2298
2299   /*
2300    * Read a loopback udp message.
2301    */
2302   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2303                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2304                      (struct sockaddr *)&from, &fromlen);
2305
2306   if(msg_len < 0)
2307   {
2308     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2309     return False;
2310   }
2311
2312   /* Validate message length. */
2313   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2314   {
2315     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2316               msg_len, 
2317               buffer_len  - UDP_CMD_HEADER_LEN));
2318     return False;
2319   }
2320
2321   /* Validate message from address (must be localhost). */
2322   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2323   {
2324     DEBUG(0,("receive_local_message: invalid 'from' address \
2325 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2326    return False;
2327   }
2328
2329   /* Setup the message header */
2330   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2331   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2332
2333   return True;
2334 }
2335
2336 /****************************************************************************
2337  structure to hold a linked list of local messages.
2338  for processing.
2339 ****************************************************************************/
2340
2341 typedef struct {
2342    ubi_slNode msg_next;
2343    char *msg_buf;
2344    int msg_len;
2345 } pending_message_list;
2346
2347 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
2348
2349 /****************************************************************************
2350  Function to push a message onto the tail of a linked list of smb messages ready
2351  for processing.
2352 ****************************************************************************/
2353
2354 static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
2355 {
2356   pending_message_list *msg = (pending_message_list *)
2357                                malloc(sizeof(pending_message_list));
2358
2359   if(msg == NULL)
2360   {
2361     DEBUG(0,("push_local_message: malloc fail (1)\n"));
2362     return False;
2363   }
2364
2365   msg->msg_buf = (char *)malloc(msg_len);
2366   if(msg->msg_buf == NULL)
2367   {
2368     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2369     free((char *)msg);
2370     return False;
2371   }
2372
2373   memcpy(msg->msg_buf, buf, msg_len);
2374   msg->msg_len = msg_len;
2375
2376   ubi_slAddTail( list_head, msg);
2377
2378   return True;
2379 }
2380
2381 /****************************************************************************
2382  Function to push a smb message onto a linked list of local smb messages ready
2383  for processing.
2384 ****************************************************************************/
2385
2386 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
2387 {
2388   return push_local_message(&smb_oplock_queue, buf, msg_len);
2389 }
2390
2391 /****************************************************************************
2392   Do a select on an two fd's - with timeout. 
2393
2394   If a local udp message has been pushed onto the
2395   queue (this can only happen during oplock break
2396   processing) return this first.
2397
2398   If a pending smb message has been pushed onto the
2399   queue (this can only happen during oplock break
2400   processing) return this next.
2401
2402   If the first smbfd is ready then read an smb from it.
2403   if the second (loopback UDP) fd is ready then read a message
2404   from it and setup the buffer header to identify the length
2405   and from address.
2406   Returns False on timeout or error.
2407   Else returns True.
2408
2409 The timeout is in milli seconds
2410 ****************************************************************************/
2411 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2412                            char *buffer, int buffer_len, 
2413                            int timeout, BOOL *got_smb)
2414 {
2415   fd_set fds;
2416   int selrtn;
2417   struct timeval to;
2418
2419   smb_read_error = 0;
2420
2421   *got_smb = False;
2422
2423   /*
2424    * Check to see if we already have a message on the smb queue.
2425    * If so - copy and return it.
2426    */
2427   
2428   if(ubi_slCount(&smb_oplock_queue) != 0)
2429   {
2430     pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
2431     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2432   
2433     /* Free the message we just copied. */
2434     free((char *)msg->msg_buf);
2435     free((char *)msg);
2436     *got_smb = True;
2437
2438     DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2439     return True;
2440   }
2441
2442   FD_ZERO(&fds);
2443   FD_SET(smbfd,&fds);
2444   FD_SET(oplock_fd,&fds);
2445
2446   to.tv_sec = timeout / 1000;
2447   to.tv_usec = (timeout % 1000) * 1000;
2448
2449   selrtn = sys_select(MAX(smbfd,oplock_fd)+1,&fds,timeout>0?&to:NULL);
2450
2451   /* Check if error */
2452   if(selrtn == -1) {
2453     /* something is wrong. Maybe the socket is dead? */
2454     smb_read_error = READ_ERROR;
2455     return False;
2456   } 
2457     
2458   /* Did we timeout ? */
2459   if (selrtn == 0) {
2460     smb_read_error = READ_TIMEOUT;
2461     return False;
2462   }
2463
2464   if (FD_ISSET(smbfd,&fds))
2465   {
2466     *got_smb = True;
2467     return receive_smb(smbfd, buffer, 0);
2468   }
2469   else
2470   {
2471     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2472   }
2473 }
2474
2475 /****************************************************************************
2476   send an smb to a fd 
2477 ****************************************************************************/
2478 BOOL send_smb(int fd,char *buffer)
2479 {
2480   int len;
2481   int ret,nwritten=0;
2482   len = smb_len(buffer) + 4;
2483
2484   while (nwritten < len)
2485     {
2486       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2487       if (ret <= 0)
2488         {
2489           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2490           close_sockets();
2491           exit(1);
2492         }
2493       nwritten += ret;
2494     }
2495
2496
2497   return True;
2498 }
2499
2500
2501 /****************************************************************************
2502 find a pointer to a netbios name
2503 ****************************************************************************/
2504 char *name_ptr(char *buf,int ofs)
2505 {
2506   unsigned char c = *(unsigned char *)(buf+ofs);
2507
2508   if ((c & 0xC0) == 0xC0)
2509     {
2510       uint16 l;
2511       char p[2];
2512       memcpy(p,buf+ofs,2);
2513       p[0] &= ~0xC0;
2514       l = RSVAL(p,0);
2515       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2516       return(buf + l);
2517     }
2518   else
2519     return(buf+ofs);
2520 }  
2521
2522 /****************************************************************************
2523 extract a netbios name from a buf
2524 ****************************************************************************/
2525 int name_extract(char *buf,int ofs,char *name)
2526 {
2527   char *p = name_ptr(buf,ofs);
2528   int d = PTR_DIFF(p,buf+ofs);
2529   pstrcpy(name,"");
2530   if (d < -50 || d > 50) return(0);
2531   return(name_interpret(p,name));
2532 }
2533   
2534 /****************************************************************************
2535 return the total storage length of a mangled name
2536 ****************************************************************************/
2537 int name_len( char *s )
2538   {
2539   int len;
2540
2541   /* If the two high bits of the byte are set, return 2. */
2542   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2543     return(2);
2544
2545   /* Add up the length bytes. */
2546   for( len = 1; (*s); s += (*s) + 1 )
2547     {
2548     len += *s + 1;
2549     }
2550
2551   return( len );
2552   } /* name_len */
2553
2554 /****************************************************************************
2555 send a single packet to a port on another machine
2556 ****************************************************************************/
2557 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2558 {
2559   BOOL ret;
2560   int out_fd;
2561   struct sockaddr_in sock_out;
2562
2563   if (passive)
2564     return(True);
2565
2566   /* create a socket to write to */
2567   out_fd = socket(AF_INET, type, 0);
2568   if (out_fd == -1) 
2569     {
2570       DEBUG(0,("socket failed"));
2571       return False;
2572     }
2573
2574   /* set the address and port */
2575   bzero((char *)&sock_out,sizeof(sock_out));
2576   putip((char *)&sock_out.sin_addr,(char *)&ip);
2577   sock_out.sin_port = htons( port );
2578   sock_out.sin_family = AF_INET;
2579   
2580   if (DEBUGLEVEL > 0)
2581     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2582              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2583         
2584   /* send it */
2585   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2586
2587   if (!ret)
2588     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2589              inet_ntoa(ip),port,strerror(errno)));
2590
2591   close(out_fd);
2592   return(ret);
2593 }
2594
2595 /*******************************************************************
2596 sleep for a specified number of milliseconds
2597 ********************************************************************/
2598 void msleep(int t)
2599 {
2600   int tdiff=0;
2601   struct timeval tval,t1,t2;  
2602   fd_set fds;
2603
2604   GetTimeOfDay(&t1);
2605   GetTimeOfDay(&t2);
2606   
2607   while (tdiff < t) {
2608     tval.tv_sec = (t-tdiff)/1000;
2609     tval.tv_usec = 1000*((t-tdiff)%1000);
2610  
2611     FD_ZERO(&fds);
2612     errno = 0;
2613     sys_select(0,&fds,&tval);
2614
2615     GetTimeOfDay(&t2);
2616     tdiff = TvalDiff(&t1,&t2);
2617   }
2618 }
2619
2620 /****************************************************************************
2621 check if a string is part of a list
2622 ****************************************************************************/
2623 BOOL in_list(char *s,char *list,BOOL casesensitive)
2624 {
2625   pstring tok;
2626   char *p=list;
2627
2628   if (!list) return(False);
2629
2630   while (next_token(&p,tok,LIST_SEP,sizeof(tok)))
2631     {
2632       if (casesensitive) {
2633         if (strcmp(tok,s) == 0)
2634           return(True);
2635       } else {
2636         if (StrCaseCmp(tok,s) == 0)
2637           return(True);
2638       }
2639     }
2640   return(False);
2641 }
2642
2643 /* this is used to prevent lots of mallocs of size 1 */
2644 static char *null_string = NULL;
2645
2646 /****************************************************************************
2647 set a string value, allocing the space for the string
2648 ****************************************************************************/
2649 BOOL string_init(char **dest,char *src)
2650 {
2651   int l;
2652   if (!src)     
2653     src = "";
2654
2655   l = strlen(src);
2656
2657   if (l == 0)
2658     {
2659       if (!null_string)
2660         null_string = (char *)malloc(1);
2661
2662       *null_string = 0;
2663       *dest = null_string;
2664     }
2665   else
2666     {
2667       (*dest) = (char *)malloc(l+1);
2668       if ((*dest) == NULL) {
2669               DEBUG(0,("Out of memory in string_init\n"));
2670               return False;
2671       }
2672
2673       pstrcpy(*dest,src);
2674     }
2675   return(True);
2676 }
2677
2678 /****************************************************************************
2679 free a string value
2680 ****************************************************************************/
2681 void string_free(char **s)
2682 {
2683   if (!s || !(*s)) return;
2684   if (*s == null_string)
2685     *s = NULL;
2686   if (*s) free(*s);
2687   *s = NULL;
2688 }
2689
2690 /****************************************************************************
2691 set a string value, allocing the space for the string, and deallocating any 
2692 existing space
2693 ****************************************************************************/
2694 BOOL string_set(char **dest,char *src)
2695 {
2696   string_free(dest);
2697
2698   return(string_init(dest,src));
2699 }
2700
2701 /****************************************************************************
2702 substitute a string for a pattern in another string. Make sure there is 
2703 enough room!
2704
2705 This routine looks for pattern in s and replaces it with 
2706 insert. It may do multiple replacements.
2707
2708 return True if a substitution was done.
2709 ****************************************************************************/
2710 BOOL string_sub(char *s,char *pattern,char *insert)
2711 {
2712   BOOL ret = False;
2713   char *p;
2714   int ls,lp,li;
2715
2716   if (!insert || !pattern || !s) return(False);
2717
2718   ls = strlen(s);
2719   lp = strlen(pattern);
2720   li = strlen(insert);
2721
2722   if (!*pattern) return(False);
2723
2724   while (lp <= ls && (p = strstr(s,pattern)))
2725     {
2726       ret = True;
2727       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2728       memcpy(p,insert,li);
2729       s = p + li;
2730       ls = strlen(s);
2731     }
2732   return(ret);
2733 }
2734
2735 /*********************************************************
2736 * Recursive routine that is called by unix_mask_match.
2737 * Does the actual matching. This is the 'original code' 
2738 * used by the unix matcher.
2739 *********************************************************/
2740 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2741 {
2742   char *p;
2743
2744   for( p = regexp; *p && *str; ) {
2745     switch(*p) {
2746     case '?':
2747       str++; p++;
2748       break;
2749
2750     case '*':
2751       /* Look for a character matching 
2752          the one after the '*' */
2753       p++;
2754       if(!*p)
2755         return True; /* Automatic match */
2756       while(*str) {
2757         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2758           str++;
2759         if(unix_do_match(str,p,case_sig))
2760           return True;
2761         if(!*str)
2762           return False;
2763         else
2764           str++;
2765       }
2766       return False;
2767
2768     default:
2769       if(case_sig) {
2770         if(*str != *p)
2771           return False;
2772       } else {
2773         if(toupper(*str) != toupper(*p))
2774           return False;
2775       }
2776       str++, p++;
2777       break;
2778     }
2779   }
2780   if(!*p && !*str)
2781     return True;
2782
2783   if (!*p && str[0] == '.' && str[1] == 0)
2784     return(True);
2785   
2786   if (!*str && *p == '?')
2787     {
2788       while (*p == '?') p++;
2789       return(!*p);
2790     }
2791
2792   if(!*str && (*p == '*' && p[1] == '\0'))
2793     return True;
2794   return False;
2795 }
2796
2797
2798 /*********************************************************
2799 * Routine to match a given string with a regexp - uses
2800 * simplified regexp that takes * and ? only. Case can be
2801 * significant or not.
2802 * This is the 'original code' used by the unix matcher.
2803 *********************************************************/
2804
2805 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2806 {
2807   char *p;
2808   pstring p1, p2;
2809   fstring ebase,eext,sbase,sext;
2810
2811   BOOL matched;
2812
2813   /* Make local copies of str and regexp */
2814   StrnCpy(p1,regexp,sizeof(pstring)-1);
2815   StrnCpy(p2,str,sizeof(pstring)-1);
2816
2817   if (!strchr(p2,'.')) {
2818     pstrcat(p2,".");
2819   }
2820
2821   /* Remove any *? and ** as they are meaningless */
2822   for(p = p1; *p; p++)
2823     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2824       (void)pstrcpy( &p[1], &p[2]);
2825
2826   if (strequal(p1,"*")) return(True);
2827
2828   DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2829
2830   if (trans2) {
2831     fstrcpy(ebase,p1);
2832     fstrcpy(sbase,p2);
2833   } else {
2834     if ((p=strrchr(p1,'.'))) {
2835       *p = 0;
2836       fstrcpy(ebase,p1);
2837       fstrcpy(eext,p+1);
2838     } else {
2839       fstrcpy(ebase,p1);
2840       eext[0] = 0;
2841     }
2842
2843   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2844     *p = 0;
2845     fstrcpy(sbase,p2);
2846     fstrcpy(sext,p+1);
2847   } else {
2848     fstrcpy(sbase,p2);
2849     fstrcpy(sext,"");
2850   }
2851   }
2852
2853   matched = unix_do_match(sbase,ebase,case_sig) && 
2854     (trans2 || unix_do_match(sext,eext,case_sig));
2855
2856   DEBUG(8,("unix_mask_match returning %d\n", matched));
2857
2858   return matched;
2859 }
2860
2861 /*********************************************************
2862 * Recursive routine that is called by mask_match.
2863 * Does the actual matching. Returns True if matched,
2864 * False if failed. This is the 'new' NT style matcher.
2865 *********************************************************/
2866
2867 BOOL do_match(char *str, char *regexp, int case_sig)
2868 {
2869   char *p;
2870
2871   for( p = regexp; *p && *str; ) {
2872     switch(*p) {
2873     case '?':
2874       str++; p++;
2875       break;
2876
2877     case '*':
2878       /* Look for a character matching 
2879          the one after the '*' */
2880       p++;
2881       if(!*p)
2882         return True; /* Automatic match */
2883       while(*str) {
2884         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2885           str++;
2886         /* Now eat all characters that match, as
2887            we want the *last* character to match. */
2888         while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2889           str++;
2890         str--; /* We've eaten the match char after the '*' */
2891         if(do_match(str,p,case_sig)) {
2892           return True;
2893         }
2894         if(!*str) {
2895           return False;
2896         } else {
2897           str++;
2898         }
2899       }
2900       return False;
2901
2902     default:
2903       if(case_sig) {
2904         if(*str != *p) {
2905           return False;
2906         }
2907       } else {
2908         if(toupper(*str) != toupper(*p)) {
2909           return False;
2910         }
2911       }
2912       str++, p++;
2913       break;
2914     }
2915   }
2916
2917   if(!*p && !*str)
2918     return True;
2919
2920   if (!*p && str[0] == '.' && str[1] == 0) {
2921     return(True);
2922   }
2923   
2924   if (!*str && *p == '?') {
2925     while (*p == '?')
2926       p++;
2927     return(!*p);
2928   }
2929
2930   if(!*str && (*p == '*' && p[1] == '\0')) {
2931     return True;
2932   }
2933  
2934   return False;
2935 }
2936
2937
2938 /*********************************************************
2939 * Routine to match a given string with a regexp - uses
2940 * simplified regexp that takes * and ? only. Case can be
2941 * significant or not.
2942 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2943 * This is the new 'NT style' matcher.
2944 *********************************************************/
2945
2946 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2947 {
2948   char *p;
2949   pstring t_pattern, t_filename, te_pattern, te_filename;
2950   fstring ebase,eext,sbase,sext;
2951
2952   BOOL matched = False;
2953
2954   /* Make local copies of str and regexp */
2955   pstrcpy(t_pattern,regexp);
2956   pstrcpy(t_filename,str);
2957
2958 #if 0
2959   /* 
2960    * Not sure if this is a good idea. JRA.
2961    */
2962   if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2963     trans2 = False;
2964 #endif
2965
2966 #if 0
2967   if (!strchr(t_filename,'.')) {
2968     pstrcat(t_filename,".");
2969   }
2970 #endif
2971
2972   /* Remove any *? and ** as they are meaningless */
2973   string_sub(t_pattern, "*?", "*");
2974   string_sub(t_pattern, "**", "*");
2975
2976   if (strequal(t_pattern,"*"))
2977     return(True);
2978
2979   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2980
2981   if(trans2) {
2982     /*
2983      * Match each component of the regexp, split up by '.'
2984      * characters.
2985      */
2986     char *fp, *rp, *cp2, *cp1;
2987     BOOL last_wcard_was_star = False;
2988     int num_path_components, num_regexp_components;
2989
2990     pstrcpy(te_pattern,t_pattern);
2991     pstrcpy(te_filename,t_filename);
2992     /*
2993      * Remove multiple "*." patterns.
2994      */
2995     string_sub(te_pattern, "*.*.", "*.");
2996     num_regexp_components = count_chars(te_pattern, '.');
2997     num_path_components = count_chars(te_filename, '.');
2998
2999     /* 
3000      * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
3001      */
3002     if(num_regexp_components == 0)
3003       matched = do_match( te_filename, te_pattern, case_sig);
3004     else {
3005       for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
3006         fp = strchr(cp2, '.');
3007         if(fp)
3008           *fp = '\0';
3009         rp = strchr(cp1, '.');
3010         if(rp)
3011           *rp = '\0';
3012
3013         if(cp1[strlen(cp1)-1] == '*')
3014           last_wcard_was_star = True;
3015         else
3016           last_wcard_was_star = False;
3017
3018         if(!do_match(cp2, cp1, case_sig))
3019           break;
3020
3021         cp1 = rp ? rp + 1 : NULL;
3022         cp2 = fp ? fp + 1 : "";
3023
3024         if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3025           /* Eat the extra path components. */
3026           int i;
3027
3028           for(i = 0; i < num_path_components - num_regexp_components; i++) {
3029             fp = strchr(cp2, '.');
3030             if(fp)
3031               *fp = '\0';
3032
3033             if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3034               cp2 = fp ? fp + 1 : "";
3035               break;
3036             }
3037             cp2 = fp ? fp + 1 : "";
3038           }
3039           num_path_components -= i;
3040         }
3041       } 
3042       if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3043         matched = True;
3044     }
3045   } else {
3046
3047     /* -------------------------------------------------
3048      * Behaviour of Win95
3049      * for 8.3 filenames and 8.3 Wildcards
3050      * -------------------------------------------------
3051      */
3052     if (strequal (t_filename, ".")) {
3053       /*
3054        *  Patterns:  *.*  *. ?. ?  are valid
3055        *
3056        */
3057       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3058          strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3059         matched = True;
3060     } else if (strequal (t_filename, "..")) {
3061       /*
3062        *  Patterns:  *.*  *. ?. ? *.? are valid
3063        *
3064        */
3065       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3066          strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3067          strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3068         matched = True;
3069     } else {
3070
3071       if ((p = strrchr (t_pattern, '.'))) {
3072         /*
3073          * Wildcard has a suffix.
3074          */
3075         *p = 0;
3076         fstrcpy (ebase, t_pattern);
3077         if (p[1]) {
3078           fstrcpy (eext, p + 1);
3079         } else {
3080           /* pattern ends in DOT: treat as if there is no DOT */
3081           *eext = 0;
3082           if (strequal (ebase, "*"))
3083             return (True);
3084         }
3085       } else {
3086         /*
3087          * No suffix for wildcard.
3088          */
3089         fstrcpy (ebase, t_pattern);
3090         eext[0] = 0;
3091       }
3092
3093       p = strrchr (t_filename, '.');
3094       if (p && (p[1] == 0)      ) {
3095         /*
3096          * Filename has an extension of '.' only.
3097          */
3098         *p = 0; /* nuke dot at end of string */
3099         p = 0;  /* and treat it as if there is no extension */
3100       }
3101
3102       if (p) {
3103         /*
3104          * Filename has an extension.
3105          */
3106         *p = 0;
3107         fstrcpy (sbase, t_filename);
3108         fstrcpy (sext, p + 1);
3109         if (*eext) {
3110           matched = do_match(sbase, ebase, case_sig)
3111                     && do_match(sext, eext, case_sig);
3112         } else {
3113           /* pattern has no extension */
3114           /* Really: match complete filename with pattern ??? means exactly 3 chars */
3115           matched = do_match(str, ebase, case_sig);
3116         }
3117       } else {
3118         /* 
3119          * Filename has no extension.
3120          */
3121         fstrcpy (sbase, t_filename);
3122         fstrcpy (sext, "");
3123         if (*eext) {
3124           /* pattern has extension */
3125           matched = do_match(sbase, ebase, case_sig)
3126                     && do_match(sext, eext, case_sig);
3127         } else {
3128           matched = do_match(sbase, ebase, case_sig);
3129 #ifdef EMULATE_WEIRD_W95_MATCHING
3130           /*
3131            * Even Microsoft has some problems
3132            * Behaviour Win95 -> local disk 
3133            * is different from Win95 -> smb drive from Nt 4.0
3134            * This branch would reflect the Win95 local disk behaviour
3135            */
3136           if (!matched) {
3137             /* a? matches aa and a in w95 */
3138             fstrcat (sbase, ".");
3139             matched = do_match(sbase, ebase, case_sig);
3140           }
3141 #endif
3142         }
3143       }
3144     }
3145   }
3146
3147   DEBUG(8,("mask_match returning %d\n", matched));
3148
3149   return matched;
3150 }
3151
3152 /****************************************************************************
3153 become a daemon, discarding the controlling terminal
3154 ****************************************************************************/
3155 void become_daemon(void)
3156 {
3157         if (fork()) {
3158                 _exit(0);
3159         }
3160
3161   /* detach from the terminal */
3162 #ifdef HAVE_SETSID
3163         setsid();
3164 #elif defined(TIOCNOTTY)
3165         {
3166                 int i = open("/dev/tty", O_RDWR);
3167                 if (i != -1) {
3168                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
3169                         close(i);
3170                 }
3171         }
3172 #endif /* HAVE_SETSID */
3173
3174         /* Close fd's 0,1,2. Needed if started by rsh */
3175         close_low_fds();
3176 }
3177
3178
3179 /****************************************************************************
3180 put up a yes/no prompt
3181 ****************************************************************************/
3182 BOOL yesno(char *p)
3183 {
3184   pstring ans;
3185   printf("%s",p);
3186
3187   if (!fgets(ans,sizeof(ans)-1,stdin))
3188     return(False);
3189
3190   if (*ans == 'y' || *ans == 'Y')
3191     return(True);
3192
3193   return(False);
3194 }
3195
3196 /****************************************************************************
3197 read a line from a file with possible \ continuation chars. 
3198 Blanks at the start or end of a line are stripped.
3199 The string will be allocated if s2 is NULL
3200 ****************************************************************************/
3201 char *fgets_slash(char *s2,int maxlen,FILE *f)
3202 {
3203   char *s=s2;
3204   int len = 0;
3205   int c;
3206   BOOL start_of_line = True;
3207
3208   if (feof(f))
3209     return(NULL);
3210
3211   if (!s2)
3212     {
3213       maxlen = MIN(maxlen,8);
3214       s = (char *)Realloc(s,maxlen);
3215     }
3216
3217   if (!s || maxlen < 2) return(NULL);
3218
3219   *s = 0;
3220
3221   while (len < maxlen-1)
3222     {
3223       c = getc(f);
3224       switch (c)
3225         {
3226         case '\r':
3227           break;
3228         case '\n':
3229           while (len > 0 && s[len-1] == ' ')
3230             {
3231               s[--len] = 0;
3232             }
3233           if (len > 0 && s[len-1] == '\\')
3234             {
3235               s[--len] = 0;
3236               start_of_line = True;
3237               break;
3238             }
3239           return(s);
3240         case EOF:
3241           if (len <= 0 && !s2) 
3242             free(s);
3243           return(len>0?s:NULL);
3244         case ' ':
3245           if (start_of_line)
3246             break;
3247         default:
3248           start_of_line = False;
3249           s[len++] = c;
3250           s[len] = 0;
3251         }
3252       if (!s2 && len > maxlen-3)
3253         {
3254           maxlen *= 2;
3255           s = (char *)Realloc(s,maxlen);
3256           if (!s) return(NULL);
3257         }
3258     }
3259   return(s);
3260 }
3261
3262
3263
3264 /****************************************************************************
3265 set the length of a file from a filedescriptor.
3266 Returns 0 on success, -1 on failure.
3267 ****************************************************************************/
3268 int set_filelen(int fd, SMB_OFF_T len)
3269 {
3270 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3271    extend a file with ftruncate. Provide alternate implementation
3272    for this */
3273
3274 #ifdef HAVE_FTRUNCATE_EXTEND
3275   return sys_ftruncate(fd, len);
3276 #else
3277   SMB_STRUCT_STAT st;
3278   char c = 0;
3279   SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
3280
3281   if(currpos < 0)
3282     return -1;
3283   /* Do an fstat to see if the file is longer than
3284      the requested size (call ftruncate),
3285      or shorter, in which case seek to len - 1 and write 1
3286      byte of zero */
3287   if(sys_fstat(fd, &st)<0)
3288     return -1;
3289
3290 #ifdef S_ISFIFO
3291   if (S_ISFIFO(st.st_mode)) return 0;
3292 #endif
3293
3294   if(st.st_size == len)
3295     return 0;
3296   if(st.st_size > len)
3297     return sys_ftruncate(fd, len);
3298
3299   if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
3300     return -1;
3301   if(write(fd, &c, 1)!=1)
3302     return -1;
3303   /* Seek to where we were */
3304   sys_lseek(fd, currpos, SEEK_SET);
3305   return 0;
3306 #endif
3307 }
3308
3309
3310 /****************************************************************************
3311 return the byte checksum of some data
3312 ****************************************************************************/
3313 int byte_checksum(char *buf,int len)
3314 {
3315   unsigned char *p = (unsigned char *)buf;
3316   int ret = 0;
3317   while (len--)
3318     ret += *p++;
3319   return(ret);
3320 }
3321
3322
3323
3324 #ifdef HPUX
3325 /****************************************************************************
3326 this is a version of setbuffer() for those machines that only have setvbuf
3327 ****************************************************************************/
3328  void setbuffer(FILE *f,char *buf,int bufsize)
3329 {
3330   setvbuf(f,buf,_IOFBF,bufsize);
3331 }
3332 #endif
3333
3334
3335 /****************************************************************************
3336 parse out a directory name from a path name. Assumes dos style filenames.
3337 ****************************************************************************/
3338 char *dirname_dos(char *path,char *buf)
3339 {
3340   char *p = strrchr(path,'\\');
3341
3342   if (!p)
3343     pstrcpy(buf,path);
3344   else
3345     {
3346       *p = 0;
3347       pstrcpy(buf,path);
3348       *p = '\\';
3349     }
3350
3351   return(buf);
3352 }
3353
3354
3355 /****************************************************************************
3356 parse out a filename from a path name. Assumes dos style filenames.
3357 ****************************************************************************/
3358 static char *filename_dos(char *path,char *buf)
3359 {
3360   char *p = strrchr(path,'\\');
3361
3362   if (!p)
3363     pstrcpy(buf,path);
3364   else
3365     pstrcpy(buf,p+1);
3366
3367   return(buf);
3368 }
3369
3370
3371
3372 /****************************************************************************
3373 expand a pointer to be a particular size
3374 ****************************************************************************/
3375 void *Realloc(void *p,int size)
3376 {
3377   void *ret=NULL;
3378
3379   if (size == 0) {
3380     if (p) free(p);
3381     DEBUG(5,("Realloc asked for 0 bytes\n"));
3382     return NULL;
3383   }
3384
3385   if (!p)
3386     ret = (void *)malloc(size);
3387   else
3388     ret = (void *)realloc(p,size);
3389
3390   if (!ret)
3391     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3392
3393   return(ret);
3394 }
3395
3396
3397 /****************************************************************************
3398 get my own name and IP
3399 ****************************************************************************/
3400 BOOL get_myname(char *my_name,struct in_addr *ip)
3401 {
3402   struct hostent *hp;
3403   pstring hostname;
3404
3405   *hostname = 0;
3406
3407   /* get my host name */
3408   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
3409     {
3410       DEBUG(0,("gethostname failed\n"));
3411       return False;
3412     } 
3413
3414   /* get host info */
3415   if ((hp = Get_Hostbyname(hostname)) == 0) 
3416     {
3417       DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3418       return False;
3419     }
3420
3421   if (my_name)
3422     {
3423       /* split off any parts after an initial . */
3424       char *p = strchr(hostname,'.');
3425       if (p) *p = 0;
3426
3427       fstrcpy(my_name,hostname);
3428     }
3429
3430   if (ip)
3431     putip((char *)ip,(char *)hp->h_addr);
3432
3433   return(True);
3434 }
3435
3436
3437 /****************************************************************************
3438 true if two IP addresses are equal
3439 ****************************************************************************/
3440 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3441 {
3442   uint32 a1,a2;
3443   a1 = ntohl(ip1.s_addr);
3444   a2 = ntohl(ip2.s_addr);
3445   return(a1 == a2);
3446 }
3447
3448
3449 /****************************************************************************
3450 open a socket of the specified type, port and address for incoming data
3451 ****************************************************************************/
3452 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3453 {
3454   struct hostent *hp;
3455   struct sockaddr_in sock;
3456   pstring host_name;
3457   int res;
3458
3459   /* get my host name */
3460   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
3461     { DEBUG(0,("gethostname failed\n")); return -1; } 
3462
3463   /* get host info */
3464   if ((hp = Get_Hostbyname(host_name)) == 0) 
3465     {
3466       DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3467       return -1;
3468     }
3469   
3470   bzero((char *)&sock,sizeof(sock));
3471   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3472
3473 #ifdef HAVE_SOCK_SIN_LEN
3474   sock.sin_len = sizeof(sock);
3475 #endif
3476   sock.sin_port = htons( port );
3477   sock.sin_family = hp->h_addrtype;
3478   sock.sin_addr.s_addr = socket_addr;
3479   res = socket(hp->h_addrtype, type, 0);
3480   if (res == -1) 
3481     { DEBUG(0,("socket failed\n")); return -1; }
3482
3483   {
3484     int one=1;
3485     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3486   }
3487
3488   /* now we've got a socket - we need to bind it */
3489   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
3490     { 
3491       if (port) {
3492         if (port == SMB_PORT || port == NMB_PORT)
3493           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3494                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
3495         close(res); 
3496
3497         if (dlevel > 0 && port < 1000)
3498           port = 7999;
3499
3500         if (port >= 1000 && port < 9000)
3501           return(open_socket_in(type,port+1,dlevel,socket_addr));
3502       }
3503
3504       return(-1); 
3505     }
3506   DEBUG(3,("bind succeeded on port %d\n",port));
3507
3508   return res;
3509 }
3510
3511
3512 /****************************************************************************
3513   create an outgoing socket
3514   **************************************************************************/
3515 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3516 {
3517   struct sockaddr_in sock_out;
3518   int res,ret;
3519   int connect_loop = 250; /* 250 milliseconds */
3520   int loops = (timeout * 1000) / connect_loop;
3521
3522   /* create a socket to write to */
3523   res = socket(PF_INET, type, 0);
3524   if (res == -1) 
3525     { DEBUG(0,("socket error\n")); return -1; }
3526
3527   if (type != SOCK_STREAM) return(res);
3528   
3529   bzero((char *)&sock_out,sizeof(sock_out));
3530   putip((char *)&sock_out.sin_addr,(char *)addr);
3531   
3532   sock_out.sin_port = htons( port );
3533   sock_out.sin_family = PF_INET;
3534
3535   /* set it non-blocking */
3536   set_blocking(res,False);
3537
3538   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3539   
3540   /* and connect it to the destination */
3541 connect_again:
3542   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3543
3544   /* Some systems return EAGAIN when they mean EINPROGRESS */
3545   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3546         errno == EAGAIN) && loops--) {
3547     msleep(connect_loop);
3548     goto connect_again;
3549   }
3550
3551   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3552          errno == EAGAIN)) {
3553       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3554       close(res);
3555       return -1;
3556   }
3557
3558 #ifdef EISCONN
3559   if (ret < 0 && errno == EISCONN) {
3560     errno = 0;
3561     ret = 0;
3562   }
3563 #endif
3564
3565   if (ret < 0) {
3566     DEBUG(1,("error connecting to %s:%d (%s)\n",
3567              inet_ntoa(*addr),port,strerror(errno)));
3568     close(res);
3569     return -1;
3570   }
3571
3572   /* set it blocking again */
3573   set_blocking(res,True);
3574
3575   return res;
3576 }
3577
3578
3579 /****************************************************************************
3580 interpret a protocol description string, with a default
3581 ****************************************************************************/
3582 int interpret_protocol(char *str,int def)
3583 {
3584   if (strequal(str,"NT1"))
3585     return(PROTOCOL_NT1);
3586   if (strequal(str,"LANMAN2"))
3587     return(PROTOCOL_LANMAN2);
3588   if (strequal(str,"LANMAN1"))
3589     return(PROTOCOL_LANMAN1);
3590   if (strequal(str,"CORE"))
3591     return(PROTOCOL_CORE);
3592   if (strequal(str,"COREPLUS"))
3593     return(PROTOCOL_COREPLUS);
3594   if (strequal(str,"CORE+"))
3595     return(PROTOCOL_COREPLUS);
3596   
3597   DEBUG(0,("Unrecognised protocol level %s\n",str));
3598   
3599   return(def);
3600 }
3601
3602 /****************************************************************************
3603 interpret a security level
3604 ****************************************************************************/
3605 int interpret_security(char *str,int def)
3606 {
3607   if (strequal(str,"SERVER"))
3608     return(SEC_SERVER);
3609   if (strequal(str,"USER"))
3610     return(SEC_USER);
3611   if (strequal(str,"SHARE"))
3612     return(SEC_SHARE);
3613   
3614   DEBUG(0,("Unrecognised security level %s\n",str));
3615   
3616   return(def);
3617 }
3618
3619
3620 /****************************************************************************
3621 interpret an internet address or name into an IP address in 4 byte form
3622 ****************************************************************************/
3623 uint32 interpret_addr(char *str)
3624 {
3625   struct hostent *hp;
3626   uint32 res;
3627   int i;
3628   BOOL pure_address = True;
3629
3630   if (strcmp(str,"0.0.0.0") == 0) return(0);
3631   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3632
3633   for (i=0; pure_address && str[i]; i++)
3634     if (!(isdigit((int)str[i]) || str[i] == '.')) 
3635       pure_address = False;
3636
3637   /* if it's in the form of an IP address then get the lib to interpret it */
3638   if (pure_address) {
3639     res = inet_addr(str);
3640   } else {
3641     /* otherwise assume it's a network name of some sort and use 
3642        Get_Hostbyname */
3643     if ((hp = Get_Hostbyname(str)) == 0) {
3644       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3645       return 0;
3646     }
3647     if(hp->h_addr == NULL) {
3648       DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3649       return 0;
3650     }
3651     putip((char *)&res,(char *)hp->h_addr);
3652   }
3653
3654   if (res == (uint32)-1) return(0);
3655
3656   return(res);
3657 }
3658
3659 /*******************************************************************
3660   a convenient addition to interpret_addr()
3661   ******************************************************************/
3662 struct in_addr *interpret_addr2(char *str)
3663 {
3664   static struct in_addr ret;
3665   uint32 a = interpret_addr(str);
3666   ret.s_addr = a;
3667   return(&ret);
3668 }
3669
3670 /*******************************************************************
3671   check if an IP is the 0.0.0.0
3672   ******************************************************************/
3673 BOOL zero_ip(struct in_addr ip)
3674 {
3675   uint32 a;
3676   putip((char *)&a,(char *)&ip);
3677   return(a == 0);
3678 }
3679
3680
3681 /*******************************************************************
3682  matchname - determine if host name matches IP address 
3683  ******************************************************************/
3684 static BOOL matchname(char *remotehost,struct in_addr  addr)
3685 {
3686   struct hostent *hp;
3687   int     i;
3688   
3689   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3690     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3691     return False;
3692   } 
3693
3694   /*
3695    * Make sure that gethostbyname() returns the "correct" host name.
3696    * Unfortunately, gethostbyname("localhost") sometimes yields
3697    * "localhost.domain". Since the latter host name comes from the
3698    * local DNS, we just have to trust it (all bets are off if the local
3699    * DNS is perverted). We always check the address list, though.
3700    */
3701   
3702   if (strcasecmp(remotehost, hp->h_name)
3703       && strcasecmp(remotehost, "localhost")) {
3704     DEBUG(0,("host name/name mismatch: %s != %s",
3705              remotehost, hp->h_name));
3706     return False;
3707   }
3708         
3709   /* Look up the host address in the address list we just got. */
3710   for (i = 0; hp->h_addr_list[i]; i++) {
3711     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3712       return True;
3713   }
3714
3715   /*
3716    * The host name does not map to the original host address. Perhaps
3717    * someone has compromised a name server. More likely someone botched
3718    * it, but that could be dangerous, too.
3719    */
3720   
3721   DEBUG(0,("host name/address mismatch: %s != %s",
3722            inet_ntoa(addr), hp->h_name));
3723   return False;
3724 }
3725
3726 /*******************************************************************
3727  Reset the 'done' variables so after a client process is created
3728  from a fork call these calls will be re-done. This should be
3729  expanded if more variables need reseting.
3730  ******************************************************************/
3731
3732 static BOOL global_client_name_done = False;
3733 static BOOL global_client_addr_done = False;
3734
3735 void reset_globals_after_fork(void)
3736 {
3737   global_client_name_done = False;
3738   global_client_addr_done = False;
3739
3740   /*
3741    * Re-seed the random crypto generator, so all smbd's
3742    * started from the same parent won't generate the same
3743    * sequence.
3744    */
3745   {
3746     unsigned char dummy;
3747     generate_random_buffer( &dummy, 1, True);
3748   } 
3749 }
3750  
3751 /*******************************************************************
3752  return the DNS name of the client 
3753  ******************************************************************/
3754 char *client_name(int fd)
3755 {
3756         struct sockaddr sa;
3757         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3758         int     length = sizeof(sa);
3759         static pstring name_buf;
3760         struct hostent *hp;
3761         static int last_fd=-1;
3762         
3763         if (global_client_name_done && last_fd == fd) 
3764                 return name_buf;
3765         
3766         last_fd = fd;
3767         global_client_name_done = False;
3768         
3769         pstrcpy(name_buf,"UNKNOWN");
3770         
3771         if (fd == -1) {
3772                 return name_buf;
3773         }
3774         
3775         if (getpeername(fd, &sa, &length) < 0) {
3776                 DEBUG(0,("getpeername failed\n"));
3777                 return name_buf;
3778         }
3779         
3780         /* Look up the remote host name. */
3781         if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3782                                 sizeof(sockin->sin_addr),
3783                                 AF_INET)) == 0) {
3784                 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3785                 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3786         } else {
3787                 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3788                 if (!matchname(name_buf, sockin->sin_addr)) {
3789                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3790                         pstrcpy(name_buf,"UNKNOWN");
3791                 }
3792         }
3793         global_client_name_done = True;
3794         return name_buf;
3795 }
3796
3797 /*******************************************************************
3798  return the IP addr of the client as a string 
3799  ******************************************************************/
3800 char *client_addr(int fd)
3801 {
3802         struct sockaddr sa;
3803         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3804         int     length = sizeof(sa);
3805         static fstring addr_buf;
3806         static int last_fd = -1;
3807
3808         if (global_client_addr_done && fd == last_fd) 
3809                 return addr_buf;
3810
3811         last_fd = fd;
3812         global_client_addr_done = False;
3813
3814         fstrcpy(addr_buf,"0.0.0.0");
3815
3816         if (fd == -1) {
3817                 return addr_buf;
3818         }
3819         
3820         if (getpeername(fd, &sa, &length) < 0) {
3821                 DEBUG(0,("getpeername failed\n"));
3822                 return addr_buf;
3823         }
3824         
3825         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3826         
3827         global_client_addr_done = True;
3828         return addr_buf;
3829 }
3830
3831 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3832 /******************************************************************
3833  Remove any mount options such as -rsize=2048,wsize=2048 etc.
3834  Based on a fix from <Thomas.Hepper@icem.de>.
3835 *******************************************************************/
3836
3837 static void strip_mount_options( pstring *str)
3838 {
3839   if (**str == '-')
3840   { 
3841     char *p = *str;
3842     while(*p && !isspace(*p))
3843       p++;
3844     while(*p && isspace(*p))
3845       p++;
3846     if(*p) {
3847       pstring tmp_str;
3848
3849       pstrcpy(tmp_str, p);
3850       pstrcpy(*str, tmp_str);
3851     }
3852   }
3853 }
3854
3855 /*******************************************************************
3856  Patch from jkf@soton.ac.uk
3857  Split Luke's automount_server into YP lookup and string splitter
3858  so can easily implement automount_path(). 
3859  As we may end up doing both, cache the last YP result. 
3860 *******************************************************************/
3861
3862 #ifdef WITH_NISPLUS_HOME
3863 static char *automount_lookup(char *user_name)
3864 {
3865   static fstring last_key = "";
3866   static pstring last_value = "";
3867  
3868   char *nis_map = (char *)lp_nis_home_map_name();
3869  
3870   char nis_domain[NIS_MAXNAMELEN + 1];
3871   char buffer[NIS_MAXATTRVAL + 1];
3872   nis_result *result;
3873   nis_object *object;
3874   entry_obj  *entry;
3875  
3876   strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3877   nis_domain[NIS_MAXNAMELEN] = '\0';
3878  
3879   DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3880  
3881   if (strcmp(user_name, last_key))
3882   {
3883     slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3884     DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3885  
3886     if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3887     {
3888        if (result->status != NIS_SUCCESS)
3889       {
3890         DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3891         fstrcpy(last_key, ""); pstrcpy(last_value, "");
3892       }
3893       else
3894       {
3895         object = result->objects.objects_val;
3896         if (object->zo_data.zo_type == ENTRY_OBJ)
3897         {
3898            entry = &object->zo_data.objdata_u.en_data;
3899            DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3900            DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3901  
3902            pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3903            string_sub(last_value, "&", user_name);
3904            fstrcpy(last_key, user_name);
3905         }
3906       }
3907     }