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