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