a048c8b3a7555c67048e7cc252aafc44cce5035f
[samba.git] / source3 / lib / util.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Samba utility functions
5    Copyright (C) Andrew Tridgell 1992-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 pstring scope = "";
25
26 int DEBUGLEVEL = 1;
27
28 BOOL passive = False;
29
30 int Protocol = PROTOCOL_COREPLUS;
31
32 /* a default finfo structure to ensure all fields are sensible */
33 file_info def_finfo = {-1,0,0,0,0,0,0,""};
34
35 /* these are some file handles where debug info will be stored */
36 FILE *dbf = NULL;
37
38 /* the client file descriptor */
39 int Client = -1;
40
41 /* the last IP received from */
42 struct in_addr lastip;
43
44 /* the last port received from */
45 int lastport=0;
46
47 /* this is used by the chaining code */
48 int chain_size = 0;
49
50 int trans_num = 0;
51
52 /*
53    case handling on filenames 
54 */
55 int case_default = CASE_LOWER;
56
57 pstring debugf = "";
58 int syslog_level;
59
60 /* the following control case operations - they are put here so the
61    client can link easily */
62 BOOL case_sensitive;
63 BOOL case_preserve;
64 BOOL use_mangled_map = False;
65 BOOL short_case_preserve;
66 BOOL case_mangle;
67
68 fstring remote_machine="";
69 fstring local_machine="";
70 fstring remote_arch="UNKNOWN";
71 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   while (*s && *t && toupper(*s) == toupper(*t))
812   {
813     s++; t++;
814   }
815
816   return(toupper(*s) - toupper(*t));
817 }
818
819 /*******************************************************************
820   case insensitive string compararison, length limited
821 ********************************************************************/
822 int StrnCaseCmp(const char *s, const char *t, int n)
823 {
824   /* compare until we run out of string, either t or s, or chars */
825   /* We *must* use toupper rather than tolower here due to the
826      asynchronous upper to lower mapping.
827    */
828   while (n-- && *s && *t && toupper(*s) == toupper(*t))
829   {
830     s++; t++;
831   }
832
833   /* not run out of chars - strings are different lengths */
834   if (n) return(toupper(*s) - toupper(*t));
835
836   /* identical up to where we run out of chars, and strings are same length */
837   return(0);
838 }
839
840 /*******************************************************************
841   compare 2 strings 
842 ********************************************************************/
843 BOOL strequal(const char *s1, const char *s2)
844 {
845   if (s1 == s2) return(True);
846   if (!s1 || !s2) return(False);
847   
848   return(StrCaseCmp(s1,s2)==0);
849 }
850
851 /*******************************************************************
852   compare 2 strings up to and including the nth char.
853   ******************************************************************/
854 BOOL strnequal(const char *s1,const char *s2,int n)
855 {
856   if (s1 == s2) return(True);
857   if (!s1 || !s2 || !n) return(False);
858   
859   return(StrnCaseCmp(s1,s2,n)==0);
860 }
861
862 /*******************************************************************
863   compare 2 strings (case sensitive)
864 ********************************************************************/
865 BOOL strcsequal(char *s1,char *s2)
866 {
867   if (s1 == s2) return(True);
868   if (!s1 || !s2) return(False);
869   
870   return(strcmp(s1,s2)==0);
871 }
872
873
874 /*******************************************************************
875   convert a string to lower case
876 ********************************************************************/
877 void strlower(char *s)
878 {
879   while (*s)
880     {
881 #ifdef KANJI
882         if (is_shift_jis (*s)) {
883             s += 2;
884         } else if (is_kana (*s)) {
885             s++;
886         } else {
887             if (isupper(*s))
888                 *s = tolower(*s);
889             s++;
890         }
891 #else
892       if (isupper(*s))
893           *s = tolower(*s);
894       s++;
895 #endif /* KANJI */
896     }
897 }
898
899 /*******************************************************************
900   convert a string to upper case
901 ********************************************************************/
902 void strupper(char *s)
903 {
904   while (*s)
905     {
906 #ifdef KANJI
907         if (is_shift_jis (*s)) {
908             s += 2;
909         } else if (is_kana (*s)) {
910             s++;
911         } else {
912             if (islower(*s))
913                 *s = toupper(*s);
914             s++;
915         }
916 #else
917       if (islower(*s))
918         *s = toupper(*s);
919       s++;
920 #endif
921     }
922 }
923
924 /*******************************************************************
925   convert a string to "normal" form
926 ********************************************************************/
927 void strnorm(char *s)
928 {
929   if (case_default == CASE_UPPER)
930     strupper(s);
931   else
932     strlower(s);
933 }
934
935 /*******************************************************************
936 check if a string is in "normal" case
937 ********************************************************************/
938 BOOL strisnormal(char *s)
939 {
940   if (case_default == CASE_UPPER)
941     return(!strhaslower(s));
942
943   return(!strhasupper(s));
944 }
945
946
947 /****************************************************************************
948   string replace
949 ****************************************************************************/
950 void string_replace(char *s,char oldc,char newc)
951 {
952   while (*s)
953     {
954 #ifdef KANJI
955         if (is_shift_jis (*s)) {
956             s += 2;
957         } else if (is_kana (*s)) {
958             s++;
959         } else {
960             if (oldc == *s)
961                 *s = newc;
962             s++;
963         }
964 #else
965       if (oldc == *s)
966         *s = newc;
967       s++;
968 #endif /* KANJI */
969     }
970 }
971
972 /****************************************************************************
973   make a file into unix format
974 ****************************************************************************/
975 void unix_format(char *fname)
976 {
977   pstring namecopy;
978   string_replace(fname,'\\','/');
979
980   if (*fname == '/')
981     {
982       strcpy(namecopy,fname);
983       strcpy(fname,".");
984       strcat(fname,namecopy);
985     }  
986 }
987
988 /****************************************************************************
989   make a file into dos format
990 ****************************************************************************/
991 void dos_format(char *fname)
992 {
993   string_replace(fname,'/','\\');
994 }
995
996
997 /*******************************************************************
998   show a smb message structure
999 ********************************************************************/
1000 void show_msg(char *buf)
1001 {
1002   int i;
1003   int j;
1004   int bcc=0;
1005   if (DEBUGLEVEL < 5)
1006     return;
1007
1008   DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1009           smb_len(buf),
1010           (int)CVAL(buf,smb_com),
1011           (int)CVAL(buf,smb_rcls),
1012           (int)CVAL(buf,smb_reh),
1013           (int)SVAL(buf,smb_err),
1014           (int)CVAL(buf,smb_flg),
1015           (int)SVAL(buf,smb_flg2)));
1016   DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1017           (int)SVAL(buf,smb_tid),
1018           (int)SVAL(buf,smb_pid),
1019           (int)SVAL(buf,smb_uid),
1020           (int)SVAL(buf,smb_mid),
1021           (int)CVAL(buf,smb_wct)));
1022   for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1023     DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1024           SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1025   bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1026   DEBUG(5,("smb_bcc=%d\n",bcc));
1027   if (DEBUGLEVEL < 10)
1028     return;
1029   for (i = 0; i < MIN(bcc, 256); i += 16)
1030   {
1031     for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1032     {
1033
1034       DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1035       if (j == 7) DEBUG(10, ("  "));
1036
1037     }
1038     DEBUG(10,("  "));  
1039
1040     for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1041     {
1042       unsigned char c = CVAL(smb_buf(buf),i+j);
1043       if (c < 32 || c > 128) c = '.';
1044       DEBUG(10,("%c",c));
1045
1046       if (j == 7) DEBUG(10, ("  "));
1047     }
1048
1049     DEBUG(10,("\n"));  
1050   }
1051 }
1052
1053 /*******************************************************************
1054   return the length of an smb packet
1055 ********************************************************************/
1056 int smb_len(char *buf)
1057 {
1058   return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1059 }
1060
1061 /*******************************************************************
1062   set the length of an smb packet
1063 ********************************************************************/
1064 void _smb_setlen(char *buf,int len)
1065 {
1066   buf[0] = 0;
1067   buf[1] = (len&0x10000)>>16;
1068   buf[2] = (len&0xFF00)>>8;
1069   buf[3] = len&0xFF;
1070 }
1071
1072 /*******************************************************************
1073   set the length and marker of an smb packet
1074 ********************************************************************/
1075 void smb_setlen(char *buf,int len)
1076 {
1077   _smb_setlen(buf,len);
1078
1079   CVAL(buf,4) = 0xFF;
1080   CVAL(buf,5) = 'S';
1081   CVAL(buf,6) = 'M';
1082   CVAL(buf,7) = 'B';
1083 }
1084
1085 /*******************************************************************
1086   setup the word count and byte count for a smb message
1087 ********************************************************************/
1088 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1089 {
1090   if (zero)
1091     bzero(buf + smb_size,num_words*2 + num_bytes);
1092   CVAL(buf,smb_wct) = num_words;
1093   SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
1094   smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1095   return (smb_size + num_words*2 + num_bytes);
1096 }
1097
1098 /*******************************************************************
1099 return the number of smb words
1100 ********************************************************************/
1101 int smb_numwords(char *buf)
1102 {
1103   return (CVAL(buf,smb_wct));
1104 }
1105
1106 /*******************************************************************
1107 return the size of the smb_buf region of a message
1108 ********************************************************************/
1109 int smb_buflen(char *buf)
1110 {
1111   return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1112 }
1113
1114 /*******************************************************************
1115   return a pointer to the smb_buf data area
1116 ********************************************************************/
1117 int smb_buf_ofs(char *buf)
1118 {
1119   return (smb_size + CVAL(buf,smb_wct)*2);
1120 }
1121
1122 /*******************************************************************
1123   return a pointer to the smb_buf data area
1124 ********************************************************************/
1125 char *smb_buf(char *buf)
1126 {
1127   return (buf + smb_buf_ofs(buf));
1128 }
1129
1130 /*******************************************************************
1131 return the SMB offset into an SMB buffer
1132 ********************************************************************/
1133 int smb_offset(char *p,char *buf)
1134 {
1135   return(PTR_DIFF(p,buf+4) + chain_size);
1136 }
1137
1138
1139 /*******************************************************************
1140 skip past some strings in a buffer
1141 ********************************************************************/
1142 char *skip_string(char *buf,int n)
1143 {
1144   while (n--)
1145     buf += strlen(buf) + 1;
1146   return(buf);
1147 }
1148
1149 /*******************************************************************
1150 trim the specified elements off the front and back of a string
1151 ********************************************************************/
1152 BOOL trim_string(char *s,char *front,char *back)
1153 {
1154   BOOL ret = False;
1155   while (front && *front && strncmp(s,front,strlen(front)) == 0)
1156     {
1157       char *p = s;
1158       ret = True;
1159       while (1)
1160         {
1161           if (!(*p = p[strlen(front)]))
1162             break;
1163           p++;
1164         }
1165     }
1166   while (back && *back && strlen(s) >= strlen(back) && 
1167          (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
1168     {
1169       ret = True;
1170       s[strlen(s)-strlen(back)] = 0;
1171     }
1172   return(ret);
1173 }
1174
1175
1176 /*******************************************************************
1177 reduce a file name, removing .. elements.
1178 ********************************************************************/
1179 void dos_clean_name(char *s)
1180 {
1181   char *p=NULL;
1182
1183   DEBUG(3,("dos_clean_name [%s]\n",s));
1184
1185   /* remove any double slashes */
1186   string_sub(s, "\\\\", "\\");
1187
1188   while ((p = strstr(s,"\\..\\")) != NULL)
1189     {
1190       pstring s1;
1191
1192       *p = 0;
1193       strcpy(s1,p+3);
1194
1195       if ((p=strrchr(s,'\\')) != NULL)
1196         *p = 0;
1197       else
1198         *s = 0;
1199       strcat(s,s1);
1200     }  
1201
1202   trim_string(s,NULL,"\\..");
1203
1204   string_sub(s, "\\.\\", "\\");
1205 }
1206
1207 /*******************************************************************
1208 reduce a file name, removing .. elements. 
1209 ********************************************************************/
1210 void unix_clean_name(char *s)
1211 {
1212   char *p=NULL;
1213
1214   DEBUG(3,("unix_clean_name [%s]\n",s));
1215
1216   /* remove any double slashes */
1217   string_sub(s, "//","/");
1218
1219   /* Remove leading ./ characters */
1220   if(strncmp(s, "./", 2) == 0) {
1221     trim_string(s, "./", NULL);
1222     if(*s == 0)
1223       strcpy(s,"./");
1224   }
1225
1226   while ((p = strstr(s,"/../")) != NULL)
1227     {
1228       pstring s1;
1229
1230       *p = 0;
1231       strcpy(s1,p+3);
1232
1233       if ((p=strrchr(s,'/')) != NULL)
1234         *p = 0;
1235       else
1236         *s = 0;
1237       strcat(s,s1);
1238     }  
1239
1240   trim_string(s,NULL,"/..");
1241 }
1242
1243
1244 /*******************************************************************
1245 a wrapper for the normal chdir() function
1246 ********************************************************************/
1247 int ChDir(char *path)
1248 {
1249   int res;
1250   static pstring LastDir="";
1251
1252   if (strcsequal(path,".")) return(0);
1253
1254   if (*path == '/' && strcsequal(LastDir,path)) return(0);
1255   DEBUG(3,("chdir to %s\n",path));
1256   res = sys_chdir(path);
1257   if (!res)
1258     strcpy(LastDir,path);
1259   return(res);
1260 }
1261
1262
1263 /*******************************************************************
1264   return the absolute current directory path. A dumb version.
1265 ********************************************************************/
1266 static char *Dumb_GetWd(char *s)
1267 {
1268   char *p;
1269 #ifdef USE_GETCWD
1270   p = (char *)getcwd(s,sizeof(pstring));
1271 #else
1272   p = (char *)getwd(s));
1273 #endif
1274   if(!p)
1275     return NULL;
1276
1277   /* Ensure we always return in dos format. */
1278   unix_to_dos(p,True);
1279   return p;
1280 }
1281
1282
1283 /* number of list structures for a caching GetWd function. */
1284 #define MAX_GETWDCACHE (50)
1285
1286 struct
1287 {
1288   ino_t inode;
1289   dev_t dev;
1290   char *text;
1291   BOOL valid;
1292 } ino_list[MAX_GETWDCACHE];
1293
1294 BOOL use_getwd_cache=True;
1295
1296 /*******************************************************************
1297   return the absolute current directory path
1298 ********************************************************************/
1299 char *GetWd(char *str)
1300 {
1301   pstring s;
1302   static BOOL getwd_cache_init = False;
1303   struct stat st, st2;
1304   int i;
1305
1306   *s = 0;
1307
1308   if (!use_getwd_cache)
1309     return(Dumb_GetWd(str));
1310
1311   /* init the cache */
1312   if (!getwd_cache_init)
1313     {
1314       getwd_cache_init = True;
1315       for (i=0;i<MAX_GETWDCACHE;i++)
1316         {
1317           string_init(&ino_list[i].text,"");
1318           ino_list[i].valid = False;
1319         }
1320     }
1321
1322   /*  Get the inode of the current directory, if this doesn't work we're
1323       in trouble :-) */
1324
1325   if (stat(".",&st) == -1) 
1326     {
1327       DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1328       return(Dumb_GetWd(str));
1329     }
1330
1331
1332   for (i=0; i<MAX_GETWDCACHE; i++)
1333     if (ino_list[i].valid)
1334       {
1335
1336         /*  If we have found an entry with a matching inode and dev number
1337             then find the inode number for the directory in the cached string.
1338             If this agrees with that returned by the stat for the current
1339             directory then all is o.k. (but make sure it is a directory all
1340             the same...) */
1341       
1342         if (st.st_ino == ino_list[i].inode &&
1343             st.st_dev == ino_list[i].dev)
1344           {
1345             if (stat(ino_list[i].text,&st2) == 0)
1346               {
1347                 if (st.st_ino == st2.st_ino &&
1348                     st.st_dev == st2.st_dev &&
1349                     (st2.st_mode & S_IFMT) == S_IFDIR)
1350                   {
1351                     strcpy (str, ino_list[i].text);
1352
1353                     /* promote it for future use */
1354                     array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1355                     return (str);
1356                   }
1357                 else
1358                   {
1359                     /*  If the inode is different then something's changed, 
1360                         scrub the entry and start from scratch. */
1361                     ino_list[i].valid = False;
1362                   }
1363               }
1364           }
1365       }
1366
1367
1368   /*  We don't have the information to hand so rely on traditional methods.
1369       The very slow getcwd, which spawns a process on some systems, or the
1370       not quite so bad getwd. */
1371
1372   if (!Dumb_GetWd(s))
1373     {
1374       DEBUG(0,("Getwd failed, errno %d\n",errno));
1375       return (NULL);
1376     }
1377
1378   strcpy(str,s);
1379
1380   DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1381
1382   /* add it to the cache */
1383   i = MAX_GETWDCACHE - 1;
1384   string_set(&ino_list[i].text,s);
1385   ino_list[i].dev = st.st_dev;
1386   ino_list[i].inode = st.st_ino;
1387   ino_list[i].valid = True;
1388
1389   /* put it at the top of the list */
1390   array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1391
1392   return (str);
1393 }
1394
1395
1396
1397 /*******************************************************************
1398 reduce a file name, removing .. elements and checking that 
1399 it is below dir in the heirachy. This uses GetWd() and so must be run
1400 on the system that has the referenced file system.
1401
1402 widelinks are allowed if widelinks is true
1403 ********************************************************************/
1404 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1405 {
1406 #ifndef REDUCE_PATHS
1407   return True;
1408 #else
1409   pstring dir2;
1410   pstring wd;
1411   pstring basename;
1412   pstring newname;
1413   char *p=NULL;
1414   BOOL relative = (*s != '/');
1415
1416   *dir2 = *wd = *basename = *newname = 0;
1417
1418   if (widelinks)
1419     {
1420       unix_clean_name(s);
1421       /* can't have a leading .. */
1422       if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1423         {
1424           DEBUG(3,("Illegal file name? (%s)\n",s));
1425           return(False);
1426         }
1427
1428       if (strlen(s) == 0)
1429         strcpy(s,"./");
1430
1431       return(True);
1432     }
1433   
1434   DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1435
1436   /* remove any double slashes */
1437   string_sub(s,"//","/");
1438
1439   strcpy(basename,s);
1440   p = strrchr(basename,'/');
1441
1442   if (!p)
1443     return(True);
1444
1445   if (!GetWd(wd))
1446     {
1447       DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1448       return(False);
1449     }
1450
1451   if (ChDir(dir) != 0)
1452     {
1453       DEBUG(0,("couldn't chdir to %s\n",dir));
1454       return(False);
1455     }
1456
1457   if (!GetWd(dir2))
1458     {
1459       DEBUG(0,("couldn't getwd for %s\n",dir));
1460       ChDir(wd);
1461       return(False);
1462     }
1463
1464
1465     if (p && (p != basename))
1466       {
1467         *p = 0;
1468         if (strcmp(p+1,".")==0)
1469           p[1]=0;
1470         if (strcmp(p+1,"..")==0)
1471           *p = '/';
1472       }
1473
1474   if (ChDir(basename) != 0)
1475     {
1476       ChDir(wd);
1477       DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1478       return(False);
1479     }
1480
1481   if (!GetWd(newname))
1482     {
1483       ChDir(wd);
1484       DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1485       return(False);
1486     }
1487
1488   if (p && (p != basename))
1489     {
1490       strcat(newname,"/");
1491       strcat(newname,p+1);
1492     }
1493
1494   {
1495     int l = strlen(dir2);    
1496     if (dir2[l-1] == '/')
1497       l--;
1498
1499     if (strncmp(newname,dir2,l) != 0)
1500       {
1501         ChDir(wd);
1502         DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1503         return(False);
1504       }
1505
1506     if (relative)
1507       {
1508         if (newname[l] == '/')
1509           strcpy(s,newname + l + 1);
1510         else
1511           strcpy(s,newname+l);
1512       }
1513     else
1514       strcpy(s,newname);
1515   }
1516
1517   ChDir(wd);
1518
1519   if (strlen(s) == 0)
1520     strcpy(s,"./");
1521
1522   DEBUG(3,("reduced to %s\n",s));
1523   return(True);
1524 #endif
1525 }
1526
1527 /****************************************************************************
1528 expand some *s 
1529 ****************************************************************************/
1530 static void expand_one(char *Mask,int len)
1531 {
1532   char *p1;
1533   while ((p1 = strchr(Mask,'*')) != NULL)
1534     {
1535       int lfill = (len+1) - strlen(Mask);
1536       int l1= (p1 - Mask);
1537       pstring tmp;
1538       strcpy(tmp,Mask);  
1539       memset(tmp+l1,'?',lfill);
1540       strcpy(tmp + l1 + lfill,Mask + l1 + 1);   
1541       strcpy(Mask,tmp);      
1542     }
1543 }
1544
1545 /****************************************************************************
1546 expand a wildcard expression, replacing *s with ?s
1547 ****************************************************************************/
1548 void expand_mask(char *Mask,BOOL doext)
1549 {
1550   pstring mbeg,mext;
1551   pstring dirpart;
1552   pstring filepart;
1553   BOOL hasdot = False;
1554   char *p1;
1555   BOOL absolute = (*Mask == '\\');
1556
1557   *mbeg = *mext = *dirpart = *filepart = 0;
1558
1559   /* parse the directory and filename */
1560   if (strchr(Mask,'\\'))
1561     dirname_dos(Mask,dirpart);
1562
1563   filename_dos(Mask,filepart);
1564
1565   strcpy(mbeg,filepart);
1566   if ((p1 = strchr(mbeg,'.')) != NULL)
1567     {
1568       hasdot = True;
1569       *p1 = 0;
1570       p1++;
1571       strcpy(mext,p1);
1572     }
1573   else
1574     {
1575       strcpy(mext,"");
1576       if (strlen(mbeg) > 8)
1577         {
1578           strcpy(mext,mbeg + 8);
1579           mbeg[8] = 0;
1580         }
1581     }
1582
1583   if (*mbeg == 0)
1584     strcpy(mbeg,"????????");
1585   if ((*mext == 0) && doext && !hasdot)
1586     strcpy(mext,"???");
1587
1588   if (strequal(mbeg,"*") && *mext==0) 
1589     strcpy(mext,"*");
1590
1591   /* expand *'s */
1592   expand_one(mbeg,8);
1593   if (*mext)
1594     expand_one(mext,3);
1595
1596   strcpy(Mask,dirpart);
1597   if (*dirpart || absolute) strcat(Mask,"\\");
1598   strcat(Mask,mbeg);
1599   strcat(Mask,".");
1600   strcat(Mask,mext);
1601
1602   DEBUG(6,("Mask expanded to [%s]\n",Mask));
1603 }  
1604
1605
1606 /****************************************************************************
1607 does a string have any uppercase chars in it?
1608 ****************************************************************************/
1609 BOOL strhasupper(char *s)
1610 {
1611   while (*s) 
1612     {
1613 #ifdef KANJI
1614         if (is_shift_jis (*s)) {
1615             s += 2;
1616         } else if (is_kana (*s)) {
1617             s++;
1618         } else {
1619             if (isupper(*s)) return(True);
1620             s++;
1621         }
1622 #else 
1623       if (isupper(*s)) return(True);
1624       s++;
1625 #endif /* KANJI */
1626     }
1627   return(False);
1628 }
1629
1630 /****************************************************************************
1631 does a string have any lowercase chars in it?
1632 ****************************************************************************/
1633 BOOL strhaslower(char *s)
1634 {
1635   while (*s) 
1636     {
1637 #ifdef KANJI
1638         if (is_shift_jis (*s)) {
1639             s += 2;
1640         } else if (is_kana (*s)) {
1641             s++;
1642         } else {
1643             if (islower(*s)) return(True);
1644             s++;
1645         }
1646 #else 
1647       if (islower(*s)) return(True);
1648       s++;
1649 #endif /* KANJI */
1650     }
1651   return(False);
1652 }
1653
1654 /****************************************************************************
1655 find the number of chars in a string
1656 ****************************************************************************/
1657 int count_chars(char *s,char c)
1658 {
1659   int count=0;
1660   while (*s) 
1661     {
1662       if (*s == c)
1663         count++;
1664       s++;
1665     }
1666   return(count);
1667 }
1668
1669
1670 /****************************************************************************
1671   make a dir struct
1672 ****************************************************************************/
1673 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1674 {  
1675   char *p;
1676   pstring mask2;
1677
1678   strcpy(mask2,mask);
1679
1680   if ((mode & aDIR) != 0)
1681     size = 0;
1682
1683   memset(buf+1,' ',11);
1684   if ((p = strchr(mask2,'.')) != NULL)
1685     {
1686       *p = 0;
1687       memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1688       memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1689       *p = '.';
1690     }
1691   else
1692     memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1693
1694   bzero(buf+21,DIR_STRUCT_SIZE-21);
1695   CVAL(buf,21) = mode;
1696   put_dos_date(buf,22,date);
1697   SSVAL(buf,26,size & 0xFFFF);
1698   SSVAL(buf,28,size >> 16);
1699   StrnCpy(buf+30,fname,12);
1700   if (!case_sensitive)
1701     strupper(buf+30);
1702   DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1703 }
1704
1705
1706 /*******************************************************************
1707 close the low 3 fd's and open dev/null in their place
1708 ********************************************************************/
1709 void close_low_fds(void)
1710 {
1711   int fd;
1712   int i;
1713   close(0); close(1); close(2);
1714   /* try and use up these file descriptors, so silly
1715      library routines writing to stdout etc won't cause havoc */
1716   for (i=0;i<3;i++) {
1717     fd = open("/dev/null",O_RDWR,0);
1718     if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1719     if (fd < 0) {
1720       DEBUG(0,("Can't open /dev/null\n"));
1721       return;
1722     }
1723     if (fd != i) {
1724       DEBUG(0,("Didn't get file descriptor %d\n",i));
1725       return;
1726     }
1727   }
1728 }
1729
1730 /****************************************************************************
1731 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1732 else
1733 if SYSV use O_NDELAY
1734 if BSD use FNDELAY
1735 ****************************************************************************/
1736 int set_blocking(int fd, BOOL set)
1737 {
1738   int val;
1739 #ifdef O_NONBLOCK
1740 #define FLAG_TO_SET O_NONBLOCK
1741 #else
1742 #ifdef SYSV
1743 #define FLAG_TO_SET O_NDELAY
1744 #else /* BSD */
1745 #define FLAG_TO_SET FNDELAY
1746 #endif
1747 #endif
1748
1749   if((val = fcntl(fd, F_GETFL, 0)) == -1)
1750         return -1;
1751   if(set) /* Turn blocking on - ie. clear nonblock flag */
1752         val &= ~FLAG_TO_SET;
1753   else
1754     val |= FLAG_TO_SET;
1755   return fcntl( fd, F_SETFL, val);
1756 #undef FLAG_TO_SET
1757 }
1758
1759
1760 /****************************************************************************
1761 write to a socket
1762 ****************************************************************************/
1763 int write_socket(int fd,char *buf,int len)
1764 {
1765   int ret=0;
1766
1767   if (passive)
1768     return(len);
1769   DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1770   ret = write_data(fd,buf,len);
1771       
1772   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1773   return(ret);
1774 }
1775
1776 /****************************************************************************
1777 read from a socket
1778 ****************************************************************************/
1779 int read_udp_socket(int fd,char *buf,int len)
1780 {
1781   int ret;
1782   struct sockaddr sock;
1783   int socklen;
1784   
1785   socklen = sizeof(sock);
1786   bzero((char *)&sock,socklen);
1787   bzero((char *)&lastip,sizeof(lastip));
1788   ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1789   if (ret <= 0) {
1790     DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1791     return(0);
1792   }
1793
1794   lastip = *(struct in_addr *) &sock.sa_data[2];
1795   lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1796
1797   return(ret);
1798 }
1799
1800 /****************************************************************************
1801 read data from a device with a timout in msec.
1802 mincount = if timeout, minimum to read before returning
1803 maxcount = number to be read.
1804 ****************************************************************************/
1805 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1806 {
1807   fd_set fds;
1808   int selrtn;
1809   int readret;
1810   int nread = 0;
1811   struct timeval timeout;
1812
1813   /* just checking .... */
1814   if (maxcnt <= 0) return(0);
1815
1816   smb_read_error = 0;
1817
1818   /* Blocking read */
1819   if (time_out <= 0) {
1820     if (mincnt == 0) mincnt = maxcnt;
1821
1822     while (nread < mincnt) {
1823       readret = read(fd, buf + nread, maxcnt - nread);
1824       if (readret == 0) {
1825         smb_read_error = READ_EOF;
1826         return -1;
1827       }
1828
1829       if (readret == -1) {
1830         smb_read_error = READ_ERROR;
1831         return -1;
1832       }
1833       nread += readret;
1834     }
1835     return(nread);
1836   }
1837   
1838   /* Most difficult - timeout read */
1839   /* If this is ever called on a disk file and 
1840          mincnt is greater then the filesize then
1841          system performance will suffer severely as 
1842          select always return true on disk files */
1843
1844   /* Set initial timeout */
1845   timeout.tv_sec = time_out / 1000;
1846   timeout.tv_usec = 1000 * (time_out % 1000);
1847
1848   for (nread=0; nread<mincnt; ) 
1849     {      
1850       FD_ZERO(&fds);
1851       FD_SET(fd,&fds);
1852       
1853       selrtn = sys_select(&fds,&timeout);
1854
1855       /* Check if error */
1856       if(selrtn == -1) {
1857         /* something is wrong. Maybe the socket is dead? */
1858         smb_read_error = READ_ERROR;
1859         return -1;
1860       }
1861       
1862       /* Did we timeout ? */
1863       if (selrtn == 0) {
1864         smb_read_error = READ_TIMEOUT;
1865         return -1;
1866       }
1867       
1868       readret = read(fd, buf+nread, maxcnt-nread);
1869       if (readret == 0) {
1870         /* we got EOF on the file descriptor */
1871         smb_read_error = READ_EOF;
1872         return -1;
1873       }
1874
1875       if (readret == -1) {
1876         /* the descriptor is probably dead */
1877         smb_read_error = READ_ERROR;
1878         return -1;
1879       }
1880       
1881       nread += readret;
1882     }
1883
1884   /* Return the number we got */
1885   return(nread);
1886 }
1887
1888 /****************************************************************************
1889 read data from the client. Maxtime is in milliseconds
1890 ****************************************************************************/
1891 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1892 {
1893   fd_set fds;
1894   int selrtn;
1895   int nread;
1896   struct timeval timeout;
1897  
1898   FD_ZERO(&fds);
1899   FD_SET(fd,&fds);
1900
1901   timeout.tv_sec = maxtime / 1000;
1902   timeout.tv_usec = (maxtime % 1000) * 1000;
1903
1904   selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1905
1906   if (!FD_ISSET(fd,&fds))
1907     return 0;
1908
1909   nread = read_udp_socket(fd, buffer, bufsize);
1910
1911   /* return the number got */
1912   return(nread);
1913 }
1914
1915 /*******************************************************************
1916 find the difference in milliseconds between two struct timeval
1917 values
1918 ********************************************************************/
1919 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1920 {
1921   return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
1922          ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
1923 }
1924
1925 /****************************************************************************
1926 send a keepalive packet (rfc1002)
1927 ****************************************************************************/
1928 BOOL send_keepalive(int client)
1929 {
1930   unsigned char buf[4];
1931
1932   buf[0] = 0x85;
1933   buf[1] = buf[2] = buf[3] = 0;
1934
1935   return(write_data(client,(char *)buf,4) == 4);
1936 }
1937
1938
1939
1940 /****************************************************************************
1941   read data from the client, reading exactly N bytes. 
1942 ****************************************************************************/
1943 int read_data(int fd,char *buffer,int N)
1944 {
1945   int  ret;
1946   int total=0;  
1947  
1948   smb_read_error = 0;
1949
1950   while (total < N)
1951     {
1952       ret = read(fd,buffer + total,N - total);
1953       if (ret == 0) {
1954         smb_read_error = READ_EOF;
1955         return 0;
1956       }
1957       if (ret == -1) {
1958         smb_read_error = READ_ERROR;
1959         return -1;
1960       }
1961       total += ret;
1962     }
1963   return total;
1964 }
1965
1966
1967 /****************************************************************************
1968   write data to a fd 
1969 ****************************************************************************/
1970 int write_data(int fd,char *buffer,int N)
1971 {
1972   int total=0;
1973   int ret;
1974
1975   while (total < N)
1976     {
1977       ret = write(fd,buffer + total,N - total);
1978
1979       if (ret == -1) return -1;
1980       if (ret == 0) return total;
1981
1982       total += ret;
1983     }
1984   return total;
1985 }
1986
1987
1988 /****************************************************************************
1989 transfer some data between two fd's
1990 ****************************************************************************/
1991 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1992 {
1993   static char *buf=NULL;  
1994   static int size=0;
1995   char *buf1,*abuf;
1996   int total = 0;
1997
1998   DEBUG(4,("transfer_file %d  (head=%d) called\n",n,headlen));
1999
2000   if (size == 0) {
2001     size = lp_readsize();
2002     size = MAX(size,1024);
2003   }
2004
2005   while (!buf && size>0) {
2006     buf = (char *)Realloc(buf,size+8);
2007     if (!buf) size /= 2;
2008   }
2009
2010   if (!buf) {
2011     DEBUG(0,("Can't allocate transfer buffer!\n"));
2012     exit(1);
2013   }
2014
2015   abuf = buf + (align%8);
2016
2017   if (header)
2018     n += headlen;
2019
2020   while (n > 0)
2021     {
2022       int s = MIN(n,size);
2023       int ret,ret2=0;
2024
2025       ret = 0;
2026
2027       if (header && (headlen >= MIN(s,1024))) {
2028         buf1 = header;
2029         s = headlen;
2030         ret = headlen;
2031         headlen = 0;
2032         header = NULL;
2033       } else {
2034         buf1 = abuf;
2035       }
2036
2037       if (header && headlen > 0)
2038         {
2039           ret = MIN(headlen,size);
2040           memcpy(buf1,header,ret);
2041           headlen -= ret;
2042           header += ret;
2043           if (headlen <= 0) header = NULL;
2044         }
2045
2046       if (s > ret)
2047         ret += read(infd,buf1+ret,s-ret);
2048
2049       if (ret > 0)
2050         {
2051           ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2052           if (ret2 > 0) total += ret2;
2053           /* if we can't write then dump excess data */
2054           if (ret2 != ret)
2055             transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2056         }
2057       if (ret <= 0 || ret2 != ret)
2058         return(total);
2059       n -= ret;
2060     }
2061   return(total);
2062 }
2063
2064
2065 /****************************************************************************
2066 read 4 bytes of a smb packet and return the smb length of the packet
2067 possibly store the result in the buffer
2068 ****************************************************************************/
2069 int read_smb_length(int fd,char *inbuf,int timeout)
2070 {
2071   char *buffer;
2072   char buf[4];
2073   int len=0, msg_type;
2074   BOOL ok=False;
2075
2076   if (inbuf)
2077     buffer = inbuf;
2078   else
2079     buffer = buf;
2080
2081   while (!ok)
2082     {
2083       if (timeout > 0)
2084         ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2085       else 
2086         ok = (read_data(fd,buffer,4) == 4);
2087
2088       if (!ok)
2089         return(-1);
2090
2091       len = smb_len(buffer);
2092       msg_type = CVAL(buffer,0);
2093
2094       if (msg_type == 0x85) 
2095         {
2096           DEBUG(5,("Got keepalive packet\n"));
2097           ok = False;
2098         }
2099     }
2100
2101   DEBUG(10,("got smb length of %d\n",len));
2102
2103   return(len);
2104 }
2105
2106
2107
2108 /****************************************************************************
2109   read an smb from a fd and return it's length
2110 The timeout is in milli seconds
2111 ****************************************************************************/
2112 BOOL receive_smb(int fd,char *buffer,int timeout)
2113 {
2114   int len,ret;
2115
2116   smb_read_error = 0;
2117
2118   bzero(buffer,smb_size + 100);
2119
2120   len = read_smb_length(fd,buffer,timeout);
2121   if (len == -1)
2122     return(False);
2123
2124   if (len > BUFFER_SIZE) {
2125     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2126     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2127       exit(1);
2128   }
2129
2130   ret = read_data(fd,buffer+4,len);
2131   if (ret != len) {
2132     smb_read_error = READ_ERROR;
2133     return False;
2134   }
2135
2136   return(True);
2137 }
2138
2139
2140 /****************************************************************************
2141   send an smb to a fd 
2142 ****************************************************************************/
2143 BOOL send_smb(int fd,char *buffer)
2144 {
2145   int len;
2146   int ret,nwritten=0;
2147   len = smb_len(buffer) + 4;
2148
2149   while (nwritten < len)
2150     {
2151       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2152       if (ret <= 0)
2153         {
2154           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2155           close_sockets();
2156           exit(1);
2157         }
2158       nwritten += ret;
2159     }
2160
2161
2162   return True;
2163 }
2164
2165
2166 /****************************************************************************
2167 find a pointer to a netbios name
2168 ****************************************************************************/
2169 char *name_ptr(char *buf,int ofs)
2170 {
2171   unsigned char c = *(unsigned char *)(buf+ofs);
2172
2173   if ((c & 0xC0) == 0xC0)
2174     {
2175       uint16 l;
2176       char p[2];
2177       memcpy(p,buf+ofs,2);
2178       p[0] &= ~0xC0;
2179       l = RSVAL(p,0);
2180       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2181       return(buf + l);
2182     }
2183   else
2184     return(buf+ofs);
2185 }  
2186
2187 /****************************************************************************
2188 extract a netbios name from a buf
2189 ****************************************************************************/
2190 int name_extract(char *buf,int ofs,char *name)
2191 {
2192   char *p = name_ptr(buf,ofs);
2193   int d = PTR_DIFF(p,buf+ofs);
2194   strcpy(name,"");
2195   if (d < -50 || d > 50) return(0);
2196   return(name_interpret(p,name));
2197 }  
2198   
2199
2200 /****************************************************************************
2201 return the total storage length of a mangled name
2202 ****************************************************************************/
2203 int name_len(char *s)
2204 {
2205   char *s0=s;
2206   unsigned char c = *(unsigned char *)s;
2207   if ((c & 0xC0) == 0xC0)
2208     return(2);
2209   while (*s) s += (*s)+1;
2210   return(PTR_DIFF(s,s0)+1);
2211 }
2212
2213 /****************************************************************************
2214 send a single packet to a port on another machine
2215 ****************************************************************************/
2216 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2217 {
2218   BOOL ret;
2219   int out_fd;
2220   struct sockaddr_in sock_out;
2221
2222   if (passive)
2223     return(True);
2224
2225   /* create a socket to write to */
2226   out_fd = socket(AF_INET, type, 0);
2227   if (out_fd == -1) 
2228     {
2229       DEBUG(0,("socket failed"));
2230       return False;
2231     }
2232
2233   /* set the address and port */
2234   bzero((char *)&sock_out,sizeof(sock_out));
2235   putip((char *)&sock_out.sin_addr,(char *)&ip);
2236   sock_out.sin_port = htons( port );
2237   sock_out.sin_family = AF_INET;
2238   
2239   if (DEBUGLEVEL > 0)
2240     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2241              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2242         
2243   /* send it */
2244   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2245
2246   if (!ret)
2247     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2248              inet_ntoa(ip),port,errno));
2249
2250   close(out_fd);
2251   return(ret);
2252 }
2253
2254 /*******************************************************************
2255 sleep for a specified number of milliseconds
2256 ********************************************************************/
2257 void msleep(int t)
2258 {
2259   int tdiff=0;
2260   struct timeval tval,t1,t2;  
2261   fd_set fds;
2262
2263   GetTimeOfDay(&t1);
2264   GetTimeOfDay(&t2);
2265   
2266   while (tdiff < t) {
2267     tval.tv_sec = (t-tdiff)/1000;
2268     tval.tv_usec = 1000*((t-tdiff)%1000);
2269  
2270     FD_ZERO(&fds);
2271     errno = 0;
2272     sys_select(&fds,&tval);
2273
2274     GetTimeOfDay(&t2);
2275     tdiff = TvalDiff(&t1,&t2);
2276   }
2277 }
2278
2279 /****************************************************************************
2280 check if a string is part of a list
2281 ****************************************************************************/
2282 BOOL in_list(char *s,char *list,BOOL casesensitive)
2283 {
2284   pstring tok;
2285   char *p=list;
2286
2287   if (!list) return(False);
2288
2289   while (next_token(&p,tok,LIST_SEP))
2290     {
2291       if (casesensitive) {
2292         if (strcmp(tok,s) == 0)
2293           return(True);
2294       } else {
2295         if (StrCaseCmp(tok,s) == 0)
2296           return(True);
2297       }
2298     }
2299   return(False);
2300 }
2301
2302 /* this is used to prevent lots of mallocs of size 1 */
2303 static char *null_string = NULL;
2304
2305 /****************************************************************************
2306 set a string value, allocing the space for the string
2307 ****************************************************************************/
2308 BOOL string_init(char **dest,char *src)
2309 {
2310   int l;
2311   if (!src)     
2312     src = "";
2313
2314   l = strlen(src);
2315
2316   if (l == 0)
2317     {
2318       if (!null_string)
2319         null_string = (char *)malloc(1);
2320
2321       *null_string = 0;
2322       *dest = null_string;
2323     }
2324   else
2325     {
2326       *dest = (char *)malloc(l+1);
2327       strcpy(*dest,src);
2328     }
2329   return(True);
2330 }
2331
2332 /****************************************************************************
2333 free a string value
2334 ****************************************************************************/
2335 void string_free(char **s)
2336 {
2337   if (!s || !(*s)) return;
2338   if (*s == null_string)
2339     *s = NULL;
2340   if (*s) free(*s);
2341   *s = NULL;
2342 }
2343
2344 /****************************************************************************
2345 set a string value, allocing the space for the string, and deallocating any 
2346 existing space
2347 ****************************************************************************/
2348 BOOL string_set(char **dest,char *src)
2349 {
2350   string_free(dest);
2351
2352   return(string_init(dest,src));
2353 }
2354
2355 /****************************************************************************
2356 substitute a string for a pattern in another string. Make sure there is 
2357 enough room!
2358
2359 This routine looks for pattern in s and replaces it with 
2360 insert. It may do multiple replacements.
2361
2362 return True if a substitution was done.
2363 ****************************************************************************/
2364 BOOL string_sub(char *s,char *pattern,char *insert)
2365 {
2366   BOOL ret = False;
2367   char *p;
2368   int ls,lp,li;
2369
2370   if (!insert || !pattern || !s) return(False);
2371
2372   ls = strlen(s);
2373   lp = strlen(pattern);
2374   li = strlen(insert);
2375
2376   if (!*pattern) return(False);
2377
2378   while (lp <= ls && (p = strstr(s,pattern)))
2379     {
2380       ret = True;
2381       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2382       memcpy(p,insert,li);
2383       s = p + li;
2384       ls = strlen(s);
2385     }
2386   return(ret);
2387 }
2388
2389
2390
2391 /*********************************************************
2392 * Recursive routine that is called by mask_match.
2393 * Does the actual matching.
2394 *********************************************************/
2395 BOOL do_match(char *str, char *regexp, int case_sig)
2396 {
2397   char *p;
2398
2399   for( p = regexp; *p && *str; ) {
2400     switch(*p) {
2401     case '?':
2402       str++; p++;
2403       break;
2404
2405     case '*':
2406       /* Look for a character matching 
2407          the one after the '*' */
2408       p++;
2409       if(!*p)
2410         return True; /* Automatic match */
2411       while(*str) {
2412         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2413           str++;
2414         if(do_match(str,p,case_sig))
2415           return True;
2416         if(!*str)
2417           return False;
2418         else
2419           str++;
2420       }
2421       return False;
2422
2423     default:
2424       if(case_sig) {
2425         if(*str != *p)
2426           return False;
2427       } else {
2428         if(toupper(*str) != toupper(*p))
2429           return False;
2430       }
2431       str++, p++;
2432       break;
2433     }
2434   }
2435   if(!*p && !*str)
2436     return True;
2437
2438   if (!*p && str[0] == '.' && str[1] == 0)
2439     return(True);
2440   
2441   if (!*str && *p == '?')
2442     {
2443       while (*p == '?') p++;
2444       return(!*p);
2445     }
2446
2447   if(!*str && (*p == '*' && p[1] == '\0'))
2448     return True;
2449   return False;
2450 }
2451
2452
2453 /*********************************************************
2454 * Routine to match a given string with a regexp - uses
2455 * simplified regexp that takes * and ? only. Case can be
2456 * significant or not.
2457 *********************************************************/
2458 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2459 {
2460   char *p;
2461   pstring p1, p2;
2462   fstring ebase,eext,sbase,sext;
2463
2464   BOOL matched;
2465
2466   /* Make local copies of str and regexp */
2467   StrnCpy(p1,regexp,sizeof(pstring)-1);
2468   StrnCpy(p2,str,sizeof(pstring)-1);
2469
2470   if (!strchr(p2,'.')) {
2471     strcat(p2,".");
2472   }
2473
2474 /*
2475   if (!strchr(p1,'.')) {
2476     strcat(p1,".");
2477   }
2478 */
2479
2480 #if 0
2481   if (strchr(p1,'.'))
2482     {
2483       string_sub(p1,"*.*","*");
2484       string_sub(p1,".*","*");
2485     }
2486 #endif
2487
2488   /* Remove any *? and ** as they are meaningless */
2489   for(p = p1; *p; p++)
2490     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2491       (void)strcpy( &p[1], &p[2]);
2492
2493   if (strequal(p1,"*")) return(True);
2494
2495   DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2496
2497   if (trans2) {
2498     strcpy(ebase,p1);
2499     strcpy(sbase,p2);
2500   } else {
2501     if ((p=strrchr(p1,'.'))) {
2502       *p = 0;
2503       strcpy(ebase,p1);
2504       strcpy(eext,p+1);
2505     } else {
2506       strcpy(ebase,p1);
2507       eext[0] = 0;
2508     }
2509
2510   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2511     *p = 0;
2512     strcpy(sbase,p2);
2513     strcpy(sext,p+1);
2514   } else {
2515     strcpy(sbase,p2);
2516     strcpy(sext,"");
2517   }
2518   }
2519
2520   matched = do_match(sbase,ebase,case_sig) && 
2521     (trans2 || do_match(sext,eext,case_sig));
2522
2523   DEBUG(5,("mask_match returning %d\n", matched));
2524
2525   return matched;
2526 }
2527
2528
2529
2530 /****************************************************************************
2531 become a daemon, discarding the controlling terminal
2532 ****************************************************************************/
2533 void become_daemon(void)
2534 {
2535 #ifndef NO_FORK_DEBUG
2536   if (fork())
2537     exit(0);
2538
2539   /* detach from the terminal */
2540 #ifdef USE_SETSID
2541   setsid();
2542 #else /* USE_SETSID */
2543 #ifdef TIOCNOTTY
2544   {
2545     int i = open("/dev/tty", O_RDWR);
2546     if (i >= 0) 
2547       {
2548         ioctl(i, (int) TIOCNOTTY, (char *)0);      
2549         close(i);
2550       }
2551   }
2552 #endif /* TIOCNOTTY */
2553 #endif /* USE_SETSID */
2554   /* Close fd's 0,1,2. Needed if started by rsh */
2555   close_low_fds();
2556 #endif /* NO_FORK_DEBUG */
2557 }
2558
2559
2560 /****************************************************************************
2561 put up a yes/no prompt
2562 ****************************************************************************/
2563 BOOL yesno(char *p)
2564 {
2565   pstring ans;
2566   printf("%s",p);
2567
2568   if (!fgets(ans,sizeof(ans)-1,stdin))
2569     return(False);
2570
2571   if (*ans == 'y' || *ans == 'Y')
2572     return(True);
2573
2574   return(False);
2575 }
2576
2577 /****************************************************************************
2578 read a line from a file with possible \ continuation chars. 
2579 Blanks at the start or end of a line are stripped.
2580 The string will be allocated if s2 is NULL
2581 ****************************************************************************/
2582 char *fgets_slash(char *s2,int maxlen,FILE *f)
2583 {
2584   char *s=s2;
2585   int len = 0;
2586   int c;
2587   BOOL start_of_line = True;
2588
2589   if (feof(f))
2590     return(NULL);
2591
2592   if (!s2)
2593     {
2594       maxlen = MIN(maxlen,8);
2595       s = (char *)Realloc(s,maxlen);
2596     }
2597
2598   if (!s || maxlen < 2) return(NULL);
2599
2600   *s = 0;
2601
2602   while (len < maxlen-1)
2603     {
2604       c = getc(f);
2605       switch (c)
2606         {
2607         case '\r':
2608           break;
2609         case '\n':
2610           while (len > 0 && s[len-1] == ' ')
2611             {
2612               s[--len] = 0;
2613             }
2614           if (len > 0 && s[len-1] == '\\')
2615             {
2616               s[--len] = 0;
2617               start_of_line = True;
2618               break;
2619             }
2620           return(s);
2621         case EOF:
2622           if (len <= 0 && !s2) 
2623             free(s);
2624           return(len>0?s:NULL);
2625         case ' ':
2626           if (start_of_line)
2627             break;
2628         default:
2629           start_of_line = False;
2630           s[len++] = c;
2631           s[len] = 0;
2632         }
2633       if (!s2 && len > maxlen-3)
2634         {
2635           maxlen *= 2;
2636           s = (char *)Realloc(s,maxlen);
2637           if (!s) return(NULL);
2638         }
2639     }
2640   return(s);
2641 }
2642
2643
2644
2645 /****************************************************************************
2646 set the length of a file from a filedescriptor.
2647 Returns 0 on success, -1 on failure.
2648 ****************************************************************************/
2649 int set_filelen(int fd, long len)
2650 {
2651 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2652    extend a file with ftruncate. Provide alternate implementation
2653    for this */
2654
2655 #if FTRUNCATE_CAN_EXTEND
2656   return ftruncate(fd, len);
2657 #else
2658   struct stat st;
2659   char c = 0;
2660   long currpos = lseek(fd, 0L, SEEK_CUR);
2661
2662   if(currpos < 0)
2663     return -1;
2664   /* Do an fstat to see if the file is longer than
2665      the requested size (call ftruncate),
2666      or shorter, in which case seek to len - 1 and write 1
2667      byte of zero */
2668   if(fstat(fd, &st)<0)
2669     return -1;
2670
2671 #ifdef S_ISFIFO
2672   if (S_ISFIFO(st.st_mode)) return 0;
2673 #endif
2674
2675   if(st.st_size == len)
2676     return 0;
2677   if(st.st_size > len)
2678     return ftruncate(fd, len);
2679
2680   if(lseek(fd, len-1, SEEK_SET) != len -1)
2681     return -1;
2682   if(write(fd, &c, 1)!=1)
2683     return -1;
2684   /* Seek to where we were */
2685   lseek(fd, currpos, SEEK_SET);
2686   return 0;
2687 #endif
2688 }
2689
2690
2691 /****************************************************************************
2692 return the byte checksum of some data
2693 ****************************************************************************/
2694 int byte_checksum(char *buf,int len)
2695 {
2696   unsigned char *p = (unsigned char *)buf;
2697   int ret = 0;
2698   while (len--)
2699     ret += *p++;
2700   return(ret);
2701 }
2702
2703
2704
2705 #ifdef HPUX
2706 /****************************************************************************
2707 this is a version of setbuffer() for those machines that only have setvbuf
2708 ****************************************************************************/
2709  void setbuffer(FILE *f,char *buf,int bufsize)
2710 {
2711   setvbuf(f,buf,_IOFBF,bufsize);
2712 }
2713 #endif
2714
2715
2716 /****************************************************************************
2717 parse out a directory name from a path name. Assumes dos style filenames.
2718 ****************************************************************************/
2719 char *dirname_dos(char *path,char *buf)
2720 {
2721   char *p = strrchr(path,'\\');
2722
2723   if (!p)
2724     strcpy(buf,path);
2725   else
2726     {
2727       *p = 0;
2728       strcpy(buf,path);
2729       *p = '\\';
2730     }
2731
2732   return(buf);
2733 }
2734
2735
2736 /****************************************************************************
2737 parse out a filename from a path name. Assumes dos style filenames.
2738 ****************************************************************************/
2739 static char *filename_dos(char *path,char *buf)
2740 {
2741   char *p = strrchr(path,'\\');
2742
2743   if (!p)
2744     strcpy(buf,path);
2745   else
2746     strcpy(buf,p+1);
2747
2748   return(buf);
2749 }
2750
2751
2752
2753 /****************************************************************************
2754 expand a pointer to be a particular size
2755 ****************************************************************************/
2756 void *Realloc(void *p,int size)
2757 {
2758   void *ret=NULL;
2759
2760   if (size == 0) {
2761     if (p) free(p);
2762     DEBUG(5,("Realloc asked for 0 bytes\n"));
2763     return NULL;
2764   }
2765
2766   if (!p)
2767     ret = (void *)malloc(size);
2768   else
2769     ret = (void *)realloc(p,size);
2770
2771   if (!ret)
2772     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2773
2774   return(ret);
2775 }
2776
2777 #ifdef NOSTRDUP
2778 /****************************************************************************
2779 duplicate a string
2780 ****************************************************************************/
2781  char *strdup(char *s)
2782 {
2783   char *ret = NULL;
2784   if (!s) return(NULL);
2785   ret = (char *)malloc(strlen(s)+1);
2786   if (!ret) return(NULL);
2787   strcpy(ret,s);
2788   return(ret);
2789 }
2790 #endif
2791
2792
2793 /****************************************************************************
2794   Signal handler for SIGPIPE (write on a disconnected socket) 
2795 ****************************************************************************/
2796 void Abort(void )
2797 {
2798   DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2799   exit(2);
2800 }
2801
2802 /****************************************************************************
2803 get my own name and IP
2804 ****************************************************************************/
2805 BOOL get_myname(char *my_name,struct in_addr *ip)
2806 {
2807   struct hostent *hp;
2808   pstring hostname;
2809
2810   *hostname = 0;
2811
2812   /* get my host name */
2813   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
2814     {
2815       DEBUG(0,("gethostname failed\n"));
2816       return False;
2817     } 
2818
2819   /* get host info */
2820   if ((hp = Get_Hostbyname(hostname)) == 0) 
2821     {
2822       DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2823       return False;
2824     }
2825
2826   if (my_name)
2827     {
2828       /* split off any parts after an initial . */
2829       char *p = strchr(hostname,'.');
2830       if (p) *p = 0;
2831
2832       strcpy(my_name,hostname);
2833     }
2834
2835   if (ip)
2836     putip((char *)ip,(char *)hp->h_addr);
2837
2838   return(True);
2839 }
2840
2841
2842 /****************************************************************************
2843 true if two IP addresses are equal
2844 ****************************************************************************/
2845 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2846 {
2847   uint32 a1,a2;
2848   a1 = ntohl(ip1.s_addr);
2849   a2 = ntohl(ip2.s_addr);
2850   return(a1 == a2);
2851 }
2852
2853
2854 /****************************************************************************
2855 open a socket of the specified type, port and address for incoming data
2856 ****************************************************************************/
2857 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2858 {
2859   struct hostent *hp;
2860   struct sockaddr_in sock;
2861   pstring host_name;
2862   int res;
2863
2864   /* get my host name */
2865   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
2866     { DEBUG(0,("gethostname failed\n")); return -1; } 
2867
2868   /* get host info */
2869   if ((hp = Get_Hostbyname(host_name)) == 0) 
2870     {
2871       DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2872       return -1;
2873     }
2874   
2875   bzero((char *)&sock,sizeof(sock));
2876   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2877 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2878   sock.sin_len = sizeof(sock);
2879 #endif
2880   sock.sin_port = htons( port );
2881   sock.sin_family = hp->h_addrtype;
2882   sock.sin_addr.s_addr = socket_addr;
2883   res = socket(hp->h_addrtype, type, 0);
2884   if (res == -1) 
2885     { DEBUG(0,("socket failed\n")); return -1; }
2886
2887   {
2888     int one=1;
2889     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2890   }
2891
2892   /* now we've got a socket - we need to bind it */
2893   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
2894     { 
2895       if (port) {
2896         if (port == SMB_PORT || port == NMB_PORT)
2897           DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2898                         port,socket_addr,strerror(errno))); 
2899         close(res); 
2900
2901         if (dlevel > 0 && port < 1000)
2902           port = 7999;
2903
2904         if (port >= 1000 && port < 9000)
2905           return(open_socket_in(type,port+1,dlevel,socket_addr));
2906       }
2907
2908       return(-1); 
2909     }
2910   DEBUG(3,("bind succeeded on port %d\n",port));
2911
2912   return res;
2913 }
2914
2915
2916 /****************************************************************************
2917   create an outgoing socket
2918   **************************************************************************/
2919 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2920 {
2921   struct sockaddr_in sock_out;
2922   int res,ret;
2923   int connect_loop = 250; /* 250 milliseconds */
2924   int loops = (timeout * 1000) / connect_loop;
2925
2926   /* create a socket to write to */
2927   res = socket(PF_INET, type, 0);
2928   if (res == -1) 
2929     { DEBUG(0,("socket error\n")); return -1; }
2930
2931   if (type != SOCK_STREAM) return(res);
2932   
2933   bzero((char *)&sock_out,sizeof(sock_out));
2934   putip((char *)&sock_out.sin_addr,(char *)addr);
2935   
2936   sock_out.sin_port = htons( port );
2937   sock_out.sin_family = PF_INET;
2938
2939   /* set it non-blocking */
2940   set_blocking(res,False);
2941
2942   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2943   
2944   /* and connect it to the destination */
2945 connect_again:
2946   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2947
2948   /* Some systems return EAGAIN when they mean EINPROGRESS */
2949   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2950         errno == EAGAIN) && loops--) {
2951     msleep(connect_loop);
2952     goto connect_again;
2953   }
2954
2955   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2956          errno == EAGAIN)) {
2957       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2958       close(res);
2959       return -1;
2960   }
2961
2962 #ifdef EISCONN
2963   if (ret < 0 && errno == EISCONN) {
2964     errno = 0;
2965     ret = 0;
2966   }
2967 #endif
2968
2969   if (ret < 0) {
2970     DEBUG(1,("error connecting to %s:%d (%s)\n",
2971              inet_ntoa(*addr),port,strerror(errno)));
2972     return -1;
2973   }
2974
2975   /* set it blocking again */
2976   set_blocking(res,True);
2977
2978   return res;
2979 }
2980
2981
2982 /****************************************************************************
2983 interpret a protocol description string, with a default
2984 ****************************************************************************/
2985 int interpret_protocol(char *str,int def)
2986 {
2987   if (strequal(str,"NT1"))
2988     return(PROTOCOL_NT1);
2989   if (strequal(str,"LANMAN2"))
2990     return(PROTOCOL_LANMAN2);
2991   if (strequal(str,"LANMAN1"))
2992     return(PROTOCOL_LANMAN1);
2993   if (strequal(str,"CORE"))
2994     return(PROTOCOL_CORE);
2995   if (strequal(str,"COREPLUS"))
2996     return(PROTOCOL_COREPLUS);
2997   if (strequal(str,"CORE+"))
2998     return(PROTOCOL_COREPLUS);
2999   
3000   DEBUG(0,("Unrecognised protocol level %s\n",str));
3001   
3002   return(def);
3003 }
3004
3005 /****************************************************************************
3006 interpret a security level
3007 ****************************************************************************/
3008 int interpret_security(char *str,int def)
3009 {
3010   if (strequal(str,"SERVER"))
3011     return(SEC_SERVER);
3012   if (strequal(str,"USER"))
3013     return(SEC_USER);
3014   if (strequal(str,"SHARE"))
3015     return(SEC_SHARE);
3016   
3017   DEBUG(0,("Unrecognised security level %s\n",str));
3018   
3019   return(def);
3020 }
3021
3022
3023 /****************************************************************************
3024 interpret an internet address or name into an IP address in 4 byte form
3025 ****************************************************************************/
3026 uint32 interpret_addr(char *str)
3027 {
3028   struct hostent *hp;
3029   uint32 res;
3030   int i;
3031   BOOL pure_address = True;
3032
3033   if (strcmp(str,"0.0.0.0") == 0) return(0);
3034   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3035
3036   for (i=0; pure_address && str[i]; i++)
3037     if (!(isdigit(str[i]) || str[i] == '.')) 
3038       pure_address = False;
3039
3040   /* if it's in the form of an IP address then get the lib to interpret it */
3041   if (pure_address) {
3042     res = inet_addr(str);
3043   } else {
3044     /* otherwise assume it's a network name of some sort and use 
3045        Get_Hostbyname */
3046     if ((hp = Get_Hostbyname(str)) == 0) {
3047       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3048       return 0;
3049     }
3050     putip((char *)&res,(char *)hp->h_addr);
3051   }
3052
3053   if (res == (uint32)-1) return(0);
3054
3055   return(res);
3056 }
3057
3058 /*******************************************************************
3059   a convenient addition to interpret_addr()
3060   ******************************************************************/
3061 struct in_addr *interpret_addr2(char *str)
3062 {
3063   static struct in_addr ret;
3064   uint32 a = interpret_addr(str);
3065   ret.s_addr = a;
3066   return(&ret);
3067 }
3068
3069 /*******************************************************************
3070   check if an IP is the 0.0.0.0
3071   ******************************************************************/
3072 BOOL zero_ip(struct in_addr ip)
3073 {
3074   uint32 a;
3075   putip((char *)&a,(char *)&ip);
3076   return(a == 0);
3077 }
3078
3079
3080 /*******************************************************************
3081  matchname - determine if host name matches IP address 
3082  ******************************************************************/
3083 static BOOL matchname(char *remotehost,struct in_addr  addr)
3084 {
3085   struct hostent *hp;
3086   int     i;
3087   
3088   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3089     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3090     return False;
3091   } 
3092
3093   /*
3094    * Make sure that gethostbyname() returns the "correct" host name.
3095    * Unfortunately, gethostbyname("localhost") sometimes yields
3096    * "localhost.domain". Since the latter host name comes from the
3097    * local DNS, we just have to trust it (all bets are off if the local
3098    * DNS is perverted). We always check the address list, though.
3099    */
3100   
3101   if (strcasecmp(remotehost, hp->h_name)
3102       && strcasecmp(remotehost, "localhost")) {
3103     DEBUG(0,("host name/name mismatch: %s != %s",
3104              remotehost, hp->h_name));
3105     return False;
3106   }
3107         
3108   /* Look up the host address in the address list we just got. */
3109   for (i = 0; hp->h_addr_list[i]; i++) {
3110     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3111       return True;
3112   }
3113
3114   /*
3115    * The host name does not map to the original host address. Perhaps
3116    * someone has compromised a name server. More likely someone botched
3117    * it, but that could be dangerous, too.
3118    */
3119   
3120   DEBUG(0,("host name/address mismatch: %s != %s",
3121            inet_ntoa(addr), hp->h_name));
3122   return False;
3123 }
3124
3125 /*******************************************************************
3126  Reset the 'done' variables so after a client process is created
3127  from a fork call these calls will be re-done. This should be
3128  expanded if more variables need reseting.
3129  ******************************************************************/
3130
3131 static BOOL global_client_name_done = False;
3132 static BOOL global_client_addr_done = False;
3133
3134 void reset_globals_after_fork()
3135 {
3136   global_client_name_done = False;
3137   global_client_addr_done = False;
3138 }
3139  
3140 /*******************************************************************
3141  return the DNS name of the client 
3142  ******************************************************************/
3143 char *client_name(void)
3144 {
3145   extern int Client;
3146   struct sockaddr sa;
3147   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3148   int     length = sizeof(sa);
3149   static pstring name_buf;
3150   struct hostent *hp;
3151
3152   if (global_client_name_done) 
3153     return name_buf;
3154
3155   strcpy(name_buf,"UNKNOWN");
3156
3157   if (getpeername(Client, &sa, &length) < 0) {
3158     DEBUG(0,("getpeername failed\n"));
3159     return name_buf;
3160   }
3161
3162   /* Look up the remote host name. */
3163   if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3164                           sizeof(sockin->sin_addr),
3165                           AF_INET)) == 0) {
3166     DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3167     StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3168   } else {
3169     StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3170     if (!matchname(name_buf, sockin->sin_addr)) {
3171       DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3172       strcpy(name_buf,"UNKNOWN");
3173     }
3174   }
3175   global_client_name_done = True;
3176   return name_buf;
3177 }
3178
3179 /*******************************************************************
3180  return the IP addr of the client as a string 
3181  ******************************************************************/
3182 char *client_addr(void)
3183 {
3184   extern int Client;
3185   struct sockaddr sa;
3186   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3187   int     length = sizeof(sa);
3188   static fstring addr_buf;
3189
3190   if (global_client_addr_done) 
3191     return addr_buf;
3192
3193   strcpy(addr_buf,"0.0.0.0");
3194
3195   if (getpeername(Client, &sa, &length) < 0) {
3196     DEBUG(0,("getpeername failed\n"));
3197     return addr_buf;
3198   }
3199
3200   strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3201
3202   global_client_addr_done = True;
3203   return addr_buf;
3204 }
3205
3206 /*******************************************************************
3207 sub strings with useful parameters
3208 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3209 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3210 ********************************************************************/
3211 void standard_sub_basic(char *string)
3212 {
3213   char *s, *p;
3214   char pidstr[10];
3215   struct passwd *pass;
3216
3217   for (s = string ; (p = strchr(s,'%')) != NULL ; s = p )
3218   {
3219     switch (*(p+1))
3220     {
3221       case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3222                    string_sub(p,"%G",gidtoname(pass->pw_gid));
3223                  else
3224                    p += 2;
3225                  break;
3226       case 'I' : string_sub(p,"%I",client_addr()); break;
3227       case 'L' : string_sub(p,"%L",local_machine); break;
3228       case 'M' : string_sub(p,"%M",client_name()); break;
3229       case 'R' : string_sub(p,"%R",remote_proto); break;
3230       case 'T' : string_sub(p,"%T",timestring()); break;
3231       case 'U' : string_sub(p,"%U",sesssetup_user); break;
3232       case 'a' : string_sub(p,"%a",remote_arch); break;
3233       case 'd' : sprintf(pidstr,"%d",(int)getpid());
3234                  string_sub(p,"%d",pidstr);
3235                  break;
3236       case 'h' : string_sub(p,"%h",myhostname); break;
3237       case 'm' : string_sub(p,"%m",remote_machine); break;
3238       case 'v' : string_sub(p,"%v",VERSION); break;
3239       case '\0' : p++; break; /* don't run off end if last character is % */
3240       default  : p+=2; break;
3241     }
3242   }
3243   return;
3244 }
3245
3246 /*******************************************************************
3247 are two IPs on the same subnet?
3248 ********************************************************************/
3249 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3250 {
3251   uint32 net1,net2,nmask;
3252
3253   nmask = ntohl(mask.s_addr);
3254   net1  = ntohl(ip1.s_addr);
3255   net2  = ntohl(ip2.s_addr);
3256             
3257   return((net1 & nmask) == (net2 & nmask));
3258 }
3259
3260
3261 /*******************************************************************
3262 write a string in unicoode format
3263 ********************************************************************/
3264 int PutUniCode(char *dst,char *src)
3265 {
3266   int ret = 0;
3267   while (*src) {
3268     dst[ret++] = src[0];
3269     dst[ret++] = 0;    
3270     src++;
3271   }
3272   dst[ret++]=0;
3273   dst[ret++]=0;
3274   return(ret);
3275 }
3276
3277 /****************************************************************************
3278 a wrapper for gethostbyname() that tries with all lower and all upper case 
3279 if the initial name fails
3280 ****************************************************************************/
3281 struct hostent *Get_Hostbyname(char *name)
3282 {
3283   char *name2 = strdup(name);
3284   struct hostent *ret;
3285
3286   if (!name2)
3287     {
3288       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3289       exit(0);
3290     }
3291
3292   if (!isalnum(*name2))
3293     {
3294       free(name2);
3295       return(NULL);
3296     }
3297
3298   ret = sys_gethostbyname(name2);
3299   if (ret != NULL)
3300     {
3301       free(name2);
3302       return(ret);
3303     }
3304
3305   /* try with all lowercase */
3306   strlower(name2);
3307   ret = sys_gethostbyname(name2);
3308   if (ret != NULL)
3309     {
3310       free(name2);
3311       return(ret);
3312     }
3313
3314   /* try with all uppercase */
3315   strupper(name2);
3316   ret = sys_gethostbyname(name2);
3317   if (ret != NULL)
3318     {
3319       free(name2);
3320       return(ret);
3321     }
3322   
3323   /* nothing works :-( */
3324   free(name2);
3325   return(NULL);
3326 }
3327
3328
3329 /****************************************************************************
3330 check if a process exists. Does this work on all unixes?
3331 ****************************************************************************/
3332 BOOL process_exists(int pid)
3333 {
3334 #ifdef LINUX
3335   fstring s;
3336   sprintf(s,"/proc/%d",pid);
3337   return(directory_exist(s,NULL));
3338 #else
3339   {
3340     static BOOL tested=False;
3341     static BOOL ok=False;
3342     fstring s;
3343     if (!tested) {
3344       tested = True;
3345       sprintf(s,"/proc/%05d",(int)getpid());
3346       ok = file_exist(s,NULL);
3347     }
3348     if (ok) {
3349       sprintf(s,"/proc/%05d",pid);
3350       return(file_exist(s,NULL));
3351     }
3352   }
3353
3354   /* CGH 8/16/96 - added ESRCH test */
3355   return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3356 #endif
3357 }
3358
3359
3360 /*******************************************************************
3361 turn a uid into a user name
3362 ********************************************************************/
3363 char *uidtoname(int uid)
3364 {
3365   static char name[40];
3366   struct passwd *pass = getpwuid(uid);
3367   if (pass) return(pass->pw_name);
3368   sprintf(name,"%d",uid);
3369   return(name);
3370 }
3371
3372 /*******************************************************************
3373 turn a gid into a group name
3374 ********************************************************************/
3375 char *gidtoname(int gid)
3376 {
3377   static char name[40];
3378   struct group *grp = getgrgid(gid);
3379   if (grp) return(grp->gr_name);
3380   sprintf(name,"%d",gid);
3381   return(name);
3382 }
3383
3384 /*******************************************************************
3385 block sigs
3386 ********************************************************************/
3387 void BlockSignals(BOOL block,int signum)
3388 {
3389 #ifdef USE_SIGBLOCK
3390   int block_mask = sigmask(signum);
3391   static int oldmask = 0;
3392   if (block) 
3393     oldmask = sigblock(block_mask);
3394   else
3395     sigsetmask(oldmask);
3396 #elif defined(USE_SIGPROCMASK)
3397   sigset_t set;
3398   sigemptyset(&set);
3399   sigaddset(&set,signum);
3400   sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3401 #endif
3402 }
3403
3404 #if AJT
3405 /*******************************************************************
3406 my own panic function - not suitable for general use
3407 ********************************************************************/
3408 void ajt_panic(void)
3409 {
3410   system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3411 }
3412 #endif
3413
3414 #ifdef USE_DIRECT
3415 #define DIRECT direct
3416 #else
3417 #define DIRECT dirent
3418 #endif
3419
3420 /*******************************************************************
3421 a readdir wrapper which just returns the file name
3422 also return the inode number if requested
3423 ********************************************************************/
3424 char *readdirname(void *p)
3425 {
3426   struct DIRECT *ptr;
3427   char *dname;
3428
3429   if (!p) return(NULL);
3430   
3431   ptr = (struct DIRECT *)readdir(p);
3432   if (!ptr) return(NULL);
3433
3434   dname = ptr->d_name;
3435
3436 #ifdef NEXT2
3437   if (telldir(p) < 0) return(NULL);
3438 #endif
3439
3440 #ifdef SUNOS5
3441   /* this handles a broken compiler setup, causing a mixture
3442    of BSD and SYSV headers and libraries */
3443   {
3444     static BOOL broken_readdir = False;
3445     if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3446       {
3447         DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3448         broken_readdir = True;
3449       }
3450     if (broken_readdir)
3451       dname = dname - 2;
3452   }
3453 #endif
3454
3455   {
3456     static pstring buf;
3457     strcpy(buf, dname);
3458     unix_to_dos(buf, True);
3459     dname = buf;
3460   }
3461
3462   return(dname);
3463 }
3464
3465 /*
3466  * Utility function used to decide if the last component 
3467  * of a path matches a (possibly wildcarded) entry in a namelist.
3468  */
3469
3470 BOOL is_in_path(char *name, name_compare_entry *namelist)
3471 {
3472   pstring last_component;
3473   char *p;
3474
3475   DEBUG(5, ("is_in_path: %s\n", name));
3476
3477   /* if we have no list it's obviously not in the path */
3478   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
3479   {
3480     DEBUG(5,("is_in_path: no name list.\n"));
3481     return False;
3482   }
3483
3484   /* Get the last component of the unix name. */
3485   p = strrchr(name, '/');
3486   strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3487   last_component[sizeof(last_component)-1] = '\0'; 
3488
3489   for(; namelist->name != NULL; namelist++)
3490   {
3491     if(namelist->is_wild)
3492     {
3493       /* look for a wildcard match. */
3494       if (mask_match(last_component, namelist->name, case_sensitive, False))
3495       {
3496          DEBUG(5,("is_in_path: mask match succeeded\n"));
3497          return True;
3498       }
3499     }
3500     else
3501     {
3502       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3503        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3504         {
3505          DEBUG(5,("is_in_path: match succeeded\n"));
3506          return True;
3507         }
3508     }
3509   }
3510   DEBUG(5,("is_in_path: match not found\n"));
3511
3512   return False;
3513 }
3514
3515 /*
3516  * Strip a '/' separated list into an array of 
3517  * name_compare_enties structures suitable for 
3518  * passing to is_in_path(). We do this for
3519  * speed so we can pre-parse all the names in the list 
3520  * and don't do it for each call to is_in_path().
3521  * namelist is modified here and is assumed to be 
3522  * a copy owned by the caller.
3523  * We also check if the entry contains a wildcard to
3524  * remove a potentially expensive call to mask_match
3525  * if possible.
3526  */
3527
3528 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3529 {
3530   char *name_end;
3531   char *nameptr = namelist;
3532   int num_entries = 0;
3533   int i;
3534
3535   (*ppname_array) = NULL;
3536
3537   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
3538     return;
3539
3540   /* We need to make two passes over the string. The
3541      first to count the number of elements, the second
3542      to split it.
3543    */
3544   while (*nameptr ) 
3545     {
3546       if ( *nameptr == '/' ) 
3547       {
3548           /* cope with multiple (useless) /s) */
3549           nameptr++;
3550           continue;
3551       }
3552       /* find the next / */
3553       name_end = strchr(nameptr, '/');
3554
3555       /* oops - the last check for a / didn't find one. */
3556       if (name_end == NULL)
3557         break;
3558
3559       /* next segment please */
3560       nameptr = name_end + 1;
3561       num_entries++;
3562     }
3563
3564   if(num_entries == 0)
3565     return;
3566
3567   if(( (*ppname_array) = (name_compare_entry *)malloc( 
3568            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3569   {
3570     DEBUG(0,("set_namearray: malloc fail\n"));
3571     return;
3572   }
3573
3574   /* Now copy out the names */
3575   nameptr = namelist;
3576   i = 0;
3577   while(*nameptr)
3578     {
3579       if ( *nameptr == '/' ) 
3580       {
3581           /* cope with multiple (useless) /s) */
3582           nameptr++;
3583           continue;
3584       }
3585       /* find the next / */
3586       if ((name_end = strchr(nameptr, '/')) != NULL) 
3587       {
3588           *name_end = 0;
3589       }
3590
3591       /* oops - the last check for a / didn't find one. */
3592       if (name_end == NULL)
3593         break;
3594
3595       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3596                                 (strchr( nameptr, '*')!=NULL));
3597       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3598       {
3599         DEBUG(0,("set_namearray: malloc fail (1)\n"));
3600         return;
3601       }
3602
3603       /* next segment please */
3604       nameptr = name_end + 1;
3605       i++;
3606     }
3607
3608   (*ppname_array)[i].name = NULL;
3609
3610   return;
3611 }
3612
3613 /****************************************************************************
3614 routine to free a namearray.
3615 ****************************************************************************/
3616
3617 void free_namearray(name_compare_entry *name_array)
3618 {
3619   if(name_array == 0)
3620     return;
3621
3622   if(name_array->name != NULL)
3623     free(name_array->name);
3624
3625   free((char *)name_array);
3626 }
3627
3628 /****************************************************************************
3629 routine to do file locking
3630 ****************************************************************************/
3631 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3632 {
3633 #if HAVE_FCNTL_LOCK
3634   struct flock lock;
3635   int ret;
3636
3637 #if 1
3638   uint32 mask = 0xC0000000;
3639
3640   /* make sure the count is reasonable, we might kill the lockd otherwise */
3641   count &= ~mask;
3642
3643   /* the offset is often strange - remove 2 of its bits if either of
3644      the top two bits are set. Shift the top ones by two bits. This
3645      still allows OLE2 apps to operate, but should stop lockd from
3646      dieing */
3647   if ((offset & mask) != 0)
3648     offset = (offset & ~mask) | ((offset & mask) >> 2);
3649 #else
3650   uint32 mask = ((unsigned)1<<31);
3651
3652   /* interpret negative counts as large numbers */
3653   if (count < 0)
3654     count &= ~mask;
3655
3656   /* no negative offsets */
3657   offset &= ~mask;
3658
3659   /* count + offset must be in range */
3660   while ((offset < 0 || (offset + count < 0)) && mask)
3661     {
3662       offset &= ~mask;
3663       mask = mask >> 1;
3664     }
3665 #endif
3666
3667
3668   DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3669
3670   lock.l_type = type;
3671   lock.l_whence = SEEK_SET;
3672   lock.l_start = (int)offset;
3673   lock.l_len = (int)count;
3674   lock.l_pid = 0;
3675
3676   errno = 0;
3677
3678   ret = fcntl(fd,op,&lock);
3679
3680   if (errno != 0)
3681     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3682
3683   /* a lock query */
3684   if (op == F_GETLK)
3685     {
3686       if ((ret != -1) &&
3687           (lock.l_type != F_UNLCK) && 
3688           (lock.l_pid != 0) && 
3689           (lock.l_pid != getpid()))
3690         {
3691           DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3692           return(True);
3693         }
3694
3695       /* it must be not locked or locked by me */
3696       return(False);
3697     }
3698
3699   /* a lock set or unset */
3700   if (ret == -1)
3701     {
3702       DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3703                offset,count,op,type,strerror(errno)));
3704
3705       /* perhaps it doesn't support this sort of locking?? */
3706       if (errno == EINVAL)
3707         {
3708           DEBUG(3,("locking not supported? returning True\n"));
3709           return(True);
3710         }
3711
3712       return(False);
3713     }
3714
3715   /* everything went OK */
3716   DEBUG(5,("Lock call successful\n"));
3717
3718   return(True);
3719 #else
3720   return(False);
3721 #endif
3722 }
3723
3724 /*******************************************************************
3725 lock a file - returning a open file descriptor or -1 on failure
3726 The timeout is in seconds. 0 means no timeout
3727 ********************************************************************/
3728 int file_lock(char *name,int timeout)
3729 {  
3730   int fd = open(name,O_RDWR|O_CREAT,0666);
3731   time_t t=0;
3732   if (fd < 0) return(-1);
3733
3734 #if HAVE_FCNTL_LOCK
3735   if (timeout) t = time(NULL);
3736   while (!timeout || (time(NULL)-t < timeout)) {
3737     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);    
3738     msleep(LOCK_RETRY_TIMEOUT);
3739   }
3740   return(-1);
3741 #else
3742   return(fd);
3743 #endif
3744 }
3745
3746 /*******************************************************************
3747 unlock a file locked by file_lock
3748 ********************************************************************/
3749 void file_unlock(int fd)
3750 {
3751   if (fd<0) return;
3752 #if HAVE_FCNTL_LOCK
3753   fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3754 #endif
3755   close(fd);
3756 }
3757
3758 /*******************************************************************
3759 is the name specified one of my netbios names
3760 returns true is it is equal, false otherwise
3761 ********************************************************************/
3762 BOOL is_myname(const char *s)
3763 {
3764   int n;
3765   BOOL ret = False;
3766
3767   for (n=0; my_netbios_names[n]; n++) {
3768     if (strequal(my_netbios_names[n], s))
3769       ret=True;
3770   }
3771   DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
3772   return(ret);
3773 }