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