r18530: typos
[Samba.git] / source / lib / util.c
blob031f50e8af6ed9785a037aec1314eb98eccaaf5c
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 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_ARRAY(char, 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 void **array = (void **)_array;
1060 if (*array_size < 0) {
1061 return;
1064 if (*array == NULL) {
1065 if (*array_size == 0) {
1066 *array_size = 128;
1069 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1070 goto error;
1073 if (mem_ctx != NULL) {
1074 *array = TALLOC(mem_ctx, element_size * (*array_size));
1075 } else {
1076 *array = SMB_MALLOC(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 if (mem_ctx != NULL) {
1092 *array = TALLOC_REALLOC(mem_ctx, *array,
1093 element_size * (*array_size));
1094 } else {
1095 *array = SMB_REALLOC(*array,
1096 element_size * (*array_size));
1099 if (*array == NULL) {
1100 goto error;
1104 memcpy((char *)(*array) + element_size*(*num_elements),
1105 element, element_size);
1106 *num_elements += 1;
1108 return;
1110 error:
1111 *num_elements = 0;
1112 *array_size = -1;
1115 /****************************************************************************
1116 Free memory, checks for NULL.
1117 Use directly SAFE_FREE()
1118 Exists only because we need to pass a function pointer somewhere --SSS
1119 ****************************************************************************/
1121 void safe_free(void *p)
1123 SAFE_FREE(p);
1126 /****************************************************************************
1127 Get my own name and IP.
1128 ****************************************************************************/
1130 BOOL get_myname(char *my_name)
1132 pstring hostname;
1134 *hostname = 0;
1136 /* get my host name */
1137 if (gethostname(hostname, sizeof(hostname)) == -1) {
1138 DEBUG(0,("gethostname failed\n"));
1139 return False;
1142 /* Ensure null termination. */
1143 hostname[sizeof(hostname)-1] = '\0';
1145 if (my_name) {
1146 /* split off any parts after an initial . */
1147 char *p = strchr_m(hostname,'.');
1149 if (p)
1150 *p = 0;
1152 fstrcpy(my_name,hostname);
1155 return(True);
1158 /****************************************************************************
1159 Get my own canonical name, including domain.
1160 ****************************************************************************/
1162 BOOL get_mydnsfullname(fstring my_dnsname)
1164 static fstring dnshostname;
1165 struct hostent *hp;
1167 if (!*dnshostname) {
1168 /* get my host name */
1169 if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
1170 *dnshostname = '\0';
1171 DEBUG(0,("gethostname failed\n"));
1172 return False;
1175 /* Ensure null termination. */
1176 dnshostname[sizeof(dnshostname)-1] = '\0';
1178 /* Ensure we get the cannonical name. */
1179 if (!(hp = sys_gethostbyname(dnshostname))) {
1180 *dnshostname = '\0';
1181 return False;
1183 fstrcpy(dnshostname, hp->h_name);
1185 fstrcpy(my_dnsname, dnshostname);
1186 return True;
1189 /****************************************************************************
1190 Get my own domain name.
1191 ****************************************************************************/
1193 BOOL get_mydnsdomname(fstring my_domname)
1195 fstring domname;
1196 char *p;
1198 *my_domname = '\0';
1199 if (!get_mydnsfullname(domname)) {
1200 return False;
1202 p = strchr_m(domname, '.');
1203 if (p) {
1204 p++;
1205 fstrcpy(my_domname, p);
1208 return False;
1211 /****************************************************************************
1212 Interpret a protocol description string, with a default.
1213 ****************************************************************************/
1215 int interpret_protocol(const char *str,int def)
1217 if (strequal(str,"NT1"))
1218 return(PROTOCOL_NT1);
1219 if (strequal(str,"LANMAN2"))
1220 return(PROTOCOL_LANMAN2);
1221 if (strequal(str,"LANMAN1"))
1222 return(PROTOCOL_LANMAN1);
1223 if (strequal(str,"CORE"))
1224 return(PROTOCOL_CORE);
1225 if (strequal(str,"COREPLUS"))
1226 return(PROTOCOL_COREPLUS);
1227 if (strequal(str,"CORE+"))
1228 return(PROTOCOL_COREPLUS);
1230 DEBUG(0,("Unrecognised protocol level %s\n",str));
1232 return(def);
1235 /****************************************************************************
1236 Return true if a string could be a pure IP address.
1237 ****************************************************************************/
1239 BOOL is_ipaddress(const char *str)
1241 BOOL pure_address = True;
1242 int i;
1244 for (i=0; pure_address && str[i]; i++)
1245 if (!(isdigit((int)str[i]) || str[i] == '.'))
1246 pure_address = False;
1248 /* Check that a pure number is not misinterpreted as an IP */
1249 pure_address = pure_address && (strchr_m(str, '.') != NULL);
1251 return pure_address;
1254 /****************************************************************************
1255 Interpret an internet address or name into an IP address in 4 byte form.
1256 ****************************************************************************/
1258 uint32 interpret_addr(const char *str)
1260 struct hostent *hp;
1261 uint32 res;
1263 if (strcmp(str,"0.0.0.0") == 0)
1264 return(0);
1265 if (strcmp(str,"255.255.255.255") == 0)
1266 return(0xFFFFFFFF);
1268 /* if it's in the form of an IP address then get the lib to interpret it */
1269 if (is_ipaddress(str)) {
1270 res = inet_addr(str);
1271 } else {
1272 /* otherwise assume it's a network name of some sort and use
1273 sys_gethostbyname */
1274 if ((hp = sys_gethostbyname(str)) == 0) {
1275 DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1276 return 0;
1279 if(hp->h_addr == NULL) {
1280 DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1281 return 0;
1283 putip((char *)&res,(char *)hp->h_addr);
1286 if (res == (uint32)-1)
1287 return(0);
1289 return(res);
1292 /*******************************************************************
1293 A convenient addition to interpret_addr().
1294 ******************************************************************/
1296 struct in_addr *interpret_addr2(const char *str)
1298 static struct in_addr ret;
1299 uint32 a = interpret_addr(str);
1300 ret.s_addr = a;
1301 return(&ret);
1304 /*******************************************************************
1305 Check if an IP is the 0.0.0.0.
1306 ******************************************************************/
1308 BOOL is_zero_ip(struct in_addr ip)
1310 uint32 a;
1311 putip((char *)&a,(char *)&ip);
1312 return(a == 0);
1315 /*******************************************************************
1316 Set an IP to 0.0.0.0.
1317 ******************************************************************/
1319 void zero_ip(struct in_addr *ip)
1321 static BOOL init;
1322 static struct in_addr ipzero;
1324 if (!init) {
1325 ipzero = *interpret_addr2("0.0.0.0");
1326 init = True;
1329 *ip = ipzero;
1332 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1333 /******************************************************************
1334 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1335 Based on a fix from <Thomas.Hepper@icem.de>.
1336 *******************************************************************/
1338 static void strip_mount_options( pstring *str)
1340 if (**str == '-') {
1341 char *p = *str;
1342 while(*p && !isspace(*p))
1343 p++;
1344 while(*p && isspace(*p))
1345 p++;
1346 if(*p) {
1347 pstring tmp_str;
1349 pstrcpy(tmp_str, p);
1350 pstrcpy(*str, tmp_str);
1355 /*******************************************************************
1356 Patch from jkf@soton.ac.uk
1357 Split Luke's automount_server into YP lookup and string splitter
1358 so can easily implement automount_path().
1359 As we may end up doing both, cache the last YP result.
1360 *******************************************************************/
1362 #ifdef WITH_NISPLUS_HOME
1363 char *automount_lookup(const char *user_name)
1365 static fstring last_key = "";
1366 static pstring last_value = "";
1368 char *nis_map = (char *)lp_nis_home_map_name();
1370 char buffer[NIS_MAXATTRVAL + 1];
1371 nis_result *result;
1372 nis_object *object;
1373 entry_obj *entry;
1375 if (strcmp(user_name, last_key)) {
1376 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1377 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1379 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1380 if (result->status != NIS_SUCCESS) {
1381 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1382 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1383 } else {
1384 object = result->objects.objects_val;
1385 if (object->zo_data.zo_type == ENTRY_OBJ) {
1386 entry = &object->zo_data.objdata_u.en_data;
1387 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1388 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1390 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1391 pstring_sub(last_value, "&", user_name);
1392 fstrcpy(last_key, user_name);
1396 nis_freeresult(result);
1399 strip_mount_options(&last_value);
1401 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1402 return last_value;
1404 #else /* WITH_NISPLUS_HOME */
1406 char *automount_lookup(const char *user_name)
1408 static fstring last_key = "";
1409 static pstring last_value = "";
1411 int nis_error; /* returned by yp all functions */
1412 char *nis_result; /* yp_match inits this */
1413 int nis_result_len; /* and set this */
1414 char *nis_domain; /* yp_get_default_domain inits this */
1415 char *nis_map = (char *)lp_nis_home_map_name();
1417 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1418 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1419 return last_value;
1422 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1424 if (!strcmp(user_name, last_key)) {
1425 nis_result = last_value;
1426 nis_result_len = strlen(last_value);
1427 nis_error = 0;
1428 } else {
1429 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1430 &nis_result, &nis_result_len)) == 0) {
1431 fstrcpy(last_key, user_name);
1432 pstrcpy(last_value, nis_result);
1433 strip_mount_options(&last_value);
1435 } else if(nis_error == YPERR_KEY) {
1437 /* If Key lookup fails user home server is not in nis_map
1438 use default information for server, and home directory */
1439 last_value[0] = 0;
1440 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1441 user_name, nis_map));
1442 DEBUG(3, ("using defaults for server and home directory\n"));
1443 } else {
1444 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1445 yperr_string(nis_error), user_name, nis_map));
1449 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1450 return last_value;
1452 #endif /* WITH_NISPLUS_HOME */
1453 #endif
1455 /*******************************************************************
1456 Are two IPs on the same subnet?
1457 ********************************************************************/
1459 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1461 uint32 net1,net2,nmask;
1463 nmask = ntohl(mask.s_addr);
1464 net1 = ntohl(ip1.s_addr);
1465 net2 = ntohl(ip2.s_addr);
1467 return((net1 & nmask) == (net2 & nmask));
1471 /****************************************************************************
1472 Check if a process exists. Does this work on all unixes?
1473 ****************************************************************************/
1475 BOOL process_exists(const struct process_id pid)
1477 if (procid_is_me(&pid)) {
1478 return True;
1481 if (!procid_is_local(&pid)) {
1482 /* This *SEVERELY* needs fixing. */
1483 return True;
1486 /* Doing kill with a non-positive pid causes messages to be
1487 * sent to places we don't want. */
1488 SMB_ASSERT(pid.pid > 0);
1489 return(kill(pid.pid,0) == 0 || errno != ESRCH);
1492 BOOL process_exists_by_pid(pid_t pid)
1494 return process_exists(pid_to_procid(pid));
1497 /*******************************************************************
1498 Convert a uid into a user name.
1499 ********************************************************************/
1501 const char *uidtoname(uid_t uid)
1503 static fstring name;
1504 struct passwd *pass;
1506 pass = getpwuid_alloc(NULL, uid);
1507 if (pass) {
1508 fstrcpy(name, pass->pw_name);
1509 TALLOC_FREE(pass);
1510 } else {
1511 slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
1513 return name;
1517 /*******************************************************************
1518 Convert a gid into a group name.
1519 ********************************************************************/
1521 char *gidtoname(gid_t gid)
1523 static fstring name;
1524 struct group *grp;
1526 grp = getgrgid(gid);
1527 if (grp)
1528 return(grp->gr_name);
1529 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1530 return(name);
1533 /*******************************************************************
1534 Convert a user name into a uid.
1535 ********************************************************************/
1537 uid_t nametouid(const char *name)
1539 struct passwd *pass;
1540 char *p;
1541 uid_t u;
1543 pass = getpwnam_alloc(NULL, name);
1544 if (pass) {
1545 u = pass->pw_uid;
1546 TALLOC_FREE(pass);
1547 return u;
1550 u = (uid_t)strtol(name, &p, 0);
1551 if ((p != name) && (*p == '\0'))
1552 return u;
1554 return (uid_t)-1;
1557 /*******************************************************************
1558 Convert a name to a gid_t if possible. Return -1 if not a group.
1559 ********************************************************************/
1561 gid_t nametogid(const char *name)
1563 struct group *grp;
1564 char *p;
1565 gid_t g;
1567 g = (gid_t)strtol(name, &p, 0);
1568 if ((p != name) && (*p == '\0'))
1569 return g;
1571 grp = sys_getgrnam(name);
1572 if (grp)
1573 return(grp->gr_gid);
1574 return (gid_t)-1;
1577 /*******************************************************************
1578 Something really nasty happened - panic !
1579 ********************************************************************/
1581 void smb_panic(const char *const why)
1583 char *cmd;
1584 int result;
1586 #ifdef DEVELOPER
1589 if (global_clobber_region_function) {
1590 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1591 global_clobber_region_function,
1592 global_clobber_region_line));
1595 #endif
1597 DEBUG(0,("PANIC (pid %llu): %s\n",
1598 (unsigned long long)sys_getpid(), why));
1599 log_stack_trace();
1601 cmd = lp_panic_action();
1602 if (cmd && *cmd) {
1603 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1604 result = system(cmd);
1606 if (result == -1)
1607 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1608 strerror(errno)));
1609 else
1610 DEBUG(0, ("smb_panic(): action returned status %d\n",
1611 WEXITSTATUS(result)));
1614 dump_core();
1617 /*******************************************************************
1618 Print a backtrace of the stack to the debug log. This function
1619 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1620 exit shortly after calling it.
1621 ********************************************************************/
1623 #ifdef HAVE_LIBUNWIND_H
1624 #include <libunwind.h>
1625 #endif
1627 #ifdef HAVE_EXECINFO_H
1628 #include <execinfo.h>
1629 #endif
1631 #ifdef HAVE_LIBEXC_H
1632 #include <libexc.h>
1633 #endif
1635 void log_stack_trace(void)
1637 #ifdef HAVE_LIBUNWIND
1638 /* Try to use libunwind before any other technique since on ia64
1639 * libunwind correctly walks the stack in more circumstances than
1640 * backtrace.
1642 unw_cursor_t cursor;
1643 unw_context_t uc;
1644 unsigned i = 0;
1646 char procname[256];
1647 unw_word_t ip, sp, off;
1649 procname[sizeof(procname) - 1] = '\0';
1651 if (unw_getcontext(&uc) != 0) {
1652 goto libunwind_failed;
1655 if (unw_init_local(&cursor, &uc) != 0) {
1656 goto libunwind_failed;
1659 DEBUG(0, ("BACKTRACE:\n"));
1661 do {
1662 ip = sp = 0;
1663 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1664 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1666 switch (unw_get_proc_name(&cursor,
1667 procname, sizeof(procname) - 1, &off) ) {
1668 case 0:
1669 /* Name found. */
1670 case -UNW_ENOMEM:
1671 /* Name truncated. */
1672 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1673 i, procname, (long long)off,
1674 (long long)ip, (long long) sp));
1675 break;
1676 default:
1677 /* case -UNW_ENOINFO: */
1678 /* case -UNW_EUNSPEC: */
1679 /* No symbol name found. */
1680 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1681 i, "<unknown symbol>",
1682 (long long)ip, (long long) sp));
1684 ++i;
1685 } while (unw_step(&cursor) > 0);
1687 return;
1689 libunwind_failed:
1690 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1692 #elif HAVE_BACKTRACE_SYMBOLS
1693 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1694 size_t backtrace_size;
1695 char **backtrace_strings;
1697 /* get the backtrace (stack frames) */
1698 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1699 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1701 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1702 (unsigned long)backtrace_size));
1704 if (backtrace_strings) {
1705 int i;
1707 for (i = 0; i < backtrace_size; i++)
1708 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1710 /* Leak the backtrace_strings, rather than risk what free() might do */
1713 #elif HAVE_LIBEXC
1715 /* The IRIX libexc library provides an API for unwinding the stack. See
1716 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1717 * since we are about to abort anyway, it hardly matters.
1720 #define NAMESIZE 32 /* Arbitrary */
1722 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1723 char * names[BACKTRACE_STACK_SIZE];
1724 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1726 int i;
1727 int levels;
1729 ZERO_ARRAY(addrs);
1730 ZERO_ARRAY(names);
1731 ZERO_ARRAY(namebuf);
1733 /* We need to be root so we can open our /proc entry to walk
1734 * our stack. It also helps when we want to dump core.
1736 become_root();
1738 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1739 names[i] = namebuf + (i * NAMESIZE);
1742 levels = trace_back_stack(0, addrs, names,
1743 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1745 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1746 for (i = 0; i < levels; i++) {
1747 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1749 #undef NAMESIZE
1751 #else
1752 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1753 #endif
1756 /*******************************************************************
1757 A readdir wrapper which just returns the file name.
1758 ********************************************************************/
1760 const char *readdirname(SMB_STRUCT_DIR *p)
1762 SMB_STRUCT_DIRENT *ptr;
1763 char *dname;
1765 if (!p)
1766 return(NULL);
1768 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1769 if (!ptr)
1770 return(NULL);
1772 dname = ptr->d_name;
1774 #ifdef NEXT2
1775 if (telldir(p) < 0)
1776 return(NULL);
1777 #endif
1779 #ifdef HAVE_BROKEN_READDIR_NAME
1780 /* using /usr/ucb/cc is BAD */
1781 dname = dname - 2;
1782 #endif
1785 static pstring buf;
1786 int len = NAMLEN(ptr);
1787 memcpy(buf, dname, len);
1788 buf[len] = 0;
1789 dname = buf;
1792 return(dname);
1795 /*******************************************************************
1796 Utility function used to decide if the last component
1797 of a path matches a (possibly wildcarded) entry in a namelist.
1798 ********************************************************************/
1800 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1802 pstring last_component;
1803 char *p;
1805 /* if we have no list it's obviously not in the path */
1806 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1807 return False;
1810 DEBUG(8, ("is_in_path: %s\n", name));
1812 /* Get the last component of the unix name. */
1813 p = strrchr_m(name, '/');
1814 pstrcpy(last_component, p ? ++p : name);
1816 for(; namelist->name != NULL; namelist++) {
1817 if(namelist->is_wild) {
1818 if (mask_match(last_component, namelist->name, case_sensitive)) {
1819 DEBUG(8,("is_in_path: mask match succeeded\n"));
1820 return True;
1822 } else {
1823 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1824 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1825 DEBUG(8,("is_in_path: match succeeded\n"));
1826 return True;
1830 DEBUG(8,("is_in_path: match not found\n"));
1832 return False;
1835 /*******************************************************************
1836 Strip a '/' separated list into an array of
1837 name_compare_enties structures suitable for
1838 passing to is_in_path(). We do this for
1839 speed so we can pre-parse all the names in the list
1840 and don't do it for each call to is_in_path().
1841 namelist is modified here and is assumed to be
1842 a copy owned by the caller.
1843 We also check if the entry contains a wildcard to
1844 remove a potentially expensive call to mask_match
1845 if possible.
1846 ********************************************************************/
1848 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1850 char *name_end;
1851 char *nameptr = namelist;
1852 int num_entries = 0;
1853 int i;
1855 (*ppname_array) = NULL;
1857 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1858 return;
1860 /* We need to make two passes over the string. The
1861 first to count the number of elements, the second
1862 to split it.
1865 while(*nameptr) {
1866 if ( *nameptr == '/' ) {
1867 /* cope with multiple (useless) /s) */
1868 nameptr++;
1869 continue;
1871 /* find the next / */
1872 name_end = strchr_m(nameptr, '/');
1874 /* oops - the last check for a / didn't find one. */
1875 if (name_end == NULL)
1876 break;
1878 /* next segment please */
1879 nameptr = name_end + 1;
1880 num_entries++;
1883 if(num_entries == 0)
1884 return;
1886 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1887 DEBUG(0,("set_namearray: malloc fail\n"));
1888 return;
1891 /* Now copy out the names */
1892 nameptr = namelist;
1893 i = 0;
1894 while(*nameptr) {
1895 if ( *nameptr == '/' ) {
1896 /* cope with multiple (useless) /s) */
1897 nameptr++;
1898 continue;
1900 /* find the next / */
1901 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1902 *name_end = 0;
1904 /* oops - the last check for a / didn't find one. */
1905 if(name_end == NULL)
1906 break;
1908 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1909 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1910 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1911 return;
1914 /* next segment please */
1915 nameptr = name_end + 1;
1916 i++;
1919 (*ppname_array)[i].name = NULL;
1921 return;
1924 /****************************************************************************
1925 Routine to free a namearray.
1926 ****************************************************************************/
1928 void free_namearray(name_compare_entry *name_array)
1930 int i;
1932 if(name_array == NULL)
1933 return;
1935 for(i=0; name_array[i].name!=NULL; i++)
1936 SAFE_FREE(name_array[i].name);
1937 SAFE_FREE(name_array);
1940 #undef DBGC_CLASS
1941 #define DBGC_CLASS DBGC_LOCKING
1943 /****************************************************************************
1944 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1945 is dealt with in posix.c
1946 Returns True if the lock was granted, False otherwise.
1947 ****************************************************************************/
1949 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1951 SMB_STRUCT_FLOCK lock;
1952 int ret;
1954 DEBUG(8,("fcntl_lock fd=%d op=%d offset=%.0f count=%.0f type=%d\n",
1955 fd,op,(double)offset,(double)count,type));
1957 lock.l_type = type;
1958 lock.l_whence = SEEK_SET;
1959 lock.l_start = offset;
1960 lock.l_len = count;
1961 lock.l_pid = 0;
1963 ret = sys_fcntl_ptr(fd,op,&lock);
1965 if (ret == -1) {
1966 int sav = errno;
1967 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1968 (double)offset,(double)count,op,type,strerror(errno)));
1969 errno = sav;
1970 return False;
1973 /* everything went OK */
1974 DEBUG(8,("fcntl_lock: Lock call successful\n"));
1976 return True;
1979 /****************************************************************************
1980 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1981 is dealt with in posix.c
1982 Returns True if we have information regarding this lock region (and returns
1983 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1984 ****************************************************************************/
1986 BOOL fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1988 SMB_STRUCT_FLOCK lock;
1989 int ret;
1991 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1992 fd,(double)*poffset,(double)*pcount,*ptype));
1994 lock.l_type = *ptype;
1995 lock.l_whence = SEEK_SET;
1996 lock.l_start = *poffset;
1997 lock.l_len = *pcount;
1998 lock.l_pid = 0;
2000 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
2002 if (ret == -1) {
2003 int sav = errno;
2004 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
2005 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
2006 errno = sav;
2007 return False;
2010 *ptype = lock.l_type;
2011 *poffset = lock.l_start;
2012 *pcount = lock.l_len;
2013 *ppid = lock.l_pid;
2015 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
2016 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
2017 return True;
2020 #undef DBGC_CLASS
2021 #define DBGC_CLASS DBGC_ALL
2023 /*******************************************************************
2024 Is the name specified one of my netbios names.
2025 Returns true if it is equal, false otherwise.
2026 ********************************************************************/
2028 BOOL is_myname(const char *s)
2030 int n;
2031 BOOL ret = False;
2033 for (n=0; my_netbios_names(n); n++) {
2034 if (strequal(my_netbios_names(n), s)) {
2035 ret=True;
2036 break;
2039 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
2040 return(ret);
2043 BOOL is_myname_or_ipaddr(const char *s)
2045 fstring name, dnsname;
2046 char *servername;
2048 if ( !s )
2049 return False;
2051 /* santize the string from '\\name' */
2053 fstrcpy( name, s );
2055 servername = strrchr_m( name, '\\' );
2056 if ( !servername )
2057 servername = name;
2058 else
2059 servername++;
2061 /* optimize for the common case */
2063 if (strequal(servername, global_myname()))
2064 return True;
2066 /* check for an alias */
2068 if (is_myname(servername))
2069 return True;
2071 /* check for loopback */
2073 if (strequal(servername, "localhost"))
2074 return True;
2076 /* maybe it's my dns name */
2078 if ( get_mydnsfullname( dnsname ) )
2079 if ( strequal( servername, dnsname ) )
2080 return True;
2082 /* handle possible CNAME records */
2084 if ( !is_ipaddress( servername ) ) {
2085 /* use DNS to resolve the name, but only the first address */
2086 struct hostent *hp;
2088 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
2089 struct in_addr return_ip;
2090 putip( (char*)&return_ip, (char*)hp->h_addr );
2091 fstrcpy( name, inet_ntoa( return_ip ) );
2092 servername = name;
2096 /* maybe its an IP address? */
2097 if (is_ipaddress(servername)) {
2098 struct iface_struct nics[MAX_INTERFACES];
2099 int i, n;
2100 uint32 ip;
2102 ip = interpret_addr(servername);
2103 if ((ip==0) || (ip==0xffffffff))
2104 return False;
2106 n = get_interfaces(nics, MAX_INTERFACES);
2107 for (i=0; i<n; i++) {
2108 if (ip == nics[i].ip.s_addr)
2109 return True;
2113 /* no match */
2114 return False;
2117 /*******************************************************************
2118 Is the name specified our workgroup/domain.
2119 Returns true if it is equal, false otherwise.
2120 ********************************************************************/
2122 BOOL is_myworkgroup(const char *s)
2124 BOOL ret = False;
2126 if (strequal(s, lp_workgroup())) {
2127 ret=True;
2130 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2131 return(ret);
2134 /*******************************************************************
2135 we distinguish between 2K and XP by the "Native Lan Manager" string
2136 WinXP => "Windows 2002 5.1"
2137 Win2k => "Windows 2000 5.0"
2138 NT4 => "Windows NT 4.0"
2139 Win9x => "Windows 4.0"
2140 Windows 2003 doesn't set the native lan manager string but
2141 they do set the domain to "Windows 2003 5.2" (probably a bug).
2142 ********************************************************************/
2144 void ra_lanman_string( const char *native_lanman )
2146 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2147 set_remote_arch( RA_WINXP );
2148 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2149 set_remote_arch( RA_WIN2K3 );
2152 /*******************************************************************
2153 Set the horrid remote_arch string based on an enum.
2154 ********************************************************************/
2156 void set_remote_arch(enum remote_arch_types type)
2158 ra_type = type;
2159 switch( type ) {
2160 case RA_WFWG:
2161 fstrcpy(remote_arch, "WfWg");
2162 break;
2163 case RA_OS2:
2164 fstrcpy(remote_arch, "OS2");
2165 break;
2166 case RA_WIN95:
2167 fstrcpy(remote_arch, "Win95");
2168 break;
2169 case RA_WINNT:
2170 fstrcpy(remote_arch, "WinNT");
2171 break;
2172 case RA_WIN2K:
2173 fstrcpy(remote_arch, "Win2K");
2174 break;
2175 case RA_WINXP:
2176 fstrcpy(remote_arch, "WinXP");
2177 break;
2178 case RA_WIN2K3:
2179 fstrcpy(remote_arch, "Win2K3");
2180 break;
2181 case RA_SAMBA:
2182 fstrcpy(remote_arch,"Samba");
2183 break;
2184 case RA_CIFSFS:
2185 fstrcpy(remote_arch,"CIFSFS");
2186 break;
2187 default:
2188 ra_type = RA_UNKNOWN;
2189 fstrcpy(remote_arch, "UNKNOWN");
2190 break;
2193 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2196 /*******************************************************************
2197 Get the remote_arch type.
2198 ********************************************************************/
2200 enum remote_arch_types get_remote_arch(void)
2202 return ra_type;
2205 void print_asc(int level, const unsigned char *buf,int len)
2207 int i;
2208 for (i=0;i<len;i++)
2209 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2212 void dump_data(int level, const char *buf1,int len)
2214 const unsigned char *buf = (const unsigned char *)buf1;
2215 int i=0;
2216 if (len<=0) return;
2218 if (!DEBUGLVL(level)) return;
2220 DEBUGADD(level,("[%03X] ",i));
2221 for (i=0;i<len;) {
2222 DEBUGADD(level,("%02X ",(int)buf[i]));
2223 i++;
2224 if (i%8 == 0) DEBUGADD(level,(" "));
2225 if (i%16 == 0) {
2226 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2227 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2228 if (i<len) DEBUGADD(level,("[%03X] ",i));
2231 if (i%16) {
2232 int n;
2233 n = 16 - (i%16);
2234 DEBUGADD(level,(" "));
2235 if (n>8) DEBUGADD(level,(" "));
2236 while (n--) DEBUGADD(level,(" "));
2237 n = MIN(8,i%16);
2238 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2239 n = (i%16) - n;
2240 if (n>0) print_asc(level,&buf[i-n],n);
2241 DEBUGADD(level,("\n"));
2245 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2247 #ifdef DEBUG_PASSWORD
2248 DEBUG(11, ("%s", msg));
2249 if (data != NULL && len > 0)
2251 dump_data(11, (const char *)data, len);
2253 #endif
2256 char *tab_depth(int depth)
2258 static pstring spaces;
2259 memset(spaces, ' ', depth * 4);
2260 spaces[depth * 4] = 0;
2261 return spaces;
2264 /*****************************************************************************
2265 Provide a checksum on a string
2267 Input: s - the null-terminated character string for which the checksum
2268 will be calculated.
2270 Output: The checksum value calculated for s.
2271 *****************************************************************************/
2273 int str_checksum(const char *s)
2275 int res = 0;
2276 int c;
2277 int i=0;
2279 while(*s) {
2280 c = *s;
2281 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2282 s++;
2283 i++;
2285 return(res);
2288 /*****************************************************************
2289 Zero a memory area then free it. Used to catch bugs faster.
2290 *****************************************************************/
2292 void zero_free(void *p, size_t size)
2294 memset(p, 0, size);
2295 SAFE_FREE(p);
2298 /*****************************************************************
2299 Set our open file limit to a requested max and return the limit.
2300 *****************************************************************/
2302 int set_maxfiles(int requested_max)
2304 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2305 struct rlimit rlp;
2306 int saved_current_limit;
2308 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2309 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2310 strerror(errno) ));
2311 /* just guess... */
2312 return requested_max;
2316 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2317 * account for the extra fd we need
2318 * as well as the log files and standard
2319 * handles etc. Save the limit we want to set in case
2320 * we are running on an OS that doesn't support this limit (AIX)
2321 * which always returns RLIM_INFINITY for rlp.rlim_max.
2324 /* Try raising the hard (max) limit to the requested amount. */
2326 #if defined(RLIM_INFINITY)
2327 if (rlp.rlim_max != RLIM_INFINITY) {
2328 int orig_max = rlp.rlim_max;
2330 if ( rlp.rlim_max < requested_max )
2331 rlp.rlim_max = requested_max;
2333 /* This failing is not an error - many systems (Linux) don't
2334 support our default request of 10,000 open files. JRA. */
2336 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2337 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2338 (int)rlp.rlim_max, strerror(errno) ));
2340 /* Set failed - restore original value from get. */
2341 rlp.rlim_max = orig_max;
2344 #endif
2346 /* Now try setting the soft (current) limit. */
2348 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2350 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2351 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2352 (int)rlp.rlim_cur, strerror(errno) ));
2353 /* just guess... */
2354 return saved_current_limit;
2357 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2358 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2359 strerror(errno) ));
2360 /* just guess... */
2361 return saved_current_limit;
2364 #if defined(RLIM_INFINITY)
2365 if(rlp.rlim_cur == RLIM_INFINITY)
2366 return saved_current_limit;
2367 #endif
2369 if((int)rlp.rlim_cur > saved_current_limit)
2370 return saved_current_limit;
2372 return rlp.rlim_cur;
2373 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2375 * No way to know - just guess...
2377 return requested_max;
2378 #endif
2381 /*****************************************************************
2382 Possibly replace mkstemp if it is broken.
2383 *****************************************************************/
2385 int smb_mkstemp(char *name_template)
2387 #if HAVE_SECURE_MKSTEMP
2388 return mkstemp(name_template);
2389 #else
2390 /* have a reasonable go at emulating it. Hope that
2391 the system mktemp() isn't completly hopeless */
2392 char *p = mktemp(name_template);
2393 if (!p)
2394 return -1;
2395 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2396 #endif
2399 /*****************************************************************
2400 malloc that aborts with smb_panic on fail or zero size.
2401 *****************************************************************/
2403 void *smb_xmalloc_array(size_t size, unsigned int count)
2405 void *p;
2406 if (size == 0)
2407 smb_panic("smb_xmalloc_array: called with zero size.\n");
2408 if (count >= MAX_ALLOC_SIZE/size) {
2409 smb_panic("smb_xmalloc: alloc size too large.\n");
2411 if ((p = SMB_MALLOC(size*count)) == NULL) {
2412 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2413 (unsigned long)size, (unsigned long)count));
2414 smb_panic("smb_xmalloc_array: malloc fail.\n");
2416 return p;
2420 Memdup with smb_panic on fail.
2423 void *smb_xmemdup(const void *p, size_t size)
2425 void *p2;
2426 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2427 memcpy(p2, p, size);
2428 return p2;
2432 strdup that aborts on malloc fail.
2435 char *smb_xstrdup(const char *s)
2437 #if defined(PARANOID_MALLOC_CHECKER)
2438 #ifdef strdup
2439 #undef strdup
2440 #endif
2441 #endif
2442 char *s1 = strdup(s);
2443 #if defined(PARANOID_MALLOC_CHECKER)
2444 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2445 #endif
2446 if (!s1)
2447 smb_panic("smb_xstrdup: malloc fail\n");
2448 return s1;
2453 strndup that aborts on malloc fail.
2456 char *smb_xstrndup(const char *s, size_t n)
2458 #if defined(PARANOID_MALLOC_CHECKER)
2459 #ifdef strndup
2460 #undef strndup
2461 #endif
2462 #endif
2463 char *s1 = strndup(s, n);
2464 #if defined(PARANOID_MALLOC_CHECKER)
2465 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2466 #endif
2467 if (!s1)
2468 smb_panic("smb_xstrndup: malloc fail\n");
2469 return s1;
2473 vasprintf that aborts on malloc fail
2476 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2478 int n;
2479 va_list ap2;
2481 VA_COPY(ap2, ap);
2483 n = vasprintf(ptr, format, ap2);
2484 if (n == -1 || ! *ptr)
2485 smb_panic("smb_xvasprintf: out of memory");
2486 return n;
2489 /*****************************************************************
2490 Like strdup but for memory.
2491 *****************************************************************/
2493 void *memdup(const void *p, size_t size)
2495 void *p2;
2496 if (size == 0)
2497 return NULL;
2498 p2 = SMB_MALLOC(size);
2499 if (!p2)
2500 return NULL;
2501 memcpy(p2, p, size);
2502 return p2;
2505 /*****************************************************************
2506 Get local hostname and cache result.
2507 *****************************************************************/
2509 char *myhostname(void)
2511 static pstring ret;
2512 if (ret[0] == 0)
2513 get_myname(ret);
2514 return ret;
2517 /*****************************************************************
2518 A useful function for returning a path in the Samba lock directory.
2519 *****************************************************************/
2521 char *lock_path(const char *name)
2523 static pstring fname;
2525 pstrcpy(fname,lp_lockdir());
2526 trim_char(fname,'\0','/');
2528 if (!directory_exist(fname,NULL))
2529 mkdir(fname,0755);
2531 pstrcat(fname,"/");
2532 pstrcat(fname,name);
2534 return fname;
2537 /*****************************************************************
2538 A useful function for returning a path in the Samba pid directory.
2539 *****************************************************************/
2541 char *pid_path(const char *name)
2543 static pstring fname;
2545 pstrcpy(fname,lp_piddir());
2546 trim_char(fname,'\0','/');
2548 if (!directory_exist(fname,NULL))
2549 mkdir(fname,0755);
2551 pstrcat(fname,"/");
2552 pstrcat(fname,name);
2554 return fname;
2558 * @brief Returns an absolute path to a file in the Samba lib directory.
2560 * @param name File to find, relative to LIBDIR.
2562 * @retval Pointer to a static #pstring containing the full path.
2565 char *lib_path(const char *name)
2567 static pstring fname;
2568 fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2569 return fname;
2573 * @brief Returns the platform specific shared library extension.
2575 * @retval Pointer to a static #fstring containing the extension.
2578 const char *shlib_ext(void)
2580 return dyn_SHLIBEXT;
2583 /*******************************************************************
2584 Given a filename - get its directory name
2585 NB: Returned in static storage. Caveats:
2586 o Not safe in thread environment.
2587 o Caller must not free.
2588 o If caller wishes to preserve, they should copy.
2589 ********************************************************************/
2591 char *parent_dirname(const char *path)
2593 static pstring dirpath;
2594 char *p;
2596 if (!path)
2597 return(NULL);
2599 pstrcpy(dirpath, path);
2600 p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
2601 if (!p) {
2602 pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
2603 } else {
2604 if (p == dirpath)
2605 ++p; /* For root "/", leave "/" in place */
2606 *p = '\0';
2608 return dirpath;
2612 /*******************************************************************
2613 Determine if a pattern contains any Microsoft wildcard characters.
2614 *******************************************************************/
2616 BOOL ms_has_wild(const char *s)
2618 char c;
2620 if (lp_posix_pathnames()) {
2621 /* With posix pathnames no characters are wild. */
2622 return False;
2625 while ((c = *s++)) {
2626 switch (c) {
2627 case '*':
2628 case '?':
2629 case '<':
2630 case '>':
2631 case '"':
2632 return True;
2635 return False;
2638 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2640 smb_ucs2_t c;
2641 if (!s) return False;
2642 while ((c = *s++)) {
2643 switch (c) {
2644 case UCS2_CHAR('*'):
2645 case UCS2_CHAR('?'):
2646 case UCS2_CHAR('<'):
2647 case UCS2_CHAR('>'):
2648 case UCS2_CHAR('"'):
2649 return True;
2652 return False;
2655 /*******************************************************************
2656 A wrapper that handles case sensitivity and the special handling
2657 of the ".." name.
2658 *******************************************************************/
2660 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2662 if (strcmp(string,"..") == 0)
2663 string = ".";
2664 if (strcmp(pattern,".") == 0)
2665 return False;
2667 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2670 /*******************************************************************
2671 A wrapper that handles case sensitivity and the special handling
2672 of the ".." name. Varient that is only called by old search code which requires
2673 pattern translation.
2674 *******************************************************************/
2676 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2678 if (strcmp(string,"..") == 0)
2679 string = ".";
2680 if (strcmp(pattern,".") == 0)
2681 return False;
2683 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2686 /*******************************************************************
2687 A wrapper that handles a list of patters and calls mask_match()
2688 on each. Returns True if any of the patterns match.
2689 *******************************************************************/
2691 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2693 while (listLen-- > 0) {
2694 if (mask_match(string, *list++, is_case_sensitive))
2695 return True;
2697 return False;
2700 /*********************************************************
2701 Recursive routine that is called by unix_wild_match.
2702 *********************************************************/
2704 static BOOL unix_do_match(const char *regexp, const char *str)
2706 const char *p;
2708 for( p = regexp; *p && *str; ) {
2710 switch(*p) {
2711 case '?':
2712 str++;
2713 p++;
2714 break;
2716 case '*':
2719 * Look for a character matching
2720 * the one after the '*'.
2722 p++;
2723 if(!*p)
2724 return True; /* Automatic match */
2725 while(*str) {
2727 while(*str && (*p != *str))
2728 str++;
2731 * Patch from weidel@multichart.de. In the case of the regexp
2732 * '*XX*' we want to ensure there are at least 2 'X' characters
2733 * in the string after the '*' for a match to be made.
2737 int matchcount=0;
2740 * Eat all the characters that match, but count how many there were.
2743 while(*str && (*p == *str)) {
2744 str++;
2745 matchcount++;
2749 * Now check that if the regexp had n identical characters that
2750 * matchcount had at least that many matches.
2753 while ( *(p+1) && (*(p+1) == *p)) {
2754 p++;
2755 matchcount--;
2758 if ( matchcount <= 0 )
2759 return False;
2762 str--; /* We've eaten the match char after the '*' */
2764 if(unix_do_match(p, str))
2765 return True;
2767 if(!*str)
2768 return False;
2769 else
2770 str++;
2772 return False;
2774 default:
2775 if(*str != *p)
2776 return False;
2777 str++;
2778 p++;
2779 break;
2783 if(!*p && !*str)
2784 return True;
2786 if (!*p && str[0] == '.' && str[1] == 0)
2787 return(True);
2789 if (!*str && *p == '?') {
2790 while (*p == '?')
2791 p++;
2792 return(!*p);
2795 if(!*str && (*p == '*' && p[1] == '\0'))
2796 return True;
2798 return False;
2801 /*******************************************************************
2802 Simple case insensitive interface to a UNIX wildcard matcher.
2803 Returns True if match, False if not.
2804 *******************************************************************/
2806 BOOL unix_wild_match(const char *pattern, const char *string)
2808 pstring p2, s2;
2809 char *p;
2811 pstrcpy(p2, pattern);
2812 pstrcpy(s2, string);
2813 strlower_m(p2);
2814 strlower_m(s2);
2816 /* Remove any *? and ** from the pattern as they are meaningless */
2817 for(p = p2; *p; p++)
2818 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2819 pstrcpy( &p[1], &p[2]);
2821 if (strequal(p2,"*"))
2822 return True;
2824 return unix_do_match(p2, s2);
2827 /**********************************************************************
2828 Converts a name to a fully qalified domain name.
2829 ***********************************************************************/
2831 void name_to_fqdn(fstring fqdn, const char *name)
2833 struct hostent *hp = sys_gethostbyname(name);
2835 if ( hp && hp->h_name && *hp->h_name ) {
2836 char *full = NULL;
2838 /* find out if the fqdn is returned as an alias
2839 * to cope with /etc/hosts files where the first
2840 * name is not the fqdn but the short name */
2841 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2842 int i;
2843 for (i = 0; hp->h_aliases[i]; i++) {
2844 if (strchr_m(hp->h_aliases[i], '.')) {
2845 full = hp->h_aliases[i];
2846 break;
2850 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2851 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2852 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2853 DEBUGADD(1, (" to Kerberos authentication probelms as localhost.localdomain\n"));
2854 DEBUGADD(1, (" may end up to be used instead of the real machine FQDN.\n"));
2855 full = hp->h_name;
2858 if (!full) {
2859 full = hp->h_name;
2862 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2863 fstrcpy(fqdn, full);
2864 } else {
2865 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2866 fstrcpy(fqdn, name);
2870 /**********************************************************************
2871 Extension to talloc_get_type: Abort on type mismatch
2872 ***********************************************************************/
2874 void *talloc_check_name_abort(const void *ptr, const char *name)
2876 void *result;
2878 result = talloc_check_name(ptr, name);
2879 if (result != NULL)
2880 return result;
2882 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2883 name, talloc_get_name(ptr)));
2884 smb_panic("aborting");
2885 /* Keep the compiler happy */
2886 return NULL;
2890 #ifdef __INSURE__
2892 /*******************************************************************
2893 This routine is a trick to immediately catch errors when debugging
2894 with insure. A xterm with a gdb is popped up when insure catches
2895 a error. It is Linux specific.
2896 ********************************************************************/
2898 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2900 static int (*fn)();
2901 int ret;
2902 char pidstr[10];
2903 /* you can get /usr/bin/backtrace from
2904 http://samba.org/ftp/unpacked/junkcode/backtrace */
2905 pstring cmd = "/usr/bin/backtrace %d";
2907 slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2908 pstring_sub(cmd, "%d", pidstr);
2910 if (!fn) {
2911 static void *h;
2912 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2913 fn = dlsym(h, "_Insure_trap_error");
2915 if (!h || h == _Insure_trap_error) {
2916 h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2917 fn = dlsym(h, "_Insure_trap_error");
2921 ret = fn(a1, a2, a3, a4, a5, a6);
2923 system(cmd);
2925 return ret;
2927 #endif
2929 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2931 switch (share_access & ~FILE_SHARE_DELETE) {
2932 case FILE_SHARE_NONE:
2933 return DENY_ALL;
2934 case FILE_SHARE_READ:
2935 return DENY_WRITE;
2936 case FILE_SHARE_WRITE:
2937 return DENY_READ;
2938 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2939 return DENY_NONE;
2941 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2942 return DENY_DOS;
2943 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2944 return DENY_FCB;
2947 return (uint32)-1;
2950 pid_t procid_to_pid(const struct process_id *proc)
2952 return proc->pid;
2955 struct process_id pid_to_procid(pid_t pid)
2957 struct process_id result;
2958 result.pid = pid;
2959 return result;
2962 struct process_id procid_self(void)
2964 return pid_to_procid(sys_getpid());
2967 BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
2969 return (p1->pid == p2->pid);
2972 BOOL procid_is_me(const struct process_id *pid)
2974 return (pid->pid == sys_getpid());
2977 struct process_id interpret_pid(const char *pid_string)
2979 return pid_to_procid(atoi(pid_string));
2982 char *procid_str_static(const struct process_id *pid)
2984 static fstring str;
2985 fstr_sprintf(str, "%d", pid->pid);
2986 return str;
2989 char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
2991 return talloc_strdup(mem_ctx, procid_str_static(pid));
2994 BOOL procid_valid(const struct process_id *pid)
2996 return (pid->pid != -1);
2999 BOOL procid_is_local(const struct process_id *pid)
3001 return True;
3004 int this_is_smp(void)
3006 #if defined(HAVE_SYSCONF)
3008 #if defined(SYSCONF_SC_NPROC_ONLN)
3009 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
3010 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
3011 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
3012 #else
3013 return 0;
3014 #endif
3016 #else
3017 return 0;
3018 #endif