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