lib/util/attr: add _UNUSED_ marco
[ira/wip.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
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 3 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, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "system/network.h"
26 #include "system/filesys.h"
27 #include "system/locale.h"
28 #include "system/shmem.h"
29
30 #undef malloc
31 #undef strcasecmp
32 #undef strncasecmp
33 #undef strdup
34 #undef realloc
35
36 #if defined(UID_WRAPPER)
37 #if !defined(UID_WRAPPER_REPLACE) && !defined(UID_WRAPPER_NOT_REPLACE)
38 #define UID_WRAPPER_REPLACE
39 #include "../uid_wrapper/uid_wrapper.h"
40 #endif
41 #else
42 #define uwrap_enabled() 0
43 #endif
44
45 /**
46  * @file
47  * @brief Misc utility functions
48  */
49
50 /**
51  Find a suitable temporary directory. The result should be copied immediately
52  as it may be overwritten by a subsequent call.
53 **/
54 _PUBLIC_ const char *tmpdir(void)
55 {
56         char *p;
57         if ((p = getenv("TMPDIR")))
58                 return p;
59         return "/tmp";
60 }
61
62
63 /**
64  Check if a file exists - call vfs_file_exist for samba files.
65 **/
66 _PUBLIC_ bool file_exist(const char *fname)
67 {
68         struct stat st;
69
70         if (stat(fname, &st) != 0) {
71                 return false;
72         }
73
74         return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode)));
75 }
76
77 /**
78  Check a files mod time.
79 **/
80
81 _PUBLIC_ time_t file_modtime(const char *fname)
82 {
83         struct stat st;
84   
85         if (stat(fname,&st) != 0) 
86                 return(0);
87
88         return(st.st_mtime);
89 }
90
91 /**
92  Check if a directory exists.
93 **/
94
95 _PUBLIC_ bool directory_exist(const char *dname)
96 {
97         struct stat st;
98         bool ret;
99
100         if (stat(dname,&st) != 0) {
101                 return false;
102         }
103
104         ret = S_ISDIR(st.st_mode);
105         if(!ret)
106                 errno = ENOTDIR;
107         return ret;
108 }
109
110 /**
111  * Try to create the specified directory if it didn't exist.
112  *
113  * @retval true if the directory already existed and has the right permissions 
114  * or was successfully created.
115  */
116 _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid, 
117                                mode_t dir_perms)
118 {
119         mode_t old_umask;
120         struct stat st;
121       
122         old_umask = umask(0);
123         if (lstat(dname, &st) == -1) {
124                 if (errno == ENOENT) {
125                         /* Create directory */
126                         if (mkdir(dname, dir_perms) == -1) {
127                                 DEBUG(0, ("error creating directory "
128                                           "%s: %s\n", dname, 
129                                           strerror(errno)));
130                                 umask(old_umask);
131                                 return false;
132                         }
133                 } else {
134                         DEBUG(0, ("lstat failed on directory %s: %s\n",
135                                   dname, strerror(errno)));
136                         umask(old_umask);
137                         return false;
138                 }
139         } else {
140                 /* Check ownership and permission on existing directory */
141                 if (!S_ISDIR(st.st_mode)) {
142                         DEBUG(0, ("directory %s isn't a directory\n",
143                                 dname));
144                         umask(old_umask);
145                         return false;
146                 }
147                 if (st.st_uid != uid && !uwrap_enabled()) {
148                         DEBUG(0, ("invalid ownership on directory "
149                                   "%s\n", dname));
150                         umask(old_umask);
151                         return false;
152                 }
153                 if ((st.st_mode & 0777) != dir_perms) {
154                         DEBUG(0, ("invalid permissions on directory "
155                                   "'%s': has 0%o should be 0%o\n", dname,
156                                   (st.st_mode & 0777), dir_perms));
157                         umask(old_umask);
158                         return false;
159                 }
160         }
161         return true;
162 }       
163
164
165 /**
166  Sleep for a specified number of milliseconds.
167 **/
168
169 _PUBLIC_ void smb_msleep(unsigned int t)
170 {
171 #if defined(HAVE_NANOSLEEP)
172         struct timespec ts;
173         int ret;
174
175         ts.tv_sec = t/1000;
176         ts.tv_nsec = 1000000*(t%1000);
177
178         do {
179                 errno = 0;
180                 ret = nanosleep(&ts, &ts);
181         } while (ret < 0 && errno == EINTR && (ts.tv_sec > 0 || ts.tv_nsec > 0));
182 #else
183         unsigned int tdiff=0;
184         struct timeval tval,t1,t2;
185         fd_set fds;
186
187         GetTimeOfDay(&t1);
188         t2 = t1;
189
190         while (tdiff < t) {
191                 tval.tv_sec = (t-tdiff)/1000;
192                 tval.tv_usec = 1000*((t-tdiff)%1000);
193
194                 /* Never wait for more than 1 sec. */
195                 if (tval.tv_sec > 1) {
196                         tval.tv_sec = 1;
197                         tval.tv_usec = 0;
198                 }
199
200                 FD_ZERO(&fds);
201                 errno = 0;
202                 select(0,&fds,NULL,NULL,&tval);
203
204                 GetTimeOfDay(&t2);
205                 if (t2.tv_sec < t1.tv_sec) {
206                         /* Someone adjusted time... */
207                         t1 = t2;
208                 }
209
210                 tdiff = usec_time_diff(&t2,&t1)/1000;
211         }
212 #endif
213 }
214
215 /**
216  Get my own name, return in talloc'ed storage.
217 **/
218
219 _PUBLIC_ char *get_myname(TALLOC_CTX *ctx)
220 {
221         char *p;
222         char hostname[HOST_NAME_MAX];
223
224         /* get my host name */
225         if (gethostname(hostname, sizeof(hostname)) == -1) {
226                 DEBUG(0,("gethostname failed\n"));
227                 return NULL;
228         }
229
230         /* Ensure null termination. */
231         hostname[sizeof(hostname)-1] = '\0';
232
233         /* split off any parts after an initial . */
234         p = strchr_m(hostname, '.');
235         if (p) {
236                 *p = 0;
237         }
238
239         return talloc_strdup(ctx, hostname);
240 }
241
242 /**
243  Check if a process exists. Does this work on all unixes?
244 **/
245
246 _PUBLIC_ bool process_exists_by_pid(pid_t pid)
247 {
248         /* Doing kill with a non-positive pid causes messages to be
249          * sent to places we don't want. */
250         SMB_ASSERT(pid > 0);
251         return(kill(pid,0) == 0 || errno != ESRCH);
252 }
253
254 /**
255  Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
256  is dealt with in posix.c
257 **/
258
259 _PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type)
260 {
261         struct flock lock;
262         int ret;
263
264         DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
265
266         lock.l_type = type;
267         lock.l_whence = SEEK_SET;
268         lock.l_start = offset;
269         lock.l_len = count;
270         lock.l_pid = 0;
271
272         ret = fcntl(fd,op,&lock);
273
274         if (ret == -1 && errno != 0)
275                 DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
276
277         /* a lock query */
278         if (op == F_GETLK) {
279                 if ((ret != -1) &&
280                                 (lock.l_type != F_UNLCK) && 
281                                 (lock.l_pid != 0) && 
282                                 (lock.l_pid != getpid())) {
283                         DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
284                         return true;
285                 }
286
287                 /* it must be not locked or locked by me */
288                 return false;
289         }
290
291         /* a lock set or unset */
292         if (ret == -1) {
293                 DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
294                         (double)offset,(double)count,op,type,strerror(errno)));
295                 return false;
296         }
297
298         /* everything went OK */
299         DEBUG(8,("fcntl_lock: Lock call successful\n"));
300
301         return true;
302 }
303
304 static void debugadd_cb(const char *buf, void *private_data)
305 {
306         int *plevel = (int *)private_data;
307         DEBUGADD(*plevel, ("%s", buf));
308 }
309
310 void print_asc_cb(const uint8_t *buf, int len,
311                   void (*cb)(const char *buf, void *private_data),
312                   void *private_data)
313 {
314         int i;
315         char s[2];
316         s[1] = 0;
317
318         for (i=0; i<len; i++) {
319                 s[0] = isprint(buf[i]) ? buf[i] : '.';
320                 cb(s, private_data);
321         }
322 }
323
324 void print_asc(int level, const uint8_t *buf,int len)
325 {
326         print_asc_cb(buf, len, debugadd_cb, &level);
327 }
328
329 /**
330  * Write dump of binary data to a callback
331  */
332 void dump_data_cb(const uint8_t *buf, int len,
333                   bool omit_zero_bytes,
334                   void (*cb)(const char *buf, void *private_data),
335                   void *private_data)
336 {
337         int i=0;
338         static const uint8_t empty[16] = { 0, };
339         bool skipped = false;
340         char tmp[16];
341
342         if (len<=0) return;
343
344         for (i=0;i<len;) {
345
346                 if (i%16 == 0) {
347                         if ((omit_zero_bytes == true) &&
348                             (i > 0) &&
349                             (len > i+16) &&
350                             (memcmp(&buf[i], &empty, 16) == 0))
351                         {
352                                 i +=16;
353                                 continue;
354                         }
355
356                         if (i<len)  {
357                                 snprintf(tmp, sizeof(tmp), "[%04X] ", i);
358                                 cb(tmp, private_data);
359                         }
360                 }
361
362                 snprintf(tmp, sizeof(tmp), "%02X ", (int)buf[i]);
363                 cb(tmp, private_data);
364                 i++;
365                 if (i%8 == 0) {
366                         cb("  ", private_data);
367                 }
368                 if (i%16 == 0) {
369
370                         print_asc_cb(&buf[i-16], 8, cb, private_data);
371                         cb(" ", private_data);
372                         print_asc_cb(&buf[i-8], 8, cb, private_data);
373                         cb("\n", private_data);
374
375                         if ((omit_zero_bytes == true) &&
376                             (len > i+16) &&
377                             (memcmp(&buf[i], &empty, 16) == 0)) {
378                                 if (!skipped) {
379                                         cb("skipping zero buffer bytes\n",
380                                            private_data);
381                                         skipped = true;
382                                 }
383                         }
384                 }
385         }
386
387         if (i%16) {
388                 int n;
389                 n = 16 - (i%16);
390                 cb(" ", private_data);
391                 if (n>8) {
392                         cb(" ", private_data);
393                 }
394                 while (n--) {
395                         cb("   ", private_data);
396                 }
397                 n = MIN(8,i%16);
398                 print_asc_cb(&buf[i-(i%16)], n, cb, private_data);
399                 cb(" ", private_data);
400                 n = (i%16) - n;
401                 if (n>0) {
402                         print_asc_cb(&buf[i-n], n, cb, private_data);
403                 }
404                 cb("\n", private_data);
405         }
406
407 }
408
409 /**
410  * Write dump of binary data to the log file.
411  *
412  * The data is only written if the log level is at least level.
413  */
414 _PUBLIC_ void dump_data(int level, const uint8_t *buf, int len)
415 {
416         if (!DEBUGLVL(level)) {
417                 return;
418         }
419         dump_data_cb(buf, len, false, debugadd_cb, &level);
420 }
421
422 /**
423  * Write dump of binary data to the log file.
424  *
425  * The data is only written if the log level is at least level.
426  * 16 zero bytes in a row are omitted
427  */
428 _PUBLIC_ void dump_data_skip_zeros(int level, const uint8_t *buf, int len)
429 {
430         if (!DEBUGLVL(level)) {
431                 return;
432         }
433         dump_data_cb(buf, len, true, debugadd_cb, &level);
434 }
435
436
437 /**
438  malloc that aborts with smb_panic on fail or zero size.
439 **/
440
441 _PUBLIC_ void *smb_xmalloc(size_t size)
442 {
443         void *p;
444         if (size == 0)
445                 smb_panic("smb_xmalloc: called with zero size.\n");
446         if ((p = malloc(size)) == NULL)
447                 smb_panic("smb_xmalloc: malloc fail.\n");
448         return p;
449 }
450
451 /**
452  Memdup with smb_panic on fail.
453 **/
454
455 _PUBLIC_ void *smb_xmemdup(const void *p, size_t size)
456 {
457         void *p2;
458         p2 = smb_xmalloc(size);
459         memcpy(p2, p, size);
460         return p2;
461 }
462
463 /**
464  strdup that aborts on malloc fail.
465 **/
466
467 char *smb_xstrdup(const char *s)
468 {
469 #if defined(PARANOID_MALLOC_CHECKER)
470 #ifdef strdup
471 #undef strdup
472 #endif
473 #endif
474
475 #ifndef HAVE_STRDUP
476 #define strdup rep_strdup
477 #endif
478
479         char *s1 = strdup(s);
480 #if defined(PARANOID_MALLOC_CHECKER)
481 #ifdef strdup
482 #undef strdup
483 #endif
484 #define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
485 #endif
486         if (!s1) {
487                 smb_panic("smb_xstrdup: malloc failed");
488         }
489         return s1;
490
491 }
492
493 /**
494  strndup that aborts on malloc fail.
495 **/
496
497 char *smb_xstrndup(const char *s, size_t n)
498 {
499 #if defined(PARANOID_MALLOC_CHECKER)
500 #ifdef strndup
501 #undef strndup
502 #endif
503 #endif
504
505 #if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
506 #undef HAVE_STRNDUP
507 #define strndup rep_strndup
508 #endif
509
510         char *s1 = strndup(s, n);
511 #if defined(PARANOID_MALLOC_CHECKER)
512 #ifdef strndup
513 #undef strndup
514 #endif
515 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
516 #endif
517         if (!s1) {
518                 smb_panic("smb_xstrndup: malloc failed");
519         }
520         return s1;
521 }
522
523
524
525 /**
526  Like strdup but for memory.
527 **/
528
529 _PUBLIC_ void *memdup(const void *p, size_t size)
530 {
531         void *p2;
532         if (size == 0)
533                 return NULL;
534         p2 = malloc(size);
535         if (!p2)
536                 return NULL;
537         memcpy(p2, p, size);
538         return p2;
539 }
540
541 /**
542  * Write a password to the log file.
543  *
544  * @note Only actually does something if DEBUG_PASSWORD was defined during 
545  * compile-time.
546  */
547 _PUBLIC_ void dump_data_pw(const char *msg, const uint8_t * data, size_t len)
548 {
549 #ifdef DEBUG_PASSWORD
550         DEBUG(11, ("%s", msg));
551         if (data != NULL && len > 0)
552         {
553                 dump_data(11, data, len);
554         }
555 #endif
556 }
557
558
559 /**
560  * see if a range of memory is all zero. A NULL pointer is considered
561  * to be all zero 
562  */
563 _PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size)
564 {
565         int i;
566         if (!ptr) return true;
567         for (i=0;i<size;i++) {
568                 if (ptr[i]) return false;
569         }
570         return true;
571 }
572
573 /**
574   realloc an array, checking for integer overflow in the array size
575 */
576 _PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail)
577 {
578 #define MAX_MALLOC_SIZE 0x7fffffff
579         if (count == 0 ||
580             count >= MAX_MALLOC_SIZE/el_size) {
581                 if (free_on_fail)
582                         SAFE_FREE(ptr);
583                 return NULL;
584         }
585         if (!ptr) {
586                 return malloc(el_size * count);
587         }
588         return realloc(ptr, el_size * count);
589 }
590
591 /****************************************************************************
592  Type-safe malloc.
593 ****************************************************************************/
594
595 void *malloc_array(size_t el_size, unsigned int count)
596 {
597         return realloc_array(NULL, el_size, count, false);
598 }
599
600 /**
601  Trim the specified elements off the front and back of a string.
602 **/
603 _PUBLIC_ bool trim_string(char *s, const char *front, const char *back)
604 {
605         bool ret = false;
606         size_t front_len;
607         size_t back_len;
608         size_t len;
609
610         /* Ignore null or empty strings. */
611         if (!s || (s[0] == '\0'))
612                 return false;
613
614         front_len       = front? strlen(front) : 0;
615         back_len        = back? strlen(back) : 0;
616
617         len = strlen(s);
618
619         if (front_len) {
620                 while (len && strncmp(s, front, front_len)==0) {
621                         /* Must use memmove here as src & dest can
622                          * easily overlap. Found by valgrind. JRA. */
623                         memmove(s, s+front_len, (len-front_len)+1);
624                         len -= front_len;
625                         ret=true;
626                 }
627         }
628         
629         if (back_len) {
630                 while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
631                         s[len-back_len]='\0';
632                         len -= back_len;
633                         ret=true;
634                 }
635         }
636         return ret;
637 }
638
639 /**
640  Find the number of 'c' chars in a string
641 **/
642 _PUBLIC_ _PURE_ size_t count_chars(const char *s, char c)
643 {
644         size_t count = 0;
645
646         while (*s) {
647                 if (*s == c) count++;
648                 s ++;
649         }
650
651         return count;
652 }
653
654 /**
655  Routine to get hex characters and turn them into a 16 byte array.
656  the array can be variable length, and any non-hex-numeric
657  characters are skipped.  "0xnn" or "0Xnn" is specially catered
658  for.
659
660  valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
661
662
663 **/
664 _PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len)
665 {
666         size_t i = 0;
667         size_t num_chars = 0;
668         uint8_t   lonybble, hinybble;
669         const char     *hexchars = "0123456789ABCDEF";
670         char           *p1 = NULL, *p2 = NULL;
671
672         /* skip leading 0x prefix */
673         if (strncasecmp(strhex, "0x", 2) == 0) {
674                 i += 2; /* skip two chars */
675         }
676
677         for (; i < strhex_len && strhex[i] != 0; i++) {
678                 if (!(p1 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
679                         break;
680
681                 i++; /* next hex digit */
682
683                 if (!(p2 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
684                         break;
685
686                 /* get the two nybbles */
687                 hinybble = PTR_DIFF(p1, hexchars);
688                 lonybble = PTR_DIFF(p2, hexchars);
689
690                 if (num_chars >= p_len) {
691                         break;
692                 }
693
694                 p[num_chars] = (hinybble << 4) | lonybble;
695                 num_chars++;
696
697                 p1 = NULL;
698                 p2 = NULL;
699         }
700         return num_chars;
701 }
702
703 /** 
704  * Parse a hex string and return a data blob. 
705  */
706 _PUBLIC_ _PURE_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
707 {
708         DATA_BLOB ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
709
710         ret_blob.length = strhex_to_str((char *)ret_blob.data, ret_blob.length,
711                                         strhex,
712                                         strlen(strhex));
713
714         return ret_blob;
715 }
716
717
718 /**
719  * Routine to print a buffer as HEX digits, into an allocated string.
720  */
721 _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_hex_buffer)
722 {
723         int i;
724         char *hex_buffer;
725
726         *out_hex_buffer = malloc_array_p(char, (len*2)+1);
727         hex_buffer = *out_hex_buffer;
728
729         for (i = 0; i < len; i++)
730                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
731 }
732
733 /**
734  * talloc version of hex_encode()
735  */
736 _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
737 {
738         int i;
739         char *hex_buffer;
740
741         hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
742         if (!hex_buffer) {
743                 return NULL;
744         }
745
746         for (i = 0; i < len; i++)
747                 slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
748
749         talloc_set_name_const(hex_buffer, hex_buffer);
750         return hex_buffer;
751 }
752
753 /**
754   varient of strcmp() that handles NULL ptrs
755 **/
756 _PUBLIC_ int strcmp_safe(const char *s1, const char *s2)
757 {
758         if (s1 == s2) {
759                 return 0;
760         }
761         if (s1 == NULL || s2 == NULL) {
762                 return s1?-1:1;
763         }
764         return strcmp(s1, s2);
765 }
766
767
768 /**
769 return the number of bytes occupied by a buffer in ASCII format
770 the result includes the null termination
771 limited by 'n' bytes
772 **/
773 _PUBLIC_ size_t ascii_len_n(const char *src, size_t n)
774 {
775         size_t len;
776
777         len = strnlen(src, n);
778         if (len+1 <= n) {
779                 len += 1;
780         }
781
782         return len;
783 }
784
785 /**
786  Set a boolean variable from the text value stored in the passed string.
787  Returns true in success, false if the passed string does not correctly 
788  represent a boolean.
789 **/
790
791 _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
792 {
793         if (strwicmp(boolean_string, "yes") == 0 ||
794             strwicmp(boolean_string, "true") == 0 ||
795             strwicmp(boolean_string, "on") == 0 ||
796             strwicmp(boolean_string, "1") == 0) {
797                 *boolean = true;
798                 return true;
799         } else if (strwicmp(boolean_string, "no") == 0 ||
800                    strwicmp(boolean_string, "false") == 0 ||
801                    strwicmp(boolean_string, "off") == 0 ||
802                    strwicmp(boolean_string, "0") == 0) {
803                 *boolean = false;
804                 return true;
805         }
806         return false;
807 }
808
809 /**
810 return the number of bytes occupied by a buffer in CH_UTF16 format
811 the result includes the null termination
812 **/
813 _PUBLIC_ size_t utf16_len(const void *buf)
814 {
815         size_t len;
816
817         for (len = 0; SVAL(buf,len); len += 2) ;
818
819         return len + 2;
820 }
821
822 /**
823 return the number of bytes occupied by a buffer in CH_UTF16 format
824 the result includes the null termination
825 limited by 'n' bytes
826 **/
827 _PUBLIC_ size_t utf16_len_n(const void *src, size_t n)
828 {
829         size_t len;
830
831         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
832
833         if (len+2 <= n) {
834                 len += 2;
835         }
836
837         return len;
838 }
839
840 /**
841  * @file
842  * @brief String utilities.
843  **/
844
845 static bool next_token_internal_talloc(TALLOC_CTX *ctx,
846                                 const char **ptr,
847                                 char **pp_buff,
848                                 const char *sep,
849                                 bool ltrim)
850 {
851         const char *s;
852         const char *saved_s;
853         char *pbuf;
854         bool quoted;
855         size_t len=1;
856
857         *pp_buff = NULL;
858         if (!ptr) {
859                 return(false);
860         }
861
862         s = *ptr;
863
864         /* default to simple separators */
865         if (!sep) {
866                 sep = " \t\n\r";
867         }
868
869         /* find the first non sep char, if left-trimming is requested */
870         if (ltrim) {
871                 while (*s && strchr_m(sep,*s)) {
872                         s++;
873                 }
874         }
875
876         /* nothing left? */
877         if (!*s) {
878                 return false;
879         }
880
881         /* When restarting we need to go from here. */
882         saved_s = s;
883
884         /* Work out the length needed. */
885         for (quoted = false; *s &&
886                         (quoted || !strchr_m(sep,*s)); s++) {
887                 if (*s == '\"') {
888                         quoted = !quoted;
889                 } else {
890                         len++;
891                 }
892         }
893
894         /* We started with len = 1 so we have space for the nul. */
895         *pp_buff = talloc_array(ctx, char, len);
896         if (!*pp_buff) {
897                 return false;
898         }
899
900         /* copy over the token */
901         pbuf = *pp_buff;
902         s = saved_s;
903         for (quoted = false; *s &&
904                         (quoted || !strchr_m(sep,*s)); s++) {
905                 if ( *s == '\"' ) {
906                         quoted = !quoted;
907                 } else {
908                         *pbuf++ = *s;
909                 }
910         }
911
912         *ptr = (*s) ? s+1 : s;
913         *pbuf = 0;
914
915         return true;
916 }
917
918 bool next_token_talloc(TALLOC_CTX *ctx,
919                         const char **ptr,
920                         char **pp_buff,
921                         const char *sep)
922 {
923         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
924 }
925
926 /*
927  * Get the next token from a string, return false if none found.  Handles
928  * double-quotes.  This version does not trim leading separator characters
929  * before looking for a token.
930  */
931
932 bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
933                         const char **ptr,
934                         char **pp_buff,
935                         const char *sep)
936 {
937         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
938 }
939
940 /**
941  * Get the next token from a string, return False if none found.
942  * Handles double-quotes.
943  *
944  * Based on a routine by GJC@VILLAGE.COM.
945  * Extensively modified by Andrew.Tridgell@anu.edu.au
946  **/
947 _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
948 {
949         const char *s;
950         bool quoted;
951         size_t len=1;
952
953         if (!ptr)
954                 return false;
955
956         s = *ptr;
957
958         /* default to simple separators */
959         if (!sep)
960                 sep = " \t\n\r";
961
962         /* find the first non sep char */
963         while (*s && strchr_m(sep,*s))
964                 s++;
965
966         /* nothing left? */
967         if (!*s)
968                 return false;
969
970         /* copy over the token */
971         for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
972                 if (*s == '\"') {
973                         quoted = !quoted;
974                 } else {
975                         len++;
976                         *buff++ = *s;
977                 }
978         }
979
980         *ptr = (*s) ? s+1 : s;
981         *buff = 0;
982
983         return true;
984 }
985
986 struct anonymous_shared_header {
987         union {
988                 size_t length;
989                 uint8_t pad[16];
990         } u;
991 };
992
993 /* Map a shared memory buffer of at least nelem counters. */
994 void *anonymous_shared_allocate(size_t orig_bufsz)
995 {
996         void *ptr;
997         void *buf;
998         size_t pagesz = getpagesize();
999         size_t pagecnt;
1000         size_t bufsz = orig_bufsz;
1001         struct anonymous_shared_header *hdr;
1002
1003         bufsz += sizeof(*hdr);
1004
1005         /* round up to full pages */
1006         pagecnt = bufsz / pagesz;
1007         if (bufsz % pagesz) {
1008                 pagecnt += 1;
1009         }
1010         bufsz = pagesz * pagecnt;
1011
1012         if (orig_bufsz >= bufsz) {
1013                 /* integer wrap */
1014                 errno = ENOMEM;
1015                 return NULL;
1016         }
1017
1018 #ifdef MAP_ANON
1019         /* BSD */
1020         buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
1021                         -1 /* fd */, 0 /* offset */);
1022 #else
1023         buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
1024                         open("/dev/zero", O_RDWR), 0 /* offset */);
1025 #endif
1026
1027         if (buf == MAP_FAILED) {
1028                 return NULL;
1029         }
1030
1031         hdr = (struct anonymous_shared_header *)buf;
1032         hdr->u.length = bufsz;
1033
1034         ptr = (void *)(&hdr[1]);
1035
1036         return ptr;
1037 }
1038
1039 void anonymous_shared_free(void *ptr)
1040 {
1041         struct anonymous_shared_header *hdr;
1042
1043         if (ptr == NULL) {
1044                 return;
1045         }
1046
1047         hdr = (struct anonymous_shared_header *)ptr;
1048
1049         hdr--;
1050
1051         munmap(hdr, hdr->u.length);
1052 }
1053
1054 #ifdef DEVELOPER
1055 /* used when you want a debugger started at a particular point in the
1056    code. Mostly useful in code that runs as a child process, where
1057    normal gdb attach is harder to organise.
1058 */
1059 void samba_start_debugger(void)
1060 {
1061         char *cmd = NULL;
1062         if (asprintf(&cmd, "xterm -e \"gdb --pid %u\"&", getpid()) == -1) {
1063                 return;
1064         }
1065         if (system(cmd) == -1) {
1066                 free(cmd);
1067                 return;
1068         }
1069         free(cmd);
1070         sleep(2);
1071 }
1072 #endif