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