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