added a function zero_free(void *, int size) that zeros an area of
[samba.git] / source / 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)
135 {
136   char *s;
137   BOOL quoted;
138
139   if (!ptr) ptr = &last_ptr;
140   if (!ptr) return(False);
141
142   s = *ptr;
143
144   /* default to simple separators */
145   if (!sep) sep = " \t\n\r";
146
147   /* find the first non sep char */
148   while(*s && strchr(sep,*s)) s++;
149
150   /* nothing left? */
151   if (! *s) return(False);
152
153   /* copy over the token */
154   for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
155     {
156       if (*s == '\"') 
157         quoted = !quoted;
158       else
159         *buff++ = *s;
160     }
161
162   *ptr = (*s) ? s+1 : s;  
163   *buff = 0;
164   last_ptr = *ptr;
165
166   return(True);
167 }
168
169 /****************************************************************************
170 Convert list of tokens to array; dependent on above routine.
171 Uses last_ptr from above - bit of a hack.
172 ****************************************************************************/
173 char **toktocliplist(int *ctok, char *sep)
174 {
175   char *s=last_ptr;
176   int ictok=0;
177   char **ret, **iret;
178
179   if (!sep) sep = " \t\n\r";
180
181   while(*s && strchr(sep,*s)) s++;
182
183   /* nothing left? */
184   if (!*s) return(NULL);
185
186   do {
187     ictok++;
188     while(*s && (!strchr(sep,*s))) s++;
189     while(*s && strchr(sep,*s)) *s++=0;
190   } while(*s);
191
192   *ctok=ictok;
193   s=last_ptr;
194
195   if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
196   
197   while(ictok--) {    
198     *iret++=s;
199     while(*s++);
200     while(!*s) s++;
201   }
202
203   return ret;
204 }
205
206
207 /* ************************************************************************* **
208  * Duplicate a block of memory.
209  * ************************************************************************* **
210  */
211 void *mem_dup( void *from, int size )
212   {
213   void *tmp;
214
215   tmp = malloc( size );
216   if( NULL != tmp )
217     (void)memcpy( tmp, from, size );
218   return( tmp );
219   } /* mem_dup */
220
221 /****************************************************************************
222 prompte a dptr (to make it recently used)
223 ****************************************************************************/
224 void array_promote(char *array,int elsize,int element)
225 {
226   char *p;
227   if (element == 0)
228     return;
229
230   p = (char *)malloc(elsize);
231
232   if (!p)
233     {
234       DEBUG(5,("Ahh! Can't malloc\n"));
235       return;
236     }
237   memcpy(p,array + element * elsize, elsize);
238   memmove(array + elsize,array,elsize*element);
239   memcpy(array,p,elsize);
240   free(p);
241 }
242
243 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
244
245 struct
246 {
247   char *name;
248   int level;
249   int option;
250   int value;
251   int opttype;
252 } socket_options[] = {
253   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
254   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
255   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
256 #ifdef TCP_NODELAY
257   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
258 #endif
259 #ifdef IPTOS_LOWDELAY
260   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
261 #endif
262 #ifdef IPTOS_THROUGHPUT
263   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
264 #endif
265 #ifdef SO_SNDBUF
266   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
267 #endif
268 #ifdef SO_RCVBUF
269   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
270 #endif
271 #ifdef SO_SNDLOWAT
272   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
273 #endif
274 #ifdef SO_RCVLOWAT
275   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
276 #endif
277 #ifdef SO_SNDTIMEO
278   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
279 #endif
280 #ifdef SO_RCVTIMEO
281   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
282 #endif
283   {NULL,0,0,0,0}};
284
285         
286
287 /****************************************************************************
288 set user socket options
289 ****************************************************************************/
290 void set_socket_options(int fd, char *options)
291 {
292   fstring tok;
293
294   while (next_token(&options,tok," \t,"))
295     {
296       int ret=0,i;
297       int value = 1;
298       char *p;
299       BOOL got_value = False;
300
301       if ((p = strchr(tok,'=')))
302         {
303           *p = 0;
304           value = atoi(p+1);
305           got_value = True;
306         }
307
308       for (i=0;socket_options[i].name;i++)
309         if (strequal(socket_options[i].name,tok))
310           break;
311
312       if (!socket_options[i].name)
313         {
314           DEBUG(0,("Unknown socket option %s\n",tok));
315           continue;
316         }
317
318       switch (socket_options[i].opttype)
319         {
320         case OPT_BOOL:
321         case OPT_INT:
322           ret = setsockopt(fd,socket_options[i].level,
323                            socket_options[i].option,(char *)&value,sizeof(int));
324           break;
325
326         case OPT_ON:
327           if (got_value)
328             DEBUG(0,("syntax error - %s does not take a value\n",tok));
329
330           {
331             int on = socket_options[i].value;
332             ret = setsockopt(fd,socket_options[i].level,
333                              socket_options[i].option,(char *)&on,sizeof(int));
334           }
335           break;          
336         }
337       
338       if (ret != 0)
339         DEBUG(0,("Failed to set socket option %s\n",tok));
340     }
341 }
342
343
344
345 /****************************************************************************
346   close the socket communication
347 ****************************************************************************/
348 void close_sockets(void )
349 {
350 #ifdef WITH_SSL
351   sslutil_disconnect(Client);
352 #endif /* WITH_SSL */
353
354   close(Client);
355   Client = 0;
356 }
357
358 /****************************************************************************
359 determine whether we are in the specified group
360 ****************************************************************************/
361 BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
362 {
363         int i;
364
365         if (group == current_gid) return(True);
366
367         for (i=0;i<ngroups;i++)
368                 if (group == groups[i])
369                         return(True);
370
371         return(False);
372 }
373
374 /****************************************************************************
375 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
376 ****************************************************************************/
377 char *StrCpy(char *dest,char *src)
378 {
379   char *d = dest;
380
381   /* I don't want to get lazy with these ... */
382   SMB_ASSERT(dest && src);
383
384   if (!dest) return(NULL);
385   if (!src) {
386     *dest = 0;
387     return(dest);
388   }
389   while ((*d++ = *src++)) ;
390   return(dest);
391 }
392
393 /****************************************************************************
394 line strncpy but always null terminates. Make sure there is room!
395 ****************************************************************************/
396 char *StrnCpy(char *dest,char *src,int n)
397 {
398   char *d = dest;
399   if (!dest) return(NULL);
400   if (!src) {
401     *dest = 0;
402     return(dest);
403   }
404   while (n-- && (*d++ = *src++)) ;
405   *d = 0;
406   return(dest);
407 }
408
409
410 /*******************************************************************
411 copy an IP address from one buffer to another
412 ********************************************************************/
413 void putip(void *dest,void *src)
414 {
415   memcpy(dest,src,4);
416 }
417
418
419 /****************************************************************************
420 interpret the weird netbios "name". Return the name type
421 ****************************************************************************/
422 static int name_interpret(char *in,char *out)
423 {
424   int ret;
425   int len = (*in++) / 2;
426
427   *out=0;
428
429   if (len > 30 || len<1) return(0);
430
431   while (len--)
432     {
433       if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
434         *out = 0;
435         return(0);
436       }
437       *out = ((in[0]-'A')<<4) + (in[1]-'A');
438       in += 2;
439       out++;
440     }
441   *out = 0;
442   ret = out[-1];
443
444 #ifdef NETBIOS_SCOPE
445   /* Handle any scope names */
446   while(*in) 
447     {
448       *out++ = '.'; /* Scope names are separated by periods */
449       len = *(unsigned char *)in++;
450       StrnCpy(out, in, len);
451       out += len;
452       *out=0;
453       in += len;
454     }
455 #endif
456   return(ret);
457 }
458
459 /****************************************************************************
460 mangle a name into netbios format
461
462   Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
463 ****************************************************************************/
464 int name_mangle( char *In, char *Out, char name_type )
465   {
466   int   i;
467   int   c;
468   int   len;
469   char  buf[20];
470   char *p = Out;
471
472   /* Safely copy the input string, In, into buf[]. */
473   (void)memset( buf, 0, 20 );
474   if( '*' == In[0] )
475     buf[0] = '*';
476   else
477     (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
478
479   /* Place the length of the first field into the output buffer. */
480   p[0] = 32;
481   p++;
482
483   /* Now convert the name to the rfc1001/1002 format. */
484   for( i = 0; i < 16; i++ )
485     {
486     c = toupper( buf[i] );
487     p[i*2]     = ( (c >> 4) & 0x000F ) + 'A';
488     p[(i*2)+1] = (c & 0x000F) + 'A';
489     }
490   p += 32;
491   p[0] = '\0';
492
493   /* Add the scope string. */
494   for( i = 0, len = 0; NULL != scope; i++, len++ )
495     {
496     switch( scope[i] )
497       {
498       case '\0':
499         p[0]     = len;
500         if( len > 0 )
501           p[len+1] = 0;
502         return( name_len(Out) );
503       case '.':
504         p[0] = len;
505         p   += (len + 1);
506         len  = 0;
507         break;
508       default:
509         p[len+1] = scope[i];
510         break;
511       }
512     }
513
514   return( name_len(Out) );
515   } /* name_mangle */
516
517 /*******************************************************************
518   check if a file exists
519 ********************************************************************/
520 BOOL file_exist(char *fname,struct stat *sbuf)
521 {
522   struct stat st;
523   if (!sbuf) sbuf = &st;
524   
525   if (sys_stat(fname,sbuf) != 0) 
526     return(False);
527
528   return(S_ISREG(sbuf->st_mode));
529 }
530
531 /*******************************************************************
532 check a files mod time
533 ********************************************************************/
534 time_t file_modtime(char *fname)
535 {
536   struct stat st;
537   
538   if (sys_stat(fname,&st) != 0) 
539     return(0);
540
541   return(st.st_mtime);
542 }
543
544 /*******************************************************************
545   check if a directory exists
546 ********************************************************************/
547 BOOL directory_exist(char *dname,struct stat *st)
548 {
549   struct stat st2;
550   BOOL ret;
551
552   if (!st) st = &st2;
553
554   if (sys_stat(dname,st) != 0) 
555     return(False);
556
557   ret = S_ISDIR(st->st_mode);
558   if(!ret)
559     errno = ENOTDIR;
560   return ret;
561 }
562
563 /*******************************************************************
564 returns the size in bytes of the named file
565 ********************************************************************/
566 uint32 file_size(char *file_name)
567 {
568   struct stat buf;
569   buf.st_size = 0;
570   sys_stat(file_name,&buf);
571   return(buf.st_size);
572 }
573
574 /*******************************************************************
575 return a string representing an attribute for a file
576 ********************************************************************/
577 char *attrib_string(int mode)
578 {
579   static fstring attrstr;
580
581   attrstr[0] = 0;
582
583   if (mode & aVOLID) fstrcat(attrstr,"V");
584   if (mode & aDIR) fstrcat(attrstr,"D");
585   if (mode & aARCH) fstrcat(attrstr,"A");
586   if (mode & aHIDDEN) fstrcat(attrstr,"H");
587   if (mode & aSYSTEM) fstrcat(attrstr,"S");
588   if (mode & aRONLY) fstrcat(attrstr,"R");        
589
590   return(attrstr);
591 }
592
593
594 /*******************************************************************
595   case insensitive string compararison
596 ********************************************************************/
597 int StrCaseCmp(char *s, char *t)
598 {
599   /* compare until we run out of string, either t or s, or find a difference */
600   /* We *must* use toupper rather than tolower here due to the
601      asynchronous upper to lower mapping.
602    */
603 #if !defined(KANJI_WIN95_COMPATIBILITY)
604   /*
605    * For completeness we should put in equivalent code for code pages
606    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
607    * doubt anyone wants Samba to behave differently from Win95 and WinNT
608    * here. They both treat full width ascii characters as case senstive
609    * filenames (ie. they don't do the work we do here).
610    * JRA.
611    */
612
613   if(lp_client_code_page() == KANJI_CODEPAGE)
614   {
615     /* Win95 treats full width ascii characters as case sensitive. */
616     int diff;
617     for (;;)
618     {
619       if (!*s || !*t)
620             return toupper (*s) - toupper (*t);
621       else if (is_sj_alph (*s) && is_sj_alph (*t))
622       {
623         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
624         if (diff)
625           return diff;
626         s += 2;
627         t += 2;
628       }
629       else if (is_shift_jis (*s) && is_shift_jis (*t))
630       {
631         diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
632         if (diff)
633           return diff;
634         diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
635         if (diff)
636           return diff;
637         s += 2;
638         t += 2;
639       }
640       else if (is_shift_jis (*s))
641         return 1;
642       else if (is_shift_jis (*t))
643         return -1;
644       else 
645       {
646         diff = toupper (*s) - toupper (*t);
647         if (diff)
648           return diff;
649         s++;
650         t++;
651       }
652     }
653   }
654   else
655 #endif /* KANJI_WIN95_COMPATIBILITY */
656   {
657     while (*s && *t && toupper(*s) == toupper(*t))
658     {
659       s++;
660       t++;
661     }
662
663     return(toupper(*s) - toupper(*t));
664   }
665 }
666
667 /*******************************************************************
668   case insensitive string compararison, length limited
669 ********************************************************************/
670 int StrnCaseCmp(char *s, char *t, int n)
671 {
672   /* compare until we run out of string, either t or s, or chars */
673   /* We *must* use toupper rather than tolower here due to the
674      asynchronous upper to lower mapping.
675    */
676 #if !defined(KANJI_WIN95_COMPATIBILITY)
677   /*
678    * For completeness we should put in equivalent code for code pages
679    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
680    * doubt anyone wants Samba to behave differently from Win95 and WinNT
681    * here. They both treat full width ascii characters as case senstive
682    * filenames (ie. they don't do the work we do here).
683    * JRA. 
684    */
685
686   if(lp_client_code_page() == KANJI_CODEPAGE)
687   {
688     /* Win95 treats full width ascii characters as case sensitive. */
689     int diff;
690     for (;n > 0;)
691     {
692       if (!*s || !*t)
693         return toupper (*s) - toupper (*t);
694       else if (is_sj_alph (*s) && is_sj_alph (*t))
695       {
696         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
697         if (diff)
698           return diff;
699         s += 2;
700         t += 2;
701         n -= 2;
702       }
703       else if (is_shift_jis (*s) && is_shift_jis (*t))
704       {
705         diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
706         if (diff)
707           return diff;
708         diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
709         if (diff)
710           return diff;
711         s += 2;
712         t += 2;
713         n -= 2;
714       }
715       else if (is_shift_jis (*s))
716         return 1;
717       else if (is_shift_jis (*t))
718         return -1;
719       else 
720       {
721         diff = toupper (*s) - toupper (*t);
722         if (diff)
723           return diff;
724         s++;
725         t++;
726         n--;
727       }
728     }
729     return 0;
730   }
731   else
732 #endif /* KANJI_WIN95_COMPATIBILITY */
733   {
734     while (n && *s && *t && toupper(*s) == toupper(*t))
735     {
736       s++;
737       t++;
738       n--;
739     }
740
741     /* not run out of chars - strings are different lengths */
742     if (n) 
743       return(toupper(*s) - toupper(*t));
744
745     /* identical up to where we run out of chars, 
746        and strings are same length */
747     return(0);
748   }
749 }
750
751 /*******************************************************************
752   compare 2 strings 
753 ********************************************************************/
754 BOOL strequal(char *s1, char *s2)
755 {
756   if (s1 == s2) return(True);
757   if (!s1 || !s2) return(False);
758   
759   return(StrCaseCmp(s1,s2)==0);
760 }
761
762 /*******************************************************************
763   compare 2 strings up to and including the nth char.
764   ******************************************************************/
765 BOOL strnequal(char *s1,char *s2,int n)
766 {
767   if (s1 == s2) return(True);
768   if (!s1 || !s2 || !n) return(False);
769   
770   return(StrnCaseCmp(s1,s2,n)==0);
771 }
772
773 /*******************************************************************
774   compare 2 strings (case sensitive)
775 ********************************************************************/
776 BOOL strcsequal(char *s1,char *s2)
777 {
778   if (s1 == s2) return(True);
779   if (!s1 || !s2) return(False);
780   
781   return(strcmp(s1,s2)==0);
782 }
783
784
785 /*******************************************************************
786   convert a string to lower case
787 ********************************************************************/
788 void strlower(char *s)
789 {
790   while (*s)
791   {
792 #if !defined(KANJI_WIN95_COMPATIBILITY)
793   /*
794    * For completeness we should put in equivalent code for code pages
795    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
796    * doubt anyone wants Samba to behave differently from Win95 and WinNT
797    * here. They both treat full width ascii characters as case senstive
798    * filenames (ie. they don't do the work we do here).
799    * JRA. 
800    */
801
802     if(lp_client_code_page() == KANJI_CODEPAGE)
803     {
804       /* Win95 treats full width ascii characters as case sensitive. */
805       if (is_shift_jis (*s))
806       {
807         if (is_sj_upper (s[0], s[1]))
808           s[1] = sj_tolower2 (s[1]);
809         s += 2;
810       }
811       else if (is_kana (*s))
812       {
813         s++;
814       }
815       else
816       {
817         if (isupper(*s))
818           *s = tolower(*s);
819         s++;
820       }
821     }
822     else
823 #endif /* KANJI_WIN95_COMPATIBILITY */
824     {
825       int skip = skip_multibyte_char( *s );
826       if( skip != 0 )
827         s += skip;
828       else
829       {
830         if (isupper(*s))
831           *s = tolower(*s);
832         s++;
833       }
834     }
835   }
836 }
837
838 /*******************************************************************
839   convert a string to upper case
840 ********************************************************************/
841 void strupper(char *s)
842 {
843   while (*s)
844   {
845 #if !defined(KANJI_WIN95_COMPATIBILITY)
846   /*
847    * For completeness we should put in equivalent code for code pages
848    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
849    * doubt anyone wants Samba to behave differently from Win95 and WinNT
850    * here. They both treat full width ascii characters as case senstive
851    * filenames (ie. they don't do the work we do here).
852    * JRA. 
853    */
854
855     if(lp_client_code_page() == KANJI_CODEPAGE)
856     {
857       /* Win95 treats full width ascii characters as case sensitive. */
858       if (is_shift_jis (*s))
859       {
860         if (is_sj_lower (s[0], s[1]))
861           s[1] = sj_toupper2 (s[1]);
862         s += 2;
863       }
864       else if (is_kana (*s))
865       {
866         s++;
867       }
868       else
869       {
870         if (islower(*s))
871           *s = toupper(*s);
872         s++;
873       }
874     }
875     else
876 #endif /* KANJI_WIN95_COMPATIBILITY */
877     {
878       int skip = skip_multibyte_char( *s );
879       if( skip != 0 )
880         s += skip;
881       else
882       {
883         if (islower(*s))
884           *s = toupper(*s);
885         s++;
886       }
887     }
888   }
889 }
890
891 /*******************************************************************
892   convert a string to "normal" form
893 ********************************************************************/
894 void strnorm(char *s)
895 {
896   if (case_default == CASE_UPPER)
897     strupper(s);
898   else
899     strlower(s);
900 }
901
902 /*******************************************************************
903 check if a string is in "normal" case
904 ********************************************************************/
905 BOOL strisnormal(char *s)
906 {
907   if (case_default == CASE_UPPER)
908     return(!strhaslower(s));
909
910   return(!strhasupper(s));
911 }
912
913
914 /****************************************************************************
915   string replace
916 ****************************************************************************/
917 void string_replace(char *s,char oldc,char newc)
918 {
919   int skip;
920   while (*s)
921   {
922     skip = skip_multibyte_char( *s );
923     if( skip != 0 )
924       s += skip;
925     else
926     {
927       if (oldc == *s)
928         *s = newc;
929       s++;
930     }
931   }
932 }
933
934 /****************************************************************************
935   make a file into unix format
936 ****************************************************************************/
937 void unix_format(char *fname)
938 {
939   pstring namecopy;
940   string_replace(fname,'\\','/');
941
942   if (*fname == '/')
943     {
944       pstrcpy(namecopy,fname);
945       pstrcpy(fname,".");
946       pstrcat(fname,namecopy);
947     }  
948 }
949
950 /****************************************************************************
951   make a file into dos format
952 ****************************************************************************/
953 void dos_format(char *fname)
954 {
955   string_replace(fname,'/','\\');
956 }
957
958 /*******************************************************************
959   show a smb message structure
960 ********************************************************************/
961 void show_msg(char *buf)
962 {
963         int i;
964         int bcc=0;
965
966         if (DEBUGLEVEL < 5) return;
967
968         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
969                         smb_len(buf),
970                         (int)CVAL(buf,smb_com),
971                         (int)CVAL(buf,smb_rcls),
972                         (int)CVAL(buf,smb_reh),
973                         (int)SVAL(buf,smb_err),
974                         (int)CVAL(buf,smb_flg),
975                         (int)SVAL(buf,smb_flg2)));
976         DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
977                         (int)SVAL(buf,smb_tid),
978                         (int)SVAL(buf,smb_pid),
979                         (int)SVAL(buf,smb_uid),
980                         (int)SVAL(buf,smb_mid),
981                         (int)CVAL(buf,smb_wct)));
982
983         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
984         {
985                 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
986                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
987         }
988
989         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
990
991         DEBUG(5,("smb_bcc=%d\n",bcc));
992
993         if (DEBUGLEVEL < 10) return;
994
995         if (DEBUGLEVEL < 50)
996         {
997                 bcc = MIN(bcc, 512);
998         }
999
1000         dump_data(10, smb_buf(buf), bcc);
1001 }
1002 /*******************************************************************
1003   return the length of an smb packet
1004 ********************************************************************/
1005 int smb_len(char *buf)
1006 {
1007   return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1008 }
1009
1010 /*******************************************************************
1011   set the length of an smb packet
1012 ********************************************************************/
1013 void _smb_setlen(char *buf,int len)
1014 {
1015   buf[0] = 0;
1016   buf[1] = (len&0x10000)>>16;
1017   buf[2] = (len&0xFF00)>>8;
1018   buf[3] = len&0xFF;
1019 }
1020
1021 /*******************************************************************
1022   set the length and marker of an smb packet
1023 ********************************************************************/
1024 void smb_setlen(char *buf,int len)
1025 {
1026   _smb_setlen(buf,len);
1027
1028   CVAL(buf,4) = 0xFF;
1029   CVAL(buf,5) = 'S';
1030   CVAL(buf,6) = 'M';
1031   CVAL(buf,7) = 'B';
1032 }
1033
1034 /*******************************************************************
1035   setup the word count and byte count for a smb message
1036 ********************************************************************/
1037 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1038 {
1039   if (zero)
1040     bzero(buf + smb_size,num_words*2 + num_bytes);
1041   CVAL(buf,smb_wct) = num_words;
1042   SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
1043   smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1044   return (smb_size + num_words*2 + num_bytes);
1045 }
1046
1047 /*******************************************************************
1048 return the number of smb words
1049 ********************************************************************/
1050 int smb_numwords(char *buf)
1051 {
1052   return (CVAL(buf,smb_wct));
1053 }
1054
1055 /*******************************************************************
1056 return the size of the smb_buf region of a message
1057 ********************************************************************/
1058 int smb_buflen(char *buf)
1059 {
1060   return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1061 }
1062
1063 /*******************************************************************
1064   return a pointer to the smb_buf data area
1065 ********************************************************************/
1066 int smb_buf_ofs(char *buf)
1067 {
1068   return (smb_size + CVAL(buf,smb_wct)*2);
1069 }
1070
1071 /*******************************************************************
1072   return a pointer to the smb_buf data area
1073 ********************************************************************/
1074 char *smb_buf(char *buf)
1075 {
1076   return (buf + smb_buf_ofs(buf));
1077 }
1078
1079 /*******************************************************************
1080 return the SMB offset into an SMB buffer
1081 ********************************************************************/
1082 int smb_offset(char *p,char *buf)
1083 {
1084   return(PTR_DIFF(p,buf+4) + chain_size);
1085 }
1086
1087
1088 /*******************************************************************
1089 skip past some strings in a buffer
1090 ********************************************************************/
1091 char *skip_string(char *buf,int n)
1092 {
1093   while (n--)
1094     buf += strlen(buf) + 1;
1095   return(buf);
1096 }
1097
1098 /*******************************************************************
1099 trim the specified elements off the front and back of a string
1100 ********************************************************************/
1101 BOOL trim_string(char *s,char *front,char *back)
1102 {
1103   BOOL ret = False;
1104   while (front && *front && strncmp(s,front,strlen(front)) == 0)
1105     {
1106       char *p = s;
1107       ret = True;
1108       while (1)
1109         {
1110           if (!(*p = p[strlen(front)]))
1111             break;
1112           p++;
1113         }
1114     }
1115   while (back && *back && strlen(s) >= strlen(back) && 
1116          (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
1117     {
1118       ret = True;
1119       s[strlen(s)-strlen(back)] = 0;
1120     }
1121   return(ret);
1122 }
1123
1124
1125 /*******************************************************************
1126 reduce a file name, removing .. elements.
1127 ********************************************************************/
1128 void dos_clean_name(char *s)
1129 {
1130   char *p=NULL;
1131
1132   DEBUG(3,("dos_clean_name [%s]\n",s));
1133
1134   /* remove any double slashes */
1135   string_sub(s, "\\\\", "\\");
1136
1137   while ((p = strstr(s,"\\..\\")) != NULL)
1138     {
1139       pstring s1;
1140
1141       *p = 0;
1142       pstrcpy(s1,p+3);
1143
1144       if ((p=strrchr(s,'\\')) != NULL)
1145         *p = 0;
1146       else
1147         *s = 0;
1148       pstrcat(s,s1);
1149     }  
1150
1151   trim_string(s,NULL,"\\..");
1152
1153   string_sub(s, "\\.\\", "\\");
1154 }
1155
1156 /*******************************************************************
1157 reduce a file name, removing .. elements. 
1158 ********************************************************************/
1159 void unix_clean_name(char *s)
1160 {
1161   char *p=NULL;
1162
1163   DEBUG(3,("unix_clean_name [%s]\n",s));
1164
1165   /* remove any double slashes */
1166   string_sub(s, "//","/");
1167
1168   /* Remove leading ./ characters */
1169   if(strncmp(s, "./", 2) == 0) {
1170     trim_string(s, "./", NULL);
1171     if(*s == 0)
1172       pstrcpy(s,"./");
1173   }
1174
1175   while ((p = strstr(s,"/../")) != NULL)
1176     {
1177       pstring s1;
1178
1179       *p = 0;
1180       pstrcpy(s1,p+3);
1181
1182       if ((p=strrchr(s,'/')) != NULL)
1183         *p = 0;
1184       else
1185         *s = 0;
1186       pstrcat(s,s1);
1187     }  
1188
1189   trim_string(s,NULL,"/..");
1190 }
1191
1192
1193 /*******************************************************************
1194 a wrapper for the normal chdir() function
1195 ********************************************************************/
1196 int ChDir(char *path)
1197 {
1198   int res;
1199   static pstring LastDir="";
1200
1201   if (strcsequal(path,".")) return(0);
1202
1203   if (*path == '/' && strcsequal(LastDir,path)) return(0);
1204   DEBUG(3,("chdir to %s\n",path));
1205   res = sys_chdir(path);
1206   if (!res)
1207     pstrcpy(LastDir,path);
1208   return(res);
1209 }
1210
1211 /* number of list structures for a caching GetWd function. */
1212 #define MAX_GETWDCACHE (50)
1213
1214 struct
1215 {
1216   ino_t inode;
1217   dev_t dev;
1218   char *text;
1219   BOOL valid;
1220 } ino_list[MAX_GETWDCACHE];
1221
1222 BOOL use_getwd_cache=True;
1223
1224 /*******************************************************************
1225   return the absolute current directory path
1226 ********************************************************************/
1227 char *GetWd(char *str)
1228 {
1229   pstring s;
1230   static BOOL getwd_cache_init = False;
1231   struct stat st, st2;
1232   int i;
1233
1234   *s = 0;
1235
1236   if (!use_getwd_cache)
1237     return(sys_getwd(str));
1238
1239   /* init the cache */
1240   if (!getwd_cache_init)
1241     {
1242       getwd_cache_init = True;
1243       for (i=0;i<MAX_GETWDCACHE;i++)
1244         {
1245           string_init(&ino_list[i].text,"");
1246           ino_list[i].valid = False;
1247         }
1248     }
1249
1250   /*  Get the inode of the current directory, if this doesn't work we're
1251       in trouble :-) */
1252
1253   if (stat(".",&st) == -1) 
1254     {
1255       DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1256       return(sys_getwd(str));
1257     }
1258
1259
1260   for (i=0; i<MAX_GETWDCACHE; i++)
1261     if (ino_list[i].valid)
1262       {
1263
1264         /*  If we have found an entry with a matching inode and dev number
1265             then find the inode number for the directory in the cached string.
1266             If this agrees with that returned by the stat for the current
1267             directory then all is o.k. (but make sure it is a directory all
1268             the same...) */
1269       
1270         if (st.st_ino == ino_list[i].inode &&
1271             st.st_dev == ino_list[i].dev)
1272           {
1273             if (stat(ino_list[i].text,&st2) == 0)
1274               {
1275                 if (st.st_ino == st2.st_ino &&
1276                     st.st_dev == st2.st_dev &&
1277                     (st2.st_mode & S_IFMT) == S_IFDIR)
1278                   {
1279                     pstrcpy (str, ino_list[i].text);
1280
1281                     /* promote it for future use */
1282                     array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1283                     return (str);
1284                   }
1285                 else
1286                   {
1287                     /*  If the inode is different then something's changed, 
1288                         scrub the entry and start from scratch. */
1289                     ino_list[i].valid = False;
1290                   }
1291               }
1292           }
1293       }
1294
1295
1296   /*  We don't have the information to hand so rely on traditional methods.
1297       The very slow getcwd, which spawns a process on some systems, or the
1298       not quite so bad getwd. */
1299
1300   if (!sys_getwd(s))
1301     {
1302       DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1303       return (NULL);
1304     }
1305
1306   pstrcpy(str,s);
1307
1308   DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1309
1310   /* add it to the cache */
1311   i = MAX_GETWDCACHE - 1;
1312   string_set(&ino_list[i].text,s);
1313   ino_list[i].dev = st.st_dev;
1314   ino_list[i].inode = st.st_ino;
1315   ino_list[i].valid = True;
1316
1317   /* put it at the top of the list */
1318   array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1319
1320   return (str);
1321 }
1322
1323
1324
1325 /*******************************************************************
1326 reduce a file name, removing .. elements and checking that 
1327 it is below dir in the heirachy. This uses GetWd() and so must be run
1328 on the system that has the referenced file system.
1329
1330 widelinks are allowed if widelinks is true
1331 ********************************************************************/
1332 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1333 {
1334 #ifndef REDUCE_PATHS
1335   return True;
1336 #else
1337   pstring dir2;
1338   pstring wd;
1339   pstring base_name;
1340   pstring newname;
1341   char *p=NULL;
1342   BOOL relative = (*s != '/');
1343
1344   *dir2 = *wd = *base_name = *newname = 0;
1345
1346   if (widelinks)
1347     {
1348       unix_clean_name(s);
1349       /* can't have a leading .. */
1350       if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1351         {
1352           DEBUG(3,("Illegal file name? (%s)\n",s));
1353           return(False);
1354         }
1355
1356       if (strlen(s) == 0)
1357         pstrcpy(s,"./");
1358
1359       return(True);
1360     }
1361   
1362   DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1363
1364   /* remove any double slashes */
1365   string_sub(s,"//","/");
1366
1367   pstrcpy(base_name,s);
1368   p = strrchr(base_name,'/');
1369
1370   if (!p)
1371     return(True);
1372
1373   if (!GetWd(wd))
1374     {
1375       DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1376       return(False);
1377     }
1378
1379   if (ChDir(dir) != 0)
1380     {
1381       DEBUG(0,("couldn't chdir to %s\n",dir));
1382       return(False);
1383     }
1384
1385   if (!GetWd(dir2))
1386     {
1387       DEBUG(0,("couldn't getwd for %s\n",dir));
1388       ChDir(wd);
1389       return(False);
1390     }
1391
1392
1393     if (p && (p != base_name))
1394       {
1395         *p = 0;
1396         if (strcmp(p+1,".")==0)
1397           p[1]=0;
1398         if (strcmp(p+1,"..")==0)
1399           *p = '/';
1400       }
1401
1402   if (ChDir(base_name) != 0)
1403     {
1404       ChDir(wd);
1405       DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1406       return(False);
1407     }
1408
1409   if (!GetWd(newname))
1410     {
1411       ChDir(wd);
1412       DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1413       return(False);
1414     }
1415
1416   if (p && (p != base_name))
1417     {
1418       pstrcat(newname,"/");
1419       pstrcat(newname,p+1);
1420     }
1421
1422   {
1423     int l = strlen(dir2);    
1424     if (dir2[l-1] == '/')
1425       l--;
1426
1427     if (strncmp(newname,dir2,l) != 0)
1428       {
1429         ChDir(wd);
1430         DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1431         return(False);
1432       }
1433
1434     if (relative)
1435       {
1436         if (newname[l] == '/')
1437           pstrcpy(s,newname + l + 1);
1438         else
1439           pstrcpy(s,newname+l);
1440       }
1441     else
1442       pstrcpy(s,newname);
1443   }
1444
1445   ChDir(wd);
1446
1447   if (strlen(s) == 0)
1448     pstrcpy(s,"./");
1449
1450   DEBUG(3,("reduced to %s\n",s));
1451   return(True);
1452 #endif
1453 }
1454
1455 /****************************************************************************
1456 expand some *s 
1457 ****************************************************************************/
1458 static void expand_one(char *Mask,int len)
1459 {
1460   char *p1;
1461   while ((p1 = strchr(Mask,'*')) != NULL)
1462     {
1463       int lfill = (len+1) - strlen(Mask);
1464       int l1= (p1 - Mask);
1465       pstring tmp;
1466       pstrcpy(tmp,Mask);  
1467       memset(tmp+l1,'?',lfill);
1468       pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);  
1469       pstrcpy(Mask,tmp);      
1470     }
1471 }
1472
1473 /****************************************************************************
1474 expand a wildcard expression, replacing *s with ?s
1475 ****************************************************************************/
1476 void expand_mask(char *Mask,BOOL doext)
1477 {
1478   pstring mbeg,mext;
1479   pstring dirpart;
1480   pstring filepart;
1481   BOOL hasdot = False;
1482   char *p1;
1483   BOOL absolute = (*Mask == '\\');
1484
1485   *mbeg = *mext = *dirpart = *filepart = 0;
1486
1487   /* parse the directory and filename */
1488   if (strchr(Mask,'\\'))
1489     dirname_dos(Mask,dirpart);
1490
1491   filename_dos(Mask,filepart);
1492
1493   pstrcpy(mbeg,filepart);
1494   if ((p1 = strchr(mbeg,'.')) != NULL)
1495     {
1496       hasdot = True;
1497       *p1 = 0;
1498       p1++;
1499       pstrcpy(mext,p1);
1500     }
1501   else
1502     {
1503       pstrcpy(mext,"");
1504       if (strlen(mbeg) > 8)
1505         {
1506           pstrcpy(mext,mbeg + 8);
1507           mbeg[8] = 0;
1508         }
1509     }
1510
1511   if (*mbeg == 0)
1512     pstrcpy(mbeg,"????????");
1513   if ((*mext == 0) && doext && !hasdot)
1514     pstrcpy(mext,"???");
1515
1516   if (strequal(mbeg,"*") && *mext==0) 
1517     pstrcpy(mext,"*");
1518
1519   /* expand *'s */
1520   expand_one(mbeg,8);
1521   if (*mext)
1522     expand_one(mext,3);
1523
1524   pstrcpy(Mask,dirpart);
1525   if (*dirpart || absolute) pstrcat(Mask,"\\");
1526   pstrcat(Mask,mbeg);
1527   pstrcat(Mask,".");
1528   pstrcat(Mask,mext);
1529
1530   DEBUG(6,("Mask expanded to [%s]\n",Mask));
1531 }  
1532
1533
1534 /****************************************************************************
1535 does a string have any uppercase chars in it?
1536 ****************************************************************************/
1537 BOOL strhasupper(char *s)
1538 {
1539   while (*s) 
1540   {
1541 #if !defined(KANJI_WIN95_COMPATIBILITY)
1542   /*
1543    * For completeness we should put in equivalent code for code pages
1544    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1545    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1546    * here. They both treat full width ascii characters as case senstive
1547    * filenames (ie. they don't do the work we do here).
1548    * JRA. 
1549    */
1550
1551     if(lp_client_code_page() == KANJI_CODEPAGE)
1552     {
1553       /* Win95 treats full width ascii characters as case sensitive. */
1554       if (is_shift_jis (*s))
1555         s += 2;
1556       else if (is_kana (*s))
1557         s++;
1558       else
1559       {
1560         if (isupper(*s))
1561           return(True);
1562         s++;
1563       }
1564     }
1565     else
1566 #endif /* KANJI_WIN95_COMPATIBILITY */
1567     {
1568       int skip = skip_multibyte_char( *s );
1569       if( skip != 0 )
1570         s += skip;
1571       else {
1572         if (isupper(*s))
1573           return(True);
1574         s++;
1575       }
1576     }
1577   }
1578   return(False);
1579 }
1580
1581 /****************************************************************************
1582 does a string have any lowercase chars in it?
1583 ****************************************************************************/
1584 BOOL strhaslower(char *s)
1585 {
1586   while (*s) 
1587   {
1588 #if !defined(KANJI_WIN95_COMPATIBILITY)
1589   /*
1590    * For completeness we should put in equivalent code for code pages
1591    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1592    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1593    * here. They both treat full width ascii characters as case senstive
1594    * filenames (ie. they don't do the work we do here).
1595    * JRA. 
1596    */
1597
1598     if(lp_client_code_page() == KANJI_CODEPAGE)
1599     {
1600       /* Win95 treats full width ascii characters as case sensitive. */
1601       if (is_shift_jis (*s))
1602       {
1603         if (is_sj_upper (s[0], s[1]))
1604           return(True);
1605         if (is_sj_lower (s[0], s[1]))
1606           return (True);
1607         s += 2;
1608       }
1609       else if (is_kana (*s))
1610       {
1611         s++;
1612       }
1613       else
1614       {
1615         if (islower(*s))
1616           return(True);
1617         s++;
1618       }
1619     }
1620     else
1621 #endif /* KANJI_WIN95_COMPATIBILITY */
1622     {
1623       int skip = skip_multibyte_char( *s );
1624       if( skip != 0 )
1625         s += skip;
1626       else {
1627         if (islower(*s))
1628           return(True);
1629         s++;
1630       }
1631     }
1632   }
1633   return(False);
1634 }
1635
1636 /****************************************************************************
1637 find the number of chars in a string
1638 ****************************************************************************/
1639 int count_chars(char *s,char c)
1640 {
1641   int count=0;
1642
1643 #if !defined(KANJI_WIN95_COMPATIBILITY)
1644   /*
1645    * For completeness we should put in equivalent code for code pages
1646    * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1647    * doubt anyone wants Samba to behave differently from Win95 and WinNT
1648    * here. They both treat full width ascii characters as case senstive
1649    * filenames (ie. they don't do the work we do here).
1650    * JRA. 
1651    */
1652
1653   if(lp_client_code_page() == KANJI_CODEPAGE)
1654   {
1655     /* Win95 treats full width ascii characters as case sensitive. */
1656     while (*s) 
1657     {
1658       if (is_shift_jis (*s))
1659         s += 2;
1660       else 
1661       {
1662         if (*s == c)
1663           count++;
1664         s++;
1665       }
1666     }
1667   }
1668   else
1669 #endif /* KANJI_WIN95_COMPATIBILITY */
1670   {
1671     while (*s) 
1672     {
1673       int skip = skip_multibyte_char( *s );
1674       if( skip != 0 )
1675         s += skip;
1676       else {
1677         if (*s == c)
1678           count++;
1679         s++;
1680       }
1681     }
1682   }
1683   return(count);
1684 }
1685
1686
1687 /****************************************************************************
1688   make a dir struct
1689 ****************************************************************************/
1690 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1691 {  
1692   char *p;
1693   pstring mask2;
1694
1695   pstrcpy(mask2,mask);
1696
1697   if ((mode & aDIR) != 0)
1698     size = 0;
1699
1700   memset(buf+1,' ',11);
1701   if ((p = strchr(mask2,'.')) != NULL)
1702     {
1703       *p = 0;
1704       memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1705       memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1706       *p = '.';
1707     }
1708   else
1709     memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1710
1711   bzero(buf+21,DIR_STRUCT_SIZE-21);
1712   CVAL(buf,21) = mode;
1713   put_dos_date(buf,22,date);
1714   SSVAL(buf,26,size & 0xFFFF);
1715   SSVAL(buf,28,size >> 16);
1716   StrnCpy(buf+30,fname,12);
1717   if (!case_sensitive)
1718     strupper(buf+30);
1719   DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1720 }
1721
1722
1723 /*******************************************************************
1724 close the low 3 fd's and open dev/null in their place
1725 ********************************************************************/
1726 void close_low_fds(void)
1727 {
1728   int fd;
1729   int i;
1730   close(0); close(1); close(2);
1731   /* try and use up these file descriptors, so silly
1732      library routines writing to stdout etc won't cause havoc */
1733   for (i=0;i<3;i++) {
1734     fd = open("/dev/null",O_RDWR,0);
1735     if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1736     if (fd < 0) {
1737       DEBUG(0,("Can't open /dev/null\n"));
1738       return;
1739     }
1740     if (fd != i) {
1741       DEBUG(0,("Didn't get file descriptor %d\n",i));
1742       return;
1743     }
1744   }
1745 }
1746
1747 /****************************************************************************
1748 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1749 else
1750 if SYSV use O_NDELAY
1751 if BSD use FNDELAY
1752 ****************************************************************************/
1753 int set_blocking(int fd, BOOL set)
1754 {
1755   int val;
1756 #ifdef O_NONBLOCK
1757 #define FLAG_TO_SET O_NONBLOCK
1758 #else
1759 #ifdef SYSV
1760 #define FLAG_TO_SET O_NDELAY
1761 #else /* BSD */
1762 #define FLAG_TO_SET FNDELAY
1763 #endif
1764 #endif
1765
1766   if((val = fcntl(fd, F_GETFL, 0)) == -1)
1767         return -1;
1768   if(set) /* Turn blocking on - ie. clear nonblock flag */
1769         val &= ~FLAG_TO_SET;
1770   else
1771     val |= FLAG_TO_SET;
1772   return fcntl( fd, F_SETFL, val);
1773 #undef FLAG_TO_SET
1774 }
1775
1776
1777 /****************************************************************************
1778 write to a socket
1779 ****************************************************************************/
1780 int write_socket(int fd,char *buf,int len)
1781 {
1782   int ret=0;
1783
1784   if (passive)
1785     return(len);
1786   DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1787   ret = write_data(fd,buf,len);
1788       
1789   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1790   if(ret <= 0)
1791     DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", 
1792        len, fd, strerror(errno) ));
1793
1794   return(ret);
1795 }
1796
1797 /****************************************************************************
1798 read from a socket
1799 ****************************************************************************/
1800 int read_udp_socket(int fd,char *buf,int len)
1801 {
1802   int ret;
1803   struct sockaddr_in sock;
1804   int socklen;
1805   
1806   socklen = sizeof(sock);
1807   bzero((char *)&sock,socklen);
1808   bzero((char *)&lastip,sizeof(lastip));
1809   ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1810   if (ret <= 0) {
1811     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1812     return(0);
1813   }
1814
1815   lastip = sock.sin_addr;
1816   lastport = ntohs(sock.sin_port);
1817
1818   DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1819              inet_ntoa(lastip), lastport, ret));
1820
1821   return(ret);
1822 }
1823
1824 /****************************************************************************
1825 read data from a device with a timout in msec.
1826 mincount = if timeout, minimum to read before returning
1827 maxcount = number to be read.
1828 ****************************************************************************/
1829 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1830 {
1831   fd_set fds;
1832   int selrtn;
1833   int readret;
1834   int nread = 0;
1835   struct timeval timeout;
1836
1837   /* just checking .... */
1838   if (maxcnt <= 0) return(0);
1839
1840   smb_read_error = 0;
1841
1842   /* Blocking read */
1843   if (time_out <= 0) {
1844     if (mincnt == 0) mincnt = maxcnt;
1845
1846     while (nread < mincnt) {
1847 #ifdef WITH_SSL
1848       if(fd == sslFd){
1849         readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1850       }else{
1851         readret = read(fd, buf + nread, maxcnt - nread);
1852       }
1853 #else /* WITH_SSL */
1854       readret = read(fd, buf + nread, maxcnt - nread);
1855 #endif /* WITH_SSL */
1856
1857       if (readret == 0) {
1858         smb_read_error = READ_EOF;
1859         return -1;
1860       }
1861
1862       if (readret == -1) {
1863         smb_read_error = READ_ERROR;
1864         return -1;
1865       }
1866       nread += readret;
1867     }
1868     return(nread);
1869   }
1870   
1871   /* Most difficult - timeout read */
1872   /* If this is ever called on a disk file and 
1873          mincnt is greater then the filesize then
1874          system performance will suffer severely as 
1875          select always return true on disk files */
1876
1877   /* Set initial timeout */
1878   timeout.tv_sec = time_out / 1000;
1879   timeout.tv_usec = 1000 * (time_out % 1000);
1880
1881   for (nread=0; nread<mincnt; ) 
1882     {      
1883       FD_ZERO(&fds);
1884       FD_SET(fd,&fds);
1885       
1886       selrtn = sys_select(fd+1,&fds,&timeout);
1887
1888       /* Check if error */
1889       if(selrtn == -1) {
1890         /* something is wrong. Maybe the socket is dead? */
1891         smb_read_error = READ_ERROR;
1892         return -1;
1893       }
1894       
1895       /* Did we timeout ? */
1896       if (selrtn == 0) {
1897         smb_read_error = READ_TIMEOUT;
1898         return -1;
1899       }
1900       
1901 #ifdef WITH_SSL
1902     if(fd == sslFd){
1903       readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1904     }else{
1905       readret = read(fd, buf + nread, maxcnt - nread);
1906     }
1907 #else /* WITH_SSL */
1908     readret = read(fd, buf+nread, maxcnt-nread);
1909 #endif /* WITH_SSL */
1910
1911       if (readret == 0) {
1912         /* we got EOF on the file descriptor */
1913         smb_read_error = READ_EOF;
1914         return -1;
1915       }
1916
1917       if (readret == -1) {
1918         /* the descriptor is probably dead */
1919         smb_read_error = READ_ERROR;
1920         return -1;
1921       }
1922       
1923       nread += readret;
1924     }
1925
1926   /* Return the number we got */
1927   return(nread);
1928 }
1929
1930 /****************************************************************************
1931 read data from the client. Maxtime is in milliseconds
1932 ****************************************************************************/
1933 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1934 {
1935   fd_set fds;
1936   int selrtn;
1937   int nread;
1938   struct timeval timeout;
1939  
1940   FD_ZERO(&fds);
1941   FD_SET(fd,&fds);
1942
1943   timeout.tv_sec = maxtime / 1000;
1944   timeout.tv_usec = (maxtime % 1000) * 1000;
1945
1946   selrtn = sys_select(fd+1,&fds,maxtime>0?&timeout:NULL);
1947
1948   if (!FD_ISSET(fd,&fds))
1949     return 0;
1950
1951   nread = read_udp_socket(fd, buffer, bufsize);
1952
1953   /* return the number got */
1954   return(nread);
1955 }
1956
1957 /*******************************************************************
1958 find the difference in milliseconds between two struct timeval
1959 values
1960 ********************************************************************/
1961 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1962 {
1963   return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
1964          ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
1965 }
1966
1967 /****************************************************************************
1968 send a keepalive packet (rfc1002)
1969 ****************************************************************************/
1970 BOOL send_keepalive(int client)
1971 {
1972   unsigned char buf[4];
1973
1974   buf[0] = 0x85;
1975   buf[1] = buf[2] = buf[3] = 0;
1976
1977   return(write_data(client,(char *)buf,4) == 4);
1978 }
1979
1980
1981
1982 /****************************************************************************
1983   read data from the client, reading exactly N bytes. 
1984 ****************************************************************************/
1985 int read_data(int fd,char *buffer,int N)
1986 {
1987   int  ret;
1988   int total=0;  
1989  
1990   smb_read_error = 0;
1991
1992   while (total < N)
1993   {
1994 #ifdef WITH_SSL
1995     if(fd == sslFd){
1996       ret = SSL_read(ssl, buffer + total, N - total);
1997     }else{
1998       ret = read(fd,buffer + total,N - total);
1999     }
2000 #else /* WITH_SSL */
2001     ret = read(fd,buffer + total,N - total);
2002 #endif /* WITH_SSL */
2003
2004     if (ret == 0)
2005     {
2006       smb_read_error = READ_EOF;
2007       return 0;
2008     }
2009     if (ret == -1)
2010     {
2011       smb_read_error = READ_ERROR;
2012       return -1;
2013     }
2014     total += ret;
2015   }
2016   return total;
2017 }
2018
2019
2020 /****************************************************************************
2021   write data to a fd 
2022 ****************************************************************************/
2023 int write_data(int fd,char *buffer,int N)
2024 {
2025   int total=0;
2026   int ret;
2027
2028   while (total < N)
2029   {
2030 #ifdef WITH_SSL
2031     if(fd == sslFd){
2032       ret = SSL_write(ssl,buffer + total,N - total);
2033     }else{
2034       ret = write(fd,buffer + total,N - total);
2035     }
2036 #else /* WITH_SSL */
2037     ret = write(fd,buffer + total,N - total);
2038 #endif /* WITH_SSL */
2039
2040     if (ret == -1) return -1;
2041     if (ret == 0) return total;
2042
2043     total += ret;
2044   }
2045   return total;
2046 }
2047
2048
2049 /****************************************************************************
2050 transfer some data between two fd's
2051 ****************************************************************************/
2052 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2053 {
2054   static char *buf=NULL;  
2055   static int size=0;
2056   char *buf1,*abuf;
2057   int total = 0;
2058
2059   DEBUG(4,("transfer_file %d  (head=%d) called\n",n,headlen));
2060
2061   if (size == 0) {
2062     size = lp_readsize();
2063     size = MAX(size,1024);
2064   }
2065
2066   while (!buf && size>0) {
2067     buf = (char *)Realloc(buf,size+8);
2068     if (!buf) size /= 2;
2069   }
2070
2071   if (!buf) {
2072     DEBUG(0,("Can't allocate transfer buffer!\n"));
2073     exit(1);
2074   }
2075
2076   abuf = buf + (align%8);
2077
2078   if (header)
2079     n += headlen;
2080
2081   while (n > 0)
2082     {
2083       int s = MIN(n,size);
2084       int ret,ret2=0;
2085
2086       ret = 0;
2087
2088       if (header && (headlen >= MIN(s,1024))) {
2089         buf1 = header;
2090         s = headlen;
2091         ret = headlen;
2092         headlen = 0;
2093         header = NULL;
2094       } else {
2095         buf1 = abuf;
2096       }
2097
2098       if (header && headlen > 0)
2099         {
2100           ret = MIN(headlen,size);
2101           memcpy(buf1,header,ret);
2102           headlen -= ret;
2103           header += ret;
2104           if (headlen <= 0) header = NULL;
2105         }
2106
2107       if (s > ret)
2108         ret += read(infd,buf1+ret,s-ret);
2109
2110       if (ret > 0)
2111         {
2112           ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2113           if (ret2 > 0) total += ret2;
2114           /* if we can't write then dump excess data */
2115           if (ret2 != ret)
2116             transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2117         }
2118       if (ret <= 0 || ret2 != ret)
2119         return(total);
2120       n -= ret;
2121     }
2122   return(total);
2123 }
2124
2125
2126 /****************************************************************************
2127 read 4 bytes of a smb packet and return the smb length of the packet
2128 store the result in the buffer
2129 This version of the function will return a length of zero on receiving
2130 a keepalive packet.
2131 ****************************************************************************/
2132 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2133 {
2134   int len=0, msg_type;
2135   BOOL ok=False;
2136
2137   while (!ok)
2138     {
2139       if (timeout > 0)
2140         ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2141       else 
2142         ok = (read_data(fd,inbuf,4) == 4);
2143
2144       if (!ok)
2145         return(-1);
2146
2147       len = smb_len(inbuf);
2148       msg_type = CVAL(inbuf,0);
2149
2150       if (msg_type == 0x85) 
2151         DEBUG(5,("Got keepalive packet\n"));
2152     }
2153
2154   DEBUG(10,("got smb length of %d\n",len));
2155
2156   return(len);
2157 }
2158
2159 /****************************************************************************
2160 read 4 bytes of a smb packet and return the smb length of the packet
2161 store the result in the buffer. This version of the function will
2162 never return a session keepalive (length of zero).
2163 ****************************************************************************/
2164 int read_smb_length(int fd,char *inbuf,int timeout)
2165 {
2166   int len;
2167
2168   for(;;)
2169   {
2170     len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2171
2172     if(len < 0)
2173       return len;
2174
2175     /* Ignore session keepalives. */
2176     if(CVAL(inbuf,0) != 0x85)
2177       break;
2178   }
2179
2180   return len;
2181 }
2182
2183 /****************************************************************************
2184   read an smb from a fd. Note that the buffer *MUST* be of size
2185   BUFFER_SIZE+SAFETY_MARGIN.
2186   The timeout is in milli seconds. 
2187
2188   This function will return on a
2189   receipt of a session keepalive packet.
2190 ****************************************************************************/
2191 BOOL receive_smb(int fd,char *buffer, int timeout)
2192 {
2193   int len,ret;
2194
2195   smb_read_error = 0;
2196
2197   bzero(buffer,smb_size + 100);
2198
2199   len = read_smb_length_return_keepalive(fd,buffer,timeout);
2200   if (len < 0)
2201     return(False);
2202
2203   if (len > BUFFER_SIZE) {
2204     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2205     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2206       exit(1);
2207   }
2208
2209   if(len > 0) {
2210     ret = read_data(fd,buffer+4,len);
2211     if (ret != len) {
2212       smb_read_error = READ_ERROR;
2213       return False;
2214     }
2215   }
2216   return(True);
2217 }
2218
2219 /****************************************************************************
2220   read an smb from a fd ignoring all keepalive packets. Note that the buffer 
2221   *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2222   The timeout is in milli seconds
2223
2224   This is exactly the same as receive_smb except that it never returns
2225   a session keepalive packet (just as receive_smb used to do).
2226   receive_smb was changed to return keepalives as the oplock processing means this call
2227   should never go into a blocking read.
2228 ****************************************************************************/
2229
2230 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2231 {
2232   BOOL ret;
2233
2234   for(;;)
2235   {
2236     ret = receive_smb(fd, buffer, timeout);
2237
2238     if(ret == False)
2239       return ret;
2240
2241     /* Ignore session keepalive packets. */
2242     if(CVAL(buffer,0) != 0x85)
2243       break;
2244   }
2245   return ret;
2246 }
2247
2248 /****************************************************************************
2249   read a message from a udp fd.
2250 The timeout is in milli seconds
2251 ****************************************************************************/
2252 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2253 {
2254   struct sockaddr_in from;
2255   int fromlen = sizeof(from);
2256   int32 msg_len = 0;
2257
2258   smb_read_error = 0;
2259
2260   if(timeout != 0)
2261   {
2262     struct timeval to;
2263     fd_set fds;
2264     int selrtn;
2265
2266     FD_ZERO(&fds);
2267     FD_SET(fd,&fds);
2268
2269     to.tv_sec = timeout / 1000;
2270     to.tv_usec = (timeout % 1000) * 1000;
2271
2272     selrtn = sys_select(fd+1,&fds,&to);
2273
2274     /* Check if error */
2275     if(selrtn == -1) 
2276     {
2277       /* something is wrong. Maybe the socket is dead? */
2278       smb_read_error = READ_ERROR;
2279       return False;
2280     } 
2281     
2282     /* Did we timeout ? */
2283     if (selrtn == 0) 
2284     {
2285       smb_read_error = READ_TIMEOUT;
2286       return False;
2287     }
2288   }
2289
2290   /*
2291    * Read a loopback udp message.
2292    */
2293   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2294                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2295                      (struct sockaddr *)&from, &fromlen);
2296
2297   if(msg_len < 0)
2298   {
2299     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2300     return False;
2301   }
2302
2303   /* Validate message length. */
2304   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2305   {
2306     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2307               msg_len, 
2308               buffer_len  - UDP_CMD_HEADER_LEN));
2309     return False;
2310   }
2311
2312   /* Validate message from address (must be localhost). */
2313   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2314   {
2315     DEBUG(0,("receive_local_message: invalid 'from' address \
2316 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2317    return False;
2318   }
2319
2320   /* Setup the message header */
2321   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2322   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2323
2324   return True;
2325 }
2326
2327 /****************************************************************************
2328  structure to hold a linked list of local messages.
2329  for processing.
2330 ****************************************************************************/
2331
2332 typedef struct {
2333    ubi_slNode msg_next;
2334    char *msg_buf;
2335    int msg_len;
2336 } pending_message_list;
2337
2338 static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
2339
2340 /****************************************************************************
2341  Function to push a message onto the tail of a linked list of smb messages ready
2342  for processing.
2343 ****************************************************************************/
2344
2345 static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
2346 {
2347   pending_message_list *msg = (pending_message_list *)
2348                                malloc(sizeof(pending_message_list));
2349
2350   if(msg == NULL)
2351   {
2352     DEBUG(0,("push_local_message: malloc fail (1)\n"));
2353     return False;
2354   }
2355
2356   msg->msg_buf = (char *)malloc(msg_len);
2357   if(msg->msg_buf == NULL)
2358   {
2359     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2360     free((char *)msg);
2361     return False;
2362   }
2363
2364   memcpy(msg->msg_buf, buf, msg_len);
2365   msg->msg_len = msg_len;
2366
2367   ubi_slAddTail( list_head, msg);
2368
2369   return True;
2370 }
2371
2372 /****************************************************************************
2373  Function to push a smb message onto a linked list of local smb messages ready
2374  for processing.
2375 ****************************************************************************/
2376
2377 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
2378 {
2379   return push_local_message(&smb_oplock_queue, buf, msg_len);
2380 }
2381
2382 /****************************************************************************
2383   Do a select on an two fd's - with timeout. 
2384
2385   If a local udp message has been pushed onto the
2386   queue (this can only happen during oplock break
2387   processing) return this first.
2388
2389   If a pending smb message has been pushed onto the
2390   queue (this can only happen during oplock break
2391   processing) return this next.
2392
2393   If the first smbfd is ready then read an smb from it.
2394   if the second (loopback UDP) fd is ready then read a message
2395   from it and setup the buffer header to identify the length
2396   and from address.
2397   Returns False on timeout or error.
2398   Else returns True.
2399
2400 The timeout is in milli seconds
2401 ****************************************************************************/
2402 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2403                            char *buffer, int buffer_len, 
2404                            int timeout, BOOL *got_smb)
2405 {
2406   fd_set fds;
2407   int selrtn;
2408   struct timeval to;
2409
2410   smb_read_error = 0;
2411
2412   *got_smb = False;
2413
2414   /*
2415    * Check to see if we already have a message on the smb queue.
2416    * If so - copy and return it.
2417    */
2418   
2419   if(ubi_slCount(&smb_oplock_queue) != 0)
2420   {
2421     pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
2422     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2423   
2424     /* Free the message we just copied. */
2425     free((char *)msg->msg_buf);
2426     free((char *)msg);
2427     *got_smb = True;
2428
2429     DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2430     return True;
2431   }
2432
2433   FD_ZERO(&fds);
2434   FD_SET(smbfd,&fds);
2435   FD_SET(oplock_fd,&fds);
2436
2437   to.tv_sec = timeout / 1000;
2438   to.tv_usec = (timeout % 1000) * 1000;
2439
2440   selrtn = sys_select(MAX(smbfd,oplock_fd)+1,&fds,timeout>0?&to:NULL);
2441
2442   /* Check if error */
2443   if(selrtn == -1) {
2444     /* something is wrong. Maybe the socket is dead? */
2445     smb_read_error = READ_ERROR;
2446     return False;
2447   } 
2448     
2449   /* Did we timeout ? */
2450   if (selrtn == 0) {
2451     smb_read_error = READ_TIMEOUT;
2452     return False;
2453   }
2454
2455   if (FD_ISSET(smbfd,&fds))
2456   {
2457     *got_smb = True;
2458     return receive_smb(smbfd, buffer, 0);
2459   }
2460   else
2461   {
2462     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2463   }
2464 }
2465
2466 /****************************************************************************
2467   send an smb to a fd 
2468 ****************************************************************************/
2469 BOOL send_smb(int fd,char *buffer)
2470 {
2471   int len;
2472   int ret,nwritten=0;
2473   len = smb_len(buffer) + 4;
2474
2475   while (nwritten < len)
2476     {
2477       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2478       if (ret <= 0)
2479         {
2480           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2481           close_sockets();
2482           exit(1);
2483         }
2484       nwritten += ret;
2485     }
2486
2487
2488   return True;
2489 }
2490
2491
2492 /****************************************************************************
2493 find a pointer to a netbios name
2494 ****************************************************************************/
2495 char *name_ptr(char *buf,int ofs)
2496 {
2497   unsigned char c = *(unsigned char *)(buf+ofs);
2498
2499   if ((c & 0xC0) == 0xC0)
2500     {
2501       uint16 l;
2502       char p[2];
2503       memcpy(p,buf+ofs,2);
2504       p[0] &= ~0xC0;
2505       l = RSVAL(p,0);
2506       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2507       return(buf + l);
2508     }
2509   else
2510     return(buf+ofs);
2511 }  
2512
2513 /****************************************************************************
2514 extract a netbios name from a buf
2515 ****************************************************************************/
2516 int name_extract(char *buf,int ofs,char *name)
2517 {
2518   char *p = name_ptr(buf,ofs);
2519   int d = PTR_DIFF(p,buf+ofs);
2520   pstrcpy(name,"");
2521   if (d < -50 || d > 50) return(0);
2522   return(name_interpret(p,name));
2523 }
2524   
2525 /****************************************************************************
2526 return the total storage length of a mangled name
2527 ****************************************************************************/
2528 int name_len( char *s )
2529   {
2530   int len;
2531
2532   /* If the two high bits of the byte are set, return 2. */
2533   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2534     return(2);
2535
2536   /* Add up the length bytes. */
2537   for( len = 1; (*s); s += (*s) + 1 )
2538     {
2539     len += *s + 1;
2540     }
2541
2542   return( len );
2543   } /* name_len */
2544
2545 /****************************************************************************
2546 send a single packet to a port on another machine
2547 ****************************************************************************/
2548 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2549 {
2550   BOOL ret;
2551   int out_fd;
2552   struct sockaddr_in sock_out;
2553
2554   if (passive)
2555     return(True);
2556
2557   /* create a socket to write to */
2558   out_fd = socket(AF_INET, type, 0);
2559   if (out_fd == -1) 
2560     {
2561       DEBUG(0,("socket failed"));
2562       return False;
2563     }
2564
2565   /* set the address and port */
2566   bzero((char *)&sock_out,sizeof(sock_out));
2567   putip((char *)&sock_out.sin_addr,(char *)&ip);
2568   sock_out.sin_port = htons( port );
2569   sock_out.sin_family = AF_INET;
2570   
2571   if (DEBUGLEVEL > 0)
2572     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2573              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2574         
2575   /* send it */
2576   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2577
2578   if (!ret)
2579     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2580              inet_ntoa(ip),port,strerror(errno)));
2581
2582   close(out_fd);
2583   return(ret);
2584 }
2585
2586 /*******************************************************************
2587 sleep for a specified number of milliseconds
2588 ********************************************************************/
2589 void msleep(int t)
2590 {
2591   int tdiff=0;
2592   struct timeval tval,t1,t2;  
2593   fd_set fds;
2594
2595   GetTimeOfDay(&t1);
2596   GetTimeOfDay(&t2);
2597   
2598   while (tdiff < t) {
2599     tval.tv_sec = (t-tdiff)/1000;
2600     tval.tv_usec = 1000*((t-tdiff)%1000);
2601  
2602     FD_ZERO(&fds);
2603     errno = 0;
2604     sys_select(0,&fds,&tval);
2605
2606     GetTimeOfDay(&t2);
2607     tdiff = TvalDiff(&t1,&t2);
2608   }
2609 }
2610
2611 /****************************************************************************
2612 check if a string is part of a list
2613 ****************************************************************************/
2614 BOOL in_list(char *s,char *list,BOOL casesensitive)
2615 {
2616   pstring tok;
2617   char *p=list;
2618
2619   if (!list) return(False);
2620
2621   while (next_token(&p,tok,LIST_SEP))
2622     {
2623       if (casesensitive) {
2624         if (strcmp(tok,s) == 0)
2625           return(True);
2626       } else {
2627         if (StrCaseCmp(tok,s) == 0)
2628           return(True);
2629       }
2630     }
2631   return(False);
2632 }
2633
2634 /* this is used to prevent lots of mallocs of size 1 */
2635 static char *null_string = NULL;
2636
2637 /****************************************************************************
2638 set a string value, allocing the space for the string
2639 ****************************************************************************/
2640 BOOL string_init(char **dest,char *src)
2641 {
2642   int l;
2643   if (!src)     
2644     src = "";
2645
2646   l = strlen(src);
2647
2648   if (l == 0)
2649     {
2650       if (!null_string)
2651         null_string = (char *)malloc(1);
2652
2653       *null_string = 0;
2654       *dest = null_string;
2655     }
2656   else
2657     {
2658       (*dest) = (char *)malloc(l+1);
2659       if ((*dest) == NULL) {
2660               DEBUG(0,("Out of memory in string_init\n"));
2661               return False;
2662       }
2663
2664       pstrcpy(*dest,src);
2665     }
2666   return(True);
2667 }
2668
2669 /****************************************************************************
2670 free a string value
2671 ****************************************************************************/
2672 void string_free(char **s)
2673 {
2674   if (!s || !(*s)) return;
2675   if (*s == null_string)
2676     *s = NULL;
2677   if (*s) free(*s);
2678   *s = NULL;
2679 }
2680
2681 /****************************************************************************
2682 set a string value, allocing the space for the string, and deallocating any 
2683 existing space
2684 ****************************************************************************/
2685 BOOL string_set(char **dest,char *src)
2686 {
2687   string_free(dest);
2688
2689   return(string_init(dest,src));
2690 }
2691
2692 /****************************************************************************
2693 substitute a string for a pattern in another string. Make sure there is 
2694 enough room!
2695
2696 This routine looks for pattern in s and replaces it with 
2697 insert. It may do multiple replacements.
2698
2699 return True if a substitution was done.
2700 ****************************************************************************/
2701 BOOL string_sub(char *s,char *pattern,char *insert)
2702 {
2703   BOOL ret = False;
2704   char *p;
2705   int ls,lp,li;
2706
2707   if (!insert || !pattern || !s) return(False);
2708
2709   ls = strlen(s);
2710   lp = strlen(pattern);
2711   li = strlen(insert);
2712
2713   if (!*pattern) return(False);
2714
2715   while (lp <= ls && (p = strstr(s,pattern)))
2716     {
2717       ret = True;
2718       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2719       memcpy(p,insert,li);
2720       s = p + li;
2721       ls = strlen(s);
2722     }
2723   return(ret);
2724 }
2725
2726 /*********************************************************
2727 * Recursive routine that is called by unix_mask_match.
2728 * Does the actual matching. This is the 'original code' 
2729 * used by the unix matcher.
2730 *********************************************************/
2731 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2732 {
2733   char *p;
2734
2735   for( p = regexp; *p && *str; ) {
2736     switch(*p) {
2737     case '?':
2738       str++; p++;
2739       break;
2740
2741     case '*':
2742       /* Look for a character matching 
2743          the one after the '*' */
2744       p++;
2745       if(!*p)
2746         return True; /* Automatic match */
2747       while(*str) {
2748         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2749           str++;
2750         if(unix_do_match(str,p,case_sig))
2751           return True;
2752         if(!*str)
2753           return False;
2754         else
2755           str++;
2756       }
2757       return False;
2758
2759     default:
2760       if(case_sig) {
2761         if(*str != *p)
2762           return False;
2763       } else {
2764         if(toupper(*str) != toupper(*p))
2765           return False;
2766       }
2767       str++, p++;
2768       break;
2769     }
2770   }
2771   if(!*p && !*str)
2772     return True;
2773
2774   if (!*p && str[0] == '.' && str[1] == 0)
2775     return(True);
2776   
2777   if (!*str && *p == '?')
2778     {
2779       while (*p == '?') p++;
2780       return(!*p);
2781     }
2782
2783   if(!*str && (*p == '*' && p[1] == '\0'))
2784     return True;
2785   return False;
2786 }
2787
2788
2789 /*********************************************************
2790 * Routine to match a given string with a regexp - uses
2791 * simplified regexp that takes * and ? only. Case can be
2792 * significant or not.
2793 * This is the 'original code' used by the unix matcher.
2794 *********************************************************/
2795
2796 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2797 {
2798   char *p;
2799   pstring p1, p2;
2800   fstring ebase,eext,sbase,sext;
2801
2802   BOOL matched;
2803
2804   /* Make local copies of str and regexp */
2805   StrnCpy(p1,regexp,sizeof(pstring)-1);
2806   StrnCpy(p2,str,sizeof(pstring)-1);
2807
2808   if (!strchr(p2,'.')) {
2809     pstrcat(p2,".");
2810   }
2811
2812   /* Remove any *? and ** as they are meaningless */
2813   for(p = p1; *p; p++)
2814     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2815       (void)pstrcpy( &p[1], &p[2]);
2816
2817   if (strequal(p1,"*")) return(True);
2818
2819   DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2820
2821   if (trans2) {
2822     fstrcpy(ebase,p1);
2823     fstrcpy(sbase,p2);
2824   } else {
2825     if ((p=strrchr(p1,'.'))) {
2826       *p = 0;
2827       fstrcpy(ebase,p1);
2828       fstrcpy(eext,p+1);
2829     } else {
2830       fstrcpy(ebase,p1);
2831       eext[0] = 0;
2832     }
2833
2834   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2835     *p = 0;
2836     fstrcpy(sbase,p2);
2837     fstrcpy(sext,p+1);
2838   } else {
2839     fstrcpy(sbase,p2);
2840     fstrcpy(sext,"");
2841   }
2842   }
2843
2844   matched = unix_do_match(sbase,ebase,case_sig) && 
2845     (trans2 || unix_do_match(sext,eext,case_sig));
2846
2847   DEBUG(8,("unix_mask_match returning %d\n", matched));
2848
2849   return matched;
2850 }
2851
2852 /*********************************************************
2853 * Recursive routine that is called by mask_match.
2854 * Does the actual matching. Returns True if matched,
2855 * False if failed. This is the 'new' NT style matcher.
2856 *********************************************************/
2857
2858 BOOL do_match(char *str, char *regexp, int case_sig)
2859 {
2860   char *p;
2861
2862   for( p = regexp; *p && *str; ) {
2863     switch(*p) {
2864     case '?':
2865       str++; p++;
2866       break;
2867
2868     case '*':
2869       /* Look for a character matching 
2870          the one after the '*' */
2871       p++;
2872       if(!*p)
2873         return True; /* Automatic match */
2874       while(*str) {
2875         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2876           str++;
2877         /* Now eat all characters that match, as
2878            we want the *last* character to match. */
2879         while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2880           str++;
2881         str--; /* We've eaten the match char after the '*' */
2882         if(do_match(str,p,case_sig)) {
2883           return True;
2884         }
2885         if(!*str) {
2886           return False;
2887         } else {
2888           str++;
2889         }
2890       }
2891       return False;
2892
2893     default:
2894       if(case_sig) {
2895         if(*str != *p) {
2896           return False;
2897         }
2898       } else {
2899         if(toupper(*str) != toupper(*p)) {
2900           return False;
2901         }
2902       }
2903       str++, p++;
2904       break;
2905     }
2906   }
2907
2908   if(!*p && !*str)
2909     return True;
2910
2911   if (!*p && str[0] == '.' && str[1] == 0) {
2912     return(True);
2913   }
2914   
2915   if (!*str && *p == '?') {
2916     while (*p == '?')
2917       p++;
2918     return(!*p);
2919   }
2920
2921   if(!*str && (*p == '*' && p[1] == '\0')) {
2922     return True;
2923   }
2924  
2925   return False;
2926 }
2927
2928
2929 /*********************************************************
2930 * Routine to match a given string with a regexp - uses
2931 * simplified regexp that takes * and ? only. Case can be
2932 * significant or not.
2933 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2934 * This is the new 'NT style' matcher.
2935 *********************************************************/
2936
2937 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2938 {
2939   char *p;
2940   pstring t_pattern, t_filename, te_pattern, te_filename;
2941   fstring ebase,eext,sbase,sext;
2942
2943   BOOL matched = False;
2944
2945   /* Make local copies of str and regexp */
2946   pstrcpy(t_pattern,regexp);
2947   pstrcpy(t_filename,str);
2948
2949 #if 0
2950   /* 
2951    * Not sure if this is a good idea. JRA.
2952    */
2953   if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2954     trans2 = False;
2955 #endif
2956
2957 #if 0
2958   if (!strchr(t_filename,'.')) {
2959     pstrcat(t_filename,".");
2960   }
2961 #endif
2962
2963   /* Remove any *? and ** as they are meaningless */
2964   string_sub(t_pattern, "*?", "*");
2965   string_sub(t_pattern, "**", "*");
2966
2967   if (strequal(t_pattern,"*"))
2968     return(True);
2969
2970   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2971
2972   if(trans2) {
2973     /*
2974      * Match each component of the regexp, split up by '.'
2975      * characters.
2976      */
2977     char *fp, *rp, *cp2, *cp1;
2978     BOOL last_wcard_was_star = False;
2979     int num_path_components, num_regexp_components;
2980
2981     pstrcpy(te_pattern,t_pattern);
2982     pstrcpy(te_filename,t_filename);
2983     /*
2984      * Remove multiple "*." patterns.
2985      */
2986     string_sub(te_pattern, "*.*.", "*.");
2987     num_regexp_components = count_chars(te_pattern, '.');
2988     num_path_components = count_chars(te_filename, '.');
2989
2990     /* 
2991      * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2992      */
2993     if(num_regexp_components == 0)
2994       matched = do_match( te_filename, te_pattern, case_sig);
2995     else {
2996       for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
2997         fp = strchr(cp2, '.');
2998         if(fp)
2999           *fp = '\0';
3000         rp = strchr(cp1, '.');
3001         if(rp)
3002           *rp = '\0';
3003
3004         if(cp1[strlen(cp1)-1] == '*')
3005           last_wcard_was_star = True;
3006         else
3007           last_wcard_was_star = False;
3008
3009         if(!do_match(cp2, cp1, case_sig))
3010           break;
3011
3012         cp1 = rp ? rp + 1 : NULL;
3013         cp2 = fp ? fp + 1 : "";
3014
3015         if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
3016           /* Eat the extra path components. */
3017           int i;
3018
3019           for(i = 0; i < num_path_components - num_regexp_components; i++) {
3020             fp = strchr(cp2, '.');
3021             if(fp)
3022               *fp = '\0';
3023
3024             if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
3025               cp2 = fp ? fp + 1 : "";
3026               break;
3027             }
3028             cp2 = fp ? fp + 1 : "";
3029           }
3030           num_path_components -= i;
3031         }
3032       } 
3033       if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
3034         matched = True;
3035     }
3036   } else {
3037
3038     /* -------------------------------------------------
3039      * Behaviour of Win95
3040      * for 8.3 filenames and 8.3 Wildcards
3041      * -------------------------------------------------
3042      */
3043     if (strequal (t_filename, ".")) {
3044       /*
3045        *  Patterns:  *.*  *. ?. ?  are valid
3046        *
3047        */
3048       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3049          strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
3050         matched = True;
3051     } else if (strequal (t_filename, "..")) {
3052       /*
3053        *  Patterns:  *.*  *. ?. ? *.? are valid
3054        *
3055        */
3056       if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
3057          strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
3058          strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
3059         matched = True;
3060     } else {
3061
3062       if ((p = strrchr (t_pattern, '.'))) {
3063         /*
3064          * Wildcard has a suffix.
3065          */
3066         *p = 0;
3067         fstrcpy (ebase, t_pattern);
3068         if (p[1]) {
3069           fstrcpy (eext, p + 1);
3070         } else {
3071           /* pattern ends in DOT: treat as if there is no DOT */
3072           *eext = 0;
3073           if (strequal (ebase, "*"))
3074             return (True);
3075         }
3076       } else {
3077         /*
3078          * No suffix for wildcard.
3079          */
3080         fstrcpy (ebase, t_pattern);
3081         eext[0] = 0;
3082       }
3083
3084       p = strrchr (t_filename, '.');
3085       if (p && (p[1] == 0)      ) {
3086         /*
3087          * Filename has an extension of '.' only.
3088          */
3089         *p = 0; /* nuke dot at end of string */
3090         p = 0;  /* and treat it as if there is no extension */
3091       }
3092
3093       if (p) {
3094         /*
3095          * Filename has an extension.
3096          */
3097         *p = 0;
3098         fstrcpy (sbase, t_filename);
3099         fstrcpy (sext, p + 1);
3100         if (*eext) {
3101           matched = do_match(sbase, ebase, case_sig)
3102                     && do_match(sext, eext, case_sig);
3103         } else {
3104           /* pattern has no extension */
3105           /* Really: match complete filename with pattern ??? means exactly 3 chars */
3106           matched = do_match(str, ebase, case_sig);
3107         }
3108       } else {
3109         /* 
3110          * Filename has no extension.
3111          */
3112         fstrcpy (sbase, t_filename);
3113         fstrcpy (sext, "");
3114         if (*eext) {
3115           /* pattern has extension */
3116           matched = do_match(sbase, ebase, case_sig)
3117                     && do_match(sext, eext, case_sig);
3118         } else {
3119           matched = do_match(sbase, ebase, case_sig);
3120 #ifdef EMULATE_WEIRD_W95_MATCHING
3121           /*
3122            * Even Microsoft has some problems
3123            * Behaviour Win95 -> local disk 
3124            * is different from Win95 -> smb drive from Nt 4.0
3125            * This branch would reflect the Win95 local disk behaviour
3126            */
3127           if (!matched) {
3128             /* a? matches aa and a in w95 */
3129             fstrcat (sbase, ".");
3130             matched = do_match(sbase, ebase, case_sig);
3131           }
3132 #endif
3133         }
3134       }
3135     }
3136   }
3137
3138   DEBUG(8,("mask_match returning %d\n", matched));
3139
3140   return matched;
3141 }
3142
3143 /****************************************************************************
3144 become a daemon, discarding the controlling terminal
3145 ****************************************************************************/
3146 void become_daemon(void)
3147 {
3148         if (fork()) {
3149                 _exit(0);
3150         }
3151
3152   /* detach from the terminal */
3153 #ifdef HAVE_SETSID
3154         setsid();
3155 #elif defined(TIOCNOTTY)
3156         {
3157                 int i = open("/dev/tty", O_RDWR);
3158                 if (i != -1) {
3159                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
3160                         close(i);
3161                 }
3162         }
3163 #endif /* HAVE_SETSID */
3164
3165         /* Close fd's 0,1,2. Needed if started by rsh */
3166         close_low_fds();
3167 }
3168
3169
3170 /****************************************************************************
3171 put up a yes/no prompt
3172 ****************************************************************************/
3173 BOOL yesno(char *p)
3174 {
3175   pstring ans;
3176   printf("%s",p);
3177
3178   if (!fgets(ans,sizeof(ans)-1,stdin))
3179     return(False);
3180
3181   if (*ans == 'y' || *ans == 'Y')
3182     return(True);
3183
3184   return(False);
3185 }
3186
3187 /****************************************************************************
3188 read a line from a file with possible \ continuation chars. 
3189 Blanks at the start or end of a line are stripped.
3190 The string will be allocated if s2 is NULL
3191 ****************************************************************************/
3192 char *fgets_slash(char *s2,int maxlen,FILE *f)
3193 {
3194   char *s=s2;
3195   int len = 0;
3196   int c;
3197   BOOL start_of_line = True;
3198
3199   if (feof(f))
3200     return(NULL);
3201
3202   if (!s2)
3203     {
3204       maxlen = MIN(maxlen,8);
3205       s = (char *)Realloc(s,maxlen);
3206     }
3207
3208   if (!s || maxlen < 2) return(NULL);
3209
3210   *s = 0;
3211
3212   while (len < maxlen-1)
3213     {
3214       c = getc(f);
3215       switch (c)
3216         {
3217         case '\r':
3218           break;
3219         case '\n':
3220           while (len > 0 && s[len-1] == ' ')
3221             {
3222               s[--len] = 0;
3223             }
3224           if (len > 0 && s[len-1] == '\\')
3225             {
3226               s[--len] = 0;
3227               start_of_line = True;
3228               break;
3229             }
3230           return(s);
3231         case EOF:
3232           if (len <= 0 && !s2) 
3233             free(s);
3234           return(len>0?s:NULL);
3235         case ' ':
3236           if (start_of_line)
3237             break;
3238         default:
3239           start_of_line = False;
3240           s[len++] = c;
3241           s[len] = 0;
3242         }
3243       if (!s2 && len > maxlen-3)
3244         {
3245           maxlen *= 2;
3246           s = (char *)Realloc(s,maxlen);
3247           if (!s) return(NULL);
3248         }
3249     }
3250   return(s);
3251 }
3252
3253
3254
3255 /****************************************************************************
3256 set the length of a file from a filedescriptor.
3257 Returns 0 on success, -1 on failure.
3258 ****************************************************************************/
3259 int set_filelen(int fd, long len)
3260 {
3261 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3262    extend a file with ftruncate. Provide alternate implementation
3263    for this */
3264
3265 #ifdef HAVE_FTRUNCATE_EXTEND
3266   return ftruncate(fd, len);
3267 #else
3268   struct stat st;
3269   char c = 0;
3270   long currpos = lseek(fd, 0L, SEEK_CUR);
3271
3272   if(currpos < 0)
3273     return -1;
3274   /* Do an fstat to see if the file is longer than
3275      the requested size (call ftruncate),
3276      or shorter, in which case seek to len - 1 and write 1
3277      byte of zero */
3278   if(fstat(fd, &st)<0)
3279     return -1;
3280
3281 #ifdef S_ISFIFO
3282   if (S_ISFIFO(st.st_mode)) return 0;
3283 #endif
3284
3285   if(st.st_size == len)
3286     return 0;
3287   if(st.st_size > len)
3288     return ftruncate(fd, len);
3289
3290   if(lseek(fd, len-1, SEEK_SET) != len -1)
3291     return -1;
3292   if(write(fd, &c, 1)!=1)
3293     return -1;
3294   /* Seek to where we were */
3295   lseek(fd, currpos, SEEK_SET);
3296   return 0;
3297 #endif
3298 }
3299
3300
3301 /****************************************************************************
3302 return the byte checksum of some data
3303 ****************************************************************************/
3304 int byte_checksum(char *buf,int len)
3305 {
3306   unsigned char *p = (unsigned char *)buf;
3307   int ret = 0;
3308   while (len--)
3309     ret += *p++;
3310   return(ret);
3311 }
3312
3313
3314
3315 #ifdef HPUX
3316 /****************************************************************************
3317 this is a version of setbuffer() for those machines that only have setvbuf
3318 ****************************************************************************/
3319  void setbuffer(FILE *f,char *buf,int bufsize)
3320 {
3321   setvbuf(f,buf,_IOFBF,bufsize);
3322 }
3323 #endif
3324
3325
3326 /****************************************************************************
3327 parse out a directory name from a path name. Assumes dos style filenames.
3328 ****************************************************************************/
3329 char *dirname_dos(char *path,char *buf)
3330 {
3331   char *p = strrchr(path,'\\');
3332
3333   if (!p)
3334     pstrcpy(buf,path);
3335   else
3336     {
3337       *p = 0;
3338       pstrcpy(buf,path);
3339       *p = '\\';
3340     }
3341
3342   return(buf);
3343 }
3344
3345
3346 /****************************************************************************
3347 parse out a filename from a path name. Assumes dos style filenames.
3348 ****************************************************************************/
3349 static char *filename_dos(char *path,char *buf)
3350 {
3351   char *p = strrchr(path,'\\');
3352
3353   if (!p)
3354     pstrcpy(buf,path);
3355   else
3356     pstrcpy(buf,p+1);
3357
3358   return(buf);
3359 }
3360
3361
3362
3363 /****************************************************************************
3364 expand a pointer to be a particular size
3365 ****************************************************************************/
3366 void *Realloc(void *p,int size)
3367 {
3368   void *ret=NULL;
3369
3370   if (size == 0) {
3371     if (p) free(p);
3372     DEBUG(5,("Realloc asked for 0 bytes\n"));
3373     return NULL;
3374   }
3375
3376   if (!p)
3377     ret = (void *)malloc(size);
3378   else
3379     ret = (void *)realloc(p,size);
3380
3381   if (!ret)
3382     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3383
3384   return(ret);
3385 }
3386
3387
3388 /****************************************************************************
3389   Signal handler for SIGPIPE (write on a disconnected socket) 
3390 ****************************************************************************/
3391 void Abort(void )
3392 {
3393   DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3394   exit(2);
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     }
3908     nis_freeresult(result);
3909   }
3910
3911   strip_mount_options(&last_value);
3912
3913   DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3914   return last_value;
3915 }
3916 #else /* WITH_NISPLUS_HOME */
3917 static char *automount_lookup(char *user_name)
3918 {
3919   static fstring last_key = "";
3920   static pstring last_value = "";
3921
3922   int nis_error;        /* returned by yp all functions */
3923   char *nis_result;     /* yp_match inits this */
3924   int nis_result_len;  /* and set this */
3925   char *nis_domain;     /* yp_get_default_domain inits this */
3926   char *nis_map = (char *)lp_nis_home_map_name();
3927
3928   if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3929   {
3930     DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3931     return last_value;
3932   }
3933
3934   DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3935
3936   if (!strcmp(user_name, last_key))
3937   {
3938     nis_result = last_value;
3939     nis_result_len = strlen(last_value);
3940     nis_error = 0;
3941   }
3942   else
3943   {
3944     if ((nis_error = yp_match(nis_domain, nis_map,
3945                               user_name, strlen(user_name),
3946                               &nis_result, &nis_result_len)) != 0)
3947     {
3948       DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
3949                yperr_string(nis_error), user_name, nis_map));
3950     }
3951     if (!nis_error && nis_result_len >= sizeof(pstring))
3952     {
3953       nis_result_len = sizeof(pstring)-1;
3954     }
3955     fstrcpy(last_key, user_name);
3956     strncpy(last_value, nis_result, nis_result_len);
3957     last_value[nis_result_len] = '\0';
3958   }
3959
3960   strip_mount_options(&last_value);
3961
3962   DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3963   return last_value;
3964 }
3965 #endif /* WITH_NISPLUS_HOME */
3966 #endif
3967
3968 /*******************************************************************
3969  Patch from jkf@soton.ac.uk
3970  This is Luke's original function with the NIS lookup code
3971  moved out to a separate function.
3972 *******************************************************************/
3973
3974 char *automount_server(char *user_name)
3975 {
3976         static pstring server_name;
3977
3978         /* use the local machine name as the default */
3979         /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3980         pstrcpy(server_name, local_machine);
3981
3982 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3983
3984         if (lp_nis_home_map())
3985         {
3986                 int home_server_len;
3987                 char *automount_value = automount_lookup(user_name);
3988                 home_server_len = strcspn(automount_value,":");
3989                 DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
3990                 if (home_server_len > sizeof(pstring))
3991                 {
3992                         home_server_len = sizeof(pstring);
3993                 }
3994                 strncpy(server_name, automount_value, home_server_len);
3995                 server_name[home_server_len] = '\0';
3996         }
3997 #endif
3998
3999         DEBUG(4,("Home server: %s\n", server_name));
4000
4001         return server_name;
4002 }
4003
4004 /*******************************************************************
4005  Patch from jkf@soton.ac.uk
4006  Added this to implement %p (NIS auto-map version of %H)
4007 *******************************************************************/
4008
4009 char *automount_path(char *user_name)
4010 {
4011         static pstring server_path;
4012
4013         /* use the passwd entry as the default */
4014         /* this will be the default if WITH_AUTOMOUNT is not used or fails */
4015         /* pstrcpy() copes with get_home_dir() returning NULL */
4016         pstrcpy(server_path, get_home_dir(user_name));
4017
4018 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
4019
4020         if (lp_nis_home_map())
4021         {
4022                 char *home_path_start;
4023                 char *automount_value = automount_lookup(user_name);
4024                 home_path_start = strchr(automount_value,':');
4025                 if (home_path_start != NULL)
4026                 {
4027                   DEBUG(5, ("NIS lookup succeeded.  Home path is: %s\n",
4028                         home_path_start?(home_path_start+1):""));
4029                   pstrcpy(server_path, home_path_start+1);
4030                 }
4031         }
4032 #endif
4033
4034         DEBUG(4,("Home server path: %s\n", server_path));
4035
4036         return server_path;
4037 }
4038
4039
4040 /*******************************************************************
4041 sub strings with useful parameters
4042 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4043 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4044 ********************************************************************/
4045 void standard_sub_basic(char *str)
4046 {
4047         char *s, *p;
4048         char pidstr[10];
4049         struct passwd *pass;
4050         char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4051
4052         for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4053         {
4054                 switch (*(p+1))
4055                 {
4056                         case 'G' :
4057                         {
4058                                 if ((pass = Get_Pwnam(username,False))!=NULL)
4059                                 {
4060                                         string_sub(p,"%G",gidtoname(pass->pw_gid));
4061                                 }
4062                                 else
4063                                 {
4064                                         p += 2;
4065                                 }
4066                                 break;
4067                         }
4068                         case 'N' : string_sub(p,"%N", automount_server(username)); break;
4069                         case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4070                         case 'L' : string_sub(p,"%L", local_machine); break;
4071                         case 'M' : string_sub(p,"%M", client_name(Client)); break;
4072                         case 'R' : string_sub(p,"%R", remote_proto); break;
4073                         case 'T' : string_sub(p,"%T", timestring()); break;
4074                         case 'U' : string_sub(p,"%U", username); break;
4075                         case 'a' : string_sub(p,"%a", remote_arch); break;
4076                         case 'd' :
4077                         {
4078                                 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4079                                 string_sub(p,"%d", pidstr);
4080                                 break;
4081                         }
4082                         case 'h' : string_sub(p,"%h", myhostname); break;
4083                         case 'm' : string_sub(p,"%m", remote_machine); break;
4084                         case 'v' : string_sub(p,"%v", VERSION); break;
4085                         case '$' : /* Expand environment variables */
4086                         {
4087                                 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4088                                 fstring envname;
4089                                 char *envval;
4090                                 char *q, *r;
4091                                 int copylen;
4092
4093                                 if (*(p+2) != '(')
4094                                 {
4095                                         p+=2;
4096                                         break;
4097                                 }
4098                                 if ((q = strchr(p,')')) == NULL)
4099                                 {
4100                                         DEBUG(0,("standard_sub_basic: Unterminated environment \
4101                                         variable [%s]\n", p));
4102                                         p+=2;
4103                                         break;
4104                                 }
4105
4106                                 r = p+3;
4107                                 copylen = MIN((q-r),(sizeof(envname)-1));
4108                                 strncpy(envname,r,copylen);
4109                                 envname[copylen] = '\0';
4110
4111                                 if ((envval = getenv(envname)) == NULL)
4112                                 {
4113                                         DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4114                                         envname));
4115                                         p+=2;
4116                                         break;
4117                                 }
4118
4119                                 copylen = MIN((q+1-p),(sizeof(envname)-1));
4120                                 strncpy(envname,p,copylen);
4121                                 envname[copylen] = '\0';
4122                                 string_sub(p,envname,envval);
4123                                 break;
4124                         }
4125                         case '\0': p++; break; /* don't run off end if last character is % */
4126                         default  : p+=2; break;
4127                 }
4128         }
4129         return;
4130 }
4131
4132
4133 /****************************************************************************
4134 do some standard substitutions in a string
4135 ****************************************************************************/
4136 void standard_sub(connection_struct *conn,char *str)
4137 {
4138         char *p, *s, *home;
4139
4140         for (s=str; (p=strchr(s, '%'));s=p) {
4141                 switch (*(p+1)) {
4142                 case 'H': 
4143                         if ((home = get_home_dir(conn->user))) {
4144                                 string_sub(p,"%H",home);
4145                         } else {
4146                                 p += 2;
4147                         }
4148                         break;
4149                         
4150                 case 'P': 
4151                         string_sub(p,"%P",conn->connectpath); 
4152                         break;
4153                         
4154                 case 'S': 
4155                         string_sub(p,"%S",
4156                                    lp_servicename(SNUM(conn))); 
4157                         break;
4158                         
4159                 case 'g': 
4160                         string_sub(p,"%g",
4161                                    gidtoname(conn->gid)); 
4162                         break;
4163                 case 'u': 
4164                         string_sub(p,"%u",conn->user); 
4165                         break;
4166                         
4167                         /* Patch from jkf@soton.ac.uk Left the %N (NIS
4168                          * server name) in standard_sub_basic as it is
4169                          * a feature for logon servers, hence uses the
4170                          * username.  The %p (NIS server path) code is
4171                          * here as it is used instead of the default
4172                          * "path =" string in [homes] and so needs the
4173                          * service name, not the username.  */
4174                 case 'p': 
4175                         string_sub(p,"%p",
4176                                    automount_path(lp_servicename(SNUM(conn)))); 
4177                         break;
4178                 case '\0': 
4179                         p++; 
4180                         break; /* don't run off the end of the string 
4181                                 */
4182                         
4183                 default: p+=2; 
4184                         break;
4185                 }
4186         }
4187         
4188         standard_sub_basic(str);
4189 }
4190
4191
4192
4193 /*******************************************************************
4194 are two IPs on the same subnet?
4195 ********************************************************************/
4196 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4197 {
4198   uint32 net1,net2,nmask;
4199
4200   nmask = ntohl(mask.s_addr);
4201   net1  = ntohl(ip1.s_addr);
4202   net2  = ntohl(ip2.s_addr);
4203             
4204   return((net1 & nmask) == (net2 & nmask));
4205 }
4206
4207
4208 /*******************************************************************
4209 write a string in unicoode format
4210 ********************************************************************/
4211 int PutUniCode(char *dst,char *src)
4212 {
4213   int ret = 0;
4214   while (*src) {
4215     dst[ret++] = src[0];
4216     dst[ret++] = 0;    
4217     src++;
4218   }
4219   dst[ret++]=0;
4220   dst[ret++]=0;
4221   return(ret);
4222 }
4223
4224 /****************************************************************************
4225 a wrapper for gethostbyname() that tries with all lower and all upper case 
4226 if the initial name fails
4227 ****************************************************************************/
4228 struct hostent *Get_Hostbyname(char *name)
4229 {
4230   char *name2 = strdup(name);
4231   struct hostent *ret;
4232
4233   if (!name2)
4234     {
4235       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4236       exit(0);
4237     }
4238
4239    
4240   /* 
4241    * This next test is redundent and causes some systems (with
4242    * broken isalnum() calls) problems.
4243    * JRA.
4244    */
4245
4246 #if 0
4247   if (!isalnum(*name2))
4248     {
4249       free(name2);
4250       return(NULL);
4251     }
4252 #endif /* 0 */
4253
4254   ret = sys_gethostbyname(name2);
4255   if (ret != NULL)
4256     {
4257       free(name2);
4258       return(ret);
4259     }
4260
4261   /* try with all lowercase */
4262   strlower(name2);
4263   ret = sys_gethostbyname(name2);
4264   if (ret != NULL)
4265     {
4266       free(name2);
4267       return(ret);
4268     }
4269
4270   /* try with all uppercase */
4271   strupper(name2);
4272   ret = sys_gethostbyname(name2);
4273   if (ret != NULL)
4274     {
4275       free(name2);
4276       return(ret);
4277     }
4278   
4279   /* nothing works :-( */
4280   free(name2);
4281   return(NULL);
4282 }
4283
4284
4285 /****************************************************************************
4286 check if a process exists. Does this work on all unixes?
4287 ****************************************************************************/
4288 BOOL process_exists(int pid)
4289 {
4290         return(kill(pid,0) == 0 || errno != ESRCH);
4291 }
4292
4293
4294 /*******************************************************************
4295 turn a uid into a user name
4296 ********************************************************************/
4297 char *uidtoname(int uid)
4298 {
4299   static char name[40];
4300   struct passwd *pass = getpwuid(uid);
4301   if (pass) return(pass->pw_name);
4302   slprintf(name, sizeof(name) - 1, "%d",uid);
4303   return(name);
4304 }
4305
4306 /*******************************************************************
4307 turn a gid into a group name
4308 ********************************************************************/
4309 char *gidtoname(int gid)
4310 {
4311         static char name[40];
4312         struct group *grp = getgrgid(gid);
4313         if (grp) return(grp->gr_name);
4314         slprintf(name,sizeof(name) - 1, "%d",gid);
4315         return(name);
4316 }
4317
4318 /*******************************************************************
4319 something really nasty happened - panic!
4320 ********************************************************************/
4321 void smb_panic(char *why)
4322 {
4323         char *cmd = lp_panic_action();
4324         if (cmd && *cmd) {
4325                 system(cmd);
4326         }
4327         DEBUG(0,("PANIC: %s\n", why));
4328         exit(1);
4329 }
4330
4331
4332 /*******************************************************************
4333 a readdir wrapper which just returns the file name
4334 also return the inode number if requested
4335 ********************************************************************/
4336 char *readdirname(void *p)
4337 {
4338         struct dirent *ptr;
4339         char *dname;
4340
4341         if (!p) return(NULL);
4342   
4343         ptr = (struct dirent *)readdir(p);
4344         if (!ptr) return(NULL);
4345
4346         dname = ptr->d_name;
4347
4348 #ifdef NEXT2
4349         if (telldir(p) < 0) return(NULL);
4350 #endif
4351
4352 #ifdef HAVE_BROKEN_READDIR
4353         /* using /usr/ucb/cc is BAD */
4354         dname = dname - 2;
4355 #endif
4356
4357         {
4358                 static pstring buf;
4359                 memcpy(buf, dname, NAMLEN(ptr)+1);
4360                 unix_to_dos(buf, True);
4361                 dname = buf;
4362         }
4363
4364         return(dname);
4365 }
4366
4367 /*******************************************************************
4368  Utility function used to decide if the last component 
4369  of a path matches a (possibly wildcarded) entry in a namelist.
4370 ********************************************************************/
4371
4372 BOOL is_in_path(char *name, name_compare_entry *namelist)
4373 {
4374   pstring last_component;
4375   char *p;
4376
4377   DEBUG(8, ("is_in_path: %s\n", name));
4378
4379   /* if we have no list it's obviously not in the path */
4380   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
4381   {
4382     DEBUG(8,("is_in_path: no name list.\n"));
4383     return False;
4384   }
4385
4386   /* Get the last component of the unix name. */
4387   p = strrchr(name, '/');
4388   strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4389   last_component[sizeof(last_component)-1] = '\0'; 
4390
4391   for(; namelist->name != NULL; namelist++)
4392   {
4393     if(namelist->is_wild)
4394     {
4395       /* 
4396        * Look for a wildcard match. Use the old
4397        * 'unix style' mask match, rather than the
4398        * new NT one.
4399        */
4400       if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4401       {
4402          DEBUG(8,("is_in_path: mask match succeeded\n"));
4403          return True;
4404       }
4405     }
4406     else
4407     {
4408       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4409        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4410         {
4411          DEBUG(8,("is_in_path: match succeeded\n"));
4412          return True;
4413         }
4414     }
4415   }
4416   DEBUG(8,("is_in_path: match not found\n"));
4417  
4418   return False;
4419 }
4420
4421 /*******************************************************************
4422  Strip a '/' separated list into an array of 
4423  name_compare_enties structures suitable for 
4424  passing to is_in_path(). We do this for
4425  speed so we can pre-parse all the names in the list 
4426  and don't do it for each call to is_in_path().
4427  namelist is modified here and is assumed to be 
4428  a copy owned by the caller.
4429  We also check if the entry contains a wildcard to
4430  remove a potentially expensive call to mask_match
4431  if possible.
4432 ********************************************************************/
4433  
4434 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4435 {
4436   char *name_end;
4437   char *nameptr = namelist;
4438   int num_entries = 0;
4439   int i;
4440
4441   (*ppname_array) = NULL;
4442
4443   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
4444     return;
4445
4446   /* We need to make two passes over the string. The
4447      first to count the number of elements, the second
4448      to split it.
4449    */
4450   while(*nameptr) 
4451     {
4452       if ( *nameptr == '/' ) 
4453         {
4454           /* cope with multiple (useless) /s) */
4455           nameptr++;
4456           continue;
4457         }
4458       /* find the next / */
4459       name_end = strchr(nameptr, '/');
4460
4461       /* oops - the last check for a / didn't find one. */
4462       if (name_end == NULL)
4463         break;
4464
4465       /* next segment please */
4466       nameptr = name_end + 1;
4467       num_entries++;
4468     }
4469
4470   if(num_entries == 0)
4471     return;
4472
4473   if(( (*ppname_array) = (name_compare_entry *)malloc( 
4474            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4475         {
4476     DEBUG(0,("set_namearray: malloc fail\n"));
4477     return;
4478         }
4479
4480   /* Now copy out the names */
4481   nameptr = namelist;
4482   i = 0;
4483   while(*nameptr)
4484              {
4485       if ( *nameptr == '/' ) 
4486       {
4487           /* cope with multiple (useless) /s) */
4488           nameptr++;
4489           continue;
4490       }
4491       /* find the next / */
4492       if ((name_end = strchr(nameptr, '/')) != NULL) 
4493       {
4494           *name_end = 0;
4495          }
4496
4497       /* oops - the last check for a / didn't find one. */
4498       if(name_end == NULL) 
4499         break;
4500
4501       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4502                                 (strchr( nameptr, '*')!=NULL));
4503       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4504       {
4505         DEBUG(0,("set_namearray: malloc fail (1)\n"));
4506         return;
4507       }
4508
4509       /* next segment please */
4510       nameptr = name_end + 1;
4511       i++;
4512     }
4513   
4514   (*ppname_array)[i].name = NULL;
4515
4516   return;
4517 }
4518
4519 /****************************************************************************
4520 routine to free a namearray.
4521 ****************************************************************************/
4522
4523 void free_namearray(name_compare_entry *name_array)
4524 {
4525   if(name_array == 0)
4526     return;
4527
4528   if(name_array->name != NULL)
4529     free(name_array->name);
4530
4531   free((char *)name_array);
4532 }
4533
4534 /****************************************************************************
4535 routine to do file locking
4536 ****************************************************************************/
4537 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4538 {
4539 #if HAVE_FCNTL_LOCK
4540   struct flock lock;
4541   int ret;
4542
4543   /*
4544    * FIXME.
4545    * NB - this code will need re-writing to cope with large (64bit)
4546    * lock requests. JRA.
4547    */
4548
4549   if(lp_ole_locking_compat()) {
4550     uint32 mask = 0xC0000000;
4551
4552     /* make sure the count is reasonable, we might kill the lockd otherwise */
4553     count &= ~mask;
4554
4555     /* the offset is often strange - remove 2 of its bits if either of
4556        the top two bits are set. Shift the top ones by two bits. This
4557        still allows OLE2 apps to operate, but should stop lockd from
4558        dieing */
4559     if ((offset & mask) != 0)
4560       offset = (offset & ~mask) | ((offset & mask) >> 2);
4561   } else {
4562     uint32 mask = ((unsigned)1<<31);
4563     int32 s_count = (int32) count; /* Signed count. */
4564     int32 s_offset = (int32)offset; /* Signed offset. */
4565
4566     /* interpret negative counts as large numbers */
4567     if (s_count < 0)
4568       s_count &= ~mask;
4569
4570     /* no negative offsets */
4571     if(s_offset < 0)
4572       s_offset &= ~mask;
4573
4574     /* count + offset must be in range */
4575     while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
4576     {
4577       s_offset &= ~mask;
4578       mask = mask >> 1;
4579     }
4580
4581     offset = (uint32)s_offset;
4582     count = (uint32)s_count;
4583   }
4584
4585
4586   DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4587
4588   lock.l_type = type;
4589   lock.l_whence = SEEK_SET;
4590   lock.l_start = (int)offset;
4591   lock.l_len = (int)count;
4592   lock.l_pid = 0;
4593
4594   errno = 0;
4595
4596   ret = fcntl(fd,op,&lock);
4597
4598   if (errno != 0)
4599     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4600
4601   /* a lock query */
4602   if (op == F_GETLK)
4603     {
4604       if ((ret != -1) &&
4605           (lock.l_type != F_UNLCK) && 
4606           (lock.l_pid != 0) && 
4607           (lock.l_pid != getpid()))
4608         {
4609           DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4610           return(True);
4611         }
4612
4613       /* it must be not locked or locked by me */
4614       return(False);
4615     }
4616
4617   /* a lock set or unset */
4618   if (ret == -1)
4619     {
4620       DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4621                offset,count,op,type,strerror(errno)));
4622
4623       /* perhaps it doesn't support this sort of locking?? */
4624       if (errno == EINVAL)
4625         {
4626           DEBUG(3,("locking not supported? returning True\n"));
4627           return(True);
4628         }
4629
4630       return(False);
4631     }
4632
4633   /* everything went OK */
4634   DEBUG(8,("Lock call successful\n"));
4635
4636   return(True);
4637 #else
4638   return(False);
4639 #endif
4640 }
4641
4642 /*******************************************************************
4643 lock a file - returning a open file descriptor or -1 on failure
4644 The timeout is in seconds. 0 means no timeout
4645 ********************************************************************/
4646 int file_lock(char *name,int timeout)
4647 {  
4648   int fd = open(name,O_RDWR|O_CREAT,0666);
4649   time_t t=0;
4650   if (fd < 0) return(-1);
4651
4652 #if HAVE_FCNTL_LOCK
4653   if (timeout) t = time(NULL);
4654   while (!timeout || (time(NULL)-t < timeout)) {
4655     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);    
4656     msleep(LOCK_RETRY_TIMEOUT);
4657   }
4658   return(-1);
4659 #else
4660   return(fd);
4661 #endif
4662 }
4663
4664 /*******************************************************************
4665 unlock a file locked by file_lock
4666 ********************************************************************/
4667 void file_unlock(int fd)
4668 {
4669   if (fd<0) return;
4670 #if HAVE_FCNTL_LOCK
4671   fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4672 #endif
4673   close(fd);
4674 }
4675
4676 /*******************************************************************
4677 is the name specified one of my netbios names
4678 returns true is it is equal, false otherwise
4679 ********************************************************************/
4680 BOOL is_myname(char *s)
4681 {
4682   int n;
4683   BOOL ret = False;
4684
4685   for (n=0; my_netbios_names[n]; n++) {
4686     if (strequal(my_netbios_names[n], s))
4687       ret=True;
4688   }
4689   DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4690   return(ret);
4691 }
4692
4693 /*******************************************************************
4694 set the horrid remote_arch string based on an enum.
4695 ********************************************************************/
4696 void set_remote_arch(enum remote_arch_types type)
4697 {
4698   ra_type = type;
4699   switch( type )
4700   {
4701   case RA_WFWG:
4702     fstrcpy(remote_arch, "WfWg");
4703     return;
4704   case RA_OS2:
4705     fstrcpy(remote_arch, "OS2");
4706     return;
4707   case RA_WIN95:
4708     fstrcpy(remote_arch, "Win95");
4709     return;
4710   case RA_WINNT:
4711     fstrcpy(remote_arch, "WinNT");
4712     return;
4713   case RA_SAMBA:
4714     fstrcpy(remote_arch,"Samba");
4715     return;
4716   default:
4717     ra_type = RA_UNKNOWN;
4718     fstrcpy(remote_arch, "UNKNOWN");
4719     break;
4720   }
4721 }
4722
4723 /*******************************************************************
4724  Get the remote_arch type.
4725 ********************************************************************/
4726 enum remote_arch_types get_remote_arch(void)
4727 {
4728   return ra_type;
4729 }
4730
4731
4732 /*******************************************************************
4733 skip past some unicode strings in a buffer
4734 ********************************************************************/
4735 char *skip_unicode_string(char *buf,int n)
4736 {
4737   while (n--)
4738   {
4739     while (*buf)
4740       buf += 2;
4741     buf += 2;
4742   }
4743   return(buf);
4744 }
4745
4746 /*******************************************************************
4747 Return a ascii version of a unicode string
4748 Hack alert: uses fixed buffer(s) and only handles ascii strings
4749 ********************************************************************/
4750 #define MAXUNI 1024
4751 char *unistrn2(uint16 *buf, int len)
4752 {
4753         static char lbufs[8][MAXUNI];
4754         static int nexti;
4755         char *lbuf = lbufs[nexti];
4756         char *p;
4757
4758         nexti = (nexti+1)%8;
4759
4760         DEBUG(10, ("unistrn2: "));
4761
4762         for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4763         {
4764                 DEBUG(10, ("%4x ", *buf));
4765                 *p = *buf;
4766         }
4767
4768         DEBUG(10,("\n"));
4769
4770         *p = 0;
4771         return lbuf;
4772 }
4773
4774 /*******************************************************************
4775 Return a ascii version of a unicode string
4776 Hack alert: uses fixed buffer(s) and only handles ascii strings
4777 ********************************************************************/
4778 #define MAXUNI 1024
4779 char *unistr2(uint16 *buf)
4780 {
4781         static char lbufs[8][MAXUNI];
4782         static int nexti;
4783         char *lbuf = lbufs[nexti];
4784         char *p;
4785
4786         nexti = (nexti+1)%8;
4787
4788         DEBUG(10, ("unistr2: "));
4789
4790         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4791         {
4792                 DEBUG(10, ("%4x ", *buf));
4793                 *p = *buf;
4794         }
4795
4796         DEBUG(10,("\n"));
4797
4798         *p = 0;
4799         return lbuf;
4800 }
4801
4802 /*******************************************************************
4803 create a null-terminated unicode string from a null-terminated ascii string.
4804 return number of unicode chars copied, excluding the null character.
4805
4806 only handles ascii strings
4807 ********************************************************************/
4808 #define MAXUNI 1024
4809 int struni2(uint16 *p, char *buf)
4810 {
4811         int len = 0;
4812
4813         if (p == NULL) return 0;
4814
4815         DEBUG(10, ("struni2: "));
4816
4817         if (buf != NULL)
4818         {
4819                 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4820                 {
4821                         DEBUG(10, ("%2x ", *buf));
4822                         *p = *buf;
4823                 }
4824
4825                 DEBUG(10,("\n"));
4826         }
4827
4828         *p = 0;
4829
4830         return len;
4831 }
4832
4833 /*******************************************************************
4834 Return a ascii version of a unicode string
4835 Hack alert: uses fixed buffer(s) and only handles ascii strings
4836 ********************************************************************/
4837 #define MAXUNI 1024
4838 char *unistr(char *buf)
4839 {
4840         static char lbufs[8][MAXUNI];
4841         static int nexti;
4842         char *lbuf = lbufs[nexti];
4843         char *p;
4844
4845         nexti = (nexti+1)%8;
4846
4847         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4848         {
4849                 *p = *buf;
4850         }
4851         *p = 0;
4852         return lbuf;
4853 }
4854
4855 /*******************************************************************
4856 strncpy for unicode strings
4857 ********************************************************************/
4858 int unistrncpy(char *dst, char *src, int len)
4859 {
4860         int num_wchars = 0;
4861
4862         while (*src && len > 0)
4863         {
4864                 *dst++ = *src++;
4865                 *dst++ = *src++;
4866                 len--;
4867                 num_wchars++;
4868         }
4869         *dst++ = 0;
4870         *dst++ = 0;
4871
4872         return num_wchars;
4873 }
4874
4875
4876 /*******************************************************************
4877 strcpy for unicode strings.  returns length (in num of wide chars)
4878 ********************************************************************/
4879 int unistrcpy(char *dst, char *src)
4880 {
4881         int num_wchars = 0;
4882
4883         while (*src)
4884         {
4885                 *dst++ = *src++;
4886                 *dst++ = *src++;
4887                 num_wchars++;
4888         }
4889         *dst++ = 0;
4890         *dst++ = 0;
4891
4892         return num_wchars;
4893 }
4894
4895 /*******************************************************************
4896 safe string copy into a known length string. maxlength does not
4897 include the terminating zero.
4898 ********************************************************************/
4899 char *safe_strcpy(char *dest, char *src, int maxlength)
4900 {
4901     int len;
4902
4903     if (!dest) {
4904         DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4905         return NULL;
4906     }
4907
4908     if (!src) {
4909         *dest = 0;
4910         return dest;
4911     }  
4912
4913     len = strlen(src);
4914
4915     if (len > maxlength) {
4916             DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4917                      len-maxlength, src));
4918             len = maxlength;
4919     }
4920       
4921     memcpy(dest, src, len);
4922     dest[len] = 0;
4923     return dest;
4924 }  
4925
4926 /*******************************************************************
4927 safe string cat into a string. maxlength does not
4928 include the terminating zero.
4929 ********************************************************************/
4930 char *safe_strcat(char *dest, char *src, int maxlength)
4931 {
4932     int src_len, dest_len;
4933
4934     if (!dest) {
4935         DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4936         return NULL;
4937     }
4938
4939     if (!src) {
4940         return dest;
4941     }  
4942
4943     src_len = strlen(src);
4944     dest_len = strlen(dest);
4945
4946     if (src_len + dest_len > maxlength) {
4947             DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4948                      src_len + dest_len - maxlength, src));
4949             src_len = maxlength - dest_len;
4950     }
4951       
4952     memcpy(&dest[dest_len], src, src_len);
4953     dest[dest_len + src_len] = 0;
4954     return dest;
4955 }
4956
4957 /*******************************************************************
4958 align a pointer to a multiple of 4 bytes
4959 ********************************************************************/
4960 char *align4(char *q, char *base)
4961 {
4962         if ((q - base) & 3)
4963         {
4964                 q += 4 - ((q - base) & 3);
4965         }
4966         return q;
4967 }
4968
4969 /*******************************************************************
4970 align a pointer to a multiple of 2 bytes
4971 ********************************************************************/
4972 char *align2(char *q, char *base)
4973 {
4974         if ((q - base) & 1)
4975         {
4976                 q++;
4977         }
4978         return q;
4979 }
4980
4981 /*******************************************************************
4982 align a pointer to a multiple of align_offset bytes.  looks like it
4983 will work for offsets of 0, 2 and 4...
4984 ********************************************************************/
4985 char *align_offset(char *q, char *base, int align_offset_len)
4986 {
4987         int mod = ((q - base) & (align_offset_len-1));
4988         if (align_offset_len != 0 && mod != 0)
4989         {
4990                 q += align_offset_len - mod;
4991         }
4992         return q;
4993 }
4994
4995 void print_asc(int level, unsigned char *buf,int len)
4996 {
4997         int i;
4998         for (i=0;i<len;i++)
4999                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
5000 }
5001
5002 void dump_data(int level,char *buf1,int len)
5003 {
5004   unsigned char *buf = (unsigned char *)buf1;
5005   int i=0;
5006   if (len<=0) return;
5007
5008   DEBUG(level,("[%03X] ",i));
5009   for (i=0;i<len;) {
5010     DEBUG(level,("%02X ",(int)buf[i]));
5011     i++;
5012     if (i%8 == 0) DEBUG(level,(" "));
5013     if (i%16 == 0) {      
5014       print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
5015       print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
5016       if (i<len) DEBUG(level,("[%03X] ",i));
5017     }
5018   }
5019   if (i%16) {
5020     int n;
5021
5022     n = 16 - (i%16);
5023     DEBUG(level,(" "));
5024     if (n>8) DEBUG(level,(" "));
5025     while (n--) DEBUG(level,("   "));
5026
5027     n = MIN(8,i%16);
5028     print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
5029     n = (i%16) - n;
5030     if (n>0) print_asc(level,&buf[i-n],n); 
5031     DEBUG(level,("\n"));    
5032   }
5033 }
5034
5035 char *tab_depth(int depth)
5036 {
5037         static pstring spaces;
5038         memset(spaces, ' ', depth * 4);
5039         spaces[depth * 4] = 0;
5040         return spaces;
5041 }
5042
5043 /*****************************************************************
5044  Convert a SID to an ascii string.
5045 *****************************************************************/
5046
5047 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
5048 {
5049   char subauth[16];
5050   int i;
5051   /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5052   uint32 ia = (sid->id_auth[5]) +
5053               (sid->id_auth[4] << 8 ) +
5054               (sid->id_auth[3] << 16) +
5055               (sid->id_auth[2] << 24);
5056
5057   slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
5058
5059   for (i = 0; i < sid->num_auths; i++)
5060   {
5061     slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
5062     pstrcat(sidstr_out, subauth);
5063   }
5064
5065   DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
5066   return sidstr_out;
5067 }
5068
5069 /*****************************************************************
5070  Convert a string to a SID. Returns True on success, False on fail.
5071 *****************************************************************/  
5072    
5073 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
5074 {
5075   pstring tok;
5076   char *p = sidstr;
5077   /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5078   uint32 ia;
5079
5080   memset((char *)sidout, '\0', sizeof(DOM_SID));
5081
5082   if(StrnCaseCmp( sidstr, "S-", 2)) {
5083     DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
5084     return False;
5085   }
5086
5087   p += 2;
5088   if(!next_token(&p, tok, "-")) {
5089     DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5090     return False;
5091   }
5092
5093   /* Get the revision number. */
5094   sidout->sid_rev_num = atoi(tok);
5095
5096   if(!next_token(&p, tok, "-")) {
5097     DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5098     return False;
5099   }
5100
5101   /* identauth in decimal should be <  2^32 */
5102   ia = atoi(tok);
5103
5104   /* NOTE - the ia value is in big-endian format. */
5105   sidout->id_auth[0] = 0;
5106   sidout->id_auth[1] = 0;
5107   sidout->id_auth[2] = (ia & 0xff000000) >> 24;
5108   sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
5109   sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
5110   sidout->id_auth[5] = (ia & 0x000000ff);
5111
5112   sidout->num_auths = 0;
5113
5114   while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) {
5115     /* 
5116      * NOTE - the subauths are in native machine-endian format. They
5117      * are converted to little-endian when linearized onto the wire.
5118      */
5119     sidout->sub_auths[sidout->num_auths++] = atoi(tok);
5120   }
5121
5122   DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
5123
5124   return True;
5125 }
5126
5127 /*****************************************************************************
5128  * Provide a checksum on a string
5129  *
5130  *  Input:  s - the nul-terminated character string for which the checksum
5131  *              will be calculated.
5132  *
5133  *  Output: The checksum value calculated for s.
5134  *
5135  * ****************************************************************************
5136  */
5137 int str_checksum(char *s)
5138 {
5139         int res = 0;
5140         int c;
5141         int i=0;
5142         
5143         while(*s) {
5144                 c = *s;
5145                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
5146                 s++;
5147                 i++;
5148         }
5149         return(res);
5150 } /* str_checksum */
5151
5152
5153
5154 /*****************************************************************
5155 zero a memory area then free it. Used to catch bugs faster
5156 *****************************************************************/  
5157 void zero_free(void *p, int size)
5158 {
5159         memset(p, 0, size);
5160         free(p);
5161 }