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