source: trunk/samba-3.0.25pre1/source/lib/util.c@ 16

Last change on this file since 16 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

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