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