r14279: Fix coverity #86, 87, 88, 89:
[Samba/nascimento.git] / source3 / lib / util.c
blob6e0a7c0e2f9dae733fdbde91c8df65a758fbc763
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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
26 extern fstring local_machine;
27 extern char *global_clobber_region_function;
28 extern unsigned int global_clobber_region_line;
29 extern fstring remote_arch;
31 /* Max allowable allococation - 256mb - 0x10000000 */
32 #define MAX_ALLOC_SIZE (1024*1024*256)
34 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
35 #ifdef WITH_NISPLUS_HOME
36 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
38 * The following lines are needed due to buggy include files
39 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
40 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
41 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
42 * an enum in /usr/include/rpcsvc/nis.h.
45 #if defined(GROUP)
46 #undef GROUP
47 #endif
49 #if defined(GROUP_OBJ)
50 #undef GROUP_OBJ
51 #endif
53 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
55 #include <rpcsvc/nis.h>
57 #endif /* WITH_NISPLUS_HOME */
58 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
60 enum protocol_types Protocol = PROTOCOL_COREPLUS;
62 /* a default finfo structure to ensure all fields are sensible */
63 file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
65 /* this is used by the chaining code */
66 int chain_size = 0;
68 int trans_num = 0;
70 static enum remote_arch_types ra_type = RA_UNKNOWN;
71 pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
73 /***********************************************************************
74 Definitions for all names.
75 ***********************************************************************/
77 static char *smb_myname;
78 static char *smb_myworkgroup;
79 static char *smb_scope;
80 static int smb_num_netbios_names;
81 static char **smb_my_netbios_names;
83 /***********************************************************************
84 Allocate and set myname. Ensure upper case.
85 ***********************************************************************/
87 BOOL set_global_myname(const char *myname)
89 SAFE_FREE(smb_myname);
90 smb_myname = SMB_STRDUP(myname);
91 if (!smb_myname)
92 return False;
93 strupper_m(smb_myname);
94 return True;
97 const char *global_myname(void)
99 return smb_myname;
102 /***********************************************************************
103 Allocate and set myworkgroup. Ensure upper case.
104 ***********************************************************************/
106 BOOL set_global_myworkgroup(const char *myworkgroup)
108 SAFE_FREE(smb_myworkgroup);
109 smb_myworkgroup = SMB_STRDUP(myworkgroup);
110 if (!smb_myworkgroup)
111 return False;
112 strupper_m(smb_myworkgroup);
113 return True;
116 const char *lp_workgroup(void)
118 return smb_myworkgroup;
121 /***********************************************************************
122 Allocate and set scope. Ensure upper case.
123 ***********************************************************************/
125 BOOL set_global_scope(const char *scope)
127 SAFE_FREE(smb_scope);
128 smb_scope = SMB_STRDUP(scope);
129 if (!smb_scope)
130 return False;
131 strupper_m(smb_scope);
132 return True;
135 /*********************************************************************
136 Ensure scope is never null string.
137 *********************************************************************/
139 const char *global_scope(void)
141 if (!smb_scope)
142 set_global_scope("");
143 return smb_scope;
146 static void free_netbios_names_array(void)
148 int i;
150 for (i = 0; i < smb_num_netbios_names; i++)
151 SAFE_FREE(smb_my_netbios_names[i]);
153 SAFE_FREE(smb_my_netbios_names);
154 smb_num_netbios_names = 0;
157 static BOOL allocate_my_netbios_names_array(size_t number)
159 free_netbios_names_array();
161 smb_num_netbios_names = number + 1;
162 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
164 if (!smb_my_netbios_names)
165 return False;
167 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
168 return True;
171 static BOOL set_my_netbios_names(const char *name, int i)
173 SAFE_FREE(smb_my_netbios_names[i]);
175 smb_my_netbios_names[i] = SMB_STRDUP(name);
176 if (!smb_my_netbios_names[i])
177 return False;
178 strupper_m(smb_my_netbios_names[i]);
179 return True;
182 const char *my_netbios_names(int i)
184 return smb_my_netbios_names[i];
187 BOOL set_netbios_aliases(const char **str_array)
189 size_t namecount;
191 /* Work out the max number of netbios aliases that we have */
192 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
195 if ( global_myname() && *global_myname())
196 namecount++;
198 /* Allocate space for the netbios aliases */
199 if (!allocate_my_netbios_names_array(namecount))
200 return False;
202 /* Use the global_myname string first */
203 namecount=0;
204 if ( global_myname() && *global_myname()) {
205 set_my_netbios_names( global_myname(), namecount );
206 namecount++;
209 if (str_array) {
210 size_t i;
211 for ( i = 0; str_array[i] != NULL; i++) {
212 size_t n;
213 BOOL duplicate = False;
215 /* Look for duplicates */
216 for( n=0; n<namecount; n++ ) {
217 if( strequal( str_array[i], my_netbios_names(n) ) ) {
218 duplicate = True;
219 break;
222 if (!duplicate) {
223 if (!set_my_netbios_names(str_array[i], namecount))
224 return False;
225 namecount++;
229 return True;
232 /****************************************************************************
233 Common name initialization code.
234 ****************************************************************************/
236 BOOL init_names(void)
238 char *p;
239 int n;
241 if (global_myname() == NULL || *global_myname() == '\0') {
242 if (!set_global_myname(myhostname())) {
243 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
244 return False;
248 if (!set_netbios_aliases(lp_netbios_aliases())) {
249 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
250 return False;
253 fstrcpy( local_machine, global_myname() );
254 trim_char( local_machine, ' ', ' ' );
255 p = strchr( local_machine, ' ' );
256 if (p)
257 *p = 0;
258 strlower_m( local_machine );
260 DEBUG( 5, ("Netbios name list:-\n") );
261 for( n=0; my_netbios_names(n); n++ )
262 DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names(n) ) );
264 return( True );
267 /**************************************************************************n
268 Find a suitable temporary directory. The result should be copied immediately
269 as it may be overwritten by a subsequent call.
270 ****************************************************************************/
272 const char *tmpdir(void)
274 char *p;
275 if ((p = getenv("TMPDIR")))
276 return p;
277 return "/tmp";
280 /****************************************************************************
281 Add a gid to an array of gids if it's not already there.
282 ****************************************************************************/
284 void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
285 gid_t **gids, size_t *num_gids)
287 int i;
289 for (i=0; i<*num_gids; i++) {
290 if ((*gids)[i] == gid)
291 return;
294 if (mem_ctx != NULL) {
295 *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
296 } else {
297 *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num_gids+1);
300 if (*gids == NULL) {
301 return;
304 (*gids)[*num_gids] = gid;
305 *num_gids += 1;
308 /****************************************************************************
309 Like atoi but gets the value up to the separator character.
310 ****************************************************************************/
312 static const char *Atoic(const char *p, int *n, const char *c)
314 if (!isdigit((int)*p)) {
315 DEBUG(5, ("Atoic: malformed number\n"));
316 return NULL;
319 (*n) = atoi(p);
321 while ((*p) && isdigit((int)*p))
322 p++;
324 if (strchr_m(c, *p) == NULL) {
325 DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
326 return NULL;
329 return p;
332 /*************************************************************************
333 Reads a list of numbers.
334 *************************************************************************/
336 const char *get_numlist(const char *p, uint32 **num, int *count)
338 int val;
340 if (num == NULL || count == NULL)
341 return NULL;
343 (*count) = 0;
344 (*num ) = NULL;
346 while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':') {
347 *num = SMB_REALLOC_ARRAY((*num), uint32, (*count)+1);
348 if (!(*num)) {
349 return NULL;
351 (*num)[(*count)] = val;
352 (*count)++;
353 p++;
356 return p;
359 /*******************************************************************
360 Check if a file exists - call vfs_file_exist for samba files.
361 ********************************************************************/
363 BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
365 SMB_STRUCT_STAT st;
366 if (!sbuf)
367 sbuf = &st;
369 if (sys_stat(fname,sbuf) != 0)
370 return(False);
372 return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
375 /*******************************************************************
376 Check a files mod time.
377 ********************************************************************/
379 time_t file_modtime(const char *fname)
381 SMB_STRUCT_STAT st;
383 if (sys_stat(fname,&st) != 0)
384 return(0);
386 return(st.st_mtime);
389 /*******************************************************************
390 Check if a directory exists.
391 ********************************************************************/
393 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
395 SMB_STRUCT_STAT st2;
396 BOOL ret;
398 if (!st)
399 st = &st2;
401 if (sys_stat(dname,st) != 0)
402 return(False);
404 ret = S_ISDIR(st->st_mode);
405 if(!ret)
406 errno = ENOTDIR;
407 return ret;
410 /*******************************************************************
411 Returns the size in bytes of the named file.
412 ********************************************************************/
414 SMB_OFF_T get_file_size(char *file_name)
416 SMB_STRUCT_STAT buf;
417 buf.st_size = 0;
418 if(sys_stat(file_name,&buf) != 0)
419 return (SMB_OFF_T)-1;
420 return(buf.st_size);
423 /*******************************************************************
424 Return a string representing an attribute for a file.
425 ********************************************************************/
427 char *attrib_string(uint16 mode)
429 static fstring attrstr;
431 attrstr[0] = 0;
433 if (mode & aVOLID) fstrcat(attrstr,"V");
434 if (mode & aDIR) fstrcat(attrstr,"D");
435 if (mode & aARCH) fstrcat(attrstr,"A");
436 if (mode & aHIDDEN) fstrcat(attrstr,"H");
437 if (mode & aSYSTEM) fstrcat(attrstr,"S");
438 if (mode & aRONLY) fstrcat(attrstr,"R");
440 return(attrstr);
443 /*******************************************************************
444 Show a smb message structure.
445 ********************************************************************/
447 void show_msg(char *buf)
449 int i;
450 int bcc=0;
452 if (!DEBUGLVL(5))
453 return;
455 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
456 smb_len(buf),
457 (int)CVAL(buf,smb_com),
458 (int)CVAL(buf,smb_rcls),
459 (int)CVAL(buf,smb_reh),
460 (int)SVAL(buf,smb_err),
461 (int)CVAL(buf,smb_flg),
462 (int)SVAL(buf,smb_flg2)));
463 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
464 (int)SVAL(buf,smb_tid),
465 (int)SVAL(buf,smb_pid),
466 (int)SVAL(buf,smb_uid),
467 (int)SVAL(buf,smb_mid)));
468 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
470 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
471 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
472 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
474 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
476 DEBUGADD(5,("smb_bcc=%d\n",bcc));
478 if (DEBUGLEVEL < 10)
479 return;
481 if (DEBUGLEVEL < 50)
482 bcc = MIN(bcc, 512);
484 dump_data(10, smb_buf(buf), bcc);
487 /*******************************************************************
488 Set the length and marker of an smb packet.
489 ********************************************************************/
491 void smb_setlen(char *buf,int len)
493 _smb_setlen(buf,len);
495 SCVAL(buf,4,0xFF);
496 SCVAL(buf,5,'S');
497 SCVAL(buf,6,'M');
498 SCVAL(buf,7,'B');
501 /*******************************************************************
502 Setup the word count and byte count for a smb message.
503 ********************************************************************/
505 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
507 if (zero)
508 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
509 SCVAL(buf,smb_wct,num_words);
510 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
511 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
512 return (smb_size + num_words*2 + num_bytes);
515 /*******************************************************************
516 Setup only the byte count for a smb message.
517 ********************************************************************/
519 int set_message_bcc(char *buf,int num_bytes)
521 int num_words = CVAL(buf,smb_wct);
522 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
523 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
524 return (smb_size + num_words*2 + num_bytes);
527 /*******************************************************************
528 Setup only the byte count for a smb message, using the end of the
529 message as a marker.
530 ********************************************************************/
532 int set_message_end(void *outbuf,void *end_ptr)
534 return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
537 /*******************************************************************
538 Reduce a file name, removing .. elements.
539 ********************************************************************/
541 void dos_clean_name(char *s)
543 char *p=NULL;
545 DEBUG(3,("dos_clean_name [%s]\n",s));
547 /* remove any double slashes */
548 all_string_sub(s, "\\\\", "\\", 0);
550 while ((p = strstr_m(s,"\\..\\")) != NULL) {
551 pstring s1;
553 *p = 0;
554 pstrcpy(s1,p+3);
556 if ((p=strrchr_m(s,'\\')) != NULL)
557 *p = 0;
558 else
559 *s = 0;
560 pstrcat(s,s1);
563 trim_string(s,NULL,"\\..");
565 all_string_sub(s, "\\.\\", "\\", 0);
568 /*******************************************************************
569 Reduce a file name, removing .. elements.
570 ********************************************************************/
572 void unix_clean_name(char *s)
574 char *p=NULL;
576 DEBUG(3,("unix_clean_name [%s]\n",s));
578 /* remove any double slashes */
579 all_string_sub(s, "//","/", 0);
581 /* Remove leading ./ characters */
582 if(strncmp(s, "./", 2) == 0) {
583 trim_string(s, "./", NULL);
584 if(*s == 0)
585 pstrcpy(s,"./");
588 while ((p = strstr_m(s,"/../")) != NULL) {
589 pstring s1;
591 *p = 0;
592 pstrcpy(s1,p+3);
594 if ((p=strrchr_m(s,'/')) != NULL)
595 *p = 0;
596 else
597 *s = 0;
598 pstrcat(s,s1);
601 trim_string(s,NULL,"/..");
604 /*******************************************************************
605 Close the low 3 fd's and open dev/null in their place.
606 ********************************************************************/
608 void close_low_fds(BOOL stderr_too)
610 #ifndef VALGRIND
611 int fd;
612 int i;
614 close(0);
615 close(1);
617 if (stderr_too)
618 close(2);
620 /* try and use up these file descriptors, so silly
621 library routines writing to stdout etc won't cause havoc */
622 for (i=0;i<3;i++) {
623 if (i == 2 && !stderr_too)
624 continue;
626 fd = sys_open("/dev/null",O_RDWR,0);
627 if (fd < 0)
628 fd = sys_open("/dev/null",O_WRONLY,0);
629 if (fd < 0) {
630 DEBUG(0,("Can't open /dev/null\n"));
631 return;
633 if (fd != i) {
634 DEBUG(0,("Didn't get file descriptor %d\n",i));
635 return;
638 #endif
641 /*******************************************************************
642 Write data into an fd at a given offset. Ignore seek errors.
643 ********************************************************************/
645 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
647 size_t total=0;
648 ssize_t ret;
650 if (pos == (SMB_OFF_T)-1) {
651 return write_data(fd, buffer, N);
653 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
654 while (total < N) {
655 ret = sys_pwrite(fd,buffer + total,N - total, pos);
656 if (ret == -1 && errno == ESPIPE) {
657 return write_data(fd, buffer + total,N - total);
659 if (ret == -1) {
660 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
661 return -1;
663 if (ret == 0) {
664 return total;
666 total += ret;
667 pos += ret;
669 return (ssize_t)total;
670 #else
671 /* Use lseek and write_data. */
672 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
673 if (errno != ESPIPE) {
674 return -1;
677 return write_data(fd, buffer, N);
678 #endif
681 /****************************************************************************
682 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
683 else
684 if SYSV use O_NDELAY
685 if BSD use FNDELAY
686 ****************************************************************************/
688 int set_blocking(int fd, BOOL set)
690 int val;
691 #ifdef O_NONBLOCK
692 #define FLAG_TO_SET O_NONBLOCK
693 #else
694 #ifdef SYSV
695 #define FLAG_TO_SET O_NDELAY
696 #else /* BSD */
697 #define FLAG_TO_SET FNDELAY
698 #endif
699 #endif
701 if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
702 return -1;
703 if(set) /* Turn blocking on - ie. clear nonblock flag */
704 val &= ~FLAG_TO_SET;
705 else
706 val |= FLAG_TO_SET;
707 return sys_fcntl_long( fd, F_SETFL, val);
708 #undef FLAG_TO_SET
711 /****************************************************************************
712 Transfer some data between two fd's.
713 ****************************************************************************/
715 #ifndef TRANSFER_BUF_SIZE
716 #define TRANSFER_BUF_SIZE 65536
717 #endif
719 ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)(int, void *, size_t),
720 ssize_t (*write_fn)(int, const void *, size_t))
722 char *buf;
723 size_t total = 0;
724 ssize_t read_ret;
725 ssize_t write_ret;
726 size_t num_to_read_thistime;
727 size_t num_written = 0;
729 if ((buf = SMB_MALLOC(TRANSFER_BUF_SIZE)) == NULL)
730 return -1;
732 while (total < n) {
733 num_to_read_thistime = MIN((n - total), TRANSFER_BUF_SIZE);
735 read_ret = (*read_fn)(infd, buf, num_to_read_thistime);
736 if (read_ret == -1) {
737 DEBUG(0,("transfer_file_internal: read failure. Error = %s\n", strerror(errno) ));
738 SAFE_FREE(buf);
739 return -1;
741 if (read_ret == 0)
742 break;
744 num_written = 0;
746 while (num_written < read_ret) {
747 write_ret = (*write_fn)(outfd,buf + num_written, read_ret - num_written);
749 if (write_ret == -1) {
750 DEBUG(0,("transfer_file_internal: write failure. Error = %s\n", strerror(errno) ));
751 SAFE_FREE(buf);
752 return -1;
754 if (write_ret == 0)
755 return (ssize_t)total;
757 num_written += (size_t)write_ret;
760 total += (size_t)read_ret;
763 SAFE_FREE(buf);
764 return (ssize_t)total;
767 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
769 return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
772 /*******************************************************************
773 Sleep for a specified number of milliseconds.
774 ********************************************************************/
776 void smb_msleep(unsigned int t)
778 #if defined(HAVE_NANOSLEEP)
779 struct timespec tval;
780 int ret;
782 tval.tv_sec = t/1000;
783 tval.tv_nsec = 1000000*(t%1000);
785 do {
786 errno = 0;
787 ret = nanosleep(&tval, &tval);
788 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
789 #else
790 unsigned int tdiff=0;
791 struct timeval tval,t1,t2;
792 fd_set fds;
794 GetTimeOfDay(&t1);
795 t2 = t1;
797 while (tdiff < t) {
798 tval.tv_sec = (t-tdiff)/1000;
799 tval.tv_usec = 1000*((t-tdiff)%1000);
801 /* Never wait for more than 1 sec. */
802 if (tval.tv_sec > 1) {
803 tval.tv_sec = 1;
804 tval.tv_usec = 0;
807 FD_ZERO(&fds);
808 errno = 0;
809 sys_select_intr(0,&fds,NULL,NULL,&tval);
811 GetTimeOfDay(&t2);
812 if (t2.tv_sec < t1.tv_sec) {
813 /* Someone adjusted time... */
814 t1 = t2;
817 tdiff = TvalDiff(&t1,&t2);
819 #endif
822 /****************************************************************************
823 Become a daemon, discarding the controlling terminal.
824 ****************************************************************************/
826 void become_daemon(BOOL Fork)
828 if (Fork) {
829 if (sys_fork()) {
830 _exit(0);
834 /* detach from the terminal */
835 #ifdef HAVE_SETSID
836 setsid();
837 #elif defined(TIOCNOTTY)
839 int i = sys_open("/dev/tty", O_RDWR, 0);
840 if (i != -1) {
841 ioctl(i, (int) TIOCNOTTY, (char *)0);
842 close(i);
845 #endif /* HAVE_SETSID */
847 /* Close fd's 0,1,2. Needed if started by rsh */
848 close_low_fds(False); /* Don't close stderr, let the debug system
849 attach it to the logfile */
852 /****************************************************************************
853 Put up a yes/no prompt.
854 ****************************************************************************/
856 BOOL yesno(char *p)
858 pstring ans;
859 printf("%s",p);
861 if (!fgets(ans,sizeof(ans)-1,stdin))
862 return(False);
864 if (*ans == 'y' || *ans == 'Y')
865 return(True);
867 return(False);
870 #if defined(PARANOID_MALLOC_CHECKER)
872 /****************************************************************************
873 Internal malloc wrapper. Externally visible.
874 ****************************************************************************/
876 void *malloc_(size_t size)
878 #undef malloc
879 return malloc(size);
880 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
883 /****************************************************************************
884 Internal calloc wrapper. Not externally visible.
885 ****************************************************************************/
887 static void *calloc_(size_t count, size_t size)
889 #undef calloc
890 return calloc(count, size);
891 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
894 /****************************************************************************
895 Internal realloc wrapper. Not externally visible.
896 ****************************************************************************/
898 static void *realloc_(void *ptr, size_t size)
900 #undef realloc
901 return realloc(ptr, size);
902 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
905 #endif /* PARANOID_MALLOC_CHECKER */
907 /****************************************************************************
908 Type-safe malloc.
909 ****************************************************************************/
911 void *malloc_array(size_t el_size, unsigned int count)
913 if (count >= MAX_ALLOC_SIZE/el_size) {
914 return NULL;
917 #if defined(PARANOID_MALLOC_CHECKER)
918 return malloc_(el_size*count);
919 #else
920 return malloc(el_size*count);
921 #endif
924 /****************************************************************************
925 Type-safe calloc.
926 ****************************************************************************/
928 void *calloc_array(size_t size, size_t nmemb)
930 if (nmemb >= MAX_ALLOC_SIZE/size) {
931 return NULL;
933 #if defined(PARANOID_MALLOC_CHECKER)
934 return calloc_(nmemb, size);
935 #else
936 return calloc(nmemb, size);
937 #endif
940 /****************************************************************************
941 Expand a pointer to be a particular size.
942 Note that this version of Realloc has an extra parameter that decides
943 whether to free the passed in storage on allocation failure or if the
944 new size is zero.
946 This is designed for use in the typical idiom of :
948 p = SMB_REALLOC(p, size)
949 if (!p) {
950 return error;
953 and not to have to keep track of the old 'p' contents to free later, nor
954 to worry if the size parameter was zero. In the case where NULL is returned
955 we guarentee that p has been freed.
957 If free later semantics are desired, then pass 'free_old_on_error' as False which
958 guarentees that the old contents are not freed on error, even if size == 0. To use
959 this idiom use :
961 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
962 if (!tmp) {
963 SAFE_FREE(p);
964 return error;
965 } else {
966 p = tmp;
969 Changes were instigated by Coverity error checking. JRA.
970 ****************************************************************************/
972 void *Realloc(void *p, size_t size, BOOL free_old_on_error)
974 void *ret=NULL;
976 if (size == 0) {
977 if (free_old_on_error) {
978 SAFE_FREE(p);
980 DEBUG(2,("Realloc asked for 0 bytes\n"));
981 return NULL;
984 #if defined(PARANOID_MALLOC_CHECKER)
985 if (!p) {
986 ret = (void *)malloc_(size);
987 } else {
988 ret = (void *)realloc_(p,size);
990 #else
991 if (!p) {
992 ret = (void *)malloc(size);
993 } else {
994 ret = (void *)realloc(p,size);
996 #endif
998 if (!ret) {
999 if (free_old_on_error && p) {
1000 SAFE_FREE(p);
1002 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1005 return(ret);
1008 /****************************************************************************
1009 Type-safe realloc.
1010 ****************************************************************************/
1012 void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_on_error)
1014 if (count >= MAX_ALLOC_SIZE/el_size) {
1015 if (free_old_on_error) {
1016 SAFE_FREE(p);
1018 return NULL;
1020 return Realloc(p, el_size*count, free_old_on_error);
1023 /****************************************************************************
1024 (Hopefully) efficient array append.
1025 ****************************************************************************/
1027 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1028 void *element, void **array, uint32 *num_elements,
1029 ssize_t *array_size)
1031 if (*array_size < 0) {
1032 return;
1035 if (*array == NULL) {
1036 if (*array_size == 0) {
1037 *array_size = 128;
1040 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1041 goto error;
1044 if (mem_ctx != NULL) {
1045 *array = TALLOC(mem_ctx, element_size * (*array_size));
1046 } else {
1047 *array = SMB_MALLOC(element_size * (*array_size));
1050 if (*array == NULL) {
1051 goto error;
1055 if (*num_elements == *array_size) {
1056 *array_size *= 2;
1058 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1059 goto error;
1062 if (mem_ctx != NULL) {
1063 *array = TALLOC_REALLOC(mem_ctx, *array,
1064 element_size * (*array_size));
1065 } else {
1066 *array = SMB_REALLOC(*array,
1067 element_size * (*array_size));
1070 if (*array == NULL) {
1071 goto error;
1075 memcpy((char *)(*array) + element_size*(*num_elements),
1076 element, element_size);
1077 *num_elements += 1;
1079 return;
1081 error:
1082 *num_elements = 0;
1083 *array_size = -1;
1086 /****************************************************************************
1087 Free memory, checks for NULL.
1088 Use directly SAFE_FREE()
1089 Exists only because we need to pass a function pointer somewhere --SSS
1090 ****************************************************************************/
1092 void safe_free(void *p)
1094 SAFE_FREE(p);
1097 /****************************************************************************
1098 Get my own name and IP.
1099 ****************************************************************************/
1101 BOOL get_myname(char *my_name)
1103 pstring hostname;
1105 *hostname = 0;
1107 /* get my host name */
1108 if (gethostname(hostname, sizeof(hostname)) == -1) {
1109 DEBUG(0,("gethostname failed\n"));
1110 return False;
1113 /* Ensure null termination. */
1114 hostname[sizeof(hostname)-1] = '\0';
1116 if (my_name) {
1117 /* split off any parts after an initial . */
1118 char *p = strchr_m(hostname,'.');
1120 if (p)
1121 *p = 0;
1123 fstrcpy(my_name,hostname);
1126 return(True);
1129 /****************************************************************************
1130 Get my own canonical name, including domain.
1131 ****************************************************************************/
1133 BOOL get_mydnsfullname(fstring my_dnsname)
1135 static fstring dnshostname;
1136 struct hostent *hp;
1138 if (!*dnshostname) {
1139 /* get my host name */
1140 if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
1141 *dnshostname = '\0';
1142 DEBUG(0,("gethostname failed\n"));
1143 return False;
1146 /* Ensure null termination. */
1147 dnshostname[sizeof(dnshostname)-1] = '\0';
1149 /* Ensure we get the cannonical name. */
1150 if (!(hp = sys_gethostbyname(dnshostname))) {
1151 *dnshostname = '\0';
1152 return False;
1154 fstrcpy(dnshostname, hp->h_name);
1156 fstrcpy(my_dnsname, dnshostname);
1157 return True;
1160 /****************************************************************************
1161 Get my own domain name.
1162 ****************************************************************************/
1164 BOOL get_mydnsdomname(fstring my_domname)
1166 fstring domname;
1167 char *p;
1169 *my_domname = '\0';
1170 if (!get_mydnsfullname(domname)) {
1171 return False;
1173 p = strchr_m(domname, '.');
1174 if (p) {
1175 p++;
1176 fstrcpy(my_domname, p);
1179 return False;
1182 /****************************************************************************
1183 Interpret a protocol description string, with a default.
1184 ****************************************************************************/
1186 int interpret_protocol(const char *str,int def)
1188 if (strequal(str,"NT1"))
1189 return(PROTOCOL_NT1);
1190 if (strequal(str,"LANMAN2"))
1191 return(PROTOCOL_LANMAN2);
1192 if (strequal(str,"LANMAN1"))
1193 return(PROTOCOL_LANMAN1);
1194 if (strequal(str,"CORE"))
1195 return(PROTOCOL_CORE);
1196 if (strequal(str,"COREPLUS"))
1197 return(PROTOCOL_COREPLUS);
1198 if (strequal(str,"CORE+"))
1199 return(PROTOCOL_COREPLUS);
1201 DEBUG(0,("Unrecognised protocol level %s\n",str));
1203 return(def);
1206 /****************************************************************************
1207 Return true if a string could be a pure IP address.
1208 ****************************************************************************/
1210 BOOL is_ipaddress(const char *str)
1212 BOOL pure_address = True;
1213 int i;
1215 for (i=0; pure_address && str[i]; i++)
1216 if (!(isdigit((int)str[i]) || str[i] == '.'))
1217 pure_address = False;
1219 /* Check that a pure number is not misinterpreted as an IP */
1220 pure_address = pure_address && (strchr_m(str, '.') != NULL);
1222 return pure_address;
1225 /****************************************************************************
1226 Interpret an internet address or name into an IP address in 4 byte form.
1227 ****************************************************************************/
1229 uint32 interpret_addr(const char *str)
1231 struct hostent *hp;
1232 uint32 res;
1234 if (strcmp(str,"0.0.0.0") == 0)
1235 return(0);
1236 if (strcmp(str,"255.255.255.255") == 0)
1237 return(0xFFFFFFFF);
1239 /* if it's in the form of an IP address then get the lib to interpret it */
1240 if (is_ipaddress(str)) {
1241 res = inet_addr(str);
1242 } else {
1243 /* otherwise assume it's a network name of some sort and use
1244 sys_gethostbyname */
1245 if ((hp = sys_gethostbyname(str)) == 0) {
1246 DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
1247 return 0;
1250 if(hp->h_addr == NULL) {
1251 DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
1252 return 0;
1254 putip((char *)&res,(char *)hp->h_addr);
1257 if (res == (uint32)-1)
1258 return(0);
1260 return(res);
1263 /*******************************************************************
1264 A convenient addition to interpret_addr().
1265 ******************************************************************/
1267 struct in_addr *interpret_addr2(const char *str)
1269 static struct in_addr ret;
1270 uint32 a = interpret_addr(str);
1271 ret.s_addr = a;
1272 return(&ret);
1275 /*******************************************************************
1276 Check if an IP is the 0.0.0.0.
1277 ******************************************************************/
1279 BOOL is_zero_ip(struct in_addr ip)
1281 uint32 a;
1282 putip((char *)&a,(char *)&ip);
1283 return(a == 0);
1286 /*******************************************************************
1287 Set an IP to 0.0.0.0.
1288 ******************************************************************/
1290 void zero_ip(struct in_addr *ip)
1292 static BOOL init;
1293 static struct in_addr ipzero;
1295 if (!init) {
1296 ipzero = *interpret_addr2("0.0.0.0");
1297 init = True;
1300 *ip = ipzero;
1303 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1304 /******************************************************************
1305 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1306 Based on a fix from <Thomas.Hepper@icem.de>.
1307 *******************************************************************/
1309 static void strip_mount_options( pstring *str)
1311 if (**str == '-') {
1312 char *p = *str;
1313 while(*p && !isspace(*p))
1314 p++;
1315 while(*p && isspace(*p))
1316 p++;
1317 if(*p) {
1318 pstring tmp_str;
1320 pstrcpy(tmp_str, p);
1321 pstrcpy(*str, tmp_str);
1326 /*******************************************************************
1327 Patch from jkf@soton.ac.uk
1328 Split Luke's automount_server into YP lookup and string splitter
1329 so can easily implement automount_path().
1330 As we may end up doing both, cache the last YP result.
1331 *******************************************************************/
1333 #ifdef WITH_NISPLUS_HOME
1334 char *automount_lookup(const char *user_name)
1336 static fstring last_key = "";
1337 static pstring last_value = "";
1339 char *nis_map = (char *)lp_nis_home_map_name();
1341 char buffer[NIS_MAXATTRVAL + 1];
1342 nis_result *result;
1343 nis_object *object;
1344 entry_obj *entry;
1346 if (strcmp(user_name, last_key)) {
1347 slprintf(buffer, sizeof(buffer)-1, "[key=%s],%s", user_name, nis_map);
1348 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1350 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1351 if (result->status != NIS_SUCCESS) {
1352 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1353 fstrcpy(last_key, ""); pstrcpy(last_value, "");
1354 } else {
1355 object = result->objects.objects_val;
1356 if (object->zo_data.zo_type == ENTRY_OBJ) {
1357 entry = &object->zo_data.objdata_u.en_data;
1358 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1359 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1361 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1362 pstring_sub(last_value, "&", user_name);
1363 fstrcpy(last_key, user_name);
1367 nis_freeresult(result);
1370 strip_mount_options(&last_value);
1372 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
1373 return last_value;
1375 #else /* WITH_NISPLUS_HOME */
1377 char *automount_lookup(const char *user_name)
1379 static fstring last_key = "";
1380 static pstring last_value = "";
1382 int nis_error; /* returned by yp all functions */
1383 char *nis_result; /* yp_match inits this */
1384 int nis_result_len; /* and set this */
1385 char *nis_domain; /* yp_get_default_domain inits this */
1386 char *nis_map = (char *)lp_nis_home_map_name();
1388 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1389 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1390 return last_value;
1393 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1395 if (!strcmp(user_name, last_key)) {
1396 nis_result = last_value;
1397 nis_result_len = strlen(last_value);
1398 nis_error = 0;
1399 } else {
1400 if ((nis_error = yp_match(nis_domain, nis_map, user_name, strlen(user_name),
1401 &nis_result, &nis_result_len)) == 0) {
1402 fstrcpy(last_key, user_name);
1403 pstrcpy(last_value, nis_result);
1404 strip_mount_options(&last_value);
1406 } else if(nis_error == YPERR_KEY) {
1408 /* If Key lookup fails user home server is not in nis_map
1409 use default information for server, and home directory */
1410 last_value[0] = 0;
1411 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1412 user_name, nis_map));
1413 DEBUG(3, ("using defaults for server and home directory\n"));
1414 } else {
1415 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1416 yperr_string(nis_error), user_name, nis_map));
1420 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
1421 return last_value;
1423 #endif /* WITH_NISPLUS_HOME */
1424 #endif
1426 /*******************************************************************
1427 Are two IPs on the same subnet?
1428 ********************************************************************/
1430 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
1432 uint32 net1,net2,nmask;
1434 nmask = ntohl(mask.s_addr);
1435 net1 = ntohl(ip1.s_addr);
1436 net2 = ntohl(ip2.s_addr);
1438 return((net1 & nmask) == (net2 & nmask));
1442 /****************************************************************************
1443 Check if a process exists. Does this work on all unixes?
1444 ****************************************************************************/
1446 BOOL process_exists(const struct process_id pid)
1448 if (!procid_is_local(&pid)) {
1449 /* This *SEVERELY* needs fixing. */
1450 return True;
1453 /* Doing kill with a non-positive pid causes messages to be
1454 * sent to places we don't want. */
1455 SMB_ASSERT(pid.pid > 0);
1456 return(kill(pid.pid,0) == 0 || errno != ESRCH);
1459 BOOL process_exists_by_pid(pid_t pid)
1461 return process_exists(pid_to_procid(pid));
1464 /*******************************************************************
1465 Convert a uid into a user name.
1466 ********************************************************************/
1468 const char *uidtoname(uid_t uid)
1470 static fstring name;
1471 struct passwd *pass;
1473 pass = getpwuid_alloc(NULL, uid);
1474 if (pass) {
1475 fstrcpy(name, pass->pw_name);
1476 TALLOC_FREE(pass);
1477 } else {
1478 slprintf(name, sizeof(name) - 1, "%ld",(long int)uid);
1480 return name;
1484 /*******************************************************************
1485 Convert a gid into a group name.
1486 ********************************************************************/
1488 char *gidtoname(gid_t gid)
1490 static fstring name;
1491 struct group *grp;
1493 grp = getgrgid(gid);
1494 if (grp)
1495 return(grp->gr_name);
1496 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
1497 return(name);
1500 /*******************************************************************
1501 Convert a user name into a uid.
1502 ********************************************************************/
1504 uid_t nametouid(const char *name)
1506 struct passwd *pass;
1507 char *p;
1508 uid_t u;
1510 pass = getpwnam_alloc(NULL, name);
1511 if (pass) {
1512 u = pass->pw_uid;
1513 TALLOC_FREE(pass);
1514 return u;
1517 u = (uid_t)strtol(name, &p, 0);
1518 if ((p != name) && (*p == '\0'))
1519 return u;
1521 return (uid_t)-1;
1524 /*******************************************************************
1525 Convert a name to a gid_t if possible. Return -1 if not a group.
1526 ********************************************************************/
1528 gid_t nametogid(const char *name)
1530 struct group *grp;
1531 char *p;
1532 gid_t g;
1534 g = (gid_t)strtol(name, &p, 0);
1535 if ((p != name) && (*p == '\0'))
1536 return g;
1538 grp = sys_getgrnam(name);
1539 if (grp)
1540 return(grp->gr_gid);
1541 return (gid_t)-1;
1544 /*******************************************************************
1545 legacy wrapper for smb_panic2()
1546 ********************************************************************/
1547 void smb_panic( const char *why )
1549 smb_panic2( why, True );
1552 /*******************************************************************
1553 Something really nasty happened - panic !
1554 ********************************************************************/
1556 #ifdef HAVE_LIBEXC_H
1557 #include <libexc.h>
1558 #endif
1560 void smb_panic2(const char *why, BOOL decrement_pid_count )
1562 char *cmd;
1563 int result;
1564 #ifdef HAVE_BACKTRACE_SYMBOLS
1565 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1566 size_t backtrace_size;
1567 char **backtrace_strings;
1568 #endif
1570 #ifdef DEVELOPER
1573 if (global_clobber_region_function) {
1574 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1575 global_clobber_region_function,
1576 global_clobber_region_line));
1579 #endif
1581 /* only smbd needs to decrement the smbd counter in connections.tdb */
1582 if ( decrement_pid_count )
1583 decrement_smbd_process_count();
1585 cmd = lp_panic_action();
1586 if (cmd && *cmd) {
1587 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1588 result = system(cmd);
1590 if (result == -1)
1591 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1592 strerror(errno)));
1593 else
1594 DEBUG(0, ("smb_panic(): action returned status %d\n",
1595 WEXITSTATUS(result)));
1597 DEBUG(0,("PANIC: %s\n", why));
1599 #ifdef HAVE_BACKTRACE_SYMBOLS
1600 /* get the backtrace (stack frames) */
1601 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1602 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1604 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1605 (unsigned long)backtrace_size));
1607 if (backtrace_strings) {
1608 int i;
1610 for (i = 0; i < backtrace_size; i++)
1611 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1613 /* Leak the backtrace_strings, rather than risk what free() might do */
1616 #elif HAVE_LIBEXC
1618 #define NAMESIZE 32 /* Arbitrary */
1620 /* The IRIX libexc library provides an API for unwinding the stack. See
1621 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1622 * since we are about to abort anyway, it hardly matters.
1624 * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this
1625 * will fail with a nasty message upon failing to open the /proc entry.
1628 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1629 char * names[BACKTRACE_STACK_SIZE];
1630 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1632 int i;
1633 int levels;
1635 ZERO_ARRAY(addrs);
1636 ZERO_ARRAY(names);
1637 ZERO_ARRAY(namebuf);
1639 /* We need to be root so we can open our /proc entry to walk
1640 * our stack. It also helps when we want to dump core.
1642 become_root();
1644 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1645 names[i] = namebuf + (i * NAMESIZE);
1648 levels = trace_back_stack(0, addrs, names,
1649 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1651 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1652 for (i = 0; i < levels; i++) {
1653 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1656 #undef NAMESIZE
1657 #endif
1659 dbgflush();
1660 #ifdef SIGABRT
1661 CatchSignal(SIGABRT,SIGNAL_CAST SIG_DFL);
1662 #endif
1663 abort();
1666 /*******************************************************************
1667 A readdir wrapper which just returns the file name.
1668 ********************************************************************/
1670 const char *readdirname(SMB_STRUCT_DIR *p)
1672 SMB_STRUCT_DIRENT *ptr;
1673 char *dname;
1675 if (!p)
1676 return(NULL);
1678 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1679 if (!ptr)
1680 return(NULL);
1682 dname = ptr->d_name;
1684 #ifdef NEXT2
1685 if (telldir(p) < 0)
1686 return(NULL);
1687 #endif
1689 #ifdef HAVE_BROKEN_READDIR
1690 /* using /usr/ucb/cc is BAD */
1691 dname = dname - 2;
1692 #endif
1695 static pstring buf;
1696 int len = NAMLEN(ptr);
1697 memcpy(buf, dname, len);
1698 buf[len] = 0;
1699 dname = buf;
1702 return(dname);
1705 /*******************************************************************
1706 Utility function used to decide if the last component
1707 of a path matches a (possibly wildcarded) entry in a namelist.
1708 ********************************************************************/
1710 BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
1712 pstring last_component;
1713 char *p;
1715 /* if we have no list it's obviously not in the path */
1716 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1717 return False;
1720 DEBUG(8, ("is_in_path: %s\n", name));
1722 /* Get the last component of the unix name. */
1723 p = strrchr_m(name, '/');
1724 pstrcpy(last_component, p ? ++p : name);
1726 for(; namelist->name != NULL; namelist++) {
1727 if(namelist->is_wild) {
1728 if (mask_match(last_component, namelist->name, case_sensitive)) {
1729 DEBUG(8,("is_in_path: mask match succeeded\n"));
1730 return True;
1732 } else {
1733 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1734 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1735 DEBUG(8,("is_in_path: match succeeded\n"));
1736 return True;
1740 DEBUG(8,("is_in_path: match not found\n"));
1742 return False;
1745 /*******************************************************************
1746 Strip a '/' separated list into an array of
1747 name_compare_enties structures suitable for
1748 passing to is_in_path(). We do this for
1749 speed so we can pre-parse all the names in the list
1750 and don't do it for each call to is_in_path().
1751 namelist is modified here and is assumed to be
1752 a copy owned by the caller.
1753 We also check if the entry contains a wildcard to
1754 remove a potentially expensive call to mask_match
1755 if possible.
1756 ********************************************************************/
1758 void set_namearray(name_compare_entry **ppname_array, char *namelist)
1760 char *name_end;
1761 char *nameptr = namelist;
1762 int num_entries = 0;
1763 int i;
1765 (*ppname_array) = NULL;
1767 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1768 return;
1770 /* We need to make two passes over the string. The
1771 first to count the number of elements, the second
1772 to split it.
1775 while(*nameptr) {
1776 if ( *nameptr == '/' ) {
1777 /* cope with multiple (useless) /s) */
1778 nameptr++;
1779 continue;
1781 /* find the next / */
1782 name_end = strchr_m(nameptr, '/');
1784 /* oops - the last check for a / didn't find one. */
1785 if (name_end == NULL)
1786 break;
1788 /* next segment please */
1789 nameptr = name_end + 1;
1790 num_entries++;
1793 if(num_entries == 0)
1794 return;
1796 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1797 DEBUG(0,("set_namearray: malloc fail\n"));
1798 return;
1801 /* Now copy out the names */
1802 nameptr = namelist;
1803 i = 0;
1804 while(*nameptr) {
1805 if ( *nameptr == '/' ) {
1806 /* cope with multiple (useless) /s) */
1807 nameptr++;
1808 continue;
1810 /* find the next / */
1811 if ((name_end = strchr_m(nameptr, '/')) != NULL)
1812 *name_end = 0;
1814 /* oops - the last check for a / didn't find one. */
1815 if(name_end == NULL)
1816 break;
1818 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1819 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1820 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1821 return;
1824 /* next segment please */
1825 nameptr = name_end + 1;
1826 i++;
1829 (*ppname_array)[i].name = NULL;
1831 return;
1834 /****************************************************************************
1835 Routine to free a namearray.
1836 ****************************************************************************/
1838 void free_namearray(name_compare_entry *name_array)
1840 int i;
1842 if(name_array == NULL)
1843 return;
1845 for(i=0; name_array[i].name!=NULL; i++)
1846 SAFE_FREE(name_array[i].name);
1847 SAFE_FREE(name_array);
1850 #undef DBGC_CLASS
1851 #define DBGC_CLASS DBGC_LOCKING
1853 /****************************************************************************
1854 Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
1855 is dealt with in posix.c
1856 ****************************************************************************/
1858 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1860 SMB_STRUCT_FLOCK lock;
1861 int ret;
1863 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
1865 lock.l_type = type;
1866 lock.l_whence = SEEK_SET;
1867 lock.l_start = offset;
1868 lock.l_len = count;
1869 lock.l_pid = 0;
1871 ret = sys_fcntl_ptr(fd,op,&lock);
1873 if (ret == -1 && errno != 0)
1874 DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
1876 /* a lock query */
1877 if (op == SMB_F_GETLK) {
1878 if ((ret != -1) &&
1879 (lock.l_type != F_UNLCK) &&
1880 (lock.l_pid != 0) &&
1881 (lock.l_pid != sys_getpid())) {
1882 DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
1883 return(True);
1886 /* it must be not locked or locked by me */
1887 return(False);
1890 /* a lock set or unset */
1891 if (ret == -1) {
1892 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
1893 (double)offset,(double)count,op,type,strerror(errno)));
1894 return(False);
1897 /* everything went OK */
1898 DEBUG(8,("fcntl_lock: Lock call successful\n"));
1900 return(True);
1903 #undef DBGC_CLASS
1904 #define DBGC_CLASS DBGC_ALL
1906 /*******************************************************************
1907 Is the name specified one of my netbios names.
1908 Returns true if it is equal, false otherwise.
1909 ********************************************************************/
1911 BOOL is_myname(const char *s)
1913 int n;
1914 BOOL ret = False;
1916 for (n=0; my_netbios_names(n); n++) {
1917 if (strequal(my_netbios_names(n), s)) {
1918 ret=True;
1919 break;
1922 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1923 return(ret);
1926 BOOL is_myname_or_ipaddr(const char *s)
1928 fstring name, dnsname;
1929 char *servername;
1931 if ( !s )
1932 return False;
1934 /* santize the string from '\\name' */
1936 fstrcpy( name, s );
1938 servername = strrchr_m( name, '\\' );
1939 if ( !servername )
1940 servername = name;
1941 else
1942 servername++;
1944 /* optimize for the common case */
1946 if (strequal(servername, global_myname()))
1947 return True;
1949 /* check for an alias */
1951 if (is_myname(servername))
1952 return True;
1954 /* check for loopback */
1956 if (strequal(servername, "localhost"))
1957 return True;
1959 /* maybe it's my dns name */
1961 if ( get_mydnsfullname( dnsname ) )
1962 if ( strequal( servername, dnsname ) )
1963 return True;
1965 /* handle possible CNAME records */
1967 if ( !is_ipaddress( servername ) ) {
1968 /* use DNS to resolve the name, but only the first address */
1969 struct hostent *hp;
1971 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
1972 struct in_addr return_ip;
1973 putip( (char*)&return_ip, (char*)hp->h_addr );
1974 fstrcpy( name, inet_ntoa( return_ip ) );
1975 servername = name;
1979 /* maybe its an IP address? */
1980 if (is_ipaddress(servername)) {
1981 struct iface_struct nics[MAX_INTERFACES];
1982 int i, n;
1983 uint32 ip;
1985 ip = interpret_addr(servername);
1986 if ((ip==0) || (ip==0xffffffff))
1987 return False;
1989 n = get_interfaces(nics, MAX_INTERFACES);
1990 for (i=0; i<n; i++) {
1991 if (ip == nics[i].ip.s_addr)
1992 return True;
1996 /* no match */
1997 return False;
2000 /*******************************************************************
2001 Is the name specified our workgroup/domain.
2002 Returns true if it is equal, false otherwise.
2003 ********************************************************************/
2005 BOOL is_myworkgroup(const char *s)
2007 BOOL ret = False;
2009 if (strequal(s, lp_workgroup())) {
2010 ret=True;
2013 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
2014 return(ret);
2017 /*******************************************************************
2018 we distinguish between 2K and XP by the "Native Lan Manager" string
2019 WinXP => "Windows 2002 5.1"
2020 Win2k => "Windows 2000 5.0"
2021 NT4 => "Windows NT 4.0"
2022 Win9x => "Windows 4.0"
2023 Windows 2003 doesn't set the native lan manager string but
2024 they do set the domain to "Windows 2003 5.2" (probably a bug).
2025 ********************************************************************/
2027 void ra_lanman_string( const char *native_lanman )
2029 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
2030 set_remote_arch( RA_WINXP );
2031 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
2032 set_remote_arch( RA_WIN2K3 );
2035 /*******************************************************************
2036 Set the horrid remote_arch string based on an enum.
2037 ********************************************************************/
2039 void set_remote_arch(enum remote_arch_types type)
2041 ra_type = type;
2042 switch( type ) {
2043 case RA_WFWG:
2044 fstrcpy(remote_arch, "WfWg");
2045 break;
2046 case RA_OS2:
2047 fstrcpy(remote_arch, "OS2");
2048 break;
2049 case RA_WIN95:
2050 fstrcpy(remote_arch, "Win95");
2051 break;
2052 case RA_WINNT:
2053 fstrcpy(remote_arch, "WinNT");
2054 break;
2055 case RA_WIN2K:
2056 fstrcpy(remote_arch, "Win2K");
2057 break;
2058 case RA_WINXP:
2059 fstrcpy(remote_arch, "WinXP");
2060 break;
2061 case RA_WIN2K3:
2062 fstrcpy(remote_arch, "Win2K3");
2063 break;
2064 case RA_SAMBA:
2065 fstrcpy(remote_arch,"Samba");
2066 break;
2067 case RA_CIFSFS:
2068 fstrcpy(remote_arch,"CIFSFS");
2069 break;
2070 default:
2071 ra_type = RA_UNKNOWN;
2072 fstrcpy(remote_arch, "UNKNOWN");
2073 break;
2076 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n", remote_arch));
2079 /*******************************************************************
2080 Get the remote_arch type.
2081 ********************************************************************/
2083 enum remote_arch_types get_remote_arch(void)
2085 return ra_type;
2088 void print_asc(int level, const unsigned char *buf,int len)
2090 int i;
2091 for (i=0;i<len;i++)
2092 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
2095 void dump_data(int level, const char *buf1,int len)
2097 const unsigned char *buf = (const unsigned char *)buf1;
2098 int i=0;
2099 if (len<=0) return;
2101 if (!DEBUGLVL(level)) return;
2103 DEBUGADD(level,("[%03X] ",i));
2104 for (i=0;i<len;) {
2105 DEBUGADD(level,("%02X ",(int)buf[i]));
2106 i++;
2107 if (i%8 == 0) DEBUGADD(level,(" "));
2108 if (i%16 == 0) {
2109 print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
2110 print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
2111 if (i<len) DEBUGADD(level,("[%03X] ",i));
2114 if (i%16) {
2115 int n;
2116 n = 16 - (i%16);
2117 DEBUGADD(level,(" "));
2118 if (n>8) DEBUGADD(level,(" "));
2119 while (n--) DEBUGADD(level,(" "));
2120 n = MIN(8,i%16);
2121 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
2122 n = (i%16) - n;
2123 if (n>0) print_asc(level,&buf[i-n],n);
2124 DEBUGADD(level,("\n"));
2128 void dump_data_pw(const char *msg, const uchar * data, size_t len)
2130 #ifdef DEBUG_PASSWORD
2131 DEBUG(11, ("%s", msg));
2132 if (data != NULL && len > 0)
2134 dump_data(11, (const char *)data, len);
2136 #endif
2139 char *tab_depth(int depth)
2141 static pstring spaces;
2142 memset(spaces, ' ', depth * 4);
2143 spaces[depth * 4] = 0;
2144 return spaces;
2147 /*****************************************************************************
2148 Provide a checksum on a string
2150 Input: s - the null-terminated character string for which the checksum
2151 will be calculated.
2153 Output: The checksum value calculated for s.
2154 *****************************************************************************/
2156 int str_checksum(const char *s)
2158 int res = 0;
2159 int c;
2160 int i=0;
2162 while(*s) {
2163 c = *s;
2164 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
2165 s++;
2166 i++;
2168 return(res);
2171 /*****************************************************************
2172 Zero a memory area then free it. Used to catch bugs faster.
2173 *****************************************************************/
2175 void zero_free(void *p, size_t size)
2177 memset(p, 0, size);
2178 SAFE_FREE(p);
2181 /*****************************************************************
2182 Set our open file limit to a requested max and return the limit.
2183 *****************************************************************/
2185 int set_maxfiles(int requested_max)
2187 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2188 struct rlimit rlp;
2189 int saved_current_limit;
2191 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2192 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2193 strerror(errno) ));
2194 /* just guess... */
2195 return requested_max;
2199 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2200 * account for the extra fd we need
2201 * as well as the log files and standard
2202 * handles etc. Save the limit we want to set in case
2203 * we are running on an OS that doesn't support this limit (AIX)
2204 * which always returns RLIM_INFINITY for rlp.rlim_max.
2207 /* Try raising the hard (max) limit to the requested amount. */
2209 #if defined(RLIM_INFINITY)
2210 if (rlp.rlim_max != RLIM_INFINITY) {
2211 int orig_max = rlp.rlim_max;
2213 if ( rlp.rlim_max < requested_max )
2214 rlp.rlim_max = requested_max;
2216 /* This failing is not an error - many systems (Linux) don't
2217 support our default request of 10,000 open files. JRA. */
2219 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2220 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2221 (int)rlp.rlim_max, strerror(errno) ));
2223 /* Set failed - restore original value from get. */
2224 rlp.rlim_max = orig_max;
2227 #endif
2229 /* Now try setting the soft (current) limit. */
2231 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2233 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2234 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2235 (int)rlp.rlim_cur, strerror(errno) ));
2236 /* just guess... */
2237 return saved_current_limit;
2240 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2241 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2242 strerror(errno) ));
2243 /* just guess... */
2244 return saved_current_limit;
2247 #if defined(RLIM_INFINITY)
2248 if(rlp.rlim_cur == RLIM_INFINITY)
2249 return saved_current_limit;
2250 #endif
2252 if((int)rlp.rlim_cur > saved_current_limit)
2253 return saved_current_limit;
2255 return rlp.rlim_cur;
2256 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2258 * No way to know - just guess...
2260 return requested_max;
2261 #endif
2264 /*****************************************************************
2265 Possibly replace mkstemp if it is broken.
2266 *****************************************************************/
2268 int smb_mkstemp(char *name_template)
2270 #if HAVE_SECURE_MKSTEMP
2271 return mkstemp(name_template);
2272 #else
2273 /* have a reasonable go at emulating it. Hope that
2274 the system mktemp() isn't completly hopeless */
2275 char *p = mktemp(name_template);
2276 if (!p)
2277 return -1;
2278 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
2279 #endif
2282 /*****************************************************************
2283 malloc that aborts with smb_panic on fail or zero size.
2284 *****************************************************************/
2286 void *smb_xmalloc_array(size_t size, unsigned int count)
2288 void *p;
2289 if (size == 0)
2290 smb_panic("smb_xmalloc_array: called with zero size.\n");
2291 if (count >= MAX_ALLOC_SIZE/size) {
2292 smb_panic("smb_xmalloc: alloc size too large.\n");
2294 if ((p = SMB_MALLOC(size*count)) == NULL) {
2295 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2296 (unsigned long)size, (unsigned long)count));
2297 smb_panic("smb_xmalloc_array: malloc fail.\n");
2299 return p;
2303 Memdup with smb_panic on fail.
2306 void *smb_xmemdup(const void *p, size_t size)
2308 void *p2;
2309 p2 = SMB_XMALLOC_ARRAY(unsigned char,size);
2310 memcpy(p2, p, size);
2311 return p2;
2315 strdup that aborts on malloc fail.
2318 char *smb_xstrdup(const char *s)
2320 #if defined(PARANOID_MALLOC_CHECKER)
2321 #ifdef strdup
2322 #undef strdup
2323 #endif
2324 #endif
2325 char *s1 = strdup(s);
2326 #if defined(PARANOID_MALLOC_CHECKER)
2327 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
2328 #endif
2329 if (!s1)
2330 smb_panic("smb_xstrdup: malloc fail\n");
2331 return s1;
2336 strndup that aborts on malloc fail.
2339 char *smb_xstrndup(const char *s, size_t n)
2341 #if defined(PARANOID_MALLOC_CHECKER)
2342 #ifdef strndup
2343 #undef strndup
2344 #endif
2345 #endif
2346 char *s1 = strndup(s, n);
2347 #if defined(PARANOID_MALLOC_CHECKER)
2348 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
2349 #endif
2350 if (!s1)
2351 smb_panic("smb_xstrndup: malloc fail\n");
2352 return s1;
2356 vasprintf that aborts on malloc fail
2359 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2361 int n;
2362 va_list ap2;
2364 VA_COPY(ap2, ap);
2366 n = vasprintf(ptr, format, ap2);
2367 if (n == -1 || ! *ptr)
2368 smb_panic("smb_xvasprintf: out of memory");
2369 return n;
2372 /*****************************************************************
2373 Like strdup but for memory.
2374 *****************************************************************/
2376 void *memdup(const void *p, size_t size)
2378 void *p2;
2379 if (size == 0)
2380 return NULL;
2381 p2 = SMB_MALLOC(size);
2382 if (!p2)
2383 return NULL;
2384 memcpy(p2, p, size);
2385 return p2;
2388 /*****************************************************************
2389 Get local hostname and cache result.
2390 *****************************************************************/
2392 char *myhostname(void)
2394 static pstring ret;
2395 if (ret[0] == 0)
2396 get_myname(ret);
2397 return ret;
2400 /*****************************************************************
2401 A useful function for returning a path in the Samba lock directory.
2402 *****************************************************************/
2404 char *lock_path(const char *name)
2406 static pstring fname;
2408 pstrcpy(fname,lp_lockdir());
2409 trim_char(fname,'\0','/');
2411 if (!directory_exist(fname,NULL))
2412 mkdir(fname,0755);
2414 pstrcat(fname,"/");
2415 pstrcat(fname,name);
2417 return fname;
2420 /*****************************************************************
2421 A useful function for returning a path in the Samba pid directory.
2422 *****************************************************************/
2424 char *pid_path(const char *name)
2426 static pstring fname;
2428 pstrcpy(fname,lp_piddir());
2429 trim_char(fname,'\0','/');
2431 if (!directory_exist(fname,NULL))
2432 mkdir(fname,0755);
2434 pstrcat(fname,"/");
2435 pstrcat(fname,name);
2437 return fname;
2441 * @brief Returns an absolute path to a file in the Samba lib directory.
2443 * @param name File to find, relative to LIBDIR.
2445 * @retval Pointer to a static #pstring containing the full path.
2448 char *lib_path(const char *name)
2450 static pstring fname;
2451 fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
2452 return fname;
2456 * @brief Returns the platform specific shared library extension.
2458 * @retval Pointer to a static #fstring containing the extension.
2461 const char *shlib_ext(void)
2463 return dyn_SHLIBEXT;
2466 /*******************************************************************
2467 Given a filename - get its directory name
2468 NB: Returned in static storage. Caveats:
2469 o Not safe in thread environment.
2470 o Caller must not free.
2471 o If caller wishes to preserve, they should copy.
2472 ********************************************************************/
2474 char *parent_dirname(const char *path)
2476 static pstring dirpath;
2477 char *p;
2479 if (!path)
2480 return(NULL);
2482 pstrcpy(dirpath, path);
2483 p = strrchr_m(dirpath, '/'); /* Find final '/', if any */
2484 if (!p) {
2485 pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
2486 } else {
2487 if (p == dirpath)
2488 ++p; /* For root "/", leave "/" in place */
2489 *p = '\0';
2491 return dirpath;
2495 /*******************************************************************
2496 Determine if a pattern contains any Microsoft wildcard characters.
2497 *******************************************************************/
2499 BOOL ms_has_wild(const char *s)
2501 char c;
2503 if (lp_posix_pathnames()) {
2504 /* With posix pathnames no characters are wild. */
2505 return False;
2508 while ((c = *s++)) {
2509 switch (c) {
2510 case '*':
2511 case '?':
2512 case '<':
2513 case '>':
2514 case '"':
2515 return True;
2518 return False;
2521 BOOL ms_has_wild_w(const smb_ucs2_t *s)
2523 smb_ucs2_t c;
2524 if (!s) return False;
2525 while ((c = *s++)) {
2526 switch (c) {
2527 case UCS2_CHAR('*'):
2528 case UCS2_CHAR('?'):
2529 case UCS2_CHAR('<'):
2530 case UCS2_CHAR('>'):
2531 case UCS2_CHAR('"'):
2532 return True;
2535 return False;
2538 /*******************************************************************
2539 A wrapper that handles case sensitivity and the special handling
2540 of the ".." name.
2541 *******************************************************************/
2543 BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
2545 if (strcmp(string,"..") == 0)
2546 string = ".";
2547 if (strcmp(pattern,".") == 0)
2548 return False;
2550 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2553 /*******************************************************************
2554 A wrapper that handles case sensitivity and the special handling
2555 of the ".." name. Varient that is only called by old search code which requires
2556 pattern translation.
2557 *******************************************************************/
2559 BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
2561 if (strcmp(string,"..") == 0)
2562 string = ".";
2563 if (strcmp(pattern,".") == 0)
2564 return False;
2566 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2569 /*******************************************************************
2570 A wrapper that handles a list of patters and calls mask_match()
2571 on each. Returns True if any of the patterns match.
2572 *******************************************************************/
2574 BOOL mask_match_list(const char *string, char **list, int listLen, BOOL is_case_sensitive)
2576 while (listLen-- > 0) {
2577 if (mask_match(string, *list++, is_case_sensitive))
2578 return True;
2580 return False;
2583 /*********************************************************
2584 Recursive routine that is called by unix_wild_match.
2585 *********************************************************/
2587 static BOOL unix_do_match(const char *regexp, const char *str)
2589 const char *p;
2591 for( p = regexp; *p && *str; ) {
2593 switch(*p) {
2594 case '?':
2595 str++;
2596 p++;
2597 break;
2599 case '*':
2602 * Look for a character matching
2603 * the one after the '*'.
2605 p++;
2606 if(!*p)
2607 return True; /* Automatic match */
2608 while(*str) {
2610 while(*str && (*p != *str))
2611 str++;
2614 * Patch from weidel@multichart.de. In the case of the regexp
2615 * '*XX*' we want to ensure there are at least 2 'X' characters
2616 * in the string after the '*' for a match to be made.
2620 int matchcount=0;
2623 * Eat all the characters that match, but count how many there were.
2626 while(*str && (*p == *str)) {
2627 str++;
2628 matchcount++;
2632 * Now check that if the regexp had n identical characters that
2633 * matchcount had at least that many matches.
2636 while ( *(p+1) && (*(p+1) == *p)) {
2637 p++;
2638 matchcount--;
2641 if ( matchcount <= 0 )
2642 return False;
2645 str--; /* We've eaten the match char after the '*' */
2647 if(unix_do_match(p, str))
2648 return True;
2650 if(!*str)
2651 return False;
2652 else
2653 str++;
2655 return False;
2657 default:
2658 if(*str != *p)
2659 return False;
2660 str++;
2661 p++;
2662 break;
2666 if(!*p && !*str)
2667 return True;
2669 if (!*p && str[0] == '.' && str[1] == 0)
2670 return(True);
2672 if (!*str && *p == '?') {
2673 while (*p == '?')
2674 p++;
2675 return(!*p);
2678 if(!*str && (*p == '*' && p[1] == '\0'))
2679 return True;
2681 return False;
2684 /*******************************************************************
2685 Simple case insensitive interface to a UNIX wildcard matcher.
2686 Returns True if match, False if not.
2687 *******************************************************************/
2689 BOOL unix_wild_match(const char *pattern, const char *string)
2691 pstring p2, s2;
2692 char *p;
2694 pstrcpy(p2, pattern);
2695 pstrcpy(s2, string);
2696 strlower_m(p2);
2697 strlower_m(s2);
2699 /* Remove any *? and ** from the pattern as they are meaningless */
2700 for(p = p2; *p; p++)
2701 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2702 pstrcpy( &p[1], &p[2]);
2704 if (strequal(p2,"*"))
2705 return True;
2707 return unix_do_match(p2, s2);
2710 /**********************************************************************
2711 Converts a name to a fully qalified domain name.
2712 ***********************************************************************/
2714 void name_to_fqdn(fstring fqdn, const char *name)
2716 struct hostent *hp = sys_gethostbyname(name);
2717 if ( hp && hp->h_name && *hp->h_name ) {
2718 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name));
2719 fstrcpy(fqdn,hp->h_name);
2720 } else {
2721 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2722 fstrcpy(fqdn, name);
2726 /**********************************************************************
2727 Extension to talloc_get_type: Abort on type mismatch
2728 ***********************************************************************/
2730 void *talloc_check_name_abort(const void *ptr, const char *name)
2732 void *result;
2734 if (ptr == NULL)
2735 return NULL;
2737 result = talloc_check_name(ptr, name);
2738 if (result != NULL)
2739 return result;
2741 DEBUG(0, ("Talloc type mismatch, expected %s, got %s\n",
2742 name, talloc_get_name(ptr)));
2743 smb_panic("aborting");
2744 /* Keep the compiler happy */
2745 return NULL;
2749 #ifdef __INSURE__
2751 /*******************************************************************
2752 This routine is a trick to immediately catch errors when debugging
2753 with insure. A xterm with a gdb is popped up when insure catches
2754 a error. It is Linux specific.
2755 ********************************************************************/
2757 int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
2759 static int (*fn)();
2760 int ret;
2761 char pidstr[10];
2762 /* you can get /usr/bin/backtrace from
2763 http://samba.org/ftp/unpacked/junkcode/backtrace */
2764 pstring cmd = "/usr/bin/backtrace %d";
2766 slprintf(pidstr, sizeof(pidstr)-1, "%d", sys_getpid());
2767 pstring_sub(cmd, "%d", pidstr);
2769 if (!fn) {
2770 static void *h;
2771 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
2772 fn = dlsym(h, "_Insure_trap_error");
2774 if (!h || h == _Insure_trap_error) {
2775 h = dlopen("/usr/local/parasoft/lib.linux2/libinsure.so", RTLD_LAZY);
2776 fn = dlsym(h, "_Insure_trap_error");
2780 ret = fn(a1, a2, a3, a4, a5, a6);
2782 system(cmd);
2784 return ret;
2786 #endif
2788 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2790 switch (share_access & ~FILE_SHARE_DELETE) {
2791 case FILE_SHARE_NONE:
2792 return DENY_ALL;
2793 case FILE_SHARE_READ:
2794 return DENY_WRITE;
2795 case FILE_SHARE_WRITE:
2796 return DENY_READ;
2797 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2798 return DENY_NONE;
2800 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2801 return DENY_DOS;
2802 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2803 return DENY_FCB;
2806 return (uint32)-1;
2809 pid_t procid_to_pid(const struct process_id *proc)
2811 return proc->pid;
2814 struct process_id pid_to_procid(pid_t pid)
2816 struct process_id result;
2817 result.pid = pid;
2818 return result;
2821 struct process_id procid_self(void)
2823 return pid_to_procid(sys_getpid());
2826 BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
2828 return (p1->pid == p2->pid);
2831 BOOL procid_is_me(const struct process_id *pid)
2833 return (pid->pid == sys_getpid());
2836 struct process_id interpret_pid(const char *pid_string)
2838 return pid_to_procid(atoi(pid_string));
2841 char *procid_str_static(const struct process_id *pid)
2843 static fstring str;
2844 fstr_sprintf(str, "%d", pid->pid);
2845 return str;
2848 char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
2850 return talloc_strdup(mem_ctx, procid_str_static(pid));
2853 BOOL procid_valid(const struct process_id *pid)
2855 return (pid->pid != -1);
2858 BOOL procid_is_local(const struct process_id *pid)
2860 return True;