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