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