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