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