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