r21250: Partial fix for BUG 4093: Make %a expand to "Vista"
[samba.git] / source / lib / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) Simo Sorce 2001
7    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8    Copyright (C) James Peach 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 2 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 extern fstring local_machine;
28 extern char *global_clobber_region_function;
29 extern unsigned int global_clobber_region_line;
30 extern fstring remote_arch;
31
32 /* Max allowable allococation - 256mb - 0x10000000 */
33 #define MAX_ALLOC_SIZE (1024*1024*256)
34
35 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
36 #ifdef WITH_NISPLUS_HOME
37 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
38 /*
39  * The following lines are needed due to buggy include files
40  * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
41  * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
42  * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
43  * an enum in /usr/include/rpcsvc/nis.h.
44  */
45
46 #if defined(GROUP)
47 #undef GROUP
48 #endif
49
50 #if defined(GROUP_OBJ)
51 #undef GROUP_OBJ
52 #endif
53
54 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
55
56 #include <rpcsvc/nis.h>
57
58 #endif /* WITH_NISPLUS_HOME */
59 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
60
61 enum protocol_types Protocol = PROTOCOL_COREPLUS;
62
63 /* a default finfo structure to ensure all fields are sensible */
64 file_info def_finfo;
65
66 /* this is used by the chaining code */
67 int chain_size = 0;
68
69 int trans_num = 0;
70
71 static enum remote_arch_types ra_type = RA_UNKNOWN;
72 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;   
73
74 /***********************************************************************
75  Definitions for all names.
76 ***********************************************************************/
77
78 static char *smb_myname;
79 static char *smb_myworkgroup;
80 static char *smb_scope;
81 static int smb_num_netbios_names;
82 static char **smb_my_netbios_names;
83
84 /***********************************************************************
85  Allocate and set myname. Ensure upper case.
86 ***********************************************************************/
87
88 BOOL set_global_myname(const char *myname)
89 {
90         SAFE_FREE(smb_myname);
91         smb_myname = SMB_STRDUP(myname);
92         if (!smb_myname)
93                 return False;
94         strupper_m(smb_myname);
95         return True;
96 }
97
98 const char *global_myname(void)
99 {
100         return smb_myname;
101 }
102
103 /***********************************************************************
104  Allocate and set myworkgroup. Ensure upper case.
105 ***********************************************************************/
106
107 BOOL set_global_myworkgroup(const char *myworkgroup)
108 {
109         SAFE_FREE(smb_myworkgroup);
110         smb_myworkgroup = SMB_STRDUP(myworkgroup);
111         if (!smb_myworkgroup)
112                 return False;
113         strupper_m(smb_myworkgroup);
114         return True;
115 }
116
117 const char *lp_workgroup(void)
118 {
119         return smb_myworkgroup;
120 }
121
122 /***********************************************************************
123  Allocate and set scope. Ensure upper case.
124 ***********************************************************************/
125
126 BOOL set_global_scope(const char *scope)
127 {
128         SAFE_FREE(smb_scope);
129         smb_scope = SMB_STRDUP(scope);
130         if (!smb_scope)
131                 return False;
132         strupper_m(smb_scope);
133         return True;
134 }
135
136 /*********************************************************************
137  Ensure scope is never null string.
138 *********************************************************************/
139
140 const char *global_scope(void)
141 {
142         if (!smb_scope)
143                 set_global_scope("");
144         return smb_scope;
145 }
146
147 static void free_netbios_names_array(void)
148 {
149         int i;
150
151         for (i = 0; i < smb_num_netbios_names; i++)
152                 SAFE_FREE(smb_my_netbios_names[i]);
153
154         SAFE_FREE(smb_my_netbios_names);
155         smb_num_netbios_names = 0;
156 }
157
158 static BOOL allocate_my_netbios_names_array(size_t number)
159 {
160         free_netbios_names_array();
161
162         smb_num_netbios_names = number + 1;
163         smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
164
165         if (!smb_my_netbios_names)
166                 return False;
167
168         memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
169         return True;
170 }
171
172 static BOOL set_my_netbios_names(const char *name, int i)
173 {
174         SAFE_FREE(smb_my_netbios_names[i]);
175
176         smb_my_netbios_names[i] = SMB_STRDUP(name);
177         if (!smb_my_netbios_names[i])
178                 return False;
179         strupper_m(smb_my_netbios_names[i]);
180         return True;
181 }
182
183 /***********************************************************************
184  Free memory allocated to global objects
185 ***********************************************************************/
186
187 void gfree_names(void)
188 {
189         SAFE_FREE( smb_myname );
190         SAFE_FREE( smb_myworkgroup );
191         SAFE_FREE( smb_scope );
192         free_netbios_names_array();
193 }
194
195 void gfree_all( void )
196 {
197         gfree_names();  
198         gfree_loadparm();
199         gfree_case_tables();
200         gfree_debugsyms();
201         gfree_charcnv();
202         gfree_messages();
203
204         /* release the talloc null_context memory last */
205         talloc_disable_null_tracking();
206 }
207
208 const char *my_netbios_names(int i)
209 {
210         return smb_my_netbios_names[i];
211 }
212
213 BOOL set_netbios_aliases(const char **str_array)
214 {
215         size_t namecount;
216
217         /* Work out the max number of netbios aliases that we have */
218         for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
219                 ;
220
221         if ( global_myname() && *global_myname())
222                 namecount++;
223
224         /* Allocate space for the netbios aliases */
225         if (!allocate_my_netbios_names_array(namecount))
226                 return False;
227
228         /* Use the global_myname string first */
229         namecount=0;
230         if ( global_myname() && *global_myname()) {
231                 set_my_netbios_names( global_myname(), namecount );
232                 namecount++;
233         }
234
235         if (str_array) {
236                 size_t i;
237                 for ( i = 0; str_array[i] != NULL; i++) {
238                         size_t n;
239                         BOOL duplicate = False;
240
241                         /* Look for duplicates */
242                         for( n=0; n<namecount; n++ ) {
243                                 if( strequal( str_array[i], my_netbios_names(n) ) ) {
244                                         duplicate = True;
245                                         break;
246                                 }
247                         }
248                         if (!duplicate) {
249                                 if (!set_my_netbios_names(str_array[i], namecount))
250                                         return False;
251                                 namecount++;
252                         }
253                 }
254         }
255         return True;
256 }
257
258 /****************************************************************************
259   Common name initialization code.
260 ****************************************************************************/
261
262 BOOL init_names(void)
263 {
264         char *p;
265         int n;
266
267         if (global_myname() == NULL || *global_myname() == '\0') {
268                 if (!set_global_myname(myhostname())) {
269                         DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
270                         return False;
271                 }
272         }
273
274         if (!set_netbios_aliases(lp_netbios_aliases())) {
275                 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
276                 return False;
277         }                       
278
279         fstrcpy( local_machine, global_myname() );
280         trim_char( local_machine, ' ', ' ' );
281         p = strchr( local_machine, ' ' );
282         if (p)
283                 *p = 0;
284         strlower_m( local_machine );
285
286         DEBUG( 5, ("Netbios name list:-\n") );
287         for( n=0; my_netbios_names(n); n++ )
288                 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names(n) ) );
289
290         return( True );
291 }
292
293 /**************************************************************************n
294  Find a suitable temporary directory. The result should be copied immediately
295  as it may be overwritten by a subsequent call.
296 ****************************************************************************/
297
298 const char *tmpdir(void)
299 {
300         char *p;
301         if ((p = getenv("TMPDIR")))
302                 return p;
303         return "/tmp";
304 }
305
306 /****************************************************************************
307  Add a gid to an array of gids if it's not already there.
308 ****************************************************************************/
309
310 BOOL add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
311                              gid_t **gids, size_t *num_gids)
312 {
313         int i;
314
315         if ((*num_gids != 0) && (*gids == NULL)) {
316                 /*
317                  * A former call to this routine has failed to allocate memory
318                  */
319                 return False;
320         }
321
322         for (i=0; i<*num_gids; i++) {
323                 if ((*gids)[i] == gid) {
324                         return True;
325                 }
326         }
327
328         *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
329         if (*gids == NULL) {
330                 *num_gids = 0;
331                 return False;
332         }
333
334         (*gids)[*num_gids] = gid;
335         *num_gids += 1;
336         return True;
337 }
338
339 /****************************************************************************
340  Like atoi but gets the value up to the separator character.
341 ****************************************************************************/
342
343 static const char *Atoic(const char *p, int *n, const char *c)
344 {
345         if (!isdigit((int)*p)) {
346                 DEBUG(5, ("Atoic: malformed number\n"));
347                 return NULL;
348         }
349
350         (*n) = atoi(p);
351
352         while ((*p) && isdigit((int)*p))
353                 p++;
354
355         if (strchr_m(c, *p) == NULL) {
356                 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
357                 return NULL;
358         }
359
360         return p;
361 }
362
363 /*************************************************************************
364  Reads a list of numbers.
365  *************************************************************************/
366
367 const char *get_numlist(const char *p, uint32 **num, int *count)
368 {
369         int val;
370
371         if (num == NULL || count == NULL)
372                 return NULL;
373
374         (*count) = 0;
375         (*num  ) = NULL;
376
377         while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
378                 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
379                 if (!(*num)) {
380                         return NULL;
381                 }
382                 (*num)[(*count)] = val;
383                 (*count)++;
384                 p++;
385         }
386
387         return p;
388 }
389
390 /*******************************************************************
391  Check if a file exists - call vfs_file_exist for samba files.
392 ********************************************************************/
393
394 BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
395 {
396         SMB_STRUCT_STAT st;
397         if (!sbuf)
398                 sbuf = &st;
399   
400         if (sys_stat(fname,sbuf) != 0) 
401                 return(False);
402
403         return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
404 }
405
406 /*******************************************************************
407  Check a files mod time.
408 ********************************************************************/
409
410 time_t file_modtime(const char *fname)
411 {
412         SMB_STRUCT_STAT st;
413   
414         if (sys_stat(fname,&st) != 0) 
415                 return(0);
416
417         return(st.st_mtime);
418 }
419
420 /*******************************************************************
421  Check if a directory exists.
422 ********************************************************************/
423
424 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
425 {
426         SMB_STRUCT_STAT st2;
427         BOOL ret;
428
429         if (!st)
430                 st = &st2;
431
432         if (sys_stat(dname,st) != 0) 
433                 return(False);
434
435         ret = S_ISDIR(st->st_mode);
436         if(!ret)
437                 errno = ENOTDIR;
438         return ret;
439 }
440
441 /*******************************************************************
442  Returns the size in bytes of the named file.
443 ********************************************************************/
444
445 SMB_OFF_T get_file_size(char *file_name)
446 {
447         SMB_STRUCT_STAT buf;
448         buf.st_size = 0;
449         if(sys_stat(file_name,&buf) != 0)
450                 return (SMB_OFF_T)-1;
451         return(buf.st_size);
452 }
453
454 /*******************************************************************
455  Return a string representing an attribute for a file.
456 ********************************************************************/
457
458 char *attrib_string(uint16 mode)
459 {
460         static fstring attrstr;
461
462         attrstr[0] = 0;
463
464         if (mode & aVOLID) fstrcat(attrstr,"V");
465         if (mode & aDIR) fstrcat(attrstr,"D");
466         if (mode & aARCH) fstrcat(attrstr,"A");
467         if (mode & aHIDDEN) fstrcat(attrstr,"H");
468         if (mode & aSYSTEM) fstrcat(attrstr,"S");
469         if (mode & aRONLY) fstrcat(attrstr,"R");          
470
471         return(attrstr);
472 }
473
474 /*******************************************************************
475  Show a smb message structure.
476 ********************************************************************/
477
478 void show_msg(char *buf)
479 {
480         int i;
481         int bcc=0;
482
483         if (!DEBUGLVL(5))
484                 return;
485         
486         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
487                         smb_len(buf),
488                         (int)CVAL(buf,smb_com),
489                         (int)CVAL(buf,smb_rcls),
490                         (int)CVAL(buf,smb_reh),
491                         (int)SVAL(buf,smb_err),
492                         (int)CVAL(buf,smb_flg),
493                         (int)SVAL(buf,smb_flg2)));
494         DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
495                         (int)SVAL(buf,smb_tid),
496                         (int)SVAL(buf,smb_pid),
497                         (int)SVAL(buf,smb_uid),
498                         (int)SVAL(buf,smb_mid)));
499         DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
500
501         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
502                 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
503                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
504         
505         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
506
507         DEBUGADD(5,("smb_bcc=%d\n",bcc));
508
509         if (DEBUGLEVEL < 10)
510                 return;
511
512         if (DEBUGLEVEL < 50)
513                 bcc = MIN(bcc, 512);
514
515         dump_data(10, smb_buf(buf), bcc);       
516 }
517
518 /*******************************************************************
519  Set the length and marker of an smb packet.
520 ********************************************************************/
521
522 void smb_setlen(char *buf,int len)
523 {
524         _smb_setlen(buf,len);
525
526         SCVAL(buf,4,0xFF);
527         SCVAL(buf,5,'S');
528         SCVAL(buf,6,'M');
529         SCVAL(buf,7,'B');
530 }
531
532 /*******************************************************************
533  Setup the word count and byte count for a smb message.
534 ********************************************************************/
535
536 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
537 {
538         if (zero && (num_words || num_bytes)) {
539                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
540         }
541         SCVAL(buf,smb_wct,num_words);
542         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
543         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
544         return (smb_size + num_words*2 + num_bytes);
545 }
546
547 /*******************************************************************
548  Setup only the byte count for a smb message.
549 ********************************************************************/
550
551 int set_message_bcc(char *buf,int num_bytes)
552 {
553         int num_words = CVAL(buf,smb_wct);
554         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
555         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
556         return (smb_size + num_words*2 + num_bytes);
557 }
558
559 /*******************************************************************
560  Setup only the byte count for a smb message, using the end of the
561  message as a marker.
562 ********************************************************************/
563
564 int set_message_end(void *outbuf,void *end_ptr)
565 {
566         return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
567 }
568
569 /*******************************************************************
570  Reduce a file name, removing .. elements.
571 ********************************************************************/
572
573 void dos_clean_name(char *s)
574 {
575         char *p=NULL;
576
577         DEBUG(3,("dos_clean_name [%s]\n",s));
578
579         /* remove any double slashes */
580         all_string_sub(s, "\\\\", "\\", 0);
581
582         while ((p = strstr_m(s,"\\..\\")) != NULL) {
583                 pstring s1;
584
585                 *p = 0;
586                 pstrcpy(s1,p+3);
587
588                 if ((p=strrchr_m(s,'\\')) != NULL)
589                         *p = 0;
590                 else
591                         *s = 0;
592                 pstrcat(s,s1);
593         }  
594
595         trim_string(s,NULL,"\\..");
596
597         all_string_sub(s, "\\.\\", "\\", 0);
598 }
599
600 /*******************************************************************
601  Reduce a file name, removing .. elements. 
602 ********************************************************************/
603
604 void unix_clean_name(char *s)
605 {
606         char *p=NULL;
607
608         DEBUG(3,("unix_clean_name [%s]\n",s));
609
610         /* remove any double slashes */
611         all_string_sub(s, "//","/", 0);
612
613         /* Remove leading ./ characters */
614         if(strncmp(s, "./", 2) == 0) {
615                 trim_string(s, "./", NULL);
616                 if(*s == 0)
617                         pstrcpy(s,"./");
618         }
619
620         while ((p = strstr_m(s,"/../")) != NULL) {
621                 pstring s1;
622
623                 *p = 0;
624                 pstrcpy(s1,p+3);
625
626                 if ((p=strrchr_m(s,'/')) != NULL)
627                         *p = 0;
628                 else
629                         *s = 0;
630                 pstrcat(s,s1);
631         }  
632
633         trim_string(s,NULL,"/..");
634 }
635
636 /*******************************************************************
637  Close the low 3 fd's and open dev/null in their place.
638 ********************************************************************/
639
640 void close_low_fds(BOOL stderr_too)
641 {
642 #ifndef VALGRIND
643         int fd;
644         int i;
645
646         close(0);
647         close(1); 
648
649         if (stderr_too)
650                 close(2);
651
652         /* try and use up these file descriptors, so silly
653                 library routines writing to stdout etc won't cause havoc */
654         for (i=0;i<3;i++) {
655                 if (i == 2 && !stderr_too)
656                         continue;
657
658                 fd = sys_open("/dev/null",O_RDWR,0);
659                 if (fd < 0)
660                         fd = sys_open("/dev/null",O_WRONLY,0);
661                 if (fd < 0) {
662                         DEBUG(0,("Can't open /dev/null\n"));
663                         return;
664                 }
665                 if (fd != i) {
666                         DEBUG(0,("Didn't get file descriptor %d\n",i));
667                         return;
668                 }
669         }
670 #endif
671 }
672
673 /*******************************************************************
674  Write data into an fd at a given offset. Ignore seek errors.
675 ********************************************************************/
676
677 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
678 {
679         size_t total=0;
680         ssize_t ret;
681
682         if (pos == (SMB_OFF_T)-1) {
683                 return write_data(fd, buffer, N);
684         }
685 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
686         while (total < N) {
687                 ret = sys_pwrite(fd,buffer + total,N - total, pos);
688                 if (ret == -1 && errno == ESPIPE) {
689                         return write_data(fd, buffer + total,N - total);
690                 }
691                 if (ret == -1) {
692                         DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
693                         return -1;
694                 }
695                 if (ret == 0) {
696                         return total;
697                 }
698                 total += ret;
699                 pos += ret;
700         }
701         return (ssize_t)total;
702 #else
703         /* Use lseek and write_data. */
704         if (sys_lseek(fd, pos, SEEK_SET) == -1) {
705                 if (errno != ESPIPE) {
706                         return -1;
707                 }
708         }
709         return write_data(fd, buffer, N);
710 #endif
711 }
712
713 /****************************************************************************
714  Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
715  else
716   if SYSV use O_NDELAY
717   if BSD use FNDELAY
718 ****************************************************************************/
719
720 int set_blocking(int fd, BOOL set)
721 {
722         int val;
723 #ifdef O_NONBLOCK
724 #define FLAG_TO_SET O_NONBLOCK
725 #else
726 #ifdef SYSV
727 #define FLAG_TO_SET O_NDELAY
728 #else /* BSD */
729 #define FLAG_TO_SET FNDELAY
730 #endif
731 #endif
732
733         if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
734                 return -1;
735         if(set) /* Turn blocking on - ie. clear nonblock flag */
736                 val &= ~FLAG_TO_SET;
737         else
738                 val |= FLAG_TO_SET;
739         return sys_fcntl_long( fd, F_SETFL, val);
740 #undef FLAG_TO_SET
741 }
742
743 /****************************************************************************
744  Transfer some data between two fd's.
745 ****************************************************************************/
746
747 #ifndef TRANSFER_BUF_SIZE
748 #define TRANSFER_BUF_SIZE 65536
749 #endif
750
751 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
752                                                 ssize_t (*write_fn)(int, const void *, size_t))
753 {
754         char *buf;
755         size_t total = 0;
756         ssize_t read_ret;
757         ssize_t write_ret;
758         size_t num_to_read_thistime;
759         size_t num_written = 0;
760
761         if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL)
762                 return -1;
763
764         while (total < n) {
765                 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
766
767                 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
768                 if (read_ret == -1) {
769                         DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
770                         SAFE_FREE(buf);
771                         return -1;
772                 }
773                 if (read_ret == 0)
774                         break;
775
776                 num_written = 0;
777  
778                 while (num_written < read_ret) {
779                         write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
780  
781                         if (write_ret == -1) {
782                                 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
783                                 SAFE_FREE(buf);
784                                 return -1;
785                         }
786                         if (write_ret == 0)
787                                 return (ssize_t)total;
788  
789                         num_written += (size_t)write_ret;
790                 }
791
792                 total += (size_t)read_ret;
793         }
794
795         SAFE_FREE(buf);
796         return (ssize_t)total;          
797 }
798
799 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
800 {
801         return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
802 }
803
804 /*******************************************************************
805  Sleep for a specified number of milliseconds.
806 ********************************************************************/
807
808 void smb_msleep(unsigned int t)
809 {
810 #if defined(HAVE_NANOSLEEP)
811         struct timespec tval;
812         int ret;
813
814         tval.tv_sec = t/1000;
815         tval.tv_nsec = 1000000*(t%1000);
816
817         do {
818                 errno = 0;
819                 ret = nanosleep(&tval, &tval);
820         } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
821 #else
822         unsigned int tdiff=0;
823         struct timeval tval,t1,t2;  
824         fd_set fds;
825
826         GetTimeOfDay(&t1);
827         t2 = t1;
828   
829         while (tdiff < t) {
830                 tval.tv_sec = (t-tdiff)/1000;
831                 tval.tv_usec = 1000*((t-tdiff)%1000);
832
833                 /* Never wait for more than 1 sec. */
834                 if (tval.tv_sec > 1) {
835                         tval.tv_sec = 1; 
836                         tval.tv_usec = 0;
837                 }
838
839                 FD_ZERO(&fds);
840                 errno = 0;
841                 sys_select_intr(0,&fds,NULL,NULL,&tval);
842
843                 GetTimeOfDay(&t2);
844                 if (t2.tv_sec < t1.tv_sec) {
845                         /* Someone adjusted time... */
846                         t1 = t2;
847                 }
848
849                 tdiff = TvalDiff(&t1,&t2);
850         }
851 #endif
852 }
853
854 /****************************************************************************
855  Become a daemon, discarding the controlling terminal.
856 ****************************************************************************/
857
858 void become_daemon(BOOL Fork, BOOL no_process_group)
859 {
860         if (Fork) {
861                 if (sys_fork()) {
862                         _exit(0);
863                 }
864         }
865
866   /* detach from the terminal */
867 #ifdef HAVE_SETSID
868         if (!no_process_group) setsid();
869 #elif defined(TIOCNOTTY)
870         if (!no_process_group) {
871                 int i = sys_open("/dev/tty", O_RDWR, 0);
872                 if (i != -1) {
873                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
874                         close(i);
875                 }
876         }
877 #endif /* HAVE_SETSID */
878
879         /* Close fd's 0,1,2. Needed if started by rsh */
880         close_low_fds(False);  /* Don't close stderr, let the debug system
881                                   attach it to the logfile */
882 }
883
884 /****************************************************************************
885  Put up a yes/no prompt.
886 ****************************************************************************/
887
888 BOOL yesno(char *p)
889 {
890         pstring ans;
891         printf("%s",p);
892
893         if (!fgets(ans,sizeof(ans)-1,stdin))
894                 return(False);
895
896         if (*ans == 'y' || *ans == 'Y')
897                 return(True);
898
899         return(False);
900 }
901
902 #if defined(PARANOID_MALLOC_CHECKER)
903
904 /****************************************************************************
905  Internal malloc wrapper. Externally visible.
906 ****************************************************************************/
907
908 void *malloc_(size_t size)
909 {
910 #undef malloc
911         return malloc(size);
912 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
913 }
914
915 /****************************************************************************
916  Internal calloc wrapper. Not externally visible.
917 ****************************************************************************/
918
919 static void *calloc_(size_t count, size_t size)
920 {
921 #undef calloc
922         return calloc(count, size);
923 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
924 }
925
926 /****************************************************************************
927  Internal realloc wrapper. Not externally visible.
928 ****************************************************************************/
929
930 static void *realloc_(void *ptr, size_t size)
931 {
932 #undef realloc
933         return realloc(ptr, size);
934 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
935 }
936
937 #endif /* PARANOID_MALLOC_CHECKER */
938
939 /****************************************************************************
940  Type-safe malloc.
941 ****************************************************************************/
942
943 void *malloc_array(size_t el_size, unsigned int count)
944 {
945         if (count >= MAX_ALLOC_SIZE/el_size) {
946                 return NULL;
947         }
948
949 #if defined(PARANOID_MALLOC_CHECKER)
950         return malloc_(el_size*count);
951 #else
952         return malloc(el_size*count);
953 #endif
954 }
955
956 /****************************************************************************
957  Type-safe calloc.
958 ****************************************************************************/
959
960 void *calloc_array(size_t size, size_t nmemb)
961 {
962         if (nmemb >= MAX_ALLOC_SIZE/size) {
963                 return NULL;
964         }
965 #if defined(PARANOID_MALLOC_CHECKER)
966         return calloc_(nmemb, size);
967 #else
968         return calloc(nmemb, size);
969 #endif
970 }
971
972 /****************************************************************************
973  Expand a pointer to be a particular size.
974  Note that this version of Realloc has an extra parameter that decides
975  whether to free the passed in storage on allocation failure or if the
976  new size is zero.
977
978  This is designed for use in the typical idiom of :
979
980  p = SMB_REALLOC(p, size)
981  if (!p) {
982     return error;
983  }
984
985  and not to have to keep track of the old 'p' contents to free later, nor
986  to worry if the size parameter was zero. In the case where NULL is returned
987  we guarentee that p has been freed.
988
989  If free later semantics are desired, then pass 'free_old_on_error' as False which
990  guarentees that the old contents are not freed on error, even if size == 0. To use
991  this idiom use :
992
993  tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
994  if (!tmp) {
995     SAFE_FREE(p);
996     return error;
997  } else {
998     p = tmp;
999  }
1000
1001  Changes were instigated by Coverity error checking. JRA.
1002 ****************************************************************************/
1003
1004 void *Realloc(void *p, size_t size, BOOL free_old_on_error)
1005 {
1006         void *ret=NULL;
1007
1008         if (size == 0) {
1009                 if (free_old_on_error) {
1010                         SAFE_FREE(p);
1011                 }
1012                 DEBUG(2,("Realloc asked for 0 bytes\n"));
1013                 return NULL;
1014         }
1015
1016 #if defined(PARANOID_MALLOC_CHECKER)
1017         if (!p) {
1018                 ret = (void *)malloc_(size);
1019         } else {
1020                 ret = (void *)realloc_(p,size);
1021         }
1022 #else
1023         if (!p) {
1024                 ret = (void *)malloc(size);
1025         } else {
1026                 ret = (void *)realloc(p,size);
1027         }
1028 #endif
1029
1030         if (!ret) {
1031                 if (free_old_on_error && p) {
1032                         SAFE_FREE(p);
1033                 }
1034                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1035         }
1036
1037         return(ret);
1038 }
1039
1040 /****************************************************************************
1041  Type-safe realloc.
1042 ****************************************************************************/
1043
1044 void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_on_error)
1045 {
1046         if (count >= MAX_ALLOC_SIZE/el_size) {
1047                 if (free_old_on_error) {
1048                         SAFE_FREE(p);
1049                 }
1050                 return NULL;
1051         }
1052         return Realloc(p, el_size*count, free_old_on_error);
1053 }
1054
1055 /****************************************************************************
1056  (Hopefully) efficient array append.
1057 ****************************************************************************/
1058
1059 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1060                         void *element, void *_array, uint32 *num_elements,
1061                         ssize_t *array_size)
1062 {
1063         void **array = (void **)_array;
1064
1065         if (*array_size < 0) {
1066                 return;
1067         }
1068
1069         if (*array == NULL) {
1070                 if (*array_size == 0) {
1071                         *array_size = 128;
1072                 }
1073
1074                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1075                         goto error;
1076                 }
1077
1078                 *array = TALLOC(mem_ctx, element_size * (*array_size));
1079                 if (*array == NULL) {
1080                         goto error;
1081                 }
1082         }
1083
1084         if (*num_elements == *array_size) {
1085                 *array_size *= 2;
1086
1087                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1088                         goto error;
1089                 }
1090
1091                 *array = TALLOC_REALLOC(mem_ctx, *array,
1092                                         element_size * (*array_size));
1093
1094                 if (*array == NULL) {
1095                         goto error;
1096                 }
1097         }
1098
1099         memcpy((char *)(*array) + element_size*(*num_elements),
1100                element, element_size);
1101         *num_elements += 1;
1102
1103         return;
1104
1105  error:
1106         *num_elements = 0;
1107         *array_size = -1;
1108 }
1109
1110 /****************************************************************************
1111  Free memory, checks for NULL.
1112  Use directly SAFE_FREE()
1113  Exists only because we need to pass a function pointer somewhere --SSS
1114 ****************************************************************************/
1115
1116 void safe_free(void *p)
1117 {
1118         SAFE_FREE(p);
1119 }
1120
1121 /****************************************************************************
1122  Get my own name and IP.
1123 ****************************************************************************/
1124
1125 BOOL get_myname(char *my_name)
1126 {
1127         pstring hostname;
1128
1129         *hostname = 0;
1130
1131         /* get my host name */
1132         if (gethostname(hostname, sizeof(hostname)) == -1) {
1133                 DEBUG(0,("gethostname failed\n"));
1134                 return False;
1135         } 
1136
1137         /* Ensure null termination. */
1138         hostname[sizeof(hostname)-1] = '\0';
1139
1140         if (my_name) {
1141                 /* split off any parts after an initial . */
1142                 char *p = strchr_m(hostname,'.');
1143
1144                 if (p)
1145                         *p = 0;
1146                 
1147                 fstrcpy(my_name,hostname);
1148         }
1149         
1150         return(True);
1151 }
1152
1153 /****************************************************************************
1154  Get my own canonical name, including domain.
1155 ****************************************************************************/
1156
1157 BOOL get_mydnsfullname(fstring my_dnsname)
1158 {
1159         static fstring dnshostname;
1160         struct hostent *hp;
1161
1162         if (!*dnshostname) {
1163                 /* get my host name */
1164                 if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
1165                         *dnshostname = '\0';
1166                         DEBUG(0,("gethostname failed\n"));
1167                         return False;
1168                 } 
1169
1170                 /* Ensure null termination. */
1171                 dnshostname[sizeof(dnshostname)-1] = '\0';
1172
1173                 /* Ensure we get the cannonical name. */
1174                 if (!(hp = sys_gethostbyname(dnshostname))) {
1175                         *dnshostname = '\0';
1176                         return False;
1177                 }
1178                 fstrcpy(dnshostname, hp->h_name);
1179         }
1180         fstrcpy(my_dnsname, dnshostname);
1181         return True;
1182 }
1183
1184 /****************************************************************************
1185  Get my own domain name.
1186 ****************************************************************************/
1187
1188 BOOL get_mydnsdomname(fstring my_domname)
1189 {
1190         fstring domname;
1191         char *p;
1192
1193         *my_domname = '\0';
1194         if (!get_mydnsfullname(domname)) {
1195                 return False;
1196         }       
1197         p = strchr_m(domname, '.');
1198         if (p) {
1199                 p++;
1200                 fstrcpy(my_domname, p);
1201         }
1202
1203         return False;
1204 }
1205
1206 /****************************************************************************
1207  Interpret a protocol description string, with a default.
1208 ****************************************************************************/
1209
1210 int interpret_protocol(const char *str,int def)
1211 {
1212         if (strequal(str,"NT1"))
1213                 return(PROTOCOL_NT1);
1214         if (strequal(str,"LANMAN2"))
1215                 return(PROTOCOL_LANMAN2);
1216         if (strequal(str,"LANMAN1"))
1217                 return(PROTOCOL_LANMAN1);
1218         if (strequal(str,"CORE"))
1219                 return(PROTOCOL_CORE);
1220         if (strequal(str,"COREPLUS"))
1221                 return(PROTOCOL_COREPLUS);
1222         if (strequal(str,"CORE+"))
1223                 return(PROTOCOL_COREPLUS);
1224   
1225         DEBUG(0,("Unrecognised protocol level %s\n",str));
1226   
1227         return(def);
1228 }
1229
1230 /****************************************************************************
1231  Return true if a string could be a pure IP address.
1232 ****************************************************************************/
1233
1234 BOOL is_ipaddress(const char *str)
1235 {
1236         BOOL pure_address = True;
1237         int i;
1238   
1239         for (i=0; pure_address && str[i]; i++)
1240                 if (!(isdigit((int)str[i]) || str[i] == '.'))
1241                         pure_address = False;
1242
1243         /* Check that a pure number is not misinterpreted as an IP */
1244         pure_address = pure_address && (strchr_m(str, '.') != NULL);
1245
1246         return pure_address;
1247 }
1248
1249 /****************************************************************************
1250  Interpret an internet address or name into an IP address in 4 byte form.
1251 ****************************************************************************/
1252
1253 uint32 interpret_addr(const char *str)
1254 {
1255         struct hostent *hp;
1256         uint32 res;
1257
1258         if (strcmp(str,"0.0.0.0") == 0)
1259                 return(0);
1260         if (strcmp(str,"255.255.255.255") == 0)
1261                 return(0xFFFFFFFF);
1262
1263   /* if it's in the form of an IP address then get the lib to interpret it */
1264         if (is_ipaddress(str)) {
1265                 res = inet_addr(str);
1266         } else {
1267                 /* otherwise assume it's a network name of some sort and use 
1268                         sys_gethostbyname */
1269                 if ((hp = sys_gethostbyname(str)) == 0) {
1270                         DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1271                         return 0;
1272                 }
1273
1274                 if(hp->h_addr == NULL) {
1275                         DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1276                         return 0;
1277                 }
1278                 putip((char *)&res,(char *)hp->h_addr);
1279         }
1280
1281         if (res == (uint32)-1)
1282                 return(0);
1283
1284         return(res);
1285 }
1286
1287 /*******************************************************************
1288  A convenient addition to interpret_addr().
1289 ******************************************************************/
1290
1291 struct in_addr *interpret_addr2(const char *str)
1292 {
1293         static struct in_addr ret;
1294         uint32 a = interpret_addr(str);
1295         ret.s_addr = a;
1296         return(&ret);
1297 }
1298
1299 /*******************************************************************
1300  Check if an IP is the 0.0.0.0.
1301 ******************************************************************/
1302
1303 BOOL is_zero_ip(struct in_addr ip)
1304 {
1305         uint32 a;
1306         putip((char *)&a,(char *)&ip);
1307         return(a == 0);
1308 }
1309
1310 /*******************************************************************
1311  Set an IP to 0.0.0.0.
1312 ******************************************************************/
1313
1314 void zero_ip(struct in_addr *ip)
1315 {
1316         static BOOL init;
1317         static struct in_addr ipzero;
1318
1319         if (!init) {
1320                 ipzero = *interpret_addr2("0.0.0.0");
1321                 init = True;
1322         }
1323
1324         *ip = ipzero;
1325 }
1326
1327 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1328 /******************************************************************
1329  Remove any mount options such as -rsize=2048,wsize=2048 etc.
1330  Based on a fix from <Thomas.Hepper@icem.de>.
1331 *******************************************************************/
1332
1333 static void strip_mount_options( pstring *str)
1334 {
1335         if (**str == '-') { 
1336                 char *p = *str;
1337                 while(*p && !isspace(*p))
1338                         p++;
1339                 while(*p && isspace(*p))
1340                         p++;
1341                 if(*p) {
1342                         pstring tmp_str;
1343
1344                         pstrcpy(tmp_str, p);
1345                         pstrcpy(*str, tmp_str);
1346                 }
1347         }
1348 }
1349
1350 /*******************************************************************
1351  Patch from jkf@soton.ac.uk
1352  Split Luke's automount_server into YP lookup and string splitter
1353  so can easily implement automount_path(). 
1354  As we may end up doing both, cache the last YP result. 
1355 *******************************************************************/
1356
1357 #ifdef WITH_NISPLUS_HOME
1358 char *automount_lookup(const char *user_name)
1359 {
1360         static fstring last_key = "";
1361         static pstring last_value = "";
1362  
1363         char *nis_map = (char *)lp_nis_home_map_name();
1364  
1365         char buffer[NIS_MAXATTRVAL + 1];
1366         nis_result *result;
1367         nis_object *object;
1368         entry_obj  *entry;
1369  
1370         if (strcmp(user_name, last_key)) {
1371                 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1372                 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1373  
1374                 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1375                         if (result->status != NIS_SUCCESS) {
1376                                 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1377                                 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1378                         } else {
1379                                 object = result->objects.objects_val;
1380                                 if (object->zo_data.zo_type == ENTRY_OBJ) {
1381                                         entry = &object->zo_data.objdata_u.en_data;
1382                                         DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1383                                         DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1384  
1385                                         pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1386                                         pstring_sub(last_value, "&", user_name);
1387                                         fstrcpy(last_key, user_name);
1388                                 }
1389                         }
1390                 }
1391                 nis_freeresult(result);
1392         }
1393
1394         strip_mount_options(&last_value);
1395
1396         DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1397         return last_value;
1398 }
1399 #else /* WITH_NISPLUS_HOME */
1400
1401 char *automount_lookup(const char *user_name)
1402 {
1403         static fstring last_key = "";
1404         static pstring last_value = "";
1405
1406         int nis_error;        /* returned by yp all functions */
1407         char *nis_result;     /* yp_match inits this */
1408         int nis_result_len;  /* and set this */
1409         char *nis_domain;     /* yp_get_default_domain inits this */
1410         char *nis_map = (char *)lp_nis_home_map_name();
1411
1412         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1413                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1414                 return last_value;
1415         }
1416
1417         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1418
1419         if (!strcmp(user_name, last_key)) {
1420                 nis_result = last_value;
1421                 nis_result_len = strlen(last_value);
1422                 nis_error = 0;
1423         } else {
1424                 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1425                                 &nis_result, &nis_result_len)) == 0) {
1426                         fstrcpy(last_key, user_name);
1427                         pstrcpy(last_value, nis_result);
1428                         strip_mount_options(&last_value);
1429
1430                 } else if(nis_error == YPERR_KEY) {
1431
1432                         /* If Key lookup fails user home server is not in nis_map 
1433                                 use default information for server, and home directory */
1434                         last_value[0] = 0;
1435                         DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
1436                                         user_name, nis_map));
1437                         DEBUG(3, ("using defaults for server and home directory\n"));
1438                 } else {
1439                         DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
1440                                         yperr_string(nis_error), user_name, nis_map));
1441                 }
1442         }
1443
1444         DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1445         return last_value;
1446 }
1447 #endif /* WITH_NISPLUS_HOME */
1448 #endif
1449
1450 /*******************************************************************
1451  Are two IPs on the same subnet?
1452 ********************************************************************/
1453
1454 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1455 {
1456         uint32 net1,net2,nmask;
1457
1458         nmask = ntohl(mask.s_addr);
1459         net1  = ntohl(ip1.s_addr);
1460         net2  = ntohl(ip2.s_addr);
1461             
1462         return((net1 & nmask) == (net2 & nmask));
1463 }
1464
1465
1466 /****************************************************************************
1467  Check if a process exists. Does this work on all unixes?
1468 ****************************************************************************/
1469
1470 BOOL process_exists(const struct process_id pid)
1471 {
1472         if (procid_is_me(&pid)) {
1473                 return True;
1474         }
1475
1476         if (!procid_is_local(&pid)) {
1477                 /* This *SEVERELY* needs fixing. */
1478                 return True;
1479         }
1480
1481         /* Doing kill with a non-positive pid causes messages to be
1482          * sent to places we don't want. */
1483         SMB_ASSERT(pid.pid > 0);
1484         return(kill(pid.pid,0) == 0 || errno != ESRCH);
1485 }
1486
1487 BOOL process_exists_by_pid(pid_t pid)
1488 {
1489         return process_exists(pid_to_procid(pid));
1490 }
1491
1492 /*******************************************************************
1493  Convert a uid into a user name.
1494 ********************************************************************/
1495
1496 const char *uidtoname(uid_t uid)
1497 {
1498         static fstring name;
1499         struct passwd *pass;
1500
1501         pass = getpwuid_alloc(NULL, uid);
1502         if (pass) {
1503                 fstrcpy(name, pass->pw_name);
1504                 TALLOC_FREE(pass);
1505         } else {
1506                 slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
1507         }
1508         return name;
1509 }
1510
1511
1512 /*******************************************************************
1513  Convert a gid into a group name.
1514 ********************************************************************/
1515
1516 char *gidtoname(gid_t gid)
1517 {
1518         static fstring name;
1519         struct group *grp;
1520
1521         grp = getgrgid(gid);
1522         if (grp)
1523                 return(grp->gr_name);
1524         slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1525         return(name);
1526 }
1527
1528 /*******************************************************************
1529  Convert a user name into a uid. 
1530 ********************************************************************/
1531
1532 uid_t nametouid(const char *name)
1533 {
1534         struct passwd *pass;
1535         char *p;
1536         uid_t u;
1537
1538         pass = getpwnam_alloc(NULL, name);
1539         if (pass) {
1540                 u = pass->pw_uid;
1541                 TALLOC_FREE(pass);
1542                 return u;
1543         }
1544
1545         u = (uid_t)strtol(name, &p, 0);
1546         if ((p != name) && (*p == '\0'))
1547                 return u;
1548
1549         return (uid_t)-1;
1550 }
1551
1552 /*******************************************************************
1553  Convert a name to a gid_t if possible. Return -1 if not a group. 
1554 ********************************************************************/
1555
1556 gid_t nametogid(const char *name)
1557 {
1558         struct group *grp;
1559         char *p;
1560         gid_t g;
1561
1562         g = (gid_t)strtol(name, &p, 0);
1563         if ((p != name) && (*p == '\0'))
1564                 return g;
1565
1566         grp = sys_getgrnam(name);
1567         if (grp)
1568                 return(grp->gr_gid);
1569         return (gid_t)-1;
1570 }
1571
1572 /*******************************************************************
1573  Something really nasty happened - panic !
1574 ********************************************************************/
1575
1576 void smb_panic(const char *const why)
1577 {
1578         char *cmd;
1579         int result;
1580
1581 #ifdef DEVELOPER
1582         {
1583
1584                 if (global_clobber_region_function) {
1585                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1586                                          global_clobber_region_function,
1587                                          global_clobber_region_line));
1588                 } 
1589         }
1590 #endif
1591
1592         DEBUG(0,("PANIC (pid %llu): %s\n",
1593                     (unsigned long long)sys_getpid(), why));
1594         log_stack_trace();
1595
1596         cmd = lp_panic_action();
1597         if (cmd && *cmd) {
1598                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1599                 result = system(cmd);
1600
1601                 if (result == -1)
1602                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1603                                           strerror(errno)));
1604                 else
1605                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1606                                           WEXITSTATUS(result)));
1607         }
1608
1609         dump_core();
1610 }
1611
1612 /*******************************************************************
1613  Print a backtrace of the stack to the debug log. This function
1614  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1615  exit shortly after calling it.
1616 ********************************************************************/
1617
1618 #ifdef HAVE_LIBUNWIND_H
1619 #include <libunwind.h>
1620 #endif
1621
1622 #ifdef HAVE_EXECINFO_H
1623 #include <execinfo.h>
1624 #endif
1625
1626 #ifdef HAVE_LIBEXC_H
1627 #include <libexc.h>
1628 #endif
1629
1630 void log_stack_trace(void)
1631 {
1632 #ifdef HAVE_LIBUNWIND
1633         /* Try to use libunwind before any other technique since on ia64
1634          * libunwind correctly walks the stack in more circumstances than
1635          * backtrace.
1636          */ 
1637         unw_cursor_t cursor;
1638         unw_context_t uc;
1639         unsigned i = 0;
1640
1641         char procname[256];
1642         unw_word_t ip, sp, off;
1643
1644         procname[sizeof(procname) - 1] = '\0';
1645
1646         if (unw_getcontext(&uc) != 0) {
1647                 goto libunwind_failed;
1648         }
1649
1650         if (unw_init_local(&cursor, &uc) != 0) {
1651                 goto libunwind_failed;
1652         }
1653
1654         DEBUG(0, ("BACKTRACE:\n"));
1655
1656         do {
1657             ip = sp = 0;
1658             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1659             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1660
1661             switch (unw_get_proc_name(&cursor,
1662                         procname, sizeof(procname) - 1, &off) ) {
1663             case 0:
1664                     /* Name found. */
1665             case -UNW_ENOMEM:
1666                     /* Name truncated. */
1667                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1668                             i, procname, (long long)off,
1669                             (long long)ip, (long long) sp));
1670                     break;
1671             default:
1672             /* case -UNW_ENOINFO: */
1673             /* case -UNW_EUNSPEC: */
1674                     /* No symbol name found. */
1675                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1676                             i, "<unknown symbol>",
1677                             (long long)ip, (long long) sp));
1678             }
1679             ++i;
1680         } while (unw_step(&cursor) > 0);
1681
1682         return;
1683
1684 libunwind_failed:
1685         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1686
1687 #elif HAVE_BACKTRACE_SYMBOLS
1688         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1689         size_t backtrace_size;
1690         char **backtrace_strings;
1691
1692         /* get the backtrace (stack frames) */
1693         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1694         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1695
1696         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1697                   (unsigned long)backtrace_size));
1698         
1699         if (backtrace_strings) {
1700                 int i;
1701
1702                 for (i = 0; i < backtrace_size; i++)
1703                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1704
1705                 /* Leak the backtrace_strings, rather than risk what free() might do */
1706         }
1707
1708 #elif HAVE_LIBEXC
1709
1710         /* The IRIX libexc library provides an API for unwinding the stack. See
1711          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1712          * since we are about to abort anyway, it hardly matters.
1713          */
1714
1715 #define NAMESIZE 32 /* Arbitrary */
1716
1717         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1718         char *          names[BACKTRACE_STACK_SIZE];
1719         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1720
1721         int             i;
1722         int             levels;
1723
1724         ZERO_ARRAY(addrs);
1725         ZERO_ARRAY(names);
1726         ZERO_ARRAY(namebuf);
1727
1728         /* We need to be root so we can open our /proc entry to walk
1729          * our stack. It also helps when we want to dump core.
1730          */
1731         become_root();
1732
1733         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1734                 names[i] = namebuf + (i * NAMESIZE);
1735         }
1736
1737         levels = trace_back_stack(0, addrs, names,
1738                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1739
1740         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1741         for (i = 0; i < levels; i++) {
1742                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1743         }
1744 #undef NAMESIZE
1745
1746 #else
1747         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1748 #endif
1749 }
1750
1751 /*******************************************************************
1752   A readdir wrapper which just returns the file name.
1753  ********************************************************************/
1754
1755 const char *readdirname(SMB_STRUCT_DIR *p)
1756 {
1757         SMB_STRUCT_DIRENT *ptr;
1758         char *dname;
1759
1760         if (!p)
1761                 return(NULL);
1762   
1763         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1764         if (!ptr)
1765                 return(NULL);
1766
1767         dname = ptr->d_name;
1768
1769 #ifdef NEXT2
1770         if (telldir(p) < 0)
1771                 return(NULL);
1772 #endif
1773
1774 #ifdef HAVE_BROKEN_READDIR_NAME
1775         /* using /usr/ucb/cc is BAD */
1776         dname = dname - 2;
1777 #endif
1778
1779         {
1780                 static pstring buf;
1781                 int len = NAMLEN(ptr);
1782                 memcpy(buf, dname, len);
1783                 buf[len] = 0;
1784                 dname = buf;
1785         }
1786
1787         return(dname);
1788 }
1789
1790 /*******************************************************************
1791  Utility function used to decide if the last component 
1792  of a path matches a (possibly wildcarded) entry in a namelist.
1793 ********************************************************************/
1794
1795 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1796 {
1797         pstring last_component;
1798         char *p;
1799
1800         /* if we have no list it's obviously not in the path */
1801         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1802                 return False;
1803         }
1804
1805         DEBUG(8, ("is_in_path: %s\n", name));
1806
1807         /* Get the last component of the unix name. */
1808         p = strrchr_m(name, '/');
1809         pstrcpy(last_component, p ? ++p : name);
1810
1811         for(; namelist->name != NULL; namelist++) {
1812                 if(namelist->is_wild) {
1813                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1814                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1815                                 return True;
1816                         }
1817                 } else {
1818                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1819                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1820                                 DEBUG(8,("is_in_path: match succeeded\n"));
1821                                 return True;
1822                         }
1823                 }
1824         }
1825         DEBUG(8,("is_in_path: match not found\n"));
1826  
1827         return False;
1828 }
1829
1830 /*******************************************************************
1831  Strip a '/' separated list into an array of 
1832  name_compare_enties structures suitable for 
1833  passing to is_in_path(). We do this for
1834  speed so we can pre-parse all the names in the list 
1835  and don't do it for each call to is_in_path().
1836  namelist is modified here and is assumed to be 
1837  a copy owned by the caller.
1838  We also check if the entry contains a wildcard to
1839  remove a potentially expensive call to mask_match
1840  if possible.
1841 ********************************************************************/
1842  
1843 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1844 {
1845         char *name_end;
1846         char *nameptr = namelist;
1847         int num_entries = 0;
1848         int i;
1849
1850         (*ppname_array) = NULL;
1851
1852         if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0'))) 
1853                 return;
1854
1855         /* We need to make two passes over the string. The
1856                 first to count the number of elements, the second
1857                 to split it.
1858         */
1859
1860         while(*nameptr) {
1861                 if ( *nameptr == '/' ) {
1862                         /* cope with multiple (useless) /s) */
1863                         nameptr++;
1864                         continue;
1865                 }
1866                 /* find the next / */
1867                 name_end = strchr_m(nameptr, '/');
1868
1869                 /* oops - the last check for a / didn't find one. */
1870                 if (name_end == NULL)
1871                         break;
1872
1873                 /* next segment please */
1874                 nameptr = name_end + 1;
1875                 num_entries++;
1876         }
1877
1878         if(num_entries == 0)
1879                 return;
1880
1881         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1882                 DEBUG(0,("set_namearray: malloc fail\n"));
1883                 return;
1884         }
1885
1886         /* Now copy out the names */
1887         nameptr = namelist;
1888         i = 0;
1889         while(*nameptr) {
1890                 if ( *nameptr == '/' ) {
1891                         /* cope with multiple (useless) /s) */
1892                         nameptr++;
1893                         continue;
1894                 }
1895                 /* find the next / */
1896                 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1897                         *name_end = 0;
1898
1899                 /* oops - the last check for a / didn't find one. */
1900                 if(name_end == NULL) 
1901                         break;
1902
1903                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1904                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1905                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1906                         return;
1907                 }
1908
1909                 /* next segment please */
1910                 nameptr = name_end + 1;
1911                 i++;
1912         }
1913   
1914         (*ppname_array)[i].name = NULL;
1915
1916         return;
1917 }
1918
1919 /****************************************************************************
1920  Routine to free a namearray.
1921 ****************************************************************************/
1922
1923 void free_namearray(name_compare_entry *name_array)
1924 {
1925         int i;
1926
1927         if(name_array == NULL)
1928                 return;
1929
1930         for(i=0; name_array[i].name!=NULL; i++)
1931                 SAFE_FREE(name_array[i].name);
1932         SAFE_FREE(name_array);
1933 }
1934
1935 #undef DBGC_CLASS
1936 #define DBGC_CLASS DBGC_LOCKING
1937
1938 /****************************************************************************
1939  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1940  is dealt with in posix.c
1941  Returns True if the lock was granted, False otherwise.
1942 ****************************************************************************/
1943
1944 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1945 {
1946         SMB_STRUCT_FLOCK lock;
1947         int ret;
1948
1949         DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1950                 fd,op,(double)offset,(double)count,type));
1951
1952         lock.l_type = type;
1953         lock.l_whence = SEEK_SET;
1954         lock.l_start = offset;
1955         lock.l_len = count;
1956         lock.l_pid = 0;
1957
1958         ret = sys_fcntl_ptr(fd,op,&lock);
1959
1960         if (ret == -1) {
1961                 int sav = errno;
1962                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1963                         (double)offset,(double)count,op,type,strerror(errno)));
1964                 errno = sav;
1965                 return False;
1966         }
1967
1968         /* everything went OK */
1969         DEBUG(8,("fcntl_lock: Lock call successful\n"));
1970
1971         return True;
1972 }
1973
1974 /****************************************************************************
1975  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1976  is dealt with in posix.c
1977  Returns True if we have information regarding this lock region (and returns
1978  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1979 ****************************************************************************/
1980
1981 BOOL fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1982 {
1983         SMB_STRUCT_FLOCK lock;
1984         int ret;
1985
1986         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1987                     fd,(double)*poffset,(double)*pcount,*ptype));
1988
1989         lock.l_type = *ptype;
1990         lock.l_whence = SEEK_SET;
1991         lock.l_start = *poffset;
1992         lock.l_len = *pcount;
1993         lock.l_pid = 0;
1994
1995         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1996
1997         if (ret == -1) {
1998                 int sav = errno;
1999                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2000                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2001                 errno = sav;
2002                 return False;
2003         }
2004
2005         *ptype = lock.l_type;
2006         *poffset = lock.l_start;
2007         *pcount = lock.l_len;
2008         *ppid = lock.l_pid;
2009         
2010         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2011                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2012         return True;
2013 }
2014
2015 #undef DBGC_CLASS
2016 #define DBGC_CLASS DBGC_ALL
2017
2018 /*******************************************************************
2019  Is the name specified one of my netbios names.
2020  Returns true if it is equal, false otherwise.
2021 ********************************************************************/
2022
2023 BOOL is_myname(const char *s)
2024 {
2025         int n;
2026         BOOL ret = False;
2027
2028         for (n=0; my_netbios_names(n); n++) {
2029                 if (strequal(my_netbios_names(n), s)) {
2030                         ret=True;
2031                         break;
2032                 }
2033         }
2034         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2035         return(ret);
2036 }
2037
2038 BOOL is_myname_or_ipaddr(const char *s)
2039 {
2040         fstring name, dnsname;
2041         char *servername;
2042
2043         if ( !s )
2044                 return False;
2045
2046         /* santize the string from '\\name' */
2047
2048         fstrcpy( name, s );
2049
2050         servername = strrchr_m( name, '\\' );
2051         if ( !servername )
2052                 servername = name;
2053         else
2054                 servername++;
2055
2056         /* optimize for the common case */
2057
2058         if (strequal(servername, global_myname())) 
2059                 return True;
2060
2061         /* check for an alias */
2062
2063         if (is_myname(servername))
2064                 return True;
2065
2066         /* check for loopback */
2067
2068         if (strequal(servername, "localhost")) 
2069                 return True;
2070
2071         /* maybe it's my dns name */
2072
2073         if ( get_mydnsfullname( dnsname ) )
2074                 if ( strequal( servername, dnsname ) )
2075                         return True;
2076                 
2077         /* handle possible CNAME records */
2078
2079         if ( !is_ipaddress( servername ) ) {
2080                 /* use DNS to resolve the name, but only the first address */
2081                 struct hostent *hp;
2082
2083                 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
2084                         struct in_addr return_ip;
2085                         putip( (char*)&return_ip, (char*)hp->h_addr );
2086                         fstrcpy( name, inet_ntoa( return_ip ) );
2087                         servername = name;
2088                 }       
2089         }
2090                 
2091         /* maybe its an IP address? */
2092         if (is_ipaddress(servername)) {
2093                 struct iface_struct nics[MAX_INTERFACES];
2094                 int i, n;
2095                 uint32 ip;
2096                 
2097                 ip = interpret_addr(servername);
2098                 if ((ip==0) || (ip==0xffffffff))
2099                         return False;
2100                         
2101                 n = get_interfaces(nics, MAX_INTERFACES);
2102                 for (i=0; i<n; i++) {
2103                         if (ip == nics[i].ip.s_addr)
2104                                 return True;
2105                 }
2106         }       
2107
2108         /* no match */
2109         return False;
2110 }
2111
2112 /*******************************************************************
2113  Is the name specified our workgroup/domain.
2114  Returns true if it is equal, false otherwise.
2115 ********************************************************************/
2116
2117 BOOL is_myworkgroup(const char *s)
2118 {
2119         BOOL ret = False;
2120
2121         if (strequal(s, lp_workgroup())) {
2122                 ret=True;
2123         }
2124
2125         DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2126         return(ret);
2127 }
2128
2129 /*******************************************************************
2130  we distinguish between 2K and XP by the "Native Lan Manager" string
2131    WinXP => "Windows 2002 5.1"
2132    Win2k => "Windows 2000 5.0"
2133    NT4   => "Windows NT 4.0" 
2134    Win9x => "Windows 4.0"
2135  Windows 2003 doesn't set the native lan manager string but 
2136  they do set the domain to "Windows 2003 5.2" (probably a bug).
2137 ********************************************************************/
2138
2139 void ra_lanman_string( const char *native_lanman )
2140 {                
2141         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2142                 set_remote_arch( RA_WINXP );
2143         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2144                 set_remote_arch( RA_WIN2K3 );
2145 }
2146
2147 /*******************************************************************
2148  Set the horrid remote_arch string based on an enum.
2149 ********************************************************************/
2150
2151 void set_remote_arch(enum remote_arch_types type)
2152 {
2153         ra_type = type;
2154         switch( type ) {
2155         case RA_WFWG:
2156                 fstrcpy(remote_arch, "WfWg");
2157                 break;
2158         case RA_OS2:
2159                 fstrcpy(remote_arch, "OS2");
2160                 break;
2161         case RA_WIN95:
2162                 fstrcpy(remote_arch, "Win95");
2163                 break;
2164         case RA_WINNT:
2165                 fstrcpy(remote_arch, "WinNT");
2166                 break;
2167         case RA_WIN2K:
2168                 fstrcpy(remote_arch, "Win2K");
2169                 break;
2170         case RA_WINXP:
2171                 fstrcpy(remote_arch, "WinXP");
2172                 break;
2173         case RA_WIN2K3:
2174                 fstrcpy(remote_arch, "Win2K3");
2175                 break;
2176         case RA_VISTA:
2177                 fstrcpy(remote_arch, "Vista");
2178                 break;
2179         case RA_SAMBA:
2180                 fstrcpy(remote_arch,"Samba");
2181                 break;
2182         case RA_CIFSFS:
2183                 fstrcpy(remote_arch,"CIFSFS");
2184                 break;
2185         default:
2186                 ra_type = RA_UNKNOWN;
2187                 fstrcpy(remote_arch, "UNKNOWN");
2188                 break;
2189         }
2190
2191         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2192 }
2193
2194 /*******************************************************************
2195  Get the remote_arch type.
2196 ********************************************************************/
2197
2198 enum remote_arch_types get_remote_arch(void)
2199 {
2200         return ra_type;
2201 }
2202
2203 void print_asc(int level, const unsigned char *buf,int len)
2204 {
2205         int i;
2206         for (i=0;i<len;i++)
2207                 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2208 }
2209
2210 void dump_data(int level, const char *buf1,int len)
2211 {
2212         const unsigned char *buf = (const unsigned char *)buf1;
2213         int i=0;
2214         if (len<=0) return;
2215
2216         if (!DEBUGLVL(level)) return;
2217         
2218         DEBUGADD(level,("[%03X] ",i));
2219         for (i=0;i<len;) {
2220                 DEBUGADD(level,("%02X ",(int)buf[i]));
2221                 i++;
2222                 if (i%8 == 0) DEBUGADD(level,(" "));
2223                 if (i%16 == 0) {      
2224                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2225                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2226                         if (i<len) DEBUGADD(level,("[%03X] ",i));
2227                 }
2228         }
2229         if (i%16) {
2230                 int n;
2231                 n = 16 - (i%16);
2232                 DEBUGADD(level,(" "));
2233                 if (n>8) DEBUGADD(level,(" "));
2234                 while (n--) DEBUGADD(level,("   "));
2235                 n = MIN(8,i%16);
2236                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2237                 n = (i%16) - n;
2238                 if (n>0) print_asc(level,&buf[i-n],n); 
2239                 DEBUGADD(level,("\n"));    
2240         }       
2241 }
2242
2243 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2244 {
2245 #ifdef DEBUG_PASSWORD
2246         DEBUG(11, ("%s", msg));
2247         if (data != NULL && len > 0)
2248         {
2249                 dump_data(11, (const char *)data, len);
2250         }
2251 #endif
2252 }
2253
2254 char *tab_depth(int depth)
2255 {
2256         static pstring spaces;
2257         memset(spaces, ' ', depth * 4);
2258         spaces[depth * 4] = 0;
2259         return spaces;
2260 }
2261
2262 /*****************************************************************************
2263  Provide a checksum on a string
2264
2265  Input:  s - the null-terminated character string for which the checksum
2266              will be calculated.
2267
2268   Output: The checksum value calculated for s.
2269 *****************************************************************************/
2270
2271 int str_checksum(const char *s)
2272 {
2273         int res = 0;
2274         int c;
2275         int i=0;
2276         
2277         while(*s) {
2278                 c = *s;
2279                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2280                 s++;
2281                 i++;
2282         }
2283         return(res);
2284 }
2285
2286 /*****************************************************************
2287  Zero a memory area then free it. Used to catch bugs faster.
2288 *****************************************************************/  
2289
2290 void zero_free(void *p, size_t size)
2291 {
2292         memset(p, 0, size);
2293         SAFE_FREE(p);
2294 }
2295
2296 /*****************************************************************
2297  Set our open file limit to a requested max and return the limit.
2298 *****************************************************************/  
2299
2300 int set_maxfiles(int requested_max)
2301 {
2302 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2303         struct rlimit rlp;
2304         int saved_current_limit;
2305
2306         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2307                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2308                         strerror(errno) ));
2309                 /* just guess... */
2310                 return requested_max;
2311         }
2312
2313         /* 
2314          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2315          * account for the extra fd we need 
2316          * as well as the log files and standard
2317          * handles etc. Save the limit we want to set in case
2318          * we are running on an OS that doesn't support this limit (AIX)
2319          * which always returns RLIM_INFINITY for rlp.rlim_max.
2320          */
2321
2322         /* Try raising the hard (max) limit to the requested amount. */
2323
2324 #if defined(RLIM_INFINITY)
2325         if (rlp.rlim_max != RLIM_INFINITY) {
2326                 int orig_max = rlp.rlim_max;
2327
2328                 if ( rlp.rlim_max < requested_max )
2329                         rlp.rlim_max = requested_max;
2330
2331                 /* This failing is not an error - many systems (Linux) don't
2332                         support our default request of 10,000 open files. JRA. */
2333
2334                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2335                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
2336                                 (int)rlp.rlim_max, strerror(errno) ));
2337
2338                         /* Set failed - restore original value from get. */
2339                         rlp.rlim_max = orig_max;
2340                 }
2341         }
2342 #endif
2343
2344         /* Now try setting the soft (current) limit. */
2345
2346         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2347
2348         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2349                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
2350                         (int)rlp.rlim_cur, strerror(errno) ));
2351                 /* just guess... */
2352                 return saved_current_limit;
2353         }
2354
2355         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2356                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2357                         strerror(errno) ));
2358                 /* just guess... */
2359                 return saved_current_limit;
2360     }
2361
2362 #if defined(RLIM_INFINITY)
2363         if(rlp.rlim_cur == RLIM_INFINITY)
2364                 return saved_current_limit;
2365 #endif
2366
2367         if((int)rlp.rlim_cur > saved_current_limit)
2368                 return saved_current_limit;
2369
2370         return rlp.rlim_cur;
2371 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2372         /*
2373          * No way to know - just guess...
2374          */
2375         return requested_max;
2376 #endif
2377 }
2378
2379 /*****************************************************************
2380  Possibly replace mkstemp if it is broken.
2381 *****************************************************************/  
2382
2383 int smb_mkstemp(char *name_template)
2384 {
2385 #if HAVE_SECURE_MKSTEMP
2386         return mkstemp(name_template);
2387 #else
2388         /* have a reasonable go at emulating it. Hope that
2389            the system mktemp() isn't completly hopeless */
2390         char *p = mktemp(name_template);
2391         if (!p)
2392                 return -1;
2393         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2394 #endif
2395 }
2396
2397 /*****************************************************************
2398  malloc that aborts with smb_panic on fail or zero size.
2399  *****************************************************************/  
2400
2401 void *smb_xmalloc_array(size_t size, unsigned int count)
2402 {
2403         void *p;
2404         if (size == 0)
2405                 smb_panic("smb_xmalloc_array: called with zero size.\n");
2406         if (count >= MAX_ALLOC_SIZE/size) {
2407                 smb_panic("smb_xmalloc: alloc size too large.\n");
2408         }
2409         if ((p = SMB_MALLOC(size*count)) == NULL) {
2410                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2411                         (unsigned long)size, (unsigned long)count));
2412                 smb_panic("smb_xmalloc_array: malloc fail.\n");
2413         }
2414         return p;
2415 }
2416
2417 /**
2418  Memdup with smb_panic on fail.
2419 **/
2420
2421 void *smb_xmemdup(const void *p, size_t size)
2422 {
2423         void *p2;
2424         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2425         memcpy(p2, p, size);
2426         return p2;
2427 }
2428
2429 /**
2430  strdup that aborts on malloc fail.
2431 **/
2432
2433 char *smb_xstrdup(const char *s)
2434 {
2435 #if defined(PARANOID_MALLOC_CHECKER)
2436 #ifdef strdup
2437 #undef strdup
2438 #endif
2439 #endif
2440
2441 #ifndef HAVE_STRDUP
2442 #define strdup rep_strdup
2443 #endif
2444
2445         char *s1 = strdup(s);
2446 #if defined(PARANOID_MALLOC_CHECKER)
2447 #ifdef strdup
2448 #undef strdup
2449 #endif
2450 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2451 #endif
2452         if (!s1)
2453                 smb_panic("smb_xstrdup: malloc fail\n");
2454         return s1;
2455
2456 }
2457
2458 /**
2459  strndup that aborts on malloc fail.
2460 **/
2461
2462 char *smb_xstrndup(const char *s, size_t n)
2463 {
2464 #if defined(PARANOID_MALLOC_CHECKER)
2465 #ifdef strndup
2466 #undef strndup
2467 #endif
2468 #endif
2469
2470 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2471 #undef HAVE_STRNDUP
2472 #define strndup rep_strndup
2473 #endif
2474
2475         char *s1 = strndup(s, n);
2476 #if defined(PARANOID_MALLOC_CHECKER)
2477 #ifdef strndup
2478 #undef strndup
2479 #endif
2480 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2481 #endif
2482         if (!s1)
2483                 smb_panic("smb_xstrndup: malloc fail\n");
2484         return s1;
2485 }
2486
2487 /*
2488   vasprintf that aborts on malloc fail
2489 */
2490
2491  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2492 {
2493         int n;
2494         va_list ap2;
2495
2496         VA_COPY(ap2, ap);
2497
2498         n = vasprintf(ptr, format, ap2);
2499         if (n == -1 || ! *ptr)
2500                 smb_panic("smb_xvasprintf: out of memory");
2501         return n;
2502 }
2503
2504 /*****************************************************************
2505  Like strdup but for memory.
2506 *****************************************************************/  
2507
2508 void *memdup(const void *p, size_t size)
2509 {
2510         void *p2;
2511         if (size == 0)
2512                 return NULL;
2513         p2 = SMB_MALLOC(size);
2514         if (!p2)
2515                 return NULL;
2516         memcpy(p2, p, size);
2517         return p2;
2518 }
2519
2520 /*****************************************************************
2521  Get local hostname and cache result.
2522 *****************************************************************/  
2523
2524 char *myhostname(void)
2525 {
2526         static pstring ret;
2527         if (ret[0] == 0)
2528                 get_myname(ret);
2529         return ret;
2530 }
2531
2532 /*****************************************************************
2533  A useful function for returning a path in the Samba lock directory.
2534 *****************************************************************/  
2535
2536 char *lock_path(const char *name)
2537 {
2538         static pstring fname;
2539
2540         pstrcpy(fname,lp_lockdir());
2541         trim_char(fname,'\0','/');
2542         
2543         if (!directory_exist(fname,NULL))
2544                 mkdir(fname,0755);
2545         
2546         pstrcat(fname,"/");
2547         pstrcat(fname,name);
2548
2549         return fname;
2550 }
2551
2552 /*****************************************************************
2553  A useful function for returning a path in the Samba pid directory.
2554 *****************************************************************/
2555
2556 char *pid_path(const char *name)
2557 {
2558         static pstring fname;
2559
2560         pstrcpy(fname,lp_piddir());
2561         trim_char(fname,'\0','/');
2562
2563         if (!directory_exist(fname,NULL))
2564                 mkdir(fname,0755);
2565
2566         pstrcat(fname,"/");
2567         pstrcat(fname,name);
2568
2569         return fname;
2570 }
2571
2572 /**
2573  * @brief Returns an absolute path to a file in the Samba lib directory.
2574  *
2575  * @param name File to find, relative to LIBDIR.
2576  *
2577  * @retval Pointer to a static #pstring containing the full path.
2578  **/
2579
2580 char *lib_path(const char *name)
2581 {
2582         static pstring fname;
2583         fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2584         return fname;
2585 }
2586
2587 /**
2588  * @brief Returns the platform specific shared library extension.
2589  *
2590  * @retval Pointer to a static #fstring containing the extension.
2591  **/
2592
2593 const char *shlib_ext(void)
2594 {
2595   return dyn_SHLIBEXT;
2596 }
2597
2598 /*******************************************************************
2599  Given a filename - get its directory name
2600  NB: Returned in static storage.  Caveats:
2601  o  Not safe in thread environment.
2602  o  Caller must not free.
2603  o  If caller wishes to preserve, they should copy.
2604 ********************************************************************/
2605
2606 char *parent_dirname(const char *path)
2607 {
2608         static pstring dirpath;
2609         char *p;
2610
2611         if (!path)
2612                 return(NULL);
2613
2614         pstrcpy(dirpath, path);
2615         p = strrchr_m(dirpath, '/');  /* Find final '/', if any */
2616         if (!p) {
2617                 pstrcpy(dirpath, ".");    /* No final "/", so dir is "." */
2618         } else {
2619                 if (p == dirpath)
2620                         ++p;    /* For root "/", leave "/" in place */
2621                 *p = '\0';
2622         }
2623         return dirpath;
2624 }
2625
2626 BOOL parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2627                            char **parent, const char **name)
2628 {
2629         char *p;
2630         ptrdiff_t len;
2631  
2632         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2633
2634         if (p == NULL) {
2635                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2636                         return False;
2637                 }
2638                 if (name) {
2639                         *name = "";
2640                 }
2641                 return True;
2642         }
2643
2644         len = p-dir;
2645
2646         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2647                 return False;
2648         }
2649         memcpy(*parent, dir, len);
2650         (*parent)[len] = '\0';
2651
2652         if (name) {
2653                 *name = p+1;
2654         }
2655         return True;
2656 }
2657
2658 /*******************************************************************
2659  Determine if a pattern contains any Microsoft wildcard characters.
2660 *******************************************************************/
2661
2662 BOOL ms_has_wild(const char *s)
2663 {
2664         char c;
2665
2666         if (lp_posix_pathnames()) {
2667                 /* With posix pathnames no characters are wild. */
2668                 return False;
2669         }
2670
2671         while ((c = *s++)) {
2672                 switch (c) {
2673                 case '*':
2674                 case '?':
2675                 case '<':
2676                 case '>':
2677                 case '"':
2678                         return True;
2679                 }
2680         }
2681         return False;
2682 }
2683
2684 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2685 {
2686         smb_ucs2_t c;
2687         if (!s) return False;
2688         while ((c = *s++)) {
2689                 switch (c) {
2690                 case UCS2_CHAR('*'):
2691                 case UCS2_CHAR('?'):
2692                 case UCS2_CHAR('<'):
2693                 case UCS2_CHAR('>'):
2694                 case UCS2_CHAR('"'):
2695                         return True;
2696                 }
2697         }
2698         return False;
2699 }
2700
2701 /*******************************************************************
2702  A wrapper that handles case sensitivity and the special handling
2703  of the ".." name.
2704 *******************************************************************/
2705
2706 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2707 {
2708         if (strcmp(string,"..") == 0)
2709                 string = ".";
2710         if (strcmp(pattern,".") == 0)
2711                 return False;
2712         
2713         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2714 }
2715
2716 /*******************************************************************
2717  A wrapper that handles case sensitivity and the special handling
2718  of the ".." name. Varient that is only called by old search code which requires
2719  pattern translation.
2720 *******************************************************************/
2721
2722 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2723 {
2724         if (strcmp(string,"..") == 0)
2725                 string = ".";
2726         if (strcmp(pattern,".") == 0)
2727                 return False;
2728         
2729         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2730 }
2731
2732 /*******************************************************************
2733  A wrapper that handles a list of patters and calls mask_match()
2734  on each.  Returns True if any of the patterns match.
2735 *******************************************************************/
2736
2737 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2738 {
2739        while (listLen-- > 0) {
2740                if (mask_match(string, *list++, is_case_sensitive))
2741                        return True;
2742        }
2743        return False;
2744 }
2745
2746 /*********************************************************
2747  Recursive routine that is called by unix_wild_match.
2748 *********************************************************/
2749
2750 static BOOL unix_do_match(const char *regexp, const char *str)
2751 {
2752         const char *p;
2753
2754         for( p = regexp; *p && *str; ) {
2755
2756                 switch(*p) {
2757                         case '?':
2758                                 str++;
2759                                 p++;
2760                                 break;
2761
2762                         case '*':
2763
2764                                 /*
2765                                  * Look for a character matching 
2766                                  * the one after the '*'.
2767                                  */
2768                                 p++;
2769                                 if(!*p)
2770                                         return True; /* Automatic match */
2771                                 while(*str) {
2772
2773                                         while(*str && (*p != *str))
2774                                                 str++;
2775
2776                                         /*
2777                                          * Patch from weidel@multichart.de. In the case of the regexp
2778                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2779                                          * in the string after the '*' for a match to be made.
2780                                          */
2781
2782                                         {
2783                                                 int matchcount=0;
2784
2785                                                 /*
2786                                                  * Eat all the characters that match, but count how many there were.
2787                                                  */
2788
2789                                                 while(*str && (*p == *str)) {
2790                                                         str++;
2791                                                         matchcount++;
2792                                                 }
2793
2794                                                 /*
2795                                                  * Now check that if the regexp had n identical characters that
2796                                                  * matchcount had at least that many matches.
2797                                                  */
2798
2799                                                 while ( *(p+1) && (*(p+1) == *p)) {
2800                                                         p++;
2801                                                         matchcount--;
2802                                                 }
2803
2804                                                 if ( matchcount <= 0 )
2805                                                         return False;
2806                                         }
2807
2808                                         str--; /* We've eaten the match char after the '*' */
2809
2810                                         if(unix_do_match(p, str))
2811                                                 return True;
2812
2813                                         if(!*str)
2814                                                 return False;
2815                                         else
2816                                                 str++;
2817                                 }
2818                                 return False;
2819
2820                         default:
2821                                 if(*str != *p)
2822                                         return False;
2823                                 str++;
2824                                 p++;
2825                                 break;
2826                 }
2827         }
2828
2829         if(!*p && !*str)
2830                 return True;
2831
2832         if (!*p && str[0] == '.' && str[1] == 0)
2833                 return(True);
2834   
2835         if (!*str && *p == '?') {
2836                 while (*p == '?')
2837                         p++;
2838                 return(!*p);
2839         }
2840
2841         if(!*str && (*p == '*' && p[1] == '\0'))
2842                 return True;
2843
2844         return False;
2845 }
2846
2847 /*******************************************************************
2848  Simple case insensitive interface to a UNIX wildcard matcher.
2849  Returns True if match, False if not.
2850 *******************************************************************/
2851
2852 BOOL unix_wild_match(const char *pattern, const char *string)
2853 {
2854         pstring p2, s2;
2855         char *p;
2856
2857         pstrcpy(p2, pattern);
2858         pstrcpy(s2, string);
2859         strlower_m(p2);
2860         strlower_m(s2);
2861
2862         /* Remove any *? and ** from the pattern as they are meaningless */
2863         for(p = p2; *p; p++)
2864                 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2865                         pstrcpy( &p[1], &p[2]);
2866  
2867         if (strequal(p2,"*"))
2868                 return True;
2869
2870         return unix_do_match(p2, s2);
2871 }
2872
2873 /**********************************************************************
2874  Converts a name to a fully qalified domain name.
2875 ***********************************************************************/
2876                                                                                                                                                    
2877 void name_to_fqdn(fstring fqdn, const char *name)
2878 {
2879         struct hostent *hp = sys_gethostbyname(name);
2880
2881         if ( hp && hp->h_name && *hp->h_name ) {
2882                 char *full = NULL;
2883
2884                 /* find out if the fqdn is returned as an alias
2885                  * to cope with /etc/hosts files where the first
2886                  * name is not the fqdn but the short name */
2887                 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2888                         int i;
2889                         for (i = 0; hp->h_aliases[i]; i++) {
2890                                 if (strchr_m(hp->h_aliases[i], '.')) {
2891                                         full = hp->h_aliases[i];
2892                                         break;
2893                                 }
2894                         }
2895                 }
2896                 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2897                         DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2898                         DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2899                         DEBUGADD(1, ("    to Kerberos authentication probelms as localhost.localdomain\n"));
2900                         DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2901                         full = hp->h_name;
2902                 }
2903                         
2904                 if (!full) {
2905                         full = hp->h_name;
2906                 }
2907
2908                 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2909                 fstrcpy(fqdn, full);
2910         } else {
2911                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2912                 fstrcpy(fqdn, name);
2913         }
2914 }
2915
2916 /**********************************************************************
2917  Extension to talloc_get_type: Abort on type mismatch
2918 ***********************************************************************/
2919
2920 void *talloc_check_name_abort(const void *ptr, const char *name)
2921 {
2922         void *result;
2923
2924         result = talloc_check_name(ptr, name);
2925         if (result != NULL)
2926                 return result;
2927
2928         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2929                   name, talloc_get_name(ptr)));
2930         smb_panic("aborting");
2931         /* Keep the compiler happy */
2932         return NULL;
2933 }
2934
2935
2936 #ifdef __INSURE__
2937
2938 /*******************************************************************
2939 This routine is a trick to immediately catch errors when debugging
2940 with insure. A xterm with a gdb is popped up when insure catches
2941 a error. It is Linux specific.
2942 ********************************************************************/
2943
2944 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2945 {
2946         static int (*fn)();
2947         int ret;
2948         char pidstr[10];
2949         /* you can get /usr/bin/backtrace from 
2950            http://samba.org/ftp/unpacked/junkcode/backtrace */
2951         pstring cmd = "/usr/bin/backtrace %d";
2952
2953         slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2954         pstring_sub(cmd, "%d", pidstr);
2955
2956         if (!fn) {
2957                 static void *h;
2958                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2959                 fn = dlsym(h, "_Insure_trap_error");
2960
2961                 if (!h || h == _Insure_trap_error) {
2962                         h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2963                         fn = dlsym(h, "_Insure_trap_error");
2964                 }               
2965         }
2966
2967         ret = fn(a1, a2, a3, a4, a5, a6);
2968
2969         system(cmd);
2970
2971         return ret;
2972 }
2973 #endif
2974
2975 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2976 {
2977         switch (share_access & ~FILE_SHARE_DELETE) {
2978                 case FILE_SHARE_NONE:
2979                         return DENY_ALL;
2980                 case FILE_SHARE_READ:
2981                         return DENY_WRITE;
2982                 case FILE_SHARE_WRITE:
2983                         return DENY_READ;
2984                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2985                         return DENY_NONE;
2986         }
2987         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2988                 return DENY_DOS;
2989         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2990                 return DENY_FCB;
2991         }
2992
2993         return (uint32)-1;
2994 }
2995
2996 pid_t procid_to_pid(const struct process_id *proc)
2997 {
2998         return proc->pid;
2999 }
3000
3001 struct process_id pid_to_procid(pid_t pid)
3002 {
3003         struct process_id result;
3004         result.pid = pid;
3005         return result;
3006 }
3007
3008 struct process_id procid_self(void)
3009 {
3010         return pid_to_procid(sys_getpid());
3011 }
3012
3013 struct server_id server_id_self(void)
3014 {
3015         struct server_id id;
3016         id.id = procid_self();
3017         return id;
3018 }
3019
3020 BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
3021 {
3022         return (p1->pid == p2->pid);
3023 }
3024
3025 BOOL cluster_id_equal(const struct server_id *id1,
3026                       const struct server_id *id2)
3027 {
3028         return procid_equal(&id1->id, &id2->id);
3029 }
3030
3031 BOOL procid_is_me(const struct process_id *pid)
3032 {
3033         return (pid->pid == sys_getpid());
3034 }
3035
3036 struct process_id interpret_pid(const char *pid_string)
3037 {
3038         return pid_to_procid(atoi(pid_string));
3039 }
3040
3041 char *procid_str_static(const struct process_id *pid)
3042 {
3043         static fstring str;
3044         fstr_sprintf(str, "%d", pid->pid);
3045         return str;
3046 }
3047
3048 char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
3049 {
3050         return talloc_strdup(mem_ctx, procid_str_static(pid));
3051 }
3052
3053 BOOL procid_valid(const struct process_id *pid)
3054 {
3055         return (pid->pid != -1);
3056 }
3057
3058 BOOL procid_is_local(const struct process_id *pid)
3059 {
3060         return True;
3061 }
3062
3063 int this_is_smp(void)
3064 {
3065 #if defined(HAVE_SYSCONF)
3066
3067 #if defined(SYSCONF_SC_NPROC_ONLN)
3068         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3069 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3070         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3071 #else
3072         return 0;
3073 #endif
3074
3075 #else
3076         return 0;
3077 #endif
3078 }