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