r20090: Fix a class of bugs found by James Peach. Ensure
[Samba/nascimento.git] / source3 / lib / util.c
blobd1801527e972a92bde5792a885df3ce70b608cc8
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;
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_messages();
204 /* release the talloc null_context memory last */
205 talloc_disable_null_tracking();
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 BOOL add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
311 gid_t **gids, size_t *num_gids)
313 int i;
315 if ((*num_gids != 0) && (*gids == NULL)) {
317 * A former call to this routine has failed to allocate memory
319 return False;
322 for (i=0; i<*num_gids; i++) {
323 if ((*gids)[i] == gid) {
324 return True;
328 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
329 if (*gids == NULL) {
330 *num_gids = 0;
331 return False;
334 (*gids)[*num_gids] = gid;
335 *num_gids += 1;
336 return True;
339 /****************************************************************************
340 Like atoi but gets the value up to the separator character.
341 ****************************************************************************/
343 static const char *Atoic(const char *p, int *n, const char *c)
345 if (!isdigit((int)*p)) {
346 DEBUG(5, ("Atoic: malformed number\n"));
347 return NULL;
350 (*n) = atoi(p);
352 while ((*p) && isdigit((int)*p))
353 p++;
355 if (strchr_m(c, *p) == NULL) {
356 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
357 return NULL;
360 return p;
363 /*************************************************************************
364 Reads a list of numbers.
365 *************************************************************************/
367 const char *get_numlist(const char *p, uint32 **num, int *count)
369 int val;
371 if (num == NULL || count == NULL)
372 return NULL;
374 (*count) = 0;
375 (*num ) = NULL;
377 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
378 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
379 if (!(*num)) {
380 return NULL;
382 (*num)[(*count)] = val;
383 (*count)++;
384 p++;
387 return p;
390 /*******************************************************************
391 Check if a file exists - call vfs_file_exist for samba files.
392 ********************************************************************/
394 BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
396 SMB_STRUCT_STAT st;
397 if (!sbuf)
398 sbuf = &st;
400 if (sys_stat(fname,sbuf) != 0)
401 return(False);
403 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
406 /*******************************************************************
407 Check a files mod time.
408 ********************************************************************/
410 time_t file_modtime(const char *fname)
412 SMB_STRUCT_STAT st;
414 if (sys_stat(fname,&st) != 0)
415 return(0);
417 return(st.st_mtime);
420 /*******************************************************************
421 Check if a directory exists.
422 ********************************************************************/
424 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
426 SMB_STRUCT_STAT st2;
427 BOOL ret;
429 if (!st)
430 st = &st2;
432 if (sys_stat(dname,st) != 0)
433 return(False);
435 ret = S_ISDIR(st->st_mode);
436 if(!ret)
437 errno = ENOTDIR;
438 return ret;
441 /*******************************************************************
442 Returns the size in bytes of the named file.
443 ********************************************************************/
445 SMB_OFF_T get_file_size(char *file_name)
447 SMB_STRUCT_STAT buf;
448 buf.st_size = 0;
449 if(sys_stat(file_name,&buf) != 0)
450 return (SMB_OFF_T)-1;
451 return(buf.st_size);
454 /*******************************************************************
455 Return a string representing an attribute for a file.
456 ********************************************************************/
458 char *attrib_string(uint16 mode)
460 static fstring attrstr;
462 attrstr[0] = 0;
464 if (mode & aVOLID) fstrcat(attrstr,"V");
465 if (mode & aDIR) fstrcat(attrstr,"D");
466 if (mode & aARCH) fstrcat(attrstr,"A");
467 if (mode & aHIDDEN) fstrcat(attrstr,"H");
468 if (mode & aSYSTEM) fstrcat(attrstr,"S");
469 if (mode & aRONLY) fstrcat(attrstr,"R");
471 return(attrstr);
474 /*******************************************************************
475 Show a smb message structure.
476 ********************************************************************/
478 void show_msg(char *buf)
480 int i;
481 int bcc=0;
483 if (!DEBUGLVL(5))
484 return;
486 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
487 smb_len(buf),
488 (int)CVAL(buf,smb_com),
489 (int)CVAL(buf,smb_rcls),
490 (int)CVAL(buf,smb_reh),
491 (int)SVAL(buf,smb_err),
492 (int)CVAL(buf,smb_flg),
493 (int)SVAL(buf,smb_flg2)));
494 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
495 (int)SVAL(buf,smb_tid),
496 (int)SVAL(buf,smb_pid),
497 (int)SVAL(buf,smb_uid),
498 (int)SVAL(buf,smb_mid)));
499 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
501 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
502 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
503 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
505 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
507 DEBUGADD(5,("smb_bcc=%d\n",bcc));
509 if (DEBUGLEVEL < 10)
510 return;
512 if (DEBUGLEVEL < 50)
513 bcc = MIN(bcc, 512);
515 dump_data(10, smb_buf(buf), bcc);
518 /*******************************************************************
519 Set the length and marker of an smb packet.
520 ********************************************************************/
522 void smb_setlen(char *buf,int len)
524 _smb_setlen(buf,len);
526 SCVAL(buf,4,0xFF);
527 SCVAL(buf,5,'S');
528 SCVAL(buf,6,'M');
529 SCVAL(buf,7,'B');
532 /*******************************************************************
533 Setup the word count and byte count for a smb message.
534 ********************************************************************/
536 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
538 if (zero && (num_words || num_bytes)) {
539 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
541 SCVAL(buf,smb_wct,num_words);
542 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
543 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
544 return (smb_size + num_words*2 + num_bytes);
547 /*******************************************************************
548 Setup only the byte count for a smb message.
549 ********************************************************************/
551 int set_message_bcc(char *buf,int num_bytes)
553 int num_words = CVAL(buf,smb_wct);
554 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
555 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
556 return (smb_size + num_words*2 + num_bytes);
559 /*******************************************************************
560 Setup only the byte count for a smb message, using the end of the
561 message as a marker.
562 ********************************************************************/
564 int set_message_end(void *outbuf,void *end_ptr)
566 return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
569 /*******************************************************************
570 Reduce a file name, removing .. elements.
571 ********************************************************************/
573 void dos_clean_name(char *s)
575 char *p=NULL;
577 DEBUG(3,("dos_clean_name [%s]\n",s));
579 /* remove any double slashes */
580 all_string_sub(s, "\\\\", "\\", 0);
582 while ((p = strstr_m(s,"\\..\\")) != NULL) {
583 pstring s1;
585 *p = 0;
586 pstrcpy(s1,p+3);
588 if ((p=strrchr_m(s,'\\')) != NULL)
589 *p = 0;
590 else
591 *s = 0;
592 pstrcat(s,s1);
595 trim_string(s,NULL,"\\..");
597 all_string_sub(s, "\\.\\", "\\", 0);
600 /*******************************************************************
601 Reduce a file name, removing .. elements.
602 ********************************************************************/
604 void unix_clean_name(char *s)
606 char *p=NULL;
608 DEBUG(3,("unix_clean_name [%s]\n",s));
610 /* remove any double slashes */
611 all_string_sub(s, "//","/", 0);
613 /* Remove leading ./ characters */
614 if(strncmp(s, "./", 2) == 0) {
615 trim_string(s, "./", NULL);
616 if(*s == 0)
617 pstrcpy(s,"./");
620 while ((p = strstr_m(s,"/../")) != NULL) {
621 pstring s1;
623 *p = 0;
624 pstrcpy(s1,p+3);
626 if ((p=strrchr_m(s,'/')) != NULL)
627 *p = 0;
628 else
629 *s = 0;
630 pstrcat(s,s1);
633 trim_string(s,NULL,"/..");
636 /*******************************************************************
637 Close the low 3 fd's and open dev/null in their place.
638 ********************************************************************/
640 void close_low_fds(BOOL stderr_too)
642 #ifndef VALGRIND
643 int fd;
644 int i;
646 close(0);
647 close(1);
649 if (stderr_too)
650 close(2);
652 /* try and use up these file descriptors, so silly
653 library routines writing to stdout etc won't cause havoc */
654 for (i=0;i<3;i++) {
655 if (i == 2 && !stderr_too)
656 continue;
658 fd = sys_open("/dev/null",O_RDWR,0);
659 if (fd < 0)
660 fd = sys_open("/dev/null",O_WRONLY,0);
661 if (fd < 0) {
662 DEBUG(0,("Can't open /dev/null\n"));
663 return;
665 if (fd != i) {
666 DEBUG(0,("Didn't get file descriptor %d\n",i));
667 return;
670 #endif
673 /*******************************************************************
674 Write data into an fd at a given offset. Ignore seek errors.
675 ********************************************************************/
677 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
679 size_t total=0;
680 ssize_t ret;
682 if (pos == (SMB_OFF_T)-1) {
683 return write_data(fd, buffer, N);
685 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
686 while (total < N) {
687 ret = sys_pwrite(fd,buffer + total,N - total, pos);
688 if (ret == -1 && errno == ESPIPE) {
689 return write_data(fd, buffer + total,N - total);
691 if (ret == -1) {
692 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
693 return -1;
695 if (ret == 0) {
696 return total;
698 total += ret;
699 pos += ret;
701 return (ssize_t)total;
702 #else
703 /* Use lseek and write_data. */
704 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
705 if (errno != ESPIPE) {
706 return -1;
709 return write_data(fd, buffer, N);
710 #endif
713 /****************************************************************************
714 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
715 else
716 if SYSV use O_NDELAY
717 if BSD use FNDELAY
718 ****************************************************************************/
720 int set_blocking(int fd, BOOL set)
722 int val;
723 #ifdef O_NONBLOCK
724 #define FLAG_TO_SET O_NONBLOCK
725 #else
726 #ifdef SYSV
727 #define FLAG_TO_SET O_NDELAY
728 #else /* BSD */
729 #define FLAG_TO_SET FNDELAY
730 #endif
731 #endif
733 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
734 return -1;
735 if(set) /* Turn blocking on - ie. clear nonblock flag */
736 val &= ~FLAG_TO_SET;
737 else
738 val |= FLAG_TO_SET;
739 return sys_fcntl_long( fd, F_SETFL, val);
740 #undef FLAG_TO_SET
743 /****************************************************************************
744 Transfer some data between two fd's.
745 ****************************************************************************/
747 #ifndef TRANSFER_BUF_SIZE
748 #define TRANSFER_BUF_SIZE 65536
749 #endif
751 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
752 ssize_t (*write_fn)(int, const void *, size_t))
754 char *buf;
755 size_t total = 0;
756 ssize_t read_ret;
757 ssize_t write_ret;
758 size_t num_to_read_thistime;
759 size_t num_written = 0;
761 if ((buf = SMB_MALLOC_ARRAY(char, TRANSFER_BUF_SIZE)) == NULL)
762 return -1;
764 while (total < n) {
765 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
767 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
768 if (read_ret == -1) {
769 DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
770 SAFE_FREE(buf);
771 return -1;
773 if (read_ret == 0)
774 break;
776 num_written = 0;
778 while (num_written < read_ret) {
779 write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
781 if (write_ret == -1) {
782 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
783 SAFE_FREE(buf);
784 return -1;
786 if (write_ret == 0)
787 return (ssize_t)total;
789 num_written += (size_t)write_ret;
792 total += (size_t)read_ret;
795 SAFE_FREE(buf);
796 return (ssize_t)total;
799 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
801 return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
804 /*******************************************************************
805 Sleep for a specified number of milliseconds.
806 ********************************************************************/
808 void smb_msleep(unsigned int t)
810 #if defined(HAVE_NANOSLEEP)
811 struct timespec tval;
812 int ret;
814 tval.tv_sec = t/1000;
815 tval.tv_nsec = 1000000*(t%1000);
817 do {
818 errno = 0;
819 ret = nanosleep(&tval, &tval);
820 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
821 #else
822 unsigned int tdiff=0;
823 struct timeval tval,t1,t2;
824 fd_set fds;
826 GetTimeOfDay(&t1);
827 t2 = t1;
829 while (tdiff < t) {
830 tval.tv_sec = (t-tdiff)/1000;
831 tval.tv_usec = 1000*((t-tdiff)%1000);
833 /* Never wait for more than 1 sec. */
834 if (tval.tv_sec > 1) {
835 tval.tv_sec = 1;
836 tval.tv_usec = 0;
839 FD_ZERO(&fds);
840 errno = 0;
841 sys_select_intr(0,&fds,NULL,NULL,&tval);
843 GetTimeOfDay(&t2);
844 if (t2.tv_sec < t1.tv_sec) {
845 /* Someone adjusted time... */
846 t1 = t2;
849 tdiff = TvalDiff(&t1,&t2);
851 #endif
854 /****************************************************************************
855 Become a daemon, discarding the controlling terminal.
856 ****************************************************************************/
858 void become_daemon(BOOL Fork, BOOL no_process_group)
860 if (Fork) {
861 if (sys_fork()) {
862 _exit(0);
866 /* detach from the terminal */
867 #ifdef HAVE_SETSID
868 if (!no_process_group) setsid();
869 #elif defined(TIOCNOTTY)
870 if (!no_process_group) {
871 int i = sys_open("/dev/tty", O_RDWR, 0);
872 if (i != -1) {
873 ioctl(i, (int) TIOCNOTTY, (char *)0);
874 close(i);
877 #endif /* HAVE_SETSID */
879 /* Close fd's 0,1,2. Needed if started by rsh */
880 close_low_fds(False); /* Don't close stderr, let the debug system
881 attach it to the logfile */
884 /****************************************************************************
885 Put up a yes/no prompt.
886 ****************************************************************************/
888 BOOL yesno(char *p)
890 pstring ans;
891 printf("%s",p);
893 if (!fgets(ans,sizeof(ans)-1,stdin))
894 return(False);
896 if (*ans == 'y' || *ans == 'Y')
897 return(True);
899 return(False);
902 #if defined(PARANOID_MALLOC_CHECKER)
904 /****************************************************************************
905 Internal malloc wrapper. Externally visible.
906 ****************************************************************************/
908 void *malloc_(size_t size)
910 #undef malloc
911 return malloc(size);
912 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
915 /****************************************************************************
916 Internal calloc wrapper. Not externally visible.
917 ****************************************************************************/
919 static void *calloc_(size_t count, size_t size)
921 #undef calloc
922 return calloc(count, size);
923 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
926 /****************************************************************************
927 Internal realloc wrapper. Not externally visible.
928 ****************************************************************************/
930 static void *realloc_(void *ptr, size_t size)
932 #undef realloc
933 return realloc(ptr, size);
934 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
937 #endif /* PARANOID_MALLOC_CHECKER */
939 /****************************************************************************
940 Type-safe malloc.
941 ****************************************************************************/
943 void *malloc_array(size_t el_size, unsigned int count)
945 if (count >= MAX_ALLOC_SIZE/el_size) {
946 return NULL;
949 #if defined(PARANOID_MALLOC_CHECKER)
950 return malloc_(el_size*count);
951 #else
952 return malloc(el_size*count);
953 #endif
956 /****************************************************************************
957 Type-safe calloc.
958 ****************************************************************************/
960 void *calloc_array(size_t size, size_t nmemb)
962 if (nmemb >= MAX_ALLOC_SIZE/size) {
963 return NULL;
965 #if defined(PARANOID_MALLOC_CHECKER)
966 return calloc_(nmemb, size);
967 #else
968 return calloc(nmemb, size);
969 #endif
972 /****************************************************************************
973 Expand a pointer to be a particular size.
974 Note that this version of Realloc has an extra parameter that decides
975 whether to free the passed in storage on allocation failure or if the
976 new size is zero.
978 This is designed for use in the typical idiom of :
980 p = SMB_REALLOC(p, size)
981 if (!p) {
982 return error;
985 and not to have to keep track of the old 'p' contents to free later, nor
986 to worry if the size parameter was zero. In the case where NULL is returned
987 we guarentee that p has been freed.
989 If free later semantics are desired, then pass 'free_old_on_error' as False which
990 guarentees that the old contents are not freed on error, even if size == 0. To use
991 this idiom use :
993 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
994 if (!tmp) {
995 SAFE_FREE(p);
996 return error;
997 } else {
998 p = tmp;
1001 Changes were instigated by Coverity error checking. JRA.
1002 ****************************************************************************/
1004 void *Realloc(void *p, size_t size, BOOL free_old_on_error)
1006 void *ret=NULL;
1008 if (size == 0) {
1009 if (free_old_on_error) {
1010 SAFE_FREE(p);
1012 DEBUG(2,("Realloc asked for 0 bytes\n"));
1013 return NULL;
1016 #if defined(PARANOID_MALLOC_CHECKER)
1017 if (!p) {
1018 ret = (void *)malloc_(size);
1019 } else {
1020 ret = (void *)realloc_(p,size);
1022 #else
1023 if (!p) {
1024 ret = (void *)malloc(size);
1025 } else {
1026 ret = (void *)realloc(p,size);
1028 #endif
1030 if (!ret) {
1031 if (free_old_on_error && p) {
1032 SAFE_FREE(p);
1034 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1037 return(ret);
1040 /****************************************************************************
1041 Type-safe realloc.
1042 ****************************************************************************/
1044 void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_on_error)
1046 if (count >= MAX_ALLOC_SIZE/el_size) {
1047 if (free_old_on_error) {
1048 SAFE_FREE(p);
1050 return NULL;
1052 return Realloc(p, el_size*count, free_old_on_error);
1055 /****************************************************************************
1056 (Hopefully) efficient array append.
1057 ****************************************************************************/
1059 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1060 void *element, void *_array, uint32 *num_elements,
1061 ssize_t *array_size)
1063 void **array = (void **)_array;
1065 if (*array_size < 0) {
1066 return;
1069 if (*array == NULL) {
1070 if (*array_size == 0) {
1071 *array_size = 128;
1074 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1075 goto error;
1078 *array = TALLOC(mem_ctx, element_size * (*array_size));
1079 if (*array == NULL) {
1080 goto error;
1084 if (*num_elements == *array_size) {
1085 *array_size *= 2;
1087 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1088 goto error;
1091 *array = TALLOC_REALLOC(mem_ctx, *array,
1092 element_size * (*array_size));
1094 if (*array == NULL) {
1095 goto error;
1099 memcpy((char *)(*array) + element_size*(*num_elements),
1100 element, element_size);
1101 *num_elements += 1;
1103 return;
1105 error:
1106 *num_elements = 0;
1107 *array_size = -1;
1110 /****************************************************************************
1111 Free memory, checks for NULL.
1112 Use directly SAFE_FREE()
1113 Exists only because we need to pass a function pointer somewhere --SSS
1114 ****************************************************************************/
1116 void safe_free(void *p)
1118 SAFE_FREE(p);
1121 /****************************************************************************
1122 Get my own name and IP.
1123 ****************************************************************************/
1125 BOOL get_myname(char *my_name)
1127 pstring hostname;
1129 *hostname = 0;
1131 /* get my host name */
1132 if (gethostname(hostname, sizeof(hostname)) == -1) {
1133 DEBUG(0,("gethostname failed\n"));
1134 return False;
1137 /* Ensure null termination. */
1138 hostname[sizeof(hostname)-1] = '\0';
1140 if (my_name) {
1141 /* split off any parts after an initial . */
1142 char *p = strchr_m(hostname,'.');
1144 if (p)
1145 *p = 0;
1147 fstrcpy(my_name,hostname);
1150 return(True);
1153 /****************************************************************************
1154 Get my own canonical name, including domain.
1155 ****************************************************************************/
1157 BOOL get_mydnsfullname(fstring my_dnsname)
1159 static fstring dnshostname;
1160 struct hostent *hp;
1162 if (!*dnshostname) {
1163 /* get my host name */
1164 if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
1165 *dnshostname = '\0';
1166 DEBUG(0,("gethostname failed\n"));
1167 return False;
1170 /* Ensure null termination. */
1171 dnshostname[sizeof(dnshostname)-1] = '\0';
1173 /* Ensure we get the cannonical name. */
1174 if (!(hp = sys_gethostbyname(dnshostname))) {
1175 *dnshostname = '\0';
1176 return False;
1178 fstrcpy(dnshostname, hp->h_name);
1180 fstrcpy(my_dnsname, dnshostname);
1181 return True;
1184 /****************************************************************************
1185 Get my own domain name.
1186 ****************************************************************************/
1188 BOOL get_mydnsdomname(fstring my_domname)
1190 fstring domname;
1191 char *p;
1193 *my_domname = '\0';
1194 if (!get_mydnsfullname(domname)) {
1195 return False;
1197 p = strchr_m(domname, '.');
1198 if (p) {
1199 p++;
1200 fstrcpy(my_domname, p);
1203 return False;
1206 /****************************************************************************
1207 Interpret a protocol description string, with a default.
1208 ****************************************************************************/
1210 int interpret_protocol(const char *str,int def)
1212 if (strequal(str,"NT1"))
1213 return(PROTOCOL_NT1);
1214 if (strequal(str,"LANMAN2"))
1215 return(PROTOCOL_LANMAN2);
1216 if (strequal(str,"LANMAN1"))
1217 return(PROTOCOL_LANMAN1);
1218 if (strequal(str,"CORE"))
1219 return(PROTOCOL_CORE);
1220 if (strequal(str,"COREPLUS"))
1221 return(PROTOCOL_COREPLUS);
1222 if (strequal(str,"CORE+"))
1223 return(PROTOCOL_COREPLUS);
1225 DEBUG(0,("Unrecognised protocol level %s\n",str));
1227 return(def);
1230 /****************************************************************************
1231 Return true if a string could be a pure IP address.
1232 ****************************************************************************/
1234 BOOL is_ipaddress(const char *str)
1236 BOOL pure_address = True;
1237 int i;
1239 for (i=0; pure_address && str[i]; i++)
1240 if (!(isdigit((int)str[i]) || str[i] == '.'))
1241 pure_address = False;
1243 /* Check that a pure number is not misinterpreted as an IP */
1244 pure_address = pure_address && (strchr_m(str, '.') != NULL);
1246 return pure_address;
1249 /****************************************************************************
1250 Interpret an internet address or name into an IP address in 4 byte form.
1251 ****************************************************************************/
1253 uint32 interpret_addr(const char *str)
1255 struct hostent *hp;
1256 uint32 res;
1258 if (strcmp(str,"0.0.0.0") == 0)
1259 return(0);
1260 if (strcmp(str,"255.255.255.255") == 0)
1261 return(0xFFFFFFFF);
1263 /* if it's in the form of an IP address then get the lib to interpret it */
1264 if (is_ipaddress(str)) {
1265 res = inet_addr(str);
1266 } else {
1267 /* otherwise assume it's a network name of some sort and use
1268 sys_gethostbyname */
1269 if ((hp = sys_gethostbyname(str)) == 0) {
1270 DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1271 return 0;
1274 if(hp->h_addr == NULL) {
1275 DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1276 return 0;
1278 putip((char *)&res,(char *)hp->h_addr);
1281 if (res == (uint32)-1)
1282 return(0);
1284 return(res);
1287 /*******************************************************************
1288 A convenient addition to interpret_addr().
1289 ******************************************************************/
1291 struct in_addr *interpret_addr2(const char *str)
1293 static struct in_addr ret;
1294 uint32 a = interpret_addr(str);
1295 ret.s_addr = a;
1296 return(&ret);
1299 /*******************************************************************
1300 Check if an IP is the 0.0.0.0.
1301 ******************************************************************/
1303 BOOL is_zero_ip(struct in_addr ip)
1305 uint32 a;
1306 putip((char *)&a,(char *)&ip);
1307 return(a == 0);
1310 /*******************************************************************
1311 Set an IP to 0.0.0.0.
1312 ******************************************************************/
1314 void zero_ip(struct in_addr *ip)
1316 static BOOL init;
1317 static struct in_addr ipzero;
1319 if (!init) {
1320 ipzero = *interpret_addr2("0.0.0.0");
1321 init = True;
1324 *ip = ipzero;
1327 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1328 /******************************************************************
1329 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1330 Based on a fix from <Thomas.Hepper@icem.de>.
1331 *******************************************************************/
1333 static void strip_mount_options( pstring *str)
1335 if (**str == '-') {
1336 char *p = *str;
1337 while(*p && !isspace(*p))
1338 p++;
1339 while(*p && isspace(*p))
1340 p++;
1341 if(*p) {
1342 pstring tmp_str;
1344 pstrcpy(tmp_str, p);
1345 pstrcpy(*str, tmp_str);
1350 /*******************************************************************
1351 Patch from jkf@soton.ac.uk
1352 Split Luke's automount_server into YP lookup and string splitter
1353 so can easily implement automount_path().
1354 As we may end up doing both, cache the last YP result.
1355 *******************************************************************/
1357 #ifdef WITH_NISPLUS_HOME
1358 char *automount_lookup(const char *user_name)
1360 static fstring last_key = "";
1361 static pstring last_value = "";
1363 char *nis_map = (char *)lp_nis_home_map_name();
1365 char buffer[NIS_MAXATTRVAL + 1];
1366 nis_result *result;
1367 nis_object *object;
1368 entry_obj *entry;
1370 if (strcmp(user_name, last_key)) {
1371 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1372 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1374 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1375 if (result->status != NIS_SUCCESS) {
1376 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1377 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1378 } else {
1379 object = result->objects.objects_val;
1380 if (object->zo_data.zo_type == ENTRY_OBJ) {
1381 entry = &object->zo_data.objdata_u.en_data;
1382 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1383 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1385 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1386 pstring_sub(last_value, "&", user_name);
1387 fstrcpy(last_key, user_name);
1391 nis_freeresult(result);
1394 strip_mount_options(&last_value);
1396 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1397 return last_value;
1399 #else /* WITH_NISPLUS_HOME */
1401 char *automount_lookup(const char *user_name)
1403 static fstring last_key = "";
1404 static pstring last_value = "";
1406 int nis_error; /* returned by yp all functions */
1407 char *nis_result; /* yp_match inits this */
1408 int nis_result_len; /* and set this */
1409 char *nis_domain; /* yp_get_default_domain inits this */
1410 char *nis_map = (char *)lp_nis_home_map_name();
1412 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1413 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1414 return last_value;
1417 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1419 if (!strcmp(user_name, last_key)) {
1420 nis_result = last_value;
1421 nis_result_len = strlen(last_value);
1422 nis_error = 0;
1423 } else {
1424 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1425 &nis_result, &nis_result_len)) == 0) {
1426 fstrcpy(last_key, user_name);
1427 pstrcpy(last_value, nis_result);
1428 strip_mount_options(&last_value);
1430 } else if(nis_error == YPERR_KEY) {
1432 /* If Key lookup fails user home server is not in nis_map
1433 use default information for server, and home directory */
1434 last_value[0] = 0;
1435 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1436 user_name, nis_map));
1437 DEBUG(3, ("using defaults for server and home directory\n"));
1438 } else {
1439 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1440 yperr_string(nis_error), user_name, nis_map));
1444 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1445 return last_value;
1447 #endif /* WITH_NISPLUS_HOME */
1448 #endif
1450 /*******************************************************************
1451 Are two IPs on the same subnet?
1452 ********************************************************************/
1454 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1456 uint32 net1,net2,nmask;
1458 nmask = ntohl(mask.s_addr);
1459 net1 = ntohl(ip1.s_addr);
1460 net2 = ntohl(ip2.s_addr);
1462 return((net1 & nmask) == (net2 & nmask));
1466 /****************************************************************************
1467 Check if a process exists. Does this work on all unixes?
1468 ****************************************************************************/
1470 BOOL process_exists(const struct process_id pid)
1472 if (procid_is_me(&pid)) {
1473 return True;
1476 if (!procid_is_local(&pid)) {
1477 /* This *SEVERELY* needs fixing. */
1478 return True;
1481 /* Doing kill with a non-positive pid causes messages to be
1482 * sent to places we don't want. */
1483 SMB_ASSERT(pid.pid > 0);
1484 return(kill(pid.pid,0) == 0 || errno != ESRCH);
1487 BOOL process_exists_by_pid(pid_t pid)
1489 return process_exists(pid_to_procid(pid));
1492 /*******************************************************************
1493 Convert a uid into a user name.
1494 ********************************************************************/
1496 const char *uidtoname(uid_t uid)
1498 static fstring name;
1499 struct passwd *pass;
1501 pass = getpwuid_alloc(NULL, uid);
1502 if (pass) {
1503 fstrcpy(name, pass->pw_name);
1504 TALLOC_FREE(pass);
1505 } else {
1506 slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
1508 return name;
1512 /*******************************************************************
1513 Convert a gid into a group name.
1514 ********************************************************************/
1516 char *gidtoname(gid_t gid)
1518 static fstring name;
1519 struct group *grp;
1521 grp = getgrgid(gid);
1522 if (grp)
1523 return(grp->gr_name);
1524 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1525 return(name);
1528 /*******************************************************************
1529 Convert a user name into a uid.
1530 ********************************************************************/
1532 uid_t nametouid(const char *name)
1534 struct passwd *pass;
1535 char *p;
1536 uid_t u;
1538 pass = getpwnam_alloc(NULL, name);
1539 if (pass) {
1540 u = pass->pw_uid;
1541 TALLOC_FREE(pass);
1542 return u;
1545 u = (uid_t)strtol(name, &p, 0);
1546 if ((p != name) && (*p == '\0'))
1547 return u;
1549 return (uid_t)-1;
1552 /*******************************************************************
1553 Convert a name to a gid_t if possible. Return -1 if not a group.
1554 ********************************************************************/
1556 gid_t nametogid(const char *name)
1558 struct group *grp;
1559 char *p;
1560 gid_t g;
1562 g = (gid_t)strtol(name, &p, 0);
1563 if ((p != name) && (*p == '\0'))
1564 return g;
1566 grp = sys_getgrnam(name);
1567 if (grp)
1568 return(grp->gr_gid);
1569 return (gid_t)-1;
1572 /*******************************************************************
1573 Something really nasty happened - panic !
1574 ********************************************************************/
1576 void smb_panic(const char *const why)
1578 char *cmd;
1579 int result;
1581 #ifdef DEVELOPER
1584 if (global_clobber_region_function) {
1585 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1586 global_clobber_region_function,
1587 global_clobber_region_line));
1590 #endif
1592 DEBUG(0,("PANIC (pid %llu): %s\n",
1593 (unsigned long long)sys_getpid(), why));
1594 log_stack_trace();
1596 cmd = lp_panic_action();
1597 if (cmd && *cmd) {
1598 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1599 result = system(cmd);
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)));
1609 dump_core();
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 ********************************************************************/
1618 #ifdef HAVE_LIBUNWIND_H
1619 #include <libunwind.h>
1620 #endif
1622 #ifdef HAVE_EXECINFO_H
1623 #include <execinfo.h>
1624 #endif
1626 #ifdef HAVE_LIBEXC_H
1627 #include <libexc.h>
1628 #endif
1630 void log_stack_trace(void)
1632 #ifdef HAVE_LIBUNWIND
1633 /* Try to use libunwind before any other technique since on ia64
1634 * libunwind correctly walks the stack in more circumstances than
1635 * backtrace.
1637 unw_cursor_t cursor;
1638 unw_context_t uc;
1639 unsigned i = 0;
1641 char procname[256];
1642 unw_word_t ip, sp, off;
1644 procname[sizeof(procname) - 1] = '\0';
1646 if (unw_getcontext(&uc) != 0) {
1647 goto libunwind_failed;
1650 if (unw_init_local(&cursor, &uc) != 0) {
1651 goto libunwind_failed;
1654 DEBUG(0, ("BACKTRACE:\n"));
1656 do {
1657 ip = sp = 0;
1658 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1659 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1661 switch (unw_get_proc_name(&cursor,
1662 procname, sizeof(procname) - 1, &off) ) {
1663 case 0:
1664 /* Name found. */
1665 case -UNW_ENOMEM:
1666 /* Name truncated. */
1667 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1668 i, procname, (long long)off,
1669 (long long)ip, (long long) sp));
1670 break;
1671 default:
1672 /* case -UNW_ENOINFO: */
1673 /* case -UNW_EUNSPEC: */
1674 /* No symbol name found. */
1675 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1676 i, "<unknown symbol>",
1677 (long long)ip, (long long) sp));
1679 ++i;
1680 } while (unw_step(&cursor) > 0);
1682 return;
1684 libunwind_failed:
1685 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1687 #elif HAVE_BACKTRACE_SYMBOLS
1688 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1689 size_t backtrace_size;
1690 char **backtrace_strings;
1692 /* get the backtrace (stack frames) */
1693 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1694 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1696 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1697 (unsigned long)backtrace_size));
1699 if (backtrace_strings) {
1700 int i;
1702 for (i = 0; i < backtrace_size; i++)
1703 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1705 /* Leak the backtrace_strings, rather than risk what free() might do */
1708 #elif HAVE_LIBEXC
1710 /* The IRIX libexc library provides an API for unwinding the stack. See
1711 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1712 * since we are about to abort anyway, it hardly matters.
1715 #define NAMESIZE 32 /* Arbitrary */
1717 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1718 char * names[BACKTRACE_STACK_SIZE];
1719 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1721 int i;
1722 int levels;
1724 ZERO_ARRAY(addrs);
1725 ZERO_ARRAY(names);
1726 ZERO_ARRAY(namebuf);
1728 /* We need to be root so we can open our /proc entry to walk
1729 * our stack. It also helps when we want to dump core.
1731 become_root();
1733 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1734 names[i] = namebuf + (i * NAMESIZE);
1737 levels = trace_back_stack(0, addrs, names,
1738 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1740 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1741 for (i = 0; i < levels; i++) {
1742 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1744 #undef NAMESIZE
1746 #else
1747 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1748 #endif
1751 /*******************************************************************
1752 A readdir wrapper which just returns the file name.
1753 ********************************************************************/
1755 const char *readdirname(SMB_STRUCT_DIR *p)
1757 SMB_STRUCT_DIRENT *ptr;
1758 char *dname;
1760 if (!p)
1761 return(NULL);
1763 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1764 if (!ptr)
1765 return(NULL);
1767 dname = ptr->d_name;
1769 #ifdef NEXT2
1770 if (telldir(p) < 0)
1771 return(NULL);
1772 #endif
1774 #ifdef HAVE_BROKEN_READDIR_NAME
1775 /* using /usr/ucb/cc is BAD */
1776 dname = dname - 2;
1777 #endif
1780 static pstring buf;
1781 int len = NAMLEN(ptr);
1782 memcpy(buf, dname, len);
1783 buf[len] = 0;
1784 dname = buf;
1787 return(dname);
1790 /*******************************************************************
1791 Utility function used to decide if the last component
1792 of a path matches a (possibly wildcarded) entry in a namelist.
1793 ********************************************************************/
1795 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1797 pstring last_component;
1798 char *p;
1800 /* if we have no list it's obviously not in the path */
1801 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1802 return False;
1805 DEBUG(8, ("is_in_path: %s\n", name));
1807 /* Get the last component of the unix name. */
1808 p = strrchr_m(name, '/');
1809 pstrcpy(last_component, p ? ++p : name);
1811 for(; namelist->name != NULL; namelist++) {
1812 if(namelist->is_wild) {
1813 if (mask_match(last_component, namelist->name, case_sensitive)) {
1814 DEBUG(8,("is_in_path: mask match succeeded\n"));
1815 return True;
1817 } else {
1818 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1819 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1820 DEBUG(8,("is_in_path: match succeeded\n"));
1821 return True;
1825 DEBUG(8,("is_in_path: match not found\n"));
1827 return False;
1830 /*******************************************************************
1831 Strip a '/' separated list into an array of
1832 name_compare_enties structures suitable for
1833 passing to is_in_path(). We do this for
1834 speed so we can pre-parse all the names in the list
1835 and don't do it for each call to is_in_path().
1836 namelist is modified here and is assumed to be
1837 a copy owned by the caller.
1838 We also check if the entry contains a wildcard to
1839 remove a potentially expensive call to mask_match
1840 if possible.
1841 ********************************************************************/
1843 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1845 char *name_end;
1846 char *nameptr = namelist;
1847 int num_entries = 0;
1848 int i;
1850 (*ppname_array) = NULL;
1852 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1853 return;
1855 /* We need to make two passes over the string. The
1856 first to count the number of elements, the second
1857 to split it.
1860 while(*nameptr) {
1861 if ( *nameptr == '/' ) {
1862 /* cope with multiple (useless) /s) */
1863 nameptr++;
1864 continue;
1866 /* find the next / */
1867 name_end = strchr_m(nameptr, '/');
1869 /* oops - the last check for a / didn't find one. */
1870 if (name_end == NULL)
1871 break;
1873 /* next segment please */
1874 nameptr = name_end + 1;
1875 num_entries++;
1878 if(num_entries == 0)
1879 return;
1881 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1882 DEBUG(0,("set_namearray: malloc fail\n"));
1883 return;
1886 /* Now copy out the names */
1887 nameptr = namelist;
1888 i = 0;
1889 while(*nameptr) {
1890 if ( *nameptr == '/' ) {
1891 /* cope with multiple (useless) /s) */
1892 nameptr++;
1893 continue;
1895 /* find the next / */
1896 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1897 *name_end = 0;
1899 /* oops - the last check for a / didn't find one. */
1900 if(name_end == NULL)
1901 break;
1903 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1904 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1905 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1906 return;
1909 /* next segment please */
1910 nameptr = name_end + 1;
1911 i++;
1914 (*ppname_array)[i].name = NULL;
1916 return;
1919 /****************************************************************************
1920 Routine to free a namearray.
1921 ****************************************************************************/
1923 void free_namearray(name_compare_entry *name_array)
1925 int i;
1927 if(name_array == NULL)
1928 return;
1930 for(i=0; name_array[i].name!=NULL; i++)
1931 SAFE_FREE(name_array[i].name);
1932 SAFE_FREE(name_array);
1935 #undef DBGC_CLASS
1936 #define DBGC_CLASS DBGC_LOCKING
1938 /****************************************************************************
1939 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1940 is dealt with in posix.c
1941 Returns True if the lock was granted, False otherwise.
1942 ****************************************************************************/
1944 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1946 SMB_STRUCT_FLOCK lock;
1947 int ret;
1949 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1950 fd,op,(double)offset,(double)count,type));
1952 lock.l_type = type;
1953 lock.l_whence = SEEK_SET;
1954 lock.l_start = offset;
1955 lock.l_len = count;
1956 lock.l_pid = 0;
1958 ret = sys_fcntl_ptr(fd,op,&lock);
1960 if (ret == -1) {
1961 int sav = errno;
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 errno = sav;
1965 return False;
1968 /* everything went OK */
1969 DEBUG(8,("fcntl_lock: Lock call successful\n"));
1971 return True;
1974 /****************************************************************************
1975 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1976 is dealt with in posix.c
1977 Returns True if we have information regarding this lock region (and returns
1978 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1979 ****************************************************************************/
1981 BOOL fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1983 SMB_STRUCT_FLOCK lock;
1984 int ret;
1986 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1987 fd,(double)*poffset,(double)*pcount,*ptype));
1989 lock.l_type = *ptype;
1990 lock.l_whence = SEEK_SET;
1991 lock.l_start = *poffset;
1992 lock.l_len = *pcount;
1993 lock.l_pid = 0;
1995 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1997 if (ret == -1) {
1998 int sav = errno;
1999 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2000 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2001 errno = sav;
2002 return False;
2005 *ptype = lock.l_type;
2006 *poffset = lock.l_start;
2007 *pcount = lock.l_len;
2008 *ppid = lock.l_pid;
2010 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2011 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2012 return True;
2015 #undef DBGC_CLASS
2016 #define DBGC_CLASS DBGC_ALL
2018 /*******************************************************************
2019 Is the name specified one of my netbios names.
2020 Returns true if it is equal, false otherwise.
2021 ********************************************************************/
2023 BOOL is_myname(const char *s)
2025 int n;
2026 BOOL ret = False;
2028 for (n=0; my_netbios_names(n); n++) {
2029 if (strequal(my_netbios_names(n), s)) {
2030 ret=True;
2031 break;
2034 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2035 return(ret);
2038 BOOL is_myname_or_ipaddr(const char *s)
2040 fstring name, dnsname;
2041 char *servername;
2043 if ( !s )
2044 return False;
2046 /* santize the string from '\\name' */
2048 fstrcpy( name, s );
2050 servername = strrchr_m( name, '\\' );
2051 if ( !servername )
2052 servername = name;
2053 else
2054 servername++;
2056 /* optimize for the common case */
2058 if (strequal(servername, global_myname()))
2059 return True;
2061 /* check for an alias */
2063 if (is_myname(servername))
2064 return True;
2066 /* check for loopback */
2068 if (strequal(servername, "localhost"))
2069 return True;
2071 /* maybe it's my dns name */
2073 if ( get_mydnsfullname( dnsname ) )
2074 if ( strequal( servername, dnsname ) )
2075 return True;
2077 /* handle possible CNAME records */
2079 if ( !is_ipaddress( servername ) ) {
2080 /* use DNS to resolve the name, but only the first address */
2081 struct hostent *hp;
2083 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
2084 struct in_addr return_ip;
2085 putip( (char*)&return_ip, (char*)hp->h_addr );
2086 fstrcpy( name, inet_ntoa( return_ip ) );
2087 servername = name;
2091 /* maybe its an IP address? */
2092 if (is_ipaddress(servername)) {
2093 struct iface_struct nics[MAX_INTERFACES];
2094 int i, n;
2095 uint32 ip;
2097 ip = interpret_addr(servername);
2098 if ((ip==0) || (ip==0xffffffff))
2099 return False;
2101 n = get_interfaces(nics, MAX_INTERFACES);
2102 for (i=0; i<n; i++) {
2103 if (ip == nics[i].ip.s_addr)
2104 return True;
2108 /* no match */
2109 return False;
2112 /*******************************************************************
2113 Is the name specified our workgroup/domain.
2114 Returns true if it is equal, false otherwise.
2115 ********************************************************************/
2117 BOOL is_myworkgroup(const char *s)
2119 BOOL ret = False;
2121 if (strequal(s, lp_workgroup())) {
2122 ret=True;
2125 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2126 return(ret);
2129 /*******************************************************************
2130 we distinguish between 2K and XP by the "Native Lan Manager" string
2131 WinXP => "Windows 2002 5.1"
2132 Win2k => "Windows 2000 5.0"
2133 NT4 => "Windows NT 4.0"
2134 Win9x => "Windows 4.0"
2135 Windows 2003 doesn't set the native lan manager string but
2136 they do set the domain to "Windows 2003 5.2" (probably a bug).
2137 ********************************************************************/
2139 void ra_lanman_string( const char *native_lanman )
2141 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2142 set_remote_arch( RA_WINXP );
2143 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2144 set_remote_arch( RA_WIN2K3 );
2147 /*******************************************************************
2148 Set the horrid remote_arch string based on an enum.
2149 ********************************************************************/
2151 void set_remote_arch(enum remote_arch_types type)
2153 ra_type = type;
2154 switch( type ) {
2155 case RA_WFWG:
2156 fstrcpy(remote_arch, "WfWg");
2157 break;
2158 case RA_OS2:
2159 fstrcpy(remote_arch, "OS2");
2160 break;
2161 case RA_WIN95:
2162 fstrcpy(remote_arch, "Win95");
2163 break;
2164 case RA_WINNT:
2165 fstrcpy(remote_arch, "WinNT");
2166 break;
2167 case RA_WIN2K:
2168 fstrcpy(remote_arch, "Win2K");
2169 break;
2170 case RA_WINXP:
2171 fstrcpy(remote_arch, "WinXP");
2172 break;
2173 case RA_WIN2K3:
2174 fstrcpy(remote_arch, "Win2K3");
2175 break;
2176 case RA_SAMBA:
2177 fstrcpy(remote_arch,"Samba");
2178 break;
2179 case RA_CIFSFS:
2180 fstrcpy(remote_arch,"CIFSFS");
2181 break;
2182 default:
2183 ra_type = RA_UNKNOWN;
2184 fstrcpy(remote_arch, "UNKNOWN");
2185 break;
2188 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2191 /*******************************************************************
2192 Get the remote_arch type.
2193 ********************************************************************/
2195 enum remote_arch_types get_remote_arch(void)
2197 return ra_type;
2200 void print_asc(int level, const unsigned char *buf,int len)
2202 int i;
2203 for (i=0;i<len;i++)
2204 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2207 void dump_data(int level, const char *buf1,int len)
2209 const unsigned char *buf = (const unsigned char *)buf1;
2210 int i=0;
2211 if (len<=0) return;
2213 if (!DEBUGLVL(level)) return;
2215 DEBUGADD(level,("[%03X] ",i));
2216 for (i=0;i<len;) {
2217 DEBUGADD(level,("%02X ",(int)buf[i]));
2218 i++;
2219 if (i%8 == 0) DEBUGADD(level,(" "));
2220 if (i%16 == 0) {
2221 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2222 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2223 if (i<len) DEBUGADD(level,("[%03X] ",i));
2226 if (i%16) {
2227 int n;
2228 n = 16 - (i%16);
2229 DEBUGADD(level,(" "));
2230 if (n>8) DEBUGADD(level,(" "));
2231 while (n--) DEBUGADD(level,(" "));
2232 n = MIN(8,i%16);
2233 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2234 n = (i%16) - n;
2235 if (n>0) print_asc(level,&buf[i-n],n);
2236 DEBUGADD(level,("\n"));
2240 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2242 #ifdef DEBUG_PASSWORD
2243 DEBUG(11, ("%s", msg));
2244 if (data != NULL && len > 0)
2246 dump_data(11, (const char *)data, len);
2248 #endif
2251 char *tab_depth(int depth)
2253 static pstring spaces;
2254 memset(spaces, ' ', depth * 4);
2255 spaces[depth * 4] = 0;
2256 return spaces;
2259 /*****************************************************************************
2260 Provide a checksum on a string
2262 Input: s - the null-terminated character string for which the checksum
2263 will be calculated.
2265 Output: The checksum value calculated for s.
2266 *****************************************************************************/
2268 int str_checksum(const char *s)
2270 int res = 0;
2271 int c;
2272 int i=0;
2274 while(*s) {
2275 c = *s;
2276 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2277 s++;
2278 i++;
2280 return(res);
2283 /*****************************************************************
2284 Zero a memory area then free it. Used to catch bugs faster.
2285 *****************************************************************/
2287 void zero_free(void *p, size_t size)
2289 memset(p, 0, size);
2290 SAFE_FREE(p);
2293 /*****************************************************************
2294 Set our open file limit to a requested max and return the limit.
2295 *****************************************************************/
2297 int set_maxfiles(int requested_max)
2299 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2300 struct rlimit rlp;
2301 int saved_current_limit;
2303 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2304 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2305 strerror(errno) ));
2306 /* just guess... */
2307 return requested_max;
2311 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2312 * account for the extra fd we need
2313 * as well as the log files and standard
2314 * handles etc. Save the limit we want to set in case
2315 * we are running on an OS that doesn't support this limit (AIX)
2316 * which always returns RLIM_INFINITY for rlp.rlim_max.
2319 /* Try raising the hard (max) limit to the requested amount. */
2321 #if defined(RLIM_INFINITY)
2322 if (rlp.rlim_max != RLIM_INFINITY) {
2323 int orig_max = rlp.rlim_max;
2325 if ( rlp.rlim_max < requested_max )
2326 rlp.rlim_max = requested_max;
2328 /* This failing is not an error - many systems (Linux) don't
2329 support our default request of 10,000 open files. JRA. */
2331 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2332 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2333 (int)rlp.rlim_max, strerror(errno) ));
2335 /* Set failed - restore original value from get. */
2336 rlp.rlim_max = orig_max;
2339 #endif
2341 /* Now try setting the soft (current) limit. */
2343 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2345 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2346 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2347 (int)rlp.rlim_cur, strerror(errno) ));
2348 /* just guess... */
2349 return saved_current_limit;
2352 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2353 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2354 strerror(errno) ));
2355 /* just guess... */
2356 return saved_current_limit;
2359 #if defined(RLIM_INFINITY)
2360 if(rlp.rlim_cur == RLIM_INFINITY)
2361 return saved_current_limit;
2362 #endif
2364 if((int)rlp.rlim_cur > saved_current_limit)
2365 return saved_current_limit;
2367 return rlp.rlim_cur;
2368 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2370 * No way to know - just guess...
2372 return requested_max;
2373 #endif
2376 /*****************************************************************
2377 Possibly replace mkstemp if it is broken.
2378 *****************************************************************/
2380 int smb_mkstemp(char *name_template)
2382 #if HAVE_SECURE_MKSTEMP
2383 return mkstemp(name_template);
2384 #else
2385 /* have a reasonable go at emulating it. Hope that
2386 the system mktemp() isn't completly hopeless */
2387 char *p = mktemp(name_template);
2388 if (!p)
2389 return -1;
2390 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2391 #endif
2394 /*****************************************************************
2395 malloc that aborts with smb_panic on fail or zero size.
2396 *****************************************************************/
2398 void *smb_xmalloc_array(size_t size, unsigned int count)
2400 void *p;
2401 if (size == 0)
2402 smb_panic("smb_xmalloc_array: called with zero size.\n");
2403 if (count >= MAX_ALLOC_SIZE/size) {
2404 smb_panic("smb_xmalloc: alloc size too large.\n");
2406 if ((p = SMB_MALLOC(size*count)) == NULL) {
2407 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2408 (unsigned long)size, (unsigned long)count));
2409 smb_panic("smb_xmalloc_array: malloc fail.\n");
2411 return p;
2415 Memdup with smb_panic on fail.
2418 void *smb_xmemdup(const void *p, size_t size)
2420 void *p2;
2421 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2422 memcpy(p2, p, size);
2423 return p2;
2427 strdup that aborts on malloc fail.
2430 char *smb_xstrdup(const char *s)
2432 #if defined(PARANOID_MALLOC_CHECKER)
2433 #ifdef strdup
2434 #undef strdup
2435 #endif
2436 #endif
2437 char *s1 = strdup(s);
2438 #if defined(PARANOID_MALLOC_CHECKER)
2439 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2440 #endif
2441 if (!s1)
2442 smb_panic("smb_xstrdup: malloc fail\n");
2443 return s1;
2448 strndup that aborts on malloc fail.
2451 char *smb_xstrndup(const char *s, size_t n)
2453 #if defined(PARANOID_MALLOC_CHECKER)
2454 #ifdef strndup
2455 #undef strndup
2456 #endif
2457 #endif
2458 char *s1 = strndup(s, n);
2459 #if defined(PARANOID_MALLOC_CHECKER)
2460 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2461 #endif
2462 if (!s1)
2463 smb_panic("smb_xstrndup: malloc fail\n");
2464 return s1;
2468 vasprintf that aborts on malloc fail
2471 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2473 int n;
2474 va_list ap2;
2476 VA_COPY(ap2, ap);
2478 n = vasprintf(ptr, format, ap2);
2479 if (n == -1 || ! *ptr)
2480 smb_panic("smb_xvasprintf: out of memory");
2481 return n;
2484 /*****************************************************************
2485 Like strdup but for memory.
2486 *****************************************************************/
2488 void *memdup(const void *p, size_t size)
2490 void *p2;
2491 if (size == 0)
2492 return NULL;
2493 p2 = SMB_MALLOC(size);
2494 if (!p2)
2495 return NULL;
2496 memcpy(p2, p, size);
2497 return p2;
2500 /*****************************************************************
2501 Get local hostname and cache result.
2502 *****************************************************************/
2504 char *myhostname(void)
2506 static pstring ret;
2507 if (ret[0] == 0)
2508 get_myname(ret);
2509 return ret;
2512 /*****************************************************************
2513 A useful function for returning a path in the Samba lock directory.
2514 *****************************************************************/
2516 char *lock_path(const char *name)
2518 static pstring fname;
2520 pstrcpy(fname,lp_lockdir());
2521 trim_char(fname,'\0','/');
2523 if (!directory_exist(fname,NULL))
2524 mkdir(fname,0755);
2526 pstrcat(fname,"/");
2527 pstrcat(fname,name);
2529 return fname;
2532 /*****************************************************************
2533 A useful function for returning a path in the Samba pid directory.
2534 *****************************************************************/
2536 char *pid_path(const char *name)
2538 static pstring fname;
2540 pstrcpy(fname,lp_piddir());
2541 trim_char(fname,'\0','/');
2543 if (!directory_exist(fname,NULL))
2544 mkdir(fname,0755);
2546 pstrcat(fname,"/");
2547 pstrcat(fname,name);
2549 return fname;
2553 * @brief Returns an absolute path to a file in the Samba lib directory.
2555 * @param name File to find, relative to LIBDIR.
2557 * @retval Pointer to a static #pstring containing the full path.
2560 char *lib_path(const char *name)
2562 static pstring fname;
2563 fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2564 return fname;
2568 * @brief Returns the platform specific shared library extension.
2570 * @retval Pointer to a static #fstring containing the extension.
2573 const char *shlib_ext(void)
2575 return dyn_SHLIBEXT;
2578 /*******************************************************************
2579 Given a filename - get its directory name
2580 NB: Returned in static storage. Caveats:
2581 o Not safe in thread environment.
2582 o Caller must not free.
2583 o If caller wishes to preserve, they should copy.
2584 ********************************************************************/
2586 char *parent_dirname(const char *path)
2588 static pstring dirpath;
2589 char *p;
2591 if (!path)
2592 return(NULL);
2594 pstrcpy(dirpath, path);
2595 p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
2596 if (!p) {
2597 pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
2598 } else {
2599 if (p == dirpath)
2600 ++p; /* For root "/", leave "/" in place */
2601 *p = '\0';
2603 return dirpath;
2607 /*******************************************************************
2608 Determine if a pattern contains any Microsoft wildcard characters.
2609 *******************************************************************/
2611 BOOL ms_has_wild(const char *s)
2613 char c;
2615 if (lp_posix_pathnames()) {
2616 /* With posix pathnames no characters are wild. */
2617 return False;
2620 while ((c = *s++)) {
2621 switch (c) {
2622 case '*':
2623 case '?':
2624 case '<':
2625 case '>':
2626 case '"':
2627 return True;
2630 return False;
2633 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2635 smb_ucs2_t c;
2636 if (!s) return False;
2637 while ((c = *s++)) {
2638 switch (c) {
2639 case UCS2_CHAR('*'):
2640 case UCS2_CHAR('?'):
2641 case UCS2_CHAR('<'):
2642 case UCS2_CHAR('>'):
2643 case UCS2_CHAR('"'):
2644 return True;
2647 return False;
2650 /*******************************************************************
2651 A wrapper that handles case sensitivity and the special handling
2652 of the ".." name.
2653 *******************************************************************/
2655 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2657 if (strcmp(string,"..") == 0)
2658 string = ".";
2659 if (strcmp(pattern,".") == 0)
2660 return False;
2662 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2665 /*******************************************************************
2666 A wrapper that handles case sensitivity and the special handling
2667 of the ".." name. Varient that is only called by old search code which requires
2668 pattern translation.
2669 *******************************************************************/
2671 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2673 if (strcmp(string,"..") == 0)
2674 string = ".";
2675 if (strcmp(pattern,".") == 0)
2676 return False;
2678 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2681 /*******************************************************************
2682 A wrapper that handles a list of patters and calls mask_match()
2683 on each. Returns True if any of the patterns match.
2684 *******************************************************************/
2686 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2688 while (listLen-- > 0) {
2689 if (mask_match(string, *list++, is_case_sensitive))
2690 return True;
2692 return False;
2695 /*********************************************************
2696 Recursive routine that is called by unix_wild_match.
2697 *********************************************************/
2699 static BOOL unix_do_match(const char *regexp, const char *str)
2701 const char *p;
2703 for( p = regexp; *p && *str; ) {
2705 switch(*p) {
2706 case '?':
2707 str++;
2708 p++;
2709 break;
2711 case '*':
2714 * Look for a character matching
2715 * the one after the '*'.
2717 p++;
2718 if(!*p)
2719 return True; /* Automatic match */
2720 while(*str) {
2722 while(*str && (*p != *str))
2723 str++;
2726 * Patch from weidel@multichart.de. In the case of the regexp
2727 * '*XX*' we want to ensure there are at least 2 'X' characters
2728 * in the string after the '*' for a match to be made.
2732 int matchcount=0;
2735 * Eat all the characters that match, but count how many there were.
2738 while(*str && (*p == *str)) {
2739 str++;
2740 matchcount++;
2744 * Now check that if the regexp had n identical characters that
2745 * matchcount had at least that many matches.
2748 while ( *(p+1) && (*(p+1) == *p)) {
2749 p++;
2750 matchcount--;
2753 if ( matchcount <= 0 )
2754 return False;
2757 str--; /* We've eaten the match char after the '*' */
2759 if(unix_do_match(p, str))
2760 return True;
2762 if(!*str)
2763 return False;
2764 else
2765 str++;
2767 return False;
2769 default:
2770 if(*str != *p)
2771 return False;
2772 str++;
2773 p++;
2774 break;
2778 if(!*p && !*str)
2779 return True;
2781 if (!*p && str[0] == '.' && str[1] == 0)
2782 return(True);
2784 if (!*str && *p == '?') {
2785 while (*p == '?')
2786 p++;
2787 return(!*p);
2790 if(!*str && (*p == '*' && p[1] == '\0'))
2791 return True;
2793 return False;
2796 /*******************************************************************
2797 Simple case insensitive interface to a UNIX wildcard matcher.
2798 Returns True if match, False if not.
2799 *******************************************************************/
2801 BOOL unix_wild_match(const char *pattern, const char *string)
2803 pstring p2, s2;
2804 char *p;
2806 pstrcpy(p2, pattern);
2807 pstrcpy(s2, string);
2808 strlower_m(p2);
2809 strlower_m(s2);
2811 /* Remove any *? and ** from the pattern as they are meaningless */
2812 for(p = p2; *p; p++)
2813 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2814 pstrcpy( &p[1], &p[2]);
2816 if (strequal(p2,"*"))
2817 return True;
2819 return unix_do_match(p2, s2);
2822 /**********************************************************************
2823 Converts a name to a fully qalified domain name.
2824 ***********************************************************************/
2826 void name_to_fqdn(fstring fqdn, const char *name)
2828 struct hostent *hp = sys_gethostbyname(name);
2830 if ( hp && hp->h_name && *hp->h_name ) {
2831 char *full = NULL;
2833 /* find out if the fqdn is returned as an alias
2834 * to cope with /etc/hosts files where the first
2835 * name is not the fqdn but the short name */
2836 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2837 int i;
2838 for (i = 0; hp->h_aliases[i]; i++) {
2839 if (strchr_m(hp->h_aliases[i], '.')) {
2840 full = hp->h_aliases[i];
2841 break;
2845 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2846 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2847 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2848 DEBUGADD(1, (" to Kerberos authentication probelms as localhost.localdomain\n"));
2849 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2850 full = hp->h_name;
2853 if (!full) {
2854 full = hp->h_name;
2857 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2858 fstrcpy(fqdn, full);
2859 } else {
2860 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2861 fstrcpy(fqdn, name);
2865 /**********************************************************************
2866 Extension to talloc_get_type: Abort on type mismatch
2867 ***********************************************************************/
2869 void *talloc_check_name_abort(const void *ptr, const char *name)
2871 void *result;
2873 result = talloc_check_name(ptr, name);
2874 if (result != NULL)
2875 return result;
2877 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2878 name, talloc_get_name(ptr)));
2879 smb_panic("aborting");
2880 /* Keep the compiler happy */
2881 return NULL;
2885 #ifdef __INSURE__
2887 /*******************************************************************
2888 This routine is a trick to immediately catch errors when debugging
2889 with insure. A xterm with a gdb is popped up when insure catches
2890 a error. It is Linux specific.
2891 ********************************************************************/
2893 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2895 static int (*fn)();
2896 int ret;
2897 char pidstr[10];
2898 /* you can get /usr/bin/backtrace from
2899 http://samba.org/ftp/unpacked/junkcode/backtrace */
2900 pstring cmd = "/usr/bin/backtrace %d";
2902 slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2903 pstring_sub(cmd, "%d", pidstr);
2905 if (!fn) {
2906 static void *h;
2907 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2908 fn = dlsym(h, "_Insure_trap_error");
2910 if (!h || h == _Insure_trap_error) {
2911 h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2912 fn = dlsym(h, "_Insure_trap_error");
2916 ret = fn(a1, a2, a3, a4, a5, a6);
2918 system(cmd);
2920 return ret;
2922 #endif
2924 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2926 switch (share_access & ~FILE_SHARE_DELETE) {
2927 case FILE_SHARE_NONE:
2928 return DENY_ALL;
2929 case FILE_SHARE_READ:
2930 return DENY_WRITE;
2931 case FILE_SHARE_WRITE:
2932 return DENY_READ;
2933 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2934 return DENY_NONE;
2936 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2937 return DENY_DOS;
2938 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2939 return DENY_FCB;
2942 return (uint32)-1;
2945 pid_t procid_to_pid(const struct process_id *proc)
2947 return proc->pid;
2950 struct process_id pid_to_procid(pid_t pid)
2952 struct process_id result;
2953 result.pid = pid;
2954 return result;
2957 struct process_id procid_self(void)
2959 return pid_to_procid(sys_getpid());
2962 BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
2964 return (p1->pid == p2->pid);
2967 BOOL procid_is_me(const struct process_id *pid)
2969 return (pid->pid == sys_getpid());
2972 struct process_id interpret_pid(const char *pid_string)
2974 return pid_to_procid(atoi(pid_string));
2977 char *procid_str_static(const struct process_id *pid)
2979 static fstring str;
2980 fstr_sprintf(str, "%d", pid->pid);
2981 return str;
2984 char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
2986 return talloc_strdup(mem_ctx, procid_str_static(pid));
2989 BOOL procid_valid(const struct process_id *pid)
2991 return (pid->pid != -1);
2994 BOOL procid_is_local(const struct process_id *pid)
2996 return True;
2999 int this_is_smp(void)
3001 #if defined(HAVE_SYSCONF)
3003 #if defined(SYSCONF_SC_NPROC_ONLN)
3004 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3005 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3006 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3007 #else
3008 return 0;
3009 #endif
3011 #else
3012 return 0;
3013 #endif