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