[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[sfrench/samba-autobuild/.git] / source3 / 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         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 talloc_strdup(talloc_tos(), 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 smb packet.
519 ********************************************************************/
520
521 void smb_setlen(char *buf,int len)
522 {
523         _smb_setlen(buf,len);
524
525         SCVAL(buf,4,0xFF);
526         SCVAL(buf,5,'S');
527         SCVAL(buf,6,'M');
528         SCVAL(buf,7,'B');
529 }
530
531 /*******************************************************************
532  Setup the word count and byte count for a smb message.
533 ********************************************************************/
534
535 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
536 {
537         if (zero && (num_words || num_bytes)) {
538                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
539         }
540         SCVAL(buf,smb_wct,num_words);
541         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
542         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
543         return (smb_size + num_words*2 + num_bytes);
544 }
545
546 /*******************************************************************
547  Setup only the byte count for a smb message.
548 ********************************************************************/
549
550 int set_message_bcc(char *buf,int num_bytes)
551 {
552         int num_words = CVAL(buf,smb_wct);
553         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);  
554         smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
555         return (smb_size + num_words*2 + num_bytes);
556 }
557
558 /*******************************************************************
559  Setup only the byte count for a smb message, using the end of the
560  message as a marker.
561 ********************************************************************/
562
563 int set_message_end(void *outbuf,void *end_ptr)
564 {
565         return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
566 }
567
568 /*******************************************************************
569  Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
570  Return the bytes added
571 ********************************************************************/
572
573 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
574 {
575         size_t newlen = smb_len(*outbuf) + 4 + blob.length;
576         uint8 *tmp;
577
578         if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
579                 DEBUG(0, ("talloc failed\n"));
580                 return -1;
581         }
582         *outbuf = tmp;
583
584         memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
585         set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
586         return blob.length;
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         fstring 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                 return True;
1260         }
1261
1262         return False;
1263 }
1264
1265 /****************************************************************************
1266  Interpret a protocol description string, with a default.
1267 ****************************************************************************/
1268
1269 int interpret_protocol(const char *str,int def)
1270 {
1271         if (strequal(str,"NT1"))
1272                 return(PROTOCOL_NT1);
1273         if (strequal(str,"LANMAN2"))
1274                 return(PROTOCOL_LANMAN2);
1275         if (strequal(str,"LANMAN1"))
1276                 return(PROTOCOL_LANMAN1);
1277         if (strequal(str,"CORE"))
1278                 return(PROTOCOL_CORE);
1279         if (strequal(str,"COREPLUS"))
1280                 return(PROTOCOL_COREPLUS);
1281         if (strequal(str,"CORE+"))
1282                 return(PROTOCOL_COREPLUS);
1283   
1284         DEBUG(0,("Unrecognised protocol level %s\n",str));
1285   
1286         return(def);
1287 }
1288
1289 /****************************************************************************
1290  Return true if a string could be a pure IP address.
1291 ****************************************************************************/
1292
1293 BOOL is_ipaddress(const char *str)
1294 {
1295         BOOL pure_address = True;
1296         int i;
1297   
1298         for (i=0; pure_address && str[i]; i++)
1299                 if (!(isdigit((int)str[i]) || str[i] == '.'))
1300                         pure_address = False;
1301
1302         /* Check that a pure number is not misinterpreted as an IP */
1303         pure_address = pure_address && (strchr_m(str, '.') != NULL);
1304
1305         return pure_address;
1306 }
1307
1308 /****************************************************************************
1309  Interpret an internet address or name into an IP address in 4 byte form.
1310 ****************************************************************************/
1311
1312 uint32 interpret_addr(const char *str)
1313 {
1314         struct hostent *hp;
1315         uint32 res;
1316
1317         if (strcmp(str,"0.0.0.0") == 0)
1318                 return(0);
1319         if (strcmp(str,"255.255.255.255") == 0)
1320                 return(0xFFFFFFFF);
1321
1322   /* if it's in the form of an IP address then get the lib to interpret it */
1323         if (is_ipaddress(str)) {
1324                 res = inet_addr(str);
1325         } else {
1326                 /* otherwise assume it's a network name of some sort and use 
1327                         sys_gethostbyname */
1328                 if ((hp = sys_gethostbyname(str)) == 0) {
1329                         DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1330                         return 0;
1331                 }
1332
1333                 if(hp->h_addr == NULL) {
1334                         DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1335                         return 0;
1336                 }
1337                 putip((char *)&res,(char *)hp->h_addr);
1338         }
1339
1340         if (res == (uint32)-1)
1341                 return(0);
1342
1343         return(res);
1344 }
1345
1346 /*******************************************************************
1347  A convenient addition to interpret_addr().
1348 ******************************************************************/
1349
1350 struct in_addr *interpret_addr2(const char *str)
1351 {
1352         static struct in_addr ret;
1353         uint32 a = interpret_addr(str);
1354         ret.s_addr = a;
1355         return(&ret);
1356 }
1357
1358 /*******************************************************************
1359  Check if an IP is the 0.0.0.0.
1360 ******************************************************************/
1361
1362 BOOL is_zero_ip(struct in_addr ip)
1363 {
1364         uint32 a;
1365         putip((char *)&a,(char *)&ip);
1366         return(a == 0);
1367 }
1368
1369 /*******************************************************************
1370  Set an IP to 0.0.0.0.
1371 ******************************************************************/
1372
1373 void zero_ip(struct in_addr *ip)
1374 {
1375         static BOOL init;
1376         static struct in_addr ipzero;
1377
1378         if (!init) {
1379                 ipzero = *interpret_addr2("0.0.0.0");
1380                 init = True;
1381         }
1382
1383         *ip = ipzero;
1384 }
1385
1386 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1387 /******************************************************************
1388  Remove any mount options such as -rsize=2048,wsize=2048 etc.
1389  Based on a fix from <Thomas.Hepper@icem.de>.
1390 *******************************************************************/
1391
1392 static void strip_mount_options( pstring *str)
1393 {
1394         if (**str == '-') { 
1395                 char *p = *str;
1396                 while(*p && !isspace(*p))
1397                         p++;
1398                 while(*p && isspace(*p))
1399                         p++;
1400                 if(*p) {
1401                         pstring tmp_str;
1402
1403                         pstrcpy(tmp_str, p);
1404                         pstrcpy(*str, tmp_str);
1405                 }
1406         }
1407 }
1408
1409 /*******************************************************************
1410  Patch from jkf@soton.ac.uk
1411  Split Luke's automount_server into YP lookup and string splitter
1412  so can easily implement automount_path(). 
1413  As we may end up doing both, cache the last YP result. 
1414 *******************************************************************/
1415
1416 #ifdef WITH_NISPLUS_HOME
1417 char *automount_lookup(const char *user_name)
1418 {
1419         static fstring last_key = "";
1420         static pstring last_value = "";
1421  
1422         char *nis_map = (char *)lp_nis_home_map_name();
1423  
1424         char buffer[NIS_MAXATTRVAL + 1];
1425         nis_result *result;
1426         nis_object *object;
1427         entry_obj  *entry;
1428  
1429         if (strcmp(user_name, last_key)) {
1430                 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1431                 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1432  
1433                 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1434                         if (result->status != NIS_SUCCESS) {
1435                                 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1436                                 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1437                         } else {
1438                                 object = result->objects.objects_val;
1439                                 if (object->zo_data.zo_type == ENTRY_OBJ) {
1440                                         entry = &object->zo_data.objdata_u.en_data;
1441                                         DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1442                                         DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1443  
1444                                         pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1445                                         pstring_sub(last_value, "&", user_name);
1446                                         fstrcpy(last_key, user_name);
1447                                 }
1448                         }
1449                 }
1450                 nis_freeresult(result);
1451         }
1452
1453         strip_mount_options(&last_value);
1454
1455         DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1456         return last_value;
1457 }
1458 #else /* WITH_NISPLUS_HOME */
1459
1460 char *automount_lookup(const char *user_name)
1461 {
1462         static fstring last_key = "";
1463         static pstring last_value = "";
1464
1465         int nis_error;        /* returned by yp all functions */
1466         char *nis_result;     /* yp_match inits this */
1467         int nis_result_len;  /* and set this */
1468         char *nis_domain;     /* yp_get_default_domain inits this */
1469         char *nis_map = (char *)lp_nis_home_map_name();
1470
1471         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1472                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1473                 return last_value;
1474         }
1475
1476         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1477
1478         if (!strcmp(user_name, last_key)) {
1479                 nis_result = last_value;
1480                 nis_result_len = strlen(last_value);
1481                 nis_error = 0;
1482         } else {
1483                 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1484                                 &nis_result, &nis_result_len)) == 0) {
1485                         fstrcpy(last_key, user_name);
1486                         pstrcpy(last_value, nis_result);
1487                         strip_mount_options(&last_value);
1488
1489                 } else if(nis_error == YPERR_KEY) {
1490
1491                         /* If Key lookup fails user home server is not in nis_map 
1492                                 use default information for server, and home directory */
1493                         last_value[0] = 0;
1494                         DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
1495                                         user_name, nis_map));
1496                         DEBUG(3, ("using defaults for server and home directory\n"));
1497                 } else {
1498                         DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
1499                                         yperr_string(nis_error), user_name, nis_map));
1500                 }
1501         }
1502
1503         DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1504         return last_value;
1505 }
1506 #endif /* WITH_NISPLUS_HOME */
1507 #endif
1508
1509 /*******************************************************************
1510  Are two IPs on the same subnet?
1511 ********************************************************************/
1512
1513 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1514 {
1515         uint32 net1,net2,nmask;
1516
1517         nmask = ntohl(mask.s_addr);
1518         net1  = ntohl(ip1.s_addr);
1519         net2  = ntohl(ip2.s_addr);
1520             
1521         return((net1 & nmask) == (net2 & nmask));
1522 }
1523
1524
1525 /****************************************************************************
1526  Check if a process exists. Does this work on all unixes?
1527 ****************************************************************************/
1528
1529 BOOL process_exists(const struct server_id pid)
1530 {
1531         if (procid_is_me(&pid)) {
1532                 return True;
1533         }
1534
1535         if (procid_is_local(&pid)) {
1536                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1537         }
1538
1539 #ifdef CLUSTER_SUPPORT
1540         return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1541                                     pid.pid);
1542 #else
1543         return False;
1544 #endif
1545 }
1546
1547 BOOL process_exists_by_pid(pid_t pid)
1548 {
1549         /* Doing kill with a non-positive pid causes messages to be
1550          * sent to places we don't want. */
1551         SMB_ASSERT(pid > 0);
1552         return(kill(pid,0) == 0 || errno != ESRCH);
1553 }
1554
1555 /*******************************************************************
1556  Convert a uid into a user name.
1557 ********************************************************************/
1558
1559 const char *uidtoname(uid_t uid)
1560 {
1561         TALLOC_CTX *ctx = talloc_tos();
1562         char *name = NULL;
1563         struct passwd *pass = NULL;
1564
1565         pass = getpwuid_alloc(ctx,uid);
1566         if (pass) {
1567                 name = talloc_strdup(ctx,pass->pw_name);
1568                 TALLOC_FREE(pass);
1569         } else {
1570                 name = talloc_asprintf(ctx,
1571                                 "%ld",
1572                                 (long int)uid);
1573         }
1574         return name;
1575 }
1576
1577 /*******************************************************************
1578  Convert a gid into a group name.
1579 ********************************************************************/
1580
1581 char *gidtoname(gid_t gid)
1582 {
1583         fstring name;
1584         struct group *grp;
1585
1586         grp = getgrgid(gid);
1587         if (grp) {
1588                 fstrcpy(name, grp->gr_name);
1589         }
1590         else {
1591                 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1592         }
1593         return talloc_strdup(talloc_tos(), name);
1594 }
1595
1596 /*******************************************************************
1597  Convert a user name into a uid. 
1598 ********************************************************************/
1599
1600 uid_t nametouid(const char *name)
1601 {
1602         struct passwd *pass;
1603         char *p;
1604         uid_t u;
1605
1606         pass = getpwnam_alloc(NULL, name);
1607         if (pass) {
1608                 u = pass->pw_uid;
1609                 TALLOC_FREE(pass);
1610                 return u;
1611         }
1612
1613         u = (uid_t)strtol(name, &p, 0);
1614         if ((p != name) && (*p == '\0'))
1615                 return u;
1616
1617         return (uid_t)-1;
1618 }
1619
1620 /*******************************************************************
1621  Convert a name to a gid_t if possible. Return -1 if not a group. 
1622 ********************************************************************/
1623
1624 gid_t nametogid(const char *name)
1625 {
1626         struct group *grp;
1627         char *p;
1628         gid_t g;
1629
1630         g = (gid_t)strtol(name, &p, 0);
1631         if ((p != name) && (*p == '\0'))
1632                 return g;
1633
1634         grp = sys_getgrnam(name);
1635         if (grp)
1636                 return(grp->gr_gid);
1637         return (gid_t)-1;
1638 }
1639
1640 /*******************************************************************
1641  Something really nasty happened - panic !
1642 ********************************************************************/
1643
1644 void smb_panic(const char *const why)
1645 {
1646         char *cmd;
1647         int result;
1648
1649 #ifdef DEVELOPER
1650         {
1651
1652                 if (global_clobber_region_function) {
1653                         DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1654                                          global_clobber_region_function,
1655                                          global_clobber_region_line));
1656                 } 
1657         }
1658 #endif
1659
1660         DEBUG(0,("PANIC (pid %llu): %s\n",
1661                     (unsigned long long)sys_getpid(), why));
1662         log_stack_trace();
1663
1664         cmd = lp_panic_action();
1665         if (cmd && *cmd) {
1666                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1667                 result = system(cmd);
1668
1669                 if (result == -1)
1670                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1671                                           strerror(errno)));
1672                 else
1673                         DEBUG(0, ("smb_panic(): action returned status %d\n",
1674                                           WEXITSTATUS(result)));
1675         }
1676
1677         dump_core();
1678 }
1679
1680 /*******************************************************************
1681  Print a backtrace of the stack to the debug log. This function
1682  DELIBERATELY LEAKS MEMORY. The expectation is that you should
1683  exit shortly after calling it.
1684 ********************************************************************/
1685
1686 #ifdef HAVE_LIBUNWIND_H
1687 #include <libunwind.h>
1688 #endif
1689
1690 #ifdef HAVE_EXECINFO_H
1691 #include <execinfo.h>
1692 #endif
1693
1694 #ifdef HAVE_LIBEXC_H
1695 #include <libexc.h>
1696 #endif
1697
1698 void log_stack_trace(void)
1699 {
1700 #ifdef HAVE_LIBUNWIND
1701         /* Try to use libunwind before any other technique since on ia64
1702          * libunwind correctly walks the stack in more circumstances than
1703          * backtrace.
1704          */ 
1705         unw_cursor_t cursor;
1706         unw_context_t uc;
1707         unsigned i = 0;
1708
1709         char procname[256];
1710         unw_word_t ip, sp, off;
1711
1712         procname[sizeof(procname) - 1] = '\0';
1713
1714         if (unw_getcontext(&uc) != 0) {
1715                 goto libunwind_failed;
1716         }
1717
1718         if (unw_init_local(&cursor, &uc) != 0) {
1719                 goto libunwind_failed;
1720         }
1721
1722         DEBUG(0, ("BACKTRACE:\n"));
1723
1724         do {
1725             ip = sp = 0;
1726             unw_get_reg(&cursor, UNW_REG_IP, &ip);
1727             unw_get_reg(&cursor, UNW_REG_SP, &sp);
1728
1729             switch (unw_get_proc_name(&cursor,
1730                         procname, sizeof(procname) - 1, &off) ) {
1731             case 0:
1732                     /* Name found. */
1733             case -UNW_ENOMEM:
1734                     /* Name truncated. */
1735                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1736                             i, procname, (long long)off,
1737                             (long long)ip, (long long) sp));
1738                     break;
1739             default:
1740             /* case -UNW_ENOINFO: */
1741             /* case -UNW_EUNSPEC: */
1742                     /* No symbol name found. */
1743                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1744                             i, "<unknown symbol>",
1745                             (long long)ip, (long long) sp));
1746             }
1747             ++i;
1748         } while (unw_step(&cursor) > 0);
1749
1750         return;
1751
1752 libunwind_failed:
1753         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1754
1755 #elif HAVE_BACKTRACE_SYMBOLS
1756         void *backtrace_stack[BACKTRACE_STACK_SIZE];
1757         size_t backtrace_size;
1758         char **backtrace_strings;
1759
1760         /* get the backtrace (stack frames) */
1761         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1762         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1763
1764         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1765                   (unsigned long)backtrace_size));
1766         
1767         if (backtrace_strings) {
1768                 int i;
1769
1770                 for (i = 0; i < backtrace_size; i++)
1771                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1772
1773                 /* Leak the backtrace_strings, rather than risk what free() might do */
1774         }
1775
1776 #elif HAVE_LIBEXC
1777
1778         /* The IRIX libexc library provides an API for unwinding the stack. See
1779          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1780          * since we are about to abort anyway, it hardly matters.
1781          */
1782
1783 #define NAMESIZE 32 /* Arbitrary */
1784
1785         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1786         char *          names[BACKTRACE_STACK_SIZE];
1787         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1788
1789         int             i;
1790         int             levels;
1791
1792         ZERO_ARRAY(addrs);
1793         ZERO_ARRAY(names);
1794         ZERO_ARRAY(namebuf);
1795
1796         /* We need to be root so we can open our /proc entry to walk
1797          * our stack. It also helps when we want to dump core.
1798          */
1799         become_root();
1800
1801         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1802                 names[i] = namebuf + (i * NAMESIZE);
1803         }
1804
1805         levels = trace_back_stack(0, addrs, names,
1806                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1807
1808         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1809         for (i = 0; i < levels; i++) {
1810                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1811         }
1812 #undef NAMESIZE
1813
1814 #else
1815         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1816 #endif
1817 }
1818
1819 /*******************************************************************
1820   A readdir wrapper which just returns the file name.
1821  ********************************************************************/
1822
1823 const char *readdirname(SMB_STRUCT_DIR *p)
1824 {
1825         SMB_STRUCT_DIRENT *ptr;
1826         char *dname;
1827
1828         if (!p)
1829                 return(NULL);
1830   
1831         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1832         if (!ptr)
1833                 return(NULL);
1834
1835         dname = ptr->d_name;
1836
1837 #ifdef NEXT2
1838         if (telldir(p) < 0)
1839                 return(NULL);
1840 #endif
1841
1842 #ifdef HAVE_BROKEN_READDIR_NAME
1843         /* using /usr/ucb/cc is BAD */
1844         dname = dname - 2;
1845 #endif
1846
1847         return talloc_strdup(talloc_tos(), dname);
1848 }
1849
1850 /*******************************************************************
1851  Utility function used to decide if the last component 
1852  of a path matches a (possibly wildcarded) entry in a namelist.
1853 ********************************************************************/
1854
1855 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1856 {
1857         const char *last_component;
1858
1859         /* if we have no list it's obviously not in the path */
1860         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1861                 return False;
1862         }
1863
1864         DEBUG(8, ("is_in_path: %s\n", name));
1865
1866         /* Get the last component of the unix name. */
1867         last_component = strrchr_m(name, '/');
1868         if (!last_component) {
1869                 last_component = name;
1870         } else {
1871                 last_component++; /* Go past '/' */
1872         }
1873
1874         for(; namelist->name != NULL; namelist++) {
1875                 if(namelist->is_wild) {
1876                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1877                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1878                                 return True;
1879                         }
1880                 } else {
1881                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1882                                                 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1883                                 DEBUG(8,("is_in_path: match succeeded\n"));
1884                                 return True;
1885                         }
1886                 }
1887         }
1888         DEBUG(8,("is_in_path: match not found\n"));
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].iface_addr.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 *buf1,int len)
2279 {
2280         const unsigned char *buf = (const unsigned char *)buf1;
2281         int i=0;
2282         if (len<=0) return;
2283
2284         if (!DEBUGLVL(level)) return;
2285         
2286         DEBUGADD(level,("[%03X] ",i));
2287         for (i=0;i<len;) {
2288                 DEBUGADD(level,("%02X ",(int)buf[i]));
2289                 i++;
2290                 if (i%8 == 0) DEBUGADD(level,(" "));
2291                 if (i%16 == 0) {      
2292                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2293                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2294                         if (i<len) DEBUGADD(level,("[%03X] ",i));
2295                 }
2296         }
2297         if (i%16) {
2298                 int n;
2299                 n = 16 - (i%16);
2300                 DEBUGADD(level,(" "));
2301                 if (n>8) DEBUGADD(level,(" "));
2302                 while (n--) DEBUGADD(level,("   "));
2303                 n = MIN(8,i%16);
2304                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2305                 n = (i%16) - n;
2306                 if (n>0) print_asc(level,&buf[i-n],n); 
2307                 DEBUGADD(level,("\n"));    
2308         }       
2309 }
2310
2311 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2312 {
2313 #ifdef DEBUG_PASSWORD
2314         DEBUG(11, ("%s", msg));
2315         if (data != NULL && len > 0)
2316         {
2317                 dump_data(11, data, len);
2318         }
2319 #endif
2320 }
2321
2322 char *tab_depth(int depth)
2323 {
2324         static pstring spaces;
2325         memset(spaces, ' ', depth * 4);
2326         spaces[depth * 4] = 0;
2327         return spaces;
2328 }
2329
2330 /*****************************************************************************
2331  Provide a checksum on a string
2332
2333  Input:  s - the null-terminated character string for which the checksum
2334              will be calculated.
2335
2336   Output: The checksum value calculated for s.
2337 *****************************************************************************/
2338
2339 int str_checksum(const char *s)
2340 {
2341         int res = 0;
2342         int c;
2343         int i=0;
2344         
2345         while(*s) {
2346                 c = *s;
2347                 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2348                 s++;
2349                 i++;
2350         }
2351         return(res);
2352 }
2353
2354 /*****************************************************************
2355  Zero a memory area then free it. Used to catch bugs faster.
2356 *****************************************************************/  
2357
2358 void zero_free(void *p, size_t size)
2359 {
2360         memset(p, 0, size);
2361         SAFE_FREE(p);
2362 }
2363
2364 /*****************************************************************
2365  Set our open file limit to a requested max and return the limit.
2366 *****************************************************************/  
2367
2368 int set_maxfiles(int requested_max)
2369 {
2370 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2371         struct rlimit rlp;
2372         int saved_current_limit;
2373
2374         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2375                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2376                         strerror(errno) ));
2377                 /* just guess... */
2378                 return requested_max;
2379         }
2380
2381         /* 
2382          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2383          * account for the extra fd we need 
2384          * as well as the log files and standard
2385          * handles etc. Save the limit we want to set in case
2386          * we are running on an OS that doesn't support this limit (AIX)
2387          * which always returns RLIM_INFINITY for rlp.rlim_max.
2388          */
2389
2390         /* Try raising the hard (max) limit to the requested amount. */
2391
2392 #if defined(RLIM_INFINITY)
2393         if (rlp.rlim_max != RLIM_INFINITY) {
2394                 int orig_max = rlp.rlim_max;
2395
2396                 if ( rlp.rlim_max < requested_max )
2397                         rlp.rlim_max = requested_max;
2398
2399                 /* This failing is not an error - many systems (Linux) don't
2400                         support our default request of 10,000 open files. JRA. */
2401
2402                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2403                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
2404                                 (int)rlp.rlim_max, strerror(errno) ));
2405
2406                         /* Set failed - restore original value from get. */
2407                         rlp.rlim_max = orig_max;
2408                 }
2409         }
2410 #endif
2411
2412         /* Now try setting the soft (current) limit. */
2413
2414         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2415
2416         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2417                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
2418                         (int)rlp.rlim_cur, strerror(errno) ));
2419                 /* just guess... */
2420                 return saved_current_limit;
2421         }
2422
2423         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2424                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2425                         strerror(errno) ));
2426                 /* just guess... */
2427                 return saved_current_limit;
2428     }
2429
2430 #if defined(RLIM_INFINITY)
2431         if(rlp.rlim_cur == RLIM_INFINITY)
2432                 return saved_current_limit;
2433 #endif
2434
2435         if((int)rlp.rlim_cur > saved_current_limit)
2436                 return saved_current_limit;
2437
2438         return rlp.rlim_cur;
2439 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2440         /*
2441          * No way to know - just guess...
2442          */
2443         return requested_max;
2444 #endif
2445 }
2446
2447 /*****************************************************************
2448  Possibly replace mkstemp if it is broken.
2449 *****************************************************************/  
2450
2451 int smb_mkstemp(char *name_template)
2452 {
2453 #if HAVE_SECURE_MKSTEMP
2454         return mkstemp(name_template);
2455 #else
2456         /* have a reasonable go at emulating it. Hope that
2457            the system mktemp() isn't completly hopeless */
2458         char *p = mktemp(name_template);
2459         if (!p)
2460                 return -1;
2461         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2462 #endif
2463 }
2464
2465 /*****************************************************************
2466  malloc that aborts with smb_panic on fail or zero size.
2467  *****************************************************************/  
2468
2469 void *smb_xmalloc_array(size_t size, unsigned int count)
2470 {
2471         void *p;
2472         if (size == 0) {
2473                 smb_panic("smb_xmalloc_array: called with zero size");
2474         }
2475         if (count >= MAX_ALLOC_SIZE/size) {
2476                 smb_panic("smb_xmalloc_array: alloc size too large");
2477         }
2478         if ((p = SMB_MALLOC(size*count)) == NULL) {
2479                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2480                         (unsigned long)size, (unsigned long)count));
2481                 smb_panic("smb_xmalloc_array: malloc failed");
2482         }
2483         return p;
2484 }
2485
2486 /**
2487  Memdup with smb_panic on fail.
2488 **/
2489
2490 void *smb_xmemdup(const void *p, size_t size)
2491 {
2492         void *p2;
2493         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2494         memcpy(p2, p, size);
2495         return p2;
2496 }
2497
2498 /**
2499  strdup that aborts on malloc fail.
2500 **/
2501
2502 char *smb_xstrdup(const char *s)
2503 {
2504 #if defined(PARANOID_MALLOC_CHECKER)
2505 #ifdef strdup
2506 #undef strdup
2507 #endif
2508 #endif
2509
2510 #ifndef HAVE_STRDUP
2511 #define strdup rep_strdup
2512 #endif
2513
2514         char *s1 = strdup(s);
2515 #if defined(PARANOID_MALLOC_CHECKER)
2516 #ifdef strdup
2517 #undef strdup
2518 #endif
2519 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2520 #endif
2521         if (!s1) {
2522                 smb_panic("smb_xstrdup: malloc failed");
2523         }
2524         return s1;
2525
2526 }
2527
2528 /**
2529  strndup that aborts on malloc fail.
2530 **/
2531
2532 char *smb_xstrndup(const char *s, size_t n)
2533 {
2534 #if defined(PARANOID_MALLOC_CHECKER)
2535 #ifdef strndup
2536 #undef strndup
2537 #endif
2538 #endif
2539
2540 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2541 #undef HAVE_STRNDUP
2542 #define strndup rep_strndup
2543 #endif
2544
2545         char *s1 = strndup(s, n);
2546 #if defined(PARANOID_MALLOC_CHECKER)
2547 #ifdef strndup
2548 #undef strndup
2549 #endif
2550 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2551 #endif
2552         if (!s1) {
2553                 smb_panic("smb_xstrndup: malloc failed");
2554         }
2555         return s1;
2556 }
2557
2558 /*
2559   vasprintf that aborts on malloc fail
2560 */
2561
2562  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2563 {
2564         int n;
2565         va_list ap2;
2566
2567         VA_COPY(ap2, ap);
2568
2569         n = vasprintf(ptr, format, ap2);
2570         if (n == -1 || ! *ptr) {
2571                 smb_panic("smb_xvasprintf: out of memory");
2572         }
2573         return n;
2574 }
2575
2576 /*****************************************************************
2577  Like strdup but for memory.
2578 *****************************************************************/  
2579
2580 void *memdup(const void *p, size_t size)
2581 {
2582         void *p2;
2583         if (size == 0)
2584                 return NULL;
2585         p2 = SMB_MALLOC(size);
2586         if (!p2)
2587                 return NULL;
2588         memcpy(p2, p, size);
2589         return p2;
2590 }
2591
2592 /*****************************************************************
2593  Get local hostname and cache result.
2594 *****************************************************************/  
2595
2596 char *myhostname(void)
2597 {
2598         static pstring ret;
2599         if (ret[0] == 0)
2600                 get_myname(ret);
2601         return ret;
2602 }
2603
2604 /*****************************************************************
2605  A useful function for returning a path in the Samba lock directory.
2606 *****************************************************************/  
2607
2608 char *lock_path(const char *name)
2609 {
2610         pstring fname;
2611
2612         pstrcpy(fname,lp_lockdir());
2613         trim_char(fname,'\0','/');
2614         
2615         if (!directory_exist(fname,NULL))
2616                 mkdir(fname,0755);
2617         
2618         pstrcat(fname,"/");
2619         pstrcat(fname,name);
2620
2621         return talloc_strdup(talloc_tos(), fname);
2622 }
2623
2624 /*****************************************************************
2625  A useful function for returning a path in the Samba pid directory.
2626 *****************************************************************/
2627
2628 char *pid_path(const char *name)
2629 {
2630         pstring fname;
2631
2632         pstrcpy(fname,lp_piddir());
2633         trim_char(fname,'\0','/');
2634
2635         if (!directory_exist(fname,NULL))
2636                 mkdir(fname,0755);
2637
2638         pstrcat(fname,"/");
2639         pstrcat(fname,name);
2640
2641         return talloc_strdup(talloc_tos(), fname);
2642 }
2643
2644 /**
2645  * @brief Returns an absolute path to a file in the Samba lib directory.
2646  *
2647  * @param name File to find, relative to LIBDIR.
2648  *
2649  * @retval Pointer to a static #pstring containing the full path.
2650  **/
2651
2652 char *lib_path(const char *name)
2653 {
2654         return talloc_asprintf(talloc_tos(), "%s/%s", dyn_LIBDIR, name);
2655 }
2656
2657 /**
2658  * @brief Returns the platform specific shared library extension.
2659  *
2660  * @retval Pointer to a static #fstring containing the extension.
2661  **/
2662
2663 const char *shlib_ext(void)
2664 {
2665   return dyn_SHLIBEXT;
2666 }
2667
2668 /*******************************************************************
2669  Given a filename - get its directory name
2670  NB: Returned in static storage.  Caveats:
2671  o  If caller wishes to preserve, they should copy.
2672 ********************************************************************/
2673
2674 char *parent_dirname(const char *path)
2675 {
2676         char *parent;
2677
2678         if (!parent_dirname_talloc(talloc_tos(), path, &parent, NULL)) {
2679                 return NULL;
2680         }
2681
2682         return parent;
2683 }
2684
2685 BOOL parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2686                            char **parent, const char **name)
2687 {
2688         char *p;
2689         ptrdiff_t len;
2690  
2691         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2692
2693         if (p == NULL) {
2694                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2695                         return False;
2696                 }
2697                 if (name) {
2698                         *name = "";
2699                 }
2700                 return True;
2701         }
2702
2703         len = p-dir;
2704
2705         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2706                 return False;
2707         }
2708         memcpy(*parent, dir, len);
2709         (*parent)[len] = '\0';
2710
2711         if (name) {
2712                 *name = p+1;
2713         }
2714         return True;
2715 }
2716
2717 /*******************************************************************
2718  Determine if a pattern contains any Microsoft wildcard characters.
2719 *******************************************************************/
2720
2721 BOOL ms_has_wild(const char *s)
2722 {
2723         char c;
2724
2725         if (lp_posix_pathnames()) {
2726                 /* With posix pathnames no characters are wild. */
2727                 return False;
2728         }
2729
2730         while ((c = *s++)) {
2731                 switch (c) {
2732                 case '*':
2733                 case '?':
2734                 case '<':
2735                 case '>':
2736                 case '"':
2737                         return True;
2738                 }
2739         }
2740         return False;
2741 }
2742
2743 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2744 {
2745         smb_ucs2_t c;
2746         if (!s) return False;
2747         while ((c = *s++)) {
2748                 switch (c) {
2749                 case UCS2_CHAR('*'):
2750                 case UCS2_CHAR('?'):
2751                 case UCS2_CHAR('<'):
2752                 case UCS2_CHAR('>'):
2753                 case UCS2_CHAR('"'):
2754                         return True;
2755                 }
2756         }
2757         return False;
2758 }
2759
2760 /*******************************************************************
2761  A wrapper that handles case sensitivity and the special handling
2762  of the ".." name.
2763 *******************************************************************/
2764
2765 BOOL mask_match(const char *string, const char *pattern, BOOL is_case_sensitive)
2766 {
2767         if (strcmp(string,"..") == 0)
2768                 string = ".";
2769         if (strcmp(pattern,".") == 0)
2770                 return False;
2771         
2772         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2773 }
2774
2775 /*******************************************************************
2776  A wrapper that handles case sensitivity and the special handling
2777  of the ".." name. Varient that is only called by old search code which requires
2778  pattern translation.
2779 *******************************************************************/
2780
2781 BOOL mask_match_search(const char *string, const char *pattern, BOOL is_case_sensitive)
2782 {
2783         if (strcmp(string,"..") == 0)
2784                 string = ".";
2785         if (strcmp(pattern,".") == 0)
2786                 return False;
2787         
2788         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2789 }
2790
2791 /*******************************************************************
2792  A wrapper that handles a list of patters and calls mask_match()
2793  on each.  Returns True if any of the patterns match.
2794 *******************************************************************/
2795
2796 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2797 {
2798        while (listLen-- > 0) {
2799                if (mask_match(string, *list++, is_case_sensitive))
2800                        return True;
2801        }
2802        return False;
2803 }
2804
2805 /*********************************************************
2806  Recursive routine that is called by unix_wild_match.
2807 *********************************************************/
2808
2809 static BOOL unix_do_match(const char *regexp, const char *str)
2810 {
2811         const char *p;
2812
2813         for( p = regexp; *p && *str; ) {
2814
2815                 switch(*p) {
2816                         case '?':
2817                                 str++;
2818                                 p++;
2819                                 break;
2820
2821                         case '*':
2822
2823                                 /*
2824                                  * Look for a character matching 
2825                                  * the one after the '*'.
2826                                  */
2827                                 p++;
2828                                 if(!*p)
2829                                         return True; /* Automatic match */
2830                                 while(*str) {
2831
2832                                         while(*str && (*p != *str))
2833                                                 str++;
2834
2835                                         /*
2836                                          * Patch from weidel@multichart.de. In the case of the regexp
2837                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2838                                          * in the string after the '*' for a match to be made.
2839                                          */
2840
2841                                         {
2842                                                 int matchcount=0;
2843
2844                                                 /*
2845                                                  * Eat all the characters that match, but count how many there were.
2846                                                  */
2847
2848                                                 while(*str && (*p == *str)) {
2849                                                         str++;
2850                                                         matchcount++;
2851                                                 }
2852
2853                                                 /*
2854                                                  * Now check that if the regexp had n identical characters that
2855                                                  * matchcount had at least that many matches.
2856                                                  */
2857
2858                                                 while ( *(p+1) && (*(p+1) == *p)) {
2859                                                         p++;
2860                                                         matchcount--;
2861                                                 }
2862
2863                                                 if ( matchcount <= 0 )
2864                                                         return False;
2865                                         }
2866
2867                                         str--; /* We've eaten the match char after the '*' */
2868
2869                                         if(unix_do_match(p, str))
2870                                                 return True;
2871
2872                                         if(!*str)
2873                                                 return False;
2874                                         else
2875                                                 str++;
2876                                 }
2877                                 return False;
2878
2879                         default:
2880                                 if(*str != *p)
2881                                         return False;
2882                                 str++;
2883                                 p++;
2884                                 break;
2885                 }
2886         }
2887
2888         if(!*p && !*str)
2889                 return True;
2890
2891         if (!*p && str[0] == '.' && str[1] == 0)
2892                 return(True);
2893   
2894         if (!*str && *p == '?') {
2895                 while (*p == '?')
2896                         p++;
2897                 return(!*p);
2898         }
2899
2900         if(!*str && (*p == '*' && p[1] == '\0'))
2901                 return True;
2902
2903         return False;
2904 }
2905
2906 /*******************************************************************
2907  Simple case insensitive interface to a UNIX wildcard matcher.
2908  Returns True if match, False if not.
2909 *******************************************************************/
2910
2911 BOOL unix_wild_match(const char *pattern, const char *string)
2912 {
2913         pstring p2, s2;
2914         char *p;
2915
2916         pstrcpy(p2, pattern);
2917         pstrcpy(s2, string);
2918         strlower_m(p2);
2919         strlower_m(s2);
2920
2921         /* Remove any *? and ** from the pattern as they are meaningless */
2922         for(p = p2; *p; p++)
2923                 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2924                         pstrcpy( &p[1], &p[2]);
2925  
2926         if (strequal(p2,"*"))
2927                 return True;
2928
2929         return unix_do_match(p2, s2);
2930 }
2931
2932 /**********************************************************************
2933  Converts a name to a fully qualified domain name.
2934  Returns True if lookup succeeded, False if not (then fqdn is set to name)
2935 ***********************************************************************/
2936                                                                                                                                                    
2937 BOOL name_to_fqdn(fstring fqdn, const char *name)
2938 {
2939         struct hostent *hp = sys_gethostbyname(name);
2940
2941         if ( hp && hp->h_name && *hp->h_name ) {
2942                 char *full = NULL;
2943
2944                 /* find out if the fqdn is returned as an alias
2945                  * to cope with /etc/hosts files where the first
2946                  * name is not the fqdn but the short name */
2947                 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2948                         int i;
2949                         for (i = 0; hp->h_aliases[i]; i++) {
2950                                 if (strchr_m(hp->h_aliases[i], '.')) {
2951                                         full = hp->h_aliases[i];
2952                                         break;
2953                                 }
2954                         }
2955                 }
2956                 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2957                         DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2958                         DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2959                         DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2960                         DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2961                         full = hp->h_name;
2962                 }
2963                         
2964                 if (!full) {
2965                         full = hp->h_name;
2966                 }
2967
2968                 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2969                 fstrcpy(fqdn, full);
2970                 return True;
2971         } else {
2972                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2973                 fstrcpy(fqdn, name);
2974                 return False;
2975         }
2976 }
2977
2978 /**********************************************************************
2979  Extension to talloc_get_type: Abort on type mismatch
2980 ***********************************************************************/
2981
2982 void *talloc_check_name_abort(const void *ptr, const char *name)
2983 {
2984         void *result;
2985
2986         result = talloc_check_name(ptr, name);
2987         if (result != NULL)
2988                 return result;
2989
2990         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2991                   name, talloc_get_name(ptr)));
2992         smb_panic("talloc type mismatch");
2993         /* Keep the compiler happy */
2994         return NULL;
2995 }
2996
2997
2998 #ifdef __INSURE__
2999
3000 /*******************************************************************
3001 This routine is a trick to immediately catch errors when debugging
3002 with insure. A xterm with a gdb is popped up when insure catches
3003 a error. It is Linux specific.
3004 ********************************************************************/
3005
3006 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
3007 {
3008         static int (*fn)();
3009         int ret;
3010         char pidstr[10];
3011         /* you can get /usr/bin/backtrace from 
3012            http://samba.org/ftp/unpacked/junkcode/backtrace */
3013         pstring cmd = "/usr/bin/backtrace %d";
3014
3015         slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
3016         pstring_sub(cmd, "%d", pidstr);
3017
3018         if (!fn) {
3019                 static void *h;
3020                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
3021                 fn = dlsym(h, "_Insure_trap_error");
3022
3023                 if (!h || h == _Insure_trap_error) {
3024                         h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
3025                         fn = dlsym(h, "_Insure_trap_error");
3026                 }               
3027         }
3028
3029         ret = fn(a1, a2, a3, a4, a5, a6);
3030
3031         system(cmd);
3032
3033         return ret;
3034 }
3035 #endif
3036
3037 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
3038 {
3039         switch (share_access & ~FILE_SHARE_DELETE) {
3040                 case FILE_SHARE_NONE:
3041                         return DENY_ALL;
3042                 case FILE_SHARE_READ:
3043                         return DENY_WRITE;
3044                 case FILE_SHARE_WRITE:
3045                         return DENY_READ;
3046                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
3047                         return DENY_NONE;
3048         }
3049         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
3050                 return DENY_DOS;
3051         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
3052                 return DENY_FCB;
3053         }
3054
3055         return (uint32)-1;
3056 }
3057
3058 pid_t procid_to_pid(const struct server_id *proc)
3059 {
3060         return proc->pid;
3061 }
3062
3063 static uint32 my_vnn = NONCLUSTER_VNN;
3064
3065 void set_my_vnn(uint32 vnn)
3066 {
3067         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3068         my_vnn = vnn;
3069 }
3070
3071 uint32 get_my_vnn(void)
3072 {
3073         return my_vnn;
3074 }
3075
3076 struct server_id pid_to_procid(pid_t pid)
3077 {
3078         struct server_id result;
3079         result.pid = pid;
3080 #ifdef CLUSTER_SUPPORT
3081         result.vnn = my_vnn;
3082 #endif
3083         return result;
3084 }
3085
3086 struct server_id procid_self(void)
3087 {
3088         return pid_to_procid(sys_getpid());
3089 }
3090
3091 struct server_id server_id_self(void)
3092 {
3093         return procid_self();
3094 }
3095
3096 BOOL procid_equal(const struct server_id *p1, const struct server_id *p2)
3097 {
3098         if (p1->pid != p2->pid)
3099                 return False;
3100 #ifdef CLUSTER_SUPPORT
3101         if (p1->vnn != p2->vnn)
3102                 return False;
3103 #endif
3104         return True;
3105 }
3106
3107 BOOL cluster_id_equal(const struct server_id *id1,
3108                       const struct server_id *id2)
3109 {
3110         return procid_equal(id1, id2);
3111 }
3112
3113 BOOL procid_is_me(const struct server_id *pid)
3114 {
3115         if (pid->pid != sys_getpid())
3116                 return False;
3117 #ifdef CLUSTER_SUPPORT
3118         if (pid->vnn != my_vnn)
3119                 return False;
3120 #endif
3121         return True;
3122 }
3123
3124 struct server_id interpret_pid(const char *pid_string)
3125 {
3126 #ifdef CLUSTER_SUPPORT
3127         unsigned int vnn, pid;
3128         struct server_id result;
3129         if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3130                 result.vnn = vnn;
3131                 result.pid = pid;
3132         }
3133         else if (sscanf(pid_string, "%u", &pid) == 1) {
3134                 result.vnn = NONCLUSTER_VNN;
3135                 result.pid = pid;
3136         }
3137         else {
3138                 result.vnn = NONCLUSTER_VNN;
3139                 result.pid = -1;
3140         }
3141         return result;
3142 #else
3143         return pid_to_procid(atoi(pid_string));
3144 #endif
3145 }
3146
3147 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3148 {
3149         fstring str;
3150 #ifdef CLUSTER_SUPPORT
3151         if (pid->vnn == NONCLUSTER_VNN) {
3152                 fstr_sprintf(str, "%d", (int)pid->pid);
3153         }
3154         else {
3155                 fstr_sprintf(str, "%u:%d", (unsigned)pid->vnn, (int)pid->pid);
3156         }
3157 #else
3158         fstr_sprintf(str, "%d", (int)pid->pid);
3159 #endif
3160         return talloc_strdup(mem_ctx, str);
3161 }
3162
3163 char *procid_str_static(const struct server_id *pid)
3164 {
3165         return procid_str(talloc_tos(), pid);
3166 }
3167
3168 BOOL procid_valid(const struct server_id *pid)
3169 {
3170         return (pid->pid != -1);
3171 }
3172
3173 BOOL procid_is_local(const struct server_id *pid)
3174 {
3175 #ifdef CLUSTER_SUPPORT
3176         return pid->vnn == my_vnn;
3177 #else
3178         return True;
3179 #endif
3180 }
3181
3182 int this_is_smp(void)
3183 {
3184 #if defined(HAVE_SYSCONF)
3185
3186 #if defined(SYSCONF_SC_NPROC_ONLN)
3187         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3188 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3189         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3190 #else
3191         return 0;
3192 #endif
3193
3194 #else
3195         return 0;
3196 #endif
3197 }
3198
3199 /****************************************************************
3200  Check if an offset into a buffer is safe.
3201  If this returns True it's safe to indirect into the byte at
3202  pointer ptr+off.
3203 ****************************************************************/
3204
3205 BOOL is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3206 {
3207         const char *end_base = buf_base + buf_len;
3208         char *end_ptr = ptr + off;
3209
3210         if (!buf_base || !ptr) {
3211                 return False;
3212         }
3213
3214         if (end_base < buf_base || end_ptr < ptr) {
3215                 return False; /* wrap. */
3216         }
3217
3218         if (end_ptr < end_base) {
3219                 return True;
3220         }
3221         return False;
3222 }
3223
3224 /****************************************************************
3225  Return a safe pointer into a buffer, or NULL.
3226 ****************************************************************/
3227
3228 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3229 {
3230         return is_offset_safe(buf_base, buf_len, ptr, off) ?
3231                         ptr + off : NULL;
3232 }
3233
3234 /****************************************************************
3235  Return a safe pointer into a string within a buffer, or NULL.
3236 ****************************************************************/
3237
3238 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3239 {
3240         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3241                 return NULL;
3242         }
3243         /* Check if a valid string exists at this offset. */
3244         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3245                 return NULL;
3246         }
3247         return ptr + off;
3248 }
3249
3250 /****************************************************************
3251  Return an SVAL at a pointer, or failval if beyond the end.
3252 ****************************************************************/
3253
3254 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3255 {
3256         /*
3257          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3258          * NOT ptr[2].
3259          */
3260         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3261                 return failval;
3262         }
3263         return SVAL(ptr,off);
3264 }
3265
3266 /****************************************************************
3267  Return an IVAL at a pointer, or failval if beyond the end.
3268 ****************************************************************/
3269
3270 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3271 {
3272         /*
3273          * Note we use off+3 here, not off+4 as IVAL accesses 
3274          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3275          */
3276         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3277                 return failval;
3278         }
3279         return IVAL(ptr,off);
3280 }
3281
3282 #if 0
3283
3284 Disable these now we have checked all code paths and ensured
3285 NULL returns on zero request. JRA.
3286
3287 /****************************************************************
3288  talloc wrapper functions that guarentee a null pointer return
3289  if size == 0.
3290 ****************************************************************/
3291
3292 #ifndef MAX_TALLOC_SIZE
3293 #define MAX_TALLOC_SIZE 0x10000000
3294 #endif
3295
3296 /*
3297  *    talloc and zero memory.
3298  *    - returns NULL if size is zero.
3299  */
3300
3301 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3302 {
3303         void *p;
3304
3305         if (size == 0) {
3306                 return NULL;
3307         }
3308
3309         p = talloc_named_const(ctx, size, name);
3310
3311         if (p) {
3312                 memset(p, '\0', size);
3313         }
3314
3315         return p;
3316 }
3317
3318 /*
3319  *   memdup with a talloc.
3320  *   - returns NULL if size is zero.
3321  */
3322
3323 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3324 {
3325         void *newp;
3326
3327         if (size == 0) {
3328                 return NULL;
3329         }
3330
3331         newp = talloc_named_const(t, size, name);
3332         if (newp) {
3333                 memcpy(newp, p, size);
3334         }
3335
3336         return newp;
3337 }
3338
3339 /*
3340  *   alloc an array, checking for integer overflow in the array size.
3341  *   - returns NULL if count or el_size are zero.
3342  */
3343
3344 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3345 {
3346         if (count >= MAX_TALLOC_SIZE/el_size) {
3347                 return NULL;
3348         }
3349
3350         if (el_size == 0 || count == 0) {
3351                 return NULL;
3352         }
3353
3354         return talloc_named_const(ctx, el_size * count, name);
3355 }
3356
3357 /*
3358  *   alloc an zero array, checking for integer overflow in the array size
3359  *   - returns NULL if count or el_size are zero.
3360  */
3361
3362 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3363 {
3364         if (count >= MAX_TALLOC_SIZE/el_size) {
3365                 return NULL;
3366         }
3367
3368         if (el_size == 0 || count == 0) {
3369                 return NULL;
3370         }
3371
3372         return _talloc_zero(ctx, el_size * count, name);
3373 }
3374
3375 /*
3376  *   Talloc wrapper that returns NULL if size == 0.
3377  */
3378 void *talloc_zeronull(const void *context, size_t size, const char *name)
3379 {
3380         if (size == 0) {
3381                 return NULL;
3382         }
3383         return talloc_named_const(context, size, name);
3384 }
3385 #endif