r2783: got rid of the unused remote architecture detection code
[bbaumbach/samba-autobuild/.git] / source4 / lib / util.c
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 J Myers 2003
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
27 /**************************************************************************n
28  Find a suitable temporary directory. The result should be copied immediately
29  as it may be overwritten by a subsequent call.
30 ****************************************************************************/
31
32 const char *tmpdir(void)
33 {
34         char *p;
35         if ((p = getenv("TMPDIR")))
36                 return p;
37         return "/tmp";
38 }
39
40 /****************************************************************************
41  Determine whether we are in the specified group.
42 ****************************************************************************/
43
44 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
45 {
46         int i;
47
48         if (group == current_gid)
49                 return(True);
50
51         for (i=0;i<ngroups;i++)
52                 if (group == groups[i])
53                         return(True);
54
55         return(False);
56 }
57
58 /*******************************************************************
59  Check if a file exists - call vfs_file_exist for samba files.
60 ********************************************************************/
61
62 BOOL file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
63 {
64         SMB_STRUCT_STAT st;
65         if (!sbuf)
66                 sbuf = &st;
67   
68         if (sys_stat(fname,sbuf) != 0) 
69                 return(False);
70
71         return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
72 }
73
74 /*******************************************************************
75  Check a files mod time.
76 ********************************************************************/
77
78 time_t file_modtime(const char *fname)
79 {
80         SMB_STRUCT_STAT st;
81   
82         if (sys_stat(fname,&st) != 0) 
83                 return(0);
84
85         return(st.st_mtime);
86 }
87
88 /*******************************************************************
89  Check if a directory exists.
90 ********************************************************************/
91
92 BOOL directory_exist(const char *dname,SMB_STRUCT_STAT *st)
93 {
94         SMB_STRUCT_STAT st2;
95         BOOL ret;
96
97         if (!st)
98                 st = &st2;
99
100         if (sys_stat(dname,st) != 0) 
101                 return(False);
102
103         ret = S_ISDIR(st->st_mode);
104         if(!ret)
105                 errno = ENOTDIR;
106         return ret;
107 }
108
109 /*******************************************************************
110  Returns the size in bytes of the named file.
111 ********************************************************************/
112 SMB_OFF_T get_file_size(char *file_name)
113 {
114         SMB_STRUCT_STAT buf;
115         buf.st_size = 0;
116         if(sys_stat(file_name,&buf) != 0)
117                 return (SMB_OFF_T)-1;
118         return(buf.st_size);
119 }
120
121 /*******************************************************************
122  Close the low 3 fd's and open dev/null in their place.
123 ********************************************************************/
124 void close_low_fds(BOOL stderr_too)
125 {
126 #ifndef VALGRIND
127         int fd;
128         int i;
129
130         close(0);
131         close(1); 
132
133         if (stderr_too)
134                 close(2);
135
136         /* try and use up these file descriptors, so silly
137                 library routines writing to stdout etc won't cause havoc */
138         for (i=0;i<3;i++) {
139                 if (i == 2 && !stderr_too)
140                         continue;
141
142                 fd = sys_open("/dev/null",O_RDWR,0);
143                 if (fd < 0)
144                         fd = sys_open("/dev/null",O_WRONLY,0);
145                 if (fd < 0) {
146                         DEBUG(0,("Can't open /dev/null\n"));
147                         return;
148                 }
149                 if (fd != i) {
150                         DEBUG(0,("Didn't get file descriptor %d\n",i));
151                         return;
152                 }
153         }
154 #endif
155 }
156
157 /****************************************************************************
158  Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
159  else
160   if SYSV use O_NDELAY
161   if BSD use FNDELAY
162 ****************************************************************************/
163
164 int set_blocking(int fd, BOOL set)
165 {
166         int val;
167 #ifdef O_NONBLOCK
168 #define FLAG_TO_SET O_NONBLOCK
169 #else
170 #ifdef SYSV
171 #define FLAG_TO_SET O_NDELAY
172 #else /* BSD */
173 #define FLAG_TO_SET FNDELAY
174 #endif
175 #endif
176
177         if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
178                 return -1;
179         if(set) /* Turn blocking on - ie. clear nonblock flag */
180                 val &= ~FLAG_TO_SET;
181         else
182                 val |= FLAG_TO_SET;
183         return sys_fcntl_long( fd, F_SETFL, val);
184 #undef FLAG_TO_SET
185 }
186
187
188 /*******************************************************************
189  Sleep for a specified number of milliseconds.
190 ********************************************************************/
191
192 void msleep(uint_t t)
193 {
194         struct timeval tval;  
195
196         tval.tv_sec = t/1000;
197         tval.tv_usec = 1000*(t%1000);
198         /* this should be the real select - do NOT replace
199            with sys_select() */
200         select(0,NULL,NULL,NULL,&tval);
201 }
202
203 /****************************************************************************
204  Become a daemon, discarding the controlling terminal.
205 ****************************************************************************/
206
207 void become_daemon(BOOL Fork)
208 {
209         if (Fork) {
210                 if (fork()) {
211                         _exit(0);
212                 }
213         }
214
215   /* detach from the terminal */
216 #ifdef HAVE_SETSID
217         setsid();
218 #elif defined(TIOCNOTTY)
219         {
220                 int i = sys_open("/dev/tty", O_RDWR, 0);
221                 if (i != -1) {
222                         ioctl(i, (int) TIOCNOTTY, (char *)0);      
223                         close(i);
224                 }
225         }
226 #endif /* HAVE_SETSID */
227
228         /* Close fd's 0,1,2. Needed if started by rsh */
229         close_low_fds(False);  /* Don't close stderr, let the debug system
230                                   attach it to the logfile */
231 }
232
233
234 /****************************************************************************
235  Expand a pointer to be a particular size.
236 ****************************************************************************/
237
238 void *Realloc(void *p,size_t size)
239 {
240         void *ret=NULL;
241
242         if (size == 0) {
243                 SAFE_FREE(p);
244                 DEBUG(5,("Realloc asked for 0 bytes\n"));
245                 return NULL;
246         }
247
248         if (!p)
249                 ret = (void *)malloc(size);
250         else
251                 ret = (void *)realloc(p,size);
252
253         if (!ret)
254                 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
255
256         return(ret);
257 }
258
259 /****************************************************************************
260  Free memory, checks for NULL.
261  Use directly SAFE_FREE()
262  Exists only because we need to pass a function pointer somewhere --SSS
263 ****************************************************************************/
264
265 void safe_free(void *p)
266 {
267         SAFE_FREE(p);
268 }
269
270
271 /*
272   see if a string matches either our primary or one of our secondary 
273   netbios aliases. do a case insensitive match
274 */
275 BOOL is_myname(const char *name)
276 {
277         const char **aliases;
278         int i;
279
280         if (strcasecmp(name, lp_netbios_name()) == 0) {
281                 return True;
282         }
283
284         aliases = lp_netbios_aliases();
285         for (i=0; aliases && aliases[i]; i++) {
286                 if (strcasecmp(name, aliases[i]) == 0) {
287                         return True;
288                 }
289         }
290
291         return False;
292 }
293
294
295 /****************************************************************************
296  Get my own name, return in malloc'ed storage.
297 ****************************************************************************/
298
299 char* get_myname(void)
300 {
301         char *hostname;
302         const int host_name_max = 255;
303         char *p;
304
305         hostname = malloc(host_name_max+1);
306         *hostname = 0;
307
308         /* get my host name */
309         if (gethostname(hostname, host_name_max+1) == -1) {
310                 DEBUG(0,("gethostname failed\n"));
311                 return NULL;
312         } 
313
314         /* Ensure null termination. */
315         hostname[host_name_max] = '\0';
316
317         /* split off any parts after an initial . */
318         p = strchr_m(hostname,'.');
319
320         if (p)
321                 *p = 0;
322         
323         return hostname;
324 }
325
326 /****************************************************************************
327  Get my own name, including domain.
328 ****************************************************************************/
329
330 BOOL get_myfullname(char *my_name)
331 {
332         pstring hostname;
333
334         *hostname = 0;
335
336         /* get my host name */
337         if (gethostname(hostname, sizeof(hostname)) == -1) {
338                 DEBUG(0,("gethostname failed\n"));
339                 return False;
340         } 
341
342         /* Ensure null termination. */
343         hostname[sizeof(hostname)-1] = '\0';
344
345         if (my_name)
346                 fstrcpy(my_name, hostname);
347         return True;
348 }
349
350 /****************************************************************************
351  Get my own domain name.
352 ****************************************************************************/
353
354 BOOL get_mydomname(fstring my_domname)
355 {
356         pstring hostname;
357         char *p;
358
359         *hostname = 0;
360         /* get my host name */
361         if (gethostname(hostname, sizeof(hostname)) == -1) {
362                 DEBUG(0,("gethostname failed\n"));
363                 return False;
364         } 
365
366         /* Ensure null termination. */
367         hostname[sizeof(hostname)-1] = '\0';
368
369         p = strchr_m(hostname, '.');
370
371         if (!p)
372                 return False;
373
374         p++;
375         
376         if (my_domname)
377                 fstrcpy(my_domname, p);
378
379         return True;
380 }
381
382 /****************************************************************************
383  Interpret a protocol description string, with a default.
384 ****************************************************************************/
385
386 int interpret_protocol(char *str,int def)
387 {
388         if (strequal(str,"NT1"))
389                 return(PROTOCOL_NT1);
390         if (strequal(str,"LANMAN2"))
391                 return(PROTOCOL_LANMAN2);
392         if (strequal(str,"LANMAN1"))
393                 return(PROTOCOL_LANMAN1);
394         if (strequal(str,"CORE"))
395                 return(PROTOCOL_CORE);
396         if (strequal(str,"COREPLUS"))
397                 return(PROTOCOL_COREPLUS);
398         if (strequal(str,"CORE+"))
399                 return(PROTOCOL_COREPLUS);
400   
401         DEBUG(0,("Unrecognised protocol level %s\n",str));
402   
403         return(def);
404 }
405
406 /****************************************************************************
407  Return true if a string could be a pure IP address.
408 ****************************************************************************/
409
410 BOOL is_ipaddress(const char *str)
411 {
412         BOOL pure_address = True;
413         int i;
414   
415         for (i=0; pure_address && str[i]; i++)
416                 if (!(isdigit((int)str[i]) || str[i] == '.'))
417                         pure_address = False;
418
419         /* Check that a pure number is not misinterpreted as an IP */
420         pure_address = pure_address && (strchr_m(str, '.') != NULL);
421
422         return pure_address;
423 }
424
425 /****************************************************************************
426  Interpret an internet address or name into an IP address in 4 byte form.
427 ****************************************************************************/
428
429 uint32_t interpret_addr(const char *str)
430 {
431         struct hostent *hp;
432         uint32_t res;
433
434         if (strcmp(str,"0.0.0.0") == 0)
435                 return(0);
436         if (strcmp(str,"255.255.255.255") == 0)
437                 return(0xFFFFFFFF);
438
439         /* if it's in the form of an IP address then get the lib to interpret it */
440         if (is_ipaddress(str)) {
441                 res = inet_addr(str);
442         } else {
443                 /* otherwise assume it's a network name of some sort and use 
444                         sys_gethostbyname */
445                 if ((hp = sys_gethostbyname(str)) == 0) {
446                         DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
447                         return 0;
448                 }
449
450                 if(hp->h_addr == NULL) {
451                         DEBUG(3,("sys_gethostbyname: host address is invalid for host %s\n",str));
452                         return 0;
453                 }
454                 putip((char *)&res,(char *)hp->h_addr);
455         }
456
457         if (res == (uint32_t)-1)
458                 return(0);
459
460         return(res);
461 }
462
463 /*******************************************************************
464  A convenient addition to interpret_addr().
465 ******************************************************************/
466
467 struct in_addr *interpret_addr2(TALLOC_CTX *mem_ctx, const char *str)
468 {
469         struct in_addr *ret;
470         uint32_t a = interpret_addr(str);
471         
472         ret = talloc(mem_ctx, sizeof(struct in_addr));
473         if (!ret) return NULL;
474         ret->s_addr = a;
475         return(ret);
476 }
477
478 /*******************************************************************
479  Check if an IP is the 0.0.0.0.
480 ******************************************************************/
481
482 BOOL is_zero_ip(struct in_addr ip)
483 {
484         uint32_t a;
485         putip((char *)&a,(char *)&ip);
486         return(a == 0);
487 }
488
489 /*******************************************************************
490  Set an IP to 0.0.0.0.
491 ******************************************************************/
492
493 void zero_ip(struct in_addr *ip)
494 {
495         *ip = inet_makeaddr(0,0);
496         return;
497 }
498
499
500 /*******************************************************************
501  Are two IPs on the same subnet?
502 ********************************************************************/
503
504 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
505 {
506         uint32_t net1,net2,nmask;
507
508         nmask = ntohl(mask.s_addr);
509         net1  = ntohl(ip1.s_addr);
510         net2  = ntohl(ip2.s_addr);
511             
512         return((net1 & nmask) == (net2 & nmask));
513 }
514
515
516 /****************************************************************************
517  Check if a process exists. Does this work on all unixes?
518 ****************************************************************************/
519
520 BOOL process_exists(pid_t pid)
521 {
522         /* Doing kill with a non-positive pid causes messages to be
523          * sent to places we don't want. */
524         SMB_ASSERT(pid > 0);
525         return(kill(pid,0) == 0 || errno != ESRCH);
526 }
527
528 /****************************************************************************
529  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
530  is dealt with in posix.c
531 ****************************************************************************/
532
533 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
534 {
535         SMB_STRUCT_FLOCK lock;
536         int ret;
537
538         DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
539
540         lock.l_type = type;
541         lock.l_whence = SEEK_SET;
542         lock.l_start = offset;
543         lock.l_len = count;
544         lock.l_pid = 0;
545
546         ret = sys_fcntl_ptr(fd,op,&lock);
547
548         if (ret == -1 && errno != 0)
549                 DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
550
551         /* a lock query */
552         if (op == SMB_F_GETLK) {
553                 if ((ret != -1) &&
554                                 (lock.l_type != F_UNLCK) && 
555                                 (lock.l_pid != 0) && 
556                                 (lock.l_pid != getpid())) {
557                         DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
558                         return(True);
559                 }
560
561                 /* it must be not locked or locked by me */
562                 return(False);
563         }
564
565         /* a lock set or unset */
566         if (ret == -1) {
567                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
568                         (double)offset,(double)count,op,type,strerror(errno)));
569                 return(False);
570         }
571
572         /* everything went OK */
573         DEBUG(8,("fcntl_lock: Lock call successful\n"));
574
575         return(True);
576 }
577
578
579 static void print_asc(int level, const uint8_t *buf,int len)
580 {
581         int i;
582         for (i=0;i<len;i++)
583                 DEBUGADD(level,("%c", isprint(buf[i])?buf[i]:'.'));
584 }
585
586 void dump_data(int level, const char *buf1,int len)
587 {
588         const uint8_t *buf = (const uint8_t *)buf1;
589         int i=0;
590         if (len<=0) return;
591
592         if (!DEBUGLVL(level)) return;
593         
594         DEBUGADD(level,("[%03X] ",i));
595         for (i=0;i<len;) {
596                 DEBUGADD(level,("%02X ",(int)buf[i]));
597                 i++;
598                 if (i%8 == 0) DEBUGADD(level,(" "));
599                 if (i%16 == 0) {      
600                         print_asc(level,&buf[i-16],8); DEBUGADD(level,(" "));
601                         print_asc(level,&buf[i-8],8); DEBUGADD(level,("\n"));
602                         if (i<len) DEBUGADD(level,("[%03X] ",i));
603                 }
604         }
605         if (i%16) {
606                 int n;
607                 n = 16 - (i%16);
608                 DEBUGADD(level,(" "));
609                 if (n>8) DEBUGADD(level,(" "));
610                 while (n--) DEBUGADD(level,("   "));
611                 n = MIN(8,i%16);
612                 print_asc(level,&buf[i-(i%16)],n); DEBUGADD(level,( " " ));
613                 n = (i%16) - n;
614                 if (n>0) print_asc(level,&buf[i-n],n); 
615                 DEBUGADD(level,("\n"));    
616         }       
617 }
618
619 /*****************************************************************
620  Possibly replace mkstemp if it is broken.
621 *****************************************************************/  
622
623 int smb_mkstemp(char *template)
624 {
625 #if HAVE_SECURE_MKSTEMP
626         return mkstemp(template);
627 #else
628         /* have a reasonable go at emulating it. Hope that
629            the system mktemp() isn't completly hopeless */
630         char *p = mktemp(template);
631         if (!p)
632                 return -1;
633         return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
634 #endif
635 }
636
637 /*****************************************************************
638  malloc that aborts with smb_panic on fail or zero size.
639  *****************************************************************/  
640
641 void *smb_xmalloc(size_t size)
642 {
643         void *p;
644         if (size == 0)
645                 smb_panic("smb_xmalloc: called with zero size.\n");
646         if ((p = malloc(size)) == NULL)
647                 smb_panic("smb_xmalloc: malloc fail.\n");
648         return p;
649 }
650
651 /**
652  Memdup with smb_panic on fail.
653 **/
654
655 void *smb_xmemdup(const void *p, size_t size)
656 {
657         void *p2;
658         p2 = smb_xmalloc(size);
659         memcpy(p2, p, size);
660         return p2;
661 }
662
663 /**
664  strdup that aborts on malloc fail.
665 **/
666
667 char *smb_xstrdup(const char *s)
668 {
669         char *s1 = strdup(s);
670         if (!s1)
671                 smb_panic("smb_xstrdup: malloc fail\n");
672         return s1;
673 }
674
675
676 /*****************************************************************
677  Like strdup but for memory.
678 *****************************************************************/  
679
680 void *memdup(const void *p, size_t size)
681 {
682         void *p2;
683         if (size == 0)
684                 return NULL;
685         p2 = malloc(size);
686         if (!p2)
687                 return NULL;
688         memcpy(p2, p, size);
689         return p2;
690 }
691
692 /*****************************************************************
693  Get local hostname and cache result.
694 *****************************************************************/  
695
696 char *myhostname(TALLOC_CTX *mem_ctx)
697 {
698         char *myname, *ret;
699         myname = get_myname();
700         ret = talloc_strdup(mem_ctx, myname);
701         free(myname);
702         return ret;
703
704 }
705
706 /**********************************************************************
707  Converts a name to a fully qalified domain name.
708 ***********************************************************************/
709
710 char *name_to_fqdn(TALLOC_CTX *mem_ctx, const char *name)
711 {
712         struct hostent *hp = sys_gethostbyname(name);
713         if ( hp && hp->h_name && *hp->h_name ) {
714                 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name));
715                 return talloc_strdup(mem_ctx, hp->h_name);
716         } else {
717                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
718                 return talloc_strdup(mem_ctx, name);
719         }
720 }
721
722
723 /*****************************************************************
724  A useful function for returning a path in the Samba lock directory.
725 *****************************************************************/  
726
727 char *lock_path(TALLOC_CTX* mem_ctx, const char *name)
728 {
729         char *fname;
730
731         fname = talloc_strdup(mem_ctx, lp_lockdir());
732         trim_string(fname,"","/");
733         
734         if (!directory_exist(fname,NULL))
735                 mkdir(fname,0755);
736         
737         fname = talloc_asprintf(mem_ctx, "%s/%s", fname, name);
738
739         return fname;
740 }
741
742 /**
743  * @brief Returns an absolute path to a file in the Samba lib directory.
744  *
745  * @param name File to find, relative to LIBDIR.
746  *
747  * @retval Pointer to a talloc'ed string containing the full path.
748  **/
749
750 char *lib_path(TALLOC_CTX* mem_ctx, const char *name)
751 {
752         char *fname;
753         fname = talloc_asprintf(mem_ctx, "%s/%s", dyn_LIBDIR, name);
754         return fname;
755 }
756
757 /**
758  * @brief Returns the platform specific shared library extension.
759  *
760  * @retval Pointer to a static #fstring containing the extension.
761  **/
762
763 const char *shlib_ext(void)
764 {
765   return dyn_SHLIBEXT;
766 }
767
768
769 /*********************************************************
770  Recursive routine that is called by unix_wild_match.
771 *********************************************************/
772
773 static BOOL unix_do_match(char *regexp, char *str)
774 {
775         char *p;
776
777         for( p = regexp; *p && *str; ) {
778
779                 switch(*p) {
780                         case '?':
781                                 str++;
782                                 p++;
783                                 break;
784
785                         case '*':
786
787                                 /*
788                                  * Look for a character matching 
789                                  * the one after the '*'.
790                                  */
791                                 p++;
792                                 if(!*p)
793                                         return True; /* Automatic match */
794                                 while(*str) {
795
796                                         while(*str && (*p != *str))
797                                                 str++;
798
799                                         /*
800                                          * Patch from weidel@multichart.de. In the case of the regexp
801                                          * '*XX*' we want to ensure there are at least 2 'X' characters
802                                          * in the string after the '*' for a match to be made.
803                                          */
804
805                                         {
806                                                 int matchcount=0;
807
808                                                 /*
809                                                  * Eat all the characters that match, but count how many there were.
810                                                  */
811
812                                                 while(*str && (*p == *str)) {
813                                                         str++;
814                                                         matchcount++;
815                                                 }
816
817                                                 /*
818                                                  * Now check that if the regexp had n identical characters that
819                                                  * matchcount had at least that many matches.
820                                                  */
821
822                                                 while ( *(p+1) && (*(p+1) == *p)) {
823                                                         p++;
824                                                         matchcount--;
825                                                 }
826
827                                                 if ( matchcount <= 0 )
828                                                         return False;
829                                         }
830
831                                         str--; /* We've eaten the match char after the '*' */
832
833                                         if(unix_do_match(p, str))
834                                                 return True;
835
836                                         if(!*str)
837                                                 return False;
838                                         else
839                                                 str++;
840                                 }
841                                 return False;
842
843                         default:
844                                 if(*str != *p)
845                                         return False;
846                                 str++;
847                                 p++;
848                                 break;
849                 }
850         }
851
852         if(!*p && !*str)
853                 return True;
854
855         if (!*p && str[0] == '.' && str[1] == 0)
856                 return(True);
857   
858         if (!*str && *p == '?') {
859                 while (*p == '?')
860                         p++;
861                 return(!*p);
862         }
863
864         if(!*str && (*p == '*' && p[1] == '\0'))
865                 return True;
866
867         return False;
868 }
869
870 void dump_data_pw(const char *msg, const uint8_t * data, size_t len)
871 {
872 #ifdef DEBUG_PASSWORD
873         DEBUG(11, ("%s", msg));
874         if (data != NULL && len > 0)
875         {
876                 dump_data(11, data, len);
877         }
878 #endif
879 }
880
881
882 /* see if a range of memory is all zero. A NULL pointer is considered
883    to be all zero */
884 BOOL all_zero(const char *ptr, uint_t size)
885 {
886         int i;
887         if (!ptr) return True;
888         for (i=0;i<size;i++) {
889                 if (ptr[i]) return False;
890         }
891         return True;
892 }
893
894
895 /*
896   this is a warning hack. The idea is to use this everywhere that we
897   get the "discarding const" warning from gcc, effectively moving all
898   the warnings to this one place. That doesn't actually fix the
899   problem of course, but it means that when we do get to cleaning them
900   up we can do it by searching the code for discard_const.
901
902   It also means that other error types aren't as swamped by the noise
903   of hundreds of const warnings, so we are more likely to notice when
904   we get new errors.
905
906   Please only add more calls to this function when you find it
907   _really_ hard to fix const warnings. Our aim is to eventually use
908   this function in only a very few places.
909
910   Also, please call this via the discard_const_p() macro interface, as that
911   makes the return type safe.
912 */
913 void *discard_const(const void *ptr)
914 {
915         return (void *)ptr;
916 }