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