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