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