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