This is the ubiqx binary tree and linked list library.
[Samba.git] / source / lib / util.c
blob4e6bfb7054ae115ec87e36a84b7eca96563ee805
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 pstring scope = "";
26 int DEBUGLEVEL = 1;
28 BOOL passive = False;
30 int Protocol = PROTOCOL_COREPLUS;
32 /* a default finfo structure to ensure all fields are sensible */
33 file_info def_finfo = {-1,0,0,0,0,0,0,""};
35 /* these are some file handles where debug info will be stored */
36 FILE *dbf = NULL;
38 /* the client file descriptor */
39 int Client = -1;
41 /* the last IP received from */
42 struct in_addr lastip;
44 /* the last port received from */
45 int lastport=0;
47 /* this is used by the chaining code */
48 int chain_size = 0;
50 int trans_num = 0;
53 case handling on filenames
55 int case_default = CASE_LOWER;
57 pstring debugf = "";
58 int syslog_level;
60 /* the following control case operations - they are put here so the
61 client can link easily */
62 BOOL case_sensitive;
63 BOOL case_preserve;
64 BOOL use_mangled_map = False;
65 BOOL short_case_preserve;
66 BOOL case_mangle;
68 fstring remote_machine="";
69 fstring local_machine="";
70 fstring remote_arch="UNKNOWN";
71 static enum remote_arch_types ra_type = RA_UNKNOWN;
72 fstring remote_proto="UNKNOWN";
73 pstring myhostname="";
74 pstring user_socket_options="";
75 pstring sesssetup_user="";
76 pstring myname = "";
77 fstring myworkgroup = "";
78 char **my_netbios_names;
80 int smb_read_error = 0;
82 static BOOL stdout_logging = False;
84 static char *filename_dos(char *path,char *buf);
86 /*******************************************************************
87 get ready for syslog stuff
88 ******************************************************************/
89 void setup_logging(char *pname,BOOL interactive)
91 #ifdef SYSLOG
92 if (!interactive) {
93 char *p = strrchr(pname,'/');
94 if (p) pname = p+1;
95 #ifdef LOG_DAEMON
96 openlog(pname, LOG_PID, LOG_DAEMON);
97 #else /* LOG_DAEMON - for old systems that have no facility codes. */
98 openlog(pname, LOG_PID);
99 #endif /* LOG_DAEMON */
101 #endif
102 if (interactive) {
103 stdout_logging = True;
104 dbf = stdout;
109 BOOL append_log=False;
112 /****************************************************************************
113 reopen the log files
114 ****************************************************************************/
115 void reopen_logs(void)
117 extern FILE *dbf;
118 pstring fname;
120 if (DEBUGLEVEL > 0)
122 strcpy(fname,debugf);
123 if (lp_loaded() && (*lp_logfile()))
124 strcpy(fname,lp_logfile());
126 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
128 int oldumask = umask(022);
129 strcpy(debugf,fname);
130 if (dbf) fclose(dbf);
131 if (append_log)
132 dbf = fopen(debugf,"a");
133 else
134 dbf = fopen(debugf,"w");
135 if (dbf) setbuf(dbf,NULL);
136 umask(oldumask);
139 else
141 if (dbf)
143 fclose(dbf);
144 dbf = NULL;
150 /*******************************************************************
151 check if the log has grown too big
152 ********************************************************************/
153 static void check_log_size(void)
155 static int debug_count=0;
156 int maxlog;
157 struct stat st;
159 if (debug_count++ < 100 || getuid() != 0) return;
161 maxlog = lp_max_log_size() * 1024;
162 if (!dbf || maxlog <= 0) return;
164 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
165 fclose(dbf); dbf = NULL;
166 reopen_logs();
167 if (dbf && file_size(debugf) > maxlog) {
168 pstring name;
169 fclose(dbf); dbf = NULL;
170 sprintf(name,"%s.old",debugf);
171 sys_rename(debugf,name);
172 reopen_logs();
175 debug_count=0;
179 /*******************************************************************
180 write an debug message on the debugfile. This is called by the DEBUG
181 macro
182 ********************************************************************/
183 #ifdef __STDC__
184 int Debug1(char *format_str, ...)
186 #else
187 int Debug1(va_alist)
188 va_dcl
190 char *format_str;
191 #endif
192 va_list ap;
193 int old_errno = errno;
195 if (stdout_logging) {
196 #ifdef __STDC__
197 va_start(ap, format_str);
198 #else
199 va_start(ap);
200 format_str = va_arg(ap,char *);
201 #endif
202 vfprintf(dbf,format_str,ap);
203 va_end(ap);
204 errno = old_errno;
205 return(0);
208 #ifdef SYSLOG
209 if (!lp_syslog_only())
210 #endif
212 if (!dbf) {
213 int oldumask = umask(022);
214 dbf = fopen(debugf,"w");
215 umask(oldumask);
216 if (dbf) {
217 setbuf(dbf,NULL);
218 } else {
219 errno = old_errno;
220 return(0);
225 #ifdef SYSLOG
226 if (syslog_level < lp_syslog())
229 * map debug levels to syslog() priorities
230 * note that not all DEBUG(0, ...) calls are
231 * necessarily errors
233 static int priority_map[] = {
234 LOG_ERR, /* 0 */
235 LOG_WARNING, /* 1 */
236 LOG_NOTICE, /* 2 */
237 LOG_INFO, /* 3 */
239 int priority;
240 pstring msgbuf;
242 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
243 syslog_level < 0)
244 priority = LOG_DEBUG;
245 else
246 priority = priority_map[syslog_level];
248 #ifdef __STDC__
249 va_start(ap, format_str);
250 #else
251 va_start(ap);
252 format_str = va_arg(ap,char *);
253 #endif
254 vsprintf(msgbuf, format_str, ap);
255 va_end(ap);
257 msgbuf[255] = '\0';
258 syslog(priority, "%s", msgbuf);
260 #endif
262 #ifdef SYSLOG
263 if (!lp_syslog_only())
264 #endif
266 #ifdef __STDC__
267 va_start(ap, format_str);
268 #else
269 va_start(ap);
270 format_str = va_arg(ap,char *);
271 #endif
272 vfprintf(dbf,format_str,ap);
273 va_end(ap);
274 fflush(dbf);
277 check_log_size();
279 errno = old_errno;
281 return(0);
284 /****************************************************************************
285 find a suitable temporary directory. The result should be copied immediately
286 as it may be overwritten by a subsequent call
287 ****************************************************************************/
288 char *tmpdir(void)
290 char *p;
291 if ((p = getenv("TMPDIR"))) {
292 return p;
294 return "/tmp";
299 /****************************************************************************
300 determine if a file descriptor is in fact a socket
301 ****************************************************************************/
302 BOOL is_a_socket(int fd)
304 int v,l;
305 l = sizeof(int);
306 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
310 static char *last_ptr=NULL;
312 /****************************************************************************
313 Get the next token from a string, return False if none found
314 handles double-quotes.
315 Based on a routine by GJC@VILLAGE.COM.
316 Extensively modified by Andrew.Tridgell@anu.edu.au
317 ****************************************************************************/
318 BOOL next_token(char **ptr,char *buff,char *sep)
320 char *s;
321 BOOL quoted;
323 if (!ptr) ptr = &last_ptr;
324 if (!ptr) return(False);
326 s = *ptr;
328 /* default to simple separators */
329 if (!sep) sep = " \t\n\r";
331 /* find the first non sep char */
332 while(*s && strchr(sep,*s)) s++;
334 /* nothing left? */
335 if (! *s) return(False);
337 /* copy over the token */
338 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
340 if (*s == '\"')
341 quoted = !quoted;
342 else
343 *buff++ = *s;
346 *ptr = (*s) ? s+1 : s;
347 *buff = 0;
348 last_ptr = *ptr;
350 return(True);
353 /****************************************************************************
354 Convert list of tokens to array; dependent on above routine.
355 Uses last_ptr from above - bit of a hack.
356 ****************************************************************************/
357 char **toktocliplist(int *ctok, char *sep)
359 char *s=last_ptr;
360 int ictok=0;
361 char **ret, **iret;
363 if (!sep) sep = " \t\n\r";
365 while(*s && strchr(sep,*s)) s++;
367 /* nothing left? */
368 if (!*s) return(NULL);
370 do {
371 ictok++;
372 while(*s && (!strchr(sep,*s))) s++;
373 while(*s && strchr(sep,*s)) *s++=0;
374 } while(*s);
376 *ctok=ictok;
377 s=last_ptr;
379 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
381 while(ictok--) {
382 *iret++=s;
383 while(*s++);
384 while(!*s) s++;
387 return ret;
390 #ifndef HAVE_MEMMOVE
391 /*******************************************************************
392 safely copies memory, ensuring no overlap problems.
393 this is only used if the machine does not have it's own memmove().
394 this is not the fastest algorithm in town, but it will do for our
395 needs.
396 ********************************************************************/
397 void *MemMove(void *dest,void *src,int size)
399 unsigned long d,s;
400 int i;
401 if (dest==src || !size) return(dest);
403 d = (unsigned long)dest;
404 s = (unsigned long)src;
406 if ((d >= (s+size)) || (s >= (d+size))) {
407 /* no overlap */
408 memcpy(dest,src,size);
409 return(dest);
412 if (d < s)
414 /* we can forward copy */
415 if (s-d >= sizeof(int) &&
416 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
417 /* do it all as words */
418 int *idest = (int *)dest;
419 int *isrc = (int *)src;
420 size /= sizeof(int);
421 for (i=0;i<size;i++) idest[i] = isrc[i];
422 } else {
423 /* simplest */
424 char *cdest = (char *)dest;
425 char *csrc = (char *)src;
426 for (i=0;i<size;i++) cdest[i] = csrc[i];
429 else
431 /* must backward copy */
432 if (d-s >= sizeof(int) &&
433 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
434 /* do it all as words */
435 int *idest = (int *)dest;
436 int *isrc = (int *)src;
437 size /= sizeof(int);
438 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
439 } else {
440 /* simplest */
441 char *cdest = (char *)dest;
442 char *csrc = (char *)src;
443 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
446 return(dest);
448 #endif
451 /****************************************************************************
452 prompte a dptr (to make it recently used)
453 ****************************************************************************/
454 void array_promote(char *array,int elsize,int element)
456 char *p;
457 if (element == 0)
458 return;
460 p = (char *)malloc(elsize);
462 if (!p)
464 DEBUG(5,("Ahh! Can't malloc\n"));
465 return;
467 memcpy(p,array + element * elsize, elsize);
468 memmove(array + elsize,array,elsize*element);
469 memcpy(array,p,elsize);
470 free(p);
473 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
475 struct
477 char *name;
478 int level;
479 int option;
480 int value;
481 int opttype;
482 } socket_options[] = {
483 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
484 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
485 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
486 #ifdef TCP_NODELAY
487 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
488 #endif
489 #ifdef IPTOS_LOWDELAY
490 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
491 #endif
492 #ifdef IPTOS_THROUGHPUT
493 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
494 #endif
495 #ifdef SO_SNDBUF
496 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
497 #endif
498 #ifdef SO_RCVBUF
499 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
500 #endif
501 #ifdef SO_SNDLOWAT
502 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
503 #endif
504 #ifdef SO_RCVLOWAT
505 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
506 #endif
507 #ifdef SO_SNDTIMEO
508 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
509 #endif
510 #ifdef SO_RCVTIMEO
511 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
512 #endif
513 {NULL,0,0,0,0}};
517 /****************************************************************************
518 set user socket options
519 ****************************************************************************/
520 void set_socket_options(int fd, char *options)
522 string tok;
524 while (next_token(&options,tok," \t,"))
526 int ret=0,i;
527 int value = 1;
528 char *p;
529 BOOL got_value = False;
531 if ((p = strchr(tok,'=')))
533 *p = 0;
534 value = atoi(p+1);
535 got_value = True;
538 for (i=0;socket_options[i].name;i++)
539 if (strequal(socket_options[i].name,tok))
540 break;
542 if (!socket_options[i].name)
544 DEBUG(0,("Unknown socket option %s\n",tok));
545 continue;
548 switch (socket_options[i].opttype)
550 case OPT_BOOL:
551 case OPT_INT:
552 ret = setsockopt(fd,socket_options[i].level,
553 socket_options[i].option,(char *)&value,sizeof(int));
554 break;
556 case OPT_ON:
557 if (got_value)
558 DEBUG(0,("syntax error - %s does not take a value\n",tok));
561 int on = socket_options[i].value;
562 ret = setsockopt(fd,socket_options[i].level,
563 socket_options[i].option,(char *)&on,sizeof(int));
565 break;
568 if (ret != 0)
569 DEBUG(0,("Failed to set socket option %s\n",tok));
575 /****************************************************************************
576 close the socket communication
577 ****************************************************************************/
578 void close_sockets(void )
580 close(Client);
581 Client = 0;
584 /****************************************************************************
585 determine whether we are in the specified group
586 ****************************************************************************/
587 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
589 int i;
591 if (group == current_gid) return(True);
593 for (i=0;i<ngroups;i++)
594 if (group == groups[i])
595 return(True);
597 return(False);
600 /****************************************************************************
601 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
602 ****************************************************************************/
603 char *StrCpy(char *dest,char *src)
605 char *d = dest;
607 #if AJT
608 /* I don't want to get lazy with these ... */
609 if (!dest || !src) {
610 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
611 ajt_panic();
613 #endif
615 if (!dest) return(NULL);
616 if (!src) {
617 *dest = 0;
618 return(dest);
620 while ((*d++ = *src++)) ;
621 return(dest);
624 /****************************************************************************
625 line strncpy but always null terminates. Make sure there is room!
626 ****************************************************************************/
627 char *StrnCpy(char *dest,char *src,int n)
629 char *d = dest;
630 if (!dest) return(NULL);
631 if (!src) {
632 *dest = 0;
633 return(dest);
635 while (n-- && (*d++ = *src++)) ;
636 *d = 0;
637 return(dest);
641 /*******************************************************************
642 copy an IP address from one buffer to another
643 ********************************************************************/
644 void putip(void *dest,void *src)
646 memcpy(dest,src,4);
650 /****************************************************************************
651 interpret the weird netbios "name". Return the name type
652 ****************************************************************************/
653 static int name_interpret(char *in,char *out)
655 int ret;
656 int len = (*in++) / 2;
658 *out=0;
660 if (len > 30 || len<1) return(0);
662 while (len--)
664 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
665 *out = 0;
666 return(0);
668 *out = ((in[0]-'A')<<4) + (in[1]-'A');
669 in += 2;
670 out++;
672 *out = 0;
673 ret = out[-1];
675 #ifdef NETBIOS_SCOPE
676 /* Handle any scope names */
677 while(*in)
679 *out++ = '.'; /* Scope names are separated by periods */
680 len = *(unsigned char *)in++;
681 StrnCpy(out, in, len);
682 out += len;
683 *out=0;
684 in += len;
686 #endif
687 return(ret);
690 /****************************************************************************
691 mangle a name into netbios format
693 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
694 ****************************************************************************/
695 int name_mangle( char *In, char *Out, char name_type )
697 int i;
698 int c;
699 int len;
700 char buf[20];
701 char *p = Out;
703 /* Safely copy the input string, In, into buf[]. */
704 (void)memset( buf, 0, 20 );
705 if( '*' == In[0] )
706 buf[0] = '*';
707 else
708 (void)sprintf( buf, "%-15.15s%c", In, name_type );
710 /* Place the length of the first field into the output buffer. */
711 p[0] = 32;
712 p++;
714 /* Now convert the name to the rfc1001/1002 format. */
715 for( i = 0; i < 16; i++ )
717 c = toupper( buf[i] );
718 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
719 p[(i*2)+1] = (c & 0x000F) + 'A';
721 p += 32;
722 p[0] = '\0';
724 /* Add the scope string. */
725 for( i = 0, len = 0; NULL != scope; i++, len++ )
727 switch( scope[i] )
729 case '\0':
730 p[0] = len;
731 if( len > 0 )
732 p[len+1] = 0;
733 return( name_len(Out) );
734 case '.':
735 p[0] = len;
736 p += (len + 1);
737 len = 0;
738 break;
739 default:
740 p[len+1] = scope[i];
741 break;
745 return( name_len(Out) );
746 } /* name_mangle */
748 /*******************************************************************
749 check if a file exists
750 ********************************************************************/
751 BOOL file_exist(char *fname,struct stat *sbuf)
753 struct stat st;
754 if (!sbuf) sbuf = &st;
756 if (sys_stat(fname,sbuf) != 0)
757 return(False);
759 return(S_ISREG(sbuf->st_mode));
762 /*******************************************************************
763 check a files mod time
764 ********************************************************************/
765 time_t file_modtime(char *fname)
767 struct stat st;
769 if (sys_stat(fname,&st) != 0)
770 return(0);
772 return(st.st_mtime);
775 /*******************************************************************
776 check if a directory exists
777 ********************************************************************/
778 BOOL directory_exist(char *dname,struct stat *st)
780 struct stat st2;
781 BOOL ret;
783 if (!st) st = &st2;
785 if (sys_stat(dname,st) != 0)
786 return(False);
788 ret = S_ISDIR(st->st_mode);
789 if(!ret)
790 errno = ENOTDIR;
791 return ret;
794 /*******************************************************************
795 returns the size in bytes of the named file
796 ********************************************************************/
797 uint32 file_size(char *file_name)
799 struct stat buf;
800 buf.st_size = 0;
801 sys_stat(file_name,&buf);
802 return(buf.st_size);
805 /*******************************************************************
806 return a string representing an attribute for a file
807 ********************************************************************/
808 char *attrib_string(int mode)
810 static char attrstr[10];
812 attrstr[0] = 0;
814 if (mode & aVOLID) strcat(attrstr,"V");
815 if (mode & aDIR) strcat(attrstr,"D");
816 if (mode & aARCH) strcat(attrstr,"A");
817 if (mode & aHIDDEN) strcat(attrstr,"H");
818 if (mode & aSYSTEM) strcat(attrstr,"S");
819 if (mode & aRONLY) strcat(attrstr,"R");
821 return(attrstr);
825 /*******************************************************************
826 case insensitive string compararison
827 ********************************************************************/
828 int StrCaseCmp(char *s, char *t)
830 /* compare until we run out of string, either t or s, or find a difference */
831 /* We *must* use toupper rather than tolower here due to the
832 asynchronous upper to lower mapping.
834 #if !defined(KANJI_WIN95_COMPATIBILITY)
835 if(lp_client_code_page() == KANJI_CODEPAGE)
837 /* Win95 treats full width ascii characters as case sensitive. */
838 int diff;
839 for (;;)
841 if (!*s || !*t)
842 return toupper (*s) - toupper (*t);
843 else if (is_sj_alph (*s) && is_sj_alph (*t))
845 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
846 if (diff)
847 return diff;
848 s += 2;
849 t += 2;
851 else if (is_shift_jis (*s) && is_shift_jis (*t))
853 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
854 if (diff)
855 return diff;
856 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
857 if (diff)
858 return diff;
859 s += 2;
860 t += 2;
862 else if (is_shift_jis (*s))
863 return 1;
864 else if (is_shift_jis (*t))
865 return -1;
866 else
868 diff = toupper (*s) - toupper (*t);
869 if (diff)
870 return diff;
871 s++;
872 t++;
876 else
877 #endif /* KANJI_WIN95_COMPATIBILITY */
879 while (*s && *t && toupper(*s) == toupper(*t))
881 s++;
882 t++;
885 return(toupper(*s) - toupper(*t));
889 /*******************************************************************
890 case insensitive string compararison, length limited
891 ********************************************************************/
892 int StrnCaseCmp(char *s, char *t, int n)
894 /* compare until we run out of string, either t or s, or chars */
895 /* We *must* use toupper rather than tolower here due to the
896 asynchronous upper to lower mapping.
898 #if !defined(KANJI_WIN95_COMPATIBILITY)
899 if(lp_client_code_page() == KANJI_CODEPAGE)
901 /* Win95 treats full width ascii characters as case sensitive. */
902 int diff;
903 for (;n > 0;)
905 if (!*s || !*t)
906 return toupper (*s) - toupper (*t);
907 else if (is_sj_alph (*s) && is_sj_alph (*t))
909 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
910 if (diff)
911 return diff;
912 s += 2;
913 t += 2;
914 n -= 2;
916 else if (is_shift_jis (*s) && is_shift_jis (*t))
918 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
919 if (diff)
920 return diff;
921 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
922 if (diff)
923 return diff;
924 s += 2;
925 t += 2;
926 n -= 2;
928 else if (is_shift_jis (*s))
929 return 1;
930 else if (is_shift_jis (*t))
931 return -1;
932 else
934 diff = toupper (*s) - toupper (*t);
935 if (diff)
936 return diff;
937 s++;
938 t++;
939 n--;
942 return 0;
944 else
945 #endif /* KANJI_WIN95_COMPATIBILITY */
947 while (n-- && *s && *t && toupper(*s) == toupper(*t))
949 s++;
950 t++;
953 /* not run out of chars - strings are different lengths */
954 if (n)
955 return(toupper(*s) - toupper(*t));
957 /* identical up to where we run out of chars,
958 and strings are same length */
959 return(0);
963 /*******************************************************************
964 compare 2 strings
965 ********************************************************************/
966 BOOL strequal(char *s1, char *s2)
968 if (s1 == s2) return(True);
969 if (!s1 || !s2) return(False);
971 return(StrCaseCmp(s1,s2)==0);
974 /*******************************************************************
975 compare 2 strings up to and including the nth char.
976 ******************************************************************/
977 BOOL strnequal(char *s1,char *s2,int n)
979 if (s1 == s2) return(True);
980 if (!s1 || !s2 || !n) return(False);
982 return(StrnCaseCmp(s1,s2,n)==0);
985 /*******************************************************************
986 compare 2 strings (case sensitive)
987 ********************************************************************/
988 BOOL strcsequal(char *s1,char *s2)
990 if (s1 == s2) return(True);
991 if (!s1 || !s2) return(False);
993 return(strcmp(s1,s2)==0);
997 /*******************************************************************
998 convert a string to lower case
999 ********************************************************************/
1000 void strlower(char *s)
1002 while (*s)
1004 #if !defined(KANJI_WIN95_COMPATIBILITY)
1005 if(lp_client_code_page() == KANJI_CODEPAGE)
1007 /* Win95 treats full width ascii characters as case sensitive. */
1008 if (is_shift_jis (*s))
1010 if (is_sj_upper (s[0], s[1]))
1011 s[1] = sj_tolower2 (s[1]);
1012 s += 2;
1014 else if (is_kana (*s))
1016 s++;
1018 else
1020 if (isupper(*s))
1021 *s = tolower(*s);
1022 s++;
1025 else
1026 #endif /* KANJI_WIN95_COMPATIBILITY */
1028 if (isupper(*s))
1029 *s = tolower(*s);
1030 s++;
1035 /*******************************************************************
1036 convert a string to upper case
1037 ********************************************************************/
1038 void strupper(char *s)
1040 while (*s)
1042 #if !defined(KANJI_WIN95_COMPATIBILITY)
1043 if(lp_client_code_page() == KANJI_CODEPAGE)
1045 /* Win95 treats full width ascii characters as case sensitive. */
1046 if (is_shift_jis (*s))
1048 if (is_sj_lower (s[0], s[1]))
1049 s[1] = sj_toupper2 (s[1]);
1050 s += 2;
1052 else if (is_kana (*s))
1054 s++;
1056 else
1058 if (islower(*s))
1059 *s = toupper(*s);
1060 s++;
1063 else
1064 #endif /* KANJI_WIN95_COMPATIBILITY */
1066 if (islower(*s))
1067 *s = toupper(*s);
1068 s++;
1073 /*******************************************************************
1074 convert a string to "normal" form
1075 ********************************************************************/
1076 void strnorm(char *s)
1078 if (case_default == CASE_UPPER)
1079 strupper(s);
1080 else
1081 strlower(s);
1084 /*******************************************************************
1085 check if a string is in "normal" case
1086 ********************************************************************/
1087 BOOL strisnormal(char *s)
1089 if (case_default == CASE_UPPER)
1090 return(!strhaslower(s));
1092 return(!strhasupper(s));
1096 /****************************************************************************
1097 string replace
1098 ****************************************************************************/
1099 void string_replace(char *s,char oldc,char newc)
1101 while (*s)
1103 #if !defined(KANJI_WIN95_COMPATIBILITY)
1104 if(lp_client_code_page() == KANJI_CODEPAGE)
1106 /* Win95 treats full width ascii characters as case sensitive. */
1107 if (is_shift_jis (*s))
1108 s += 2;
1109 else if (is_kana (*s))
1110 s++;
1111 else
1113 if (oldc == *s)
1114 *s = newc;
1115 s++;
1118 else
1119 #endif /* KANJI_WIN95_COMPATIBILITY */
1121 if (oldc == *s)
1122 *s = newc;
1123 s++;
1128 /****************************************************************************
1129 make a file into unix format
1130 ****************************************************************************/
1131 void unix_format(char *fname)
1133 pstring namecopy;
1134 string_replace(fname,'\\','/');
1136 if (*fname == '/')
1138 pstrcpy(namecopy,fname);
1139 strcpy(fname,".");
1140 strcat(fname,namecopy);
1144 /****************************************************************************
1145 make a file into dos format
1146 ****************************************************************************/
1147 void dos_format(char *fname)
1149 string_replace(fname,'/','\\');
1153 /*******************************************************************
1154 show a smb message structure
1155 ********************************************************************/
1156 void show_msg(char *buf)
1158 int i;
1159 int j;
1160 int bcc=0;
1161 if (DEBUGLEVEL < 5)
1162 return;
1164 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1165 smb_len(buf),
1166 (int)CVAL(buf,smb_com),
1167 (int)CVAL(buf,smb_rcls),
1168 (int)CVAL(buf,smb_reh),
1169 (int)SVAL(buf,smb_err),
1170 (int)CVAL(buf,smb_flg),
1171 (int)SVAL(buf,smb_flg2)));
1172 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1173 (int)SVAL(buf,smb_tid),
1174 (int)SVAL(buf,smb_pid),
1175 (int)SVAL(buf,smb_uid),
1176 (int)SVAL(buf,smb_mid),
1177 (int)CVAL(buf,smb_wct)));
1178 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1179 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1180 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1181 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1182 DEBUG(5,("smb_bcc=%d\n",bcc));
1183 if (DEBUGLEVEL < 10)
1184 return;
1185 for (i = 0; i < MIN(bcc, 256); i += 16)
1187 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1190 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1191 if (j == 7) DEBUG(10, (" "));
1194 DEBUG(10,(" "));
1196 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1198 unsigned char c = CVAL(smb_buf(buf),i+j);
1199 if (c < 32 || c > 128) c = '.';
1200 DEBUG(10,("%c",c));
1202 if (j == 7) DEBUG(10, (" "));
1205 DEBUG(10,("\n"));
1209 /*******************************************************************
1210 return the length of an smb packet
1211 ********************************************************************/
1212 int smb_len(char *buf)
1214 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1217 /*******************************************************************
1218 set the length of an smb packet
1219 ********************************************************************/
1220 void _smb_setlen(char *buf,int len)
1222 buf[0] = 0;
1223 buf[1] = (len&0x10000)>>16;
1224 buf[2] = (len&0xFF00)>>8;
1225 buf[3] = len&0xFF;
1228 /*******************************************************************
1229 set the length and marker of an smb packet
1230 ********************************************************************/
1231 void smb_setlen(char *buf,int len)
1233 _smb_setlen(buf,len);
1235 CVAL(buf,4) = 0xFF;
1236 CVAL(buf,5) = 'S';
1237 CVAL(buf,6) = 'M';
1238 CVAL(buf,7) = 'B';
1241 /*******************************************************************
1242 setup the word count and byte count for a smb message
1243 ********************************************************************/
1244 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1246 if (zero)
1247 bzero(buf + smb_size,num_words*2 + num_bytes);
1248 CVAL(buf,smb_wct) = num_words;
1249 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1250 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1251 return (smb_size + num_words*2 + num_bytes);
1254 /*******************************************************************
1255 return the number of smb words
1256 ********************************************************************/
1257 int smb_numwords(char *buf)
1259 return (CVAL(buf,smb_wct));
1262 /*******************************************************************
1263 return the size of the smb_buf region of a message
1264 ********************************************************************/
1265 int smb_buflen(char *buf)
1267 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1270 /*******************************************************************
1271 return a pointer to the smb_buf data area
1272 ********************************************************************/
1273 int smb_buf_ofs(char *buf)
1275 return (smb_size + CVAL(buf,smb_wct)*2);
1278 /*******************************************************************
1279 return a pointer to the smb_buf data area
1280 ********************************************************************/
1281 char *smb_buf(char *buf)
1283 return (buf + smb_buf_ofs(buf));
1286 /*******************************************************************
1287 return the SMB offset into an SMB buffer
1288 ********************************************************************/
1289 int smb_offset(char *p,char *buf)
1291 return(PTR_DIFF(p,buf+4) + chain_size);
1295 /*******************************************************************
1296 skip past some strings in a buffer
1297 ********************************************************************/
1298 char *skip_string(char *buf,int n)
1300 while (n--)
1301 buf += strlen(buf) + 1;
1302 return(buf);
1305 /*******************************************************************
1306 trim the specified elements off the front and back of a string
1307 ********************************************************************/
1308 BOOL trim_string(char *s,char *front,char *back)
1310 BOOL ret = False;
1311 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1313 char *p = s;
1314 ret = True;
1315 while (1)
1317 if (!(*p = p[strlen(front)]))
1318 break;
1319 p++;
1322 while (back && *back && strlen(s) >= strlen(back) &&
1323 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1325 ret = True;
1326 s[strlen(s)-strlen(back)] = 0;
1328 return(ret);
1332 /*******************************************************************
1333 reduce a file name, removing .. elements.
1334 ********************************************************************/
1335 void dos_clean_name(char *s)
1337 char *p=NULL;
1339 DEBUG(3,("dos_clean_name [%s]\n",s));
1341 /* remove any double slashes */
1342 string_sub(s, "\\\\", "\\");
1344 while ((p = strstr(s,"\\..\\")) != NULL)
1346 pstring s1;
1348 *p = 0;
1349 pstrcpy(s1,p+3);
1351 if ((p=strrchr(s,'\\')) != NULL)
1352 *p = 0;
1353 else
1354 *s = 0;
1355 strcat(s,s1);
1358 trim_string(s,NULL,"\\..");
1360 string_sub(s, "\\.\\", "\\");
1363 /*******************************************************************
1364 reduce a file name, removing .. elements.
1365 ********************************************************************/
1366 void unix_clean_name(char *s)
1368 char *p=NULL;
1370 DEBUG(3,("unix_clean_name [%s]\n",s));
1372 /* remove any double slashes */
1373 string_sub(s, "//","/");
1375 /* Remove leading ./ characters */
1376 if(strncmp(s, "./", 2) == 0) {
1377 trim_string(s, "./", NULL);
1378 if(*s == 0)
1379 strcpy(s,"./");
1382 while ((p = strstr(s,"/../")) != NULL)
1384 pstring s1;
1386 *p = 0;
1387 pstrcpy(s1,p+3);
1389 if ((p=strrchr(s,'/')) != NULL)
1390 *p = 0;
1391 else
1392 *s = 0;
1393 strcat(s,s1);
1396 trim_string(s,NULL,"/..");
1400 /*******************************************************************
1401 a wrapper for the normal chdir() function
1402 ********************************************************************/
1403 int ChDir(char *path)
1405 int res;
1406 static pstring LastDir="";
1408 if (strcsequal(path,".")) return(0);
1410 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1411 DEBUG(3,("chdir to %s\n",path));
1412 res = sys_chdir(path);
1413 if (!res)
1414 pstrcpy(LastDir,path);
1415 return(res);
1418 /* number of list structures for a caching GetWd function. */
1419 #define MAX_GETWDCACHE (50)
1421 struct
1423 ino_t inode;
1424 dev_t dev;
1425 char *text;
1426 BOOL valid;
1427 } ino_list[MAX_GETWDCACHE];
1429 BOOL use_getwd_cache=True;
1431 /*******************************************************************
1432 return the absolute current directory path
1433 ********************************************************************/
1434 char *GetWd(char *str)
1436 pstring s;
1437 static BOOL getwd_cache_init = False;
1438 struct stat st, st2;
1439 int i;
1441 *s = 0;
1443 if (!use_getwd_cache)
1444 return(sys_getwd(str));
1446 /* init the cache */
1447 if (!getwd_cache_init)
1449 getwd_cache_init = True;
1450 for (i=0;i<MAX_GETWDCACHE;i++)
1452 string_init(&ino_list[i].text,"");
1453 ino_list[i].valid = False;
1457 /* Get the inode of the current directory, if this doesn't work we're
1458 in trouble :-) */
1460 if (stat(".",&st) == -1)
1462 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1463 return(sys_getwd(str));
1467 for (i=0; i<MAX_GETWDCACHE; i++)
1468 if (ino_list[i].valid)
1471 /* If we have found an entry with a matching inode and dev number
1472 then find the inode number for the directory in the cached string.
1473 If this agrees with that returned by the stat for the current
1474 directory then all is o.k. (but make sure it is a directory all
1475 the same...) */
1477 if (st.st_ino == ino_list[i].inode &&
1478 st.st_dev == ino_list[i].dev)
1480 if (stat(ino_list[i].text,&st2) == 0)
1482 if (st.st_ino == st2.st_ino &&
1483 st.st_dev == st2.st_dev &&
1484 (st2.st_mode & S_IFMT) == S_IFDIR)
1486 strcpy (str, ino_list[i].text);
1488 /* promote it for future use */
1489 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1490 return (str);
1492 else
1494 /* If the inode is different then something's changed,
1495 scrub the entry and start from scratch. */
1496 ino_list[i].valid = False;
1503 /* We don't have the information to hand so rely on traditional methods.
1504 The very slow getcwd, which spawns a process on some systems, or the
1505 not quite so bad getwd. */
1507 if (!sys_getwd(s))
1509 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1510 return (NULL);
1513 strcpy(str,s);
1515 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1517 /* add it to the cache */
1518 i = MAX_GETWDCACHE - 1;
1519 string_set(&ino_list[i].text,s);
1520 ino_list[i].dev = st.st_dev;
1521 ino_list[i].inode = st.st_ino;
1522 ino_list[i].valid = True;
1524 /* put it at the top of the list */
1525 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1527 return (str);
1532 /*******************************************************************
1533 reduce a file name, removing .. elements and checking that
1534 it is below dir in the heirachy. This uses GetWd() and so must be run
1535 on the system that has the referenced file system.
1537 widelinks are allowed if widelinks is true
1538 ********************************************************************/
1539 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1541 #ifndef REDUCE_PATHS
1542 return True;
1543 #else
1544 pstring dir2;
1545 pstring wd;
1546 pstring basename;
1547 pstring newname;
1548 char *p=NULL;
1549 BOOL relative = (*s != '/');
1551 *dir2 = *wd = *basename = *newname = 0;
1553 if (widelinks)
1555 unix_clean_name(s);
1556 /* can't have a leading .. */
1557 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1559 DEBUG(3,("Illegal file name? (%s)\n",s));
1560 return(False);
1563 if (strlen(s) == 0)
1564 strcpy(s,"./");
1566 return(True);
1569 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1571 /* remove any double slashes */
1572 string_sub(s,"//","/");
1574 pstrcpy(basename,s);
1575 p = strrchr(basename,'/');
1577 if (!p)
1578 return(True);
1580 if (!GetWd(wd))
1582 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1583 return(False);
1586 if (ChDir(dir) != 0)
1588 DEBUG(0,("couldn't chdir to %s\n",dir));
1589 return(False);
1592 if (!GetWd(dir2))
1594 DEBUG(0,("couldn't getwd for %s\n",dir));
1595 ChDir(wd);
1596 return(False);
1600 if (p && (p != basename))
1602 *p = 0;
1603 if (strcmp(p+1,".")==0)
1604 p[1]=0;
1605 if (strcmp(p+1,"..")==0)
1606 *p = '/';
1609 if (ChDir(basename) != 0)
1611 ChDir(wd);
1612 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1613 return(False);
1616 if (!GetWd(newname))
1618 ChDir(wd);
1619 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1620 return(False);
1623 if (p && (p != basename))
1625 strcat(newname,"/");
1626 strcat(newname,p+1);
1630 int l = strlen(dir2);
1631 if (dir2[l-1] == '/')
1632 l--;
1634 if (strncmp(newname,dir2,l) != 0)
1636 ChDir(wd);
1637 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1638 return(False);
1641 if (relative)
1643 if (newname[l] == '/')
1644 pstrcpy(s,newname + l + 1);
1645 else
1646 pstrcpy(s,newname+l);
1648 else
1649 pstrcpy(s,newname);
1652 ChDir(wd);
1654 if (strlen(s) == 0)
1655 strcpy(s,"./");
1657 DEBUG(3,("reduced to %s\n",s));
1658 return(True);
1659 #endif
1662 /****************************************************************************
1663 expand some *s
1664 ****************************************************************************/
1665 static void expand_one(char *Mask,int len)
1667 char *p1;
1668 while ((p1 = strchr(Mask,'*')) != NULL)
1670 int lfill = (len+1) - strlen(Mask);
1671 int l1= (p1 - Mask);
1672 pstring tmp;
1673 pstrcpy(tmp,Mask);
1674 memset(tmp+l1,'?',lfill);
1675 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1676 pstrcpy(Mask,tmp);
1680 /****************************************************************************
1681 expand a wildcard expression, replacing *s with ?s
1682 ****************************************************************************/
1683 void expand_mask(char *Mask,BOOL doext)
1685 pstring mbeg,mext;
1686 pstring dirpart;
1687 pstring filepart;
1688 BOOL hasdot = False;
1689 char *p1;
1690 BOOL absolute = (*Mask == '\\');
1692 *mbeg = *mext = *dirpart = *filepart = 0;
1694 /* parse the directory and filename */
1695 if (strchr(Mask,'\\'))
1696 dirname_dos(Mask,dirpart);
1698 filename_dos(Mask,filepart);
1700 pstrcpy(mbeg,filepart);
1701 if ((p1 = strchr(mbeg,'.')) != NULL)
1703 hasdot = True;
1704 *p1 = 0;
1705 p1++;
1706 pstrcpy(mext,p1);
1708 else
1710 strcpy(mext,"");
1711 if (strlen(mbeg) > 8)
1713 pstrcpy(mext,mbeg + 8);
1714 mbeg[8] = 0;
1718 if (*mbeg == 0)
1719 strcpy(mbeg,"????????");
1720 if ((*mext == 0) && doext && !hasdot)
1721 strcpy(mext,"???");
1723 if (strequal(mbeg,"*") && *mext==0)
1724 strcpy(mext,"*");
1726 /* expand *'s */
1727 expand_one(mbeg,8);
1728 if (*mext)
1729 expand_one(mext,3);
1731 pstrcpy(Mask,dirpart);
1732 if (*dirpart || absolute) strcat(Mask,"\\");
1733 strcat(Mask,mbeg);
1734 strcat(Mask,".");
1735 strcat(Mask,mext);
1737 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1741 /****************************************************************************
1742 does a string have any uppercase chars in it?
1743 ****************************************************************************/
1744 BOOL strhasupper(char *s)
1746 while (*s)
1748 #if !defined(KANJI_WIN95_COMPATIBILITY)
1749 if(lp_client_code_page() == KANJI_CODEPAGE)
1751 /* Win95 treats full width ascii characters as case sensitive. */
1752 if (is_shift_jis (*s))
1753 s += 2;
1754 else if (is_kana (*s))
1755 s++;
1756 else
1758 if (isupper(*s))
1759 return(True);
1760 s++;
1763 else
1764 #endif /* KANJI_WIN95_COMPATIBILITY */
1766 if (isupper(*s))
1767 return(True);
1768 s++;
1771 return(False);
1774 /****************************************************************************
1775 does a string have any lowercase chars in it?
1776 ****************************************************************************/
1777 BOOL strhaslower(char *s)
1779 while (*s)
1781 #if !defined(KANJI_WIN95_COMPATIBILITY)
1782 if(lp_client_code_page() == KANJI_CODEPAGE)
1784 /* Win95 treats full width ascii characters as case sensitive. */
1785 if (is_shift_jis (*s))
1787 if (is_sj_upper (s[0], s[1]))
1788 return(True);
1789 if (is_sj_lower (s[0], s[1]))
1790 return (True);
1791 s += 2;
1793 else if (is_kana (*s))
1795 s++;
1797 else
1799 if (islower(*s))
1800 return(True);
1801 s++;
1804 else
1805 #endif /* KANJI_WIN95_COMPATIBILITY */
1807 if (islower(*s))
1808 return(True);
1809 s++;
1812 return(False);
1815 /****************************************************************************
1816 find the number of chars in a string
1817 ****************************************************************************/
1818 int count_chars(char *s,char c)
1820 int count=0;
1822 #if !defined(KANJI_WIN95_COMPATIBILITY)
1823 if(lp_client_code_page() == KANJI_CODEPAGE)
1825 /* Win95 treats full width ascii characters as case sensitive. */
1826 while (*s)
1828 if (is_shift_jis (*s))
1829 s += 2;
1830 else
1832 if (*s == c)
1833 count++;
1834 s++;
1838 else
1839 #endif /* KANJI_WIN95_COMPATIBILITY */
1841 while (*s)
1843 if (*s == c)
1844 count++;
1845 s++;
1848 return(count);
1852 /****************************************************************************
1853 make a dir struct
1854 ****************************************************************************/
1855 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1857 char *p;
1858 pstring mask2;
1860 pstrcpy(mask2,mask);
1862 if ((mode & aDIR) != 0)
1863 size = 0;
1865 memset(buf+1,' ',11);
1866 if ((p = strchr(mask2,'.')) != NULL)
1868 *p = 0;
1869 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1870 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1871 *p = '.';
1873 else
1874 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1876 bzero(buf+21,DIR_STRUCT_SIZE-21);
1877 CVAL(buf,21) = mode;
1878 put_dos_date(buf,22,date);
1879 SSVAL(buf,26,size & 0xFFFF);
1880 SSVAL(buf,28,size >> 16);
1881 StrnCpy(buf+30,fname,12);
1882 if (!case_sensitive)
1883 strupper(buf+30);
1884 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1888 /*******************************************************************
1889 close the low 3 fd's and open dev/null in their place
1890 ********************************************************************/
1891 void close_low_fds(void)
1893 int fd;
1894 int i;
1895 close(0); close(1); close(2);
1896 /* try and use up these file descriptors, so silly
1897 library routines writing to stdout etc won't cause havoc */
1898 for (i=0;i<3;i++) {
1899 fd = open("/dev/null",O_RDWR,0);
1900 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1901 if (fd < 0) {
1902 DEBUG(0,("Can't open /dev/null\n"));
1903 return;
1905 if (fd != i) {
1906 DEBUG(0,("Didn't get file descriptor %d\n",i));
1907 return;
1912 /****************************************************************************
1913 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1914 else
1915 if SYSV use O_NDELAY
1916 if BSD use FNDELAY
1917 ****************************************************************************/
1918 int set_blocking(int fd, BOOL set)
1920 int val;
1921 #ifdef O_NONBLOCK
1922 #define FLAG_TO_SET O_NONBLOCK
1923 #else
1924 #ifdef SYSV
1925 #define FLAG_TO_SET O_NDELAY
1926 #else /* BSD */
1927 #define FLAG_TO_SET FNDELAY
1928 #endif
1929 #endif
1931 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1932 return -1;
1933 if(set) /* Turn blocking on - ie. clear nonblock flag */
1934 val &= ~FLAG_TO_SET;
1935 else
1936 val |= FLAG_TO_SET;
1937 return fcntl( fd, F_SETFL, val);
1938 #undef FLAG_TO_SET
1942 /****************************************************************************
1943 write to a socket
1944 ****************************************************************************/
1945 int write_socket(int fd,char *buf,int len)
1947 int ret=0;
1949 if (passive)
1950 return(len);
1951 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1952 ret = write_data(fd,buf,len);
1954 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1955 return(ret);
1958 /****************************************************************************
1959 read from a socket
1960 ****************************************************************************/
1961 int read_udp_socket(int fd,char *buf,int len)
1963 int ret;
1964 struct sockaddr sock;
1965 int socklen;
1967 socklen = sizeof(sock);
1968 bzero((char *)&sock,socklen);
1969 bzero((char *)&lastip,sizeof(lastip));
1970 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1971 if (ret <= 0) {
1972 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1973 return(0);
1976 lastip = *(struct in_addr *) &sock.sa_data[2];
1977 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1979 return(ret);
1982 /****************************************************************************
1983 read data from a device with a timout in msec.
1984 mincount = if timeout, minimum to read before returning
1985 maxcount = number to be read.
1986 ****************************************************************************/
1987 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1989 fd_set fds;
1990 int selrtn;
1991 int readret;
1992 int nread = 0;
1993 struct timeval timeout;
1995 /* just checking .... */
1996 if (maxcnt <= 0) return(0);
1998 smb_read_error = 0;
2000 /* Blocking read */
2001 if (time_out <= 0) {
2002 if (mincnt == 0) mincnt = maxcnt;
2004 while (nread < mincnt) {
2005 readret = read(fd, buf + nread, maxcnt - nread);
2006 if (readret == 0) {
2007 smb_read_error = READ_EOF;
2008 return -1;
2011 if (readret == -1) {
2012 smb_read_error = READ_ERROR;
2013 return -1;
2015 nread += readret;
2017 return(nread);
2020 /* Most difficult - timeout read */
2021 /* If this is ever called on a disk file and
2022 mincnt is greater then the filesize then
2023 system performance will suffer severely as
2024 select always return true on disk files */
2026 /* Set initial timeout */
2027 timeout.tv_sec = time_out / 1000;
2028 timeout.tv_usec = 1000 * (time_out % 1000);
2030 for (nread=0; nread<mincnt; )
2032 FD_ZERO(&fds);
2033 FD_SET(fd,&fds);
2035 selrtn = sys_select(&fds,&timeout);
2037 /* Check if error */
2038 if(selrtn == -1) {
2039 /* something is wrong. Maybe the socket is dead? */
2040 smb_read_error = READ_ERROR;
2041 return -1;
2044 /* Did we timeout ? */
2045 if (selrtn == 0) {
2046 smb_read_error = READ_TIMEOUT;
2047 return -1;
2050 readret = read(fd, buf+nread, maxcnt-nread);
2051 if (readret == 0) {
2052 /* we got EOF on the file descriptor */
2053 smb_read_error = READ_EOF;
2054 return -1;
2057 if (readret == -1) {
2058 /* the descriptor is probably dead */
2059 smb_read_error = READ_ERROR;
2060 return -1;
2063 nread += readret;
2066 /* Return the number we got */
2067 return(nread);
2070 /****************************************************************************
2071 read data from the client. Maxtime is in milliseconds
2072 ****************************************************************************/
2073 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2075 fd_set fds;
2076 int selrtn;
2077 int nread;
2078 struct timeval timeout;
2080 FD_ZERO(&fds);
2081 FD_SET(fd,&fds);
2083 timeout.tv_sec = maxtime / 1000;
2084 timeout.tv_usec = (maxtime % 1000) * 1000;
2086 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2088 if (!FD_ISSET(fd,&fds))
2089 return 0;
2091 nread = read_udp_socket(fd, buffer, bufsize);
2093 /* return the number got */
2094 return(nread);
2097 /*******************************************************************
2098 find the difference in milliseconds between two struct timeval
2099 values
2100 ********************************************************************/
2101 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2103 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2104 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2107 /****************************************************************************
2108 send a keepalive packet (rfc1002)
2109 ****************************************************************************/
2110 BOOL send_keepalive(int client)
2112 unsigned char buf[4];
2114 buf[0] = 0x85;
2115 buf[1] = buf[2] = buf[3] = 0;
2117 return(write_data(client,(char *)buf,4) == 4);
2122 /****************************************************************************
2123 read data from the client, reading exactly N bytes.
2124 ****************************************************************************/
2125 int read_data(int fd,char *buffer,int N)
2127 int ret;
2128 int total=0;
2130 smb_read_error = 0;
2132 while (total < N)
2134 ret = read(fd,buffer + total,N - total);
2135 if (ret == 0) {
2136 smb_read_error = READ_EOF;
2137 return 0;
2139 if (ret == -1) {
2140 smb_read_error = READ_ERROR;
2141 return -1;
2143 total += ret;
2145 return total;
2149 /****************************************************************************
2150 write data to a fd
2151 ****************************************************************************/
2152 int write_data(int fd,char *buffer,int N)
2154 int total=0;
2155 int ret;
2157 while (total < N)
2159 ret = write(fd,buffer + total,N - total);
2161 if (ret == -1) return -1;
2162 if (ret == 0) return total;
2164 total += ret;
2166 return total;
2170 /****************************************************************************
2171 transfer some data between two fd's
2172 ****************************************************************************/
2173 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2175 static char *buf=NULL;
2176 static int size=0;
2177 char *buf1,*abuf;
2178 int total = 0;
2180 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2182 if (size == 0) {
2183 size = lp_readsize();
2184 size = MAX(size,1024);
2187 while (!buf && size>0) {
2188 buf = (char *)Realloc(buf,size+8);
2189 if (!buf) size /= 2;
2192 if (!buf) {
2193 DEBUG(0,("Can't allocate transfer buffer!\n"));
2194 exit(1);
2197 abuf = buf + (align%8);
2199 if (header)
2200 n += headlen;
2202 while (n > 0)
2204 int s = MIN(n,size);
2205 int ret,ret2=0;
2207 ret = 0;
2209 if (header && (headlen >= MIN(s,1024))) {
2210 buf1 = header;
2211 s = headlen;
2212 ret = headlen;
2213 headlen = 0;
2214 header = NULL;
2215 } else {
2216 buf1 = abuf;
2219 if (header && headlen > 0)
2221 ret = MIN(headlen,size);
2222 memcpy(buf1,header,ret);
2223 headlen -= ret;
2224 header += ret;
2225 if (headlen <= 0) header = NULL;
2228 if (s > ret)
2229 ret += read(infd,buf1+ret,s-ret);
2231 if (ret > 0)
2233 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2234 if (ret2 > 0) total += ret2;
2235 /* if we can't write then dump excess data */
2236 if (ret2 != ret)
2237 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2239 if (ret <= 0 || ret2 != ret)
2240 return(total);
2241 n -= ret;
2243 return(total);
2247 /****************************************************************************
2248 read 4 bytes of a smb packet and return the smb length of the packet
2249 possibly store the result in the buffer
2250 ****************************************************************************/
2251 int read_smb_length(int fd,char *inbuf,int timeout)
2253 char *buffer;
2254 char buf[4];
2255 int len=0, msg_type;
2256 BOOL ok=False;
2258 if (inbuf)
2259 buffer = inbuf;
2260 else
2261 buffer = buf;
2263 while (!ok)
2265 if (timeout > 0)
2266 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2267 else
2268 ok = (read_data(fd,buffer,4) == 4);
2270 if (!ok)
2271 return(-1);
2273 len = smb_len(buffer);
2274 msg_type = CVAL(buffer,0);
2276 if (msg_type == 0x85)
2278 DEBUG(5,("Got keepalive packet\n"));
2279 ok = False;
2283 DEBUG(10,("got smb length of %d\n",len));
2285 return(len);
2290 /****************************************************************************
2291 read an smb from a fd. Note that the buffer *MUST* be of size
2292 BUFFER_SIZE+SAFETY_MARGIN.
2293 The timeout is in milli seconds
2294 ****************************************************************************/
2295 BOOL receive_smb(int fd,char *buffer, int timeout)
2297 int len,ret;
2299 smb_read_error = 0;
2301 bzero(buffer,smb_size + 100);
2303 len = read_smb_length(fd,buffer,timeout);
2304 if (len == -1)
2305 return(False);
2307 if (len > BUFFER_SIZE) {
2308 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2309 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2310 exit(1);
2313 ret = read_data(fd,buffer+4,len);
2314 if (ret != len) {
2315 smb_read_error = READ_ERROR;
2316 return False;
2319 return(True);
2322 /****************************************************************************
2323 read a message from a udp fd.
2324 The timeout is in milli seconds
2325 ****************************************************************************/
2326 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2328 struct sockaddr_in from;
2329 int fromlen = sizeof(from);
2330 int32 msg_len = 0;
2332 if(timeout != 0)
2334 struct timeval to;
2335 fd_set fds;
2336 int selrtn;
2338 FD_ZERO(&fds);
2339 FD_SET(fd,&fds);
2341 to.tv_sec = timeout / 1000;
2342 to.tv_usec = (timeout % 1000) * 1000;
2344 selrtn = sys_select(&fds,&to);
2346 /* Check if error */
2347 if(selrtn == -1)
2349 /* something is wrong. Maybe the socket is dead? */
2350 smb_read_error = READ_ERROR;
2351 return False;
2354 /* Did we timeout ? */
2355 if (selrtn == 0)
2357 smb_read_error = READ_TIMEOUT;
2358 return False;
2363 * Read a loopback udp message.
2365 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2366 buffer_len - UDP_CMD_HEADER_LEN, 0,
2367 (struct sockaddr *)&from, &fromlen);
2369 if(msg_len < 0)
2371 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2372 return False;
2375 /* Validate message length. */
2376 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2378 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2379 msg_len,
2380 buffer_len - UDP_CMD_HEADER_LEN));
2381 return False;
2384 /* Validate message from address (must be localhost). */
2385 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2387 DEBUG(0,("receive_local_message: invalid 'from' address \
2388 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2389 return False;
2392 /* Setup the message header */
2393 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2394 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2396 return True;
2399 /****************************************************************************
2400 structure to hold a linked list of local udp messages.
2401 for processing.
2402 ****************************************************************************/
2404 typedef struct _udp_message_list {
2405 struct _udp_message_list *msg_next;
2406 char *msg_buf;
2407 int msg_len;
2408 } udp_message_list;
2410 static udp_message_list *udp_msg_head = NULL;
2412 /****************************************************************************
2413 Function to push a linked list of local udp messages ready
2414 for processing.
2415 ****************************************************************************/
2416 BOOL push_local_message(char *buf, int msg_len)
2418 udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
2420 if(msg == NULL)
2422 DEBUG(0,("push_local_message: malloc fail (1)\n"));
2423 return False;
2426 msg->msg_buf = (char *)malloc(msg_len);
2427 if(msg->msg_buf == NULL)
2429 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2430 free((char *)msg);
2431 return False;
2434 memcpy(msg->msg_buf, buf, msg_len);
2435 msg->msg_len = msg_len;
2437 msg->msg_next = udp_msg_head;
2438 udp_msg_head = msg;
2440 return True;
2443 /****************************************************************************
2444 Do a select on an two fd's - with timeout.
2446 If a local udp message has been pushed onto the
2447 queue (this can only happen during oplock break
2448 processing) return this first.
2450 If the first smbfd is ready then read an smb from it.
2451 if the second (loopback UDP) fd is ready then read a message
2452 from it and setup the buffer header to identify the length
2453 and from address.
2454 Returns False on timeout or error.
2455 Else returns True.
2457 The timeout is in milli seconds
2458 ****************************************************************************/
2459 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2460 char *buffer, int buffer_len,
2461 int timeout, BOOL *got_smb)
2463 fd_set fds;
2464 int selrtn;
2465 struct timeval to;
2467 *got_smb = False;
2470 * Check to see if we already have a message on the udp queue.
2471 * If so - copy and return it.
2474 if(udp_msg_head)
2476 udp_message_list *msg = udp_msg_head;
2477 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2478 udp_msg_head = msg->msg_next;
2480 /* Free the message we just copied. */
2481 free((char *)msg->msg_buf);
2482 free((char *)msg);
2483 return True;
2486 FD_ZERO(&fds);
2487 FD_SET(smbfd,&fds);
2488 FD_SET(oplock_fd,&fds);
2490 to.tv_sec = timeout / 1000;
2491 to.tv_usec = (timeout % 1000) * 1000;
2493 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2495 /* Check if error */
2496 if(selrtn == -1) {
2497 /* something is wrong. Maybe the socket is dead? */
2498 smb_read_error = READ_ERROR;
2499 return False;
2502 /* Did we timeout ? */
2503 if (selrtn == 0) {
2504 smb_read_error = READ_TIMEOUT;
2505 return False;
2508 if (FD_ISSET(smbfd,&fds))
2510 *got_smb = True;
2511 return receive_smb(smbfd, buffer, 0);
2513 else
2515 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2519 /****************************************************************************
2520 send an smb to a fd
2521 ****************************************************************************/
2522 BOOL send_smb(int fd,char *buffer)
2524 int len;
2525 int ret,nwritten=0;
2526 len = smb_len(buffer) + 4;
2528 while (nwritten < len)
2530 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2531 if (ret <= 0)
2533 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2534 close_sockets();
2535 exit(1);
2537 nwritten += ret;
2541 return True;
2545 /****************************************************************************
2546 find a pointer to a netbios name
2547 ****************************************************************************/
2548 char *name_ptr(char *buf,int ofs)
2550 unsigned char c = *(unsigned char *)(buf+ofs);
2552 if ((c & 0xC0) == 0xC0)
2554 uint16 l;
2555 char p[2];
2556 memcpy(p,buf+ofs,2);
2557 p[0] &= ~0xC0;
2558 l = RSVAL(p,0);
2559 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2560 return(buf + l);
2562 else
2563 return(buf+ofs);
2566 /****************************************************************************
2567 extract a netbios name from a buf
2568 ****************************************************************************/
2569 int name_extract(char *buf,int ofs,char *name)
2571 char *p = name_ptr(buf,ofs);
2572 int d = PTR_DIFF(p,buf+ofs);
2573 strcpy(name,"");
2574 if (d < -50 || d > 50) return(0);
2575 return(name_interpret(p,name));
2578 /****************************************************************************
2579 return the total storage length of a mangled name
2580 ****************************************************************************/
2581 int name_len( char *s )
2583 int len;
2585 /* If the two high bits of the byte are set, return 2. */
2586 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2587 return(2);
2589 /* Add up the length bytes. */
2590 for( len = 1; (*s); s += (*s) + 1 )
2592 len += *s + 1;
2595 return( len );
2596 } /* name_len */
2598 /****************************************************************************
2599 send a single packet to a port on another machine
2600 ****************************************************************************/
2601 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2603 BOOL ret;
2604 int out_fd;
2605 struct sockaddr_in sock_out;
2607 if (passive)
2608 return(True);
2610 /* create a socket to write to */
2611 out_fd = socket(AF_INET, type, 0);
2612 if (out_fd == -1)
2614 DEBUG(0,("socket failed"));
2615 return False;
2618 /* set the address and port */
2619 bzero((char *)&sock_out,sizeof(sock_out));
2620 putip((char *)&sock_out.sin_addr,(char *)&ip);
2621 sock_out.sin_port = htons( port );
2622 sock_out.sin_family = AF_INET;
2624 if (DEBUGLEVEL > 0)
2625 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2626 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2628 /* send it */
2629 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2631 if (!ret)
2632 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2633 inet_ntoa(ip),port,strerror(errno)));
2635 close(out_fd);
2636 return(ret);
2639 /*******************************************************************
2640 sleep for a specified number of milliseconds
2641 ********************************************************************/
2642 void msleep(int t)
2644 int tdiff=0;
2645 struct timeval tval,t1,t2;
2646 fd_set fds;
2648 GetTimeOfDay(&t1);
2649 GetTimeOfDay(&t2);
2651 while (tdiff < t) {
2652 tval.tv_sec = (t-tdiff)/1000;
2653 tval.tv_usec = 1000*((t-tdiff)%1000);
2655 FD_ZERO(&fds);
2656 errno = 0;
2657 sys_select(&fds,&tval);
2659 GetTimeOfDay(&t2);
2660 tdiff = TvalDiff(&t1,&t2);
2664 /****************************************************************************
2665 check if a string is part of a list
2666 ****************************************************************************/
2667 BOOL in_list(char *s,char *list,BOOL casesensitive)
2669 pstring tok;
2670 char *p=list;
2672 if (!list) return(False);
2674 while (next_token(&p,tok,LIST_SEP))
2676 if (casesensitive) {
2677 if (strcmp(tok,s) == 0)
2678 return(True);
2679 } else {
2680 if (StrCaseCmp(tok,s) == 0)
2681 return(True);
2684 return(False);
2687 /* this is used to prevent lots of mallocs of size 1 */
2688 static char *null_string = NULL;
2690 /****************************************************************************
2691 set a string value, allocing the space for the string
2692 ****************************************************************************/
2693 BOOL string_init(char **dest,char *src)
2695 int l;
2696 if (!src)
2697 src = "";
2699 l = strlen(src);
2701 if (l == 0)
2703 if (!null_string)
2704 null_string = (char *)malloc(1);
2706 *null_string = 0;
2707 *dest = null_string;
2709 else
2711 (*dest) = (char *)malloc(l+1);
2712 if ((*dest) == NULL) {
2713 DEBUG(0,("Out of memory in string_init\n"));
2714 return False;
2717 strcpy(*dest,src);
2719 return(True);
2722 /****************************************************************************
2723 free a string value
2724 ****************************************************************************/
2725 void string_free(char **s)
2727 if (!s || !(*s)) return;
2728 if (*s == null_string)
2729 *s = NULL;
2730 if (*s) free(*s);
2731 *s = NULL;
2734 /****************************************************************************
2735 set a string value, allocing the space for the string, and deallocating any
2736 existing space
2737 ****************************************************************************/
2738 BOOL string_set(char **dest,char *src)
2740 string_free(dest);
2742 return(string_init(dest,src));
2745 /****************************************************************************
2746 substitute a string for a pattern in another string. Make sure there is
2747 enough room!
2749 This routine looks for pattern in s and replaces it with
2750 insert. It may do multiple replacements.
2752 return True if a substitution was done.
2753 ****************************************************************************/
2754 BOOL string_sub(char *s,char *pattern,char *insert)
2756 BOOL ret = False;
2757 char *p;
2758 int ls,lp,li;
2760 if (!insert || !pattern || !s) return(False);
2762 ls = strlen(s);
2763 lp = strlen(pattern);
2764 li = strlen(insert);
2766 if (!*pattern) return(False);
2768 while (lp <= ls && (p = strstr(s,pattern)))
2770 ret = True;
2771 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2772 memcpy(p,insert,li);
2773 s = p + li;
2774 ls = strlen(s);
2776 return(ret);
2781 /*********************************************************
2782 * Recursive routine that is called by mask_match.
2783 * Does the actual matching.
2784 *********************************************************/
2785 BOOL do_match(char *str, char *regexp, int case_sig)
2787 char *p;
2789 for( p = regexp; *p && *str; ) {
2790 switch(*p) {
2791 case '?':
2792 str++; p++;
2793 break;
2795 case '*':
2796 /* Look for a character matching
2797 the one after the '*' */
2798 p++;
2799 if(!*p)
2800 return True; /* Automatic match */
2801 while(*str) {
2802 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2803 str++;
2804 if(do_match(str,p,case_sig))
2805 return True;
2806 if(!*str)
2807 return False;
2808 else
2809 str++;
2811 return False;
2813 default:
2814 if(case_sig) {
2815 if(*str != *p)
2816 return False;
2817 } else {
2818 if(toupper(*str) != toupper(*p))
2819 return False;
2821 str++, p++;
2822 break;
2825 if(!*p && !*str)
2826 return True;
2828 if (!*p && str[0] == '.' && str[1] == 0)
2829 return(True);
2831 if (!*str && *p == '?')
2833 while (*p == '?') p++;
2834 return(!*p);
2837 if(!*str && (*p == '*' && p[1] == '\0'))
2838 return True;
2839 return False;
2843 /*********************************************************
2844 * Routine to match a given string with a regexp - uses
2845 * simplified regexp that takes * and ? only. Case can be
2846 * significant or not.
2847 *********************************************************/
2848 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2850 char *p;
2851 pstring p1, p2;
2852 fstring ebase,eext,sbase,sext;
2854 BOOL matched;
2856 /* Make local copies of str and regexp */
2857 StrnCpy(p1,regexp,sizeof(pstring)-1);
2858 StrnCpy(p2,str,sizeof(pstring)-1);
2860 if (!strchr(p2,'.')) {
2861 strcat(p2,".");
2865 if (!strchr(p1,'.')) {
2866 strcat(p1,".");
2870 #if 0
2871 if (strchr(p1,'.'))
2873 string_sub(p1,"*.*","*");
2874 string_sub(p1,".*","*");
2876 #endif
2878 /* Remove any *? and ** as they are meaningless */
2879 for(p = p1; *p; p++)
2880 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2881 (void)strcpy( &p[1], &p[2]);
2883 if (strequal(p1,"*")) return(True);
2885 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2887 if (trans2) {
2888 fstrcpy(ebase,p1);
2889 fstrcpy(sbase,p2);
2890 } else {
2891 if ((p=strrchr(p1,'.'))) {
2892 *p = 0;
2893 fstrcpy(ebase,p1);
2894 fstrcpy(eext,p+1);
2895 } else {
2896 fstrcpy(ebase,p1);
2897 eext[0] = 0;
2900 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2901 *p = 0;
2902 fstrcpy(sbase,p2);
2903 fstrcpy(sext,p+1);
2904 } else {
2905 fstrcpy(sbase,p2);
2906 fstrcpy(sext,"");
2910 matched = do_match(sbase,ebase,case_sig) &&
2911 (trans2 || do_match(sext,eext,case_sig));
2913 DEBUG(8,("mask_match returning %d\n", matched));
2915 return matched;
2920 /****************************************************************************
2921 become a daemon, discarding the controlling terminal
2922 ****************************************************************************/
2923 void become_daemon(void)
2925 #ifndef NO_FORK_DEBUG
2926 if (fork())
2927 exit(0);
2929 /* detach from the terminal */
2930 #ifdef USE_SETSID
2931 setsid();
2932 #else /* USE_SETSID */
2933 #ifdef TIOCNOTTY
2935 int i = open("/dev/tty", O_RDWR);
2936 if (i >= 0)
2938 ioctl(i, (int) TIOCNOTTY, (char *)0);
2939 close(i);
2942 #endif /* TIOCNOTTY */
2943 #endif /* USE_SETSID */
2944 /* Close fd's 0,1,2. Needed if started by rsh */
2945 close_low_fds();
2946 #endif /* NO_FORK_DEBUG */
2950 /****************************************************************************
2951 put up a yes/no prompt
2952 ****************************************************************************/
2953 BOOL yesno(char *p)
2955 pstring ans;
2956 printf("%s",p);
2958 if (!fgets(ans,sizeof(ans)-1,stdin))
2959 return(False);
2961 if (*ans == 'y' || *ans == 'Y')
2962 return(True);
2964 return(False);
2967 /****************************************************************************
2968 read a line from a file with possible \ continuation chars.
2969 Blanks at the start or end of a line are stripped.
2970 The string will be allocated if s2 is NULL
2971 ****************************************************************************/
2972 char *fgets_slash(char *s2,int maxlen,FILE *f)
2974 char *s=s2;
2975 int len = 0;
2976 int c;
2977 BOOL start_of_line = True;
2979 if (feof(f))
2980 return(NULL);
2982 if (!s2)
2984 maxlen = MIN(maxlen,8);
2985 s = (char *)Realloc(s,maxlen);
2988 if (!s || maxlen < 2) return(NULL);
2990 *s = 0;
2992 while (len < maxlen-1)
2994 c = getc(f);
2995 switch (c)
2997 case '\r':
2998 break;
2999 case '\n':
3000 while (len > 0 && s[len-1] == ' ')
3002 s[--len] = 0;
3004 if (len > 0 && s[len-1] == '\\')
3006 s[--len] = 0;
3007 start_of_line = True;
3008 break;
3010 return(s);
3011 case EOF:
3012 if (len <= 0 && !s2)
3013 free(s);
3014 return(len>0?s:NULL);
3015 case ' ':
3016 if (start_of_line)
3017 break;
3018 default:
3019 start_of_line = False;
3020 s[len++] = c;
3021 s[len] = 0;
3023 if (!s2 && len > maxlen-3)
3025 maxlen *= 2;
3026 s = (char *)Realloc(s,maxlen);
3027 if (!s) return(NULL);
3030 return(s);
3035 /****************************************************************************
3036 set the length of a file from a filedescriptor.
3037 Returns 0 on success, -1 on failure.
3038 ****************************************************************************/
3039 int set_filelen(int fd, long len)
3041 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3042 extend a file with ftruncate. Provide alternate implementation
3043 for this */
3045 #if FTRUNCATE_CAN_EXTEND
3046 return ftruncate(fd, len);
3047 #else
3048 struct stat st;
3049 char c = 0;
3050 long currpos = lseek(fd, 0L, SEEK_CUR);
3052 if(currpos < 0)
3053 return -1;
3054 /* Do an fstat to see if the file is longer than
3055 the requested size (call ftruncate),
3056 or shorter, in which case seek to len - 1 and write 1
3057 byte of zero */
3058 if(fstat(fd, &st)<0)
3059 return -1;
3061 #ifdef S_ISFIFO
3062 if (S_ISFIFO(st.st_mode)) return 0;
3063 #endif
3065 if(st.st_size == len)
3066 return 0;
3067 if(st.st_size > len)
3068 return ftruncate(fd, len);
3070 if(lseek(fd, len-1, SEEK_SET) != len -1)
3071 return -1;
3072 if(write(fd, &c, 1)!=1)
3073 return -1;
3074 /* Seek to where we were */
3075 lseek(fd, currpos, SEEK_SET);
3076 return 0;
3077 #endif
3081 /****************************************************************************
3082 return the byte checksum of some data
3083 ****************************************************************************/
3084 int byte_checksum(char *buf,int len)
3086 unsigned char *p = (unsigned char *)buf;
3087 int ret = 0;
3088 while (len--)
3089 ret += *p++;
3090 return(ret);
3095 #ifdef HPUX
3096 /****************************************************************************
3097 this is a version of setbuffer() for those machines that only have setvbuf
3098 ****************************************************************************/
3099 void setbuffer(FILE *f,char *buf,int bufsize)
3101 setvbuf(f,buf,_IOFBF,bufsize);
3103 #endif
3106 /****************************************************************************
3107 parse out a directory name from a path name. Assumes dos style filenames.
3108 ****************************************************************************/
3109 char *dirname_dos(char *path,char *buf)
3111 char *p = strrchr(path,'\\');
3113 if (!p)
3114 strcpy(buf,path);
3115 else
3117 *p = 0;
3118 strcpy(buf,path);
3119 *p = '\\';
3122 return(buf);
3126 /****************************************************************************
3127 parse out a filename from a path name. Assumes dos style filenames.
3128 ****************************************************************************/
3129 static char *filename_dos(char *path,char *buf)
3131 char *p = strrchr(path,'\\');
3133 if (!p)
3134 strcpy(buf,path);
3135 else
3136 strcpy(buf,p+1);
3138 return(buf);
3143 /****************************************************************************
3144 expand a pointer to be a particular size
3145 ****************************************************************************/
3146 void *Realloc(void *p,int size)
3148 void *ret=NULL;
3150 if (size == 0) {
3151 if (p) free(p);
3152 DEBUG(5,("Realloc asked for 0 bytes\n"));
3153 return NULL;
3156 if (!p)
3157 ret = (void *)malloc(size);
3158 else
3159 ret = (void *)realloc(p,size);
3161 if (!ret)
3162 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3164 return(ret);
3167 #ifdef NOSTRDUP
3168 /****************************************************************************
3169 duplicate a string
3170 ****************************************************************************/
3171 char *strdup(char *s)
3173 char *ret = NULL;
3174 if (!s) return(NULL);
3175 ret = (char *)malloc(strlen(s)+1);
3176 if (!ret) return(NULL);
3177 strcpy(ret,s);
3178 return(ret);
3180 #endif
3183 /****************************************************************************
3184 Signal handler for SIGPIPE (write on a disconnected socket)
3185 ****************************************************************************/
3186 void Abort(void )
3188 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3189 exit(2);
3192 /****************************************************************************
3193 get my own name and IP
3194 ****************************************************************************/
3195 BOOL get_myname(char *my_name,struct in_addr *ip)
3197 struct hostent *hp;
3198 pstring hostname;
3200 *hostname = 0;
3202 /* get my host name */
3203 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3205 DEBUG(0,("gethostname failed\n"));
3206 return False;
3209 /* get host info */
3210 if ((hp = Get_Hostbyname(hostname)) == 0)
3212 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3213 return False;
3216 if (my_name)
3218 /* split off any parts after an initial . */
3219 char *p = strchr(hostname,'.');
3220 if (p) *p = 0;
3222 fstrcpy(my_name,hostname);
3225 if (ip)
3226 putip((char *)ip,(char *)hp->h_addr);
3228 return(True);
3232 /****************************************************************************
3233 true if two IP addresses are equal
3234 ****************************************************************************/
3235 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3237 uint32 a1,a2;
3238 a1 = ntohl(ip1.s_addr);
3239 a2 = ntohl(ip2.s_addr);
3240 return(a1 == a2);
3244 /****************************************************************************
3245 open a socket of the specified type, port and address for incoming data
3246 ****************************************************************************/
3247 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3249 struct hostent *hp;
3250 struct sockaddr_in sock;
3251 pstring host_name;
3252 int res;
3254 /* get my host name */
3255 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3256 { DEBUG(0,("gethostname failed\n")); return -1; }
3258 /* get host info */
3259 if ((hp = Get_Hostbyname(host_name)) == 0)
3261 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3262 return -1;
3265 bzero((char *)&sock,sizeof(sock));
3266 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3267 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
3268 sock.sin_len = sizeof(sock);
3269 #endif
3270 sock.sin_port = htons( port );
3271 sock.sin_family = hp->h_addrtype;
3272 sock.sin_addr.s_addr = socket_addr;
3273 res = socket(hp->h_addrtype, type, 0);
3274 if (res == -1)
3275 { DEBUG(0,("socket failed\n")); return -1; }
3278 int one=1;
3279 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3282 /* now we've got a socket - we need to bind it */
3283 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3285 if (port) {
3286 if (port == SMB_PORT || port == NMB_PORT)
3287 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
3288 port,socket_addr,strerror(errno)));
3289 close(res);
3291 if (dlevel > 0 && port < 1000)
3292 port = 7999;
3294 if (port >= 1000 && port < 9000)
3295 return(open_socket_in(type,port+1,dlevel,socket_addr));
3298 return(-1);
3300 DEBUG(3,("bind succeeded on port %d\n",port));
3302 return res;
3306 /****************************************************************************
3307 create an outgoing socket
3308 **************************************************************************/
3309 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3311 struct sockaddr_in sock_out;
3312 int res,ret;
3313 int connect_loop = 250; /* 250 milliseconds */
3314 int loops = (timeout * 1000) / connect_loop;
3316 /* create a socket to write to */
3317 res = socket(PF_INET, type, 0);
3318 if (res == -1)
3319 { DEBUG(0,("socket error\n")); return -1; }
3321 if (type != SOCK_STREAM) return(res);
3323 bzero((char *)&sock_out,sizeof(sock_out));
3324 putip((char *)&sock_out.sin_addr,(char *)addr);
3326 sock_out.sin_port = htons( port );
3327 sock_out.sin_family = PF_INET;
3329 /* set it non-blocking */
3330 set_blocking(res,False);
3332 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3334 /* and connect it to the destination */
3335 connect_again:
3336 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3338 /* Some systems return EAGAIN when they mean EINPROGRESS */
3339 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3340 errno == EAGAIN) && loops--) {
3341 msleep(connect_loop);
3342 goto connect_again;
3345 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3346 errno == EAGAIN)) {
3347 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3348 close(res);
3349 return -1;
3352 #ifdef EISCONN
3353 if (ret < 0 && errno == EISCONN) {
3354 errno = 0;
3355 ret = 0;
3357 #endif
3359 if (ret < 0) {
3360 DEBUG(1,("error connecting to %s:%d (%s)\n",
3361 inet_ntoa(*addr),port,strerror(errno)));
3362 return -1;
3365 /* set it blocking again */
3366 set_blocking(res,True);
3368 return res;
3372 /****************************************************************************
3373 interpret a protocol description string, with a default
3374 ****************************************************************************/
3375 int interpret_protocol(char *str,int def)
3377 if (strequal(str,"NT1"))
3378 return(PROTOCOL_NT1);
3379 if (strequal(str,"LANMAN2"))
3380 return(PROTOCOL_LANMAN2);
3381 if (strequal(str,"LANMAN1"))
3382 return(PROTOCOL_LANMAN1);
3383 if (strequal(str,"CORE"))
3384 return(PROTOCOL_CORE);
3385 if (strequal(str,"COREPLUS"))
3386 return(PROTOCOL_COREPLUS);
3387 if (strequal(str,"CORE+"))
3388 return(PROTOCOL_COREPLUS);
3390 DEBUG(0,("Unrecognised protocol level %s\n",str));
3392 return(def);
3395 /****************************************************************************
3396 interpret a security level
3397 ****************************************************************************/
3398 int interpret_security(char *str,int def)
3400 if (strequal(str,"SERVER"))
3401 return(SEC_SERVER);
3402 if (strequal(str,"USER"))
3403 return(SEC_USER);
3404 if (strequal(str,"SHARE"))
3405 return(SEC_SHARE);
3407 DEBUG(0,("Unrecognised security level %s\n",str));
3409 return(def);
3413 /****************************************************************************
3414 interpret an internet address or name into an IP address in 4 byte form
3415 ****************************************************************************/
3416 uint32 interpret_addr(char *str)
3418 struct hostent *hp;
3419 uint32 res;
3420 int i;
3421 BOOL pure_address = True;
3423 if (strcmp(str,"0.0.0.0") == 0) return(0);
3424 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3426 for (i=0; pure_address && str[i]; i++)
3427 if (!(isdigit(str[i]) || str[i] == '.'))
3428 pure_address = False;
3430 /* if it's in the form of an IP address then get the lib to interpret it */
3431 if (pure_address) {
3432 res = inet_addr(str);
3433 } else {
3434 /* otherwise assume it's a network name of some sort and use
3435 Get_Hostbyname */
3436 if ((hp = Get_Hostbyname(str)) == 0) {
3437 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3438 return 0;
3440 if(hp->h_addr == NULL) {
3441 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
3442 return 0;
3444 putip((char *)&res,(char *)hp->h_addr);
3447 if (res == (uint32)-1) return(0);
3449 return(res);
3452 /*******************************************************************
3453 a convenient addition to interpret_addr()
3454 ******************************************************************/
3455 struct in_addr *interpret_addr2(char *str)
3457 static struct in_addr ret;
3458 uint32 a = interpret_addr(str);
3459 ret.s_addr = a;
3460 return(&ret);
3463 /*******************************************************************
3464 check if an IP is the 0.0.0.0
3465 ******************************************************************/
3466 BOOL zero_ip(struct in_addr ip)
3468 uint32 a;
3469 putip((char *)&a,(char *)&ip);
3470 return(a == 0);
3474 /*******************************************************************
3475 matchname - determine if host name matches IP address
3476 ******************************************************************/
3477 static BOOL matchname(char *remotehost,struct in_addr addr)
3479 struct hostent *hp;
3480 int i;
3482 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3483 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3484 return False;
3488 * Make sure that gethostbyname() returns the "correct" host name.
3489 * Unfortunately, gethostbyname("localhost") sometimes yields
3490 * "localhost.domain". Since the latter host name comes from the
3491 * local DNS, we just have to trust it (all bets are off if the local
3492 * DNS is perverted). We always check the address list, though.
3495 if (strcasecmp(remotehost, hp->h_name)
3496 && strcasecmp(remotehost, "localhost")) {
3497 DEBUG(0,("host name/name mismatch: %s != %s",
3498 remotehost, hp->h_name));
3499 return False;
3502 /* Look up the host address in the address list we just got. */
3503 for (i = 0; hp->h_addr_list[i]; i++) {
3504 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3505 return True;
3509 * The host name does not map to the original host address. Perhaps
3510 * someone has compromised a name server. More likely someone botched
3511 * it, but that could be dangerous, too.
3514 DEBUG(0,("host name/address mismatch: %s != %s",
3515 inet_ntoa(addr), hp->h_name));
3516 return False;
3519 /*******************************************************************
3520 Reset the 'done' variables so after a client process is created
3521 from a fork call these calls will be re-done. This should be
3522 expanded if more variables need reseting.
3523 ******************************************************************/
3525 static BOOL global_client_name_done = False;
3526 static BOOL global_client_addr_done = False;
3528 void reset_globals_after_fork()
3530 global_client_name_done = False;
3531 global_client_addr_done = False;
3534 /*******************************************************************
3535 return the DNS name of the client
3536 ******************************************************************/
3537 char *client_name(void)
3539 extern int Client;
3540 struct sockaddr sa;
3541 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3542 int length = sizeof(sa);
3543 static pstring name_buf;
3544 struct hostent *hp;
3546 if (global_client_name_done)
3547 return name_buf;
3549 strcpy(name_buf,"UNKNOWN");
3551 if (getpeername(Client, &sa, &length) < 0) {
3552 DEBUG(0,("getpeername failed\n"));
3553 return name_buf;
3556 /* Look up the remote host name. */
3557 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3558 sizeof(sockin->sin_addr),
3559 AF_INET)) == 0) {
3560 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3561 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3562 } else {
3563 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3564 if (!matchname(name_buf, sockin->sin_addr)) {
3565 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3566 strcpy(name_buf,"UNKNOWN");
3569 global_client_name_done = True;
3570 return name_buf;
3573 /*******************************************************************
3574 return the IP addr of the client as a string
3575 ******************************************************************/
3576 char *client_addr(void)
3578 extern int Client;
3579 struct sockaddr sa;
3580 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3581 int length = sizeof(sa);
3582 static fstring addr_buf;
3584 if (global_client_addr_done)
3585 return addr_buf;
3587 strcpy(addr_buf,"0.0.0.0");
3589 if (getpeername(Client, &sa, &length) < 0) {
3590 DEBUG(0,("getpeername failed\n"));
3591 return addr_buf;
3594 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3596 global_client_addr_done = True;
3597 return addr_buf;
3600 /*******************************************************************
3601 sub strings with useful parameters
3602 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3603 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3604 ********************************************************************/
3605 void standard_sub_basic(char *str)
3607 char *s, *p;
3608 char pidstr[10];
3609 struct passwd *pass;
3611 for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
3613 switch (*(p+1))
3615 case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3616 string_sub(p,"%G",gidtoname(pass->pw_gid));
3617 else
3618 p += 2;
3619 break;
3620 case 'I' : string_sub(p,"%I",client_addr()); break;
3621 case 'L' : string_sub(p,"%L",local_machine); break;
3622 case 'M' : string_sub(p,"%M",client_name()); break;
3623 case 'R' : string_sub(p,"%R",remote_proto); break;
3624 case 'T' : string_sub(p,"%T",timestring()); break;
3625 case 'U' : string_sub(p,"%U",sesssetup_user); break;
3626 case 'a' : string_sub(p,"%a",remote_arch); break;
3627 case 'd' : sprintf(pidstr,"%d",(int)getpid());
3628 string_sub(p,"%d",pidstr);
3629 break;
3630 case 'h' : string_sub(p,"%h",myhostname); break;
3631 case 'm' : string_sub(p,"%m",remote_machine); break;
3632 case 'v' : string_sub(p,"%v",VERSION); break;
3633 case '\0' : p++; break; /* don't run off end if last character is % */
3634 default : p+=2; break;
3637 return;
3640 /*******************************************************************
3641 are two IPs on the same subnet?
3642 ********************************************************************/
3643 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3645 uint32 net1,net2,nmask;
3647 nmask = ntohl(mask.s_addr);
3648 net1 = ntohl(ip1.s_addr);
3649 net2 = ntohl(ip2.s_addr);
3651 return((net1 & nmask) == (net2 & nmask));
3655 /*******************************************************************
3656 write a string in unicoode format
3657 ********************************************************************/
3658 int PutUniCode(char *dst,char *src)
3660 int ret = 0;
3661 while (*src) {
3662 dst[ret++] = src[0];
3663 dst[ret++] = 0;
3664 src++;
3666 dst[ret++]=0;
3667 dst[ret++]=0;
3668 return(ret);
3671 /****************************************************************************
3672 a wrapper for gethostbyname() that tries with all lower and all upper case
3673 if the initial name fails
3674 ****************************************************************************/
3675 struct hostent *Get_Hostbyname(char *name)
3677 char *name2 = strdup(name);
3678 struct hostent *ret;
3680 if (!name2)
3682 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3683 exit(0);
3686 if (!isalnum(*name2))
3688 free(name2);
3689 return(NULL);
3692 ret = sys_gethostbyname(name2);
3693 if (ret != NULL)
3695 free(name2);
3696 return(ret);
3699 /* try with all lowercase */
3700 strlower(name2);
3701 ret = sys_gethostbyname(name2);
3702 if (ret != NULL)
3704 free(name2);
3705 return(ret);
3708 /* try with all uppercase */
3709 strupper(name2);
3710 ret = sys_gethostbyname(name2);
3711 if (ret != NULL)
3713 free(name2);
3714 return(ret);
3717 /* nothing works :-( */
3718 free(name2);
3719 return(NULL);
3723 /****************************************************************************
3724 check if a process exists. Does this work on all unixes?
3725 ****************************************************************************/
3726 BOOL process_exists(int pid)
3728 #ifdef LINUX
3729 fstring s;
3730 sprintf(s,"/proc/%d",pid);
3731 return(directory_exist(s,NULL));
3732 #else
3734 static BOOL tested=False;
3735 static BOOL ok=False;
3736 fstring s;
3737 if (!tested) {
3738 tested = True;
3739 sprintf(s,"/proc/%05d",(int)getpid());
3740 ok = file_exist(s,NULL);
3742 if (ok) {
3743 sprintf(s,"/proc/%05d",pid);
3744 return(file_exist(s,NULL));
3748 /* CGH 8/16/96 - added ESRCH test */
3749 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3750 #endif
3754 /*******************************************************************
3755 turn a uid into a user name
3756 ********************************************************************/
3757 char *uidtoname(int uid)
3759 static char name[40];
3760 struct passwd *pass = getpwuid(uid);
3761 if (pass) return(pass->pw_name);
3762 sprintf(name,"%d",uid);
3763 return(name);
3766 /*******************************************************************
3767 turn a gid into a group name
3768 ********************************************************************/
3769 char *gidtoname(int gid)
3771 static char name[40];
3772 struct group *grp = getgrgid(gid);
3773 if (grp) return(grp->gr_name);
3774 sprintf(name,"%d",gid);
3775 return(name);
3778 /*******************************************************************
3779 block sigs
3780 ********************************************************************/
3781 void BlockSignals(BOOL block,int signum)
3783 #ifdef USE_SIGBLOCK
3784 int block_mask = sigmask(signum);
3785 static int oldmask = 0;
3786 if (block)
3787 oldmask = sigblock(block_mask);
3788 else
3789 sigsetmask(oldmask);
3790 #elif defined(USE_SIGPROCMASK)
3791 sigset_t set;
3792 sigemptyset(&set);
3793 sigaddset(&set,signum);
3794 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3795 #endif
3798 #if AJT
3799 /*******************************************************************
3800 my own panic function - not suitable for general use
3801 ********************************************************************/
3802 void ajt_panic(void)
3804 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3806 #endif
3808 #ifdef USE_DIRECT
3809 #define DIRECT direct
3810 #else
3811 #define DIRECT dirent
3812 #endif
3814 /*******************************************************************
3815 a readdir wrapper which just returns the file name
3816 also return the inode number if requested
3817 ********************************************************************/
3818 char *readdirname(void *p)
3820 struct DIRECT *ptr;
3821 char *dname;
3823 if (!p) return(NULL);
3825 ptr = (struct DIRECT *)readdir(p);
3826 if (!ptr) return(NULL);
3828 dname = ptr->d_name;
3830 #ifdef NEXT2
3831 if (telldir(p) < 0) return(NULL);
3832 #endif
3834 #ifdef SUNOS5
3835 /* this handles a broken compiler setup, causing a mixture
3836 of BSD and SYSV headers and libraries */
3838 static BOOL broken_readdir = False;
3839 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3841 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3842 broken_readdir = True;
3844 if (broken_readdir)
3845 dname = dname - 2;
3847 #endif
3850 static pstring buf;
3851 pstrcpy(buf, dname);
3852 unix_to_dos(buf, True);
3853 dname = buf;
3856 return(dname);
3859 /*******************************************************************
3860 Utility function used to decide if the last component
3861 of a path matches a (possibly wildcarded) entry in a namelist.
3862 ********************************************************************/
3864 BOOL is_in_path(char *name, name_compare_entry *namelist)
3866 pstring last_component;
3867 char *p;
3869 DEBUG(8, ("is_in_path: %s\n", name));
3871 /* if we have no list it's obviously not in the path */
3872 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3874 DEBUG(8,("is_in_path: no name list.\n"));
3875 return False;
3878 /* Get the last component of the unix name. */
3879 p = strrchr(name, '/');
3880 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3881 last_component[sizeof(last_component)-1] = '\0';
3883 for(; namelist->name != NULL; namelist++)
3885 if(namelist->is_wild)
3887 /* look for a wildcard match. */
3888 if (mask_match(last_component, namelist->name, case_sensitive, False))
3890 DEBUG(8,("is_in_path: mask match succeeded\n"));
3891 return True;
3894 else
3896 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3897 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3899 DEBUG(8,("is_in_path: match succeeded\n"));
3900 return True;
3904 DEBUG(8,("is_in_path: match not found\n"));
3906 return False;
3909 /*******************************************************************
3910 Strip a '/' separated list into an array of
3911 name_compare_enties structures suitable for
3912 passing to is_in_path(). We do this for
3913 speed so we can pre-parse all the names in the list
3914 and don't do it for each call to is_in_path().
3915 namelist is modified here and is assumed to be
3916 a copy owned by the caller.
3917 We also check if the entry contains a wildcard to
3918 remove a potentially expensive call to mask_match
3919 if possible.
3920 ********************************************************************/
3922 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3924 char *name_end;
3925 char *nameptr = namelist;
3926 int num_entries = 0;
3927 int i;
3929 (*ppname_array) = NULL;
3931 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3932 return;
3934 /* We need to make two passes over the string. The
3935 first to count the number of elements, the second
3936 to split it.
3938 while(*nameptr)
3940 if ( *nameptr == '/' )
3942 /* cope with multiple (useless) /s) */
3943 nameptr++;
3944 continue;
3946 /* find the next / */
3947 name_end = strchr(nameptr, '/');
3949 /* oops - the last check for a / didn't find one. */
3950 if (name_end == NULL)
3951 break;
3953 /* next segment please */
3954 nameptr = name_end + 1;
3955 num_entries++;
3958 if(num_entries == 0)
3959 return;
3961 if(( (*ppname_array) = (name_compare_entry *)malloc(
3962 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3964 DEBUG(0,("set_namearray: malloc fail\n"));
3965 return;
3968 /* Now copy out the names */
3969 nameptr = namelist;
3970 i = 0;
3971 while(*nameptr)
3973 if ( *nameptr == '/' )
3975 /* cope with multiple (useless) /s) */
3976 nameptr++;
3977 continue;
3979 /* find the next / */
3980 if ((name_end = strchr(nameptr, '/')) != NULL)
3982 *name_end = 0;
3985 /* oops - the last check for a / didn't find one. */
3986 if(name_end == NULL)
3987 break;
3989 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3990 (strchr( nameptr, '*')!=NULL));
3991 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3993 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3994 return;
3997 /* next segment please */
3998 nameptr = name_end + 1;
3999 i++;
4002 (*ppname_array)[i].name = NULL;
4004 return;
4007 /****************************************************************************
4008 routine to free a namearray.
4009 ****************************************************************************/
4011 void free_namearray(name_compare_entry *name_array)
4013 if(name_array == 0)
4014 return;
4016 if(name_array->name != NULL)
4017 free(name_array->name);
4019 free((char *)name_array);
4022 /****************************************************************************
4023 routine to do file locking
4024 ****************************************************************************/
4025 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4027 #if HAVE_FCNTL_LOCK
4028 struct flock lock;
4029 int ret;
4031 #if 1
4032 uint32 mask = 0xC0000000;
4034 /* make sure the count is reasonable, we might kill the lockd otherwise */
4035 count &= ~mask;
4037 /* the offset is often strange - remove 2 of its bits if either of
4038 the top two bits are set. Shift the top ones by two bits. This
4039 still allows OLE2 apps to operate, but should stop lockd from
4040 dieing */
4041 if ((offset & mask) != 0)
4042 offset = (offset & ~mask) | ((offset & mask) >> 2);
4043 #else
4044 uint32 mask = ((unsigned)1<<31);
4046 /* interpret negative counts as large numbers */
4047 if (count < 0)
4048 count &= ~mask;
4050 /* no negative offsets */
4051 offset &= ~mask;
4053 /* count + offset must be in range */
4054 while ((offset < 0 || (offset + count < 0)) && mask)
4056 offset &= ~mask;
4057 mask = mask >> 1;
4059 #endif
4062 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4064 lock.l_type = type;
4065 lock.l_whence = SEEK_SET;
4066 lock.l_start = (int)offset;
4067 lock.l_len = (int)count;
4068 lock.l_pid = 0;
4070 errno = 0;
4072 ret = fcntl(fd,op,&lock);
4074 if (errno != 0)
4075 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4077 /* a lock query */
4078 if (op == F_GETLK)
4080 if ((ret != -1) &&
4081 (lock.l_type != F_UNLCK) &&
4082 (lock.l_pid != 0) &&
4083 (lock.l_pid != getpid()))
4085 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4086 return(True);
4089 /* it must be not locked or locked by me */
4090 return(False);
4093 /* a lock set or unset */
4094 if (ret == -1)
4096 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4097 offset,count,op,type,strerror(errno)));
4099 /* perhaps it doesn't support this sort of locking?? */
4100 if (errno == EINVAL)
4102 DEBUG(3,("locking not supported? returning True\n"));
4103 return(True);
4106 return(False);
4109 /* everything went OK */
4110 DEBUG(8,("Lock call successful\n"));
4112 return(True);
4113 #else
4114 return(False);
4115 #endif
4118 /*******************************************************************
4119 lock a file - returning a open file descriptor or -1 on failure
4120 The timeout is in seconds. 0 means no timeout
4121 ********************************************************************/
4122 int file_lock(char *name,int timeout)
4124 int fd = open(name,O_RDWR|O_CREAT,0666);
4125 time_t t=0;
4126 if (fd < 0) return(-1);
4128 #if HAVE_FCNTL_LOCK
4129 if (timeout) t = time(NULL);
4130 while (!timeout || (time(NULL)-t < timeout)) {
4131 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4132 msleep(LOCK_RETRY_TIMEOUT);
4134 return(-1);
4135 #else
4136 return(fd);
4137 #endif
4140 /*******************************************************************
4141 unlock a file locked by file_lock
4142 ********************************************************************/
4143 void file_unlock(int fd)
4145 if (fd<0) return;
4146 #if HAVE_FCNTL_LOCK
4147 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4148 #endif
4149 close(fd);
4152 /*******************************************************************
4153 is the name specified one of my netbios names
4154 returns true is it is equal, false otherwise
4155 ********************************************************************/
4156 BOOL is_myname(char *s)
4158 int n;
4159 BOOL ret = False;
4161 for (n=0; my_netbios_names[n]; n++) {
4162 if (strequal(my_netbios_names[n], s))
4163 ret=True;
4165 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4166 return(ret);
4169 /*******************************************************************
4170 set the horrid remote_arch string based on an enum.
4171 ********************************************************************/
4172 void set_remote_arch(enum remote_arch_types type)
4174 ra_type = type;
4175 switch( type )
4177 case RA_WFWG:
4178 strcpy(remote_arch, "WfWg");
4179 return;
4180 case RA_OS2:
4181 strcpy(remote_arch, "OS2");
4182 return;
4183 case RA_WIN95:
4184 strcpy(remote_arch, "Win95");
4185 return;
4186 case RA_WINNT:
4187 strcpy(remote_arch, "WinNT");
4188 return;
4189 case RA_SAMBA:
4190 strcpy(remote_arch,"Samba");
4191 return;
4192 default:
4193 ra_type = RA_UNKNOWN;
4194 strcpy(remote_arch, "UNKNOWN");
4195 break;
4199 /*******************************************************************
4200 Get the remote_arch type.
4201 ********************************************************************/
4202 enum remote_arch_types get_remote_arch()
4204 return ra_type;
4208 /*******************************************************************
4209 skip past some unicode strings in a buffer
4210 ********************************************************************/
4211 char *skip_unicode_string(char *buf,int n)
4213 while (n--)
4215 while (*buf)
4216 buf += 2;
4217 buf += 2;
4219 return(buf);
4222 /*******************************************************************
4223 Return a ascii version of a unicode string
4224 Hack alert: uses fixed buffer(s) and only handles ascii strings
4225 ********************************************************************/
4226 #define MAXUNI 1024
4227 char *unistr2(uint16 *buf)
4229 static char lbufs[8][MAXUNI];
4230 static int nexti;
4231 char *lbuf = lbufs[nexti];
4232 char *p;
4233 nexti = (nexti+1)%8;
4234 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4236 *p = *buf;
4238 *p = 0;
4239 return lbuf;
4242 /*******************************************************************
4243 Return a ascii version of a unicode string
4244 Hack alert: uses fixed buffer(s) and only handles ascii strings
4245 ********************************************************************/
4246 #define MAXUNI 1024
4247 char *unistr(char *buf)
4249 static char lbufs[8][MAXUNI];
4250 static int nexti;
4251 char *lbuf = lbufs[nexti];
4252 char *p;
4254 nexti = (nexti+1)%8;
4256 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4258 *p = *buf;
4260 *p = 0;
4261 return lbuf;
4264 /*******************************************************************
4265 strncpy for unicode strings
4266 ********************************************************************/
4267 int unistrncpy(char *dst, char *src, int len)
4269 int num_wchars = 0;
4271 while (*src && len > 0)
4273 *dst++ = *src++;
4274 *dst++ = *src++;
4275 len--;
4276 num_wchars++;
4278 *dst++ = 0;
4279 *dst++ = 0;
4281 return num_wchars;
4285 /*******************************************************************
4286 strcpy for unicode strings. returns length (in num of wide chars)
4287 ********************************************************************/
4288 int unistrcpy(char *dst, char *src)
4290 int num_wchars = 0;
4292 while (*src)
4294 *dst++ = *src++;
4295 *dst++ = *src++;
4296 num_wchars++;
4298 *dst++ = 0;
4299 *dst++ = 0;
4301 return num_wchars;
4305 /*******************************************************************
4306 safe string copy into a fstring
4307 ********************************************************************/
4308 void fstrcpy(char *dest, char *src)
4310 int maxlength = sizeof(fstring) - 1;
4311 if (!dest) {
4312 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4313 return;
4316 if (!src) {
4317 *dest = 0;
4318 return;
4321 while (maxlength-- && *src)
4322 *dest++ = *src++;
4323 *dest = 0;
4324 if (*src) {
4325 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4326 strlen(src)));
4330 /*******************************************************************
4331 safe string copy into a pstring
4332 ********************************************************************/
4333 void pstrcpy(char *dest, char *src)
4335 int maxlength = sizeof(pstring) - 1;
4336 if (!dest) {
4337 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4338 return;
4341 if (!src) {
4342 *dest = 0;
4343 return;
4346 while (maxlength-- && *src)
4347 *dest++ = *src++;
4348 *dest = 0;
4349 if (*src) {
4350 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4351 strlen(src)));
4356 /*******************************************************************
4357 align a pointer to a multiple of 4 bytes
4358 ********************************************************************/
4359 char *align4(char *q, char *base)
4361 if ((q - base) & 3)
4363 q += 4 - ((q - base) & 3);
4365 return q;
4368 /*******************************************************************
4369 align a pointer to a multiple of 2 bytes
4370 ********************************************************************/
4371 char *align2(char *q, char *base)
4373 if ((q - base) & 1)
4375 q++;
4377 return q;
4380 /*******************************************************************
4381 align a pointer to a multiple of align_offset bytes. looks like it
4382 will work for offsets of 0, 2 and 4...
4383 ********************************************************************/
4384 char *align_offset(char *q, char *base, int align_offset_len)
4386 if (align_offset_len != 0 && ((q - base) & (align_offset_len-1)))
4388 q += align_offset_len - ((q - base) & (align_offset_len));
4390 return q;