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