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