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