trans2.c: Forced trans2_findfirst to behave as NT does in error returns.
[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         {
2272           DEBUG(5,("Got keepalive packet\n"));
2273           ok = False;
2274         }
2275     }
2276
2277   DEBUG(10,("got smb length of %d\n",len));
2278
2279   return(len);
2280 }
2281
2282
2283
2284 /****************************************************************************
2285   read an smb from a fd. Note that the buffer *MUST* be of size
2286   BUFFER_SIZE+SAFETY_MARGIN.
2287 The timeout is in milli seconds
2288 ****************************************************************************/
2289 BOOL receive_smb(int fd,char *buffer, int timeout)
2290 {
2291   int len,ret;
2292
2293   smb_read_error = 0;
2294
2295   bzero(buffer,smb_size + 100);
2296
2297   len = read_smb_length(fd,buffer,timeout);
2298   if (len == -1)
2299     return(False);
2300
2301   if (len > BUFFER_SIZE) {
2302     DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2303     if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2304       exit(1);
2305   }
2306
2307   ret = read_data(fd,buffer+4,len);
2308   if (ret != len) {
2309     smb_read_error = READ_ERROR;
2310     return False;
2311   }
2312
2313   return(True);
2314 }
2315
2316 /****************************************************************************
2317   read a message from a udp fd.
2318 The timeout is in milli seconds
2319 ****************************************************************************/
2320 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2321 {
2322   struct sockaddr_in from;
2323   int fromlen = sizeof(from);
2324   int32 msg_len = 0;
2325
2326   if(timeout != 0)
2327   {
2328     struct timeval to;
2329     fd_set fds;
2330     int selrtn;
2331
2332     FD_ZERO(&fds);
2333     FD_SET(fd,&fds);
2334
2335     to.tv_sec = timeout / 1000;
2336     to.tv_usec = (timeout % 1000) * 1000;
2337
2338     selrtn = sys_select(&fds,&to);
2339
2340     /* Check if error */
2341     if(selrtn == -1) 
2342     {
2343       /* something is wrong. Maybe the socket is dead? */
2344       smb_read_error = READ_ERROR;
2345       return False;
2346     } 
2347     
2348     /* Did we timeout ? */
2349     if (selrtn == 0) 
2350     {
2351       smb_read_error = READ_TIMEOUT;
2352       return False;
2353     }
2354   }
2355
2356   /*
2357    * Read a loopback udp message.
2358    */
2359   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2360                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2361                      (struct sockaddr *)&from, &fromlen);
2362
2363   if(msg_len < 0)
2364   {
2365     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2366     return False;
2367   }
2368
2369   /* Validate message length. */
2370   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2371   {
2372     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2373               msg_len, 
2374               buffer_len  - UDP_CMD_HEADER_LEN));
2375     return False;
2376   }
2377
2378   /* Validate message from address (must be localhost). */
2379   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2380   {
2381     DEBUG(0,("receive_local_message: invalid 'from' address \
2382 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2383    return False;
2384   }
2385
2386   /* Setup the message header */
2387   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2388   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2389
2390   return True;
2391 }
2392
2393 /****************************************************************************
2394  structure to hold a linked list of local udp messages.
2395  for processing.
2396 ****************************************************************************/
2397
2398 typedef struct _udp_message_list {
2399    struct _udp_message_list *msg_next;
2400    char *msg_buf;
2401    int msg_len;
2402 } udp_message_list;
2403
2404 static udp_message_list *udp_msg_head = NULL;
2405
2406 /****************************************************************************
2407  Function to push a linked list of local udp messages ready
2408  for processing.
2409 ****************************************************************************/
2410 BOOL push_local_message(char *buf, int msg_len)
2411 {
2412   udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
2413
2414   if(msg == NULL)
2415   {
2416     DEBUG(0,("push_local_message: malloc fail (1)\n"));
2417     return False;
2418   }
2419
2420   msg->msg_buf = (char *)malloc(msg_len);
2421   if(msg->msg_buf == NULL)
2422   {
2423     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2424     free((char *)msg);
2425     return False;
2426   }
2427
2428   memcpy(msg->msg_buf, buf, msg_len);
2429   msg->msg_len = msg_len;
2430
2431   msg->msg_next = udp_msg_head;
2432   udp_msg_head = msg;
2433
2434   return True;
2435 }
2436
2437 /****************************************************************************
2438   Do a select on an two fd's - with timeout. 
2439
2440   If a local udp message has been pushed onto the
2441   queue (this can only happen during oplock break
2442   processing) return this first.
2443
2444   If the first smbfd is ready then read an smb from it.
2445   if the second (loopback UDP) fd is ready then read a message
2446   from it and setup the buffer header to identify the length
2447   and from address.
2448   Returns False on timeout or error.
2449   Else returns True.
2450
2451 The timeout is in milli seconds
2452 ****************************************************************************/
2453 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2454                            char *buffer, int buffer_len, 
2455                            int timeout, BOOL *got_smb)
2456 {
2457   fd_set fds;
2458   int selrtn;
2459   struct timeval to;
2460
2461   *got_smb = False;
2462
2463   /*
2464    * Check to see if we already have a message on the udp queue.
2465    * If so - copy and return it.
2466    */
2467
2468   if(udp_msg_head)
2469   {
2470     udp_message_list *msg = udp_msg_head;
2471     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2472     udp_msg_head = msg->msg_next;
2473
2474     /* Free the message we just copied. */
2475     free((char *)msg->msg_buf);
2476     free((char *)msg);
2477     return True;
2478   }
2479
2480   FD_ZERO(&fds);
2481   FD_SET(smbfd,&fds);
2482   FD_SET(oplock_fd,&fds);
2483
2484   to.tv_sec = timeout / 1000;
2485   to.tv_usec = (timeout % 1000) * 1000;
2486
2487   selrtn = sys_select(&fds,timeout>0?&to:NULL);
2488
2489   /* Check if error */
2490   if(selrtn == -1) {
2491     /* something is wrong. Maybe the socket is dead? */
2492     smb_read_error = READ_ERROR;
2493     return False;
2494   } 
2495     
2496   /* Did we timeout ? */
2497   if (selrtn == 0) {
2498     smb_read_error = READ_TIMEOUT;
2499     return False;
2500   }
2501
2502   if (FD_ISSET(smbfd,&fds))
2503   {
2504     *got_smb = True;
2505     return receive_smb(smbfd, buffer, 0);
2506   }
2507   else
2508   {
2509     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2510   }
2511 }
2512
2513 /****************************************************************************
2514   send an smb to a fd 
2515 ****************************************************************************/
2516 BOOL send_smb(int fd,char *buffer)
2517 {
2518   int len;
2519   int ret,nwritten=0;
2520   len = smb_len(buffer) + 4;
2521
2522   while (nwritten < len)
2523     {
2524       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2525       if (ret <= 0)
2526         {
2527           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2528           close_sockets();
2529           exit(1);
2530         }
2531       nwritten += ret;
2532     }
2533
2534
2535   return True;
2536 }
2537
2538
2539 /****************************************************************************
2540 find a pointer to a netbios name
2541 ****************************************************************************/
2542 char *name_ptr(char *buf,int ofs)
2543 {
2544   unsigned char c = *(unsigned char *)(buf+ofs);
2545
2546   if ((c & 0xC0) == 0xC0)
2547     {
2548       uint16 l;
2549       char p[2];
2550       memcpy(p,buf+ofs,2);
2551       p[0] &= ~0xC0;
2552       l = RSVAL(p,0);
2553       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2554       return(buf + l);
2555     }
2556   else
2557     return(buf+ofs);
2558 }  
2559
2560 /****************************************************************************
2561 extract a netbios name from a buf
2562 ****************************************************************************/
2563 int name_extract(char *buf,int ofs,char *name)
2564 {
2565   char *p = name_ptr(buf,ofs);
2566   int d = PTR_DIFF(p,buf+ofs);
2567   strcpy(name,"");
2568   if (d < -50 || d > 50) return(0);
2569   return(name_interpret(p,name));
2570 }
2571   
2572 /****************************************************************************
2573 return the total storage length of a mangled name
2574 ****************************************************************************/
2575 int name_len( char *s )
2576   {
2577   int len;
2578
2579   /* If the two high bits of the byte are set, return 2. */
2580   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2581     return(2);
2582
2583   /* Add up the length bytes. */
2584   for( len = 1; (*s); s += (*s) + 1 )
2585     {
2586     len += *s + 1;
2587     }
2588
2589   return( len );
2590   } /* name_len */
2591
2592 /****************************************************************************
2593 send a single packet to a port on another machine
2594 ****************************************************************************/
2595 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2596 {
2597   BOOL ret;
2598   int out_fd;
2599   struct sockaddr_in sock_out;
2600
2601   if (passive)
2602     return(True);
2603
2604   /* create a socket to write to */
2605   out_fd = socket(AF_INET, type, 0);
2606   if (out_fd == -1) 
2607     {
2608       DEBUG(0,("socket failed"));
2609       return False;
2610     }
2611
2612   /* set the address and port */
2613   bzero((char *)&sock_out,sizeof(sock_out));
2614   putip((char *)&sock_out.sin_addr,(char *)&ip);
2615   sock_out.sin_port = htons( port );
2616   sock_out.sin_family = AF_INET;
2617   
2618   if (DEBUGLEVEL > 0)
2619     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2620              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2621         
2622   /* send it */
2623   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2624
2625   if (!ret)
2626     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2627              inet_ntoa(ip),port,strerror(errno)));
2628
2629   close(out_fd);
2630   return(ret);
2631 }
2632
2633 /*******************************************************************
2634 sleep for a specified number of milliseconds
2635 ********************************************************************/
2636 void msleep(int t)
2637 {
2638   int tdiff=0;
2639   struct timeval tval,t1,t2;  
2640   fd_set fds;
2641
2642   GetTimeOfDay(&t1);
2643   GetTimeOfDay(&t2);
2644   
2645   while (tdiff < t) {
2646     tval.tv_sec = (t-tdiff)/1000;
2647     tval.tv_usec = 1000*((t-tdiff)%1000);
2648  
2649     FD_ZERO(&fds);
2650     errno = 0;
2651     sys_select(&fds,&tval);
2652
2653     GetTimeOfDay(&t2);
2654     tdiff = TvalDiff(&t1,&t2);
2655   }
2656 }
2657
2658 /****************************************************************************
2659 check if a string is part of a list
2660 ****************************************************************************/
2661 BOOL in_list(char *s,char *list,BOOL casesensitive)
2662 {
2663   pstring tok;
2664   char *p=list;
2665
2666   if (!list) return(False);
2667
2668   while (next_token(&p,tok,LIST_SEP))
2669     {
2670       if (casesensitive) {
2671         if (strcmp(tok,s) == 0)
2672           return(True);
2673       } else {
2674         if (StrCaseCmp(tok,s) == 0)
2675           return(True);
2676       }
2677     }
2678   return(False);
2679 }
2680
2681 /* this is used to prevent lots of mallocs of size 1 */
2682 static char *null_string = NULL;
2683
2684 /****************************************************************************
2685 set a string value, allocing the space for the string
2686 ****************************************************************************/
2687 BOOL string_init(char **dest,char *src)
2688 {
2689   int l;
2690   if (!src)     
2691     src = "";
2692
2693   l = strlen(src);
2694
2695   if (l == 0)
2696     {
2697       if (!null_string)
2698         null_string = (char *)malloc(1);
2699
2700       *null_string = 0;
2701       *dest = null_string;
2702     }
2703   else
2704     {
2705       (*dest) = (char *)malloc(l+1);
2706       if ((*dest) == NULL) {
2707               DEBUG(0,("Out of memory in string_init\n"));
2708               return False;
2709       }
2710
2711       strcpy(*dest,src);
2712     }
2713   return(True);
2714 }
2715
2716 /****************************************************************************
2717 free a string value
2718 ****************************************************************************/
2719 void string_free(char **s)
2720 {
2721   if (!s || !(*s)) return;
2722   if (*s == null_string)
2723     *s = NULL;
2724   if (*s) free(*s);
2725   *s = NULL;
2726 }
2727
2728 /****************************************************************************
2729 set a string value, allocing the space for the string, and deallocating any 
2730 existing space
2731 ****************************************************************************/
2732 BOOL string_set(char **dest,char *src)
2733 {
2734   string_free(dest);
2735
2736   return(string_init(dest,src));
2737 }
2738
2739 /****************************************************************************
2740 substitute a string for a pattern in another string. Make sure there is 
2741 enough room!
2742
2743 This routine looks for pattern in s and replaces it with 
2744 insert. It may do multiple replacements.
2745
2746 return True if a substitution was done.
2747 ****************************************************************************/
2748 BOOL string_sub(char *s,char *pattern,char *insert)
2749 {
2750   BOOL ret = False;
2751   char *p;
2752   int ls,lp,li;
2753
2754   if (!insert || !pattern || !s) return(False);
2755
2756   ls = strlen(s);
2757   lp = strlen(pattern);
2758   li = strlen(insert);
2759
2760   if (!*pattern) return(False);
2761
2762   while (lp <= ls && (p = strstr(s,pattern)))
2763     {
2764       ret = True;
2765       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2766       memcpy(p,insert,li);
2767       s = p + li;
2768       ls = strlen(s);
2769     }
2770   return(ret);
2771 }
2772
2773
2774
2775 /*********************************************************
2776 * Recursive routine that is called by mask_match.
2777 * Does the actual matching.
2778 *********************************************************/
2779 BOOL do_match(char *str, char *regexp, int case_sig)
2780 {
2781   char *p;
2782
2783   for( p = regexp; *p && *str; ) {
2784     switch(*p) {
2785     case '?':
2786       str++; p++;
2787       break;
2788
2789     case '*':
2790       /* Look for a character matching 
2791          the one after the '*' */
2792       p++;
2793       if(!*p)
2794         return True; /* Automatic match */
2795       while(*str) {
2796         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2797           str++;
2798         if(do_match(str,p,case_sig))
2799           return True;
2800         if(!*str)
2801           return False;
2802         else
2803           str++;
2804       }
2805       return False;
2806
2807     default:
2808       if(case_sig) {
2809         if(*str != *p)
2810           return False;
2811       } else {
2812         if(toupper(*str) != toupper(*p))
2813           return False;
2814       }
2815       str++, p++;
2816       break;
2817     }
2818   }
2819   if(!*p && !*str)
2820     return True;
2821
2822   if (!*p && str[0] == '.' && str[1] == 0)
2823     return(True);
2824   
2825   if (!*str && *p == '?')
2826     {
2827       while (*p == '?') p++;
2828       return(!*p);
2829     }
2830
2831   if(!*str && (*p == '*' && p[1] == '\0'))
2832     return True;
2833   return False;
2834 }
2835
2836
2837 /*********************************************************
2838 * Routine to match a given string with a regexp - uses
2839 * simplified regexp that takes * and ? only. Case can be
2840 * significant or not.
2841 *********************************************************/
2842 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2843 {
2844   char *p;
2845   pstring p1, p2;
2846   fstring ebase,eext,sbase,sext;
2847
2848   BOOL matched;
2849
2850   /* Make local copies of str and regexp */
2851   StrnCpy(p1,regexp,sizeof(pstring)-1);
2852   StrnCpy(p2,str,sizeof(pstring)-1);
2853
2854   if (!strchr(p2,'.')) {
2855     strcat(p2,".");
2856   }
2857
2858 /*
2859   if (!strchr(p1,'.')) {
2860     strcat(p1,".");
2861   }
2862 */
2863
2864 #if 0
2865   if (strchr(p1,'.'))
2866     {
2867       string_sub(p1,"*.*","*");
2868       string_sub(p1,".*","*");
2869     }
2870 #endif
2871
2872   /* Remove any *? and ** as they are meaningless */
2873   for(p = p1; *p; p++)
2874     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2875       (void)strcpy( &p[1], &p[2]);
2876
2877   if (strequal(p1,"*")) return(True);
2878
2879   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2880
2881   if (trans2) {
2882     fstrcpy(ebase,p1);
2883     fstrcpy(sbase,p2);
2884   } else {
2885     if ((p=strrchr(p1,'.'))) {
2886       *p = 0;
2887       fstrcpy(ebase,p1);
2888       fstrcpy(eext,p+1);
2889     } else {
2890       fstrcpy(ebase,p1);
2891       eext[0] = 0;
2892     }
2893
2894   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2895     *p = 0;
2896     fstrcpy(sbase,p2);
2897     fstrcpy(sext,p+1);
2898   } else {
2899     fstrcpy(sbase,p2);
2900     fstrcpy(sext,"");
2901   }
2902   }
2903
2904   matched = do_match(sbase,ebase,case_sig) && 
2905     (trans2 || do_match(sext,eext,case_sig));
2906
2907   DEBUG(8,("mask_match returning %d\n", matched));
2908
2909   return matched;
2910 }
2911
2912
2913
2914 /****************************************************************************
2915 become a daemon, discarding the controlling terminal
2916 ****************************************************************************/
2917 void become_daemon(void)
2918 {
2919 #ifndef NO_FORK_DEBUG
2920   if (fork())
2921     exit(0);
2922
2923   /* detach from the terminal */
2924 #ifdef USE_SETSID
2925   setsid();
2926 #else /* USE_SETSID */
2927 #ifdef TIOCNOTTY
2928   {
2929     int i = open("/dev/tty", O_RDWR);
2930     if (i >= 0) 
2931       {
2932         ioctl(i, (int) TIOCNOTTY, (char *)0);      
2933         close(i);
2934       }
2935   }
2936 #endif /* TIOCNOTTY */
2937 #endif /* USE_SETSID */
2938   /* Close fd's 0,1,2. Needed if started by rsh */
2939   close_low_fds();
2940 #endif /* NO_FORK_DEBUG */
2941 }
2942
2943
2944 /****************************************************************************
2945 put up a yes/no prompt
2946 ****************************************************************************/
2947 BOOL yesno(char *p)
2948 {
2949   pstring ans;
2950   printf("%s",p);
2951
2952   if (!fgets(ans,sizeof(ans)-1,stdin))
2953     return(False);
2954
2955   if (*ans == 'y' || *ans == 'Y')
2956     return(True);
2957
2958   return(False);
2959 }
2960
2961 /****************************************************************************
2962 read a line from a file with possible \ continuation chars. 
2963 Blanks at the start or end of a line are stripped.
2964 The string will be allocated if s2 is NULL
2965 ****************************************************************************/
2966 char *fgets_slash(char *s2,int maxlen,FILE *f)
2967 {
2968   char *s=s2;
2969   int len = 0;
2970   int c;
2971   BOOL start_of_line = True;
2972
2973   if (feof(f))
2974     return(NULL);
2975
2976   if (!s2)
2977     {
2978       maxlen = MIN(maxlen,8);
2979       s = (char *)Realloc(s,maxlen);
2980     }
2981
2982   if (!s || maxlen < 2) return(NULL);
2983
2984   *s = 0;
2985
2986   while (len < maxlen-1)
2987     {
2988       c = getc(f);
2989       switch (c)
2990         {
2991         case '\r':
2992           break;
2993         case '\n':
2994           while (len > 0 && s[len-1] == ' ')
2995             {
2996               s[--len] = 0;
2997             }
2998           if (len > 0 && s[len-1] == '\\')
2999             {
3000               s[--len] = 0;
3001               start_of_line = True;
3002               break;
3003             }
3004           return(s);
3005         case EOF:
3006           if (len <= 0 && !s2) 
3007             free(s);
3008           return(len>0?s:NULL);
3009         case ' ':
3010           if (start_of_line)
3011             break;
3012         default:
3013           start_of_line = False;
3014           s[len++] = c;
3015           s[len] = 0;
3016         }
3017       if (!s2 && len > maxlen-3)
3018         {
3019           maxlen *= 2;
3020           s = (char *)Realloc(s,maxlen);
3021           if (!s) return(NULL);
3022         }
3023     }
3024   return(s);
3025 }
3026
3027
3028
3029 /****************************************************************************
3030 set the length of a file from a filedescriptor.
3031 Returns 0 on success, -1 on failure.
3032 ****************************************************************************/
3033 int set_filelen(int fd, long len)
3034 {
3035 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3036    extend a file with ftruncate. Provide alternate implementation
3037    for this */
3038
3039 #if FTRUNCATE_CAN_EXTEND
3040   return ftruncate(fd, len);
3041 #else
3042   struct stat st;
3043   char c = 0;
3044   long currpos = lseek(fd, 0L, SEEK_CUR);
3045
3046   if(currpos < 0)
3047     return -1;
3048   /* Do an fstat to see if the file is longer than
3049      the requested size (call ftruncate),
3050      or shorter, in which case seek to len - 1 and write 1
3051      byte of zero */
3052   if(fstat(fd, &st)<0)
3053     return -1;
3054
3055 #ifdef S_ISFIFO
3056   if (S_ISFIFO(st.st_mode)) return 0;
3057 #endif
3058
3059   if(st.st_size == len)
3060     return 0;
3061   if(st.st_size > len)
3062     return ftruncate(fd, len);
3063
3064   if(lseek(fd, len-1, SEEK_SET) != len -1)
3065     return -1;
3066   if(write(fd, &c, 1)!=1)
3067     return -1;
3068   /* Seek to where we were */
3069   lseek(fd, currpos, SEEK_SET);
3070   return 0;
3071 #endif
3072 }
3073
3074
3075 /****************************************************************************
3076 return the byte checksum of some data
3077 ****************************************************************************/
3078 int byte_checksum(char *buf,int len)
3079 {
3080   unsigned char *p = (unsigned char *)buf;
3081   int ret = 0;
3082   while (len--)
3083     ret += *p++;
3084   return(ret);
3085 }
3086
3087
3088
3089 #ifdef HPUX
3090 /****************************************************************************
3091 this is a version of setbuffer() for those machines that only have setvbuf
3092 ****************************************************************************/
3093  void setbuffer(FILE *f,char *buf,int bufsize)
3094 {
3095   setvbuf(f,buf,_IOFBF,bufsize);
3096 }
3097 #endif
3098
3099
3100 /****************************************************************************
3101 parse out a directory name from a path name. Assumes dos style filenames.
3102 ****************************************************************************/
3103 char *dirname_dos(char *path,char *buf)
3104 {
3105   char *p = strrchr(path,'\\');
3106
3107   if (!p)
3108     strcpy(buf,path);
3109   else
3110     {
3111       *p = 0;
3112       strcpy(buf,path);
3113       *p = '\\';
3114     }
3115
3116   return(buf);
3117 }
3118
3119
3120 /****************************************************************************
3121 parse out a filename from a path name. Assumes dos style filenames.
3122 ****************************************************************************/
3123 static char *filename_dos(char *path,char *buf)
3124 {
3125   char *p = strrchr(path,'\\');
3126
3127   if (!p)
3128     strcpy(buf,path);
3129   else
3130     strcpy(buf,p+1);
3131
3132   return(buf);
3133 }
3134
3135
3136
3137 /****************************************************************************
3138 expand a pointer to be a particular size
3139 ****************************************************************************/
3140 void *Realloc(void *p,int size)
3141 {
3142   void *ret=NULL;
3143
3144   if (size == 0) {
3145     if (p) free(p);
3146     DEBUG(5,("Realloc asked for 0 bytes\n"));
3147     return NULL;
3148   }
3149
3150   if (!p)
3151     ret = (void *)malloc(size);
3152   else
3153     ret = (void *)realloc(p,size);
3154
3155   if (!ret)
3156     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3157
3158   return(ret);
3159 }
3160
3161 #ifdef NOSTRDUP
3162 /****************************************************************************
3163 duplicate a string
3164 ****************************************************************************/
3165  char *strdup(char *s)
3166 {
3167   char *ret = NULL;
3168   if (!s) return(NULL);
3169   ret = (char *)malloc(strlen(s)+1);
3170   if (!ret) return(NULL);
3171   strcpy(ret,s);
3172   return(ret);
3173 }
3174 #endif
3175
3176
3177 /****************************************************************************
3178   Signal handler for SIGPIPE (write on a disconnected socket) 
3179 ****************************************************************************/
3180 void Abort(void )
3181 {
3182   DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3183   exit(2);
3184 }
3185
3186 /****************************************************************************
3187 get my own name and IP
3188 ****************************************************************************/
3189 BOOL get_myname(char *my_name,struct in_addr *ip)
3190 {
3191   struct hostent *hp;
3192   pstring hostname;
3193
3194   *hostname = 0;
3195
3196   /* get my host name */
3197   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
3198     {
3199       DEBUG(0,("gethostname failed\n"));
3200       return False;
3201     } 
3202
3203   /* get host info */
3204   if ((hp = Get_Hostbyname(hostname)) == 0) 
3205     {
3206       DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3207       return False;
3208     }
3209
3210   if (my_name)
3211     {
3212       /* split off any parts after an initial . */
3213       char *p = strchr(hostname,'.');
3214       if (p) *p = 0;
3215
3216       fstrcpy(my_name,hostname);
3217     }
3218
3219   if (ip)
3220     putip((char *)ip,(char *)hp->h_addr);
3221
3222   return(True);
3223 }
3224
3225
3226 /****************************************************************************
3227 true if two IP addresses are equal
3228 ****************************************************************************/
3229 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3230 {
3231   uint32 a1,a2;
3232   a1 = ntohl(ip1.s_addr);
3233   a2 = ntohl(ip2.s_addr);
3234   return(a1 == a2);
3235 }
3236
3237
3238 /****************************************************************************
3239 open a socket of the specified type, port and address for incoming data
3240 ****************************************************************************/
3241 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3242 {
3243   struct hostent *hp;
3244   struct sockaddr_in sock;
3245   pstring host_name;
3246   int res;
3247
3248   /* get my host name */
3249   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
3250     { DEBUG(0,("gethostname failed\n")); return -1; } 
3251
3252   /* get host info */
3253   if ((hp = Get_Hostbyname(host_name)) == 0) 
3254     {
3255       DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3256       return -1;
3257     }
3258   
3259   bzero((char *)&sock,sizeof(sock));
3260   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3261 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3262   sock.sin_len = sizeof(sock);
3263 #endif
3264   sock.sin_port = htons( port );
3265   sock.sin_family = hp->h_addrtype;
3266   sock.sin_addr.s_addr = socket_addr;
3267   res = socket(hp->h_addrtype, type, 0);
3268   if (res == -1) 
3269     { DEBUG(0,("socket failed\n")); return -1; }
3270
3271   {
3272     int one=1;
3273     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3274   }
3275
3276   /* now we've got a socket - we need to bind it */
3277   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
3278     { 
3279       if (port) {
3280         if (port == SMB_PORT || port == NMB_PORT)
3281           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3282                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
3283         close(res); 
3284
3285         if (dlevel > 0 && port < 1000)
3286           port = 7999;
3287
3288         if (port >= 1000 && port < 9000)
3289           return(open_socket_in(type,port+1,dlevel,socket_addr));
3290       }
3291
3292       return(-1); 
3293     }
3294   DEBUG(3,("bind succeeded on port %d\n",port));
3295
3296   return res;
3297 }
3298
3299
3300 /****************************************************************************
3301   create an outgoing socket
3302   **************************************************************************/
3303 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3304 {
3305   struct sockaddr_in sock_out;
3306   int res,ret;
3307   int connect_loop = 250; /* 250 milliseconds */
3308   int loops = (timeout * 1000) / connect_loop;
3309
3310   /* create a socket to write to */
3311   res = socket(PF_INET, type, 0);
3312   if (res == -1) 
3313     { DEBUG(0,("socket error\n")); return -1; }
3314
3315   if (type != SOCK_STREAM) return(res);
3316   
3317   bzero((char *)&sock_out,sizeof(sock_out));
3318   putip((char *)&sock_out.sin_addr,(char *)addr);
3319   
3320   sock_out.sin_port = htons( port );
3321   sock_out.sin_family = PF_INET;
3322
3323   /* set it non-blocking */
3324   set_blocking(res,False);
3325
3326   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3327   
3328   /* and connect it to the destination */
3329 connect_again:
3330   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3331
3332   /* Some systems return EAGAIN when they mean EINPROGRESS */
3333   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3334         errno == EAGAIN) && loops--) {
3335     msleep(connect_loop);
3336     goto connect_again;
3337   }
3338
3339   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3340          errno == EAGAIN)) {
3341       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3342       close(res);
3343       return -1;
3344   }
3345
3346 #ifdef EISCONN
3347   if (ret < 0 && errno == EISCONN) {
3348     errno = 0;
3349     ret = 0;
3350   }
3351 #endif
3352
3353   if (ret < 0) {
3354     DEBUG(1,("error connecting to %s:%d (%s)\n",
3355              inet_ntoa(*addr),port,strerror(errno)));
3356     return -1;
3357   }
3358
3359   /* set it blocking again */
3360   set_blocking(res,True);
3361
3362   return res;
3363 }
3364
3365
3366 /****************************************************************************
3367 interpret a protocol description string, with a default
3368 ****************************************************************************/
3369 int interpret_protocol(char *str,int def)
3370 {
3371   if (strequal(str,"NT1"))
3372     return(PROTOCOL_NT1);
3373   if (strequal(str,"LANMAN2"))
3374     return(PROTOCOL_LANMAN2);
3375   if (strequal(str,"LANMAN1"))
3376     return(PROTOCOL_LANMAN1);
3377   if (strequal(str,"CORE"))
3378     return(PROTOCOL_CORE);
3379   if (strequal(str,"COREPLUS"))
3380     return(PROTOCOL_COREPLUS);
3381   if (strequal(str,"CORE+"))
3382     return(PROTOCOL_COREPLUS);
3383   
3384   DEBUG(0,("Unrecognised protocol level %s\n",str));
3385   
3386   return(def);
3387 }
3388
3389 /****************************************************************************
3390 interpret a security level
3391 ****************************************************************************/
3392 int interpret_security(char *str,int def)
3393 {
3394   if (strequal(str,"SERVER"))
3395     return(SEC_SERVER);
3396   if (strequal(str,"USER"))
3397     return(SEC_USER);
3398   if (strequal(str,"SHARE"))
3399     return(SEC_SHARE);
3400   
3401   DEBUG(0,("Unrecognised security level %s\n",str));
3402   
3403   return(def);
3404 }
3405
3406
3407 /****************************************************************************
3408 interpret an internet address or name into an IP address in 4 byte form
3409 ****************************************************************************/
3410 uint32 interpret_addr(char *str)
3411 {
3412   struct hostent *hp;
3413   uint32 res;
3414   int i;
3415   BOOL pure_address = True;
3416
3417   if (strcmp(str,"0.0.0.0") == 0) return(0);
3418   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3419
3420   for (i=0; pure_address && str[i]; i++)
3421     if (!(isdigit(str[i]) || str[i] == '.')) 
3422       pure_address = False;
3423
3424   /* if it's in the form of an IP address then get the lib to interpret it */
3425   if (pure_address) {
3426     res = inet_addr(str);
3427   } else {
3428     /* otherwise assume it's a network name of some sort and use 
3429        Get_Hostbyname */
3430     if ((hp = Get_Hostbyname(str)) == 0) {
3431       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3432       return 0;
3433     }
3434     if(hp->h_addr == NULL) {
3435       DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3436       return 0;
3437     }
3438     putip((char *)&res,(char *)hp->h_addr);
3439   }
3440
3441   if (res == (uint32)-1) return(0);
3442
3443   return(res);
3444 }
3445
3446 /*******************************************************************
3447   a convenient addition to interpret_addr()
3448   ******************************************************************/
3449 struct in_addr *interpret_addr2(char *str)
3450 {
3451   static struct in_addr ret;
3452   uint32 a = interpret_addr(str);
3453   ret.s_addr = a;
3454   return(&ret);
3455 }
3456
3457 /*******************************************************************
3458   check if an IP is the 0.0.0.0
3459   ******************************************************************/
3460 BOOL zero_ip(struct in_addr ip)
3461 {
3462   uint32 a;
3463   putip((char *)&a,(char *)&ip);
3464   return(a == 0);
3465 }
3466
3467
3468 /*******************************************************************
3469  matchname - determine if host name matches IP address 
3470  ******************************************************************/
3471 static BOOL matchname(char *remotehost,struct in_addr  addr)
3472 {
3473   struct hostent *hp;
3474   int     i;
3475   
3476   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3477     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3478     return False;
3479   } 
3480
3481   /*
3482    * Make sure that gethostbyname() returns the "correct" host name.
3483    * Unfortunately, gethostbyname("localhost") sometimes yields
3484    * "localhost.domain". Since the latter host name comes from the
3485    * local DNS, we just have to trust it (all bets are off if the local
3486    * DNS is perverted). We always check the address list, though.
3487    */
3488   
3489   if (strcasecmp(remotehost, hp->h_name)
3490       && strcasecmp(remotehost, "localhost")) {
3491     DEBUG(0,("host name/name mismatch: %s != %s",
3492              remotehost, hp->h_name));
3493     return False;
3494   }
3495         
3496   /* Look up the host address in the address list we just got. */
3497   for (i = 0; hp->h_addr_list[i]; i++) {
3498     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3499       return True;
3500   }
3501
3502   /*
3503    * The host name does not map to the original host address. Perhaps
3504    * someone has compromised a name server. More likely someone botched
3505    * it, but that could be dangerous, too.
3506    */
3507   
3508   DEBUG(0,("host name/address mismatch: %s != %s",
3509            inet_ntoa(addr), hp->h_name));
3510   return False;
3511 }
3512
3513 /*******************************************************************
3514  Reset the 'done' variables so after a client process is created
3515  from a fork call these calls will be re-done. This should be
3516  expanded if more variables need reseting.
3517  ******************************************************************/
3518
3519 static BOOL global_client_name_done = False;
3520 static BOOL global_client_addr_done = False;
3521
3522 void reset_globals_after_fork()
3523 {
3524   global_client_name_done = False;
3525   global_client_addr_done = False;
3526 }
3527  
3528 /*******************************************************************
3529  return the DNS name of the client 
3530  ******************************************************************/
3531 char *client_name(void)
3532 {
3533   extern int Client;
3534   struct sockaddr sa;
3535   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3536   int     length = sizeof(sa);
3537   static pstring name_buf;
3538   struct hostent *hp;
3539
3540   if (global_client_name_done) 
3541     return name_buf;
3542
3543   strcpy(name_buf,"UNKNOWN");
3544
3545   if (Client == -1) {
3546           return name_buf;
3547   }
3548
3549   if (getpeername(Client, &sa, &length) < 0) {
3550     DEBUG(0,("getpeername failed\n"));
3551     return name_buf;
3552   }
3553
3554   /* Look up the remote host name. */
3555   if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3556                           sizeof(sockin->sin_addr),
3557                           AF_INET)) == 0) {
3558     DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3559     StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3560   } else {
3561     StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3562     if (!matchname(name_buf, sockin->sin_addr)) {
3563       DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3564       strcpy(name_buf,"UNKNOWN");
3565     }
3566   }
3567   global_client_name_done = True;
3568   return name_buf;
3569 }
3570
3571 /*******************************************************************
3572  return the IP addr of the client as a string 
3573  ******************************************************************/
3574 char *client_addr(void)
3575 {
3576   extern int Client;
3577   struct sockaddr sa;
3578   struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3579   int     length = sizeof(sa);
3580   static fstring addr_buf;
3581
3582   if (global_client_addr_done) 
3583     return addr_buf;
3584
3585   strcpy(addr_buf,"0.0.0.0");
3586
3587   if (Client == -1) {
3588           return addr_buf;
3589   }
3590
3591   if (getpeername(Client, &sa, &length) < 0) {
3592     DEBUG(0,("getpeername failed\n"));
3593     return addr_buf;
3594   }
3595
3596   fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3597
3598   global_client_addr_done = True;
3599   return addr_buf;
3600 }
3601
3602 char *automount_server(char *user_name)
3603 {
3604         static pstring server_name;
3605
3606 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3607         int nis_error;        /* returned by yp all functions */
3608         char *nis_result;     /* yp_match inits this */
3609         int nis_result_len;  /* and set this */
3610         char *nis_domain;     /* yp_get_default_domain inits this */
3611         char *nis_map = (char *)lp_nis_home_map_name();
3612         int home_server_len;
3613
3614         /* set to default of local machine */
3615         pstrcpy(server_name, local_machine);
3616
3617         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3618         {
3619                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3620         }
3621
3622         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3623
3624         if ((nis_error = yp_match(nis_domain, nis_map,
3625                         user_name, strlen(user_name),
3626                         &nis_result, &nis_result_len)) != 0)
3627         {
3628                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3629         }
3630
3631         if (!nis_error && lp_nis_home_map())
3632         {
3633                 home_server_len = strcspn(nis_result,":");
3634                 DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
3635                 if (home_server_len > sizeof(pstring))
3636                 {
3637                         home_server_len = sizeof(pstring);
3638                 }
3639                 strncpy(server_name, nis_result, home_server_len);
3640         }
3641 #else
3642         /* use the local machine name instead of the auto-map server */
3643         pstrcpy(server_name, local_machine);
3644 #endif
3645
3646         DEBUG(4,("Home server: %s\n", server_name));
3647
3648         return server_name;
3649 }
3650
3651 /*******************************************************************
3652 sub strings with useful parameters
3653 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3654 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3655 ********************************************************************/
3656 void standard_sub_basic(char *str)
3657 {
3658         char *s, *p;
3659         char pidstr[10];
3660         struct passwd *pass;
3661         char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3662
3663         for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3664         {
3665                 switch (*(p+1))
3666                 {
3667                         case 'G' :
3668                         {
3669                                 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3670                                 {
3671                                         string_sub(p,"%G",gidtoname(pass->pw_gid));
3672                                 }
3673                                 else
3674                                 {
3675                                         p += 2;
3676                                 }
3677                                 break;
3678                         }
3679                         case 'N' : string_sub(p,"%N", automount_server(username)); break;
3680                         case 'I' : string_sub(p,"%I", client_addr()); break;
3681                         case 'L' : string_sub(p,"%L", local_machine); break;
3682                         case 'M' : string_sub(p,"%M", client_name()); break;
3683                         case 'R' : string_sub(p,"%R", remote_proto); break;
3684                         case 'T' : string_sub(p,"%T", timestring()); break;
3685                         case 'U' : string_sub(p,"%U", username); break;
3686                         case 'a' : string_sub(p,"%a", remote_arch); break;
3687                         case 'd' :
3688                         {
3689                                 sprintf(pidstr,"%d",(int)getpid());
3690                                 string_sub(p,"%d", pidstr);
3691                                 break;
3692                         }
3693                         case 'h' : string_sub(p,"%h", myhostname); break;
3694                         case 'm' : string_sub(p,"%m", remote_machine); break;
3695                         case 'v' : string_sub(p,"%v", VERSION); break;
3696                         case '\0': p++; break; /* don't run off end if last character is % */
3697                         default  : p+=2; break;
3698                 }
3699         }
3700         return;
3701 }
3702
3703 /*******************************************************************
3704 are two IPs on the same subnet?
3705 ********************************************************************/
3706 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3707 {
3708   uint32 net1,net2,nmask;
3709
3710   nmask = ntohl(mask.s_addr);
3711   net1  = ntohl(ip1.s_addr);
3712   net2  = ntohl(ip2.s_addr);
3713             
3714   return((net1 & nmask) == (net2 & nmask));
3715 }
3716
3717
3718 /*******************************************************************
3719 write a string in unicoode format
3720 ********************************************************************/
3721 int PutUniCode(char *dst,char *src)
3722 {
3723   int ret = 0;
3724   while (*src) {
3725     dst[ret++] = src[0];
3726     dst[ret++] = 0;    
3727     src++;
3728   }
3729   dst[ret++]=0;
3730   dst[ret++]=0;
3731   return(ret);
3732 }
3733
3734 /****************************************************************************
3735 a wrapper for gethostbyname() that tries with all lower and all upper case 
3736 if the initial name fails
3737 ****************************************************************************/
3738 struct hostent *Get_Hostbyname(char *name)
3739 {
3740   char *name2 = strdup(name);
3741   struct hostent *ret;
3742
3743   if (!name2)
3744     {
3745       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3746       exit(0);
3747     }
3748
3749   if (!isalnum(*name2))
3750     {
3751       free(name2);
3752       return(NULL);
3753     }
3754
3755   ret = sys_gethostbyname(name2);
3756   if (ret != NULL)
3757     {
3758       free(name2);
3759       return(ret);
3760     }
3761
3762   /* try with all lowercase */
3763   strlower(name2);
3764   ret = sys_gethostbyname(name2);
3765   if (ret != NULL)
3766     {
3767       free(name2);
3768       return(ret);
3769     }
3770
3771   /* try with all uppercase */
3772   strupper(name2);
3773   ret = sys_gethostbyname(name2);
3774   if (ret != NULL)
3775     {
3776       free(name2);
3777       return(ret);
3778     }
3779   
3780   /* nothing works :-( */
3781   free(name2);
3782   return(NULL);
3783 }
3784
3785
3786 /****************************************************************************
3787 check if a process exists. Does this work on all unixes?
3788 ****************************************************************************/
3789 BOOL process_exists(int pid)
3790 {
3791         return(kill(pid,0) == 0 || errno != ESRCH);
3792 }
3793
3794
3795 /*******************************************************************
3796 turn a uid into a user name
3797 ********************************************************************/
3798 char *uidtoname(int uid)
3799 {
3800   static char name[40];
3801   struct passwd *pass = getpwuid(uid);
3802   if (pass) return(pass->pw_name);
3803   sprintf(name,"%d",uid);
3804   return(name);
3805 }
3806
3807 /*******************************************************************
3808 turn a gid into a group name
3809 ********************************************************************/
3810 char *gidtoname(int gid)
3811 {
3812   static char name[40];
3813   struct group *grp = getgrgid(gid);
3814   if (grp) return(grp->gr_name);
3815   sprintf(name,"%d",gid);
3816   return(name);
3817 }
3818
3819 /*******************************************************************
3820 block sigs
3821 ********************************************************************/
3822 void BlockSignals(BOOL block,int signum)
3823 {
3824 #ifdef USE_SIGBLOCK
3825   int block_mask = sigmask(signum);
3826   static int oldmask = 0;
3827   if (block) 
3828     oldmask = sigblock(block_mask);
3829   else
3830     sigsetmask(oldmask);
3831 #elif defined(USE_SIGPROCMASK)
3832   sigset_t set;
3833   sigemptyset(&set);
3834   sigaddset(&set,signum);
3835   sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3836 #endif
3837 }
3838
3839 #if AJT
3840 /*******************************************************************
3841 my own panic function - not suitable for general use
3842 ********************************************************************/
3843 void ajt_panic(void)
3844 {
3845   system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
3846 }
3847 #endif
3848
3849 #ifdef USE_DIRECT
3850 #define DIRECT direct
3851 #else
3852 #define DIRECT dirent
3853 #endif
3854
3855 /*******************************************************************
3856 a readdir wrapper which just returns the file name
3857 also return the inode number if requested
3858 ********************************************************************/
3859 char *readdirname(void *p)
3860 {
3861   struct DIRECT *ptr;
3862   char *dname;
3863
3864   if (!p) return(NULL);
3865   
3866   ptr = (struct DIRECT *)readdir(p);
3867   if (!ptr) return(NULL);
3868
3869   dname = ptr->d_name;
3870
3871 #ifdef NEXT2
3872   if (telldir(p) < 0) return(NULL);
3873 #endif
3874
3875 #ifdef SUNOS5
3876   /* this handles a broken compiler setup, causing a mixture
3877    of BSD and SYSV headers and libraries */
3878   {
3879     static BOOL broken_readdir = False;
3880     if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3881       {
3882         DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3883         broken_readdir = True;
3884       }
3885     if (broken_readdir)
3886       dname = dname - 2;
3887   }
3888 #endif
3889
3890   {
3891     static pstring buf;
3892     pstrcpy(buf, dname);
3893     unix_to_dos(buf, True);
3894     dname = buf;
3895   }
3896
3897   return(dname);
3898 }
3899
3900 /*******************************************************************
3901  Utility function used to decide if the last component 
3902  of a path matches a (possibly wildcarded) entry in a namelist.
3903 ********************************************************************/
3904
3905 BOOL is_in_path(char *name, name_compare_entry *namelist)
3906 {
3907   pstring last_component;
3908   char *p;
3909
3910   DEBUG(8, ("is_in_path: %s\n", name));
3911
3912   /* if we have no list it's obviously not in the path */
3913   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
3914   {
3915     DEBUG(8,("is_in_path: no name list.\n"));
3916     return False;
3917   }
3918
3919   /* Get the last component of the unix name. */
3920   p = strrchr(name, '/');
3921   strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3922   last_component[sizeof(last_component)-1] = '\0'; 
3923
3924   for(; namelist->name != NULL; namelist++)
3925   {
3926     if(namelist->is_wild)
3927     {
3928       /* look for a wildcard match. */
3929       if (mask_match(last_component, namelist->name, case_sensitive, False))
3930       {
3931          DEBUG(8,("is_in_path: mask match succeeded\n"));
3932          return True;
3933       }
3934     }
3935     else
3936     {
3937       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3938        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3939         {
3940          DEBUG(8,("is_in_path: match succeeded\n"));
3941          return True;
3942         }
3943     }
3944   }
3945   DEBUG(8,("is_in_path: match not found\n"));
3946  
3947   return False;
3948 }
3949
3950 /*******************************************************************
3951  Strip a '/' separated list into an array of 
3952  name_compare_enties structures suitable for 
3953  passing to is_in_path(). We do this for
3954  speed so we can pre-parse all the names in the list 
3955  and don't do it for each call to is_in_path().
3956  namelist is modified here and is assumed to be 
3957  a copy owned by the caller.
3958  We also check if the entry contains a wildcard to
3959  remove a potentially expensive call to mask_match
3960  if possible.
3961 ********************************************************************/
3962  
3963 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3964 {
3965   char *name_end;
3966   char *nameptr = namelist;
3967   int num_entries = 0;
3968   int i;
3969
3970   (*ppname_array) = NULL;
3971
3972   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
3973     return;
3974
3975   /* We need to make two passes over the string. The
3976      first to count the number of elements, the second
3977      to split it.
3978    */
3979   while(*nameptr) 
3980     {
3981       if ( *nameptr == '/' ) 
3982         {
3983           /* cope with multiple (useless) /s) */
3984           nameptr++;
3985           continue;
3986         }
3987       /* find the next / */
3988       name_end = strchr(nameptr, '/');
3989
3990       /* oops - the last check for a / didn't find one. */
3991       if (name_end == NULL)
3992         break;
3993
3994       /* next segment please */
3995       nameptr = name_end + 1;
3996       num_entries++;
3997     }
3998
3999   if(num_entries == 0)
4000     return;
4001
4002   if(( (*ppname_array) = (name_compare_entry *)malloc( 
4003            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4004         {
4005     DEBUG(0,("set_namearray: malloc fail\n"));
4006     return;
4007         }
4008
4009   /* Now copy out the names */
4010   nameptr = namelist;
4011   i = 0;
4012   while(*nameptr)
4013              {
4014       if ( *nameptr == '/' ) 
4015       {
4016           /* cope with multiple (useless) /s) */
4017           nameptr++;
4018           continue;
4019       }
4020       /* find the next / */
4021       if ((name_end = strchr(nameptr, '/')) != NULL) 
4022       {
4023           *name_end = 0;
4024          }
4025
4026       /* oops - the last check for a / didn't find one. */
4027       if(name_end == NULL) 
4028         break;
4029
4030       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4031                                 (strchr( nameptr, '*')!=NULL));
4032       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4033       {
4034         DEBUG(0,("set_namearray: malloc fail (1)\n"));
4035         return;
4036       }
4037
4038       /* next segment please */
4039       nameptr = name_end + 1;
4040       i++;
4041     }
4042   
4043   (*ppname_array)[i].name = NULL;
4044
4045   return;
4046 }
4047
4048 /****************************************************************************
4049 routine to free a namearray.
4050 ****************************************************************************/
4051
4052 void free_namearray(name_compare_entry *name_array)
4053 {
4054   if(name_array == 0)
4055     return;
4056
4057   if(name_array->name != NULL)
4058     free(name_array->name);
4059
4060   free((char *)name_array);
4061 }
4062
4063 /****************************************************************************
4064 routine to do file locking
4065 ****************************************************************************/
4066 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4067 {
4068 #if HAVE_FCNTL_LOCK
4069   struct flock lock;
4070   int ret;
4071
4072 #if 1
4073   uint32 mask = 0xC0000000;
4074
4075   /* make sure the count is reasonable, we might kill the lockd otherwise */
4076   count &= ~mask;
4077
4078   /* the offset is often strange - remove 2 of its bits if either of
4079      the top two bits are set. Shift the top ones by two bits. This
4080      still allows OLE2 apps to operate, but should stop lockd from
4081      dieing */
4082   if ((offset & mask) != 0)
4083     offset = (offset & ~mask) | ((offset & mask) >> 2);
4084 #else
4085   uint32 mask = ((unsigned)1<<31);
4086
4087   /* interpret negative counts as large numbers */
4088   if (count < 0)
4089     count &= ~mask;
4090
4091   /* no negative offsets */
4092   offset &= ~mask;
4093
4094   /* count + offset must be in range */
4095   while ((offset < 0 || (offset + count < 0)) && mask)
4096     {
4097       offset &= ~mask;
4098       mask = mask >> 1;
4099     }
4100 #endif
4101
4102
4103   DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4104
4105   lock.l_type = type;
4106   lock.l_whence = SEEK_SET;
4107   lock.l_start = (int)offset;
4108   lock.l_len = (int)count;
4109   lock.l_pid = 0;
4110
4111   errno = 0;
4112
4113   ret = fcntl(fd,op,&lock);
4114
4115   if (errno != 0)
4116     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4117
4118   /* a lock query */
4119   if (op == F_GETLK)
4120     {
4121       if ((ret != -1) &&
4122           (lock.l_type != F_UNLCK) && 
4123           (lock.l_pid != 0) && 
4124           (lock.l_pid != getpid()))
4125         {
4126           DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4127           return(True);
4128         }
4129
4130       /* it must be not locked or locked by me */
4131       return(False);
4132     }
4133
4134   /* a lock set or unset */
4135   if (ret == -1)
4136     {
4137       DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4138                offset,count,op,type,strerror(errno)));
4139
4140       /* perhaps it doesn't support this sort of locking?? */
4141       if (errno == EINVAL)
4142         {
4143           DEBUG(3,("locking not supported? returning True\n"));
4144           return(True);
4145         }
4146
4147       return(False);
4148     }
4149
4150   /* everything went OK */
4151   DEBUG(8,("Lock call successful\n"));
4152
4153   return(True);
4154 #else
4155   return(False);
4156 #endif
4157 }
4158
4159 /*******************************************************************
4160 lock a file - returning a open file descriptor or -1 on failure
4161 The timeout is in seconds. 0 means no timeout
4162 ********************************************************************/
4163 int file_lock(char *name,int timeout)
4164 {  
4165   int fd = open(name,O_RDWR|O_CREAT,0666);
4166   time_t t=0;
4167   if (fd < 0) return(-1);
4168
4169 #if HAVE_FCNTL_LOCK
4170   if (timeout) t = time(NULL);
4171   while (!timeout || (time(NULL)-t < timeout)) {
4172     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);    
4173     msleep(LOCK_RETRY_TIMEOUT);
4174   }
4175   return(-1);
4176 #else
4177   return(fd);
4178 #endif
4179 }
4180
4181 /*******************************************************************
4182 unlock a file locked by file_lock
4183 ********************************************************************/
4184 void file_unlock(int fd)
4185 {
4186   if (fd<0) return;
4187 #if HAVE_FCNTL_LOCK
4188   fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4189 #endif
4190   close(fd);
4191 }
4192
4193 /*******************************************************************
4194 is the name specified one of my netbios names
4195 returns true is it is equal, false otherwise
4196 ********************************************************************/
4197 BOOL is_myname(char *s)
4198 {
4199   int n;
4200   BOOL ret = False;
4201
4202   for (n=0; my_netbios_names[n]; n++) {
4203     if (strequal(my_netbios_names[n], s))
4204       ret=True;
4205   }
4206   DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4207   return(ret);
4208 }
4209
4210 /*******************************************************************
4211 set the horrid remote_arch string based on an enum.
4212 ********************************************************************/
4213 void set_remote_arch(enum remote_arch_types type)
4214 {
4215   ra_type = type;
4216   switch( type )
4217   {
4218   case RA_WFWG:
4219     strcpy(remote_arch, "WfWg");
4220     return;
4221   case RA_OS2:
4222     strcpy(remote_arch, "OS2");
4223     return;
4224   case RA_WIN95:
4225     strcpy(remote_arch, "Win95");
4226     return;
4227   case RA_WINNT:
4228     strcpy(remote_arch, "WinNT");
4229     return;
4230   case RA_SAMBA:
4231     strcpy(remote_arch,"Samba");
4232     return;
4233   default:
4234     ra_type = RA_UNKNOWN;
4235     strcpy(remote_arch, "UNKNOWN");
4236     break;
4237   }
4238 }
4239
4240 /*******************************************************************
4241  Get the remote_arch type.
4242 ********************************************************************/
4243 enum remote_arch_types get_remote_arch()
4244 {
4245   return ra_type;
4246 }
4247
4248
4249 /*******************************************************************
4250 skip past some unicode strings in a buffer
4251 ********************************************************************/
4252 char *skip_unicode_string(char *buf,int n)
4253 {
4254   while (n--)
4255   {
4256     while (*buf)
4257       buf += 2;
4258     buf += 2;
4259   }
4260   return(buf);
4261 }
4262
4263 /*******************************************************************
4264 Return a ascii version of a unicode string
4265 Hack alert: uses fixed buffer(s) and only handles ascii strings
4266 ********************************************************************/
4267 #define MAXUNI 1024
4268 char *unistrn2(uint16 *buf, int len)
4269 {
4270         static char lbufs[8][MAXUNI];
4271         static int nexti;
4272         char *lbuf = lbufs[nexti];
4273         char *p;
4274
4275         nexti = (nexti+1)%8;
4276
4277         DEBUG(10, ("unistrn2: "));
4278
4279         for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4280         {
4281                 DEBUG(10, ("%4x ", *buf));
4282                 *p = *buf;
4283         }
4284
4285         DEBUG(10,("\n"));
4286
4287         *p = 0;
4288         return lbuf;
4289 }
4290
4291 /*******************************************************************
4292 Return a ascii version of a unicode string
4293 Hack alert: uses fixed buffer(s) and only handles ascii strings
4294 ********************************************************************/
4295 #define MAXUNI 1024
4296 char *unistr2(uint16 *buf)
4297 {
4298         static char lbufs[8][MAXUNI];
4299         static int nexti;
4300         char *lbuf = lbufs[nexti];
4301         char *p;
4302
4303         nexti = (nexti+1)%8;
4304
4305         DEBUG(10, ("unistr2: "));
4306
4307         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4308         {
4309                 DEBUG(10, ("%4x ", *buf));
4310                 *p = *buf;
4311         }
4312
4313         DEBUG(10,("\n"));
4314
4315         *p = 0;
4316         return lbuf;
4317 }
4318
4319 /*******************************************************************
4320 create a null-terminated unicode string from a null-terminated ascii string.
4321 return number of unicode chars copied, excluding the null character.
4322
4323 only handles ascii strings
4324 ********************************************************************/
4325 #define MAXUNI 1024
4326 int struni2(uint16 *p, char *buf)
4327 {
4328         int len = 0;
4329
4330         if (p == NULL) return 0;
4331
4332         DEBUG(10, ("struni2: "));
4333
4334         if (buf != NULL)
4335         {
4336                 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4337                 {
4338                         DEBUG(10, ("%2x ", *buf));
4339                         *p = *buf;
4340                 }
4341
4342                 DEBUG(10,("\n"));
4343         }
4344
4345         *p = 0;
4346
4347         return len;
4348 }
4349
4350 /*******************************************************************
4351 Return a ascii version of a unicode string
4352 Hack alert: uses fixed buffer(s) and only handles ascii strings
4353 ********************************************************************/
4354 #define MAXUNI 1024
4355 char *unistr(char *buf)
4356 {
4357         static char lbufs[8][MAXUNI];
4358         static int nexti;
4359         char *lbuf = lbufs[nexti];
4360         char *p;
4361
4362         nexti = (nexti+1)%8;
4363
4364         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4365         {
4366                 *p = *buf;
4367         }
4368         *p = 0;
4369         return lbuf;
4370 }
4371
4372 /*******************************************************************
4373 strncpy for unicode strings
4374 ********************************************************************/
4375 int unistrncpy(char *dst, char *src, int len)
4376 {
4377         int num_wchars = 0;
4378
4379         while (*src && len > 0)
4380         {
4381                 *dst++ = *src++;
4382                 *dst++ = *src++;
4383                 len--;
4384                 num_wchars++;
4385         }
4386         *dst++ = 0;
4387         *dst++ = 0;
4388
4389         return num_wchars;
4390 }
4391
4392
4393 /*******************************************************************
4394 strcpy for unicode strings.  returns length (in num of wide chars)
4395 ********************************************************************/
4396 int unistrcpy(char *dst, char *src)
4397 {
4398         int num_wchars = 0;
4399
4400         while (*src)
4401         {
4402                 *dst++ = *src++;
4403                 *dst++ = *src++;
4404                 num_wchars++;
4405         }
4406         *dst++ = 0;
4407         *dst++ = 0;
4408
4409         return num_wchars;
4410 }
4411
4412
4413 /*******************************************************************
4414 safe string copy into a fstring
4415 ********************************************************************/
4416 void fstrcpy(char *dest, char *src)
4417 {
4418     int maxlength = sizeof(fstring) - 1;
4419     if (!dest) {
4420         DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4421         return;
4422     }
4423
4424     if (!src) {
4425         *dest = 0;
4426         return;
4427     }  
4428       
4429     while (maxlength-- && *src)
4430         *dest++ = *src++;
4431     *dest = 0;
4432     if (*src) {
4433         DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4434              strlen(src)));
4435     }    
4436 }   
4437
4438 /*******************************************************************
4439 safe string copy into a pstring
4440 ********************************************************************/
4441 void pstrcpy(char *dest, char *src)
4442 {
4443     int maxlength = sizeof(pstring) - 1;
4444     if (!dest) {
4445         DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4446         return;
4447     }
4448    
4449     if (!src) {
4450         *dest = 0;
4451         return;
4452     }
4453    
4454     while (maxlength-- && *src)
4455         *dest++ = *src++;
4456     *dest = 0;
4457     if (*src) {
4458         DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4459              strlen(src)));
4460     }
4461 }  
4462
4463
4464 /*******************************************************************
4465 align a pointer to a multiple of 4 bytes
4466 ********************************************************************/
4467 char *align4(char *q, char *base)
4468 {
4469         if ((q - base) & 3)
4470         {
4471                 q += 4 - ((q - base) & 3);
4472         }
4473         return q;
4474 }
4475
4476 /*******************************************************************
4477 align a pointer to a multiple of 2 bytes
4478 ********************************************************************/
4479 char *align2(char *q, char *base)
4480 {
4481         if ((q - base) & 1)
4482         {
4483                 q++;
4484         }
4485         return q;
4486 }
4487
4488 /*******************************************************************
4489 align a pointer to a multiple of align_offset bytes.  looks like it
4490 will work for offsets of 0, 2 and 4...
4491 ********************************************************************/
4492 char *align_offset(char *q, char *base, int align_offset_len)
4493 {
4494         int mod = ((q - base) & (align_offset_len-1));
4495         if (align_offset_len != 0 && mod != 0)
4496         {
4497                 q += align_offset_len - mod;
4498         }
4499         return q;
4500 }
4501
4502 void print_asc(int level, unsigned char *buf,int len)
4503 {
4504         int i;
4505         for (i=0;i<len;i++)
4506                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4507 }
4508
4509 void dump_data(int level,char *buf1,int len)
4510 {
4511   unsigned char *buf = (unsigned char *)buf1;
4512   int i=0;
4513   if (len<=0) return;
4514
4515   DEBUG(level,("[%03X] ",i));
4516   for (i=0;i<len;) {
4517     DEBUG(level,("%02X ",(int)buf[i]));
4518     i++;
4519     if (i%8 == 0) DEBUG(level,(" "));
4520     if (i%16 == 0) {      
4521       print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4522       print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4523       if (i<len) DEBUG(level,("[%03X] ",i));
4524     }
4525   }
4526   if (i%16) {
4527     int n;
4528
4529     n = 16 - (i%16);
4530     DEBUG(level,(" "));
4531     if (n>8) DEBUG(level,(" "));
4532     while (n--) DEBUG(level,("   "));
4533
4534     n = MIN(8,i%16);
4535     print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4536     n = (i%16) - n;
4537     if (n>0) print_asc(level,&buf[i-n],n); 
4538     DEBUG(level,("\n"));    
4539   }
4540 }
4541
4542 char *tab_depth(int depth)
4543 {
4544         static pstring spaces;
4545         memset(spaces, ' ', depth * 4);
4546         spaces[depth * 4] = 0;
4547         return spaces;
4548 }
4549
4550