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