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