2cd0f7749929ebccd026234ce3ce8771d101785b
[kai/samba.git] / source3 / lib / util.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 2001-2002
6    Copyright (C) Simo Sorce 2001
7    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8    Copyright (C) James Peach 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, 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");
2474         }
2475         if (count >= MAX_ALLOC_SIZE/size) {
2476                 smb_panic("smb_xmalloc_array: alloc size too large");
2477         }
2478         if ((p = SMB_MALLOC(size*count)) == NULL) {
2479                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2480                         (unsigned long)size, (unsigned long)count));
2481                 smb_panic("smb_xmalloc_array: malloc failed");
2482         }
2483         return p;
2484 }
2485
2486 /**
2487  Memdup with smb_panic on fail.
2488 **/
2489
2490 void *smb_xmemdup(const void *p, size_t size)
2491 {
2492         void *p2;
2493         p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2494         memcpy(p2, p, size);
2495         return p2;
2496 }
2497
2498 /**
2499  strdup that aborts on malloc fail.
2500 **/
2501
2502 char *smb_xstrdup(const char *s)
2503 {
2504 #if defined(PARANOID_MALLOC_CHECKER)
2505 #ifdef strdup
2506 #undef strdup
2507 #endif
2508 #endif
2509
2510 #ifndef HAVE_STRDUP
2511 #define strdup rep_strdup
2512 #endif
2513
2514         char *s1 = strdup(s);
2515 #if defined(PARANOID_MALLOC_CHECKER)
2516 #ifdef strdup
2517 #undef strdup
2518 #endif
2519 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2520 #endif
2521         if (!s1) {
2522                 smb_panic("smb_xstrdup: malloc failed");
2523         }
2524         return s1;
2525
2526 }
2527
2528 /**
2529  strndup that aborts on malloc fail.
2530 **/
2531
2532 char *smb_xstrndup(const char *s, size_t n)
2533 {
2534 #if defined(PARANOID_MALLOC_CHECKER)
2535 #ifdef strndup
2536 #undef strndup
2537 #endif
2538 #endif
2539
2540 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
2541 #undef HAVE_STRNDUP
2542 #define strndup rep_strndup
2543 #endif
2544
2545         char *s1 = strndup(s, n);
2546 #if defined(PARANOID_MALLOC_CHECKER)
2547 #ifdef strndup
2548 #undef strndup
2549 #endif
2550 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2551 #endif
2552         if (!s1) {
2553                 smb_panic("smb_xstrndup: malloc failed");
2554         }
2555         return s1;
2556 }
2557
2558 /*
2559   vasprintf that aborts on malloc fail
2560 */
2561
2562  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2563 {
2564         int n;
2565         va_list ap2;
2566
2567         VA_COPY(ap2, ap);
2568
2569         n = vasprintf(ptr, format, ap2);
2570         if (n == -1 || ! *ptr) {
2571                 smb_panic("smb_xvasprintf: out of memory");
2572         }
2573         return n;
2574 }
2575
2576 /*****************************************************************
2577  Like strdup but for memory.
2578 *****************************************************************/  
2579
2580 void *memdup(const void *p, size_t size)
2581 {
2582         void *p2;
2583         if (size == 0)
2584                 return NULL;
2585         p2 = SMB_MALLOC(size);
2586         if (!p2)
2587                 return NULL;
2588         memcpy(p2, p, size);
2589         return p2;
2590 }
2591
2592 /*****************************************************************
2593  Get local hostname and cache result.
2594 *****************************************************************/  
2595
2596 char *myhostname(void)
2597 {
2598         static pstring ret;
2599         if (ret[0] == 0)
2600                 get_myname(ret);
2601         return ret;
2602 }
2603
2604 /*****************************************************************
2605  A useful function for returning a path in the Samba lock directory.
2606 *****************************************************************/  
2607
2608 char *lock_path(const char *name)
2609 {
2610         static pstring fname;
2611
2612         pstrcpy(fname,lp_lockdir());
2613         trim_char(fname,'\0','/');
2614         
2615         if (!directory_exist(fname,NULL))
2616                 mkdir(fname,0755);
2617         
2618         pstrcat(fname,"/");
2619         pstrcat(fname,name);
2620
2621         return fname;
2622 }
2623
2624 /*****************************************************************
2625  A useful function for returning a path in the Samba pid directory.
2626 *****************************************************************/
2627
2628 char *pid_path(const char *name)
2629 {
2630         static pstring fname;
2631
2632         pstrcpy(fname,lp_piddir());
2633         trim_char(fname,'\0','/');
2634
2635         if (!directory_exist(fname,NULL))
2636                 mkdir(fname,0755);
2637
2638         pstrcat(fname,"/");
2639         pstrcat(fname,name);
2640
2641         return fname;
2642 }
2643
2644 /**
2645  * @brief Returns an absolute path to a file in the Samba lib directory.
2646  *
2647  * @param name File to find, relative to LIBDIR.
2648  *
2649  * @retval Pointer to a static #pstring containing the full path.
2650  **/
2651
2652 char *lib_path(const char *name)
2653 {
2654         static pstring fname;
2655         fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2656         return fname;
2657 }
2658
2659 /**
2660  * @brief Returns the platform specific shared library extension.
2661  *
2662  * @retval Pointer to a static #fstring containing the extension.
2663  **/
2664
2665 const char *shlib_ext(void)
2666 {
2667   return dyn_SHLIBEXT;
2668 }
2669
2670 /*******************************************************************
2671  Given a filename - get its directory name
2672  NB: Returned in static storage.  Caveats:
2673  o  Not safe in thread environment.
2674  o  Caller must not free.
2675  o  If caller wishes to preserve, they should copy.
2676 ********************************************************************/
2677
2678 char *parent_dirname(const char *path)
2679 {
2680         static pstring dirpath;
2681         char *p;
2682
2683         if (!path)
2684                 return(NULL);
2685
2686         pstrcpy(dirpath, path);
2687         p = strrchr_m(dirpath, '/');  /* Find final '/', if any */
2688         if (!p) {
2689                 pstrcpy(dirpath, ".");    /* No final "/", so dir is "." */
2690         } else {
2691                 if (p == dirpath)
2692                         ++p;    /* For root "/", leave "/" in place */
2693                 *p = '\0';
2694         }
2695         return dirpath;
2696 }
2697
2698 BOOL parent_dirname_talloc(TALLOC_CTX *mem_ctx, const char *dir,
2699                            char **parent, const char **name)
2700 {
2701         char *p;
2702         ptrdiff_t len;
2703  
2704         p = strrchr_m(dir, '/'); /* Find final '/', if any */
2705
2706         if (p == NULL) {
2707                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2708                         return False;
2709                 }
2710                 if (name) {
2711                         *name = "";
2712                 }
2713                 return True;
2714         }
2715
2716         len = p-dir;
2717
2718         if (!(*parent = TALLOC_ARRAY(mem_ctx, char, len+1))) {
2719                 return False;
2720         }
2721         memcpy(*parent, dir, len);
2722         (*parent)[len] = '\0';
2723
2724         if (name) {
2725                 *name = p+1;
2726         }
2727         return True;
2728 }
2729
2730 /*******************************************************************
2731  Determine if a pattern contains any Microsoft wildcard characters.
2732 *******************************************************************/
2733
2734 BOOL ms_has_wild(const char *s)
2735 {
2736         char c;
2737
2738         if (lp_posix_pathnames()) {
2739                 /* With posix pathnames no characters are wild. */
2740                 return False;
2741         }
2742
2743         while ((c = *s++)) {
2744                 switch (c) {
2745                 case '*':
2746                 case '?':
2747                 case '<':
2748                 case '>':
2749                 case '"':
2750                         return True;
2751                 }
2752         }
2753         return False;
2754 }
2755
2756 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2757 {
2758         smb_ucs2_t c;
2759         if (!s) return False;
2760         while ((c = *s++)) {
2761                 switch (c) {
2762                 case UCS2_CHAR('*'):
2763                 case UCS2_CHAR('?'):
2764                 case UCS2_CHAR('<'):
2765                 case UCS2_CHAR('>'):
2766                 case UCS2_CHAR('"'):
2767                         return True;
2768                 }
2769         }
2770         return False;
2771 }
2772
2773 /*******************************************************************
2774  A wrapper that handles case sensitivity and the special handling
2775  of the ".." name.
2776 *******************************************************************/
2777
2778 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2779 {
2780         if (strcmp(string,"..") == 0)
2781                 string = ".";
2782         if (strcmp(pattern,".") == 0)
2783                 return False;
2784         
2785         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2786 }
2787
2788 /*******************************************************************
2789  A wrapper that handles case sensitivity and the special handling
2790  of the ".." name. Varient that is only called by old search code which requires
2791  pattern translation.
2792 *******************************************************************/
2793
2794 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2795 {
2796         if (strcmp(string,"..") == 0)
2797                 string = ".";
2798         if (strcmp(pattern,".") == 0)
2799                 return False;
2800         
2801         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2802 }
2803
2804 /*******************************************************************
2805  A wrapper that handles a list of patters and calls mask_match()
2806  on each.  Returns True if any of the patterns match.
2807 *******************************************************************/
2808
2809 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2810 {
2811        while (listLen-- > 0) {
2812                if (mask_match(string, *list++, is_case_sensitive))
2813                        return True;
2814        }
2815        return False;
2816 }
2817
2818 /*********************************************************
2819  Recursive routine that is called by unix_wild_match.
2820 *********************************************************/
2821
2822 static BOOL unix_do_match(const char *regexp, const char *str)
2823 {
2824         const char *p;
2825
2826         for( p = regexp; *p && *str; ) {
2827
2828                 switch(*p) {
2829                         case '?':
2830                                 str++;
2831                                 p++;
2832                                 break;
2833
2834                         case '*':
2835
2836                                 /*
2837                                  * Look for a character matching 
2838                                  * the one after the '*'.
2839                                  */
2840                                 p++;
2841                                 if(!*p)
2842                                         return True; /* Automatic match */
2843                                 while(*str) {
2844
2845                                         while(*str && (*p != *str))
2846                                                 str++;
2847
2848                                         /*
2849                                          * Patch from weidel@multichart.de. In the case of the regexp
2850                                          * '*XX*' we want to ensure there are at least 2 'X' characters
2851                                          * in the string after the '*' for a match to be made.
2852                                          */
2853
2854                                         {
2855                                                 int matchcount=0;
2856
2857                                                 /*
2858                                                  * Eat all the characters that match, but count how many there were.
2859                                                  */
2860
2861                                                 while(*str && (*p == *str)) {
2862                                                         str++;
2863                                                         matchcount++;
2864                                                 }
2865
2866                                                 /*
2867                                                  * Now check that if the regexp had n identical characters that
2868                                                  * matchcount had at least that many matches.
2869                                                  */
2870
2871                                                 while ( *(p+1) && (*(p+1) == *p)) {
2872                                                         p++;
2873                                                         matchcount--;
2874                                                 }
2875
2876                                                 if ( matchcount <= 0 )
2877                                                         return False;
2878                                         }
2879
2880                                         str--; /* We've eaten the match char after the '*' */
2881
2882                                         if(unix_do_match(p, str))
2883                                                 return True;
2884
2885                                         if(!*str)
2886                                                 return False;
2887                                         else
2888                                                 str++;
2889                                 }
2890                                 return False;
2891
2892                         default:
2893                                 if(*str != *p)
2894                                         return False;
2895                                 str++;
2896                                 p++;
2897                                 break;
2898                 }
2899         }
2900
2901         if(!*p && !*str)
2902                 return True;
2903
2904         if (!*p && str[0] == '.' && str[1] == 0)
2905                 return(True);
2906   
2907         if (!*str && *p == '?') {
2908                 while (*p == '?')
2909                         p++;
2910                 return(!*p);
2911         }
2912
2913         if(!*str && (*p == '*' && p[1] == '\0'))
2914                 return True;
2915
2916         return False;
2917 }
2918
2919 /*******************************************************************
2920  Simple case insensitive interface to a UNIX wildcard matcher.
2921  Returns True if match, False if not.
2922 *******************************************************************/
2923
2924 BOOL unix_wild_match(const char *pattern, const char *string)
2925 {
2926         pstring p2, s2;
2927         char *p;
2928
2929         pstrcpy(p2, pattern);
2930         pstrcpy(s2, string);
2931         strlower_m(p2);
2932         strlower_m(s2);
2933
2934         /* Remove any *? and ** from the pattern as they are meaningless */
2935         for(p = p2; *p; p++)
2936                 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2937                         pstrcpy( &p[1], &p[2]);
2938  
2939         if (strequal(p2,"*"))
2940                 return True;
2941
2942         return unix_do_match(p2, s2);
2943 }
2944
2945 /**********************************************************************
2946  Converts a name to a fully qualified domain name.
2947  Returns True if lookup succeeded, False if not (then fqdn is set to name)
2948 ***********************************************************************/
2949                                                                                                                                                    
2950 BOOL name_to_fqdn(fstring fqdn, const char *name)
2951 {
2952         struct hostent *hp = sys_gethostbyname(name);
2953
2954         if ( hp && hp->h_name && *hp->h_name ) {
2955                 char *full = NULL;
2956
2957                 /* find out if the fqdn is returned as an alias
2958                  * to cope with /etc/hosts files where the first
2959                  * name is not the fqdn but the short name */
2960                 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2961                         int i;
2962                         for (i = 0; hp->h_aliases[i]; i++) {
2963                                 if (strchr_m(hp->h_aliases[i], '.')) {
2964                                         full = hp->h_aliases[i];
2965                                         break;
2966                                 }
2967                         }
2968                 }
2969                 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2970                         DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2971                         DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2972                         DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
2973                         DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
2974                         full = hp->h_name;
2975                 }
2976                         
2977                 if (!full) {
2978                         full = hp->h_name;
2979                 }
2980
2981                 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2982                 fstrcpy(fqdn, full);
2983                 return True;
2984         } else {
2985                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2986                 fstrcpy(fqdn, name);
2987                 return False;
2988         }
2989 }
2990
2991 /**********************************************************************
2992  Extension to talloc_get_type: Abort on type mismatch
2993 ***********************************************************************/
2994
2995 void *talloc_check_name_abort(const void *ptr, const char *name)
2996 {
2997         void *result;
2998
2999         result = talloc_check_name(ptr, name);
3000         if (result != NULL)
3001                 return result;
3002
3003         DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
3004                   name, talloc_get_name(ptr)));
3005         smb_panic("talloc type mismatch");
3006         /* Keep the compiler happy */
3007         return NULL;
3008 }
3009
3010
3011 #ifdef __INSURE__
3012
3013 /*******************************************************************
3014 This routine is a trick to immediately catch errors when debugging
3015 with insure. A xterm with a gdb is popped up when insure catches
3016 a error. It is Linux specific.
3017 ********************************************************************/
3018
3019 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
3020 {
3021         static int (*fn)();
3022         int ret;
3023         char pidstr[10];
3024         /* you can get /usr/bin/backtrace from 
3025            http://samba.org/ftp/unpacked/junkcode/backtrace */
3026         pstring cmd = "/usr/bin/backtrace %d";
3027
3028         slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
3029         pstring_sub(cmd, "%d", pidstr);
3030
3031         if (!fn) {
3032                 static void *h;
3033                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
3034                 fn = dlsym(h, "_Insure_trap_error");
3035
3036                 if (!h || h == _Insure_trap_error) {
3037                         h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
3038                         fn = dlsym(h, "_Insure_trap_error");
3039                 }               
3040         }
3041
3042         ret = fn(a1, a2, a3, a4, a5, a6);
3043
3044         system(cmd);
3045
3046         return ret;
3047 }
3048 #endif
3049
3050 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
3051 {
3052         switch (share_access & ~FILE_SHARE_DELETE) {
3053                 case FILE_SHARE_NONE:
3054                         return DENY_ALL;
3055                 case FILE_SHARE_READ:
3056                         return DENY_WRITE;
3057                 case FILE_SHARE_WRITE:
3058                         return DENY_READ;
3059                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
3060                         return DENY_NONE;
3061         }
3062         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
3063                 return DENY_DOS;
3064         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
3065                 return DENY_FCB;
3066         }
3067
3068         return (uint32)-1;
3069 }
3070
3071 pid_t procid_to_pid(const struct server_id *proc)
3072 {
3073         return proc->pid;
3074 }
3075
3076 static uint32 my_vnn = NONCLUSTER_VNN;
3077
3078 void set_my_vnn(uint32 vnn)
3079 {
3080         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
3081         my_vnn = vnn;
3082 }
3083
3084 uint32 get_my_vnn(void)
3085 {
3086         return my_vnn;
3087 }
3088
3089 struct server_id pid_to_procid(pid_t pid)
3090 {
3091         struct server_id result;
3092         result.pid = pid;
3093 #ifdef CLUSTER_SUPPORT
3094         result.vnn = my_vnn;
3095 #endif
3096         return result;
3097 }
3098
3099 struct server_id procid_self(void)
3100 {
3101         return pid_to_procid(sys_getpid());
3102 }
3103
3104 struct server_id server_id_self(void)
3105 {
3106         return procid_self();
3107 }
3108
3109 BOOL procid_equal(const struct server_id *p1, const struct server_id *p2)
3110 {
3111         if (p1->pid != p2->pid)
3112                 return False;
3113 #ifdef CLUSTER_SUPPORT
3114         if (p1->vnn != p2->vnn)
3115                 return False;
3116 #endif
3117         return True;
3118 }
3119
3120 BOOL cluster_id_equal(const struct server_id *id1,
3121                       const struct server_id *id2)
3122 {
3123         return procid_equal(id1, id2);
3124 }
3125
3126 BOOL procid_is_me(const struct server_id *pid)
3127 {
3128         if (pid->pid != sys_getpid())
3129                 return False;
3130 #ifdef CLUSTER_SUPPORT
3131         if (pid->vnn != my_vnn)
3132                 return False;
3133 #endif
3134         return True;
3135 }
3136
3137 struct server_id interpret_pid(const char *pid_string)
3138 {
3139 #ifdef CLUSTER_SUPPORT
3140         unsigned int vnn, pid;
3141         struct server_id result;
3142         if (sscanf(pid_string, "%u:%u", &vnn, &pid) == 2) {
3143                 result.vnn = vnn;
3144                 result.pid = pid;
3145         }
3146         else if (sscanf(pid_string, "%u", &pid) == 1) {
3147                 result.vnn = NONCLUSTER_VNN;
3148                 result.pid = pid;
3149         }
3150         else {
3151                 result.vnn = NONCLUSTER_VNN;
3152                 result.pid = -1;
3153         }
3154         return result;
3155 #else
3156         return pid_to_procid(atoi(pid_string));
3157 #endif
3158 }
3159
3160 char *procid_str_static(const struct server_id *pid)
3161 {
3162         static fstring str;
3163 #ifdef CLUSTER_SUPPORT
3164         if (pid->vnn == NONCLUSTER_VNN) {
3165                 fstr_sprintf(str, "%d", (int)pid->pid);
3166         }
3167         else {
3168                 fstr_sprintf(str, "%u:%d", (unsigned)pid->vnn, (int)pid->pid);
3169         }
3170 #else
3171         fstr_sprintf(str, "%d", (int)pid->pid);
3172 #endif
3173         return str;
3174 }
3175
3176 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
3177 {
3178         return talloc_strdup(mem_ctx, procid_str_static(pid));
3179 }
3180
3181 BOOL procid_valid(const struct server_id *pid)
3182 {
3183         return (pid->pid != -1);
3184 }
3185
3186 BOOL procid_is_local(const struct server_id *pid)
3187 {
3188 #ifdef CLUSTER_SUPPORT
3189         return pid->vnn == my_vnn;
3190 #else
3191         return True;
3192 #endif
3193 }
3194
3195 int this_is_smp(void)
3196 {
3197 #if defined(HAVE_SYSCONF)
3198
3199 #if defined(SYSCONF_SC_NPROC_ONLN)
3200         return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3201 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3202         return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3203 #else
3204         return 0;
3205 #endif
3206
3207 #else
3208         return 0;
3209 #endif
3210 }
3211
3212 /****************************************************************
3213  Check if an offset into a buffer is safe.
3214  If this returns True it's safe to indirect into the byte at
3215  pointer ptr+off.
3216 ****************************************************************/
3217
3218 BOOL is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3219 {
3220         const char *end_base = buf_base + buf_len;
3221         char *end_ptr = ptr + off;
3222
3223         if (!buf_base || !ptr) {
3224                 return False;
3225         }
3226
3227         if (end_base < buf_base || end_ptr < ptr) {
3228                 return False; /* wrap. */
3229         }
3230
3231         if (end_ptr < end_base) {
3232                 return True;
3233         }
3234         return False;
3235 }
3236
3237 /****************************************************************
3238  Return a safe pointer into a buffer, or NULL.
3239 ****************************************************************/
3240
3241 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3242 {
3243         return is_offset_safe(buf_base, buf_len, ptr, off) ?
3244                         ptr + off : NULL;
3245 }
3246
3247 /****************************************************************
3248  Return a safe pointer into a string within a buffer, or NULL.
3249 ****************************************************************/
3250
3251 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
3252 {
3253         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
3254                 return NULL;
3255         }
3256         /* Check if a valid string exists at this offset. */
3257         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
3258                 return NULL;
3259         }
3260         return ptr + off;
3261 }
3262
3263 /****************************************************************
3264  Return an SVAL at a pointer, or failval if beyond the end.
3265 ****************************************************************/
3266
3267 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3268 {
3269         /*
3270          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
3271          * NOT ptr[2].
3272          */
3273         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
3274                 return failval;
3275         }
3276         return SVAL(ptr,off);
3277 }
3278
3279 /****************************************************************
3280  Return an IVAL at a pointer, or failval if beyond the end.
3281 ****************************************************************/
3282
3283 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
3284 {
3285         /*
3286          * Note we use off+3 here, not off+4 as IVAL accesses 
3287          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
3288          */
3289         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
3290                 return failval;
3291         }
3292         return IVAL(ptr,off);
3293 }
3294
3295 /****************************************************************
3296  talloc wrapper functions that guarentee a null pointer return
3297  if size == 0.
3298 ****************************************************************/
3299
3300 #ifndef MAX_TALLOC_SIZE
3301 #define MAX_TALLOC_SIZE 0x10000000
3302 #endif
3303
3304 /*
3305  *    talloc and zero memory.
3306  *    - returns NULL if size is zero.
3307  */
3308
3309 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
3310 {
3311         void *p;
3312
3313         if (size == 0) {
3314                 return NULL;
3315         }
3316
3317         p = talloc_named_const(ctx, size, name);
3318
3319         if (p) {
3320                 memset(p, '\0', size);
3321         }
3322
3323         return p;
3324 }
3325
3326 /*
3327  *   memdup with a talloc.
3328  *   - returns NULL if size is zero.
3329  */
3330
3331 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
3332 {
3333         void *newp;
3334
3335         if (size == 0) {
3336                 return NULL;
3337         }
3338
3339         newp = talloc_named_const(t, size, name);
3340         if (newp) {
3341                 memcpy(newp, p, size);
3342         }
3343
3344         return newp;
3345 }
3346
3347 /*
3348  *   alloc an array, checking for integer overflow in the array size.
3349  *   - returns NULL if count or el_size are zero.
3350  */
3351
3352 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3353 {
3354         if (count >= MAX_TALLOC_SIZE/el_size) {
3355                 return NULL;
3356         }
3357
3358         if (el_size == 0 || count == 0) {
3359                 return NULL;
3360         }
3361
3362         return talloc_named_const(ctx, el_size * count, name);
3363 }
3364
3365 /*
3366  *   alloc an zero array, checking for integer overflow in the array size
3367  *   - returns NULL if count or el_size are zero.
3368  */
3369
3370 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3371 {
3372         if (count >= MAX_TALLOC_SIZE/el_size) {
3373                 return NULL;
3374         }
3375
3376         if (el_size == 0 || count == 0) {
3377                 return NULL;
3378         }
3379
3380         return _talloc_zero(ctx, el_size * count, name);
3381 }
3382
3383 /*
3384  *   Talloc wrapper that returns NULL if size == 0.
3385  */
3386 void *talloc_zeronull(const void *context, size_t size, const char *name)
3387 {
3388         if (size == 0) {
3389                 return NULL;
3390         }
3391         return talloc_named_const(context, size, name);
3392 }