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