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