lib: Simplify directory_create_or_exist with an early return
[kai/samba-autobuild/.git] / lib / util / 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-2011
7    Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
8    Copyright (C) James J Myers 2003
9    Copyright (C) Volker Lendecke 2010
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "system/network.h"
27 #include "system/filesys.h"
28 #include "system/locale.h"
29 #include "system/shmem.h"
30 #include "system/passwd.h"
31
32 #undef malloc
33 #undef strcasecmp
34 #undef strncasecmp
35 #undef strdup
36 #undef realloc
37 #undef calloc
38
39 /**
40  * @file
41  * @brief Misc utility functions
42  */
43
44 /**
45  Find a suitable temporary directory. The result should be copied immediately
46  as it may be overwritten by a subsequent call.
47 **/
48 _PUBLIC_ const char *tmpdir(void)
49 {
50         char *p;
51         if ((p = getenv("TMPDIR")))
52                 return p;
53         return "/tmp";
54 }
55
56
57 /**
58  Create a tmp file, open it and immediately unlink it.
59  If dir is NULL uses tmpdir()
60  Returns the file descriptor or -1 on error.
61 **/
62 int create_unlink_tmp(const char *dir)
63 {
64         char *fname;
65         int fd;
66         mode_t mask;
67
68         if (!dir) {
69                 dir = tmpdir();
70         }
71
72         fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
73         if (fname == NULL) {
74                 errno = ENOMEM;
75                 return -1;
76         }
77         mask = umask(S_IRWXO | S_IRWXG);
78         fd = mkstemp(fname);
79         umask(mask);
80         if (fd == -1) {
81                 TALLOC_FREE(fname);
82                 return -1;
83         }
84         if (unlink(fname) == -1) {
85                 int sys_errno = errno;
86                 close(fd);
87                 TALLOC_FREE(fname);
88                 errno = sys_errno;
89                 return -1;
90         }
91         TALLOC_FREE(fname);
92         return fd;
93 }
94
95
96 /**
97  Check if a file exists - call vfs_file_exist for samba files.
98 **/
99 _PUBLIC_ bool file_exist(const char *fname)
100 {
101         struct stat st;
102
103         if (stat(fname, &st) != 0) {
104                 return false;
105         }
106
107         return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode)));
108 }
109
110 /**
111  Check a files mod time.
112 **/
113
114 _PUBLIC_ time_t file_modtime(const char *fname)
115 {
116         struct stat st;
117   
118         if (stat(fname,&st) != 0) 
119                 return(0);
120
121         return(st.st_mtime);
122 }
123
124 /**
125  Check file permissions.
126 **/
127
128 _PUBLIC_ bool file_check_permissions(const char *fname,
129                                      uid_t uid,
130                                      mode_t file_perms,
131                                      struct stat *pst)
132 {
133         int ret;
134         struct stat st;
135
136         if (pst == NULL) {
137                 pst = &st;
138         }
139
140         ZERO_STRUCTP(pst);
141
142         ret = stat(fname, pst);
143         if (ret != 0) {
144                 DEBUG(0, ("stat failed on file '%s': %s\n",
145                          fname, strerror(errno)));
146                 return false;
147         }
148
149         if (pst->st_uid != uid && !uid_wrapper_enabled()) {
150                 DEBUG(0, ("invalid ownership of file '%s': "
151                          "owned by uid %u, should be %u\n",
152                          fname, (unsigned int)pst->st_uid,
153                          (unsigned int)uid));
154                 return false;
155         }
156
157         if ((pst->st_mode & 0777) != file_perms) {
158                 DEBUG(0, ("invalid permissions on file "
159                          "'%s': has 0%o should be 0%o\n", fname,
160                          (unsigned int)(pst->st_mode & 0777),
161                          (unsigned int)file_perms));
162                 return false;
163         }
164
165         return true;
166 }
167
168 /**
169  Check if a directory exists.
170 **/
171
172 _PUBLIC_ bool directory_exist(const char *dname)
173 {
174         struct stat st;
175         bool ret;
176
177         if (stat(dname,&st) != 0) {
178                 return false;
179         }
180
181         ret = S_ISDIR(st.st_mode);
182         if(!ret)
183                 errno = ENOTDIR;
184         return ret;
185 }
186
187 /**
188  * Try to create the specified directory if it didn't exist.
189  *
190  * @retval true if the directory already existed and has the right permissions 
191  * or was successfully created.
192  */
193 _PUBLIC_ bool directory_create_or_exist(const char *dname,
194                                         uid_t uid,
195                                         mode_t dir_perms)
196 {
197         int ret;
198         struct stat st;
199         mode_t old_umask;
200
201         ret = lstat(dname, &st);
202         if (ret == 0) {
203                 return true;
204         }
205
206         if (errno != ENOENT) {
207                 DEBUG(0, ("lstat failed on directory %s: %s\n",
208                           dname, strerror(errno)));
209                 return false;
210         }
211
212         /* Create directory */
213         old_umask = umask(0);
214         ret = mkdir(dname, dir_perms);
215         if (ret == -1 && errno != EEXIST) {
216                 DEBUG(0, ("mkdir failed on directory "
217                           "%s: %s\n", dname,
218                           strerror(errno)));
219                 umask(old_umask);
220                 return false;
221         }
222         umask(old_umask);
223
224         ret = lstat(dname, &st);
225         if (ret == -1) {
226                 DEBUG(0, ("lstat failed on created directory %s: %s\n",
227                           dname, strerror(errno)));
228                 return false;
229         }
230
231         return true;
232 }
233
234 /**
235  * @brief Try to create a specified directory if it doesn't exist.
236  *
237  * The function creates a directory with the given uid and permissions if it
238  * doesn't exist. If it exists it makes sure the uid and permissions are
239  * correct and it will fail if they are different.
240  *
241  * @param[in]  dname  The directory to create.
242  *
243  * @param[in]  uid    The uid the directory needs to belong too.
244  *
245  * @param[in]  dir_perms  The expected permissions of the directory.
246  *
247  * @return True on success, false on error.
248  */
249 _PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
250                                                uid_t uid,
251                                                mode_t dir_perms)
252 {
253         struct stat st;
254         bool ok;
255         int rc;
256
257         ok = directory_create_or_exist(dname, uid, dir_perms);
258         if (!ok) {
259                 return false;
260         }
261
262         rc = lstat(dname, &st);
263         if (rc == -1) {
264                 DEBUG(0, ("lstat failed on created directory %s: %s\n",
265                           dname, strerror(errno)));
266                 return false;
267         }
268
269         /* Check ownership and permission on existing directory */
270         if (!S_ISDIR(st.st_mode)) {
271                 DEBUG(0, ("directory %s isn't a directory\n",
272                         dname));
273                 return false;
274         }
275         if (st.st_uid != uid && !uid_wrapper_enabled()) {
276                 DEBUG(0, ("invalid ownership on directory "
277                           "%s\n", dname));
278                 return false;
279         }
280         if ((st.st_mode & 0777) != dir_perms) {
281                 DEBUG(0, ("invalid permissions on directory "
282                           "'%s': has 0%o should be 0%o\n", dname,
283                           (unsigned int)(st.st_mode & 0777), (unsigned int)dir_perms));
284                 return false;
285         }
286
287         return true;
288 }
289
290
291 /**
292  Sleep for a specified number of milliseconds.
293 **/
294
295 _PUBLIC_ void smb_msleep(unsigned int t)
296 {
297 #if defined(HAVE_NANOSLEEP)
298         struct timespec ts;
299         int ret;
300
301         ts.tv_sec = t/1000;
302         ts.tv_nsec = 1000000*(t%1000);
303
304         do {
305                 errno = 0;
306                 ret = nanosleep(&ts, &ts);
307         } while (ret < 0 && errno == EINTR && (ts.tv_sec > 0 || ts.tv_nsec > 0));
308 #else
309         unsigned int tdiff=0;
310         struct timeval tval,t1,t2;
311         fd_set fds;
312
313         GetTimeOfDay(&t1);
314         t2 = t1;
315
316         while (tdiff < t) {
317                 tval.tv_sec = (t-tdiff)/1000;
318                 tval.tv_usec = 1000*((t-tdiff)%1000);
319
320                 /* Never wait for more than 1 sec. */
321                 if (tval.tv_sec > 1) {
322                         tval.tv_sec = 1;
323                         tval.tv_usec = 0;
324                 }
325
326                 FD_ZERO(&fds);
327                 errno = 0;
328                 select(0,&fds,NULL,NULL,&tval);
329
330                 GetTimeOfDay(&t2);
331                 if (t2.tv_sec < t1.tv_sec) {
332                         /* Someone adjusted time... */
333                         t1 = t2;
334                 }
335
336                 tdiff = usec_time_diff(&t2,&t1)/1000;
337         }
338 #endif
339 }
340
341 /**
342  Get my own name, return in talloc'ed storage.
343 **/
344
345 _PUBLIC_ char *get_myname(TALLOC_CTX *ctx)
346 {
347         char *p;
348         char hostname[HOST_NAME_MAX];
349
350         /* get my host name */
351         if (gethostname(hostname, sizeof(hostname)) == -1) {
352                 DEBUG(0,("gethostname failed\n"));
353                 return NULL;
354         }
355
356         /* Ensure null termination. */
357         hostname[sizeof(hostname)-1] = '\0';
358
359         /* split off any parts after an initial . */
360         p = strchr_m(hostname, '.');
361         if (p) {
362                 *p = 0;
363         }
364
365         return talloc_strdup(ctx, hostname);
366 }
367
368 /**
369  Check if a process exists. Does this work on all unixes?
370 **/
371
372 _PUBLIC_ bool process_exists_by_pid(pid_t pid)
373 {
374         /* Doing kill with a non-positive pid causes messages to be
375          * sent to places we don't want. */
376         if (pid <= 0) {
377                 return false;
378         }
379         return(kill(pid,0) == 0 || errno != ESRCH);
380 }
381
382 /**
383  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
384  is dealt with in posix.c
385 **/
386
387 _PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type)
388 {
389         struct flock lock;
390         int ret;
391
392         DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
393
394         lock.l_type = type;
395         lock.l_whence = SEEK_SET;
396         lock.l_start = offset;
397         lock.l_len = count;
398         lock.l_pid = 0;
399
400         ret = fcntl(fd,op,&lock);
401
402         if (ret == -1 && errno != 0)
403                 DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
404
405         /* a lock query */
406         if (op == F_GETLK) {
407                 if ((ret != -1) &&
408                                 (lock.l_type != F_UNLCK) && 
409                                 (lock.l_pid != 0) && 
410                                 (lock.l_pid != getpid())) {
411                         DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
412                         return true;
413                 }
414
415                 /* it must be not locked or locked by me */
416                 return false;
417         }
418
419         /* a lock set or unset */
420         if (ret == -1) {
421                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
422                         (double)offset,(double)count,op,type,strerror(errno)));
423                 return false;
424         }
425
426         /* everything went OK */
427         DEBUG(8,("fcntl_lock: Lock call successful\n"));
428
429         return true;
430 }
431
432 struct debug_channel_level {
433         int channel;
434         int level;
435 };
436
437 static void debugadd_channel_cb(const char *buf, void *private_data)
438 {
439         struct debug_channel_level *dcl =
440                 (struct debug_channel_level *)private_data;
441
442         DEBUGADDC(dcl->channel, dcl->level,("%s", buf));
443 }
444
445 static void debugadd_cb(const char *buf, void *private_data)
446 {
447         int *plevel = (int *)private_data;
448         DEBUGADD(*plevel, ("%s", buf));
449 }
450
451 void print_asc_cb(const uint8_t *buf, int len,
452                   void (*cb)(const char *buf, void *private_data),
453                   void *private_data)
454 {
455         int i;
456         char s[2];
457         s[1] = 0;
458
459         for (i=0; i<len; i++) {
460                 s[0] = isprint(buf[i]) ? buf[i] : '.';
461                 cb(s, private_data);
462         }
463 }
464
465 void print_asc(int level, const uint8_t *buf,int len)
466 {
467         print_asc_cb(buf, len, debugadd_cb, &level);
468 }
469
470 /**
471  * Write dump of binary data to a callback
472  */
473 void dump_data_cb(const uint8_t *buf, int len,
474                   bool omit_zero_bytes,
475                   void (*cb)(const char *buf, void *private_data),
476                   void *private_data)
477 {
478         int i=0;
479         static const uint8_t empty[16] = { 0, };
480         bool skipped = false;
481         char tmp[16];
482
483         if (len<=0) return;
484
485         for (i=0;i<len;) {
486
487                 if (i%16 == 0) {
488                         if ((omit_zero_bytes == true) &&
489                             (i > 0) &&
490                             (len > i+16) &&
491                             (memcmp(&buf[i], &empty, 16) == 0))
492                         {
493                                 i +=16;
494                                 continue;
495                         }
496
497                         if (i<len)  {
498                                 snprintf(tmp, sizeof(tmp), "[%04X] ", i);
499                                 cb(tmp, private_data);
500                         }
501                 }
502
503                 snprintf(tmp, sizeof(tmp), "%02X ", (int)buf[i]);
504                 cb(tmp, private_data);
505                 i++;
506                 if (i%8 == 0) {
507                         cb("  ", private_data);
508                 }
509                 if (i%16 == 0) {
510
511                         print_asc_cb(&buf[i-16], 8, cb, private_data);
512                         cb(" ", private_data);
513                         print_asc_cb(&buf[i-8], 8, cb, private_data);
514                         cb("\n", private_data);
515
516                         if ((omit_zero_bytes == true) &&
517                             (len > i+16) &&
518                             (memcmp(&buf[i], &empty, 16) == 0)) {
519                                 if (!skipped) {
520                                         cb("skipping zero buffer bytes\n",
521                                            private_data);
522                                         skipped = true;
523                                 }
524                         }
525                 }
526         }
527
528         if (i%16) {
529                 int n;
530                 n = 16 - (i%16);
531                 cb(" ", private_data);
532                 if (n>8) {
533                         cb(" ", private_data);
534                 }
535                 while (n--) {
536                         cb("   ", private_data);
537                 }
538                 n = MIN(8,i%16);
539                 print_asc_cb(&buf[i-(i%16)], n, cb, private_data);
540                 cb(" ", private_data);
541                 n = (i%16) - n;
542                 if (n>0) {
543                         print_asc_cb(&buf[i-n], n, cb, private_data);
544                 }
545                 cb("\n", private_data);
546         }
547
548 }
549
550 /**
551  * Write dump of binary data to the log file.
552  *
553  * The data is only written if the log level is at least level.
554  */
555 _PUBLIC_ void dump_data(int level, const uint8_t *buf, int len)
556 {
557         if (!DEBUGLVL(level)) {
558                 return;
559         }
560         dump_data_cb(buf, len, false, debugadd_cb, &level);
561 }
562
563 /**
564  * Write dump of binary data to the log file.
565  *
566  * The data is only written if the log level is at least level for
567  * debug class dbgc_class.
568  */
569 _PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len)
570 {
571         struct debug_channel_level dcl = { dbgc_class, level };
572
573         if (!DEBUGLVLC(dbgc_class, level)) {
574                 return;
575         }
576         dump_data_cb(buf, len, false, debugadd_channel_cb, &dcl);
577 }
578
579 /**
580  * Write dump of binary data to the log file.
581  *
582  * The data is only written if the log level is at least level.
583  * 16 zero bytes in a row are omitted
584  */
585 _PUBLIC_ void dump_data_skip_zeros(int level, const uint8_t *buf, int len)
586 {
587         if (!DEBUGLVL(level)) {
588                 return;
589         }
590         dump_data_cb(buf, len, true, debugadd_cb, &level);
591 }
592
593 static void fprintf_cb(const char *buf, void *private_data)
594 {
595         FILE *f = (FILE *)private_data;
596         fprintf(f, "%s", buf);
597 }
598
599 void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
600                     FILE *f)
601 {
602         dump_data_cb(buf, len, omit_zero_bytes, fprintf_cb, f);
603 }
604
605 /**
606  malloc that aborts with smb_panic on fail or zero size.
607 **/
608
609 _PUBLIC_ void *smb_xmalloc(size_t size)
610 {
611         void *p;
612         if (size == 0)
613                 smb_panic("smb_xmalloc: called with zero size.\n");
614         if ((p = malloc(size)) == NULL)
615                 smb_panic("smb_xmalloc: malloc fail.\n");
616         return p;
617 }
618
619 /**
620  Memdup with smb_panic on fail.
621 **/
622
623 _PUBLIC_ void *smb_xmemdup(const void *p, size_t size)
624 {
625         void *p2;
626         p2 = smb_xmalloc(size);
627         memcpy(p2, p, size);
628         return p2;
629 }
630
631 /**
632  strdup that aborts on malloc fail.
633 **/
634
635 char *smb_xstrdup(const char *s)
636 {
637 #if defined(PARANOID_MALLOC_CHECKER)
638 #ifdef strdup
639 #undef strdup
640 #endif
641 #endif
642
643 #ifndef HAVE_STRDUP
644 #define strdup rep_strdup
645 #endif
646
647         char *s1 = strdup(s);
648 #if defined(PARANOID_MALLOC_CHECKER)
649 #ifdef strdup
650 #undef strdup
651 #endif
652 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
653 #endif
654         if (!s1) {
655                 smb_panic("smb_xstrdup: malloc failed");
656         }
657         return s1;
658
659 }
660
661 /**
662  strndup that aborts on malloc fail.
663 **/
664
665 char *smb_xstrndup(const char *s, size_t n)
666 {
667 #if defined(PARANOID_MALLOC_CHECKER)
668 #ifdef strndup
669 #undef strndup
670 #endif
671 #endif
672
673 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
674 #undef HAVE_STRNDUP
675 #define strndup rep_strndup
676 #endif
677
678         char *s1 = strndup(s, n);
679 #if defined(PARANOID_MALLOC_CHECKER)
680 #ifdef strndup
681 #undef strndup
682 #endif
683 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
684 #endif
685         if (!s1) {
686                 smb_panic("smb_xstrndup: malloc failed");
687         }
688         return s1;
689 }
690
691
692
693 /**
694  Like strdup but for memory.
695 **/
696
697 _PUBLIC_ void *smb_memdup(const void *p, size_t size)
698 {
699         void *p2;
700         if (size == 0)
701                 return NULL;
702         p2 = malloc(size);
703         if (!p2)
704                 return NULL;
705         memcpy(p2, p, size);
706         return p2;
707 }
708
709 /**
710  * Write a password to the log file.
711  *
712  * @note Only actually does something if DEBUG_PASSWORD was defined during 
713  * compile-time.
714  */
715 _PUBLIC_ void dump_data_pw(const char *msg, const uint8_t * data, size_t len)
716 {
717 #ifdef DEBUG_PASSWORD
718         DEBUG(11, ("%s", msg));
719         if (data != NULL && len > 0)
720         {
721                 dump_data(11, data, len);
722         }
723 #endif
724 }
725
726
727 /**
728  * see if a range of memory is all zero. A NULL pointer is considered
729  * to be all zero 
730  */
731 _PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size)
732 {
733         int i;
734         if (!ptr) return true;
735         for (i=0;i<size;i++) {
736                 if (ptr[i]) return false;
737         }
738         return true;
739 }
740
741 /**
742   realloc an array, checking for integer overflow in the array size
743 */
744 _PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail)
745 {
746 #define MAX_MALLOC_SIZE 0x7fffffff
747         if (count == 0 ||
748             count >= MAX_MALLOC_SIZE/el_size) {
749                 if (free_on_fail)
750                         SAFE_FREE(ptr);
751                 return NULL;
752         }
753         if (!ptr) {
754                 return malloc(el_size * count);
755         }
756         return realloc(ptr, el_size * count);
757 }
758
759 /****************************************************************************
760  Type-safe malloc.
761 ****************************************************************************/
762
763 void *malloc_array(size_t el_size, unsigned int count)
764 {
765         return realloc_array(NULL, el_size, count, false);
766 }
767
768 /****************************************************************************
769  Type-safe memalign
770 ****************************************************************************/
771
772 void *memalign_array(size_t el_size, size_t align, unsigned int count)
773 {
774         if (count*el_size >= MAX_MALLOC_SIZE) {
775                 return NULL;
776         }
777
778         return memalign(align, el_size*count);
779 }
780
781 /****************************************************************************
782  Type-safe calloc.
783 ****************************************************************************/
784
785 void *calloc_array(size_t size, size_t nmemb)
786 {
787         if (nmemb >= MAX_MALLOC_SIZE/size) {
788                 return NULL;
789         }
790         if (size == 0 || nmemb == 0) {
791                 return NULL;
792         }
793         return calloc(nmemb, size);
794 }
795
796 /**
797  Trim the specified elements off the front and back of a string.
798 **/
799 _PUBLIC_ bool trim_string(char *s, const char *front, const char *back)
800 {
801         bool ret = false;
802         size_t front_len;
803         size_t back_len;
804         size_t len;
805
806         /* Ignore null or empty strings. */
807         if (!s || (s[0] == '\0'))
808                 return false;
809
810         front_len       = front? strlen(front) : 0;
811         back_len        = back? strlen(back) : 0;
812
813         len = strlen(s);
814
815         if (front_len) {
816                 while (len && strncmp(s, front, front_len)==0) {
817                         /* Must use memmove here as src & dest can
818                          * easily overlap. Found by valgrind. JRA. */
819                         memmove(s, s+front_len, (len-front_len)+1);
820                         len -= front_len;
821                         ret=true;
822                 }
823         }
824         
825         if (back_len) {
826                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
827                         s[len-back_len]='\0';
828                         len -= back_len;
829                         ret=true;
830                 }
831         }
832         return ret;
833 }
834
835 /**
836  Find the number of 'c' chars in a string
837 **/
838 _PUBLIC_ _PURE_ size_t count_chars(const char *s, char c)
839 {
840         size_t count = 0;
841
842         while (*s) {
843                 if (*s == c) count++;
844                 s ++;
845         }
846
847         return count;
848 }
849
850 /**
851  * Routine to get hex characters and turn them into a byte array.
852  * the array can be variable length.
853  * -  "0xnn" or "0Xnn" is specially catered for.
854  * - The first non-hex-digit character (apart from possibly leading "0x"
855  *   finishes the conversion and skips the rest of the input.
856  * - A single hex-digit character at the end of the string is skipped.
857  *
858  * valid examples: "0A5D15"; "0x123456"
859  */
860 _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len)
861 {
862         size_t i = 0;
863         size_t num_chars = 0;
864         uint8_t   lonybble, hinybble;
865         const char     *hexchars = "0123456789ABCDEF";
866         char           *p1 = NULL, *p2 = NULL;
867
868         /* skip leading 0x prefix */
869         if (strncasecmp(strhex, "0x", 2) == 0) {
870                 i += 2; /* skip two chars */
871         }
872
873         for (; i+1 < strhex_len && strhex[i] != 0 && strhex[i+1] != 0; i++) {
874                 p1 = strchr(hexchars, toupper((unsigned char)strhex[i]));
875                 if (p1 == NULL) {
876                         break;
877                 }
878
879                 i++; /* next hex digit */
880
881                 p2 = strchr(hexchars, toupper((unsigned char)strhex[i]));
882                 if (p2 == NULL) {
883                         break;
884                 }
885
886                 /* get the two nybbles */
887                 hinybble = PTR_DIFF(p1, hexchars);
888                 lonybble = PTR_DIFF(p2, hexchars);
889
890                 if (num_chars >= p_len) {
891                         break;
892                 }
893
894                 p[num_chars] = (hinybble << 4) | lonybble;
895                 num_chars++;
896
897                 p1 = NULL;
898                 p2 = NULL;
899         }
900         return num_chars;
901 }
902
903 /** 
904  * Parse a hex string and return a data blob. 
905  */
906 _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
907 {
908         DATA_BLOB ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
909
910         ret_blob.length = strhex_to_str((char *)ret_blob.data, ret_blob.length,
911                                         strhex,
912                                         strlen(strhex));
913
914         return ret_blob;
915 }
916
917 /**
918  * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
919  */
920 _PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen)
921 {
922         size_t i;
923         for (i=0; i<srclen; i++) {
924                 snprintf(dst + i*2, 3, "%02X", src[i]);
925         }
926         /*
927          * Ensure 0-termination for 0-length buffers
928          */
929         dst[srclen*2] = '\0';
930 }
931
932 /**
933  * Routine to print a buffer as HEX digits, into an allocated string.
934  */
935 _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
936 {
937         char *hex_buffer;
938
939         *out_hex_buffer = malloc_array_p(char, (len*2)+1);
940         hex_buffer = *out_hex_buffer;
941         hex_encode_buf(hex_buffer, buff_in, len);
942 }
943
944 /**
945  * talloc version of hex_encode()
946  */
947 _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
948 {
949         char *hex_buffer;
950
951         hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
952         if (!hex_buffer) {
953                 return NULL;
954         }
955         hex_encode_buf(hex_buffer, buff_in, len);
956         talloc_set_name_const(hex_buffer, hex_buffer);
957         return hex_buffer;
958 }
959
960 /**
961   varient of strcmp() that handles NULL ptrs
962 **/
963 _PUBLIC_ int strcmp_safe(const char *s1, const char *s2)
964 {
965         if (s1 == s2) {
966                 return 0;
967         }
968         if (s1 == NULL || s2 == NULL) {
969                 return s1?-1:1;
970         }
971         return strcmp(s1, s2);
972 }
973
974
975 /**
976 return the number of bytes occupied by a buffer in ASCII format
977 the result includes the null termination
978 limited by 'n' bytes
979 **/
980 _PUBLIC_ size_t ascii_len_n(const char *src, size_t n)
981 {
982         size_t len;
983
984         len = strnlen(src, n);
985         if (len+1 <= n) {
986                 len += 1;
987         }
988
989         return len;
990 }
991
992 /**
993  Set a boolean variable from the text value stored in the passed string.
994  Returns true in success, false if the passed string does not correctly 
995  represent a boolean.
996 **/
997
998 _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
999 {
1000         if (strwicmp(boolean_string, "yes") == 0 ||
1001             strwicmp(boolean_string, "true") == 0 ||
1002             strwicmp(boolean_string, "on") == 0 ||
1003             strwicmp(boolean_string, "1") == 0) {
1004                 *boolean = true;
1005                 return true;
1006         } else if (strwicmp(boolean_string, "no") == 0 ||
1007                    strwicmp(boolean_string, "false") == 0 ||
1008                    strwicmp(boolean_string, "off") == 0 ||
1009                    strwicmp(boolean_string, "0") == 0) {
1010                 *boolean = false;
1011                 return true;
1012         }
1013         return false;
1014 }
1015
1016 /**
1017 return the number of bytes occupied by a buffer in CH_UTF16 format
1018 the result includes the null termination
1019 **/
1020 _PUBLIC_ size_t utf16_len(const void *buf)
1021 {
1022         size_t len;
1023
1024         for (len = 0; SVAL(buf,len); len += 2) ;
1025
1026         return len + 2;
1027 }
1028
1029 /**
1030 return the number of bytes occupied by a buffer in CH_UTF16 format
1031 the result includes the null termination
1032 limited by 'n' bytes
1033 **/
1034 _PUBLIC_ size_t utf16_len_n(const void *src, size_t n)
1035 {
1036         size_t len;
1037
1038         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
1039
1040         if (len+2 <= n) {
1041                 len += 2;
1042         }
1043
1044         return len;
1045 }
1046
1047 /**
1048  * @file
1049  * @brief String utilities.
1050  **/
1051
1052 static bool next_token_internal_talloc(TALLOC_CTX *ctx,
1053                                 const char **ptr,
1054                                 char **pp_buff,
1055                                 const char *sep,
1056                                 bool ltrim)
1057 {
1058         const char *s;
1059         const char *saved_s;
1060         char *pbuf;
1061         bool quoted;
1062         size_t len=1;
1063
1064         *pp_buff = NULL;
1065         if (!ptr) {
1066                 return(false);
1067         }
1068
1069         s = *ptr;
1070
1071         /* default to simple separators */
1072         if (!sep) {
1073                 sep = " \t\n\r";
1074         }
1075
1076         /* find the first non sep char, if left-trimming is requested */
1077         if (ltrim) {
1078                 while (*s && strchr_m(sep,*s)) {
1079                         s++;
1080                 }
1081         }
1082
1083         /* nothing left? */
1084         if (!*s) {
1085                 return false;
1086         }
1087
1088         /* When restarting we need to go from here. */
1089         saved_s = s;
1090
1091         /* Work out the length needed. */
1092         for (quoted = false; *s &&
1093                         (quoted || !strchr_m(sep,*s)); s++) {
1094                 if (*s == '\"') {
1095                         quoted = !quoted;
1096                 } else {
1097                         len++;
1098                 }
1099         }
1100
1101         /* We started with len = 1 so we have space for the nul. */
1102         *pp_buff = talloc_array(ctx, char, len);
1103         if (!*pp_buff) {
1104                 return false;
1105         }
1106
1107         /* copy over the token */
1108         pbuf = *pp_buff;
1109         s = saved_s;
1110         for (quoted = false; *s &&
1111                         (quoted || !strchr_m(sep,*s)); s++) {
1112                 if ( *s == '\"' ) {
1113                         quoted = !quoted;
1114                 } else {
1115                         *pbuf++ = *s;
1116                 }
1117         }
1118
1119         *ptr = (*s) ? s+1 : s;
1120         *pbuf = 0;
1121
1122         return true;
1123 }
1124
1125 bool next_token_talloc(TALLOC_CTX *ctx,
1126                         const char **ptr,
1127                         char **pp_buff,
1128                         const char *sep)
1129 {
1130         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
1131 }
1132
1133 /*
1134  * Get the next token from a string, return false if none found.  Handles
1135  * double-quotes.  This version does not trim leading separator characters
1136  * before looking for a token.
1137  */
1138
1139 bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
1140                         const char **ptr,
1141                         char **pp_buff,
1142                         const char *sep)
1143 {
1144         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
1145 }
1146
1147 /**
1148  * Get the next token from a string, return False if none found.
1149  * Handles double-quotes.
1150  *
1151  * Based on a routine by GJC@VILLAGE.COM.
1152  * Extensively modified by Andrew.Tridgell@anu.edu.au
1153  **/
1154 _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
1155 {
1156         const char *s;
1157         bool quoted;
1158         size_t len=1;
1159
1160         if (!ptr)
1161                 return false;
1162
1163         s = *ptr;
1164
1165         /* default to simple separators */
1166         if (!sep)
1167                 sep = " \t\n\r";
1168
1169         /* find the first non sep char */
1170         while (*s && strchr_m(sep,*s))
1171                 s++;
1172
1173         /* nothing left? */
1174         if (!*s)
1175                 return false;
1176
1177         /* copy over the token */
1178         for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
1179                 if (*s == '\"') {
1180                         quoted = !quoted;
1181                 } else {
1182                         len++;
1183                         *buff++ = *s;
1184                 }
1185         }
1186
1187         *ptr = (*s) ? s+1 : s;
1188         *buff = 0;
1189
1190         return true;
1191 }
1192
1193 struct anonymous_shared_header {
1194         union {
1195                 size_t length;
1196                 uint8_t pad[16];
1197         } u;
1198 };
1199
1200 /* Map a shared memory buffer of at least nelem counters. */
1201 void *anonymous_shared_allocate(size_t orig_bufsz)
1202 {
1203         void *ptr;
1204         void *buf;
1205         size_t pagesz = getpagesize();
1206         size_t pagecnt;
1207         size_t bufsz = orig_bufsz;
1208         struct anonymous_shared_header *hdr;
1209
1210         bufsz += sizeof(*hdr);
1211
1212         /* round up to full pages */
1213         pagecnt = bufsz / pagesz;
1214         if (bufsz % pagesz) {
1215                 pagecnt += 1;
1216         }
1217         bufsz = pagesz * pagecnt;
1218
1219         if (orig_bufsz >= bufsz) {
1220                 /* integer wrap */
1221                 errno = ENOMEM;
1222                 return NULL;
1223         }
1224
1225 #ifdef MAP_ANON
1226         /* BSD */
1227         buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
1228                         -1 /* fd */, 0 /* offset */);
1229 #else
1230 {
1231         int saved_errno;
1232         int fd;
1233
1234         fd = open("/dev/zero", O_RDWR);
1235         if (fd == -1) {
1236                 return NULL;
1237         }
1238
1239         buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
1240                    fd, 0 /* offset */);
1241         saved_errno = errno;
1242         close(fd);
1243         errno = saved_errno;
1244 }
1245 #endif
1246
1247         if (buf == MAP_FAILED) {
1248                 return NULL;
1249         }
1250
1251         hdr = (struct anonymous_shared_header *)buf;
1252         hdr->u.length = bufsz;
1253
1254         ptr = (void *)(&hdr[1]);
1255
1256         return ptr;
1257 }
1258
1259 void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
1260 {
1261 #ifdef HAVE_MREMAP
1262         void *buf;
1263         size_t pagesz = getpagesize();
1264         size_t pagecnt;
1265         size_t bufsz;
1266         struct anonymous_shared_header *hdr;
1267         int flags = 0;
1268
1269         if (ptr == NULL) {
1270                 errno = EINVAL;
1271                 return NULL;
1272         }
1273
1274         hdr = (struct anonymous_shared_header *)ptr;
1275         hdr--;
1276         if (hdr->u.length > (new_size + sizeof(*hdr))) {
1277                 errno = EINVAL;
1278                 return NULL;
1279         }
1280
1281         bufsz = new_size + sizeof(*hdr);
1282
1283         /* round up to full pages */
1284         pagecnt = bufsz / pagesz;
1285         if (bufsz % pagesz) {
1286                 pagecnt += 1;
1287         }
1288         bufsz = pagesz * pagecnt;
1289
1290         if (new_size >= bufsz) {
1291                 /* integer wrap */
1292                 errno = ENOSPC;
1293                 return NULL;
1294         }
1295
1296         if (bufsz <= hdr->u.length) {
1297                 return ptr;
1298         }
1299
1300         if (maymove) {
1301                 flags = MREMAP_MAYMOVE;
1302         }
1303
1304         buf = mremap(hdr, hdr->u.length, bufsz, flags);
1305
1306         if (buf == MAP_FAILED) {
1307                 errno = ENOSPC;
1308                 return NULL;
1309         }
1310
1311         hdr = (struct anonymous_shared_header *)buf;
1312         hdr->u.length = bufsz;
1313
1314         ptr = (void *)(&hdr[1]);
1315
1316         return ptr;
1317 #else
1318         errno = ENOSPC;
1319         return NULL;
1320 #endif
1321 }
1322
1323 void anonymous_shared_free(void *ptr)
1324 {
1325         struct anonymous_shared_header *hdr;
1326
1327         if (ptr == NULL) {
1328                 return;
1329         }
1330
1331         hdr = (struct anonymous_shared_header *)ptr;
1332
1333         hdr--;
1334
1335         munmap(hdr, hdr->u.length);
1336 }
1337
1338 #ifdef DEVELOPER
1339 /* used when you want a debugger started at a particular point in the
1340    code. Mostly useful in code that runs as a child process, where
1341    normal gdb attach is harder to organise.
1342 */
1343 void samba_start_debugger(void)
1344 {
1345         char *cmd = NULL;
1346         if (asprintf(&cmd, "xterm -e \"gdb --pid %u\"&", getpid()) == -1) {
1347                 return;
1348         }
1349         if (system(cmd) == -1) {
1350                 free(cmd);
1351                 return;
1352         }
1353         free(cmd);
1354         sleep(2);
1355 }
1356 #endif