r15385: Some work to bring the python code up to date with the
[Samba/gebeck_regimport.git] / source / lib / util.c
blobc023df0b017f8ced03d2ea1f78baadc057b74423
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2002
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "includes.h"
27 extern fstring local_machine;
28 extern char *global_clobber_region_function;
29 extern unsigned int global_clobber_region_line;
30 extern fstring remote_arch;
32 /* Max allowable allococation - 256mb - 0x10000000 */
33 #define MAX_ALLOC_SIZE (1024*1024*256)
35 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
36 #ifdef WITH_NISPLUS_HOME
37 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
39 * The following lines are needed due to buggy include files
40 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
41 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
42 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
43 * an enum in /usr/include/rpcsvc/nis.h.
46 #if defined(GROUP)
47 #undef GROUP
48 #endif
50 #if defined(GROUP_OBJ)
51 #undef GROUP_OBJ
52 #endif
54 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
56 #include <rpcsvc/nis.h>
58 #endif /* WITH_NISPLUS_HOME */
59 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
61 enum protocol_types Protocol = PROTOCOL_COREPLUS;
63 /* a default finfo structure to ensure all fields are sensible */
64 file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
66 /* this is used by the chaining code */
67 int chain_size = 0;
69 int trans_num = 0;
71 static enum remote_arch_types ra_type = RA_UNKNOWN;
72 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
74 /***********************************************************************
75 Definitions for all names.
76 ***********************************************************************/
78 static char *smb_myname;
79 static char *smb_myworkgroup;
80 static char *smb_scope;
81 static int smb_num_netbios_names;
82 static char **smb_my_netbios_names;
84 /***********************************************************************
85 Allocate and set myname. Ensure upper case.
86 ***********************************************************************/
88 BOOL set_global_myname(const char *myname)
90 SAFE_FREE(smb_myname);
91 smb_myname = SMB_STRDUP(myname);
92 if (!smb_myname)
93 return False;
94 strupper_m(smb_myname);
95 return True;
98 const char *global_myname(void)
100 return smb_myname;
103 /***********************************************************************
104 Allocate and set myworkgroup. Ensure upper case.
105 ***********************************************************************/
107 BOOL set_global_myworkgroup(const char *myworkgroup)
109 SAFE_FREE(smb_myworkgroup);
110 smb_myworkgroup = SMB_STRDUP(myworkgroup);
111 if (!smb_myworkgroup)
112 return False;
113 strupper_m(smb_myworkgroup);
114 return True;
117 const char *lp_workgroup(void)
119 return smb_myworkgroup;
122 /***********************************************************************
123 Allocate and set scope. Ensure upper case.
124 ***********************************************************************/
126 BOOL set_global_scope(const char *scope)
128 SAFE_FREE(smb_scope);
129 smb_scope = SMB_STRDUP(scope);
130 if (!smb_scope)
131 return False;
132 strupper_m(smb_scope);
133 return True;
136 /*********************************************************************
137 Ensure scope is never null string.
138 *********************************************************************/
140 const char *global_scope(void)
142 if (!smb_scope)
143 set_global_scope("");
144 return smb_scope;
147 static void free_netbios_names_array(void)
149 int i;
151 for (i = 0; i < smb_num_netbios_names; i++)
152 SAFE_FREE(smb_my_netbios_names[i]);
154 SAFE_FREE(smb_my_netbios_names);
155 smb_num_netbios_names = 0;
158 static BOOL allocate_my_netbios_names_array(size_t number)
160 free_netbios_names_array();
162 smb_num_netbios_names = number + 1;
163 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
165 if (!smb_my_netbios_names)
166 return False;
168 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
169 return True;
172 static BOOL set_my_netbios_names(const char *name, int i)
174 SAFE_FREE(smb_my_netbios_names[i]);
176 smb_my_netbios_names[i] = SMB_STRDUP(name);
177 if (!smb_my_netbios_names[i])
178 return False;
179 strupper_m(smb_my_netbios_names[i]);
180 return True;
183 /***********************************************************************
184 Free memory allocated to global objects
185 ***********************************************************************/
187 void gfree_names(void)
189 SAFE_FREE( smb_myname );
190 SAFE_FREE( smb_myworkgroup );
191 SAFE_FREE( smb_scope );
192 free_netbios_names_array();
195 void gfree_all( void )
197 gfree_names();
198 gfree_loadparm();
199 gfree_case_tables();
200 gfree_debugsyms();
201 gfree_charcnv();
202 gfree_messsges();
204 /* release the talloc null_context memory last */
205 talloc_nc_free();
208 const char *my_netbios_names(int i)
210 return smb_my_netbios_names[i];
213 BOOL set_netbios_aliases(const char **str_array)
215 size_t namecount;
217 /* Work out the max number of netbios aliases that we have */
218 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
221 if ( global_myname() && *global_myname())
222 namecount++;
224 /* Allocate space for the netbios aliases */
225 if (!allocate_my_netbios_names_array(namecount))
226 return False;
228 /* Use the global_myname string first */
229 namecount=0;
230 if ( global_myname() && *global_myname()) {
231 set_my_netbios_names( global_myname(), namecount );
232 namecount++;
235 if (str_array) {
236 size_t i;
237 for ( i = 0; str_array[i] != NULL; i++) {
238 size_t n;
239 BOOL duplicate = False;
241 /* Look for duplicates */
242 for( n=0; n<namecount; n++ ) {
243 if( strequal( str_array[i], my_netbios_names(n) ) ) {
244 duplicate = True;
245 break;
248 if (!duplicate) {
249 if (!set_my_netbios_names(str_array[i], namecount))
250 return False;
251 namecount++;
255 return True;
258 /****************************************************************************
259 Common name initialization code.
260 ****************************************************************************/
262 BOOL init_names(void)
264 char *p;
265 int n;
267 if (global_myname() == NULL || *global_myname() == '\0') {
268 if (!set_global_myname(myhostname())) {
269 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
270 return False;
274 if (!set_netbios_aliases(lp_netbios_aliases())) {
275 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
276 return False;
279 fstrcpy( local_machine, global_myname() );
280 trim_char( local_machine, ' ', ' ' );
281 p = strchr( local_machine, ' ' );
282 if (p)
283 *p = 0;
284 strlower_m( local_machine );
286 DEBUG( 5, ("Netbios name list:-\n") );
287 for( n=0; my_netbios_names(n); n++ )
288 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names(n) ) );
290 return( True );
293 /**************************************************************************n
294 Find a suitable temporary directory. The result should be copied immediately
295 as it may be overwritten by a subsequent call.
296 ****************************************************************************/
298 const char *tmpdir(void)
300 char *p;
301 if ((p = getenv("TMPDIR")))
302 return p;
303 return "/tmp";
306 /****************************************************************************
307 Add a gid to an array of gids if it's not already there.
308 ****************************************************************************/
310 void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
311 gid_t **gids, size_t *num_gids)
313 int i;
315 for (i=0; i<*num_gids; i++) {
316 if ((*gids)[i] == gid)
317 return;
320 if (mem_ctx != NULL) {
321 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
322 } else {
323 *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num_gids+1);
326 if (*gids == NULL) {
327 return;
330 (*gids)[*num_gids] = gid;
331 *num_gids += 1;
334 /****************************************************************************
335 Like atoi but gets the value up to the separator character.
336 ****************************************************************************/
338 static const char *Atoic(const char *p, int *n, const char *c)
340 if (!isdigit((int)*p)) {
341 DEBUG(5, ("Atoic: malformed number\n"));
342 return NULL;
345 (*n) = atoi(p);
347 while ((*p) && isdigit((int)*p))
348 p++;
350 if (strchr_m(c, *p) == NULL) {
351 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
352 return NULL;
355 return p;
358 /*************************************************************************
359 Reads a list of numbers.
360 *************************************************************************/
362 const char *get_numlist(const char *p, uint32 **num, int *count)
364 int val;
366 if (num == NULL || count == NULL)
367 return NULL;
369 (*count) = 0;
370 (*num ) = NULL;
372 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
373 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
374 if (!(*num)) {
375 return NULL;
377 (*num)[(*count)] = val;
378 (*count)++;
379 p++;
382 return p;
385 /*******************************************************************
386 Check if a file exists - call vfs_file_exist for samba files.
387 ********************************************************************/
389 BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
391 SMB_STRUCT_STAT st;
392 if (!sbuf)
393 sbuf = &st;
395 if (sys_stat(fname,sbuf) != 0)
396 return(False);
398 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
401 /*******************************************************************
402 Check a files mod time.
403 ********************************************************************/
405 time_t file_modtime(const char *fname)
407 SMB_STRUCT_STAT st;
409 if (sys_stat(fname,&st) != 0)
410 return(0);
412 return(st.st_mtime);
415 /*******************************************************************
416 Check if a directory exists.
417 ********************************************************************/
419 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
421 SMB_STRUCT_STAT st2;
422 BOOL ret;
424 if (!st)
425 st = &st2;
427 if (sys_stat(dname,st) != 0)
428 return(False);
430 ret = S_ISDIR(st->st_mode);
431 if(!ret)
432 errno = ENOTDIR;
433 return ret;
436 /*******************************************************************
437 Returns the size in bytes of the named file.
438 ********************************************************************/
440 SMB_OFF_T get_file_size(char *file_name)
442 SMB_STRUCT_STAT buf;
443 buf.st_size = 0;
444 if(sys_stat(file_name,&buf) != 0)
445 return (SMB_OFF_T)-1;
446 return(buf.st_size);
449 /*******************************************************************
450 Return a string representing an attribute for a file.
451 ********************************************************************/
453 char *attrib_string(uint16 mode)
455 static fstring attrstr;
457 attrstr[0] = 0;
459 if (mode & aVOLID) fstrcat(attrstr,"V");
460 if (mode & aDIR) fstrcat(attrstr,"D");
461 if (mode & aARCH) fstrcat(attrstr,"A");
462 if (mode & aHIDDEN) fstrcat(attrstr,"H");
463 if (mode & aSYSTEM) fstrcat(attrstr,"S");
464 if (mode & aRONLY) fstrcat(attrstr,"R");
466 return(attrstr);
469 /*******************************************************************
470 Show a smb message structure.
471 ********************************************************************/
473 void show_msg(char *buf)
475 int i;
476 int bcc=0;
478 if (!DEBUGLVL(5))
479 return;
481 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
482 smb_len(buf),
483 (int)CVAL(buf,smb_com),
484 (int)CVAL(buf,smb_rcls),
485 (int)CVAL(buf,smb_reh),
486 (int)SVAL(buf,smb_err),
487 (int)CVAL(buf,smb_flg),
488 (int)SVAL(buf,smb_flg2)));
489 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
490 (int)SVAL(buf,smb_tid),
491 (int)SVAL(buf,smb_pid),
492 (int)SVAL(buf,smb_uid),
493 (int)SVAL(buf,smb_mid)));
494 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
496 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
497 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
498 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
500 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
502 DEBUGADD(5,("smb_bcc=%d\n",bcc));
504 if (DEBUGLEVEL < 10)
505 return;
507 if (DEBUGLEVEL < 50)
508 bcc = MIN(bcc, 512);
510 dump_data(10, smb_buf(buf), bcc);
513 /*******************************************************************
514 Set the length and marker of an smb packet.
515 ********************************************************************/
517 void smb_setlen(char *buf,int len)
519 _smb_setlen(buf,len);
521 SCVAL(buf,4,0xFF);
522 SCVAL(buf,5,'S');
523 SCVAL(buf,6,'M');
524 SCVAL(buf,7,'B');
527 /*******************************************************************
528 Setup the word count and byte count for a smb message.
529 ********************************************************************/
531 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
533 if (zero && (num_words || num_bytes)) {
534 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
536 SCVAL(buf,smb_wct,num_words);
537 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
538 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
539 return (smb_size + num_words*2 + num_bytes);
542 /*******************************************************************
543 Setup only the byte count for a smb message.
544 ********************************************************************/
546 int set_message_bcc(char *buf,int num_bytes)
548 int num_words = CVAL(buf,smb_wct);
549 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
550 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
551 return (smb_size + num_words*2 + num_bytes);
554 /*******************************************************************
555 Setup only the byte count for a smb message, using the end of the
556 message as a marker.
557 ********************************************************************/
559 int set_message_end(void *outbuf,void *end_ptr)
561 return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
564 /*******************************************************************
565 Reduce a file name, removing .. elements.
566 ********************************************************************/
568 void dos_clean_name(char *s)
570 char *p=NULL;
572 DEBUG(3,("dos_clean_name [%s]\n",s));
574 /* remove any double slashes */
575 all_string_sub(s, "\\\\", "\\", 0);
577 while ((p = strstr_m(s,"\\..\\")) != NULL) {
578 pstring s1;
580 *p = 0;
581 pstrcpy(s1,p+3);
583 if ((p=strrchr_m(s,'\\')) != NULL)
584 *p = 0;
585 else
586 *s = 0;
587 pstrcat(s,s1);
590 trim_string(s,NULL,"\\..");
592 all_string_sub(s, "\\.\\", "\\", 0);
595 /*******************************************************************
596 Reduce a file name, removing .. elements.
597 ********************************************************************/
599 void unix_clean_name(char *s)
601 char *p=NULL;
603 DEBUG(3,("unix_clean_name [%s]\n",s));
605 /* remove any double slashes */
606 all_string_sub(s, "//","/", 0);
608 /* Remove leading ./ characters */
609 if(strncmp(s, "./", 2) == 0) {
610 trim_string(s, "./", NULL);
611 if(*s == 0)
612 pstrcpy(s,"./");
615 while ((p = strstr_m(s,"/../")) != NULL) {
616 pstring s1;
618 *p = 0;
619 pstrcpy(s1,p+3);
621 if ((p=strrchr_m(s,'/')) != NULL)
622 *p = 0;
623 else
624 *s = 0;
625 pstrcat(s,s1);
628 trim_string(s,NULL,"/..");
631 /*******************************************************************
632 Close the low 3 fd's and open dev/null in their place.
633 ********************************************************************/
635 void close_low_fds(BOOL stderr_too)
637 #ifndef VALGRIND
638 int fd;
639 int i;
641 close(0);
642 close(1);
644 if (stderr_too)
645 close(2);
647 /* try and use up these file descriptors, so silly
648 library routines writing to stdout etc won't cause havoc */
649 for (i=0;i<3;i++) {
650 if (i == 2 && !stderr_too)
651 continue;
653 fd = sys_open("/dev/null",O_RDWR,0);
654 if (fd < 0)
655 fd = sys_open("/dev/null",O_WRONLY,0);
656 if (fd < 0) {
657 DEBUG(0,("Can't open /dev/null\n"));
658 return;
660 if (fd != i) {
661 DEBUG(0,("Didn't get file descriptor %d\n",i));
662 return;
665 #endif
668 /*******************************************************************
669 Write data into an fd at a given offset. Ignore seek errors.
670 ********************************************************************/
672 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
674 size_t total=0;
675 ssize_t ret;
677 if (pos == (SMB_OFF_T)-1) {
678 return write_data(fd, buffer, N);
680 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
681 while (total < N) {
682 ret = sys_pwrite(fd,buffer + total,N - total, pos);
683 if (ret == -1 && errno == ESPIPE) {
684 return write_data(fd, buffer + total,N - total);
686 if (ret == -1) {
687 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
688 return -1;
690 if (ret == 0) {
691 return total;
693 total += ret;
694 pos += ret;
696 return (ssize_t)total;
697 #else
698 /* Use lseek and write_data. */
699 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
700 if (errno != ESPIPE) {
701 return -1;
704 return write_data(fd, buffer, N);
705 #endif
708 /****************************************************************************
709 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
710 else
711 if SYSV use O_NDELAY
712 if BSD use FNDELAY
713 ****************************************************************************/
715 int set_blocking(int fd, BOOL set)
717 int val;
718 #ifdef O_NONBLOCK
719 #define FLAG_TO_SET O_NONBLOCK
720 #else
721 #ifdef SYSV
722 #define FLAG_TO_SET O_NDELAY
723 #else /* BSD */
724 #define FLAG_TO_SET FNDELAY
725 #endif
726 #endif
728 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
729 return -1;
730 if(set) /* Turn blocking on - ie. clear nonblock flag */
731 val &= ~FLAG_TO_SET;
732 else
733 val |= FLAG_TO_SET;
734 return sys_fcntl_long( fd, F_SETFL, val);
735 #undef FLAG_TO_SET
738 /****************************************************************************
739 Transfer some data between two fd's.
740 ****************************************************************************/
742 #ifndef TRANSFER_BUF_SIZE
743 #define TRANSFER_BUF_SIZE 65536
744 #endif
746 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
747 ssize_t (*write_fn)(int, const void *, size_t))
749 char *buf;
750 size_t total = 0;
751 ssize_t read_ret;
752 ssize_t write_ret;
753 size_t num_to_read_thistime;
754 size_t num_written = 0;
756 if ((buf = SMB_MALLOC(TRANSFER_BUF_SIZE)) == NULL)
757 return -1;
759 while (total < n) {
760 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
762 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
763 if (read_ret == -1) {
764 DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
765 SAFE_FREE(buf);
766 return -1;
768 if (read_ret == 0)
769 break;
771 num_written = 0;
773 while (num_written < read_ret) {
774 write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
776 if (write_ret == -1) {
777 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
778 SAFE_FREE(buf);
779 return -1;
781 if (write_ret == 0)
782 return (ssize_t)total;
784 num_written += (size_t)write_ret;
787 total += (size_t)read_ret;
790 SAFE_FREE(buf);
791 return (ssize_t)total;
794 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
796 return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
799 /*******************************************************************
800 Sleep for a specified number of milliseconds.
801 ********************************************************************/
803 void smb_msleep(unsigned int t)
805 #if defined(HAVE_NANOSLEEP)
806 struct timespec tval;
807 int ret;
809 tval.tv_sec = t/1000;
810 tval.tv_nsec = 1000000*(t%1000);
812 do {
813 errno = 0;
814 ret = nanosleep(&tval, &tval);
815 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
816 #else
817 unsigned int tdiff=0;
818 struct timeval tval,t1,t2;
819 fd_set fds;
821 GetTimeOfDay(&t1);
822 t2 = t1;
824 while (tdiff < t) {
825 tval.tv_sec = (t-tdiff)/1000;
826 tval.tv_usec = 1000*((t-tdiff)%1000);
828 /* Never wait for more than 1 sec. */
829 if (tval.tv_sec > 1) {
830 tval.tv_sec = 1;
831 tval.tv_usec = 0;
834 FD_ZERO(&fds);
835 errno = 0;
836 sys_select_intr(0,&fds,NULL,NULL,&tval);
838 GetTimeOfDay(&t2);
839 if (t2.tv_sec < t1.tv_sec) {
840 /* Someone adjusted time... */
841 t1 = t2;
844 tdiff = TvalDiff(&t1,&t2);
846 #endif
849 /****************************************************************************
850 Become a daemon, discarding the controlling terminal.
851 ****************************************************************************/
853 void become_daemon(BOOL Fork, BOOL no_process_group)
855 if (Fork) {
856 if (sys_fork()) {
857 _exit(0);
861 /* detach from the terminal */
862 #ifdef HAVE_SETSID
863 if (!no_process_group) setsid();
864 #elif defined(TIOCNOTTY)
865 if (!no_process_group) {
866 int i = sys_open("/dev/tty", O_RDWR, 0);
867 if (i != -1) {
868 ioctl(i, (int) TIOCNOTTY, (char *)0);
869 close(i);
872 #endif /* HAVE_SETSID */
874 /* Close fd's 0,1,2. Needed if started by rsh */
875 close_low_fds(False); /* Don't close stderr, let the debug system
876 attach it to the logfile */
879 /****************************************************************************
880 Put up a yes/no prompt.
881 ****************************************************************************/
883 BOOL yesno(char *p)
885 pstring ans;
886 printf("%s",p);
888 if (!fgets(ans,sizeof(ans)-1,stdin))
889 return(False);
891 if (*ans == 'y' || *ans == 'Y')
892 return(True);
894 return(False);
897 #if defined(PARANOID_MALLOC_CHECKER)
899 /****************************************************************************
900 Internal malloc wrapper. Externally visible.
901 ****************************************************************************/
903 void *malloc_(size_t size)
905 #undef malloc
906 return malloc(size);
907 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
910 /****************************************************************************
911 Internal calloc wrapper. Not externally visible.
912 ****************************************************************************/
914 static void *calloc_(size_t count, size_t size)
916 #undef calloc
917 return calloc(count, size);
918 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
921 /****************************************************************************
922 Internal realloc wrapper. Not externally visible.
923 ****************************************************************************/
925 static void *realloc_(void *ptr, size_t size)
927 #undef realloc
928 return realloc(ptr, size);
929 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
932 #endif /* PARANOID_MALLOC_CHECKER */
934 /****************************************************************************
935 Type-safe malloc.
936 ****************************************************************************/
938 void *malloc_array(size_t el_size, unsigned int count)
940 if (count >= MAX_ALLOC_SIZE/el_size) {
941 return NULL;
944 #if defined(PARANOID_MALLOC_CHECKER)
945 return malloc_(el_size*count);
946 #else
947 return malloc(el_size*count);
948 #endif
951 /****************************************************************************
952 Type-safe calloc.
953 ****************************************************************************/
955 void *calloc_array(size_t size, size_t nmemb)
957 if (nmemb >= MAX_ALLOC_SIZE/size) {
958 return NULL;
960 #if defined(PARANOID_MALLOC_CHECKER)
961 return calloc_(nmemb, size);
962 #else
963 return calloc(nmemb, size);
964 #endif
967 /****************************************************************************
968 Expand a pointer to be a particular size.
969 Note that this version of Realloc has an extra parameter that decides
970 whether to free the passed in storage on allocation failure or if the
971 new size is zero.
973 This is designed for use in the typical idiom of :
975 p = SMB_REALLOC(p, size)
976 if (!p) {
977 return error;
980 and not to have to keep track of the old 'p' contents to free later, nor
981 to worry if the size parameter was zero. In the case where NULL is returned
982 we guarentee that p has been freed.
984 If free later semantics are desired, then pass 'free_old_on_error' as False which
985 guarentees that the old contents are not freed on error, even if size == 0. To use
986 this idiom use :
988 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
989 if (!tmp) {
990 SAFE_FREE(p);
991 return error;
992 } else {
993 p = tmp;
996 Changes were instigated by Coverity error checking. JRA.
997 ****************************************************************************/
999 void *Realloc(void *p, size_t size, BOOL free_old_on_error)
1001 void *ret=NULL;
1003 if (size == 0) {
1004 if (free_old_on_error) {
1005 SAFE_FREE(p);
1007 DEBUG(2,("Realloc asked for 0 bytes\n"));
1008 return NULL;
1011 #if defined(PARANOID_MALLOC_CHECKER)
1012 if (!p) {
1013 ret = (void *)malloc_(size);
1014 } else {
1015 ret = (void *)realloc_(p,size);
1017 #else
1018 if (!p) {
1019 ret = (void *)malloc(size);
1020 } else {
1021 ret = (void *)realloc(p,size);
1023 #endif
1025 if (!ret) {
1026 if (free_old_on_error && p) {
1027 SAFE_FREE(p);
1029 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1032 return(ret);
1035 /****************************************************************************
1036 Type-safe realloc.
1037 ****************************************************************************/
1039 void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_on_error)
1041 if (count >= MAX_ALLOC_SIZE/el_size) {
1042 if (free_old_on_error) {
1043 SAFE_FREE(p);
1045 return NULL;
1047 return Realloc(p, el_size*count, free_old_on_error);
1050 /****************************************************************************
1051 (Hopefully) efficient array append.
1052 ****************************************************************************/
1054 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1055 void *element, void **array, uint32 *num_elements,
1056 ssize_t *array_size)
1058 if (*array_size < 0) {
1059 return;
1062 if (*array == NULL) {
1063 if (*array_size == 0) {
1064 *array_size = 128;
1067 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1068 goto error;
1071 if (mem_ctx != NULL) {
1072 *array = TALLOC(mem_ctx, element_size * (*array_size));
1073 } else {
1074 *array = SMB_MALLOC(element_size * (*array_size));
1077 if (*array == NULL) {
1078 goto error;
1082 if (*num_elements == *array_size) {
1083 *array_size *= 2;
1085 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1086 goto error;
1089 if (mem_ctx != NULL) {
1090 *array = TALLOC_REALLOC(mem_ctx, *array,
1091 element_size * (*array_size));
1092 } else {
1093 *array = SMB_REALLOC(*array,
1094 element_size * (*array_size));
1097 if (*array == NULL) {
1098 goto error;
1102 memcpy((char *)(*array) + element_size*(*num_elements),
1103 element, element_size);
1104 *num_elements += 1;
1106 return;
1108 error:
1109 *num_elements = 0;
1110 *array_size = -1;
1113 /****************************************************************************
1114 Free memory, checks for NULL.
1115 Use directly SAFE_FREE()
1116 Exists only because we need to pass a function pointer somewhere --SSS
1117 ****************************************************************************/
1119 void safe_free(void *p)
1121 SAFE_FREE(p);
1124 /****************************************************************************
1125 Get my own name and IP.
1126 ****************************************************************************/
1128 BOOL get_myname(char *my_name)
1130 pstring hostname;
1132 *hostname = 0;
1134 /* get my host name */
1135 if (gethostname(hostname, sizeof(hostname)) == -1) {
1136 DEBUG(0,("gethostname failed\n"));
1137 return False;
1140 /* Ensure null termination. */
1141 hostname[sizeof(hostname)-1] = '\0';
1143 if (my_name) {
1144 /* split off any parts after an initial . */
1145 char *p = strchr_m(hostname,'.');
1147 if (p)
1148 *p = 0;
1150 fstrcpy(my_name,hostname);
1153 return(True);
1156 /****************************************************************************
1157 Get my own canonical name, including domain.
1158 ****************************************************************************/
1160 BOOL get_mydnsfullname(fstring my_dnsname)
1162 static fstring dnshostname;
1163 struct hostent *hp;
1165 if (!*dnshostname) {
1166 /* get my host name */
1167 if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
1168 *dnshostname = '\0';
1169 DEBUG(0,("gethostname failed\n"));
1170 return False;
1173 /* Ensure null termination. */
1174 dnshostname[sizeof(dnshostname)-1] = '\0';
1176 /* Ensure we get the cannonical name. */
1177 if (!(hp = sys_gethostbyname(dnshostname))) {
1178 *dnshostname = '\0';
1179 return False;
1181 fstrcpy(dnshostname, hp->h_name);
1183 fstrcpy(my_dnsname, dnshostname);
1184 return True;
1187 /****************************************************************************
1188 Get my own domain name.
1189 ****************************************************************************/
1191 BOOL get_mydnsdomname(fstring my_domname)
1193 fstring domname;
1194 char *p;
1196 *my_domname = '\0';
1197 if (!get_mydnsfullname(domname)) {
1198 return False;
1200 p = strchr_m(domname, '.');
1201 if (p) {
1202 p++;
1203 fstrcpy(my_domname, p);
1206 return False;
1209 /****************************************************************************
1210 Interpret a protocol description string, with a default.
1211 ****************************************************************************/
1213 int interpret_protocol(const char *str,int def)
1215 if (strequal(str,"NT1"))
1216 return(PROTOCOL_NT1);
1217 if (strequal(str,"LANMAN2"))
1218 return(PROTOCOL_LANMAN2);
1219 if (strequal(str,"LANMAN1"))
1220 return(PROTOCOL_LANMAN1);
1221 if (strequal(str,"CORE"))
1222 return(PROTOCOL_CORE);
1223 if (strequal(str,"COREPLUS"))
1224 return(PROTOCOL_COREPLUS);
1225 if (strequal(str,"CORE+"))
1226 return(PROTOCOL_COREPLUS);
1228 DEBUG(0,("Unrecognised protocol level %s\n",str));
1230 return(def);
1233 /****************************************************************************
1234 Return true if a string could be a pure IP address.
1235 ****************************************************************************/
1237 BOOL is_ipaddress(const char *str)
1239 BOOL pure_address = True;
1240 int i;
1242 for (i=0; pure_address && str[i]; i++)
1243 if (!(isdigit((int)str[i]) || str[i] == '.'))
1244 pure_address = False;
1246 /* Check that a pure number is not misinterpreted as an IP */
1247 pure_address = pure_address && (strchr_m(str, '.') != NULL);
1249 return pure_address;
1252 /****************************************************************************
1253 Interpret an internet address or name into an IP address in 4 byte form.
1254 ****************************************************************************/
1256 uint32 interpret_addr(const char *str)
1258 struct hostent *hp;
1259 uint32 res;
1261 if (strcmp(str,"0.0.0.0") == 0)
1262 return(0);
1263 if (strcmp(str,"255.255.255.255") == 0)
1264 return(0xFFFFFFFF);
1266 /* if it's in the form of an IP address then get the lib to interpret it */
1267 if (is_ipaddress(str)) {
1268 res = inet_addr(str);
1269 } else {
1270 /* otherwise assume it's a network name of some sort and use
1271 sys_gethostbyname */
1272 if ((hp = sys_gethostbyname(str)) == 0) {
1273 DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1274 return 0;
1277 if(hp->h_addr == NULL) {
1278 DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1279 return 0;
1281 putip((char *)&res,(char *)hp->h_addr);
1284 if (res == (uint32)-1)
1285 return(0);
1287 return(res);
1290 /*******************************************************************
1291 A convenient addition to interpret_addr().
1292 ******************************************************************/
1294 struct in_addr *interpret_addr2(const char *str)
1296 static struct in_addr ret;
1297 uint32 a = interpret_addr(str);
1298 ret.s_addr = a;
1299 return(&ret);
1302 /*******************************************************************
1303 Check if an IP is the 0.0.0.0.
1304 ******************************************************************/
1306 BOOL is_zero_ip(struct in_addr ip)
1308 uint32 a;
1309 putip((char *)&a,(char *)&ip);
1310 return(a == 0);
1313 /*******************************************************************
1314 Set an IP to 0.0.0.0.
1315 ******************************************************************/
1317 void zero_ip(struct in_addr *ip)
1319 static BOOL init;
1320 static struct in_addr ipzero;
1322 if (!init) {
1323 ipzero = *interpret_addr2("0.0.0.0");
1324 init = True;
1327 *ip = ipzero;
1330 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1331 /******************************************************************
1332 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1333 Based on a fix from <Thomas.Hepper@icem.de>.
1334 *******************************************************************/
1336 static void strip_mount_options( pstring *str)
1338 if (**str == '-') {
1339 char *p = *str;
1340 while(*p && !isspace(*p))
1341 p++;
1342 while(*p && isspace(*p))
1343 p++;
1344 if(*p) {
1345 pstring tmp_str;
1347 pstrcpy(tmp_str, p);
1348 pstrcpy(*str, tmp_str);
1353 /*******************************************************************
1354 Patch from jkf@soton.ac.uk
1355 Split Luke's automount_server into YP lookup and string splitter
1356 so can easily implement automount_path().
1357 As we may end up doing both, cache the last YP result.
1358 *******************************************************************/
1360 #ifdef WITH_NISPLUS_HOME
1361 char *automount_lookup(const char *user_name)
1363 static fstring last_key = "";
1364 static pstring last_value = "";
1366 char *nis_map = (char *)lp_nis_home_map_name();
1368 char buffer[NIS_MAXATTRVAL + 1];
1369 nis_result *result;
1370 nis_object *object;
1371 entry_obj *entry;
1373 if (strcmp(user_name, last_key)) {
1374 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1375 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1377 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1378 if (result->status != NIS_SUCCESS) {
1379 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1380 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1381 } else {
1382 object = result->objects.objects_val;
1383 if (object->zo_data.zo_type == ENTRY_OBJ) {
1384 entry = &object->zo_data.objdata_u.en_data;
1385 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1386 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1388 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1389 pstring_sub(last_value, "&", user_name);
1390 fstrcpy(last_key, user_name);
1394 nis_freeresult(result);
1397 strip_mount_options(&last_value);
1399 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1400 return last_value;
1402 #else /* WITH_NISPLUS_HOME */
1404 char *automount_lookup(const char *user_name)
1406 static fstring last_key = "";
1407 static pstring last_value = "";
1409 int nis_error; /* returned by yp all functions */
1410 char *nis_result; /* yp_match inits this */
1411 int nis_result_len; /* and set this */
1412 char *nis_domain; /* yp_get_default_domain inits this */
1413 char *nis_map = (char *)lp_nis_home_map_name();
1415 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1416 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1417 return last_value;
1420 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1422 if (!strcmp(user_name, last_key)) {
1423 nis_result = last_value;
1424 nis_result_len = strlen(last_value);
1425 nis_error = 0;
1426 } else {
1427 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1428 &nis_result, &nis_result_len)) == 0) {
1429 fstrcpy(last_key, user_name);
1430 pstrcpy(last_value, nis_result);
1431 strip_mount_options(&last_value);
1433 } else if(nis_error == YPERR_KEY) {
1435 /* If Key lookup fails user home server is not in nis_map
1436 use default information for server, and home directory */
1437 last_value[0] = 0;
1438 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1439 user_name, nis_map));
1440 DEBUG(3, ("using defaults for server and home directory\n"));
1441 } else {
1442 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1443 yperr_string(nis_error), user_name, nis_map));
1447 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1448 return last_value;
1450 #endif /* WITH_NISPLUS_HOME */
1451 #endif
1453 /*******************************************************************
1454 Are two IPs on the same subnet?
1455 ********************************************************************/
1457 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1459 uint32 net1,net2,nmask;
1461 nmask = ntohl(mask.s_addr);
1462 net1 = ntohl(ip1.s_addr);
1463 net2 = ntohl(ip2.s_addr);
1465 return((net1 & nmask) == (net2 & nmask));
1469 /****************************************************************************
1470 Check if a process exists. Does this work on all unixes?
1471 ****************************************************************************/
1473 BOOL process_exists(const struct process_id pid)
1475 if (!procid_is_local(&pid)) {
1476 /* This *SEVERELY* needs fixing. */
1477 return True;
1480 /* Doing kill with a non-positive pid causes messages to be
1481 * sent to places we don't want. */
1482 SMB_ASSERT(pid.pid > 0);
1483 return(kill(pid.pid,0) == 0 || errno != ESRCH);
1486 BOOL process_exists_by_pid(pid_t pid)
1488 return process_exists(pid_to_procid(pid));
1491 /*******************************************************************
1492 Convert a uid into a user name.
1493 ********************************************************************/
1495 const char *uidtoname(uid_t uid)
1497 static fstring name;
1498 struct passwd *pass;
1500 pass = getpwuid_alloc(NULL, uid);
1501 if (pass) {
1502 fstrcpy(name, pass->pw_name);
1503 TALLOC_FREE(pass);
1504 } else {
1505 slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
1507 return name;
1511 /*******************************************************************
1512 Convert a gid into a group name.
1513 ********************************************************************/
1515 char *gidtoname(gid_t gid)
1517 static fstring name;
1518 struct group *grp;
1520 grp = getgrgid(gid);
1521 if (grp)
1522 return(grp->gr_name);
1523 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1524 return(name);
1527 /*******************************************************************
1528 Convert a user name into a uid.
1529 ********************************************************************/
1531 uid_t nametouid(const char *name)
1533 struct passwd *pass;
1534 char *p;
1535 uid_t u;
1537 pass = getpwnam_alloc(NULL, name);
1538 if (pass) {
1539 u = pass->pw_uid;
1540 TALLOC_FREE(pass);
1541 return u;
1544 u = (uid_t)strtol(name, &p, 0);
1545 if ((p != name) && (*p == '\0'))
1546 return u;
1548 return (uid_t)-1;
1551 /*******************************************************************
1552 Convert a name to a gid_t if possible. Return -1 if not a group.
1553 ********************************************************************/
1555 gid_t nametogid(const char *name)
1557 struct group *grp;
1558 char *p;
1559 gid_t g;
1561 g = (gid_t)strtol(name, &p, 0);
1562 if ((p != name) && (*p == '\0'))
1563 return g;
1565 grp = sys_getgrnam(name);
1566 if (grp)
1567 return(grp->gr_gid);
1568 return (gid_t)-1;
1571 /*******************************************************************
1572 Something really nasty happened - panic !
1573 ********************************************************************/
1575 void smb_panic(const char *const why)
1577 char *cmd;
1578 int result;
1580 #ifdef DEVELOPER
1583 if (global_clobber_region_function) {
1584 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1585 global_clobber_region_function,
1586 global_clobber_region_line));
1589 #endif
1591 DEBUG(0,("PANIC (pid %llu): %s\n",
1592 (unsigned long long)sys_getpid(), why));
1593 log_stack_trace();
1595 /* only smbd needs to decrement the smbd counter in connections.tdb */
1596 decrement_smbd_process_count();
1598 cmd = lp_panic_action();
1599 if (cmd && *cmd) {
1600 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1601 result = system(cmd);
1603 if (result == -1)
1604 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1605 strerror(errno)));
1606 else
1607 DEBUG(0, ("smb_panic(): action returned status %d\n",
1608 WEXITSTATUS(result)));
1611 dump_core();
1614 /*******************************************************************
1615 Print a backtrace of the stack to the debug log. This function
1616 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1617 exit shortly after calling it.
1618 ********************************************************************/
1620 #ifdef HAVE_LIBUNWIND_H
1621 #include <libunwind.h>
1622 #endif
1624 #ifdef HAVE_EXECINFO_H
1625 #include <execinfo.h>
1626 #endif
1628 #ifdef HAVE_LIBEXC_H
1629 #include <libexc.h>
1630 #endif
1632 void log_stack_trace(void)
1634 #ifdef HAVE_LIBUNWIND
1635 /* Try to use libunwind before any other technique since on ia64
1636 * libunwind correctly walks the stack in more circumstances than
1637 * backtrace.
1639 unw_cursor_t cursor;
1640 unw_context_t uc;
1641 unsigned i = 0;
1643 char procname[256];
1644 unw_word_t ip, sp, off;
1646 procname[sizeof(procname) - 1] = '\0';
1648 if (unw_getcontext(&uc) != 0) {
1649 goto libunwind_failed;
1652 if (unw_init_local(&cursor, &uc) != 0) {
1653 goto libunwind_failed;
1656 DEBUG(0, ("BACKTRACE:\n"));
1658 do {
1659 ip = sp = 0;
1660 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1661 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1663 switch (unw_get_proc_name(&cursor,
1664 procname, sizeof(procname) - 1, &off) ) {
1665 case 0:
1666 /* Name found. */
1667 case -UNW_ENOMEM:
1668 /* Name truncated. */
1669 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1670 i, procname, (long long)off,
1671 (long long)ip, (long long) sp));
1672 break;
1673 default:
1674 /* case -UNW_ENOINFO: */
1675 /* case -UNW_EUNSPEC: */
1676 /* No symbol name found. */
1677 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1678 i, "<unknown symbol>",
1679 (long long)ip, (long long) sp));
1681 ++i;
1682 } while (unw_step(&cursor) > 0);
1684 return;
1686 libunwind_failed:
1687 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1689 #elif HAVE_BACKTRACE_SYMBOLS
1690 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1691 size_t backtrace_size;
1692 char **backtrace_strings;
1694 /* get the backtrace (stack frames) */
1695 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1696 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1698 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1699 (unsigned long)backtrace_size));
1701 if (backtrace_strings) {
1702 int i;
1704 for (i = 0; i < backtrace_size; i++)
1705 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1707 /* Leak the backtrace_strings, rather than risk what free() might do */
1710 #elif HAVE_LIBEXC
1712 /* The IRIX libexc library provides an API for unwinding the stack. See
1713 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1714 * since we are about to abort anyway, it hardly matters.
1717 #define NAMESIZE 32 /* Arbitrary */
1719 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1720 char * names[BACKTRACE_STACK_SIZE];
1721 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1723 int i;
1724 int levels;
1726 ZERO_ARRAY(addrs);
1727 ZERO_ARRAY(names);
1728 ZERO_ARRAY(namebuf);
1730 /* We need to be root so we can open our /proc entry to walk
1731 * our stack. It also helps when we want to dump core.
1733 become_root();
1735 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1736 names[i] = namebuf + (i * NAMESIZE);
1739 levels = trace_back_stack(0, addrs, names,
1740 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1742 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1743 for (i = 0; i < levels; i++) {
1744 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1746 #undef NAMESIZE
1748 #else
1749 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1750 #endif
1753 /*******************************************************************
1754 A readdir wrapper which just returns the file name.
1755 ********************************************************************/
1757 const char *readdirname(SMB_STRUCT_DIR *p)
1759 SMB_STRUCT_DIRENT *ptr;
1760 char *dname;
1762 if (!p)
1763 return(NULL);
1765 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1766 if (!ptr)
1767 return(NULL);
1769 dname = ptr->d_name;
1771 #ifdef NEXT2
1772 if (telldir(p) < 0)
1773 return(NULL);
1774 #endif
1776 #ifdef HAVE_BROKEN_READDIR_NAME
1777 /* using /usr/ucb/cc is BAD */
1778 dname = dname - 2;
1779 #endif
1782 static pstring buf;
1783 int len = NAMLEN(ptr);
1784 memcpy(buf, dname, len);
1785 buf[len] = 0;
1786 dname = buf;
1789 return(dname);
1792 /*******************************************************************
1793 Utility function used to decide if the last component
1794 of a path matches a (possibly wildcarded) entry in a namelist.
1795 ********************************************************************/
1797 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1799 pstring last_component;
1800 char *p;
1802 /* if we have no list it's obviously not in the path */
1803 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1804 return False;
1807 DEBUG(8, ("is_in_path: %s\n", name));
1809 /* Get the last component of the unix name. */
1810 p = strrchr_m(name, '/');
1811 pstrcpy(last_component, p ? ++p : name);
1813 for(; namelist->name != NULL; namelist++) {
1814 if(namelist->is_wild) {
1815 if (mask_match(last_component, namelist->name, case_sensitive)) {
1816 DEBUG(8,("is_in_path: mask match succeeded\n"));
1817 return True;
1819 } else {
1820 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1821 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1822 DEBUG(8,("is_in_path: match succeeded\n"));
1823 return True;
1827 DEBUG(8,("is_in_path: match not found\n"));
1829 return False;
1832 /*******************************************************************
1833 Strip a '/' separated list into an array of
1834 name_compare_enties structures suitable for
1835 passing to is_in_path(). We do this for
1836 speed so we can pre-parse all the names in the list
1837 and don't do it for each call to is_in_path().
1838 namelist is modified here and is assumed to be
1839 a copy owned by the caller.
1840 We also check if the entry contains a wildcard to
1841 remove a potentially expensive call to mask_match
1842 if possible.
1843 ********************************************************************/
1845 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1847 char *name_end;
1848 char *nameptr = namelist;
1849 int num_entries = 0;
1850 int i;
1852 (*ppname_array) = NULL;
1854 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1855 return;
1857 /* We need to make two passes over the string. The
1858 first to count the number of elements, the second
1859 to split it.
1862 while(*nameptr) {
1863 if ( *nameptr == '/' ) {
1864 /* cope with multiple (useless) /s) */
1865 nameptr++;
1866 continue;
1868 /* find the next / */
1869 name_end = strchr_m(nameptr, '/');
1871 /* oops - the last check for a / didn't find one. */
1872 if (name_end == NULL)
1873 break;
1875 /* next segment please */
1876 nameptr = name_end + 1;
1877 num_entries++;
1880 if(num_entries == 0)
1881 return;
1883 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1884 DEBUG(0,("set_namearray: malloc fail\n"));
1885 return;
1888 /* Now copy out the names */
1889 nameptr = namelist;
1890 i = 0;
1891 while(*nameptr) {
1892 if ( *nameptr == '/' ) {
1893 /* cope with multiple (useless) /s) */
1894 nameptr++;
1895 continue;
1897 /* find the next / */
1898 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1899 *name_end = 0;
1901 /* oops - the last check for a / didn't find one. */
1902 if(name_end == NULL)
1903 break;
1905 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1906 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1907 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1908 return;
1911 /* next segment please */
1912 nameptr = name_end + 1;
1913 i++;
1916 (*ppname_array)[i].name = NULL;
1918 return;
1921 /****************************************************************************
1922 Routine to free a namearray.
1923 ****************************************************************************/
1925 void free_namearray(name_compare_entry *name_array)
1927 int i;
1929 if(name_array == NULL)
1930 return;
1932 for(i=0; name_array[i].name!=NULL; i++)
1933 SAFE_FREE(name_array[i].name);
1934 SAFE_FREE(name_array);
1937 #undef DBGC_CLASS
1938 #define DBGC_CLASS DBGC_LOCKING
1940 /****************************************************************************
1941 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1942 is dealt with in posix.c
1943 Returns True if the lock was granted, False otherwise.
1944 ****************************************************************************/
1946 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1948 SMB_STRUCT_FLOCK lock;
1949 int ret;
1951 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
1953 lock.l_type = type;
1954 lock.l_whence = SEEK_SET;
1955 lock.l_start = offset;
1956 lock.l_len = count;
1957 lock.l_pid = 0;
1959 ret = sys_fcntl_ptr(fd,op,&lock);
1961 if (ret == -1) {
1962 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1963 (double)offset,(double)count,op,type,strerror(errno)));
1964 return False;
1967 /* everything went OK */
1968 DEBUG(8,("fcntl_lock: Lock call successful\n"));
1970 return True;
1973 /****************************************************************************
1974 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1975 is dealt with in posix.c
1976 Returns True if we have information regarding this lock region (and returns
1977 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1978 ****************************************************************************/
1980 BOOL fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1982 SMB_STRUCT_FLOCK lock;
1983 int ret;
1985 DEBUG(8,("fcntl_getlock %d %.0f %.0f %d\n",fd,(double)*poffset,(double)*pcount,*ptype));
1987 lock.l_type = *ptype;
1988 lock.l_whence = SEEK_SET;
1989 lock.l_start = *poffset;
1990 lock.l_len = *pcount;
1991 lock.l_pid = 0;
1993 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1995 if (ret == -1) {
1996 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1997 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1998 return False;
2001 *ptype = lock.l_type;
2002 *poffset = lock.l_start;
2003 *pcount = lock.l_len;
2004 *ppid = lock.l_pid;
2006 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2007 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2008 return True;
2011 #undef DBGC_CLASS
2012 #define DBGC_CLASS DBGC_ALL
2014 /*******************************************************************
2015 Is the name specified one of my netbios names.
2016 Returns true if it is equal, false otherwise.
2017 ********************************************************************/
2019 BOOL is_myname(const char *s)
2021 int n;
2022 BOOL ret = False;
2024 for (n=0; my_netbios_names(n); n++) {
2025 if (strequal(my_netbios_names(n), s)) {
2026 ret=True;
2027 break;
2030 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2031 return(ret);
2034 BOOL is_myname_or_ipaddr(const char *s)
2036 fstring name, dnsname;
2037 char *servername;
2039 if ( !s )
2040 return False;
2042 /* santize the string from '\\name' */
2044 fstrcpy( name, s );
2046 servername = strrchr_m( name, '\\' );
2047 if ( !servername )
2048 servername = name;
2049 else
2050 servername++;
2052 /* optimize for the common case */
2054 if (strequal(servername, global_myname()))
2055 return True;
2057 /* check for an alias */
2059 if (is_myname(servername))
2060 return True;
2062 /* check for loopback */
2064 if (strequal(servername, "localhost"))
2065 return True;
2067 /* maybe it's my dns name */
2069 if ( get_mydnsfullname( dnsname ) )
2070 if ( strequal( servername, dnsname ) )
2071 return True;
2073 /* handle possible CNAME records */
2075 if ( !is_ipaddress( servername ) ) {
2076 /* use DNS to resolve the name, but only the first address */
2077 struct hostent *hp;
2079 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
2080 struct in_addr return_ip;
2081 putip( (char*)&return_ip, (char*)hp->h_addr );
2082 fstrcpy( name, inet_ntoa( return_ip ) );
2083 servername = name;
2087 /* maybe its an IP address? */
2088 if (is_ipaddress(servername)) {
2089 struct iface_struct nics[MAX_INTERFACES];
2090 int i, n;
2091 uint32 ip;
2093 ip = interpret_addr(servername);
2094 if ((ip==0) || (ip==0xffffffff))
2095 return False;
2097 n = get_interfaces(nics, MAX_INTERFACES);
2098 for (i=0; i<n; i++) {
2099 if (ip == nics[i].ip.s_addr)
2100 return True;
2104 /* no match */
2105 return False;
2108 /*******************************************************************
2109 Is the name specified our workgroup/domain.
2110 Returns true if it is equal, false otherwise.
2111 ********************************************************************/
2113 BOOL is_myworkgroup(const char *s)
2115 BOOL ret = False;
2117 if (strequal(s, lp_workgroup())) {
2118 ret=True;
2121 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2122 return(ret);
2125 /*******************************************************************
2126 we distinguish between 2K and XP by the "Native Lan Manager" string
2127 WinXP => "Windows 2002 5.1"
2128 Win2k => "Windows 2000 5.0"
2129 NT4 => "Windows NT 4.0"
2130 Win9x => "Windows 4.0"
2131 Windows 2003 doesn't set the native lan manager string but
2132 they do set the domain to "Windows 2003 5.2" (probably a bug).
2133 ********************************************************************/
2135 void ra_lanman_string( const char *native_lanman )
2137 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2138 set_remote_arch( RA_WINXP );
2139 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2140 set_remote_arch( RA_WIN2K3 );
2143 /*******************************************************************
2144 Set the horrid remote_arch string based on an enum.
2145 ********************************************************************/
2147 void set_remote_arch(enum remote_arch_types type)
2149 ra_type = type;
2150 switch( type ) {
2151 case RA_WFWG:
2152 fstrcpy(remote_arch, "WfWg");
2153 break;
2154 case RA_OS2:
2155 fstrcpy(remote_arch, "OS2");
2156 break;
2157 case RA_WIN95:
2158 fstrcpy(remote_arch, "Win95");
2159 break;
2160 case RA_WINNT:
2161 fstrcpy(remote_arch, "WinNT");
2162 break;
2163 case RA_WIN2K:
2164 fstrcpy(remote_arch, "Win2K");
2165 break;
2166 case RA_WINXP:
2167 fstrcpy(remote_arch, "WinXP");
2168 break;
2169 case RA_WIN2K3:
2170 fstrcpy(remote_arch, "Win2K3");
2171 break;
2172 case RA_SAMBA:
2173 fstrcpy(remote_arch,"Samba");
2174 break;
2175 case RA_CIFSFS:
2176 fstrcpy(remote_arch,"CIFSFS");
2177 break;
2178 default:
2179 ra_type = RA_UNKNOWN;
2180 fstrcpy(remote_arch, "UNKNOWN");
2181 break;
2184 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2187 /*******************************************************************
2188 Get the remote_arch type.
2189 ********************************************************************/
2191 enum remote_arch_types get_remote_arch(void)
2193 return ra_type;
2196 void print_asc(int level, const unsigned char *buf,int len)
2198 int i;
2199 for (i=0;i<len;i++)
2200 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2203 void dump_data(int level, const char *buf1,int len)
2205 const unsigned char *buf = (const unsigned char *)buf1;
2206 int i=0;
2207 if (len<=0) return;
2209 if (!DEBUGLVL(level)) return;
2211 DEBUGADD(level,("[%03X] ",i));
2212 for (i=0;i<len;) {
2213 DEBUGADD(level,("%02X ",(int)buf[i]));
2214 i++;
2215 if (i%8 == 0) DEBUGADD(level,(" "));
2216 if (i%16 == 0) {
2217 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2218 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2219 if (i<len) DEBUGADD(level,("[%03X] ",i));
2222 if (i%16) {
2223 int n;
2224 n = 16 - (i%16);
2225 DEBUGADD(level,(" "));
2226 if (n>8) DEBUGADD(level,(" "));
2227 while (n--) DEBUGADD(level,(" "));
2228 n = MIN(8,i%16);
2229 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2230 n = (i%16) - n;
2231 if (n>0) print_asc(level,&buf[i-n],n);
2232 DEBUGADD(level,("\n"));
2236 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2238 #ifdef DEBUG_PASSWORD
2239 DEBUG(11, ("%s", msg));
2240 if (data != NULL && len > 0)
2242 dump_data(11, (const char *)data, len);
2244 #endif
2247 char *tab_depth(int depth)
2249 static pstring spaces;
2250 memset(spaces, ' ', depth * 4);
2251 spaces[depth * 4] = 0;
2252 return spaces;
2255 /*****************************************************************************
2256 Provide a checksum on a string
2258 Input: s - the null-terminated character string for which the checksum
2259 will be calculated.
2261 Output: The checksum value calculated for s.
2262 *****************************************************************************/
2264 int str_checksum(const char *s)
2266 int res = 0;
2267 int c;
2268 int i=0;
2270 while(*s) {
2271 c = *s;
2272 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2273 s++;
2274 i++;
2276 return(res);
2279 /*****************************************************************
2280 Zero a memory area then free it. Used to catch bugs faster.
2281 *****************************************************************/
2283 void zero_free(void *p, size_t size)
2285 memset(p, 0, size);
2286 SAFE_FREE(p);
2289 /*****************************************************************
2290 Set our open file limit to a requested max and return the limit.
2291 *****************************************************************/
2293 int set_maxfiles(int requested_max)
2295 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2296 struct rlimit rlp;
2297 int saved_current_limit;
2299 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2300 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2301 strerror(errno) ));
2302 /* just guess... */
2303 return requested_max;
2307 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2308 * account for the extra fd we need
2309 * as well as the log files and standard
2310 * handles etc. Save the limit we want to set in case
2311 * we are running on an OS that doesn't support this limit (AIX)
2312 * which always returns RLIM_INFINITY for rlp.rlim_max.
2315 /* Try raising the hard (max) limit to the requested amount. */
2317 #if defined(RLIM_INFINITY)
2318 if (rlp.rlim_max != RLIM_INFINITY) {
2319 int orig_max = rlp.rlim_max;
2321 if ( rlp.rlim_max < requested_max )
2322 rlp.rlim_max = requested_max;
2324 /* This failing is not an error - many systems (Linux) don't
2325 support our default request of 10,000 open files. JRA. */
2327 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2328 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2329 (int)rlp.rlim_max, strerror(errno) ));
2331 /* Set failed - restore original value from get. */
2332 rlp.rlim_max = orig_max;
2335 #endif
2337 /* Now try setting the soft (current) limit. */
2339 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2341 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2342 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2343 (int)rlp.rlim_cur, strerror(errno) ));
2344 /* just guess... */
2345 return saved_current_limit;
2348 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2349 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2350 strerror(errno) ));
2351 /* just guess... */
2352 return saved_current_limit;
2355 #if defined(RLIM_INFINITY)
2356 if(rlp.rlim_cur == RLIM_INFINITY)
2357 return saved_current_limit;
2358 #endif
2360 if((int)rlp.rlim_cur > saved_current_limit)
2361 return saved_current_limit;
2363 return rlp.rlim_cur;
2364 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2366 * No way to know - just guess...
2368 return requested_max;
2369 #endif
2372 /*****************************************************************
2373 Possibly replace mkstemp if it is broken.
2374 *****************************************************************/
2376 int smb_mkstemp(char *name_template)
2378 #if HAVE_SECURE_MKSTEMP
2379 return mkstemp(name_template);
2380 #else
2381 /* have a reasonable go at emulating it. Hope that
2382 the system mktemp() isn't completly hopeless */
2383 char *p = mktemp(name_template);
2384 if (!p)
2385 return -1;
2386 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2387 #endif
2390 /*****************************************************************
2391 malloc that aborts with smb_panic on fail or zero size.
2392 *****************************************************************/
2394 void *smb_xmalloc_array(size_t size, unsigned int count)
2396 void *p;
2397 if (size == 0)
2398 smb_panic("smb_xmalloc_array: called with zero size.\n");
2399 if (count >= MAX_ALLOC_SIZE/size) {
2400 smb_panic("smb_xmalloc: alloc size too large.\n");
2402 if ((p = SMB_MALLOC(size*count)) == NULL) {
2403 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2404 (unsigned long)size, (unsigned long)count));
2405 smb_panic("smb_xmalloc_array: malloc fail.\n");
2407 return p;
2411 Memdup with smb_panic on fail.
2414 void *smb_xmemdup(const void *p, size_t size)
2416 void *p2;
2417 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2418 memcpy(p2, p, size);
2419 return p2;
2423 strdup that aborts on malloc fail.
2426 char *smb_xstrdup(const char *s)
2428 #if defined(PARANOID_MALLOC_CHECKER)
2429 #ifdef strdup
2430 #undef strdup
2431 #endif
2432 #endif
2433 char *s1 = strdup(s);
2434 #if defined(PARANOID_MALLOC_CHECKER)
2435 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2436 #endif
2437 if (!s1)
2438 smb_panic("smb_xstrdup: malloc fail\n");
2439 return s1;
2444 strndup that aborts on malloc fail.
2447 char *smb_xstrndup(const char *s, size_t n)
2449 #if defined(PARANOID_MALLOC_CHECKER)
2450 #ifdef strndup
2451 #undef strndup
2452 #endif
2453 #endif
2454 char *s1 = strndup(s, n);
2455 #if defined(PARANOID_MALLOC_CHECKER)
2456 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2457 #endif
2458 if (!s1)
2459 smb_panic("smb_xstrndup: malloc fail\n");
2460 return s1;
2464 vasprintf that aborts on malloc fail
2467 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2469 int n;
2470 va_list ap2;
2472 VA_COPY(ap2, ap);
2474 n = vasprintf(ptr, format, ap2);
2475 if (n == -1 || ! *ptr)
2476 smb_panic("smb_xvasprintf: out of memory");
2477 return n;
2480 /*****************************************************************
2481 Like strdup but for memory.
2482 *****************************************************************/
2484 void *memdup(const void *p, size_t size)
2486 void *p2;
2487 if (size == 0)
2488 return NULL;
2489 p2 = SMB_MALLOC(size);
2490 if (!p2)
2491 return NULL;
2492 memcpy(p2, p, size);
2493 return p2;
2496 /*****************************************************************
2497 Get local hostname and cache result.
2498 *****************************************************************/
2500 char *myhostname(void)
2502 static pstring ret;
2503 if (ret[0] == 0)
2504 get_myname(ret);
2505 return ret;
2508 /*****************************************************************
2509 A useful function for returning a path in the Samba lock directory.
2510 *****************************************************************/
2512 char *lock_path(const char *name)
2514 static pstring fname;
2516 pstrcpy(fname,lp_lockdir());
2517 trim_char(fname,'\0','/');
2519 if (!directory_exist(fname,NULL))
2520 mkdir(fname,0755);
2522 pstrcat(fname,"/");
2523 pstrcat(fname,name);
2525 return fname;
2528 /*****************************************************************
2529 A useful function for returning a path in the Samba pid directory.
2530 *****************************************************************/
2532 char *pid_path(const char *name)
2534 static pstring fname;
2536 pstrcpy(fname,lp_piddir());
2537 trim_char(fname,'\0','/');
2539 if (!directory_exist(fname,NULL))
2540 mkdir(fname,0755);
2542 pstrcat(fname,"/");
2543 pstrcat(fname,name);
2545 return fname;
2549 * @brief Returns an absolute path to a file in the Samba lib directory.
2551 * @param name File to find, relative to LIBDIR.
2553 * @retval Pointer to a static #pstring containing the full path.
2556 char *lib_path(const char *name)
2558 static pstring fname;
2559 fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2560 return fname;
2564 * @brief Returns the platform specific shared library extension.
2566 * @retval Pointer to a static #fstring containing the extension.
2569 const char *shlib_ext(void)
2571 return dyn_SHLIBEXT;
2574 /*******************************************************************
2575 Given a filename - get its directory name
2576 NB: Returned in static storage. Caveats:
2577 o Not safe in thread environment.
2578 o Caller must not free.
2579 o If caller wishes to preserve, they should copy.
2580 ********************************************************************/
2582 char *parent_dirname(const char *path)
2584 static pstring dirpath;
2585 char *p;
2587 if (!path)
2588 return(NULL);
2590 pstrcpy(dirpath, path);
2591 p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
2592 if (!p) {
2593 pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
2594 } else {
2595 if (p == dirpath)
2596 ++p; /* For root "/", leave "/" in place */
2597 *p = '\0';
2599 return dirpath;
2603 /*******************************************************************
2604 Determine if a pattern contains any Microsoft wildcard characters.
2605 *******************************************************************/
2607 BOOL ms_has_wild(const char *s)
2609 char c;
2611 if (lp_posix_pathnames()) {
2612 /* With posix pathnames no characters are wild. */
2613 return False;
2616 while ((c = *s++)) {
2617 switch (c) {
2618 case '*':
2619 case '?':
2620 case '<':
2621 case '>':
2622 case '"':
2623 return True;
2626 return False;
2629 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2631 smb_ucs2_t c;
2632 if (!s) return False;
2633 while ((c = *s++)) {
2634 switch (c) {
2635 case UCS2_CHAR('*'):
2636 case UCS2_CHAR('?'):
2637 case UCS2_CHAR('<'):
2638 case UCS2_CHAR('>'):
2639 case UCS2_CHAR('"'):
2640 return True;
2643 return False;
2646 /*******************************************************************
2647 A wrapper that handles case sensitivity and the special handling
2648 of the ".." name.
2649 *******************************************************************/
2651 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2653 if (strcmp(string,"..") == 0)
2654 string = ".";
2655 if (strcmp(pattern,".") == 0)
2656 return False;
2658 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2661 /*******************************************************************
2662 A wrapper that handles case sensitivity and the special handling
2663 of the ".." name. Varient that is only called by old search code which requires
2664 pattern translation.
2665 *******************************************************************/
2667 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2669 if (strcmp(string,"..") == 0)
2670 string = ".";
2671 if (strcmp(pattern,".") == 0)
2672 return False;
2674 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2677 /*******************************************************************
2678 A wrapper that handles a list of patters and calls mask_match()
2679 on each. Returns True if any of the patterns match.
2680 *******************************************************************/
2682 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2684 while (listLen-- > 0) {
2685 if (mask_match(string, *list++, is_case_sensitive))
2686 return True;
2688 return False;
2691 /*********************************************************
2692 Recursive routine that is called by unix_wild_match.
2693 *********************************************************/
2695 static BOOL unix_do_match(const char *regexp, const char *str)
2697 const char *p;
2699 for( p = regexp; *p && *str; ) {
2701 switch(*p) {
2702 case '?':
2703 str++;
2704 p++;
2705 break;
2707 case '*':
2710 * Look for a character matching
2711 * the one after the '*'.
2713 p++;
2714 if(!*p)
2715 return True; /* Automatic match */
2716 while(*str) {
2718 while(*str && (*p != *str))
2719 str++;
2722 * Patch from weidel@multichart.de. In the case of the regexp
2723 * '*XX*' we want to ensure there are at least 2 'X' characters
2724 * in the string after the '*' for a match to be made.
2728 int matchcount=0;
2731 * Eat all the characters that match, but count how many there were.
2734 while(*str && (*p == *str)) {
2735 str++;
2736 matchcount++;
2740 * Now check that if the regexp had n identical characters that
2741 * matchcount had at least that many matches.
2744 while ( *(p+1) && (*(p+1) == *p)) {
2745 p++;
2746 matchcount--;
2749 if ( matchcount <= 0 )
2750 return False;
2753 str--; /* We've eaten the match char after the '*' */
2755 if(unix_do_match(p, str))
2756 return True;
2758 if(!*str)
2759 return False;
2760 else
2761 str++;
2763 return False;
2765 default:
2766 if(*str != *p)
2767 return False;
2768 str++;
2769 p++;
2770 break;
2774 if(!*p && !*str)
2775 return True;
2777 if (!*p && str[0] == '.' && str[1] == 0)
2778 return(True);
2780 if (!*str && *p == '?') {
2781 while (*p == '?')
2782 p++;
2783 return(!*p);
2786 if(!*str && (*p == '*' && p[1] == '\0'))
2787 return True;
2789 return False;
2792 /*******************************************************************
2793 Simple case insensitive interface to a UNIX wildcard matcher.
2794 Returns True if match, False if not.
2795 *******************************************************************/
2797 BOOL unix_wild_match(const char *pattern, const char *string)
2799 pstring p2, s2;
2800 char *p;
2802 pstrcpy(p2, pattern);
2803 pstrcpy(s2, string);
2804 strlower_m(p2);
2805 strlower_m(s2);
2807 /* Remove any *? and ** from the pattern as they are meaningless */
2808 for(p = p2; *p; p++)
2809 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2810 pstrcpy( &p[1], &p[2]);
2812 if (strequal(p2,"*"))
2813 return True;
2815 return unix_do_match(p2, s2);
2818 /**********************************************************************
2819 Converts a name to a fully qalified domain name.
2820 ***********************************************************************/
2822 void name_to_fqdn(fstring fqdn, const char *name)
2824 struct hostent *hp = sys_gethostbyname(name);
2825 if ( hp && hp->h_name && *hp->h_name ) {
2826 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name));
2827 fstrcpy(fqdn,hp->h_name);
2828 } else {
2829 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2830 fstrcpy(fqdn, name);
2834 /**********************************************************************
2835 Extension to talloc_get_type: Abort on type mismatch
2836 ***********************************************************************/
2838 void *talloc_check_name_abort(const void *ptr, const char *name)
2840 void *result;
2842 if (ptr == NULL)
2843 return NULL;
2845 result = talloc_check_name(ptr, name);
2846 if (result != NULL)
2847 return result;
2849 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2850 name, talloc_get_name(ptr)));
2851 smb_panic("aborting");
2852 /* Keep the compiler happy */
2853 return NULL;
2857 #ifdef __INSURE__
2859 /*******************************************************************
2860 This routine is a trick to immediately catch errors when debugging
2861 with insure. A xterm with a gdb is popped up when insure catches
2862 a error. It is Linux specific.
2863 ********************************************************************/
2865 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2867 static int (*fn)();
2868 int ret;
2869 char pidstr[10];
2870 /* you can get /usr/bin/backtrace from
2871 http://samba.org/ftp/unpacked/junkcode/backtrace */
2872 pstring cmd = "/usr/bin/backtrace %d";
2874 slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2875 pstring_sub(cmd, "%d", pidstr);
2877 if (!fn) {
2878 static void *h;
2879 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2880 fn = dlsym(h, "_Insure_trap_error");
2882 if (!h || h == _Insure_trap_error) {
2883 h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2884 fn = dlsym(h, "_Insure_trap_error");
2888 ret = fn(a1, a2, a3, a4, a5, a6);
2890 system(cmd);
2892 return ret;
2894 #endif
2896 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2898 switch (share_access & ~FILE_SHARE_DELETE) {
2899 case FILE_SHARE_NONE:
2900 return DENY_ALL;
2901 case FILE_SHARE_READ:
2902 return DENY_WRITE;
2903 case FILE_SHARE_WRITE:
2904 return DENY_READ;
2905 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2906 return DENY_NONE;
2908 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2909 return DENY_DOS;
2910 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2911 return DENY_FCB;
2914 return (uint32)-1;
2917 pid_t procid_to_pid(const struct process_id *proc)
2919 return proc->pid;
2922 struct process_id pid_to_procid(pid_t pid)
2924 struct process_id result;
2925 result.pid = pid;
2926 return result;
2929 struct process_id procid_self(void)
2931 return pid_to_procid(sys_getpid());
2934 BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
2936 return (p1->pid == p2->pid);
2939 BOOL procid_is_me(const struct process_id *pid)
2941 return (pid->pid == sys_getpid());
2944 struct process_id interpret_pid(const char *pid_string)
2946 return pid_to_procid(atoi(pid_string));
2949 char *procid_str_static(const struct process_id *pid)
2951 static fstring str;
2952 fstr_sprintf(str, "%d", pid->pid);
2953 return str;
2956 char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
2958 return talloc_strdup(mem_ctx, procid_str_static(pid));
2961 BOOL procid_valid(const struct process_id *pid)
2963 return (pid->pid != -1);
2966 BOOL procid_is_local(const struct process_id *pid)
2968 return True;