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