ypserver not available: AUTOMOUNT server and path don't work.
[samba.git] / source / 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   smb_read_error = 0;
2496
2497   if(timeout != 0)
2498   {
2499     struct timeval to;
2500     fd_set fds;
2501     int selrtn;
2502
2503     FD_ZERO(&fds);
2504     FD_SET(fd,&fds);
2505
2506     to.tv_sec = timeout / 1000;
2507     to.tv_usec = (timeout % 1000) * 1000;
2508
2509     selrtn = sys_select(&fds,&to);
2510
2511     /* Check if error */
2512     if(selrtn == -1) 
2513     {
2514       /* something is wrong. Maybe the socket is dead? */
2515       smb_read_error = READ_ERROR;
2516       return False;
2517     } 
2518     
2519     /* Did we timeout ? */
2520     if (selrtn == 0) 
2521     {
2522       smb_read_error = READ_TIMEOUT;
2523       return False;
2524     }
2525   }
2526
2527   /*
2528    * Read a loopback udp message.
2529    */
2530   msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], 
2531                      buffer_len - UDP_CMD_HEADER_LEN, 0,
2532                      (struct sockaddr *)&from, &fromlen);
2533
2534   if(msg_len < 0)
2535   {
2536     DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2537     return False;
2538   }
2539
2540   /* Validate message length. */
2541   if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2542   {
2543     DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2544               msg_len, 
2545               buffer_len  - UDP_CMD_HEADER_LEN));
2546     return False;
2547   }
2548
2549   /* Validate message from address (must be localhost). */
2550   if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2551   {
2552     DEBUG(0,("receive_local_message: invalid 'from' address \
2553 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2554    return False;
2555   }
2556
2557   /* Setup the message header */
2558   SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2559   SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2560
2561   return True;
2562 }
2563
2564 /****************************************************************************
2565  structure to hold a linked list of local messages.
2566  for processing.
2567 ****************************************************************************/
2568
2569 typedef struct _message_list {
2570    struct _message_list *msg_next;
2571    char *msg_buf;
2572    int msg_len;
2573 } pending_message_list;
2574
2575 static pending_message_list *smb_msg_head = NULL;
2576
2577 /****************************************************************************
2578  Function to push a linked list of local messages ready
2579  for processing.
2580 ****************************************************************************/
2581
2582 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2583 {
2584   pending_message_list *msg = (pending_message_list *)
2585                                malloc(sizeof(pending_message_list));
2586
2587   if(msg == NULL)
2588   {
2589     DEBUG(0,("push_message: malloc fail (1)\n"));
2590     return False;
2591   }
2592
2593   msg->msg_buf = (char *)malloc(msg_len);
2594   if(msg->msg_buf == NULL)
2595   {
2596     DEBUG(0,("push_local_message: malloc fail (2)\n"));
2597     free((char *)msg);
2598     return False;
2599   }
2600
2601   memcpy(msg->msg_buf, buf, msg_len);
2602   msg->msg_len = msg_len;
2603
2604   msg->msg_next = *pml;
2605   *pml = msg;
2606
2607   return True;
2608 }
2609
2610 /****************************************************************************
2611  Function to push a linked list of local smb messages ready
2612  for processing.
2613 ****************************************************************************/
2614
2615 BOOL push_smb_message(char *buf, int msg_len)
2616 {
2617   return push_local_message(&smb_msg_head, buf, msg_len);
2618 }
2619
2620 /****************************************************************************
2621   Do a select on an two fd's - with timeout. 
2622
2623   If a local udp message has been pushed onto the
2624   queue (this can only happen during oplock break
2625   processing) return this first.
2626
2627   If a pending smb message has been pushed onto the
2628   queue (this can only happen during oplock break
2629   processing) return this next.
2630
2631   If the first smbfd is ready then read an smb from it.
2632   if the second (loopback UDP) fd is ready then read a message
2633   from it and setup the buffer header to identify the length
2634   and from address.
2635   Returns False on timeout or error.
2636   Else returns True.
2637
2638 The timeout is in milli seconds
2639 ****************************************************************************/
2640 BOOL receive_message_or_smb(int smbfd, int oplock_fd, 
2641                            char *buffer, int buffer_len, 
2642                            int timeout, BOOL *got_smb)
2643 {
2644   fd_set fds;
2645   int selrtn;
2646   struct timeval to;
2647
2648   smb_read_error = 0;
2649
2650   *got_smb = False;
2651
2652   /*
2653    * Check to see if we already have a message on the smb queue.
2654    * If so - copy and return it.
2655    */
2656   
2657   if(smb_msg_head)
2658   {
2659     pending_message_list *msg = smb_msg_head;
2660     memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2661     smb_msg_head = msg->msg_next;
2662   
2663     /* Free the message we just copied. */
2664     free((char *)msg->msg_buf);
2665     free((char *)msg);
2666     *got_smb = True;
2667
2668     DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2669     return True;
2670   }
2671
2672   FD_ZERO(&fds);
2673   FD_SET(smbfd,&fds);
2674   FD_SET(oplock_fd,&fds);
2675
2676   to.tv_sec = timeout / 1000;
2677   to.tv_usec = (timeout % 1000) * 1000;
2678
2679   selrtn = sys_select(&fds,timeout>0?&to:NULL);
2680
2681   /* Check if error */
2682   if(selrtn == -1) {
2683     /* something is wrong. Maybe the socket is dead? */
2684     smb_read_error = READ_ERROR;
2685     return False;
2686   } 
2687     
2688   /* Did we timeout ? */
2689   if (selrtn == 0) {
2690     smb_read_error = READ_TIMEOUT;
2691     return False;
2692   }
2693
2694   if (FD_ISSET(smbfd,&fds))
2695   {
2696     *got_smb = True;
2697     return receive_smb(smbfd, buffer, 0);
2698   }
2699   else
2700   {
2701     return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2702   }
2703 }
2704
2705 /****************************************************************************
2706   send an smb to a fd 
2707 ****************************************************************************/
2708 BOOL send_smb(int fd,char *buffer)
2709 {
2710   int len;
2711   int ret,nwritten=0;
2712   len = smb_len(buffer) + 4;
2713
2714   while (nwritten < len)
2715     {
2716       ret = write_socket(fd,buffer+nwritten,len - nwritten);
2717       if (ret <= 0)
2718         {
2719           DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2720           close_sockets();
2721           exit(1);
2722         }
2723       nwritten += ret;
2724     }
2725
2726
2727   return True;
2728 }
2729
2730
2731 /****************************************************************************
2732 find a pointer to a netbios name
2733 ****************************************************************************/
2734 char *name_ptr(char *buf,int ofs)
2735 {
2736   unsigned char c = *(unsigned char *)(buf+ofs);
2737
2738   if ((c & 0xC0) == 0xC0)
2739     {
2740       uint16 l;
2741       char p[2];
2742       memcpy(p,buf+ofs,2);
2743       p[0] &= ~0xC0;
2744       l = RSVAL(p,0);
2745       DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2746       return(buf + l);
2747     }
2748   else
2749     return(buf+ofs);
2750 }  
2751
2752 /****************************************************************************
2753 extract a netbios name from a buf
2754 ****************************************************************************/
2755 int name_extract(char *buf,int ofs,char *name)
2756 {
2757   char *p = name_ptr(buf,ofs);
2758   int d = PTR_DIFF(p,buf+ofs);
2759   strcpy(name,"");
2760   if (d < -50 || d > 50) return(0);
2761   return(name_interpret(p,name));
2762 }
2763   
2764 /****************************************************************************
2765 return the total storage length of a mangled name
2766 ****************************************************************************/
2767 int name_len( char *s )
2768   {
2769   int len;
2770
2771   /* If the two high bits of the byte are set, return 2. */
2772   if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2773     return(2);
2774
2775   /* Add up the length bytes. */
2776   for( len = 1; (*s); s += (*s) + 1 )
2777     {
2778     len += *s + 1;
2779     }
2780
2781   return( len );
2782   } /* name_len */
2783
2784 /****************************************************************************
2785 send a single packet to a port on another machine
2786 ****************************************************************************/
2787 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2788 {
2789   BOOL ret;
2790   int out_fd;
2791   struct sockaddr_in sock_out;
2792
2793   if (passive)
2794     return(True);
2795
2796   /* create a socket to write to */
2797   out_fd = socket(AF_INET, type, 0);
2798   if (out_fd == -1) 
2799     {
2800       DEBUG(0,("socket failed"));
2801       return False;
2802     }
2803
2804   /* set the address and port */
2805   bzero((char *)&sock_out,sizeof(sock_out));
2806   putip((char *)&sock_out.sin_addr,(char *)&ip);
2807   sock_out.sin_port = htons( port );
2808   sock_out.sin_family = AF_INET;
2809   
2810   if (DEBUGLEVEL > 0)
2811     DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2812              len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2813         
2814   /* send it */
2815   ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2816
2817   if (!ret)
2818     DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2819              inet_ntoa(ip),port,strerror(errno)));
2820
2821   close(out_fd);
2822   return(ret);
2823 }
2824
2825 /*******************************************************************
2826 sleep for a specified number of milliseconds
2827 ********************************************************************/
2828 void msleep(int t)
2829 {
2830   int tdiff=0;
2831   struct timeval tval,t1,t2;  
2832   fd_set fds;
2833
2834   GetTimeOfDay(&t1);
2835   GetTimeOfDay(&t2);
2836   
2837   while (tdiff < t) {
2838     tval.tv_sec = (t-tdiff)/1000;
2839     tval.tv_usec = 1000*((t-tdiff)%1000);
2840  
2841     FD_ZERO(&fds);
2842     errno = 0;
2843     sys_select(&fds,&tval);
2844
2845     GetTimeOfDay(&t2);
2846     tdiff = TvalDiff(&t1,&t2);
2847   }
2848 }
2849
2850 /****************************************************************************
2851 check if a string is part of a list
2852 ****************************************************************************/
2853 BOOL in_list(char *s,char *list,BOOL casesensitive)
2854 {
2855   pstring tok;
2856   char *p=list;
2857
2858   if (!list) return(False);
2859
2860   while (next_token(&p,tok,LIST_SEP))
2861     {
2862       if (casesensitive) {
2863         if (strcmp(tok,s) == 0)
2864           return(True);
2865       } else {
2866         if (StrCaseCmp(tok,s) == 0)
2867           return(True);
2868       }
2869     }
2870   return(False);
2871 }
2872
2873 /* this is used to prevent lots of mallocs of size 1 */
2874 static char *null_string = NULL;
2875
2876 /****************************************************************************
2877 set a string value, allocing the space for the string
2878 ****************************************************************************/
2879 BOOL string_init(char **dest,char *src)
2880 {
2881   int l;
2882   if (!src)     
2883     src = "";
2884
2885   l = strlen(src);
2886
2887   if (l == 0)
2888     {
2889       if (!null_string)
2890         null_string = (char *)malloc(1);
2891
2892       *null_string = 0;
2893       *dest = null_string;
2894     }
2895   else
2896     {
2897       (*dest) = (char *)malloc(l+1);
2898       if ((*dest) == NULL) {
2899               DEBUG(0,("Out of memory in string_init\n"));
2900               return False;
2901       }
2902
2903       strcpy(*dest,src);
2904     }
2905   return(True);
2906 }
2907
2908 /****************************************************************************
2909 free a string value
2910 ****************************************************************************/
2911 void string_free(char **s)
2912 {
2913   if (!s || !(*s)) return;
2914   if (*s == null_string)
2915     *s = NULL;
2916   if (*s) free(*s);
2917   *s = NULL;
2918 }
2919
2920 /****************************************************************************
2921 set a string value, allocing the space for the string, and deallocating any 
2922 existing space
2923 ****************************************************************************/
2924 BOOL string_set(char **dest,char *src)
2925 {
2926   string_free(dest);
2927
2928   return(string_init(dest,src));
2929 }
2930
2931 /****************************************************************************
2932 substitute a string for a pattern in another string. Make sure there is 
2933 enough room!
2934
2935 This routine looks for pattern in s and replaces it with 
2936 insert. It may do multiple replacements.
2937
2938 return True if a substitution was done.
2939 ****************************************************************************/
2940 BOOL string_sub(char *s,char *pattern,char *insert)
2941 {
2942   BOOL ret = False;
2943   char *p;
2944   int ls,lp,li;
2945
2946   if (!insert || !pattern || !s) return(False);
2947
2948   ls = strlen(s);
2949   lp = strlen(pattern);
2950   li = strlen(insert);
2951
2952   if (!*pattern) return(False);
2953
2954   while (lp <= ls && (p = strstr(s,pattern)))
2955     {
2956       ret = True;
2957       memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2958       memcpy(p,insert,li);
2959       s = p + li;
2960       ls = strlen(s);
2961     }
2962   return(ret);
2963 }
2964
2965
2966
2967 /*********************************************************
2968 * Recursive routine that is called by mask_match.
2969 * Does the actual matching.
2970 *********************************************************/
2971 BOOL do_match(char *str, char *regexp, int case_sig)
2972 {
2973   char *p;
2974
2975   for( p = regexp; *p && *str; ) {
2976     switch(*p) {
2977     case '?':
2978       str++; p++;
2979       break;
2980
2981     case '*':
2982       /* Look for a character matching 
2983          the one after the '*' */
2984       p++;
2985       if(!*p)
2986         return True; /* Automatic match */
2987       while(*str) {
2988         while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2989           str++;
2990         if(do_match(str,p,case_sig))
2991           return True;
2992         if(!*str)
2993           return False;
2994         else
2995           str++;
2996       }
2997       return False;
2998
2999     default:
3000       if(case_sig) {
3001         if(*str != *p)
3002           return False;
3003       } else {
3004         if(toupper(*str) != toupper(*p))
3005           return False;
3006       }
3007       str++, p++;
3008       break;
3009     }
3010   }
3011   if(!*p && !*str)
3012     return True;
3013
3014   if (!*p && str[0] == '.' && str[1] == 0)
3015     return(True);
3016   
3017   if (!*str && *p == '?')
3018     {
3019       while (*p == '?') p++;
3020       return(!*p);
3021     }
3022
3023   if(!*str && (*p == '*' && p[1] == '\0'))
3024     return True;
3025   return False;
3026 }
3027
3028
3029 /*********************************************************
3030 * Routine to match a given string with a regexp - uses
3031 * simplified regexp that takes * and ? only. Case can be
3032 * significant or not.
3033 *********************************************************/
3034 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3035 {
3036   char *p;
3037   pstring p1, p2;
3038   fstring ebase,eext,sbase,sext;
3039
3040   BOOL matched;
3041
3042   /* Make local copies of str and regexp */
3043   StrnCpy(p1,regexp,sizeof(pstring)-1);
3044   StrnCpy(p2,str,sizeof(pstring)-1);
3045
3046   if (!strchr(p2,'.')) {
3047     strcat(p2,".");
3048   }
3049
3050 /*
3051   if (!strchr(p1,'.')) {
3052     strcat(p1,".");
3053   }
3054 */
3055
3056 #if 0
3057   if (strchr(p1,'.'))
3058     {
3059       string_sub(p1,"*.*","*");
3060       string_sub(p1,".*","*");
3061     }
3062 #endif
3063
3064   /* Remove any *? and ** as they are meaningless */
3065   for(p = p1; *p; p++)
3066     while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3067       (void)strcpy( &p[1], &p[2]);
3068
3069   if (strequal(p1,"*")) return(True);
3070
3071   DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3072
3073   if (trans2) {
3074     fstrcpy(ebase,p1);
3075     fstrcpy(sbase,p2);
3076   } else {
3077     if ((p=strrchr(p1,'.'))) {
3078       *p = 0;
3079       fstrcpy(ebase,p1);
3080       fstrcpy(eext,p+1);
3081     } else {
3082       fstrcpy(ebase,p1);
3083       eext[0] = 0;
3084     }
3085
3086   if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3087     *p = 0;
3088     fstrcpy(sbase,p2);
3089     fstrcpy(sext,p+1);
3090   } else {
3091     fstrcpy(sbase,p2);
3092     fstrcpy(sext,"");
3093   }
3094   }
3095
3096   matched = do_match(sbase,ebase,case_sig) && 
3097     (trans2 || do_match(sext,eext,case_sig));
3098
3099   DEBUG(8,("mask_match returning %d\n", matched));
3100
3101   return matched;
3102 }
3103
3104
3105
3106 /****************************************************************************
3107 become a daemon, discarding the controlling terminal
3108 ****************************************************************************/
3109 void become_daemon(void)
3110 {
3111 #ifndef NO_FORK_DEBUG
3112   if (fork())
3113     _exit(0);
3114
3115   /* detach from the terminal */
3116 #ifdef USE_SETSID
3117   setsid();
3118 #else /* USE_SETSID */
3119 #ifdef TIOCNOTTY
3120   {
3121     int i = open("/dev/tty", O_RDWR);
3122     if (i >= 0) 
3123       {
3124         ioctl(i, (int) TIOCNOTTY, (char *)0);      
3125         close(i);
3126       }
3127   }
3128 #endif /* TIOCNOTTY */
3129 #endif /* USE_SETSID */
3130   /* Close fd's 0,1,2. Needed if started by rsh */
3131   close_low_fds();
3132 #endif /* NO_FORK_DEBUG */
3133 }
3134
3135
3136 /****************************************************************************
3137 put up a yes/no prompt
3138 ****************************************************************************/
3139 BOOL yesno(char *p)
3140 {
3141   pstring ans;
3142   printf("%s",p);
3143
3144   if (!fgets(ans,sizeof(ans)-1,stdin))
3145     return(False);
3146
3147   if (*ans == 'y' || *ans == 'Y')
3148     return(True);
3149
3150   return(False);
3151 }
3152
3153 /****************************************************************************
3154 read a line from a file with possible \ continuation chars. 
3155 Blanks at the start or end of a line are stripped.
3156 The string will be allocated if s2 is NULL
3157 ****************************************************************************/
3158 char *fgets_slash(char *s2,int maxlen,FILE *f)
3159 {
3160   char *s=s2;
3161   int len = 0;
3162   int c;
3163   BOOL start_of_line = True;
3164
3165   if (feof(f))
3166     return(NULL);
3167
3168   if (!s2)
3169     {
3170       maxlen = MIN(maxlen,8);
3171       s = (char *)Realloc(s,maxlen);
3172     }
3173
3174   if (!s || maxlen < 2) return(NULL);
3175
3176   *s = 0;
3177
3178   while (len < maxlen-1)
3179     {
3180       c = getc(f);
3181       switch (c)
3182         {
3183         case '\r':
3184           break;
3185         case '\n':
3186           while (len > 0 && s[len-1] == ' ')
3187             {
3188               s[--len] = 0;
3189             }
3190           if (len > 0 && s[len-1] == '\\')
3191             {
3192               s[--len] = 0;
3193               start_of_line = True;
3194               break;
3195             }
3196           return(s);
3197         case EOF:
3198           if (len <= 0 && !s2) 
3199             free(s);
3200           return(len>0?s:NULL);
3201         case ' ':
3202           if (start_of_line)
3203             break;
3204         default:
3205           start_of_line = False;
3206           s[len++] = c;
3207           s[len] = 0;
3208         }
3209       if (!s2 && len > maxlen-3)
3210         {
3211           maxlen *= 2;
3212           s = (char *)Realloc(s,maxlen);
3213           if (!s) return(NULL);
3214         }
3215     }
3216   return(s);
3217 }
3218
3219
3220
3221 /****************************************************************************
3222 set the length of a file from a filedescriptor.
3223 Returns 0 on success, -1 on failure.
3224 ****************************************************************************/
3225 int set_filelen(int fd, long len)
3226 {
3227 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3228    extend a file with ftruncate. Provide alternate implementation
3229    for this */
3230
3231 #if FTRUNCATE_CAN_EXTEND
3232   return ftruncate(fd, len);
3233 #else
3234   struct stat st;
3235   char c = 0;
3236   long currpos = lseek(fd, 0L, SEEK_CUR);
3237
3238   if(currpos < 0)
3239     return -1;
3240   /* Do an fstat to see if the file is longer than
3241      the requested size (call ftruncate),
3242      or shorter, in which case seek to len - 1 and write 1
3243      byte of zero */
3244   if(fstat(fd, &st)<0)
3245     return -1;
3246
3247 #ifdef S_ISFIFO
3248   if (S_ISFIFO(st.st_mode)) return 0;
3249 #endif
3250
3251   if(st.st_size == len)
3252     return 0;
3253   if(st.st_size > len)
3254     return ftruncate(fd, len);
3255
3256   if(lseek(fd, len-1, SEEK_SET) != len -1)
3257     return -1;
3258   if(write(fd, &c, 1)!=1)
3259     return -1;
3260   /* Seek to where we were */
3261   lseek(fd, currpos, SEEK_SET);
3262   return 0;
3263 #endif
3264 }
3265
3266
3267 /****************************************************************************
3268 return the byte checksum of some data
3269 ****************************************************************************/
3270 int byte_checksum(char *buf,int len)
3271 {
3272   unsigned char *p = (unsigned char *)buf;
3273   int ret = 0;
3274   while (len--)
3275     ret += *p++;
3276   return(ret);
3277 }
3278
3279
3280
3281 #ifdef HPUX
3282 /****************************************************************************
3283 this is a version of setbuffer() for those machines that only have setvbuf
3284 ****************************************************************************/
3285  void setbuffer(FILE *f,char *buf,int bufsize)
3286 {
3287   setvbuf(f,buf,_IOFBF,bufsize);
3288 }
3289 #endif
3290
3291
3292 /****************************************************************************
3293 parse out a directory name from a path name. Assumes dos style filenames.
3294 ****************************************************************************/
3295 char *dirname_dos(char *path,char *buf)
3296 {
3297   char *p = strrchr(path,'\\');
3298
3299   if (!p)
3300     strcpy(buf,path);
3301   else
3302     {
3303       *p = 0;
3304       strcpy(buf,path);
3305       *p = '\\';
3306     }
3307
3308   return(buf);
3309 }
3310
3311
3312 /****************************************************************************
3313 parse out a filename from a path name. Assumes dos style filenames.
3314 ****************************************************************************/
3315 static char *filename_dos(char *path,char *buf)
3316 {
3317   char *p = strrchr(path,'\\');
3318
3319   if (!p)
3320     strcpy(buf,path);
3321   else
3322     strcpy(buf,p+1);
3323
3324   return(buf);
3325 }
3326
3327
3328
3329 /****************************************************************************
3330 expand a pointer to be a particular size
3331 ****************************************************************************/
3332 void *Realloc(void *p,int size)
3333 {
3334   void *ret=NULL;
3335
3336   if (size == 0) {
3337     if (p) free(p);
3338     DEBUG(5,("Realloc asked for 0 bytes\n"));
3339     return NULL;
3340   }
3341
3342   if (!p)
3343     ret = (void *)malloc(size);
3344   else
3345     ret = (void *)realloc(p,size);
3346
3347   if (!ret)
3348     DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3349
3350   return(ret);
3351 }
3352
3353 #ifdef NOSTRDUP
3354 /****************************************************************************
3355 duplicate a string
3356 ****************************************************************************/
3357  char *strdup(char *s)
3358 {
3359   char *ret = NULL;
3360   if (!s) return(NULL);
3361   ret = (char *)malloc(strlen(s)+1);
3362   if (!ret) return(NULL);
3363   strcpy(ret,s);
3364   return(ret);
3365 }
3366 #endif
3367
3368
3369 /****************************************************************************
3370   Signal handler for SIGPIPE (write on a disconnected socket) 
3371 ****************************************************************************/
3372 void Abort(void )
3373 {
3374   DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3375   exit(2);
3376 }
3377
3378 /****************************************************************************
3379 get my own name and IP
3380 ****************************************************************************/
3381 BOOL get_myname(char *my_name,struct in_addr *ip)
3382 {
3383   struct hostent *hp;
3384   pstring hostname;
3385
3386   *hostname = 0;
3387
3388   /* get my host name */
3389   if (gethostname(hostname, MAXHOSTNAMELEN) == -1) 
3390     {
3391       DEBUG(0,("gethostname failed\n"));
3392       return False;
3393     } 
3394
3395   /* get host info */
3396   if ((hp = Get_Hostbyname(hostname)) == 0) 
3397     {
3398       DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3399       return False;
3400     }
3401
3402   if (my_name)
3403     {
3404       /* split off any parts after an initial . */
3405       char *p = strchr(hostname,'.');
3406       if (p) *p = 0;
3407
3408       fstrcpy(my_name,hostname);
3409     }
3410
3411   if (ip)
3412     putip((char *)ip,(char *)hp->h_addr);
3413
3414   return(True);
3415 }
3416
3417
3418 /****************************************************************************
3419 true if two IP addresses are equal
3420 ****************************************************************************/
3421 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3422 {
3423   uint32 a1,a2;
3424   a1 = ntohl(ip1.s_addr);
3425   a2 = ntohl(ip2.s_addr);
3426   return(a1 == a2);
3427 }
3428
3429
3430 /****************************************************************************
3431 open a socket of the specified type, port and address for incoming data
3432 ****************************************************************************/
3433 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3434 {
3435   struct hostent *hp;
3436   struct sockaddr_in sock;
3437   pstring host_name;
3438   int res;
3439
3440   /* get my host name */
3441   if (gethostname(host_name, MAXHOSTNAMELEN) == -1) 
3442     { DEBUG(0,("gethostname failed\n")); return -1; } 
3443
3444   /* get host info */
3445   if ((hp = Get_Hostbyname(host_name)) == 0) 
3446     {
3447       DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3448       return -1;
3449     }
3450   
3451   bzero((char *)&sock,sizeof(sock));
3452   memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3453 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3454   sock.sin_len = sizeof(sock);
3455 #endif
3456   sock.sin_port = htons( port );
3457   sock.sin_family = hp->h_addrtype;
3458   sock.sin_addr.s_addr = socket_addr;
3459   res = socket(hp->h_addrtype, type, 0);
3460   if (res == -1) 
3461     { DEBUG(0,("socket failed\n")); return -1; }
3462
3463   {
3464     int one=1;
3465     setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3466   }
3467
3468   /* now we've got a socket - we need to bind it */
3469   if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0) 
3470     { 
3471       if (port) {
3472         if (port == SMB_PORT || port == NMB_PORT)
3473           DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3474                         port,inet_ntoa(sock.sin_addr),strerror(errno))); 
3475         close(res); 
3476
3477         if (dlevel > 0 && port < 1000)
3478           port = 7999;
3479
3480         if (port >= 1000 && port < 9000)
3481           return(open_socket_in(type,port+1,dlevel,socket_addr));
3482       }
3483
3484       return(-1); 
3485     }
3486   DEBUG(3,("bind succeeded on port %d\n",port));
3487
3488   return res;
3489 }
3490
3491
3492 /****************************************************************************
3493   create an outgoing socket
3494   **************************************************************************/
3495 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3496 {
3497   struct sockaddr_in sock_out;
3498   int res,ret;
3499   int connect_loop = 250; /* 250 milliseconds */
3500   int loops = (timeout * 1000) / connect_loop;
3501
3502   /* create a socket to write to */
3503   res = socket(PF_INET, type, 0);
3504   if (res == -1) 
3505     { DEBUG(0,("socket error\n")); return -1; }
3506
3507   if (type != SOCK_STREAM) return(res);
3508   
3509   bzero((char *)&sock_out,sizeof(sock_out));
3510   putip((char *)&sock_out.sin_addr,(char *)addr);
3511   
3512   sock_out.sin_port = htons( port );
3513   sock_out.sin_family = PF_INET;
3514
3515   /* set it non-blocking */
3516   set_blocking(res,False);
3517
3518   DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3519   
3520   /* and connect it to the destination */
3521 connect_again:
3522   ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3523
3524   /* Some systems return EAGAIN when they mean EINPROGRESS */
3525   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3526         errno == EAGAIN) && loops--) {
3527     msleep(connect_loop);
3528     goto connect_again;
3529   }
3530
3531   if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3532          errno == EAGAIN)) {
3533       DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3534       close(res);
3535       return -1;
3536   }
3537
3538 #ifdef EISCONN
3539   if (ret < 0 && errno == EISCONN) {
3540     errno = 0;
3541     ret = 0;
3542   }
3543 #endif
3544
3545   if (ret < 0) {
3546     DEBUG(1,("error connecting to %s:%d (%s)\n",
3547              inet_ntoa(*addr),port,strerror(errno)));
3548     return -1;
3549   }
3550
3551   /* set it blocking again */
3552   set_blocking(res,True);
3553
3554   return res;
3555 }
3556
3557
3558 /****************************************************************************
3559 interpret a protocol description string, with a default
3560 ****************************************************************************/
3561 int interpret_protocol(char *str,int def)
3562 {
3563   if (strequal(str,"NT1"))
3564     return(PROTOCOL_NT1);
3565   if (strequal(str,"LANMAN2"))
3566     return(PROTOCOL_LANMAN2);
3567   if (strequal(str,"LANMAN1"))
3568     return(PROTOCOL_LANMAN1);
3569   if (strequal(str,"CORE"))
3570     return(PROTOCOL_CORE);
3571   if (strequal(str,"COREPLUS"))
3572     return(PROTOCOL_COREPLUS);
3573   if (strequal(str,"CORE+"))
3574     return(PROTOCOL_COREPLUS);
3575   
3576   DEBUG(0,("Unrecognised protocol level %s\n",str));
3577   
3578   return(def);
3579 }
3580
3581 /****************************************************************************
3582 interpret a security level
3583 ****************************************************************************/
3584 int interpret_security(char *str,int def)
3585 {
3586   if (strequal(str,"SERVER"))
3587     return(SEC_SERVER);
3588   if (strequal(str,"USER"))
3589     return(SEC_USER);
3590   if (strequal(str,"SHARE"))
3591     return(SEC_SHARE);
3592   
3593   DEBUG(0,("Unrecognised security level %s\n",str));
3594   
3595   return(def);
3596 }
3597
3598
3599 /****************************************************************************
3600 interpret an internet address or name into an IP address in 4 byte form
3601 ****************************************************************************/
3602 uint32 interpret_addr(char *str)
3603 {
3604   struct hostent *hp;
3605   uint32 res;
3606   int i;
3607   BOOL pure_address = True;
3608
3609   if (strcmp(str,"0.0.0.0") == 0) return(0);
3610   if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3611
3612   for (i=0; pure_address && str[i]; i++)
3613     if (!(isdigit(str[i]) || str[i] == '.')) 
3614       pure_address = False;
3615
3616   /* if it's in the form of an IP address then get the lib to interpret it */
3617   if (pure_address) {
3618     res = inet_addr(str);
3619   } else {
3620     /* otherwise assume it's a network name of some sort and use 
3621        Get_Hostbyname */
3622     if ((hp = Get_Hostbyname(str)) == 0) {
3623       DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3624       return 0;
3625     }
3626     if(hp->h_addr == NULL) {
3627       DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3628       return 0;
3629     }
3630     putip((char *)&res,(char *)hp->h_addr);
3631   }
3632
3633   if (res == (uint32)-1) return(0);
3634
3635   return(res);
3636 }
3637
3638 /*******************************************************************
3639   a convenient addition to interpret_addr()
3640   ******************************************************************/
3641 struct in_addr *interpret_addr2(char *str)
3642 {
3643   static struct in_addr ret;
3644   uint32 a = interpret_addr(str);
3645   ret.s_addr = a;
3646   return(&ret);
3647 }
3648
3649 /*******************************************************************
3650   check if an IP is the 0.0.0.0
3651   ******************************************************************/
3652 BOOL zero_ip(struct in_addr ip)
3653 {
3654   uint32 a;
3655   putip((char *)&a,(char *)&ip);
3656   return(a == 0);
3657 }
3658
3659
3660 /*******************************************************************
3661  matchname - determine if host name matches IP address 
3662  ******************************************************************/
3663 static BOOL matchname(char *remotehost,struct in_addr  addr)
3664 {
3665   struct hostent *hp;
3666   int     i;
3667   
3668   if ((hp = Get_Hostbyname(remotehost)) == 0) {
3669     DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3670     return False;
3671   } 
3672
3673   /*
3674    * Make sure that gethostbyname() returns the "correct" host name.
3675    * Unfortunately, gethostbyname("localhost") sometimes yields
3676    * "localhost.domain". Since the latter host name comes from the
3677    * local DNS, we just have to trust it (all bets are off if the local
3678    * DNS is perverted). We always check the address list, though.
3679    */
3680   
3681   if (strcasecmp(remotehost, hp->h_name)
3682       && strcasecmp(remotehost, "localhost")) {
3683     DEBUG(0,("host name/name mismatch: %s != %s",
3684              remotehost, hp->h_name));
3685     return False;
3686   }
3687         
3688   /* Look up the host address in the address list we just got. */
3689   for (i = 0; hp->h_addr_list[i]; i++) {
3690     if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3691       return True;
3692   }
3693
3694   /*
3695    * The host name does not map to the original host address. Perhaps
3696    * someone has compromised a name server. More likely someone botched
3697    * it, but that could be dangerous, too.
3698    */
3699   
3700   DEBUG(0,("host name/address mismatch: %s != %s",
3701            inet_ntoa(addr), hp->h_name));
3702   return False;
3703 }
3704
3705 /*******************************************************************
3706  Reset the 'done' variables so after a client process is created
3707  from a fork call these calls will be re-done. This should be
3708  expanded if more variables need reseting.
3709  ******************************************************************/
3710
3711 static BOOL global_client_name_done = False;
3712 static BOOL global_client_addr_done = False;
3713
3714 void reset_globals_after_fork()
3715 {
3716   global_client_name_done = False;
3717   global_client_addr_done = False;
3718 }
3719  
3720 /*******************************************************************
3721  return the DNS name of the client 
3722  ******************************************************************/
3723 char *client_name(int fd)
3724 {
3725         struct sockaddr sa;
3726         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3727         int     length = sizeof(sa);
3728         static pstring name_buf;
3729         struct hostent *hp;
3730         static int last_fd=-1;
3731         
3732         if (global_client_name_done && last_fd == fd) 
3733                 return name_buf;
3734         
3735         last_fd = fd;
3736         global_client_name_done = False;
3737         
3738         strcpy(name_buf,"UNKNOWN");
3739         
3740         if (fd == -1) {
3741                 return name_buf;
3742         }
3743         
3744         if (getpeername(fd, &sa, &length) < 0) {
3745                 DEBUG(0,("getpeername failed\n"));
3746                 return name_buf;
3747         }
3748         
3749         /* Look up the remote host name. */
3750         if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3751                                 sizeof(sockin->sin_addr),
3752                                 AF_INET)) == 0) {
3753                 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3754                 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3755         } else {
3756                 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3757                 if (!matchname(name_buf, sockin->sin_addr)) {
3758                         DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3759                         strcpy(name_buf,"UNKNOWN");
3760                 }
3761         }
3762         global_client_name_done = True;
3763         return name_buf;
3764 }
3765
3766 /*******************************************************************
3767  return the IP addr of the client as a string 
3768  ******************************************************************/
3769 char *client_addr(int fd)
3770 {
3771         struct sockaddr sa;
3772         struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3773         int     length = sizeof(sa);
3774         static fstring addr_buf;
3775         static int last_fd = -1;
3776
3777         if (global_client_addr_done && fd == last_fd) 
3778                 return addr_buf;
3779
3780         last_fd = fd;
3781         global_client_addr_done = False;
3782
3783         strcpy(addr_buf,"0.0.0.0");
3784
3785         if (fd == -1) {
3786                 return addr_buf;
3787         }
3788         
3789         if (getpeername(fd, &sa, &length) < 0) {
3790                 DEBUG(0,("getpeername failed\n"));
3791                 return addr_buf;
3792         }
3793         
3794         fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3795         
3796         global_client_addr_done = True;
3797         return addr_buf;
3798 }
3799
3800 /*******************************************************************
3801  Patch from jkf@soton.ac.uk
3802  Split Luke's automount_server into YP lookup and string splitter
3803  so can easily implement automount_path(). 
3804  As we may end up doing both, cache the last YP result. 
3805 *******************************************************************/
3806
3807 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3808 static char *automount_lookup(char *user_name)
3809 {
3810   static fstring last_key = "";
3811   static pstring last_value = "";
3812
3813   int nis_error;        /* returned by yp all functions */
3814   char *nis_result;     /* yp_match inits this */
3815   int nis_result_len;  /* and set this */
3816   char *nis_domain;     /* yp_get_default_domain inits this */
3817   char *nis_map = (char *)lp_nis_home_map_name();
3818
3819   if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3820   {
3821     DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3822     return last_value;
3823   }
3824
3825   DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3826
3827   if (!strcmp(user_name, last_key))
3828   {
3829     nis_result = last_value;
3830     nis_result_len = strlen(last_value);
3831     nis_error = 0;
3832   }
3833   else
3834   {
3835     if ((nis_error = yp_match(nis_domain, nis_map,
3836                               user_name, strlen(user_name),
3837                               &nis_result, &nis_result_len)) != 0)
3838     {
3839       DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
3840                yperr_string(nis_error), user_name, nis_map));
3841     }
3842     if (!nis_error && nis_result_len >= sizeof(pstring))
3843     {
3844       nis_result_len = sizeof(pstring)-1;
3845     }
3846     fstrcpy(last_key, user_name);
3847     strncpy(last_value, nis_result, nis_result_len);
3848     last_value[nis_result_len] = '\0';
3849   }
3850
3851   DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3852   return last_value;
3853 }
3854 #endif
3855
3856 /*******************************************************************
3857  Patch from jkf@soton.ac.uk
3858  This is Luke's original function with the NIS lookup code
3859  moved out to a separate function.
3860 *******************************************************************/
3861
3862 char *automount_server(char *user_name)
3863 {
3864         static pstring server_name;
3865         int home_server_len;
3866
3867         /* use the local machine name as the default */
3868         /* this will be the default if AUTOMOUNT is not used or fails */
3869         pstrcpy(server_name, local_machine);
3870
3871 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3872
3873         if (lp_nis_home_map())
3874         {
3875                 char *automount_value = automount_lookup(user_name);
3876                 home_server_len = strcspn(automount_value,":");
3877                 DEBUG(5, ("NIS lookup succeeded.  Home server length: %d\n",home_server_len));
3878                 if (home_server_len > sizeof(pstring))
3879                 {
3880                         home_server_len = sizeof(pstring);
3881                 }
3882                 strncpy(server_name, automount_value, home_server_len);
3883                 server_name[home_server_len] = '\0';
3884         }
3885 #endif
3886
3887         DEBUG(4,("Home server: %s\n", server_name));
3888
3889         return server_name;
3890 }
3891
3892 /*******************************************************************
3893  Patch from jkf@soton.ac.uk
3894  Added this to implement %p (NIS auto-map version of %H)
3895 *******************************************************************/
3896
3897 char *automount_path(char *user_name)
3898 {
3899         static pstring server_path;
3900         char *home_path_start;
3901
3902         /* use the passwd entry as the default */
3903         /* this will be the default if AUTOMOUNT is not used or fails */
3904         /* pstrcpy() copes with get_home_dir() returning NULL */
3905         pstrcpy(server_path, get_home_dir(user_name));
3906
3907 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3908
3909         if (lp_nis_home_map())
3910         {
3911                 char *automount_value = automount_lookup(user_name);
3912                 home_path_start = strchr(automount_value,':');
3913                 if (home_path_start != NULL)
3914                 {
3915                   DEBUG(5, ("NIS lookup succeeded.  Home path is: %s\n",
3916                         home_path_start?(home_path_start+1):""));
3917                   strcpy(server_path, home_path_start+1);
3918                 }
3919         }
3920 #endif
3921
3922         DEBUG(4,("Home server path: %s\n", server_path));
3923
3924         return server_path;
3925 }
3926
3927
3928 /*******************************************************************
3929 sub strings with useful parameters
3930 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3931 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3932 ********************************************************************/
3933 void standard_sub_basic(char *str)
3934 {
3935         char *s, *p;
3936         char pidstr[10];
3937         struct passwd *pass;
3938         char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3939
3940         for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3941         {
3942                 switch (*(p+1))
3943                 {
3944                         case 'G' :
3945                         {
3946                                 if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3947                                 {
3948                                         string_sub(p,"%G",gidtoname(pass->pw_gid));
3949                                 }
3950                                 else
3951                                 {
3952                                         p += 2;
3953                                 }
3954                                 break;
3955                         }
3956                         case 'N' : string_sub(p,"%N", automount_server(username)); break;
3957                         case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3958                         case 'L' : string_sub(p,"%L", local_machine); break;
3959                         case 'M' : string_sub(p,"%M", client_name(Client)); break;
3960                         case 'R' : string_sub(p,"%R", remote_proto); break;
3961                         case 'T' : string_sub(p,"%T", timestring()); break;
3962                         case 'U' : string_sub(p,"%U", username); break;
3963                         case 'a' : string_sub(p,"%a", remote_arch); break;
3964                         case 'd' :
3965                         {
3966                                 sprintf(pidstr,"%d",(int)getpid());
3967                                 string_sub(p,"%d", pidstr);
3968                                 break;
3969                         }
3970                         case 'h' : string_sub(p,"%h", myhostname); break;
3971                         case 'm' : string_sub(p,"%m", remote_machine); break;
3972                         case 'v' : string_sub(p,"%v", VERSION); break;
3973                         case '$' : /* Expand environment variables */
3974                         {
3975                           /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3976                           fstring envname;
3977                           char *envval;
3978                           char *q, *r;
3979                           int copylen;
3980  
3981                           if (*(p+2) != '(') { p+=2; break; }
3982                           if ((q = strchr(p,')')) == NULL)
3983                           {
3984                             DEBUG(0,("standard_sub_basic: Unterminated environment \
3985 variable [%s]\n", p));
3986                             p+=2; break;
3987                           }
3988  
3989                           r = p+3;
3990                           copylen = MIN((q-r),(sizeof(envname)-1));
3991                           strncpy(envname,r,copylen);
3992                           envname[copylen] = '\0';
3993                           if ((envval = getenv(envname)) == NULL)
3994                           {
3995                             DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3996                                      envname));
3997                             p+=2; break;
3998                           }
3999                           copylen = MIN((q+1-p),(sizeof(envname)-1));
4000                           strncpy(envname,p,copylen);
4001                           envname[copylen] = '\0';
4002                           string_sub(p,envname,envval);
4003                           break;
4004                         }
4005                         case '\0': p++; break; /* don't run off end if last character is % */
4006                         default  : p+=2; break;
4007                 }
4008         }
4009         return;
4010 }
4011
4012 /*******************************************************************
4013 are two IPs on the same subnet?
4014 ********************************************************************/
4015 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4016 {
4017   uint32 net1,net2,nmask;
4018
4019   nmask = ntohl(mask.s_addr);
4020   net1  = ntohl(ip1.s_addr);
4021   net2  = ntohl(ip2.s_addr);
4022             
4023   return((net1 & nmask) == (net2 & nmask));
4024 }
4025
4026
4027 /*******************************************************************
4028 write a string in unicoode format
4029 ********************************************************************/
4030 int PutUniCode(char *dst,char *src)
4031 {
4032   int ret = 0;
4033   while (*src) {
4034     dst[ret++] = src[0];
4035     dst[ret++] = 0;    
4036     src++;
4037   }
4038   dst[ret++]=0;
4039   dst[ret++]=0;
4040   return(ret);
4041 }
4042
4043 /****************************************************************************
4044 a wrapper for gethostbyname() that tries with all lower and all upper case 
4045 if the initial name fails
4046 ****************************************************************************/
4047 struct hostent *Get_Hostbyname(char *name)
4048 {
4049   char *name2 = strdup(name);
4050   struct hostent *ret;
4051
4052   if (!name2)
4053     {
4054       DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4055       exit(0);
4056     }
4057
4058    
4059   /* 
4060    * This next test is redundent and causes some systems (with
4061    * broken isalnum() calls) problems.
4062    * JRA.
4063    */
4064
4065 #if 0
4066   if (!isalnum(*name2))
4067     {
4068       free(name2);
4069       return(NULL);
4070     }
4071 #endif /* 0 */
4072
4073   ret = sys_gethostbyname(name2);
4074   if (ret != NULL)
4075     {
4076       free(name2);
4077       return(ret);
4078     }
4079
4080   /* try with all lowercase */
4081   strlower(name2);
4082   ret = sys_gethostbyname(name2);
4083   if (ret != NULL)
4084     {
4085       free(name2);
4086       return(ret);
4087     }
4088
4089   /* try with all uppercase */
4090   strupper(name2);
4091   ret = sys_gethostbyname(name2);
4092   if (ret != NULL)
4093     {
4094       free(name2);
4095       return(ret);
4096     }
4097   
4098   /* nothing works :-( */
4099   free(name2);
4100   return(NULL);
4101 }
4102
4103
4104 /****************************************************************************
4105 check if a process exists. Does this work on all unixes?
4106 ****************************************************************************/
4107 BOOL process_exists(int pid)
4108 {
4109         return(kill(pid,0) == 0 || errno != ESRCH);
4110 }
4111
4112
4113 /*******************************************************************
4114 turn a uid into a user name
4115 ********************************************************************/
4116 char *uidtoname(int uid)
4117 {
4118   static char name[40];
4119   struct passwd *pass = getpwuid(uid);
4120   if (pass) return(pass->pw_name);
4121   sprintf(name,"%d",uid);
4122   return(name);
4123 }
4124
4125 /*******************************************************************
4126 turn a gid into a group name
4127 ********************************************************************/
4128 char *gidtoname(int gid)
4129 {
4130   static char name[40];
4131   struct group *grp = getgrgid(gid);
4132   if (grp) return(grp->gr_name);
4133   sprintf(name,"%d",gid);
4134   return(name);
4135 }
4136
4137 /*******************************************************************
4138 block sigs
4139 ********************************************************************/
4140 void BlockSignals(BOOL block,int signum)
4141 {
4142 #ifdef USE_SIGBLOCK
4143   int block_mask = sigmask(signum);
4144   static int oldmask = 0;
4145   if (block) 
4146     oldmask = sigblock(block_mask);
4147   else
4148     sigsetmask(oldmask);
4149 #elif defined(USE_SIGPROCMASK)
4150   sigset_t set;
4151   sigemptyset(&set);
4152   sigaddset(&set,signum);
4153   sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4154 #endif
4155 }
4156
4157 #if AJT
4158 /*******************************************************************
4159 my own panic function - not suitable for general use
4160 ********************************************************************/
4161 void ajt_panic(void)
4162 {
4163   system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4164 }
4165 #endif
4166
4167 #ifdef USE_DIRECT
4168 #define DIRECT direct
4169 #else
4170 #define DIRECT dirent
4171 #endif
4172
4173 /*******************************************************************
4174 a readdir wrapper which just returns the file name
4175 also return the inode number if requested
4176 ********************************************************************/
4177 char *readdirname(void *p)
4178 {
4179   struct DIRECT *ptr;
4180   char *dname;
4181
4182   if (!p) return(NULL);
4183   
4184   ptr = (struct DIRECT *)readdir(p);
4185   if (!ptr) return(NULL);
4186
4187   dname = ptr->d_name;
4188
4189 #ifdef NEXT2
4190   if (telldir(p) < 0) return(NULL);
4191 #endif
4192
4193 #ifdef SUNOS5
4194   /* this handles a broken compiler setup, causing a mixture
4195    of BSD and SYSV headers and libraries */
4196   {
4197     static BOOL broken_readdir = False;
4198     if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4199       {
4200         DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4201         broken_readdir = True;
4202       }
4203     if (broken_readdir)
4204       dname = dname - 2;
4205   }
4206 #endif
4207
4208   {
4209     static pstring buf;
4210     pstrcpy(buf, dname);
4211     unix_to_dos(buf, True);
4212     dname = buf;
4213   }
4214
4215   return(dname);
4216 }
4217
4218 /*******************************************************************
4219  Utility function used to decide if the last component 
4220  of a path matches a (possibly wildcarded) entry in a namelist.
4221 ********************************************************************/
4222
4223 BOOL is_in_path(char *name, name_compare_entry *namelist)
4224 {
4225   pstring last_component;
4226   char *p;
4227
4228   DEBUG(8, ("is_in_path: %s\n", name));
4229
4230   /* if we have no list it's obviously not in the path */
4231   if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) 
4232   {
4233     DEBUG(8,("is_in_path: no name list.\n"));
4234     return False;
4235   }
4236
4237   /* Get the last component of the unix name. */
4238   p = strrchr(name, '/');
4239   strncpy(last_component, p ? p : name, sizeof(last_component)-1);
4240   last_component[sizeof(last_component)-1] = '\0'; 
4241
4242   for(; namelist->name != NULL; namelist++)
4243   {
4244     if(namelist->is_wild)
4245     {
4246       /* look for a wildcard match. */
4247       if (mask_match(last_component, namelist->name, case_sensitive, False))
4248       {
4249          DEBUG(8,("is_in_path: mask match succeeded\n"));
4250          return True;
4251       }
4252     }
4253     else
4254     {
4255       if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4256        (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4257         {
4258          DEBUG(8,("is_in_path: match succeeded\n"));
4259          return True;
4260         }
4261     }
4262   }
4263   DEBUG(8,("is_in_path: match not found\n"));
4264  
4265   return False;
4266 }
4267
4268 /*******************************************************************
4269  Strip a '/' separated list into an array of 
4270  name_compare_enties structures suitable for 
4271  passing to is_in_path(). We do this for
4272  speed so we can pre-parse all the names in the list 
4273  and don't do it for each call to is_in_path().
4274  namelist is modified here and is assumed to be 
4275  a copy owned by the caller.
4276  We also check if the entry contains a wildcard to
4277  remove a potentially expensive call to mask_match
4278  if possible.
4279 ********************************************************************/
4280  
4281 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4282 {
4283   char *name_end;
4284   char *nameptr = namelist;
4285   int num_entries = 0;
4286   int i;
4287
4288   (*ppname_array) = NULL;
4289
4290   if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
4291     return;
4292
4293   /* We need to make two passes over the string. The
4294      first to count the number of elements, the second
4295      to split it.
4296    */
4297   while(*nameptr) 
4298     {
4299       if ( *nameptr == '/' ) 
4300         {
4301           /* cope with multiple (useless) /s) */
4302           nameptr++;
4303           continue;
4304         }
4305       /* find the next / */
4306       name_end = strchr(nameptr, '/');
4307
4308       /* oops - the last check for a / didn't find one. */
4309       if (name_end == NULL)
4310         break;
4311
4312       /* next segment please */
4313       nameptr = name_end + 1;
4314       num_entries++;
4315     }
4316
4317   if(num_entries == 0)
4318     return;
4319
4320   if(( (*ppname_array) = (name_compare_entry *)malloc( 
4321            (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4322         {
4323     DEBUG(0,("set_namearray: malloc fail\n"));
4324     return;
4325         }
4326
4327   /* Now copy out the names */
4328   nameptr = namelist;
4329   i = 0;
4330   while(*nameptr)
4331              {
4332       if ( *nameptr == '/' ) 
4333       {
4334           /* cope with multiple (useless) /s) */
4335           nameptr++;
4336           continue;
4337       }
4338       /* find the next / */
4339       if ((name_end = strchr(nameptr, '/')) != NULL) 
4340       {
4341           *name_end = 0;
4342          }
4343
4344       /* oops - the last check for a / didn't find one. */
4345       if(name_end == NULL) 
4346         break;
4347
4348       (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4349                                 (strchr( nameptr, '*')!=NULL));
4350       if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4351       {
4352         DEBUG(0,("set_namearray: malloc fail (1)\n"));
4353         return;
4354       }
4355
4356       /* next segment please */
4357       nameptr = name_end + 1;
4358       i++;
4359     }
4360   
4361   (*ppname_array)[i].name = NULL;
4362
4363   return;
4364 }
4365
4366 /****************************************************************************
4367 routine to free a namearray.
4368 ****************************************************************************/
4369
4370 void free_namearray(name_compare_entry *name_array)
4371 {
4372   if(name_array == 0)
4373     return;
4374
4375   if(name_array->name != NULL)
4376     free(name_array->name);
4377
4378   free((char *)name_array);
4379 }
4380
4381 /****************************************************************************
4382 routine to do file locking
4383 ****************************************************************************/
4384 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4385 {
4386 #if HAVE_FCNTL_LOCK
4387   struct flock lock;
4388   int ret;
4389
4390 #if 1
4391   uint32 mask = 0xC0000000;
4392
4393   /* make sure the count is reasonable, we might kill the lockd otherwise */
4394   count &= ~mask;
4395
4396   /* the offset is often strange - remove 2 of its bits if either of
4397      the top two bits are set. Shift the top ones by two bits. This
4398      still allows OLE2 apps to operate, but should stop lockd from
4399      dieing */
4400   if ((offset & mask) != 0)
4401     offset = (offset & ~mask) | ((offset & mask) >> 2);
4402 #else
4403   uint32 mask = ((unsigned)1<<31);
4404
4405   /* interpret negative counts as large numbers */
4406   if (count < 0)
4407     count &= ~mask;
4408
4409   /* no negative offsets */
4410   offset &= ~mask;
4411
4412   /* count + offset must be in range */
4413   while ((offset < 0 || (offset + count < 0)) && mask)
4414     {
4415       offset &= ~mask;
4416       mask = mask >> 1;
4417     }
4418 #endif
4419
4420
4421   DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4422
4423   lock.l_type = type;
4424   lock.l_whence = SEEK_SET;
4425   lock.l_start = (int)offset;
4426   lock.l_len = (int)count;
4427   lock.l_pid = 0;
4428
4429   errno = 0;
4430
4431   ret = fcntl(fd,op,&lock);
4432
4433   if (errno != 0)
4434     DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4435
4436   /* a lock query */
4437   if (op == F_GETLK)
4438     {
4439       if ((ret != -1) &&
4440           (lock.l_type != F_UNLCK) && 
4441           (lock.l_pid != 0) && 
4442           (lock.l_pid != getpid()))
4443         {
4444           DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4445           return(True);
4446         }
4447
4448       /* it must be not locked or locked by me */
4449       return(False);
4450     }
4451
4452   /* a lock set or unset */
4453   if (ret == -1)
4454     {
4455       DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4456                offset,count,op,type,strerror(errno)));
4457
4458       /* perhaps it doesn't support this sort of locking?? */
4459       if (errno == EINVAL)
4460         {
4461           DEBUG(3,("locking not supported? returning True\n"));
4462           return(True);
4463         }
4464
4465       return(False);
4466     }
4467
4468   /* everything went OK */
4469   DEBUG(8,("Lock call successful\n"));
4470
4471   return(True);
4472 #else
4473   return(False);
4474 #endif
4475 }
4476
4477 /*******************************************************************
4478 lock a file - returning a open file descriptor or -1 on failure
4479 The timeout is in seconds. 0 means no timeout
4480 ********************************************************************/
4481 int file_lock(char *name,int timeout)
4482 {  
4483   int fd = open(name,O_RDWR|O_CREAT,0666);
4484   time_t t=0;
4485   if (fd < 0) return(-1);
4486
4487 #if HAVE_FCNTL_LOCK
4488   if (timeout) t = time(NULL);
4489   while (!timeout || (time(NULL)-t < timeout)) {
4490     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);    
4491     msleep(LOCK_RETRY_TIMEOUT);
4492   }
4493   return(-1);
4494 #else
4495   return(fd);
4496 #endif
4497 }
4498
4499 /*******************************************************************
4500 unlock a file locked by file_lock
4501 ********************************************************************/
4502 void file_unlock(int fd)
4503 {
4504   if (fd<0) return;
4505 #if HAVE_FCNTL_LOCK
4506   fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4507 #endif
4508   close(fd);
4509 }
4510
4511 /*******************************************************************
4512 is the name specified one of my netbios names
4513 returns true is it is equal, false otherwise
4514 ********************************************************************/
4515 BOOL is_myname(char *s)
4516 {
4517   int n;
4518   BOOL ret = False;
4519
4520   for (n=0; my_netbios_names[n]; n++) {
4521     if (strequal(my_netbios_names[n], s))
4522       ret=True;
4523   }
4524   DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4525   return(ret);
4526 }
4527
4528 /*******************************************************************
4529 set the horrid remote_arch string based on an enum.
4530 ********************************************************************/
4531 void set_remote_arch(enum remote_arch_types type)
4532 {
4533   ra_type = type;
4534   switch( type )
4535   {
4536   case RA_WFWG:
4537     strcpy(remote_arch, "WfWg");
4538     return;
4539   case RA_OS2:
4540     strcpy(remote_arch, "OS2");
4541     return;
4542   case RA_WIN95:
4543     strcpy(remote_arch, "Win95");
4544     return;
4545   case RA_WINNT:
4546     strcpy(remote_arch, "WinNT");
4547     return;
4548   case RA_SAMBA:
4549     strcpy(remote_arch,"Samba");
4550     return;
4551   default:
4552     ra_type = RA_UNKNOWN;
4553     strcpy(remote_arch, "UNKNOWN");
4554     break;
4555   }
4556 }
4557
4558 /*******************************************************************
4559  Get the remote_arch type.
4560 ********************************************************************/
4561 enum remote_arch_types get_remote_arch()
4562 {
4563   return ra_type;
4564 }
4565
4566
4567 /*******************************************************************
4568 skip past some unicode strings in a buffer
4569 ********************************************************************/
4570 char *skip_unicode_string(char *buf,int n)
4571 {
4572   while (n--)
4573   {
4574     while (*buf)
4575       buf += 2;
4576     buf += 2;
4577   }
4578   return(buf);
4579 }
4580
4581 /*******************************************************************
4582 Return a ascii version of a unicode string
4583 Hack alert: uses fixed buffer(s) and only handles ascii strings
4584 ********************************************************************/
4585 #define MAXUNI 1024
4586 char *unistrn2(uint16 *buf, int len)
4587 {
4588         static char lbufs[8][MAXUNI];
4589         static int nexti;
4590         char *lbuf = lbufs[nexti];
4591         char *p;
4592
4593         nexti = (nexti+1)%8;
4594
4595         DEBUG(10, ("unistrn2: "));
4596
4597         for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4598         {
4599                 DEBUG(10, ("%4x ", *buf));
4600                 *p = *buf;
4601         }
4602
4603         DEBUG(10,("\n"));
4604
4605         *p = 0;
4606         return lbuf;
4607 }
4608
4609 /*******************************************************************
4610 Return a ascii version of a unicode string
4611 Hack alert: uses fixed buffer(s) and only handles ascii strings
4612 ********************************************************************/
4613 #define MAXUNI 1024
4614 char *unistr2(uint16 *buf)
4615 {
4616         static char lbufs[8][MAXUNI];
4617         static int nexti;
4618         char *lbuf = lbufs[nexti];
4619         char *p;
4620
4621         nexti = (nexti+1)%8;
4622
4623         DEBUG(10, ("unistr2: "));
4624
4625         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4626         {
4627                 DEBUG(10, ("%4x ", *buf));
4628                 *p = *buf;
4629         }
4630
4631         DEBUG(10,("\n"));
4632
4633         *p = 0;
4634         return lbuf;
4635 }
4636
4637 /*******************************************************************
4638 create a null-terminated unicode string from a null-terminated ascii string.
4639 return number of unicode chars copied, excluding the null character.
4640
4641 only handles ascii strings
4642 ********************************************************************/
4643 #define MAXUNI 1024
4644 int struni2(uint16 *p, char *buf)
4645 {
4646         int len = 0;
4647
4648         if (p == NULL) return 0;
4649
4650         DEBUG(10, ("struni2: "));
4651
4652         if (buf != NULL)
4653         {
4654                 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4655                 {
4656                         DEBUG(10, ("%2x ", *buf));
4657                         *p = *buf;
4658                 }
4659
4660                 DEBUG(10,("\n"));
4661         }
4662
4663         *p = 0;
4664
4665         return len;
4666 }
4667
4668 /*******************************************************************
4669 Return a ascii version of a unicode string
4670 Hack alert: uses fixed buffer(s) and only handles ascii strings
4671 ********************************************************************/
4672 #define MAXUNI 1024
4673 char *unistr(char *buf)
4674 {
4675         static char lbufs[8][MAXUNI];
4676         static int nexti;
4677         char *lbuf = lbufs[nexti];
4678         char *p;
4679
4680         nexti = (nexti+1)%8;
4681
4682         for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4683         {
4684                 *p = *buf;
4685         }
4686         *p = 0;
4687         return lbuf;
4688 }
4689
4690 /*******************************************************************
4691 strncpy for unicode strings
4692 ********************************************************************/
4693 int unistrncpy(char *dst, char *src, int len)
4694 {
4695         int num_wchars = 0;
4696
4697         while (*src && len > 0)
4698         {
4699                 *dst++ = *src++;
4700                 *dst++ = *src++;
4701                 len--;
4702                 num_wchars++;
4703         }
4704         *dst++ = 0;
4705         *dst++ = 0;
4706
4707         return num_wchars;
4708 }
4709
4710
4711 /*******************************************************************
4712 strcpy for unicode strings.  returns length (in num of wide chars)
4713 ********************************************************************/
4714 int unistrcpy(char *dst, char *src)
4715 {
4716         int num_wchars = 0;
4717
4718         while (*src)
4719         {
4720                 *dst++ = *src++;
4721                 *dst++ = *src++;
4722                 num_wchars++;
4723         }
4724         *dst++ = 0;
4725         *dst++ = 0;
4726
4727         return num_wchars;
4728 }
4729
4730
4731 /*******************************************************************
4732 safe string copy into a fstring
4733 ********************************************************************/
4734 void fstrcpy(char *dest, char *src)
4735 {
4736     int maxlength = sizeof(fstring) - 1;
4737     if (!dest) {
4738         DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4739         return;
4740     }
4741
4742     if (!src) {
4743         *dest = 0;
4744         return;
4745     }  
4746       
4747     while (maxlength-- && *src)
4748         *dest++ = *src++;
4749     *dest = 0;
4750     if (*src) {
4751         DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4752              strlen(src)));
4753     }    
4754 }   
4755
4756 /*******************************************************************
4757 safe string copy into a pstring
4758 ********************************************************************/
4759 void pstrcpy(char *dest, char *src)
4760 {
4761     int maxlength = sizeof(pstring) - 1;
4762     if (!dest) {
4763         DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4764         return;
4765     }
4766    
4767     if (!src) {
4768         *dest = 0;
4769         return;
4770     }
4771    
4772     while (maxlength-- && *src)
4773         *dest++ = *src++;
4774     *dest = 0;
4775     if (*src) {
4776         DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4777              strlen(src)));
4778     }
4779 }  
4780
4781
4782 /*******************************************************************
4783 align a pointer to a multiple of 4 bytes
4784 ********************************************************************/
4785 char *align4(char *q, char *base)
4786 {
4787         if ((q - base) & 3)
4788         {
4789                 q += 4 - ((q - base) & 3);
4790         }
4791         return q;
4792 }
4793
4794 /*******************************************************************
4795 align a pointer to a multiple of 2 bytes
4796 ********************************************************************/
4797 char *align2(char *q, char *base)
4798 {
4799         if ((q - base) & 1)
4800         {
4801                 q++;
4802         }
4803         return q;
4804 }
4805
4806 /*******************************************************************
4807 align a pointer to a multiple of align_offset bytes.  looks like it
4808 will work for offsets of 0, 2 and 4...
4809 ********************************************************************/
4810 char *align_offset(char *q, char *base, int align_offset_len)
4811 {
4812         int mod = ((q - base) & (align_offset_len-1));
4813         if (align_offset_len != 0 && mod != 0)
4814         {
4815                 q += align_offset_len - mod;
4816         }
4817         return q;
4818 }
4819
4820 void print_asc(int level, unsigned char *buf,int len)
4821 {
4822         int i;
4823         for (i=0;i<len;i++)
4824                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4825 }
4826
4827 void dump_data(int level,char *buf1,int len)
4828 {
4829   unsigned char *buf = (unsigned char *)buf1;
4830   int i=0;
4831   if (len<=0) return;
4832
4833   DEBUG(level,("[%03X] ",i));
4834   for (i=0;i<len;) {
4835     DEBUG(level,("%02X ",(int)buf[i]));
4836     i++;
4837     if (i%8 == 0) DEBUG(level,(" "));
4838     if (i%16 == 0) {      
4839       print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4840       print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4841       if (i<len) DEBUG(level,("[%03X] ",i));
4842     }
4843   }
4844   if (i%16) {
4845     int n;
4846
4847     n = 16 - (i%16);
4848     DEBUG(level,(" "));
4849     if (n>8) DEBUG(level,(" "));
4850     while (n--) DEBUG(level,("   "));
4851
4852     n = MIN(8,i%16);
4853     print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4854     n = (i%16) - n;
4855     if (n>0) print_asc(level,&buf[i-n],n); 
4856     DEBUG(level,("\n"));    
4857   }
4858 }
4859
4860 char *tab_depth(int depth)
4861 {
4862         static pstring spaces;
4863         memset(spaces, ' ', depth * 4);
4864         spaces[depth * 4] = 0;
4865         return spaces;
4866 }
4867
4868 /*****************************************************************
4869  Convert a domain SID to an ascii string. (non-reentrant).
4870 *****************************************************************/
4871
4872 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4873 char *dom_sid_to_string(DOM_SID *sid)
4874 {
4875   static pstring sidstr;
4876   char subauth[16];
4877   int i;
4878   uint32 ia = (sid->id_auth[5]) +
4879               (sid->id_auth[4] << 8 ) +
4880               (sid->id_auth[3] << 16) +
4881               (sid->id_auth[2] << 24);
4882
4883   sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
4884
4885   for (i = 0; i < sid->num_auths; i++)
4886   {
4887     sprintf(subauth, "-%d", sid->sub_auths[i]);
4888     strcat(sidstr, subauth);
4889   }
4890
4891   DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));
4892   return sidstr;
4893 }