loadparm.c: Added fix for veto oplock files bug from Charles Hoch <hoch@hplcgh.hpl...
[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-1997
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 #if (defined(NETGROUP) && defined (AUTOMOUNT))
25 #include "rpcsvc/ypclnt.h"
26 #endif
27
28 pstring scope = "";
29
30 int DEBUGLEVEL = 1;
31
32 BOOL passive = False;
33
34 int Protocol = PROTOCOL_COREPLUS;
35
36 /* a default finfo structure to ensure all fields are sensible */
37 file_info def_finfo = {-1,0,0,0,0,0,0,""};
38
39 /* these are some file handles where debug info will be stored */
40 FILE *dbf = NULL;
41
42 /* the client file descriptor */
43 int Client = -1;
44
45 /* the last IP received from */
46 struct in_addr lastip;
47
48 /* the last port received from */
49 int lastport=0;
50
51 /* this is used by the chaining code */
52 int chain_size = 0;
53
54 int trans_num = 0;
55
56 /*
57    case handling on filenames 
58 */
59 int case_default = CASE_LOWER;
60
61 pstring debugf = "";
62 int syslog_level;
63
64 /* the following control case operations - they are put here so the
65    client can link easily */
66 BOOL case_sensitive;
67 BOOL case_preserve;
68 BOOL use_mangled_map = False;
69 BOOL short_case_preserve;
70 BOOL case_mangle;
71
72 fstring remote_machine="";
73 fstring local_machine="";
74 fstring remote_arch="UNKNOWN";
75 static enum remote_arch_types ra_type = RA_UNKNOWN;
76 fstring remote_proto="UNKNOWN";
77 pstring myhostname="";
78 pstring user_socket_options="";   
79
80 pstring sesssetup_user="";
81 pstring samlogon_user="";
82
83 BOOL sam_logon_in_ssb = False;
84
85 pstring myname = "";
86 fstring myworkgroup = "";
87 char **my_netbios_names;
88
89 int smb_read_error = 0;
90
91 static BOOL stdout_logging = False;
92
93 static char *filename_dos(char *path,char *buf);
94
95 /*******************************************************************
96   get ready for syslog stuff
97   ******************************************************************/
98 void setup_logging(char *pname,BOOL interactive)
99 {
100 #ifdef SYSLOG
101   if (!interactive) {
102     char *p = strrchr(pname,'/');
103     if (p) pname = p+1;
104 #ifdef LOG_DAEMON
105     openlog(pname, LOG_PID, SYSLOG_FACILITY);
106 #else /* for old systems that have no facility codes. */
107     openlog(pname, LOG_PID);
108 #endif
109   }
110 #endif
111   if (interactive) {
112     stdout_logging = True;
113     dbf = stdout;
114   }
115 }
116
117
118 BOOL append_log=False;
119
120
121 /****************************************************************************
122 reopen the log files
123 ****************************************************************************/
124 void reopen_logs(void)
125 {
126   extern FILE *dbf;
127   pstring fname;
128   
129   if (DEBUGLEVEL > 0)
130     {
131       strcpy(fname,debugf);
132       if (lp_loaded() && (*lp_logfile()))
133         strcpy(fname,lp_logfile());
134
135       if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
136         {
137           int oldumask = umask(022);
138           strcpy(debugf,fname);
139           if (dbf) fclose(dbf);
140           if (append_log)
141             dbf = fopen(debugf,"a");
142           else
143             dbf = fopen(debugf,"w");
144           if (dbf) setbuf(dbf,NULL);
145           umask(oldumask);
146         }
147     }
148   else
149     {
150       if (dbf)
151         {
152           fclose(dbf);
153           dbf = NULL;
154         }
155     }
156 }
157
158
159 /*******************************************************************
160 check if the log has grown too big
161 ********************************************************************/
162 static void check_log_size(void)
163 {
164   static int debug_count=0;
165   int maxlog;
166   struct stat st;
167
168   if (debug_count++ < 100 || getuid() != 0) return;
169
170   maxlog = lp_max_log_size() * 1024;
171   if (!dbf || maxlog <= 0) return;
172
173   if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
174     fclose(dbf); dbf = NULL;
175     reopen_logs();
176     if (dbf && file_size(debugf) > maxlog) {
177       pstring name;
178       fclose(dbf); dbf = NULL;
179       sprintf(name,"%s.old",debugf);
180       sys_rename(debugf,name);
181       reopen_logs();
182     }
183   }
184   debug_count=0;
185 }
186
187
188 /*******************************************************************
189 write an debug message on the debugfile. This is called by the DEBUG
190 macro
191 ********************************************************************/
192 #ifdef __STDC__
193  int Debug1(char *format_str, ...)
194 {
195 #else
196  int Debug1(va_alist)
197 va_dcl
198 {  
199   char *format_str;
200 #endif
201   va_list ap;  
202   int old_errno = errno;
203
204   if (stdout_logging) {
205 #ifdef __STDC__
206     va_start(ap, format_str);
207 #else
208     va_start(ap);
209     format_str = va_arg(ap,char *);
210 #endif
211     vfprintf(dbf,format_str,ap);
212     va_end(ap);
213     errno = old_errno;
214     return(0);
215   }
216   
217 #ifdef SYSLOG
218   if (!lp_syslog_only())
219 #endif  
220     {
221       if (!dbf) {
222               int oldumask = umask(022);
223               dbf = fopen(debugf,"w");
224               umask(oldumask);
225               if (dbf) {
226                       setbuf(dbf,NULL);
227               } else {
228                       errno = old_errno;
229                       return(0);
230               }
231       }
232     }
233
234 #ifdef SYSLOG
235   if (syslog_level < lp_syslog())
236     {
237       /* 
238        * map debug levels to syslog() priorities
239        * note that not all DEBUG(0, ...) calls are
240        * necessarily errors
241        */
242       static int priority_map[] = { 
243         LOG_ERR,     /* 0 */
244         LOG_WARNING, /* 1 */
245         LOG_NOTICE,  /* 2 */
246         LOG_INFO,    /* 3 */
247       };
248       int priority;
249       pstring msgbuf;
250       
251       if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
252           syslog_level < 0)
253         priority = LOG_DEBUG;
254       else
255         priority = priority_map[syslog_level];
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       vsprintf(msgbuf, format_str, ap);
264       va_end(ap);
265       
266       msgbuf[255] = '\0';
267       syslog(priority, "%s", msgbuf);
268     }
269 #endif
270   
271 #ifdef SYSLOG
272   if (!lp_syslog_only())
273 #endif
274     {
275 #ifdef __STDC__
276       va_start(ap, format_str);
277 #else
278       va_start(ap);
279       format_str = va_arg(ap,char *);
280 #endif
281       vfprintf(dbf,format_str,ap);
282       va_end(ap);
283       fflush(dbf);
284     }
285
286   check_log_size();
287
288   errno = old_errno;
289
290   return(0);
291 }
292
293 /****************************************************************************
294   find a suitable temporary directory. The result should be copied immediately
295   as it may be overwritten by a subsequent call
296   ****************************************************************************/
297 char *tmpdir(void)
298 {
299   char *p;
300   if ((p = getenv("TMPDIR"))) {
301     return p;
302   }
303   return "/tmp";
304 }
305
306
307
308 /****************************************************************************
309 determine if a file descriptor is in fact a socket
310 ****************************************************************************/
311 BOOL is_a_socket(int fd)
312 {
313   int v,l;
314   l = sizeof(int);
315   return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
316 }
317
318
319 static char *last_ptr=NULL;
320
321 /****************************************************************************
322   Get the next token from a string, return False if none found
323   handles double-quotes. 
324 Based on a routine by GJC@VILLAGE.COM. 
325 Extensively modified by Andrew.Tridgell@anu.edu.au
326 ****************************************************************************/
327 BOOL next_token(char **ptr,char *buff,char *sep)
328 {
329   char *s;
330   BOOL quoted;
331
332   if (!ptr) ptr = &last_ptr;
333   if (!ptr) return(False);
334
335   s = *ptr;
336
337   /* default to simple separators */
338   if (!sep) sep = " \t\n\r";
339
340   /* find the first non sep char */
341   while(*s && strchr(sep,*s)) s++;
342
343   /* nothing left? */
344   if (! *s) return(False);
345
346   /* copy over the token */
347   for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
348     {
349       if (*s == '\"') 
350         quoted = !quoted;
351       else
352         *buff++ = *s;
353     }
354
355   *ptr = (*s) ? s+1 : s;  
356   *buff = 0;
357   last_ptr = *ptr;
358
359   return(True);
360 }
361
362 /****************************************************************************
363 Convert list of tokens to array; dependent on above routine.
364 Uses last_ptr from above - bit of a hack.
365 ****************************************************************************/
366 char **toktocliplist(int *ctok, char *sep)
367 {
368   char *s=last_ptr;
369   int ictok=0;
370   char **ret, **iret;
371
372   if (!sep) sep = " \t\n\r";
373
374   while(*s && strchr(sep,*s)) s++;
375
376   /* nothing left? */
377   if (!*s) return(NULL);
378
379   do {
380     ictok++;
381     while(*s && (!strchr(sep,*s))) s++;
382     while(*s && strchr(sep,*s)) *s++=0;
383   } while(*s);
384
385   *ctok=ictok;
386   s=last_ptr;
387
388   if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
389   
390   while(ictok--) {    
391     *iret++=s;
392     while(*s++);
393     while(!*s) s++;
394   }
395
396   return ret;
397 }
398
399 #ifndef HAVE_MEMMOVE
400 /*******************************************************************
401 safely copies memory, ensuring no overlap problems.
402 this is only used if the machine does not have it's own memmove().
403 this is not the fastest algorithm in town, but it will do for our
404 needs.
405 ********************************************************************/
406 void *MemMove(void *dest,void *src,int size)
407 {
408   unsigned long d,s;
409   int i;
410   if (dest==src || !size) return(dest);
411
412   d = (unsigned long)dest;
413   s = (unsigned long)src;
414
415   if ((d >= (s+size)) || (s >= (d+size))) {
416     /* no overlap */
417     memcpy(dest,src,size);
418     return(dest);
419   }
420
421   if (d < s)
422     {
423       /* we can forward copy */
424       if (s-d >= sizeof(int) && 
425           !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
426         /* do it all as words */
427         int *idest = (int *)dest;
428         int *isrc = (int *)src;
429         size /= sizeof(int);
430         for (i=0;i<size;i++) idest[i] = isrc[i];
431       } else {
432         /* simplest */
433         char *cdest = (char *)dest;
434         char *csrc = (char *)src;
435         for (i=0;i<size;i++) cdest[i] = csrc[i];
436       }
437     }
438   else
439     {
440       /* must backward copy */
441       if (d-s >= sizeof(int) && 
442           !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
443         /* do it all as words */
444         int *idest = (int *)dest;
445         int *isrc = (int *)src;
446         size /= sizeof(int);
447         for (i=size-1;i>=0;i--) idest[i] = isrc[i];
448       } else {
449         /* simplest */
450         char *cdest = (char *)dest;
451         char *csrc = (char *)src;
452         for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
453       }      
454     }
455   return(dest);
456 }
457 #endif
458
459
460 /****************************************************************************
461 prompte a dptr (to make it recently used)
462 ****************************************************************************/
463 void array_promote(char *array,int elsize,int element)
464 {
465   char *p;
466   if (element == 0)
467     return;
468
469   p = (char *)malloc(elsize);
470
471   if (!p)
472     {
473       DEBUG(5,("Ahh! Can't malloc\n"));
474       return;
475     }
476   memcpy(p,array + element * elsize, elsize);
477   memmove(array + elsize,array,elsize*element);
478   memcpy(array,p,elsize);
479   free(p);
480 }
481
482 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
483
484 struct
485 {
486   char *name;
487   int level;
488   int option;
489   int value;
490   int opttype;
491 } socket_options[] = {
492   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
493   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
494   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
495 #ifdef TCP_NODELAY
496   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
497 #endif
498 #ifdef IPTOS_LOWDELAY
499   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
500 #endif
501 #ifdef IPTOS_THROUGHPUT
502   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
503 #endif
504 #ifdef SO_SNDBUF
505   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
506 #endif
507 #ifdef SO_RCVBUF
508   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
509 #endif
510 #ifdef SO_SNDLOWAT
511   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
512 #endif
513 #ifdef SO_RCVLOWAT
514   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
515 #endif
516 #ifdef SO_SNDTIMEO
517   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
518 #endif
519 #ifdef SO_RCVTIMEO
520   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
521 #endif
522   {NULL,0,0,0,0}};
523
524         
525
526 /****************************************************************************
527 set user socket options
528 ****************************************************************************/
529 void set_socket_options(int fd, char *options)
530 {
531   string tok;
532
533   while (next_token(&options,tok," \t,"))
534     {
535       int ret=0,i;
536       int value = 1;
537       char *p;
538       BOOL got_value = False;
539
540       if ((p = strchr(tok,'=')))
541         {
542           *p = 0;
543           value = atoi(p+1);
544           got_value = True;
545         }
546
547       for (i=0;socket_options[i].name;i++)
548         if (strequal(socket_options[i].name,tok))
549           break;
550
551       if (!socket_options[i].name)
552         {
553           DEBUG(0,("Unknown socket option %s\n",tok));
554           continue;
555         }
556
557       switch (socket_options[i].opttype)
558         {
559         case OPT_BOOL:
560         case OPT_INT:
561           ret = setsockopt(fd,socket_options[i].level,
562                            socket_options[i].option,(char *)&value,sizeof(int));
563           break;
564
565         case OPT_ON:
566           if (got_value)
567             DEBUG(0,("syntax error - %s does not take a value\n",tok));
568
569           {
570             int on = socket_options[i].value;
571             ret = setsockopt(fd,socket_options[i].level,
572                              socket_options[i].option,(char *)&on,sizeof(int));
573           }
574           break;          
575         }
576       
577       if (ret != 0)
578         DEBUG(0,("Failed to set socket option %s\n",tok));
579     }
580 }
581
582
583
584 /****************************************************************************
585   close the socket communication
586 ****************************************************************************/
587 void close_sockets(void )
588 {
589   close(Client);
590   Client = 0;
591 }
592
593 /****************************************************************************
594 determine whether we are in the specified group
595 ****************************************************************************/
596 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
597 {
598   int i;
599
600   if (group == current_gid) return(True);
601
602   for (i=0;i<ngroups;i++)
603     if (group == groups[i])
604       return(True);
605
606   return(False);
607 }
608
609 /****************************************************************************
610 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
611 ****************************************************************************/
612 char *StrCpy(char *dest,char *src)
613 {
614   char *d = dest;
615
616 #if AJT
617   /* I don't want to get lazy with these ... */
618   if (!dest || !src) {
619     DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
620     ajt_panic();
621   }
622 #endif
623
624   if (!dest) return(NULL);
625   if (!src) {
626     *dest = 0;
627     return(dest);
628   }
629   while ((*d++ = *src++)) ;
630   return(dest);
631 }
632
633 /****************************************************************************
634 line strncpy but always null terminates. Make sure there is room!
635 ****************************************************************************/
636 char *StrnCpy(char *dest,char *src,int n)
637 {
638   char *d = dest;
639   if (!dest) return(NULL);
640   if (!src) {
641     *dest = 0;
642     return(dest);
643   }
644   while (n-- && (*d++ = *src++)) ;
645   *d = 0;
646   return(dest);
647 }
648
649
650 /*******************************************************************
651 copy an IP address from one buffer to another
652 ********************************************************************/
653 void putip(void *dest,void *src)
654 {
655   memcpy(dest,src,4);
656 }
657
658
659 /****************************************************************************
660 interpret the weird netbios "name". Return the name type
661 ****************************************************************************/
662 static int name_interpret(char *in,char *out)
663 {
664   int ret;
665   int len = (*in++) / 2;
666
667   *out=0;
668
669   if (len > 30 || len<1) return(0);
670
671   while (len--)
672     {
673       if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
674         *out = 0;
675         return(0);
676       }
677       *out = ((in[0]-'A')<<4) + (in[1]-'A');
678       in += 2;
679       out++;
680     }
681   *out = 0;
682   ret = out[-1];
683
684 #ifdef NETBIOS_SCOPE
685   /* Handle any scope names */
686   while(*in) 
687     {
688       *out++ = '.'; /* Scope names are separated by periods */
689       len = *(unsigned char *)in++;
690       StrnCpy(out, in, len);
691       out += len;
692       *out=0;
693       in += len;
694     }
695 #endif
696   return(ret);
697 }
698
699 /****************************************************************************
700 mangle a name into netbios format
701
702   Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
703 ****************************************************************************/
704 int name_mangle( char *In, char *Out, char name_type )
705   {
706   int   i;
707   int   c;
708   int   len;
709   char  buf[20];
710   char *p = Out;
711
712   /* Safely copy the input string, In, into buf[]. */
713   (void)memset( buf, 0, 20 );
714   if( '*' == In[0] )
715     buf[0] = '*';
716   else
717     (void)sprintf( buf, "%-15.15s%c", In, name_type );
718
719   /* Place the length of the first field into the output buffer. */
720   p[0] = 32;
721   p++;
722
723   /* Now convert the name to the rfc1001/1002 format. */
724   for( i = 0; i < 16; i++ )
725     {
726     c = toupper( buf[i] );
727     p[i*2]     = ( (c >> 4) & 0x000F ) + 'A';
728     p[(i*2)+1] = (c & 0x000F) + 'A';
729     }
730   p += 32;
731   p[0] = '\0';
732
733   /* Add the scope string. */
734   for( i = 0, len = 0; NULL != scope; i++, len++ )
735     {
736     switch( scope[i] )
737       {
738       case '\0':
739         p[0]     = len;
740         if( len > 0 )
741           p[len+1] = 0;
742         return( name_len(Out) );
743       case '.':
744         p[0] = len;
745         p   += (len + 1);
746         len  = 0;
747         break;
748       default:
749         p[len+1] = scope[i];
750         break;
751       }
752     }
753
754   return( name_len(Out) );
755   } /* name_mangle */
756
757 /*******************************************************************
758   check if a file exists
759 ********************************************************************/
760 BOOL file_exist(char *fname,struct stat *sbuf)
761 {
762   struct stat st;
763   if (!sbuf) sbuf = &st;
764   
765   if (sys_stat(fname,sbuf) != 0) 
766     return(False);
767
768   return(S_ISREG(sbuf->st_mode));
769 }
770
771 /*******************************************************************
772 check a files mod time
773 ********************************************************************/
774 time_t file_modtime(char *fname)
775 {
776   struct stat st;
777   
778   if (sys_stat(fname,&st) != 0) 
779     return(0);
780
781   return(st.st_mtime);
782 }
783
784 /*******************************************************************
785   check if a directory exists
786 ********************************************************************/
787 BOOL directory_exist(char *dname,struct stat *st)
788 {
789   struct stat st2;
790   BOOL ret;
791
792   if (!st) st = &st2;
793
794   if (sys_stat(dname,st) != 0) 
795     return(False);
796
797   ret = S_ISDIR(st->st_mode);
798   if(!ret)
799     errno = ENOTDIR;
800   return ret;
801 }
802
803 /*******************************************************************
804 returns the size in bytes of the named file
805 ********************************************************************/
806 uint32 file_size(char *file_name)
807 {
808   struct stat buf;
809   buf.st_size = 0;
810   sys_stat(file_name,&buf);
811   return(buf.st_size);
812 }
813
814 /*******************************************************************
815 return a string representing an attribute for a file
816 ********************************************************************/
817 char *attrib_string(int mode)
818 {
819   static char attrstr[10];
820
821   attrstr[0] = 0;
822
823   if (mode & aVOLID) strcat(attrstr,"V");
824   if (mode & aDIR) strcat(attrstr,"D");
825   if (mode & aARCH) strcat(attrstr,"A");
826   if (mode & aHIDDEN) strcat(attrstr,"H");
827   if (mode & aSYSTEM) strcat(attrstr,"S");
828   if (mode & aRONLY) strcat(attrstr,"R");         
829
830   return(attrstr);
831 }
832
833
834 /*******************************************************************
835   case insensitive string compararison
836 ********************************************************************/
837 int StrCaseCmp(char *s, char *t)
838 {
839   /* compare until we run out of string, either t or s, or find a difference */
840   /* We *must* use toupper rather than tolower here due to the
841      asynchronous upper to lower mapping.
842    */
843 #if !defined(KANJI_WIN95_COMPATIBILITY)
844   if(lp_client_code_page() == KANJI_CODEPAGE)
845   {
846     /* Win95 treats full width ascii characters as case sensitive. */
847     int diff;
848     for (;;)
849     {
850       if (!*s || !*t)
851             return toupper (*s) - toupper (*t);
852       else if (is_sj_alph (*s) && is_sj_alph (*t))
853       {
854         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
855         if (diff)
856           return diff;
857         s += 2;
858         t += 2;
859       }
860       else if (is_shift_jis (*s) && is_shift_jis (*t))
861       {
862         diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
863         if (diff)
864           return diff;
865         diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
866         if (diff)
867           return diff;
868         s += 2;
869         t += 2;
870       }
871       else if (is_shift_jis (*s))
872         return 1;
873       else if (is_shift_jis (*t))
874         return -1;
875       else 
876       {
877         diff = toupper (*s) - toupper (*t);
878         if (diff)
879           return diff;
880         s++;
881         t++;
882       }
883     }
884   }
885   else
886 #endif /* KANJI_WIN95_COMPATIBILITY */
887   {
888     while (*s && *t && toupper(*s) == toupper(*t))
889     {
890       s++;
891       t++;
892     }
893
894     return(toupper(*s) - toupper(*t));
895   }
896 }
897
898 /*******************************************************************
899   case insensitive string compararison, length limited
900 ********************************************************************/
901 int StrnCaseCmp(char *s, char *t, int n)
902 {
903   /* compare until we run out of string, either t or s, or chars */
904   /* We *must* use toupper rather than tolower here due to the
905      asynchronous upper to lower mapping.
906    */
907 #if !defined(KANJI_WIN95_COMPATIBILITY)
908   if(lp_client_code_page() == KANJI_CODEPAGE)
909   {
910     /* Win95 treats full width ascii characters as case sensitive. */
911     int diff;
912     for (;n > 0;)
913     {
914       if (!*s || !*t)
915         return toupper (*s) - toupper (*t);
916       else if (is_sj_alph (*s) && is_sj_alph (*t))
917       {
918         diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
919         if (diff)
920           return diff;
921         s += 2;
922         t += 2;
923         n -= 2;
924       }
925       else if (is_shift_jis (*s) && is_shift_jis (*t))
926       {
927         diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
928         if (diff)
929           return diff;
930         diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
931         if (diff)
932           return diff;
933         s += 2;
934         t += 2;
935         n -= 2;
936       }
937       else if (is_shift_jis (*s))
938         return 1;
939       else if (is_shift_jis (*t))
940         return -1;
941       else 
942       {
943         diff = toupper (*s) - toupper (*t);
944         if (diff)
945           return diff;
946         s++;
947         t++;
948         n--;
949       }
950     }
951     return 0;
952   }
953   else
954 #endif /* KANJI_WIN95_COMPATIBILITY */
955   {
956     while (n && *s && *t && toupper(*s) == toupper(*t))
957     {
958       s++;
959       t++;
960       n--;
961     }
962
963     /* not run out of chars - strings are different lengths */
964     if (n) 
965       return(toupper(*s) - toupper(*t));
966
967     /* identical up to where we run out of chars, 
968        and strings are same length */
969     return(0);
970   }
971 }
972
973 /*******************************************************************
974   compare 2 strings 
975 ********************************************************************/
976 BOOL strequal(char *s1, char *s2)
977 {
978   if (s1 == s2) return(True);
979   if (!s1 || !s2) return(False);
980   
981   return(StrCaseCmp(s1,s2)==0);
982 }
983
984 /*******************************************************************
985   compare 2 strings up to and including the nth char.
986   ******************************************************************/
987 BOOL strnequal(char *s1,char *s2,int n)
988 {
989   if (s1 == s2) return(True);
990   if (!s1 || !s2 || !n) return(False);
991   
992   return(StrnCaseCmp(s1,s2,n)==0);
993 }
994
995 /*******************************************************************
996   compare 2 strings (case sensitive)
997 ********************************************************************/
998 BOOL strcsequal(char *s1,char *s2)
999 {
1000   if (s1 == s2) return(True);
1001   if (!s1 || !s2) return(False);
1002   
1003   return(strcmp(s1,s2)==0);
1004 }
1005
1006
1007 /*******************************************************************
1008   convert a string to lower case
1009 ********************************************************************/
1010 void strlower(char *s)
1011 {
1012   while (*s)
1013   {
1014 #if !defined(KANJI_WIN95_COMPATIBILITY)
1015     if(lp_client_code_page() == KANJI_CODEPAGE)
1016     {
1017       /* Win95 treats full width ascii characters as case sensitive. */
1018       if (is_shift_jis (*s))
1019       {
1020         if (is_sj_upper (s[0], s[1]))
1021           s[1] = sj_tolower2 (s[1]);
1022         s += 2;
1023       }
1024       else if (is_kana (*s))
1025       {
1026         s++;
1027       }
1028       else
1029       {
1030         if (isupper(*s))
1031           *s = tolower(*s);
1032         s++;
1033       }
1034     }
1035     else
1036 #endif /* KANJI_WIN95_COMPATIBILITY */
1037     {
1038       if (isupper(*s))
1039         *s = tolower(*s);
1040       s++;
1041     }
1042   }
1043 }
1044
1045 /*******************************************************************
1046   convert a string to upper case
1047 ********************************************************************/
1048 void strupper(char *s)
1049 {
1050   while (*s)
1051   {
1052 #if !defined(KANJI_WIN95_COMPATIBILITY)
1053     if(lp_client_code_page() == KANJI_CODEPAGE)
1054     {
1055       /* Win95 treats full width ascii characters as case sensitive. */
1056       if (is_shift_jis (*s))
1057       {
1058         if (is_sj_lower (s[0], s[1]))
1059           s[1] = sj_toupper2 (s[1]);
1060         s += 2;
1061       }
1062       else if (is_kana (*s))
1063       {
1064         s++;
1065       }
1066       else
1067       {
1068         if (islower(*s))
1069           *s = toupper(*s);
1070         s++;
1071       }
1072     }
1073     else
1074 #endif /* KANJI_WIN95_COMPATIBILITY */
1075     {
1076       if (islower(*s))
1077         *s = toupper(*s);
1078       s++;
1079     }
1080   }
1081 }
1082
1083 /*******************************************************************
1084   convert a string to "normal" form
1085 ********************************************************************/
1086 void strnorm(char *s)
1087 {
1088   if (case_default == CASE_UPPER)
1089     strupper(s);
1090   else
1091     strlower(s);
1092 }
1093
1094 /*******************************************************************
1095 check if a string is in "normal" case
1096 ********************************************************************/
1097 BOOL strisnormal(char *s)
1098 {
1099   if (case_default == CASE_UPPER)
1100     return(!strhaslower(s));
1101
1102   return(!strhasupper(s));
1103 }
1104
1105
1106 /****************************************************************************
1107   string replace
1108 ****************************************************************************/
1109 void string_replace(char *s,char oldc,char newc)
1110 {
1111   while (*s)
1112   {
1113 #if !defined(KANJI_WIN95_COMPATIBILITY)
1114     if(lp_client_code_page() == KANJI_CODEPAGE)
1115     {
1116       /* Win95 treats full width ascii characters as case sensitive. */
1117       if (is_shift_jis (*s))
1118         s += 2;
1119       else if (is_kana (*s))
1120         s++;
1121       else
1122       {
1123         if (oldc == *s)
1124           *s = newc;
1125         s++;
1126       }
1127     }
1128     else
1129 #endif /* KANJI_WIN95_COMPATIBILITY */
1130     {
1131       if (oldc == *s)
1132         *s = newc;
1133       s++;
1134     }
1135   }
1136 }
1137
1138 /****************************************************************************
1139   make a file into unix format
1140 ****************************************************************************/
1141 void unix_format(char *fname)
1142 {
1143   pstring namecopy;
1144   string_replace(fname,'\\','/');
1145
1146   if (*fname == '/')
1147     {
1148       pstrcpy(namecopy,fname);
1149       strcpy(fname,".");
1150       strcat(fname,namecopy);
1151     }  
1152 }
1153
1154 /****************************************************************************
1155   make a file into dos format
1156 ****************************************************************************/
1157 void dos_format(char *fname)
1158 {
1159   string_replace(fname,'/','\\');
1160 }
1161
1162
1163 /*******************************************************************
1164   show a smb message structure
1165 ********************************************************************/
1166 void show_msg(char *buf)
1167 {
1168   int i;
1169   int bcc=0;
1170
1171   if (DEBUGLEVEL < 5) return;
1172
1173   DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1174           smb_len(buf),
1175           (int)CVAL(buf,smb_com),
1176           (int)CVAL(buf,smb_rcls),
1177           (int)CVAL(buf,smb_reh),
1178           (int)SVAL(buf,smb_err),
1179           (int)CVAL(buf,smb_flg),
1180           (int)SVAL(buf,smb_flg2)));
1181   DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1182           (int)SVAL(buf,smb_tid),
1183           (int)SVAL(buf,smb_pid),
1184           (int)SVAL(buf,smb_uid),
1185           (int)SVAL(buf,smb_mid),
1186           (int)CVAL(buf,smb_wct)));
1187
1188   for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1189     DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1190           SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1191
1192   bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1193   DEBUG(5,("smb_bcc=%d\n",bcc));
1194
1195   if (DEBUGLEVEL < 10) return;
1196
1197   dump_data(10, smb_buf(buf), MIN(bcc, 512));
1198 }
1199
1200 /*******************************************************************
1201   return the length of an smb packet
1202 ********************************************************************/
1203 int smb_len(char *buf)
1204 {
1205   return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1206 }
1207
1208 /*******************************************************************
1209   set the length of an smb packet
1210 ********************************************************************/
1211 void _smb_setlen(char *buf,int len)
1212 {
1213   buf[0] = 0;
1214   buf[1] = (len&0x10000)>>16;
1215   buf[2] = (len&0xFF00)>>8;
1216   buf[3] = len&0xFF;
1217 }
1218
1219 /*******************************************************************
1220   set the length and marker of an smb packet
1221 ********************************************************************/
1222 void smb_setlen(char *buf,int len)
1223 {
1224   _smb_setlen(buf,len);
1225
1226   CVAL(buf,4) = 0xFF;
1227   CVAL(buf,5) = 'S';
1228   CVAL(buf,6) = 'M';
1229   CVAL(buf,7) = 'B';
1230 }
1231
1232 /*******************************************************************
1233   setup the word count and byte count for a smb message
1234 ********************************************************************/
1235 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1236 {
1237   if (zero)
1238     bzero(buf + smb_size,num_words*2 + num_bytes);
1239   CVAL(buf,smb_wct) = num_words;
1240   SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
1241   smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1242   return (smb_size + num_words*2 + num_bytes);
1243 }
1244
1245 /*******************************************************************
1246 return the number of smb words
1247 ********************************************************************/
1248 int smb_numwords(char *buf)
1249 {
1250   return (CVAL(buf,smb_wct));
1251 }
1252
1253 /*******************************************************************
1254 return the size of the smb_buf region of a message
1255 ********************************************************************/
1256 int smb_buflen(char *buf)
1257 {
1258   return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1259 }
1260
1261 /*******************************************************************
1262   return a pointer to the smb_buf data area
1263 ********************************************************************/
1264 int smb_buf_ofs(char *buf)
1265 {
1266   return (smb_size + CVAL(buf,smb_wct)*2);
1267 }
1268
1269 /*******************************************************************
1270   return a pointer to the smb_buf data area
1271 ********************************************************************/
1272 char *smb_buf(char *buf)
1273 {
1274   return (buf + smb_buf_ofs(buf));
1275 }
1276
1277 /*******************************************************************
1278 return the SMB offset into an SMB buffer
1279 ********************************************************************/
1280 int smb_offset(char *p,char *buf)
1281 {
1282   return(PTR_DIFF(p,buf+4) + chain_size);
1283 }
1284
1285
1286 /*******************************************************************
1287 skip past some strings in a buffer
1288 ********************************************************************/
1289 char *skip_string(char *buf,int n)
1290 {
1291   while (n--)
1292     buf += strlen(buf) + 1;
1293   return(buf);
1294 }
1295
1296 /*******************************************************************
1297 trim the specified elements off the front and back of a string
1298 ********************************************************************/
1299 BOOL trim_string(char *s,char *front,char *back)
1300 {
1301   BOOL ret = False;
1302   while (front && *front && strncmp(s,front,strlen(front)) == 0)
1303     {
1304       char *p = s;
1305       ret = True;
1306       while (1)
1307         {
1308           if (!(*p = p[strlen(front)]))
1309             break;
1310           p++;
1311         }
1312     }
1313   while (back && *back && strlen(s) >= strlen(back) && 
1314          (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))  
1315     {
1316       ret = True;
1317       s[strlen(s)-strlen(back)] = 0;
1318     }
1319   return(ret);
1320 }
1321
1322
1323 /*******************************************************************
1324 reduce a file name, removing .. elements.
1325 ********************************************************************/
1326 void dos_clean_name(char *s)
1327 {
1328   char *p=NULL;
1329
1330   DEBUG(3,("dos_clean_name [%s]\n",s));
1331
1332   /* remove any double slashes */
1333   string_sub(s, "\\\\", "\\");
1334
1335   while ((p = strstr(s,"\\..\\")) != NULL)
1336     {
1337       pstring s1;
1338
1339       *p = 0;
1340       pstrcpy(s1,p+3);
1341
1342       if ((p=strrchr(s,'\\')) != NULL)
1343         *p = 0;
1344       else
1345         *s = 0;
1346       strcat(s,s1);
1347     }  
1348
1349   trim_string(s,NULL,"\\..");
1350
1351   string_sub(s, "\\.\\", "\\");
1352 }
1353
1354 /*******************************************************************
1355 reduce a file name, removing .. elements. 
1356 ********************************************************************/
1357 void unix_clean_name(char *s)
1358 {
1359   char *p=NULL;
1360
1361   DEBUG(3,("unix_clean_name [%s]\n",s));
1362
1363   /* remove any double slashes */
1364   string_sub(s, "//","/");
1365
1366   /* Remove leading ./ characters */
1367   if(strncmp(s, "./", 2) == 0) {
1368     trim_string(s, "./", NULL);
1369     if(*s == 0)
1370       strcpy(s,"./");
1371   }
1372
1373   while ((p = strstr(s,"/../")) != NULL)
1374     {
1375       pstring s1;
1376
1377       *p = 0;
1378       pstrcpy(s1,p+3);
1379
1380       if ((p=strrchr(s,'/')) != NULL)
1381         *p = 0;
1382       else
1383         *s = 0;
1384       strcat(s,s1);
1385     }  
1386
1387   trim_string(s,NULL,"/..");
1388 }
1389
1390
1391 /*******************************************************************
1392 a wrapper for the normal chdir() function
1393 ********************************************************************/
1394 int ChDir(char *path)
1395 {
1396   int res;
1397   static pstring LastDir="";
1398
1399   if (strcsequal(path,".")) return(0);
1400
1401   if (*path == '/' && strcsequal(LastDir,path)) return(0);
1402   DEBUG(3,("chdir to %s\n",path));
1403   res = sys_chdir(path);
1404   if (!res)
1405     pstrcpy(LastDir,path);
1406   return(res);
1407 }
1408
1409 /* number of list structures for a caching GetWd function. */
1410 #define MAX_GETWDCACHE (50)
1411
1412 struct
1413 {
1414   ino_t inode;
1415   dev_t dev;
1416   char *text;
1417   BOOL valid;
1418 } ino_list[MAX_GETWDCACHE];
1419
1420 BOOL use_getwd_cache=True;
1421
1422 /*******************************************************************
1423   return the absolute current directory path
1424 ********************************************************************/
1425 char *GetWd(char *str)
1426 {
1427   pstring s;
1428   static BOOL getwd_cache_init = False;
1429   struct stat st, st2;
1430   int i;
1431
1432   *s = 0;
1433
1434   if (!use_getwd_cache)
1435     return(sys_getwd(str));
1436
1437   /* init the cache */
1438   if (!getwd_cache_init)
1439     {
1440       getwd_cache_init = True;
1441       for (i=0;i<MAX_GETWDCACHE;i++)
1442         {
1443           string_init(&ino_list[i].text,"");
1444           ino_list[i].valid = False;
1445         }
1446     }
1447
1448   /*  Get the inode of the current directory, if this doesn't work we're
1449       in trouble :-) */
1450
1451   if (stat(".",&st) == -1) 
1452     {
1453       DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1454       return(sys_getwd(str));
1455     }
1456
1457
1458   for (i=0; i<MAX_GETWDCACHE; i++)
1459     if (ino_list[i].valid)
1460       {
1461
1462         /*  If we have found an entry with a matching inode and dev number
1463             then find the inode number for the directory in the cached string.
1464             If this agrees with that returned by the stat for the current
1465             directory then all is o.k. (but make sure it is a directory all
1466             the same...) */
1467       
1468         if (st.st_ino == ino_list[i].inode &&
1469             st.st_dev == ino_list[i].dev)
1470           {
1471             if (stat(ino_list[i].text,&st2) == 0)
1472               {
1473                 if (st.st_ino == st2.st_ino &&
1474                     st.st_dev == st2.st_dev &&
1475                     (st2.st_mode & S_IFMT) == S_IFDIR)
1476                   {
1477                     strcpy (str, ino_list[i].text);
1478
1479                     /* promote it for future use */
1480                     array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1481                     return (str);
1482                   }
1483                 else
1484                   {
1485                     /*  If the inode is different then something's changed, 
1486                         scrub the entry and start from scratch. */
1487                     ino_list[i].valid = False;
1488                   }
1489               }
1490           }
1491       }
1492
1493
1494   /*  We don't have the information to hand so rely on traditional methods.
1495       The very slow getcwd, which spawns a process on some systems, or the
1496       not quite so bad getwd. */
1497
1498   if (!sys_getwd(s))
1499     {
1500       DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1501       return (NULL);
1502     }
1503
1504   strcpy(str,s);
1505
1506   DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1507
1508   /* add it to the cache */
1509   i = MAX_GETWDCACHE - 1;
1510   string_set(&ino_list[i].text,s);
1511   ino_list[i].dev = st.st_dev;
1512   ino_list[i].inode = st.st_ino;
1513   ino_list[i].valid = True;
1514
1515   /* put it at the top of the list */
1516   array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1517
1518   return (str);
1519 }
1520
1521
1522
1523 /*******************************************************************
1524 reduce a file name, removing .. elements and checking that 
1525 it is below dir in the heirachy. This uses GetWd() and so must be run
1526 on the system that has the referenced file system.
1527
1528 widelinks are allowed if widelinks is true
1529 ********************************************************************/
1530 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1531 {
1532 #ifndef REDUCE_PATHS
1533   return True;
1534 #else
1535   pstring dir2;
1536   pstring wd;
1537   pstring basename;
1538   pstring newname;
1539   char *p=NULL;
1540   BOOL relative = (*s != '/');
1541
1542   *dir2 = *wd = *basename = *newname = 0;
1543
1544   if (widelinks)
1545     {
1546       unix_clean_name(s);
1547       /* can't have a leading .. */
1548       if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1549         {
1550           DEBUG(3,("Illegal file name? (%s)\n",s));
1551           return(False);
1552         }
1553
1554       if (strlen(s) == 0)
1555         strcpy(s,"./");
1556
1557       return(True);
1558     }
1559   
1560   DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1561
1562   /* remove any double slashes */
1563   string_sub(s,"//","/");
1564
1565   pstrcpy(basename,s);
1566   p = strrchr(basename,'/');
1567
1568   if (!p)
1569     return(True);
1570
1571   if (!GetWd(wd))
1572     {
1573       DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1574       return(False);
1575     }
1576
1577   if (ChDir(dir) != 0)
1578     {
1579       DEBUG(0,("couldn't chdir to %s\n",dir));
1580       return(False);
1581     }
1582
1583   if (!GetWd(dir2))
1584     {
1585       DEBUG(0,("couldn't getwd for %s\n",dir));
1586       ChDir(wd);
1587       return(False);
1588     }
1589
1590
1591     if (p && (p != basename))
1592       {
1593         *p = 0;
1594         if (strcmp(p+1,".")==0)
1595           p[1]=0;
1596         if (strcmp(p+1,"..")==0)
1597           *p = '/';
1598       }
1599
1600   if (ChDir(basename) != 0)
1601     {
1602       ChDir(wd);
1603       DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1604       return(False);
1605     }
1606
1607   if (!GetWd(newname))
1608     {
1609       ChDir(wd);
1610       DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1611       return(False);
1612     }
1613
1614   if (p && (p != basename))
1615     {
1616       strcat(newname,"/");
1617       strcat(newname,p+1);
1618     }
1619
1620   {
1621     int l = strlen(dir2);    
1622     if (dir2[l-1] == '/')
1623       l--;
1624
1625     if (strncmp(newname,dir2,l) != 0)
1626       {
1627         ChDir(wd);
1628         DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1629         return(False);
1630       }
1631
1632     if (relative)
1633       {
1634         if (newname[l] == '/')
1635           pstrcpy(s,newname + l + 1);
1636         else
1637           pstrcpy(s,newname+l);
1638       }
1639     else
1640       pstrcpy(s,newname);
1641   }
1642
1643   ChDir(wd);
1644
1645   if (strlen(s) == 0)
1646     strcpy(s,"./");
1647
1648   DEBUG(3,("reduced to %s\n",s));
1649   return(True);
1650 #endif
1651 }
1652
1653 /****************************************************************************
1654 expand some *s 
1655 ****************************************************************************/
1656 static void expand_one(char *Mask,int len)
1657 {
1658   char *p1;
1659   while ((p1 = strchr(Mask,'*')) != NULL)
1660     {
1661       int lfill = (len+1) - strlen(Mask);
1662       int l1= (p1 - Mask);
1663       pstring tmp;
1664       pstrcpy(tmp,Mask);  
1665       memset(tmp+l1,'?',lfill);
1666       pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);  
1667       pstrcpy(Mask,tmp);      
1668     }
1669 }
1670
1671 /****************************************************************************
1672 expand a wildcard expression, replacing *s with ?s
1673 ****************************************************************************/
1674 void expand_mask(char *Mask,BOOL doext)
1675 {
1676   pstring mbeg,mext;
1677   pstring dirpart;
1678   pstring filepart;
1679   BOOL hasdot = False;
1680   char *p1;
1681   BOOL absolute = (*Mask == '\\');
1682
1683   *mbeg = *mext = *dirpart = *filepart = 0;
1684
1685   /* parse the directory and filename */
1686   if (strchr(Mask,'\\'))
1687     dirname_dos(Mask,dirpart);
1688
1689   filename_dos(Mask,filepart);
1690
1691   pstrcpy(mbeg,filepart);
1692   if ((p1 = strchr(mbeg,'.')) != NULL)
1693     {
1694       hasdot = True;
1695       *p1 = 0;
1696       p1++;
1697       pstrcpy(mext,p1);
1698     }
1699   else
1700     {
1701       strcpy(mext,"");
1702       if (strlen(mbeg) > 8)
1703         {
1704           pstrcpy(mext,mbeg + 8);
1705           mbeg[8] = 0;
1706         }
1707     }
1708
1709   if (*mbeg == 0)
1710     strcpy(mbeg,"????????");
1711   if ((*mext == 0) && doext && !hasdot)
1712     strcpy(mext,"???");
1713
1714   if (strequal(mbeg,"*") && *mext==0) 
1715     strcpy(mext,"*");
1716
1717   /* expand *'s */
1718   expand_one(mbeg,8);
1719   if (*mext)
1720     expand_one(mext,3);
1721
1722   pstrcpy(Mask,dirpart);
1723   if (*dirpart || absolute) strcat(Mask,"\\");
1724   strcat(Mask,mbeg);
1725   strcat(Mask,".");
1726   strcat(Mask,mext);
1727
1728   DEBUG(6,("Mask expanded to [%s]\n",Mask));
1729 }  
1730
1731
1732 /****************************************************************************
1733 does a string have any uppercase chars in it?
1734 ****************************************************************************/
1735 BOOL strhasupper(char *s)
1736 {
1737   while (*s) 
1738   {
1739 #if !defined(KANJI_WIN95_COMPATIBILITY)
1740     if(lp_client_code_page() == KANJI_CODEPAGE)
1741     {
1742       /* Win95 treats full width ascii characters as case sensitive. */
1743       if (is_shift_jis (*s))
1744         s += 2;
1745       else if (is_kana (*s))
1746         s++;
1747       else
1748       {
1749         if (isupper(*s))
1750           return(True);
1751         s++;
1752       }
1753     }
1754     else
1755 #endif /* KANJI_WIN95_COMPATIBILITY */
1756     {
1757       if (isupper(*s))
1758         return(True);
1759       s++;
1760     }
1761   }
1762   return(False);
1763 }
1764
1765 /****************************************************************************
1766 does a string have any lowercase chars in it?
1767 ****************************************************************************/
1768 BOOL strhaslower(char *s)
1769 {
1770   while (*s) 
1771   {
1772 #if !defined(KANJI_WIN95_COMPATIBILITY)
1773     if(lp_client_code_page() == KANJI_CODEPAGE)
1774     {
1775       /* Win95 treats full width ascii characters as case sensitive. */
1776       if (is_shift_jis (*s))
1777       {
1778         if (is_sj_upper (s[0], s[1]))
1779           return(True);
1780         if (is_sj_lower (s[0], s[1]))
1781           return (True);
1782         s += 2;
1783       }
1784       else if (is_kana (*s))
1785       {
1786         s++;
1787       }
1788       else
1789       {
1790         if (islower(*s))
1791           return(True);
1792         s++;
1793       }
1794     }
1795     else
1796 #endif /* KANJI_WIN95_COMPATIBILITY */
1797     {
1798       if (islower(*s))
1799         return(True);
1800       s++;
1801     }
1802   }
1803   return(False);
1804 }
1805
1806 /****************************************************************************
1807 find the number of chars in a string
1808 ****************************************************************************/
1809 int count_chars(char *s,char c)
1810 {
1811   int count=0;
1812
1813 #if !defined(KANJI_WIN95_COMPATIBILITY)
1814   if(lp_client_code_page() == KANJI_CODEPAGE)
1815   {
1816     /* Win95 treats full width ascii characters as case sensitive. */
1817     while (*s) 
1818     {
1819       if (is_shift_jis (*s))
1820         s += 2;
1821       else 
1822       {
1823         if (*s == c)
1824           count++;
1825         s++;
1826       }
1827     }
1828   }
1829   else
1830 #endif /* KANJI_WIN95_COMPATIBILITY */
1831   {
1832     while (*s) 
1833     {
1834       if (*s == c)
1835         count++;
1836       s++;
1837     }
1838   }
1839   return(count);
1840 }
1841
1842
1843 /****************************************************************************
1844   make a dir struct
1845 ****************************************************************************/
1846 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1847 {  
1848   char *p;
1849   pstring mask2;
1850
1851   pstrcpy(mask2,mask);
1852
1853   if ((mode & aDIR) != 0)
1854     size = 0;
1855
1856   memset(buf+1,' ',11);
1857   if ((p = strchr(mask2,'.')) != NULL)
1858     {
1859       *p = 0;
1860       memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1861       memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1862       *p = '.';
1863     }
1864   else
1865     memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1866
1867   bzero(buf+21,DIR_STRUCT_SIZE-21);
1868   CVAL(buf,21) = mode;
1869   put_dos_date(buf,22,date);
1870   SSVAL(buf,26,size & 0xFFFF);
1871   SSVAL(buf,28,size >> 16);
1872   StrnCpy(buf+30,fname,12);
1873   if (!case_sensitive)
1874     strupper(buf+30);
1875   DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1876 }
1877
1878
1879 /*******************************************************************
1880 close the low 3 fd's and open dev/null in their place
1881 ********************************************************************/
1882 void close_low_fds(void)
1883 {
1884   int fd;
1885   int i;
1886   close(0); close(1); close(2);
1887   /* try and use up these file descriptors, so silly
1888      library routines writing to stdout etc won't cause havoc */
1889   for (i=0;i<3;i++) {
1890     fd = open("/dev/null",O_RDWR,0);
1891     if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1892     if (fd < 0) {
1893       DEBUG(0,("Can't open /dev/null\n"));
1894       return;
1895     }
1896     if (fd != i) {
1897       DEBUG(0,("Didn't get file descriptor %d\n",i));
1898       return;
1899     }
1900   }
1901 }
1902
1903 /****************************************************************************
1904 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1905 else
1906 if SYSV use O_NDELAY
1907 if BSD use FNDELAY
1908 ****************************************************************************/
1909 int set_blocking(int fd, BOOL set)
1910 {
1911   int val;
1912 #ifdef O_NONBLOCK
1913 #define FLAG_TO_SET O_NONBLOCK
1914 #else
1915 #ifdef SYSV
1916 #define FLAG_TO_SET O_NDELAY
1917 #else /* BSD */
1918 #define FLAG_TO_SET FNDELAY
1919 #endif
1920 #endif
1921
1922   if((val = fcntl(fd, F_GETFL, 0)) == -1)
1923         return -1;
1924   if(set) /* Turn blocking on - ie. clear nonblock flag */
1925         val &= ~FLAG_TO_SET;
1926   else
1927     val |= FLAG_TO_SET;
1928   return fcntl( fd, F_SETFL, val);
1929 #undef FLAG_TO_SET
1930 }
1931
1932
1933 /****************************************************************************
1934 write to a socket
1935 ****************************************************************************/
1936 int write_socket(int fd,char *buf,int len)
1937 {
1938   int ret=0;
1939
1940   if (passive)
1941     return(len);
1942   DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1943   ret = write_data(fd,buf,len);
1944       
1945   DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1946   return(ret);
1947 }
1948
1949 /****************************************************************************
1950 read from a socket
1951 ****************************************************************************/
1952 int read_udp_socket(int fd,char *buf,int len)
1953 {
1954   int ret;
1955   struct sockaddr sock;
1956   int socklen;
1957   
1958   socklen = sizeof(sock);
1959   bzero((char *)&sock,socklen);
1960   bzero((char *)&lastip,sizeof(lastip));
1961   ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1962   if (ret <= 0) {
1963     DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1964     return(0);
1965   }
1966
1967   lastip = *(struct in_addr *) &sock.sa_data[2];
1968   lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1969
1970   DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1971              inet_ntoa(lastip), lastport, ret));
1972
1973   return(ret);
1974 }
1975
1976 /****************************************************************************
1977 read data from a device with a timout in msec.
1978 mincount = if timeout, minimum to read before returning
1979 maxcount = number to be read.
1980 ****************************************************************************/
1981 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1982 {
1983   fd_set fds;
1984   int selrtn;
1985   int readret;
1986   int nread = 0;
1987   struct timeval timeout;
1988
1989   /* just checking .... */
1990   if (maxcnt <= 0) return(0);
1991
1992   smb_read_error = 0;
1993
1994   /* Blocking read */
1995   if (time_out <= 0) {
1996     if (mincnt == 0) mincnt = maxcnt;
1997
1998     while (nread < mincnt) {
1999       readret = read(fd, buf + nread, maxcnt - nread);
2000       if (readret == 0) {
2001         smb_read_error = READ_EOF;
2002         return -1;
2003       }
2004
2005       if (readret == -1) {
2006         smb_read_error = READ_ERROR;
2007         return -1;
2008       }
2009       nread += readret;
2010     }
2011     return(nread);
2012   }
2013   
2014   /* Most difficult - timeout read */
2015   /* If this is ever called on a disk file and 
2016          mincnt is greater then the filesize then
2017          system performance will suffer severely as 
2018          select always return true on disk files */
2019
2020   /* Set initial timeout */
2021   timeout.tv_sec = time_out / 1000;
2022   timeout.tv_usec = 1000 * (time_out % 1000);
2023
2024   for (nread=0; nread<mincnt; ) 
2025     {      
2026       FD_ZERO(&fds);
2027       FD_SET(fd,&fds);
2028       
2029       selrtn = sys_select(&fds,&timeout);
2030
2031       /* Check if error */
2032       if(selrtn == -1) {
2033         /* something is wrong. Maybe the socket is dead? */
2034         smb_read_error = READ_ERROR;
2035         return -1;
2036       }
2037       
2038       /* Did we timeout ? */
2039       if (selrtn == 0) {
2040         smb_read_error = READ_TIMEOUT;
2041         return -1;
2042       }
2043       
2044       readret = read(fd, buf+nread, maxcnt-nread);
2045       if (readret == 0) {
2046         /* we got EOF on the file descriptor */
2047         smb_read_error = READ_EOF;
2048         return -1;
2049       }
2050
2051       if (readret == -1) {
2052         /* the descriptor is probably dead */
2053         smb_read_error = READ_ERROR;
2054         return -1;
2055       }
2056       
2057       nread += readret;
2058     }
2059
2060   /* Return the number we got */
2061   return(nread);
2062 }
2063
2064 /****************************************************************************
2065 read data from the client. Maxtime is in milliseconds
2066 ****************************************************************************/
2067 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2068 {
2069   fd_set fds;
2070   int selrtn;
2071   int nread;
2072   struct timeval timeout;
2073  
2074   FD_ZERO(&fds);
2075   FD_SET(fd,&fds);
2076
2077   timeout.tv_sec = maxtime / 1000;
2078   timeout.tv_usec = (maxtime % 1000) * 1000;
2079
2080   selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2081
2082   if (!FD_ISSET(fd,&fds))
2083     return 0;
2084
2085   nread = read_udp_socket(fd, buffer, bufsize);
2086
2087   /* return the number got */
2088   return(nread);
2089 }
2090
2091 /*******************************************************************
2092 find the difference in milliseconds between two struct timeval
2093 values
2094 ********************************************************************/
2095 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2096 {
2097   return((tvalnew->tv_sec - tvalold->tv_sec)*1000 + 
2098          ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);  
2099 }
2100
2101 /****************************************************************************
2102 send a keepalive packet (rfc1002)
2103 ****************************************************************************/
2104 BOOL send_keepalive(int client)
2105 {
2106   unsigned char buf[4];
2107
2108   buf[0] = 0x85;
2109   buf[1] = buf[2] = buf[3] = 0;
2110
2111   return(write_data(client,(char *)buf,4) == 4);
2112 }
2113
2114
2115
2116 /****************************************************************************
2117   read data from the client, reading exactly N bytes. 
2118 ****************************************************************************/
2119 int read_data(int fd,char *buffer,int N)
2120 {
2121   int  ret;
2122   int total=0;  
2123  
2124   smb_read_error = 0;
2125
2126   while (total < N)
2127     {
2128       ret = read(fd,buffer + total,N - total);
2129       if (ret == 0) {
2130         smb_read_error = READ_EOF;
2131         return 0;
2132       }
2133       if (ret == -1) {
2134         smb_read_error = READ_ERROR;
2135         return -1;
2136       }
2137       total += ret;
2138     }
2139   return total;
2140 }
2141
2142
2143 /****************************************************************************
2144   write data to a fd 
2145 ****************************************************************************/
2146 int write_data(int fd,char *buffer,int N)
2147 {
2148   int total=0;
2149   int ret;
2150
2151   while (total < N)
2152     {
2153       ret = write(fd,buffer + total,N - total);
2154
2155       if (ret == -1) return -1;
2156       if (ret == 0) return total;
2157
2158       total += ret;
2159     }
2160   return total;
2161 }
2162
2163
2164 /****************************************************************************
2165 transfer some data between two fd's
2166 ****************************************************************************/
2167 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2168 {
2169   static char *buf=NULL;  
2170   static int size=0;
2171   char *buf1,*abuf;
2172   int total = 0;
2173
2174   DEBUG(4,("transfer_file %d  (head=%d) called\n",n,headlen));
2175
2176   if (size == 0) {
2177     size = lp_readsize();
2178     size = MAX(size,1024);
2179   }
2180
2181   while (!buf && size>0) {
2182     buf = (char *)Realloc(buf,size+8);
2183     if (!buf) size /= 2;
2184   }
2185
2186   if (!buf) {
2187     DEBUG(0,("Can't allocate transfer buffer!\n"));
2188     exit(1);
2189   }
2190
2191   abuf = buf + (align%8);
2192
2193   if (header)
2194     n += headlen;
2195
2196   while (n > 0)
2197     {
2198       int s = MIN(n,size);
2199       int ret,ret2=0;
2200
2201       ret = 0;
2202
2203       if (header && (headlen >= MIN(s,1024))) {
2204         buf1 = header;
2205         s = headlen;
2206         ret = headlen;
2207         headlen = 0;
2208         header = NULL;
2209       } else {
2210         buf1 = abuf;
2211       }
2212
2213       if (header && headlen > 0)
2214         {
2215           ret = MIN(headlen,size);
2216           memcpy(buf1,header,ret);
2217           headlen -= ret;
2218           header += ret;
2219           if (headlen <= 0) header = NULL;
2220         }
2221
2222       if (s > ret)
2223         ret += read(infd,buf1+ret,s-ret);
2224
2225       if (ret > 0)
2226         {
2227           ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2228           if (ret2 > 0) total += ret2;
2229           /* if we can't write then dump excess data */
2230           if (ret2 != ret)
2231             transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2232         }
2233       if (ret <= 0 || ret2 != ret)
2234         return(total);
2235       n -= ret;
2236     }
2237   return(total);
2238 }
2239
2240
2241 /****************************************************************************
2242 read 4 bytes of a smb packet and return the smb length of the packet
2243 possibly store the result in the buffer
2244 ****************************************************************************/
2245 int read_smb_length(int fd,char *inbuf,int timeout)
2246 {
2247   char *buffer;
2248   char buf[4];
2249   int len=0, msg_type;
2250   BOOL ok=False;
2251
2252   if (inbuf)
2253     buffer = inbuf;
2254   else
2255     buffer = buf;
2256
2257   while (!ok)
2258     {
2259       if (timeout > 0)
2260         ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2261       else 
2262         ok = (read_data(fd,buffer,4) == 4);
2263
2264       if (!ok)
2265         return(-1);
2266
2267       len = smb_len(buffer);
2268       msg_type = CVAL(buffer,0);
2269
2270       if (msg_type == 0x85) 
2271         DEBUG(5,("Got keepalive packet\n"));
2272     }
2273
2274   DEBUG(10,("got smb length of %d\n",len));
2275
2276   return(len);
2277 }
2278
2279
2280
2281 /****************************************************************************
2282   read an smb from a fd. Note that the buffer *MUST* be of size
2283   BUFFER_SIZE+SAFETY_MARGIN.
2284 The timeout is in milli seconds
2285 ****************************************************************************/
2286 BOOL receive_smb(int fd,char *buffer, int timeout)
2287 {
2288   int len,ret;
2289
2290   smb_read_error = 0;
2291
2292   bzero(buffer,smb_size + 100);
2293
2294   len = read_smb_length(fd,buffer,timeout);
2295   if (len < 0)
2296     return(False);
2297
2298   if (len > BUFFER_SIZE) {
2299     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2300     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2301       exit(1);
2302   }
2303
2304   if(len > 0) {
2305     ret = read_data(fd,buffer+4,len);
2306     if (ret != len) {
2307       smb_read_error = READ_ERROR;
2308       return False;
2309     }
2310   }
2311   return(True);
2312 }
2313
2314 /****************************************************************************
2315   read a message from a udp fd.
2316 The timeout is in milli seconds
2317 ****************************************************************************/
2318 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2319 {
2320   struct sockaddr_in from;
2321   int fromlen = sizeof(from);
2322   int32 msg_len = 0;
2323
2324   if(timeout != 0)
2325   {
2326     struct timeval to;
2327     fd_set fds;
2328     int selrtn;
2329
2330     FD_ZERO(&fds);
2331     FD_SET(fd,&fds);
2332
2333     to.tv_sec = timeout / 1000;
2334     to.tv_usec = (timeout % 1000) * 1000;
2335
2336     selrtn = sys_select(&fds,&to);
2337
2338     /* Check if error */
2339     if(selrtn == -1) 
2340     {
2341       /* something is wrong. Maybe the socket is dead? */
2342       smb_read_error = READ_ERROR;
2343       return False;
2344     } 
2345     
2346     /* Did we timeout ? */
2347     if (selrtn == 0) 
2348     {
2349       smb_read_error = READ_TIMEOUT;
2350       return False;
2351     }
2352   }
2353
2354   /*
2355    * Read a loopback udp message.
2356    */
2357   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2358                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2359                      (struct sockaddr *)&from, &fromlen);
2360
2361   if(msg_len < 0)
2362   {
2363     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2364     return False;
2365   }
2366
2367   /* Validate message length. */
2368   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2369   {
2370     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2371               msg_len, 
2372               buffer_len  - UDP_CMD_HEADER_LEN));
2373     return False;
2374   }
2375
2376   /* Validate message from address (must be localhost). */
2377   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2378   {
2379     DEBUG(0,("receive_local_message: invalid 'from' address \
2380 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2381    return False;
2382   }
2383
2384   /* Setup the message header */
2385   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2386   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2387
2388   return True;
2389 }
2390
2391 /****************************************************************************
2392  structure to hold a linked list of local udp messages.
2393  for processing.
2394 ****************************************************************************/
2395
2396 typedef struct _udp_message_list {
2397    struct _udp_message_list *msg_next;
2398    char *msg_buf;
2399    int msg_len;
2400 } udp_message_list;
2401
2402 static udp_message_list *udp_msg_head = NULL;
2403
2404 /****************************************************************************
2405  Function to push a linked list of local udp messages ready
2406  for processing.
2407 ****************************************************************************/
2408 BOOL push_local_message(char *buf, int msg_len)
2409 {
2410   udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
2411
2412   if(msg == NULL)
2413   {
2414     DEBUG(0,("push_local_message: malloc fail (1)\n"));
2415     return False;
2416   }
2417
2418   msg->msg_buf = (char *)malloc(msg_len);
2419   if(msg->msg_buf == NULL)
2420   {
2421     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2422     free((char *)msg);
2423     return False;
2424   }
2425
2426   memcpy(msg->msg_buf, buf, msg_len);
2427   msg->msg_len = msg_len;
2428
2429   msg->msg_next = udp_msg_head;
2430   udp_msg_head = msg;
2431
2432   return True;
2433 }
2434
2435 /****************************************************************************
2436   Do a select on an two fd's - with timeout. 
2437
2438   If a local udp message has been pushed onto the
2439   queue (this can only happen during oplock break
2440   processing) return this first.
2441
2442   If the first smbfd is ready then read an smb from it.
2443   if the second (loopback UDP) fd is ready then read a message
2444   from it and setup the buffer header to identify the length
2445   and from address.
2446   Returns False on timeout or error.
2447   Else returns True.
2448
2449 The timeout is in milli seconds
2450 ****************************************************************************/
2451 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2452                            char *buffer, int buffer_len, 
2453                            int timeout, BOOL *got_smb)
2454 {
2455   fd_set fds;
2456   int selrtn;
2457   struct timeval to;
2458
2459   *got_smb = False;
2460
2461   /*
2462    * Check to see if we already have a message on the udp queue.
2463    * If so - copy and return it.
2464    */
2465
2466   if(udp_msg_head)
2467   {
2468     udp_message_list *msg = udp_msg_head;
2469     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2470     udp_msg_head = msg->msg_next;
2471
2472     /* Free the message we just copied. */
2473     free((char *)msg->msg_buf);
2474     free((char *)msg);
2475     return True;
2476   }
2477
2478   FD_ZERO(&fds);
2479   FD_SET(smbfd,&fds);
2480   FD_SET(oplock_fd,&fds);
2481
2482   to.tv_sec = timeout / 1000;
2483   to.tv_usec = (timeout % 1000) * 1000;
2484
2485   selrtn = sys_select(&fds,timeout>0?&to:NULL);
2486
2487   /* Check if error */
2488   if(selrtn == -1) {
2489     /* something is wrong. Maybe the socket is dead? */
2490     smb_read_error = READ_ERROR;
2491     return False;
2492   } 
2493     
2494   /* Did we timeout ? */
2495   if (selrtn == 0) {
2496     smb_read_error = READ_TIMEOUT;
2497     return False;
2498   }
2499
2500   if (FD_ISSET(smbfd,&fds))
2501   {
2502     *got_smb = True;
2503     return receive_smb(smbfd, buffer, 0);
2504   }
2505   else
2506   {
2507     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2508   }
2509 }
2510
2511 /****************************************************************************
2512   send an smb to a fd 
2513 ****************************************************************************/
2514 BOOL send_smb(int fd,char *buffer)
2515 {
2516   int len;
2517   int ret,nwritten=0;
2518   len = smb_len(buffer) + 4;
2519
2520   while (nwritten < len)
2521     {
2522       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2523       if (ret <= 0)
2524         {
2525           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2526           close_sockets();
2527           exit(1);
2528         }
2529       nwritten += ret;
2530     }
2531
2532
2533   return True;
2534 }
2535
2536
2537 /****************************************************************************
2538 find a pointer to a netbios name
2539 ****************************************************************************/
2540 char *name_ptr(char *buf,int ofs)
2541 {
2542   unsigned char c = *(unsigned char *)(buf+ofs);
2543
2544   if ((c & 0xC0) == 0xC0)
2545     {
2546       uint16 l;
2547       char p[2];
2548       memcpy(p,buf+ofs,2);
2549       p[0] &= ~0xC0;
2550       l = RSVAL(p,0);
2551       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2552       return(buf + l);
2553     }
2554   else
2555     return(buf+ofs);
2556 }  
2557
2558 /****************************************************************************
2559 extract a netbios name from a buf
2560 ****************************************************************************/
2561 int name_extract(char *buf,int ofs,char *name)
2562 {
2563   char *p = name_ptr(buf,ofs);
2564   int d = PTR_DIFF(p,buf+ofs);
2565   strcpy(name,"");
2566   if (d < -50 || d > 50) return(0);
2567   return(name_interpret(p,name));
2568 }
2569   
2570 /****************************************************************************
2571 return the total storage length of a mangled name
2572 ****************************************************************************/
2573 int name_len( char *s )
2574   {
2575   int len;
2576
2577   /* If the two high bits of the byte are set, return 2. */
2578   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2579     return(2);
2580
2581   /* Add up the length bytes. */
2582   for( len = 1; (*s); s += (*s) + 1 )
2583     {
2584     len += *s + 1;
2585     }
2586
2587   return( len );
2588   } /* name_len */
2589
2590 /****************************************************************************
2591 send a single packet to a port on another machine
2592 ****************************************************************************/
2593 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2594 {
2595   BOOL ret;
2596   int out_fd;
2597   struct sockaddr_in sock_out;
2598
2599   if (passive)
2600     return(True);
2601
2602   /* create a socket to write to */
2603   out_fd = socket(AF_INET, type, 0);
2604   if (out_fd == -1) 
2605     {
2606       DEBUG(0,("socket failed"));
2607       return False;
2608     }
2609
2610   /* set the address and port */
2611   bzero((char *)&sock_out,sizeof(sock_out));
2612   putip((char *)&sock_out.sin_addr,(char *)&ip);
2613   sock_out.sin_port = htons( port );
2614   sock_out.sin_family = AF_INET;
2615   
2616   if (DEBUGLEVEL > 0)
2617     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2618              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2619         
2620   /* send it */
2621   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2622
2623   if (!ret)
2624     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2625              inet_ntoa(ip),port,strerror(errno)));
2626
2627   close(out_fd);
2628   return(ret);
2629 }
2630
2631 /*******************************************************************
2632 sleep for a specified number of milliseconds
2633 ********************************************************************/
2634 void msleep(int t)
2635 {
2636   int tdiff=0;
2637   struct timeval tval,t1,t2;  
2638   fd_set fds;
2639
2640   GetTimeOfDay(&t1);
2641   GetTimeOfDay(&t2);
2642   
2643   while (tdiff < t) {
2644     tval.tv_sec = (t-tdiff)/1000;
2645     tval.tv_usec = 1000*((t-tdiff)%1000);
2646  
2647     FD_ZERO(&fds);
2648     errno = 0;
2649     sys_select(&fds,&tval);
2650
2651     GetTimeOfDay(&t2);
2652     tdiff = TvalDiff(&t1,&t2);
2653   }
2654 }
2655
2656 /****************************************************************************
2657 check if a string is part of a list
2658 ****************************************************************************/
2659 BOOL in_list(char *s,char *list,BOOL casesensitive)
2660 {
2661   pstring tok;
2662   char *p=list;
2663
2664   if (!list) return(False);
2665
2666   while (next_token(&p,tok,LIST_SEP))
2667     {
2668       if (casesensitive) {
2669         if (strcmp(tok,s) == 0)
2670           return(True);
2671       } else {
2672         if (StrCaseCmp(tok,s) == 0)
2673           return(True);
2674       }
2675     }
2676   return(False);
2677 }
2678
2679 /* this is used to prevent lots of mallocs of size 1 */
2680 static char *null_string = NULL;
2681
2682 /****************************************************************************
2683 set a string value, allocing the space for the string
2684 ****************************************************************************/
2685 BOOL string_init(char **dest,char *src)
2686 {
2687   int l;
2688   if (!src)     
2689     src = "";
2690
2691   l = strlen(src);
2692
2693   if (l == 0)
2694     {
2695       if (!null_string)
2696         null_string = (char *)malloc(1);
2697
2698       *null_string = 0;
2699       *dest = null_string;
2700     }
2701   else
2702     {
2703       (*dest) = (char *)malloc(l+1);
2704       if ((*dest) == NULL) {
2705               DEBUG(0,("Out of memory in string_init\n"));
2706               return False;
2707       }
2708
2709       strcpy(*dest,src);
2710     }
2711   return(True);
2712 }
2713
2714 /****************************************************************************
2715 free a string value
2716 ****************************************************************************/
2717 void string_free(char **s)
2718 {
2719   if (!s || !(*s)) return;
2720   if (*s == null_string)
2721     *s = NULL;
2722   if (*s) free(*s);
2723   *s = NULL;
2724 }
2725
2726 /****************************************************************************
2727 set a string value, allocing the space for the string, and deallocating any 
2728 existing space
2729 ****************************************************************************/
2730 BOOL string_set(char **dest,char *src)
2731 {
2732   string_free(dest);
2733
2734   return(string_init(dest,src));
2735 }
2736
2737 /****************************************************************************
2738 substitute a string for a pattern in another string. Make sure there is 
2739 enough room!
2740
2741 This routine looks for pattern in s and replaces it with 
2742 insert. It may do multiple replacements.
2743
2744 return True if a substitution was done.
2745 ****************************************************************************/
2746 BOOL string_sub(char *s,char *pattern,char *insert)
2747 {
2748   BOOL ret = False;
2749   char *p;
2750   int ls,lp,li;
2751
2752   if (!insert || !pattern || !s) return(False);
2753
2754   ls = strlen(s);
2755   lp = strlen(pattern);
2756   li = strlen(insert);
2757
2758   if (!*pattern) return(False);
2759
2760   while (lp <= ls && (p = strstr(s,pattern)))
2761     {
2762       ret = True;
2763       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2764       memcpy(p,insert,li);
2765       s = p + li;
2766       ls = strlen(s);
2767     }
2768   return(ret);
2769 }
2770
2771
2772
2773 /*********************************************************
2774 * Recursive routine that is called by mask_match.
2775 * Does the actual matching.
2776 *********************************************************/
2777 BOOL do_match(char *str, char *regexp, int case_sig)
2778 {
2779   char *p;
2780
2781   for( p = regexp; *p && *str; ) {
2782     switch(*p) {
2783     case '?':
2784       str++; p++;
2785       break;
2786
2787     case '*':
2788       /* Look for a character matching 
2789          the one after the '*' */
2790       p++;
2791       if(!*p)
2792         return True; /* Automatic match */
2793       while(*str) {
2794         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2795           str++;
2796         if(do_match(str,p,case_sig))
2797           return True;
2798         if(!*str)
2799           return False;
2800         else
2801           str++;
2802       }
2803       return False;
2804
2805     default:
2806       if(case_sig) {
2807         if(*str != *p)
2808           return False;
2809       } else {
2810         if(toupper(*str) != toupper(*p))
2811           return False;
2812       }
2813       str++, p++;
2814       break;
2815     }
2816   }
2817   if(!*p && !*str)
2818     return True;
2819
2820   if (!*p && str[0] == '.' && str[1] == 0)
2821     return(True);
2822   
2823   if (!*str && *p == '?')
2824     {
2825       while (*p == '?') p++;
2826       return(!*p);
2827     }
2828
2829   if(!*str && (*p == '*' && p[1] == '\0'))
2830     return True;
2831   return False;
2832 }
2833
2834
2835 /*********************************************************
2836 * Routine to match a given string with a regexp - uses
2837 * simplified regexp that takes * and ? only. Case can be
2838 * significant or not.
2839 *********************************************************/
2840 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2841 {
2842   char *p;
2843   pstring p1, p2;
2844   fstring ebase,eext,sbase,sext;
2845
2846   BOOL matched;
2847
2848   /* Make local copies of str and regexp */
2849   StrnCpy(p1,regexp,sizeof(pstring)-1);
2850   StrnCpy(p2,str,sizeof(pstring)-1);
2851
2852   if (!strchr(p2,'.')) {
2853     strcat(p2,".");
2854   }
2855
2856 /*
2857   if (!strchr(p1,'.')) {
2858     strcat(p1,".");
2859   }
2860 */
2861
2862 #if 0
2863   if (strchr(p1,'.'))
2864     {
2865       string_sub(p1,"*.*","*");
2866       string_sub(p1,".*","*");
2867     }
2868 #endif
2869
2870   /* Remove any *? and ** as they are meaningless */
2871   for(p = p1; *p; p++)
2872     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2873       (void)strcpy( &p[1], &p[2]);
2874
2875   if (strequal(p1,"*")) return(True);
2876
2877   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2878
2879   if (trans2) {
2880     fstrcpy(ebase,p1);
2881     fstrcpy(sbase,p2);
2882   } else {
2883     if ((p=strrchr(p1,'.'))) {
2884       *p = 0;
2885       fstrcpy(ebase,p1);
2886       fstrcpy(eext,p+1);
2887     } else {
2888       fstrcpy(ebase,p1);
2889       eext[0] = 0;
2890     }
2891
2892   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2893     *p = 0;
2894     fstrcpy(sbase,p2);
2895     fstrcpy(sext,p+1);
2896   } else {
2897     fstrcpy(sbase,p2);
2898     fstrcpy(sext,"");
2899   }
2900   }
2901
2902   matched = do_match(sbase,ebase,case_sig) && 
2903     (trans2 || do_match(sext,eext,case_sig));
2904
2905   DEBUG(8,("mask_match returning %d\n", matched));
2906
2907   return matched;
2908 }
2909
2910
2911
2912 /****************************************************************************
2913 become a daemon, discarding the controlling terminal
2914 ****************************************************************************/
2915 void become_daemon(void)
2916 {
2917 #ifndef NO_FORK_DEBUG
2918   if (fork())
2919     exit(0);
2920
2921   /* detach from the terminal */
2922 #ifdef USE_SETSID
2923   setsid();
2924 #else /* USE_SETSID */
2925 #ifdef TIOCNOTTY
2926   {
2927     int i = open("/dev/tty", O_RDWR);
2928     if (i >= 0) 
2929       {
2930         ioctl(i, (int) TIOCNOTTY, (char *)0);      
2931         close(i);
2932       }
2933   }
2934 #endif /* TIOCNOTTY */
2935 #endif /* USE_SETSID */
2936   /* Close fd's 0,1,2. Needed if started by rsh */
2937   close_low_fds();
2938 #endif /* NO_FORK_DEBUG */
2939 }
2940
2941
2942 /****************************************************************************
2943 put up a yes/no prompt
2944 ****************************************************************************/
2945 BOOL yesno(char *p)
2946 {
2947   pstring ans;
2948   printf("%s",p);
2949
2950   if (!fgets(ans,sizeof(ans)-1,stdin))
2951     return(False);
2952
2953   if (*ans == 'y' || *ans == 'Y')
2954     return(True);
2955
2956   return(False);
2957 }
2958
2959 /****************************************************************************
2960 read a line from a file with possible \ continuation chars. 
2961 Blanks at the start or end of a line are stripped.
2962 The string will be allocated if s2 is NULL
2963 ****************************************************************************/
2964 char *fgets_slash(char *s2,int maxlen,FILE *f)
2965 {
2966   char *s=s2;
2967   int len = 0;
2968   int c;
2969   BOOL start_of_line = True;
2970
2971   if (feof(f))
2972     return(NULL);
2973
2974   if (!s2)
2975     {
2976       maxlen = MIN(maxlen,8);
2977       s = (char *)Realloc(s,maxlen);
2978     }
2979
2980   if (!s || maxlen < 2) return(NULL);
2981
2982   *s = 0;
2983
2984   while (len < maxlen-1)
2985     {
2986       c = getc(f);
2987       switch (c)
2988         {
2989         case '\r':
2990           break;
2991         case '\n':
2992           while (len > 0 && s[len-1] == ' ')
2993             {
2994               s[--len] = 0;
2995             }
2996           if (len > 0 && s[len-1] == '\\')
2997             {
2998               s[--len] = 0;
2999               start_of_line = True;
3000               break;
3001             }
3002           return(s);
3003         case EOF:
3004           if (len <= 0 && !s2) 
3005             free(s);
3006           return(len>0?s:NULL);
3007         case ' ':
3008           if (start_of_line)
3009             break;
3010         default:
3011           start_of_line = False;
3012           s[len++] = c;
3013           s[len] = 0;
3014         }
3015       if (!s2 && len > maxlen-3)
3016         {
3017           maxlen *= 2;
3018           s = (char *)Realloc(s,maxlen);
3019           if (!s) return(NULL);
3020         }
3021     }
3022   return(s);
3023 }
3024
3025
3026
3027 /****************************************************************************
3028 set the length of a file from a filedescriptor.
3029 Returns 0 on success, -1 on failure.
3030 ****************************************************************************/
3031 int set_filelen(int fd, long len)
3032 {
3033 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3034    extend a file with ftruncate. Provide alternate implementation
3035    for this */
3036
3037 #if FTRUNCATE_CAN_EXTEND
3038   return ftruncate(fd, len);
3039 #else
3040   struct stat st;
3041   char c = 0;
3042   long currpos = lseek(fd, 0L, SEEK_CUR);
3043
3044   if(currpos < 0)
3045     return -1;
3046   /* Do an fstat to see if the file is longer than
3047      the requested size (call ftruncate),
3048      or shorter, in which case seek to len - 1 and write 1
3049      byte of zero */
3050   if(fstat(fd, &st)<0)
3051     return -1;
3052
3053 #ifdef S_ISFIFO
3054   if (S_ISFIFO(st.st_mode)) return 0;
3055 #endif
3056
3057   if(st.st_size == len)
3058     return 0;
3059   if(st.st_size > len)
3060     return ftruncate(fd, len);
3061
3062   if(lseek(fd, len-1, SEEK_SET) != len -1)
3063     return -1;
3064   if(write(fd, &c, 1)!=1)
3065     return -1;
3066   /* Seek to where we were */
3067   lseek(fd, currpos, SEEK_SET);
3068   return 0;
3069 #endif
3070 }
3071
3072
3073 /****************************************************************************
3074 return the byte checksum of some data
3075 ****************************************************************************/
3076 int byte_checksum(char *buf,int len)
3077 {
3078   unsigned char *p = (unsigned char *)buf;
3079   int ret = 0;
3080   while (len--)
3081     ret += *p++;
3082   return(ret);
3083 }
3084
3085
3086
3087 #ifdef HPUX
3088 /****************************************************************************
3089 this is a version of setbuffer() for those machines that only have setvbuf
3090 ****************************************************************************/
3091  void setbuffer(FILE *f,char *buf,int bufsize)
3092 {
3093   setvbuf(f,buf,_IOFBF,bufsize);
3094 }
3095 #endif
3096
3097
3098 /****************************************************************************
3099 parse out a directory name from a path name. Assumes dos style filenames.
3100 ****************************************************************************/
3101 char *dirname_dos(char *path,char *buf)
3102 {
3103   char *p = strrchr(path,'\\');
3104
3105   if (!p)
3106     strcpy(buf,path);
3107   else
3108     {
3109       *p = 0;
3110       strcpy(buf,path);
3111       *p = '\\';
3112     }
3113
3114   return(buf);
3115 }
3116
3117
3118 /****************************************************************************
3119 parse out a filename from a path name. Assumes dos style filenames.
3120 ****************************************************************************/
3121 static char *filename_dos(char *path,char *buf)
3122 {
3123   char *p = strrchr(path,'\\');
3124
3125   if (!p)
3126     strcpy(buf,path);
3127   else
3128     strcpy(buf,p+1);
3129
3130   return(buf);
3131 }
3132
3133
3134
3135 /****************************************************************************
3136 expand a pointer to be a particular size
3137 ****************************************************************************/
3138 void *Realloc(void *p,int size)
3139 {
3140   void *ret=NULL;
3141
3142   if (size == 0) {
3143     if (p) free(p);
3144     DEBUG(5,("Realloc asked for 0 bytes\n"));
3145     return NULL;
3146   }
3147
3148   if (!p)
3149     ret = (void *)malloc(size);
3150   else
3151     ret = (void *)realloc(p,size);
3152
3153   if (!ret)
3154     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3155
3156   return(ret);
3157 }
3158
3159 #ifdef NOSTRDUP
3160 /****************************************************************************
3161 duplicate a string
3162 ****************************************************************************/
3163  char *strdup(char *s)
3164 {
3165   char *ret = NULL;
3166   if (!s) return(NULL);
3167   ret = (char *)malloc(strlen(s)+1);
3168   if (!ret) return(NULL);
3169   strcpy(ret,s);
3170   return(ret);
3171 }
3172 #endif
3173
3174
3175 /****************************************************************************
3176   Signal handler for SIGPIPE (write on a disconnected socket) 
3177 ****************************************************************************/
3178 void Abort(void )
3179 {
3180   DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3181   exit(2);
3182 }
3183
3184 /****************************************************************************
3185 get my own name and IP
3186 ****************************************************************************/
3187 BOOL get_myname(char *my_name,struct in_addr *ip)
3188 {
3189   struct hostent *hp;
3190   pstring hostname;
3191
3192   *hostname = 0;
3193
3194   /* get my host name */
3195   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
3196     {
3197       DEBUG(0,("gethostname failed\n"));
3198       return False;
3199     } 
3200
3201   /* get host info */
3202   if ((hp = Get_Hostbyname(hostname)) == 0) 
3203     {
3204       DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3205       return False;
3206     }
3207
3208   if (my_name)
3209     {
3210       /* split off any parts after an initial . */
3211       char *p = strchr(hostname,'.');
3212       if (p) *p = 0;
3213
3214       fstrcpy(my_name,hostname);
3215     }
3216
3217   if (ip)
3218     putip((char *)ip,(char *)hp->h_addr);
3219
3220   return(True);
3221 }
3222
3223
3224 /****************************************************************************
3225 true if two IP addresses are equal
3226 ****************************************************************************/
3227 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3228 {
3229   uint32 a1,a2;
3230   a1 = ntohl(ip1.s_addr);
3231   a2 = ntohl(ip2.s_addr);
3232   return(a1 == a2);
3233 }
3234
3235
3236 /****************************************************************************
3237 open a socket of the specified type, port and address for incoming data
3238 ****************************************************************************/
3239 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3240 {
3241   struct hostent *hp;
3242   struct sockaddr_in sock;
3243   pstring host_name;
3244   int res;
3245
3246   /* get my host name */
3247   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
3248     { DEBUG(0,("gethostname failed\n")); return -1; } 
3249
3250   /* get host info */
3251   if ((hp = Get_Hostbyname(host_name)) == 0) 
3252     {
3253       DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3254       return -1;
3255     }
3256   
3257   bzero((char *)&sock,sizeof(sock));
3258   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3259 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3260   sock.sin_len = sizeof(sock);
3261 #endif
3262   sock.sin_port = htons( port );
3263   sock.sin_family = hp->h_addrtype;
3264   sock.sin_addr.s_addr = socket_addr;
3265   res = socket(hp->h_addrtype, type, 0);
3266   if (res == -1) 
3267     { DEBUG(0,("socket failed\n")); return -1; }
3268
3269   {
3270     int one=1;
3271     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3272   }
3273
3274   /* now we've got a socket - we need to bind it */
3275   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
3276     { 
3277       if (port) {
3278         if (port == SMB_PORT || port == NMB_PORT)
3279           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3280                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
3281         close(res); 
3282
3283         if (dlevel > 0 && port < 1000)
3284           port = 7999;
3285
3286         if (port >= 1000 && port < 9000)
3287           return(open_socket_in(type,port+1,dlevel,socket_addr));
3288       }
3289
3290       return(-1); 
3291     }
3292   DEBUG(3,("bind succeeded on port %d\n",port));
3293
3294   return res;
3295 }
3296
3297
3298 /****************************************************************************
3299   create an outgoing socket
3300   **************************************************************************/
3301 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3302 {
3303   struct sockaddr_in sock_out;
3304   int res,ret;
3305   int connect_loop = 250; /* 250 milliseconds */
3306   int loops = (timeout * 1000) / connect_loop;
3307
3308   /* create a socket to write to */
3309   res = socket(PF_INET, type, 0);
3310   if (res == -1) 
3311     { DEBUG(0,("socket error\n")); return -1; }
3312
3313   if (type != SOCK_STREAM) return(res);
3314   
3315   bzero((char *)&sock_out,sizeof(sock_out));
3316   putip((char *)&sock_out.sin_addr,(char *)addr);
3317   
3318   sock_out.sin_port = htons( port );
3319   sock_out.sin_family = PF_INET;
3320
3321   /* set it non-blocking */
3322   set_blocking(res,False);
3323
3324   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3325   
3326   /* and connect it to the destination */
3327 connect_again:
3328   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3329
3330   /* Some systems return EAGAIN when they mean EINPROGRESS */
3331   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3332         errno == EAGAIN) && loops--) {
3333     msleep(connect_loop);
3334     goto connect_again;
3335   }
3336
3337   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3338          errno == EAGAIN)) {
3339       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3340       close(res);
3341       return -1;
3342   }
3343
3344 #ifdef EISCONN
3345   if (ret < 0 && errno == EISCONN) {
3346     errno = 0;
3347     ret = 0;
3348   }
3349 #endif
3350
3351   if (ret < 0) {
3352     DEBUG(1,("error connecting to %s:%d (%s)\n",
3353              inet_ntoa(*addr),port,strerror(errno)));
3354     return -1;
3355   }
3356
3357   /* set it blocking again */
3358   set_blocking(res,True);
3359
3360   return res;
3361 }
3362
3363
3364 /****************************************************************************
3365 interpret a protocol description string, with a default
3366 ****************************************************************************/
3367 int interpret_protocol(char *str,int def)
3368 {
3369   if (strequal(str,"NT1"))
3370     return(PROTOCOL_NT1);
3371   if (strequal(str,"LANMAN2"))
3372     return(PROTOCOL_LANMAN2);
3373   if (strequal(str,"LANMAN1"))
3374     return(PROTOCOL_LANMAN1);
3375   if (strequal(str,"CORE"))
3376     return(PROTOCOL_CORE);
3377   if (strequal(str,"COREPLUS"))
3378     return(PROTOCOL_COREPLUS);
3379   if (strequal(str,"CORE+"))
3380     return(PROTOCOL_COREPLUS);
3381   
3382   DEBUG(0,("Unrecognised protocol level %s\n",str));
3383   
3384   return(def);
3385 }
3386
3387 /****************************************************************************
3388 interpret a security level
3389 ****************************************************************************/
3390 int interpret_security(char *str,int def)
3391 {
3392   if (strequal(str,"SERVER"))
3393     return(SEC_SERVER);
3394   if (strequal(str,"USER"))
3395     return(SEC_USER);
3396   if (strequal(str,"SHARE"))
3397     return(SEC_SHARE);
3398   
3399   DEBUG(0,("Unrecognised security level %s\n",str));
3400   
3401   return(def);
3402 }
3403
3404
3405 /****************************************************************************
3406 interpret an internet address or name into an IP address in 4 byte form
3407 ****************************************************************************/
3408 uint32 interpret_addr(char *str)
3409 {
3410   struct hostent *hp;
3411   uint32 res;
3412   int i;
3413   BOOL pure_address = True;
3414
3415   if (strcmp(str,"0.0.0.0") == 0) return(0);
3416   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3417
3418   for (i=0; pure_address && str[i]; i++)
3419     if (!(isdigit(str[i]) || str[i] == '.')) 
3420       pure_address = False;
3421
3422   /* if it's in the form of an IP address then get the lib to interpret it */
3423   if (pure_address) {
3424     res = inet_addr(str);
3425   } else {
3426     /* otherwise assume it's a network name of some sort and use 
3427        Get_Hostbyname */
3428     if ((hp = Get_Hostbyname(str)) == 0) {
3429       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3430       return 0;
3431     }
3432     if(hp->h_addr == NULL) {
3433       DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3434       return 0;
3435     }
3436     putip((char *)&res,(char *)hp->h_addr);
3437   }
3438
3439   if (res == (uint32)-1) return(0);
3440
3441   return(res);
3442 }
3443
3444 /*******************************************************************
3445   a convenient addition to interpret_addr()
3446   ******************************************************************/
3447 struct in_addr *interpret_addr2(char *str)
3448 {
3449   static struct in_addr ret;
3450   uint32 a = interpret_addr(str);
3451   ret.s_addr = a;
3452   return(&ret);
3453 }
3454
3455 /*******************************************************************
3456   check if an IP is the 0.0.0.0
3457   ******************************************************************/
3458 BOOL zero_ip(struct in_addr ip)
3459 {
3460   uint32 a;
3461   putip((char *)&a,(char *)&ip);
3462   return(a == 0);
3463 }
3464
3465
3466 /*******************************************************************
3467  matchname - determine if host name matches IP address 
3468  ******************************************************************/
3469 static BOOL matchname(char *remotehost,struct in_addr  addr)
3470 {
3471   struct hostent *hp;
3472   int     i;
3473   
3474   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3475     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3476     return False;
3477   } 
3478
3479   /*
3480    * Make sure that gethostbyname() returns the "correct" host name.
3481    * Unfortunately, gethostbyname("localhost") sometimes yields
3482    * "localhost.domain". Since the latter host name comes from the
3483    * local DNS, we just have to trust it (all bets are off if the local
3484    * DNS is perverted). We always check the address list, though.
3485    */
3486   
3487   if (strcasecmp(remotehost, hp->h_name)
3488       && strcasecmp(remotehost, "localhost")) {
3489     DEBUG(0,("host name/name mismatch: %s != %s",
3490              remotehost, hp->h_name));
3491     return False;
3492   }
3493         
3494   /* Look up the host address in the address list we just got. */
3495   for (i = 0; hp->h_addr_list[i]; i++) {
3496     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3497       return True;
3498   }
3499
3500   /*
3501    * The host name does not map to the original host address. Perhaps
3502    * someone has compromised a name server. More likely someone botched
3503    * it, but that could be dangerous, too.
3504    */
3505   
3506   DEBUG(0,("host name/address mismatch: %s != %s",
3507            inet_ntoa(addr), hp->h_name));
3508   return False;
3509 }
3510
3511 /*******************************************************************
3512  Reset the 'done' variables so after a client process is created
3513  from a fork call these calls will be re-done. This should be
3514  expanded if more variables need reseting.
3515  ******************************************************************/
3516
3517 static BOOL global_client_name_done = False;
3518 static BOOL global_client_addr_done = False;
3519
3520 void reset_globals_after_fork()
3521 {
3522   global_client_name_done = False;
3523   global_client_addr_done = False;
3524 }
3525  
3526 /*******************************************************************
3527  return the DNS name of the client 
3528  ******************************************************************/
3529 char *client_name(void)
3530 {
3531   extern int Client;
3532   struct sockaddr sa;
3533   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3534   int     length = sizeof(sa);
3535   static pstring name_buf;
3536   struct hostent *hp;
3537
3538   if (global_client_name_done) 
3539     return name_buf;
3540
3541   strcpy(name_buf,"UNKNOWN");
3542
3543   if (Client == -1) {
3544           return name_buf;
3545   }
3546
3547   if (getpeername(Client, &sa, &length) < 0) {
3548     DEBUG(0,("getpeername failed\n"));
3549     return name_buf;
3550   }
3551
3552   /* Look up the remote host name. */
3553   if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3554                           sizeof(sockin->sin_addr),
3555                           AF_INET)) == 0) {
3556     DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3557     StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3558   } else {
3559     StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3560     if (!matchname(name_buf, sockin->sin_addr)) {
3561       DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3562       strcpy(name_buf,"UNKNOWN");
3563     }
3564   }
3565   global_client_name_done = True;
3566   return name_buf;
3567 }
3568
3569 /*******************************************************************
3570  return the IP addr of the client as a string 
3571  ******************************************************************/
3572 char *client_addr(void)
3573 {
3574   extern int Client;
3575   struct sockaddr sa;
3576   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3577   int     length = sizeof(sa);
3578   static fstring addr_buf;
3579
3580   if (global_client_addr_done) 
3581     return addr_buf;
3582
3583   strcpy(addr_buf,"0.0.0.0");
3584
3585   if (Client == -1) {
3586           return addr_buf;
3587   }
3588
3589   if (getpeername(Client, &sa, &length) < 0) {
3590     DEBUG(0,("getpeername failed\n"));
3591     return addr_buf;
3592   }
3593
3594   fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3595
3596   global_client_addr_done = True;
3597   return addr_buf;
3598 }
3599
3600 char *automount_server(char *user_name)
3601 {
3602         static pstring server_name;
3603
3604 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3605         int nis_error;        /* returned by yp all functions */
3606         char *nis_result;     /* yp_match inits this */
3607         int nis_result_len;  /* and set this */
3608         char *nis_domain;     /* yp_get_default_domain inits this */
3609         char *nis_map = (char *)lp_nis_home_map_name();
3610         int home_server_len;
3611
3612         /* set to default of local machine */
3613         pstrcpy(server_name, local_machine);
3614
3615         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3616         {
3617                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3618         }
3619
3620         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3621
3622         if ((nis_error = yp_match(nis_domain, nis_map,
3623                         user_name, strlen(user_name),
3624                         &nis_result, &nis_result_len)) != 0)
3625         {
3626                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3627         }
3628
3629         if (!nis_error && lp_nis_home_map())
3630         {
3631                 home_server_len = strcspn(nis_result,":");
3632                 DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
3633                 if (home_server_len > sizeof(pstring))
3634                 {
3635                         home_server_len = sizeof(pstring);
3636                 }
3637                 strncpy(server_name, nis_result, home_server_len);
3638         }
3639 #else
3640         /* use the local machine name instead of the auto-map server */
3641         pstrcpy(server_name, local_machine);
3642 #endif
3643
3644         DEBUG(4,("Home server: %s\n", server_name));
3645
3646         return server_name;
3647 }
3648
3649 /*******************************************************************
3650 sub strings with useful parameters
3651 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3652 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3653 ********************************************************************/
3654 void standard_sub_basic(char *str)
3655 {
3656         char *s, *p;
3657         char pidstr[10];
3658         struct passwd *pass;
3659         char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3660
3661         for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3662         {
3663                 switch (*(p+1))
3664                 {
3665                         case 'G' :
3666                         {
3667                                 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3668                                 {
3669                                         string_sub(p,"%G",gidtoname(pass->pw_gid));
3670                                 }
3671                                 else
3672                                 {
3673                                         p += 2;
3674                                 }
3675                                 break;
3676                         }
3677                         case 'N' : string_sub(p,"%N", automount_server(username)); break;
3678                         case 'I' : string_sub(p,"%I", client_addr()); break;
3679                         case 'L' : string_sub(p,"%L", local_machine); break;
3680                         case 'M' : string_sub(p,"%M", client_name()); break;
3681                         case 'R' : string_sub(p,"%R", remote_proto); break;
3682                         case 'T' : string_sub(p,"%T", timestring()); break;
3683                         case 'U' : string_sub(p,"%U", username); break;
3684                         case 'a' : string_sub(p,"%a", remote_arch); break;
3685                         case 'd' :
3686                         {
3687                                 sprintf(pidstr,"%d",(int)getpid());
3688                                 string_sub(p,"%d", pidstr);
3689                                 break;
3690                         }
3691                         case 'h' : string_sub(p,"%h", myhostname); break;
3692                         case 'm' : string_sub(p,"%m", remote_machine); break;
3693                         case 'v' : string_sub(p,"%v", VERSION); break;
3694                         case '\0': p++; break; /* don't run off end if last character is % */
3695                         default  : p+=2; break;
3696                 }
3697         }
3698         return;
3699 }
3700
3701 /*******************************************************************
3702 are two IPs on the same subnet?
3703 ********************************************************************/
3704 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3705 {
3706   uint32 net1,net2,nmask;
3707
3708   nmask = ntohl(mask.s_addr);
3709   net1  = ntohl(ip1.s_addr);
3710   net2  = ntohl(ip2.s_addr);
3711             
3712   return((net1 & nmask) == (net2 & nmask));
3713 }
3714
3715
3716 /*******************************************************************
3717 write a string in unicoode format
3718 ********************************************************************/
3719 int PutUniCode(char *dst,char *src)
3720 {
3721   int ret = 0;
3722   while (*src) {
3723     dst[ret++] = src[0];
3724     dst[ret++] = 0;    
3725     src++;
3726   }
3727   dst[ret++]=0;
3728   dst[ret++]=0;
3729   return(ret);
3730 }
3731
3732 /****************************************************************************
3733 a wrapper for gethostbyname() that tries with all lower and all upper case 
3734 if the initial name fails
3735 ****************************************************************************/
3736 struct hostent *Get_Hostbyname(char *name)
3737 {
3738   char *name2 = strdup(name);
3739   struct hostent *ret;
3740
3741   if (!name2)
3742     {
3743       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3744       exit(0);
3745     }
3746
3747   if (!isalnum(*name2))
3748     {
3749       free(name2);
3750       return(NULL);
3751     }
3752
3753   ret = sys_gethostbyname(name2);
3754   if (ret != NULL)
3755     {
3756       free(name2);
3757       return(ret);
3758     }
3759
3760   /* try with all lowercase */
3761   strlower(name2);
3762   ret = sys_gethostbyname(name2);
3763   if (ret != NULL)
3764     {
3765       free(name2);
3766       return(ret);
3767     }
3768
3769   /* try with all uppercase */
3770   strupper(name2);
3771   ret = sys_gethostbyname(name2);
3772   if (ret != NULL)
3773     {
3774       free(name2);
3775       return(ret);
3776     }
3777   
3778   /* nothing works :-( */
3779   free(name2);
3780   return(NULL);
3781 }
3782
3783
3784 /****************************************************************************
3785 check if a process exists. Does this work on all unixes?
3786 ****************************************************************************/
3787 BOOL process_exists(int pid)
3788 {
3789         return(kill(pid,0) == 0 || errno != ESRCH);
3790 }
3791
3792
3793 /*******************************************************************
3794 turn a uid into a user name
3795 ********************************************************************/
3796 char *uidtoname(int uid)
3797 {
3798   static char name[40];
3799   struct passwd *pass = getpwuid(uid);
3800   if (pass) return(pass->pw_name);
3801   sprintf(name,"%d",uid);
3802   return(name);
3803 }
3804
3805 /*******************************************************************
3806 turn a gid into a group name
3807 ********************************************************************/
3808 char *gidtoname(int gid)
3809 {
3810   static char name[40];
3811   struct group *grp = getgrgid(gid);
3812   if (grp) return(grp->gr_name);
3813   sprintf(name,"%d",gid);
3814   return(name);
3815 }
3816
3817 /*******************************************************************
3818 block sigs
3819 ********************************************************************/
3820 void BlockSignals(BOOL block,int signum)
3821 {
3822 #ifdef USE_SIGBLOCK
3823   int block_mask = sigmask(signum);
3824   static int oldmask = 0;
3825   if (block) 
3826     oldmask = sigblock(block_mask);
3827   else
3828     sigsetmask(oldmask);
3829 #elif defined(USE_SIGPROCMASK)
3830   sigset_t set;
3831   sigemptyset(&set);
3832   sigaddset(&set,signum);
3833   sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3834 #endif
3835 }
3836
3837 #if AJT
3838 /*******************************************************************
3839 my own panic function - not suitable for general use
3840 ********************************************************************/
3841 void ajt_panic(void)
3842 {
3843   system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
3844 }
3845 #endif
3846
3847 #ifdef USE_DIRECT
3848 #define DIRECT direct
3849 #else
3850 #define DIRECT dirent
3851 #endif
3852
3853 /*******************************************************************
3854 a readdir wrapper which just returns the file name
3855 also return the inode number if requested
3856 ********************************************************************/
3857 char *readdirname(void *p)
3858 {
3859   struct DIRECT *ptr;
3860   char *dname;
3861
3862   if (!p) return(NULL);
3863   
3864   ptr = (struct DIRECT *)readdir(p);
3865   if (!ptr) return(NULL);
3866
3867   dname = ptr->d_name;
3868
3869 #ifdef NEXT2
3870   if (telldir(p) < 0) return(NULL);
3871 #endif
3872
3873 #ifdef SUNOS5
3874   /* this handles a broken compiler setup, causing a mixture
3875    of BSD and SYSV headers and libraries */
3876   {
3877     static BOOL broken_readdir = False;
3878     if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3879       {
3880         DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3881         broken_readdir = True;
3882       }
3883     if (broken_readdir)
3884       dname = dname - 2;
3885   }
3886 #endif
3887
3888   {
3889     static pstring buf;
3890     pstrcpy(buf, dname);
3891     unix_to_dos(buf, True);
3892     dname = buf;
3893   }
3894
3895   return(dname);
3896 }
3897
3898 /*******************************************************************
3899  Utility function used to decide if the last component 
3900  of a path matches a (possibly wildcarded) entry in a namelist.
3901 ********************************************************************/
3902
3903 BOOL is_in_path(char *name, name_compare_entry *namelist)
3904 {
3905   pstring last_component;
3906   char *p;
3907
3908   DEBUG(8, ("is_in_path: %s\n", name));
3909
3910   /* if we have no list it's obviously not in the path */
3911   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
3912   {
3913     DEBUG(8,("is_in_path: no name list.\n"));
3914     return False;
3915   }
3916
3917   /* Get the last component of the unix name. */
3918   p = strrchr(name, '/');
3919   strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3920   last_component[sizeof(last_component)-1] = '\0'; 
3921
3922   for(; namelist->name != NULL; namelist++)
3923   {
3924     if(namelist->is_wild)
3925     {
3926       /* look for a wildcard match. */
3927       if (mask_match(last_component, namelist->name, case_sensitive, False))
3928       {
3929          DEBUG(8,("is_in_path: mask match succeeded\n"));
3930          return True;
3931       }
3932     }
3933     else
3934     {
3935       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3936        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3937         {
3938          DEBUG(8,("is_in_path: match succeeded\n"));
3939          return True;
3940         }
3941     }
3942   }
3943   DEBUG(8,("is_in_path: match not found\n"));
3944  
3945   return False;
3946 }
3947
3948 /*******************************************************************
3949  Strip a '/' separated list into an array of 
3950  name_compare_enties structures suitable for 
3951  passing to is_in_path(). We do this for
3952  speed so we can pre-parse all the names in the list 
3953  and don't do it for each call to is_in_path().
3954  namelist is modified here and is assumed to be 
3955  a copy owned by the caller.
3956  We also check if the entry contains a wildcard to
3957  remove a potentially expensive call to mask_match
3958  if possible.
3959 ********************************************************************/
3960  
3961 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3962 {
3963   char *name_end;
3964   char *nameptr = namelist;
3965   int num_entries = 0;
3966   int i;
3967
3968   (*ppname_array) = NULL;
3969
3970   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
3971     return;
3972
3973   /* We need to make two passes over the string. The
3974      first to count the number of elements, the second
3975      to split it.
3976    */
3977   while(*nameptr) 
3978     {
3979       if ( *nameptr == '/' ) 
3980         {
3981           /* cope with multiple (useless) /s) */
3982           nameptr++;
3983           continue;
3984         }
3985       /* find the next / */
3986       name_end = strchr(nameptr, '/');
3987
3988       /* oops - the last check for a / didn't find one. */
3989       if (name_end == NULL)
3990         break;
3991
3992       /* next segment please */
3993       nameptr = name_end + 1;
3994       num_entries++;
3995     }
3996
3997   if(num_entries == 0)
3998     return;
3999
4000   if(( (*ppname_array) = (name_compare_entry *)malloc( 
4001            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4002         {
4003     DEBUG(0,("set_namearray: malloc fail\n"));
4004     return;
4005         }
4006
4007   /* Now copy out the names */
4008   nameptr = namelist;
4009   i = 0;
4010   while(*nameptr)
4011              {
4012       if ( *nameptr == '/' ) 
4013       {
4014           /* cope with multiple (useless) /s) */
4015           nameptr++;
4016           continue;
4017       }
4018       /* find the next / */
4019       if ((name_end = strchr(nameptr, '/')) != NULL) 
4020       {
4021           *name_end = 0;
4022          }
4023
4024       /* oops - the last check for a / didn't find one. */
4025       if(name_end == NULL) 
4026         break;
4027
4028       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4029                                 (strchr( nameptr, '*')!=NULL));
4030       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4031       {
4032         DEBUG(0,("set_namearray: malloc fail (1)\n"));
4033         return;
4034       }
4035
4036       /* next segment please */
4037       nameptr = name_end + 1;
4038       i++;
4039     }
4040   
4041   (*ppname_array)[i].name = NULL;
4042
4043   return;
4044 }
4045
4046 /****************************************************************************
4047 routine to free a namearray.
4048 ****************************************************************************/
4049
4050 void free_namearray(name_compare_entry *name_array)
4051 {
4052   if(name_array == 0)
4053     return;
4054
4055   if(name_array->name != NULL)
4056     free(name_array->name);
4057
4058   free((char *)name_array);
4059 }
4060
4061 /****************************************************************************
4062 routine to do file locking
4063 ****************************************************************************/
4064 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4065 {
4066 #if HAVE_FCNTL_LOCK
4067   struct flock lock;
4068   int ret;
4069
4070 #if 1
4071   uint32 mask = 0xC0000000;
4072
4073   /* make sure the count is reasonable, we might kill the lockd otherwise */
4074   count &= ~mask;
4075
4076   /* the offset is often strange - remove 2 of its bits if either of
4077      the top two bits are set. Shift the top ones by two bits. This
4078      still allows OLE2 apps to operate, but should stop lockd from
4079      dieing */
4080   if ((offset & mask) != 0)
4081     offset = (offset & ~mask) | ((offset & mask) >> 2);
4082 #else
4083   uint32 mask = ((unsigned)1<<31);
4084
4085   /* interpret negative counts as large numbers */
4086   if (count < 0)
4087     count &= ~mask;
4088
4089   /* no negative offsets */
4090   offset &= ~mask;
4091
4092   /* count + offset must be in range */
4093   while ((offset < 0 || (offset + count < 0)) && mask)
4094     {
4095       offset &= ~mask;
4096       mask = mask >> 1;
4097     }
4098 #endif
4099
4100
4101   DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4102
4103   lock.l_type = type;
4104   lock.l_whence = SEEK_SET;
4105   lock.l_start = (int)offset;
4106   lock.l_len = (int)count;
4107   lock.l_pid = 0;
4108
4109   errno = 0;
4110
4111   ret = fcntl(fd,op,&lock);
4112
4113   if (errno != 0)
4114     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4115
4116   /* a lock query */
4117   if (op == F_GETLK)
4118     {
4119       if ((ret != -1) &&
4120           (lock.l_type != F_UNLCK) && 
4121           (lock.l_pid != 0) && 
4122           (lock.l_pid != getpid()))
4123         {
4124           DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4125           return(True);
4126         }
4127
4128       /* it must be not locked or locked by me */
4129       return(False);
4130     }
4131
4132   /* a lock set or unset */
4133   if (ret == -1)
4134     {
4135       DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4136                offset,count,op,type,strerror(errno)));
4137
4138       /* perhaps it doesn't support this sort of locking?? */
4139       if (errno == EINVAL)
4140         {
4141           DEBUG(3,("locking not supported? returning True\n"));
4142           return(True);
4143         }
4144
4145       return(False);
4146     }
4147
4148   /* everything went OK */
4149   DEBUG(8,("Lock call successful\n"));
4150
4151   return(True);
4152 #else
4153   return(False);
4154 #endif
4155 }
4156
4157 /*******************************************************************
4158 lock a file - returning a open file descriptor or -1 on failure
4159 The timeout is in seconds. 0 means no timeout
4160 ********************************************************************/
4161 int file_lock(char *name,int timeout)
4162 {  
4163   int fd = open(name,O_RDWR|O_CREAT,0666);
4164   time_t t=0;
4165   if (fd < 0) return(-1);
4166
4167 #if HAVE_FCNTL_LOCK
4168   if (timeout) t = time(NULL);
4169   while (!timeout || (time(NULL)-t < timeout)) {
4170     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);    
4171     msleep(LOCK_RETRY_TIMEOUT);
4172   }
4173   return(-1);
4174 #else
4175   return(fd);
4176 #endif
4177 }
4178
4179 /*******************************************************************
4180 unlock a file locked by file_lock
4181 ********************************************************************/
4182 void file_unlock(int fd)
4183 {
4184   if (fd<0) return;
4185 #if HAVE_FCNTL_LOCK
4186   fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4187 #endif
4188   close(fd);
4189 }
4190
4191 /*******************************************************************
4192 is the name specified one of my netbios names
4193 returns true is it is equal, false otherwise
4194 ********************************************************************/
4195 BOOL is_myname(char *s)
4196 {
4197   int n;
4198   BOOL ret = False;
4199
4200   for (n=0; my_netbios_names[n]; n++) {
4201     if (strequal(my_netbios_names[n], s))
4202       ret=True;
4203   }
4204   DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4205   return(ret);
4206 }
4207
4208 /*******************************************************************
4209 set the horrid remote_arch string based on an enum.
4210 ********************************************************************/
4211 void set_remote_arch(enum remote_arch_types type)
4212 {
4213   ra_type = type;
4214   switch( type )
4215   {
4216   case RA_WFWG:
4217     strcpy(remote_arch, "WfWg");
4218     return;
4219   case RA_OS2:
4220     strcpy(remote_arch, "OS2");
4221     return;
4222   case RA_WIN95:
4223     strcpy(remote_arch, "Win95");
4224     return;
4225   case RA_WINNT:
4226     strcpy(remote_arch, "WinNT");
4227     return;
4228   case RA_SAMBA:
4229     strcpy(remote_arch,"Samba");
4230     return;
4231   default:
4232     ra_type = RA_UNKNOWN;
4233     strcpy(remote_arch, "UNKNOWN");
4234     break;
4235   }
4236 }
4237
4238 /*******************************************************************
4239  Get the remote_arch type.
4240 ********************************************************************/
4241 enum remote_arch_types get_remote_arch()
4242 {
4243   return ra_type;
4244 }
4245
4246
4247 /*******************************************************************
4248 skip past some unicode strings in a buffer
4249 ********************************************************************/
4250 char *skip_unicode_string(char *buf,int n)
4251 {
4252   while (n--)
4253   {
4254     while (*buf)
4255       buf += 2;
4256     buf += 2;
4257   }
4258   return(buf);
4259 }
4260
4261 /*******************************************************************
4262 Return a ascii version of a unicode string
4263 Hack alert: uses fixed buffer(s) and only handles ascii strings
4264 ********************************************************************/
4265 #define MAXUNI 1024
4266 char *unistrn2(uint16 *buf, int len)
4267 {
4268         static char lbufs[8][MAXUNI];
4269         static int nexti;
4270         char *lbuf = lbufs[nexti];
4271         char *p;
4272
4273         nexti = (nexti+1)%8;
4274
4275         DEBUG(10, ("unistrn2: "));
4276
4277         for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4278         {
4279                 DEBUG(10, ("%4x ", *buf));
4280                 *p = *buf;
4281         }
4282
4283         DEBUG(10,("\n"));
4284
4285         *p = 0;
4286         return lbuf;
4287 }
4288
4289 /*******************************************************************
4290 Return a ascii version of a unicode string
4291 Hack alert: uses fixed buffer(s) and only handles ascii strings
4292 ********************************************************************/
4293 #define MAXUNI 1024
4294 char *unistr2(uint16 *buf)
4295 {
4296         static char lbufs[8][MAXUNI];
4297         static int nexti;
4298         char *lbuf = lbufs[nexti];
4299         char *p;
4300
4301         nexti = (nexti+1)%8;
4302
4303         DEBUG(10, ("unistr2: "));
4304
4305         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4306         {
4307                 DEBUG(10, ("%4x ", *buf));
4308                 *p = *buf;
4309         }
4310
4311         DEBUG(10,("\n"));
4312
4313         *p = 0;
4314         return lbuf;
4315 }
4316
4317 /*******************************************************************
4318 create a null-terminated unicode string from a null-terminated ascii string.
4319 return number of unicode chars copied, excluding the null character.
4320
4321 only handles ascii strings
4322 ********************************************************************/
4323 #define MAXUNI 1024
4324 int struni2(uint16 *p, char *buf)
4325 {
4326         int len = 0;
4327
4328         if (p == NULL) return 0;
4329
4330         DEBUG(10, ("struni2: "));
4331
4332         if (buf != NULL)
4333         {
4334                 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4335                 {
4336                         DEBUG(10, ("%2x ", *buf));
4337                         *p = *buf;
4338                 }
4339
4340                 DEBUG(10,("\n"));
4341         }
4342
4343         *p = 0;
4344
4345         return len;
4346 }
4347
4348 /*******************************************************************
4349 Return a ascii version of a unicode string
4350 Hack alert: uses fixed buffer(s) and only handles ascii strings
4351 ********************************************************************/
4352 #define MAXUNI 1024
4353 char *unistr(char *buf)
4354 {
4355         static char lbufs[8][MAXUNI];
4356         static int nexti;
4357         char *lbuf = lbufs[nexti];
4358         char *p;
4359
4360         nexti = (nexti+1)%8;
4361
4362         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4363         {
4364                 *p = *buf;
4365         }
4366         *p = 0;
4367         return lbuf;
4368 }
4369
4370 /*******************************************************************
4371 strncpy for unicode strings
4372 ********************************************************************/
4373 int unistrncpy(char *dst, char *src, int len)
4374 {
4375         int num_wchars = 0;
4376
4377         while (*src && len > 0)
4378         {
4379                 *dst++ = *src++;
4380                 *dst++ = *src++;
4381                 len--;
4382                 num_wchars++;
4383         }
4384         *dst++ = 0;
4385         *dst++ = 0;
4386
4387         return num_wchars;
4388 }
4389
4390
4391 /*******************************************************************
4392 strcpy for unicode strings.  returns length (in num of wide chars)
4393 ********************************************************************/
4394 int unistrcpy(char *dst, char *src)
4395 {
4396         int num_wchars = 0;
4397
4398         while (*src)
4399         {
4400                 *dst++ = *src++;
4401                 *dst++ = *src++;
4402                 num_wchars++;
4403         }
4404         *dst++ = 0;
4405         *dst++ = 0;
4406
4407         return num_wchars;
4408 }
4409
4410
4411 /*******************************************************************
4412 safe string copy into a fstring
4413 ********************************************************************/
4414 void fstrcpy(char *dest, char *src)
4415 {
4416     int maxlength = sizeof(fstring) - 1;
4417     if (!dest) {
4418         DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4419         return;
4420     }
4421
4422     if (!src) {
4423         *dest = 0;
4424         return;
4425     }  
4426       
4427     while (maxlength-- && *src)
4428         *dest++ = *src++;
4429     *dest = 0;
4430     if (*src) {
4431         DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4432              strlen(src)));
4433     }    
4434 }   
4435
4436 /*******************************************************************
4437 safe string copy into a pstring
4438 ********************************************************************/
4439 void pstrcpy(char *dest, char *src)
4440 {
4441     int maxlength = sizeof(pstring) - 1;
4442     if (!dest) {
4443         DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4444         return;
4445     }
4446    
4447     if (!src) {
4448         *dest = 0;
4449         return;
4450     }
4451    
4452     while (maxlength-- && *src)
4453         *dest++ = *src++;
4454     *dest = 0;
4455     if (*src) {
4456         DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4457              strlen(src)));
4458     }
4459 }  
4460
4461
4462 /*******************************************************************
4463 align a pointer to a multiple of 4 bytes
4464 ********************************************************************/
4465 char *align4(char *q, char *base)
4466 {
4467         if ((q - base) & 3)
4468         {
4469                 q += 4 - ((q - base) & 3);
4470         }
4471         return q;
4472 }
4473
4474 /*******************************************************************
4475 align a pointer to a multiple of 2 bytes
4476 ********************************************************************/
4477 char *align2(char *q, char *base)
4478 {
4479         if ((q - base) & 1)
4480         {
4481                 q++;
4482         }
4483         return q;
4484 }
4485
4486 /*******************************************************************
4487 align a pointer to a multiple of align_offset bytes.  looks like it
4488 will work for offsets of 0, 2 and 4...
4489 ********************************************************************/
4490 char *align_offset(char *q, char *base, int align_offset_len)
4491 {
4492         int mod = ((q - base) & (align_offset_len-1));
4493         if (align_offset_len != 0 && mod != 0)
4494         {
4495                 q += align_offset_len - mod;
4496         }
4497         return q;
4498 }
4499
4500 void print_asc(int level, unsigned char *buf,int len)
4501 {
4502         int i;
4503         for (i=0;i<len;i++)
4504                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4505 }
4506
4507 void dump_data(int level,char *buf1,int len)
4508 {
4509   unsigned char *buf = (unsigned char *)buf1;
4510   int i=0;
4511   if (len<=0) return;
4512
4513   DEBUG(level,("[%03X] ",i));
4514   for (i=0;i<len;) {
4515     DEBUG(level,("%02X ",(int)buf[i]));
4516     i++;
4517     if (i%8 == 0) DEBUG(level,(" "));
4518     if (i%16 == 0) {      
4519       print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4520       print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4521       if (i<len) DEBUG(level,("[%03X] ",i));
4522     }
4523   }
4524   if (i%16) {
4525     int n;
4526
4527     n = 16 - (i%16);
4528     DEBUG(level,(" "));
4529     if (n>8) DEBUG(level,(" "));
4530     while (n--) DEBUG(level,("   "));
4531
4532     n = MIN(8,i%16);
4533     print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4534     n = (i%16) - n;
4535     if (n>0) print_asc(level,&buf[i-n],n); 
4536     DEBUG(level,("\n"));    
4537   }
4538 }
4539
4540 char *tab_depth(int depth)
4541 {
4542         static pstring spaces;
4543         memset(spaces, ' ', depth * 4);
4544         spaces[depth * 4] = 0;
4545         return spaces;
4546 }
4547
4548