Makefile: Changed for HPUX10 tidyup.
[Samba.git] / source / lib / util.c
blobca17fbdcb46dcf1531932e7ffda7bd42236e8c80
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 fstring remote_proto="UNKNOWN";
72 pstring myhostname="";
73 pstring user_socket_options="";
74 pstring sesssetup_user="";
75 pstring myname = "";
76 fstring myworkgroup = "";
77 char **my_netbios_names;
79 int smb_read_error = 0;
81 static BOOL stdout_logging = False;
83 static char *filename_dos(char *path,char *buf);
85 /*******************************************************************
86 get ready for syslog stuff
87 ******************************************************************/
88 void setup_logging(char *pname,BOOL interactive)
90 #ifdef SYSLOG
91 if (!interactive) {
92 char *p = strrchr(pname,'/');
93 if (p) pname = p+1;
94 openlog(pname, LOG_PID, LOG_DAEMON);
96 #endif
97 if (interactive) {
98 stdout_logging = True;
99 dbf = stdout;
104 BOOL append_log=False;
107 /****************************************************************************
108 reopen the log files
109 ****************************************************************************/
110 void reopen_logs(void)
112 extern FILE *dbf;
113 pstring fname;
115 if (DEBUGLEVEL > 0)
117 strcpy(fname,debugf);
118 if (lp_loaded() && (*lp_logfile()))
119 strcpy(fname,lp_logfile());
121 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
123 int oldumask = umask(022);
124 strcpy(debugf,fname);
125 if (dbf) fclose(dbf);
126 if (append_log)
127 dbf = fopen(debugf,"a");
128 else
129 dbf = fopen(debugf,"w");
130 if (dbf) setbuf(dbf,NULL);
131 umask(oldumask);
134 else
136 if (dbf)
138 fclose(dbf);
139 dbf = NULL;
145 /*******************************************************************
146 check if the log has grown too big
147 ********************************************************************/
148 static void check_log_size(void)
150 static int debug_count=0;
151 int maxlog;
152 struct stat st;
154 if (debug_count++ < 100) return;
156 maxlog = lp_max_log_size() * 1024;
157 if (!dbf || maxlog <= 0) return;
159 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
160 fclose(dbf); dbf = NULL;
161 reopen_logs();
162 if (dbf && file_size(debugf) > maxlog) {
163 pstring name;
164 fclose(dbf); dbf = NULL;
165 sprintf(name,"%s.old",debugf);
166 sys_rename(debugf,name);
167 reopen_logs();
170 debug_count=0;
174 /*******************************************************************
175 write an debug message on the debugfile. This is called by the DEBUG
176 macro
177 ********************************************************************/
178 #ifdef __STDC__
179 int Debug1(char *format_str, ...)
181 #else
182 int Debug1(va_alist)
183 va_dcl
185 char *format_str;
186 #endif
187 va_list ap;
189 if (stdout_logging) {
190 #ifdef __STDC__
191 va_start(ap, format_str);
192 #else
193 va_start(ap);
194 format_str = va_arg(ap,char *);
195 #endif
196 vfprintf(dbf,format_str,ap);
197 va_end(ap);
198 return(0);
201 #ifdef SYSLOG
202 if (!lp_syslog_only())
203 #endif
205 if (!dbf)
207 int oldumask = umask(022);
208 dbf = fopen(debugf,"w");
209 umask(oldumask);
210 if (dbf)
211 setbuf(dbf,NULL);
212 else
213 return(0);
217 #ifdef SYSLOG
218 if (syslog_level < lp_syslog())
221 * map debug levels to syslog() priorities
222 * note that not all DEBUG(0, ...) calls are
223 * necessarily errors
225 static int priority_map[] = {
226 LOG_ERR, /* 0 */
227 LOG_WARNING, /* 1 */
228 LOG_NOTICE, /* 2 */
229 LOG_INFO, /* 3 */
231 int priority;
232 pstring msgbuf;
234 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
235 syslog_level < 0)
236 priority = LOG_DEBUG;
237 else
238 priority = priority_map[syslog_level];
240 #ifdef __STDC__
241 va_start(ap, format_str);
242 #else
243 va_start(ap);
244 format_str = va_arg(ap,char *);
245 #endif
246 vsprintf(msgbuf, format_str, ap);
247 va_end(ap);
249 msgbuf[255] = '\0';
250 syslog(priority, "%s", msgbuf);
252 #endif
254 #ifdef SYSLOG
255 if (!lp_syslog_only())
256 #endif
258 #ifdef __STDC__
259 va_start(ap, format_str);
260 #else
261 va_start(ap);
262 format_str = va_arg(ap,char *);
263 #endif
264 vfprintf(dbf,format_str,ap);
265 va_end(ap);
266 fflush(dbf);
269 check_log_size();
271 return(0);
274 /****************************************************************************
275 find a suitable temporary directory. The result should be copied immediately
276 as it may be overwritten by a subsequent call
277 ****************************************************************************/
278 char *tmpdir(void)
280 char *p;
281 if ((p = getenv("TMPDIR"))) {
282 return p;
284 return "/tmp";
289 /****************************************************************************
290 determine if a file descriptor is in fact a socket
291 ****************************************************************************/
292 BOOL is_a_socket(int fd)
294 int v,l;
295 l = sizeof(int);
296 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
300 static char *last_ptr=NULL;
302 /****************************************************************************
303 Get the next token from a string, return False if none found
304 handles double-quotes.
305 Based on a routine by GJC@VILLAGE.COM.
306 Extensively modified by Andrew.Tridgell@anu.edu.au
307 ****************************************************************************/
308 BOOL next_token(char **ptr,char *buff,char *sep)
310 char *s;
311 BOOL quoted;
313 if (!ptr) ptr = &last_ptr;
314 if (!ptr) return(False);
316 s = *ptr;
318 /* default to simple separators */
319 if (!sep) sep = " \t\n\r";
321 /* find the first non sep char */
322 while(*s && strchr(sep,*s)) s++;
324 /* nothing left? */
325 if (! *s) return(False);
327 /* copy over the token */
328 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
330 if (*s == '\"')
331 quoted = !quoted;
332 else
333 *buff++ = *s;
336 *ptr = (*s) ? s+1 : s;
337 *buff = 0;
338 last_ptr = *ptr;
340 return(True);
343 /****************************************************************************
344 Convert list of tokens to array; dependent on above routine.
345 Uses last_ptr from above - bit of a hack.
346 ****************************************************************************/
347 char **toktocliplist(int *ctok, char *sep)
349 char *s=last_ptr;
350 int ictok=0;
351 char **ret, **iret;
353 if (!sep) sep = " \t\n\r";
355 while(*s && strchr(sep,*s)) s++;
357 /* nothing left? */
358 if (!*s) return(NULL);
360 do {
361 ictok++;
362 while(*s && (!strchr(sep,*s))) s++;
363 while(*s && strchr(sep,*s)) *s++=0;
364 } while(*s);
366 *ctok=ictok;
367 s=last_ptr;
369 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
371 while(ictok--) {
372 *iret++=s;
373 while(*s++);
374 while(!*s) s++;
377 return ret;
380 #ifndef HAVE_MEMMOVE
381 /*******************************************************************
382 safely copies memory, ensuring no overlap problems.
383 this is only used if the machine does not have it's own memmove().
384 this is not the fastest algorithm in town, but it will do for our
385 needs.
386 ********************************************************************/
387 void *MemMove(void *dest,void *src,int size)
389 unsigned long d,s;
390 int i;
391 if (dest==src || !size) return(dest);
393 d = (unsigned long)dest;
394 s = (unsigned long)src;
396 if ((d >= (s+size)) || (s >= (d+size))) {
397 /* no overlap */
398 memcpy(dest,src,size);
399 return(dest);
402 if (d < s)
404 /* we can forward copy */
405 if (s-d >= sizeof(int) &&
406 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
407 /* do it all as words */
408 int *idest = (int *)dest;
409 int *isrc = (int *)src;
410 size /= sizeof(int);
411 for (i=0;i<size;i++) idest[i] = isrc[i];
412 } else {
413 /* simplest */
414 char *cdest = (char *)dest;
415 char *csrc = (char *)src;
416 for (i=0;i<size;i++) cdest[i] = csrc[i];
419 else
421 /* must backward copy */
422 if (d-s >= sizeof(int) &&
423 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
424 /* do it all as words */
425 int *idest = (int *)dest;
426 int *isrc = (int *)src;
427 size /= sizeof(int);
428 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
429 } else {
430 /* simplest */
431 char *cdest = (char *)dest;
432 char *csrc = (char *)src;
433 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
436 return(dest);
438 #endif
441 /****************************************************************************
442 prompte a dptr (to make it recently used)
443 ****************************************************************************/
444 void array_promote(char *array,int elsize,int element)
446 char *p;
447 if (element == 0)
448 return;
450 p = (char *)malloc(elsize);
452 if (!p)
454 DEBUG(5,("Ahh! Can't malloc\n"));
455 return;
457 memcpy(p,array + element * elsize, elsize);
458 memmove(array + elsize,array,elsize*element);
459 memcpy(array,p,elsize);
460 free(p);
463 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
465 struct
467 char *name;
468 int level;
469 int option;
470 int value;
471 int opttype;
472 } socket_options[] = {
473 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
474 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
475 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
476 #ifdef TCP_NODELAY
477 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
478 #endif
479 #ifdef IPTOS_LOWDELAY
480 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
481 #endif
482 #ifdef IPTOS_THROUGHPUT
483 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
484 #endif
485 #ifdef SO_SNDBUF
486 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
487 #endif
488 #ifdef SO_RCVBUF
489 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
490 #endif
491 #ifdef SO_SNDLOWAT
492 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
493 #endif
494 #ifdef SO_RCVLOWAT
495 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
496 #endif
497 #ifdef SO_SNDTIMEO
498 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
499 #endif
500 #ifdef SO_RCVTIMEO
501 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
502 #endif
503 {NULL,0,0,0,0}};
507 /****************************************************************************
508 set user socket options
509 ****************************************************************************/
510 void set_socket_options(int fd, char *options)
512 string tok;
514 while (next_token(&options,tok," \t,"))
516 int ret=0,i;
517 int value = 1;
518 char *p;
519 BOOL got_value = False;
521 if ((p = strchr(tok,'=')))
523 *p = 0;
524 value = atoi(p+1);
525 got_value = True;
528 for (i=0;socket_options[i].name;i++)
529 if (strequal(socket_options[i].name,tok))
530 break;
532 if (!socket_options[i].name)
534 DEBUG(0,("Unknown socket option %s\n",tok));
535 continue;
538 switch (socket_options[i].opttype)
540 case OPT_BOOL:
541 case OPT_INT:
542 ret = setsockopt(fd,socket_options[i].level,
543 socket_options[i].option,(char *)&value,sizeof(int));
544 break;
546 case OPT_ON:
547 if (got_value)
548 DEBUG(0,("syntax error - %s does not take a value\n",tok));
551 int on = socket_options[i].value;
552 ret = setsockopt(fd,socket_options[i].level,
553 socket_options[i].option,(char *)&on,sizeof(int));
555 break;
558 if (ret != 0)
559 DEBUG(0,("Failed to set socket option %s\n",tok));
565 /****************************************************************************
566 close the socket communication
567 ****************************************************************************/
568 void close_sockets(void )
570 close(Client);
571 Client = 0;
574 /****************************************************************************
575 determine whether we are in the specified group
576 ****************************************************************************/
577 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
579 int i;
581 if (group == current_gid) return(True);
583 for (i=0;i<ngroups;i++)
584 if (group == groups[i])
585 return(True);
587 return(False);
590 /****************************************************************************
591 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
592 ****************************************************************************/
593 char *StrCpy(char *dest,char *src)
595 char *d = dest;
597 #if AJT
598 /* I don't want to get lazy with these ... */
599 if (!dest || !src) {
600 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
601 ajt_panic();
603 #endif
605 if (!dest) return(NULL);
606 if (!src) {
607 *dest = 0;
608 return(dest);
610 while ((*d++ = *src++)) ;
611 return(dest);
614 /****************************************************************************
615 line strncpy but always null terminates. Make sure there is room!
616 ****************************************************************************/
617 char *StrnCpy(char *dest,char *src,int n)
619 char *d = dest;
620 if (!dest) return(NULL);
621 if (!src) {
622 *dest = 0;
623 return(dest);
625 while (n-- && (*d++ = *src++)) ;
626 *d = 0;
627 return(dest);
631 /*******************************************************************
632 copy an IP address from one buffer to another
633 ********************************************************************/
634 void putip(void *dest,void *src)
636 memcpy(dest,src,4);
640 /****************************************************************************
641 interpret the weird netbios "name". Return the name type
642 ****************************************************************************/
643 static int name_interpret(char *in,char *out)
645 int ret;
646 int len = (*in++) / 2;
648 *out=0;
650 if (len > 30 || len<1) return(0);
652 while (len--)
654 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
655 *out = 0;
656 return(0);
658 *out = ((in[0]-'A')<<4) + (in[1]-'A');
659 in += 2;
660 out++;
662 *out = 0;
663 ret = out[-1];
665 #ifdef NETBIOS_SCOPE
666 /* Handle any scope names */
667 while(*in)
669 *out++ = '.'; /* Scope names are separated by periods */
670 len = *(unsigned char *)in++;
671 StrnCpy(out, in, len);
672 out += len;
673 *out=0;
674 in += len;
676 #endif
677 return(ret);
680 /****************************************************************************
681 mangle a name into netbios format
682 ****************************************************************************/
683 int name_mangle(char *In,char *Out,char name_type)
685 fstring name;
686 char buf[20];
687 char *in = (char *)&buf[0];
688 char *out = (char *)Out;
689 char *p, *label;
690 int i;
692 if (In[0] != '*') {
693 StrnCpy(name,In,sizeof(name)-1);
694 sprintf(buf,"%-15.15s%c",name,name_type);
695 } else {
696 buf[0]='*';
697 memset(&buf[1],0,16);
700 *out++ = 32;
701 for (i=0;i<16;i++) {
702 char c = toupper(in[i]);
703 out[i*2] = (c>>4) + 'A';
704 out[i*2+1] = (c & 0xF) + 'A';
706 out[32]=0;
707 out += 32;
709 label = scope;
710 while (*label)
712 p = strchr(label, '.');
713 if (p == 0)
714 p = label + strlen(label);
715 *out++ = p - label;
716 memcpy(out, label, p - label);
717 out += p - label;
718 label += p - label + (*p == '.');
720 *out = 0;
721 return(name_len(Out));
725 /*******************************************************************
726 check if a file exists
727 ********************************************************************/
728 BOOL file_exist(char *fname,struct stat *sbuf)
730 struct stat st;
731 if (!sbuf) sbuf = &st;
733 if (sys_stat(fname,sbuf) != 0)
734 return(False);
736 return(S_ISREG(sbuf->st_mode));
739 /*******************************************************************
740 check a files mod time
741 ********************************************************************/
742 time_t file_modtime(char *fname)
744 struct stat st;
746 if (sys_stat(fname,&st) != 0)
747 return(0);
749 return(st.st_mtime);
752 /*******************************************************************
753 check if a directory exists
754 ********************************************************************/
755 BOOL directory_exist(char *dname,struct stat *st)
757 struct stat st2;
758 if (!st) st = &st2;
760 if (sys_stat(dname,st) != 0)
761 return(False);
763 return(S_ISDIR(st->st_mode));
766 /*******************************************************************
767 returns the size in bytes of the named file
768 ********************************************************************/
769 uint32 file_size(char *file_name)
771 struct stat buf;
772 buf.st_size = 0;
773 sys_stat(file_name,&buf);
774 return(buf.st_size);
777 /*******************************************************************
778 return a string representing an attribute for a file
779 ********************************************************************/
780 char *attrib_string(int mode)
782 static char attrstr[10];
784 attrstr[0] = 0;
786 if (mode & aVOLID) strcat(attrstr,"V");
787 if (mode & aDIR) strcat(attrstr,"D");
788 if (mode & aARCH) strcat(attrstr,"A");
789 if (mode & aHIDDEN) strcat(attrstr,"H");
790 if (mode & aSYSTEM) strcat(attrstr,"S");
791 if (mode & aRONLY) strcat(attrstr,"R");
793 return(attrstr);
797 /*******************************************************************
798 case insensitive string compararison
799 ********************************************************************/
800 int StrCaseCmp(const char *s, const char *t)
802 /* compare until we run out of string, either t or s, or find a difference */
803 /* We *must* use toupper rather than tolower here due to the
804 asynchronous upper to lower mapping.
806 while (*s && *t && toupper(*s) == toupper(*t))
808 s++; t++;
811 return(toupper(*s) - toupper(*t));
814 /*******************************************************************
815 case insensitive string compararison, length limited
816 ********************************************************************/
817 int StrnCaseCmp(const char *s, const char *t, int n)
819 /* compare until we run out of string, either t or s, or chars */
820 /* We *must* use toupper rather than tolower here due to the
821 asynchronous upper to lower mapping.
823 while (n-- && *s && *t && toupper(*s) == toupper(*t))
825 s++; t++;
828 /* not run out of chars - strings are different lengths */
829 if (n) return(toupper(*s) - toupper(*t));
831 /* identical up to where we run out of chars, and strings are same length */
832 return(0);
835 /*******************************************************************
836 compare 2 strings
837 ********************************************************************/
838 BOOL strequal(const char *s1, const char *s2)
840 if (s1 == s2) return(True);
841 if (!s1 || !s2) return(False);
843 return(StrCaseCmp(s1,s2)==0);
846 /*******************************************************************
847 compare 2 strings up to and including the nth char.
848 ******************************************************************/
849 BOOL strnequal(const char *s1,const char *s2,int n)
851 if (s1 == s2) return(True);
852 if (!s1 || !s2 || !n) return(False);
854 return(StrnCaseCmp(s1,s2,n)==0);
857 /*******************************************************************
858 compare 2 strings (case sensitive)
859 ********************************************************************/
860 BOOL strcsequal(char *s1,char *s2)
862 if (s1 == s2) return(True);
863 if (!s1 || !s2) return(False);
865 return(strcmp(s1,s2)==0);
869 /*******************************************************************
870 convert a string to lower case
871 ********************************************************************/
872 void strlower(char *s)
874 while (*s)
876 #ifdef KANJI
877 if (is_shift_jis (*s)) {
878 s += 2;
879 } else if (is_kana (*s)) {
880 s++;
881 } else {
882 if (isupper(*s))
883 *s = tolower(*s);
884 s++;
886 #else
887 if (isupper(*s))
888 *s = tolower(*s);
889 s++;
890 #endif /* KANJI */
894 /*******************************************************************
895 convert a string to upper case
896 ********************************************************************/
897 void strupper(char *s)
899 while (*s)
901 #ifdef KANJI
902 if (is_shift_jis (*s)) {
903 s += 2;
904 } else if (is_kana (*s)) {
905 s++;
906 } else {
907 if (islower(*s))
908 *s = toupper(*s);
909 s++;
911 #else
912 if (islower(*s))
913 *s = toupper(*s);
914 s++;
915 #endif
919 /*******************************************************************
920 convert a string to "normal" form
921 ********************************************************************/
922 void strnorm(char *s)
924 if (case_default == CASE_UPPER)
925 strupper(s);
926 else
927 strlower(s);
930 /*******************************************************************
931 check if a string is in "normal" case
932 ********************************************************************/
933 BOOL strisnormal(char *s)
935 if (case_default == CASE_UPPER)
936 return(!strhaslower(s));
938 return(!strhasupper(s));
942 /****************************************************************************
943 string replace
944 ****************************************************************************/
945 void string_replace(char *s,char oldc,char newc)
947 while (*s)
949 #ifdef KANJI
950 if (is_shift_jis (*s)) {
951 s += 2;
952 } else if (is_kana (*s)) {
953 s++;
954 } else {
955 if (oldc == *s)
956 *s = newc;
957 s++;
959 #else
960 if (oldc == *s)
961 *s = newc;
962 s++;
963 #endif /* KANJI */
967 /****************************************************************************
968 make a file into unix format
969 ****************************************************************************/
970 void unix_format(char *fname)
972 pstring namecopy;
973 string_replace(fname,'\\','/');
975 if (*fname == '/')
977 strcpy(namecopy,fname);
978 strcpy(fname,".");
979 strcat(fname,namecopy);
983 /****************************************************************************
984 make a file into dos format
985 ****************************************************************************/
986 void dos_format(char *fname)
988 string_replace(fname,'/','\\');
992 /*******************************************************************
993 show a smb message structure
994 ********************************************************************/
995 void show_msg(char *buf)
997 int i;
998 int j;
999 int bcc=0;
1000 if (DEBUGLEVEL < 5)
1001 return;
1003 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1004 smb_len(buf),
1005 (int)CVAL(buf,smb_com),
1006 (int)CVAL(buf,smb_rcls),
1007 (int)CVAL(buf,smb_reh),
1008 (int)SVAL(buf,smb_err),
1009 (int)CVAL(buf,smb_flg),
1010 (int)SVAL(buf,smb_flg2)));
1011 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1012 (int)SVAL(buf,smb_tid),
1013 (int)SVAL(buf,smb_pid),
1014 (int)SVAL(buf,smb_uid),
1015 (int)SVAL(buf,smb_mid),
1016 (int)CVAL(buf,smb_wct)));
1017 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1018 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1019 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1020 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1021 DEBUG(5,("smb_bcc=%d\n",bcc));
1022 if (DEBUGLEVEL < 10)
1023 return;
1024 for (i = 0; i < MIN(bcc, 256); i += 16)
1026 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1029 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1030 if (j == 7) DEBUG(10, (" "));
1033 DEBUG(10,(" "));
1035 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1037 unsigned char c = CVAL(smb_buf(buf),i+j);
1038 if (c < 32 || c > 128) c = '.';
1039 DEBUG(10,("%c",c));
1041 if (j == 7) DEBUG(10, (" "));
1044 DEBUG(10,("\n"));
1048 /*******************************************************************
1049 return the length of an smb packet
1050 ********************************************************************/
1051 int smb_len(char *buf)
1053 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1056 /*******************************************************************
1057 set the length of an smb packet
1058 ********************************************************************/
1059 void _smb_setlen(char *buf,int len)
1061 buf[0] = 0;
1062 buf[1] = (len&0x10000)>>16;
1063 buf[2] = (len&0xFF00)>>8;
1064 buf[3] = len&0xFF;
1067 /*******************************************************************
1068 set the length and marker of an smb packet
1069 ********************************************************************/
1070 void smb_setlen(char *buf,int len)
1072 _smb_setlen(buf,len);
1074 CVAL(buf,4) = 0xFF;
1075 CVAL(buf,5) = 'S';
1076 CVAL(buf,6) = 'M';
1077 CVAL(buf,7) = 'B';
1080 /*******************************************************************
1081 setup the word count and byte count for a smb message
1082 ********************************************************************/
1083 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1085 if (zero)
1086 bzero(buf + smb_size,num_words*2 + num_bytes);
1087 CVAL(buf,smb_wct) = num_words;
1088 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1089 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1090 return (smb_size + num_words*2 + num_bytes);
1093 /*******************************************************************
1094 return the number of smb words
1095 ********************************************************************/
1096 int smb_numwords(char *buf)
1098 return (CVAL(buf,smb_wct));
1101 /*******************************************************************
1102 return the size of the smb_buf region of a message
1103 ********************************************************************/
1104 int smb_buflen(char *buf)
1106 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1109 /*******************************************************************
1110 return a pointer to the smb_buf data area
1111 ********************************************************************/
1112 int smb_buf_ofs(char *buf)
1114 return (smb_size + CVAL(buf,smb_wct)*2);
1117 /*******************************************************************
1118 return a pointer to the smb_buf data area
1119 ********************************************************************/
1120 char *smb_buf(char *buf)
1122 return (buf + smb_buf_ofs(buf));
1125 /*******************************************************************
1126 return the SMB offset into an SMB buffer
1127 ********************************************************************/
1128 int smb_offset(char *p,char *buf)
1130 return(PTR_DIFF(p,buf+4) + chain_size);
1134 /*******************************************************************
1135 skip past some strings in a buffer
1136 ********************************************************************/
1137 char *skip_string(char *buf,int n)
1139 while (n--)
1140 buf += strlen(buf) + 1;
1141 return(buf);
1144 /*******************************************************************
1145 trim the specified elements off the front and back of a string
1146 ********************************************************************/
1147 BOOL trim_string(char *s,char *front,char *back)
1149 BOOL ret = False;
1150 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1152 char *p = s;
1153 ret = True;
1154 while (1)
1156 if (!(*p = p[strlen(front)]))
1157 break;
1158 p++;
1161 while (back && *back && strlen(s) >= strlen(back) &&
1162 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1164 ret = True;
1165 s[strlen(s)-strlen(back)] = 0;
1167 return(ret);
1171 /*******************************************************************
1172 reduce a file name, removing .. elements.
1173 ********************************************************************/
1174 void dos_clean_name(char *s)
1176 char *p=NULL;
1178 DEBUG(3,("dos_clean_name [%s]\n",s));
1180 /* remove any double slashes */
1181 string_sub(s, "\\\\", "\\");
1183 while ((p = strstr(s,"\\..\\")) != NULL)
1185 pstring s1;
1187 *p = 0;
1188 strcpy(s1,p+3);
1190 if ((p=strrchr(s,'\\')) != NULL)
1191 *p = 0;
1192 else
1193 *s = 0;
1194 strcat(s,s1);
1197 trim_string(s,NULL,"\\..");
1199 string_sub(s, "\\.\\", "\\");
1202 /*******************************************************************
1203 reduce a file name, removing .. elements.
1204 ********************************************************************/
1205 void unix_clean_name(char *s)
1207 char *p=NULL;
1209 DEBUG(3,("unix_clean_name [%s]\n",s));
1211 /* remove any double slashes */
1212 string_sub(s, "//","/");
1214 /* Remove leading ./ characters */
1215 if(strncmp(s, "./", 2) == 0) {
1216 trim_string(s, "./", NULL);
1217 if(*s == 0)
1218 strcpy(s,"./");
1221 while ((p = strstr(s,"/../")) != NULL)
1223 pstring s1;
1225 *p = 0;
1226 strcpy(s1,p+3);
1228 if ((p=strrchr(s,'/')) != NULL)
1229 *p = 0;
1230 else
1231 *s = 0;
1232 strcat(s,s1);
1235 trim_string(s,NULL,"/..");
1239 /*******************************************************************
1240 a wrapper for the normal chdir() function
1241 ********************************************************************/
1242 int ChDir(char *path)
1244 int res;
1245 static pstring LastDir="";
1247 if (strcsequal(path,".")) return(0);
1249 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1250 DEBUG(3,("chdir to %s\n",path));
1251 res = sys_chdir(path);
1252 if (!res)
1253 strcpy(LastDir,path);
1254 return(res);
1258 /*******************************************************************
1259 return the absolute current directory path. A dumb version.
1260 ********************************************************************/
1261 static char *Dumb_GetWd(char *s)
1263 char *p;
1264 #ifdef USE_GETCWD
1265 p = (char *)getcwd(s,sizeof(pstring));
1266 #else
1267 p = (char *)getwd(s));
1268 #endif
1269 if(!p)
1270 return NULL;
1272 /* Ensure we always return in dos format. */
1273 unix_to_dos(p,True);
1274 return p;
1278 /* number of list structures for a caching GetWd function. */
1279 #define MAX_GETWDCACHE (50)
1281 struct
1283 ino_t inode;
1284 dev_t dev;
1285 char *text;
1286 BOOL valid;
1287 } ino_list[MAX_GETWDCACHE];
1289 BOOL use_getwd_cache=True;
1291 /*******************************************************************
1292 return the absolute current directory path
1293 ********************************************************************/
1294 char *GetWd(char *str)
1296 pstring s;
1297 static BOOL getwd_cache_init = False;
1298 struct stat st, st2;
1299 int i;
1301 *s = 0;
1303 if (!use_getwd_cache)
1304 return(Dumb_GetWd(str));
1306 /* init the cache */
1307 if (!getwd_cache_init)
1309 getwd_cache_init = True;
1310 for (i=0;i<MAX_GETWDCACHE;i++)
1312 string_init(&ino_list[i].text,"");
1313 ino_list[i].valid = False;
1317 /* Get the inode of the current directory, if this doesn't work we're
1318 in trouble :-) */
1320 if (stat(".",&st) == -1)
1322 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1323 return(Dumb_GetWd(str));
1327 for (i=0; i<MAX_GETWDCACHE; i++)
1328 if (ino_list[i].valid)
1331 /* If we have found an entry with a matching inode and dev number
1332 then find the inode number for the directory in the cached string.
1333 If this agrees with that returned by the stat for the current
1334 directory then all is o.k. (but make sure it is a directory all
1335 the same...) */
1337 if (st.st_ino == ino_list[i].inode &&
1338 st.st_dev == ino_list[i].dev)
1340 if (stat(ino_list[i].text,&st2) == 0)
1342 if (st.st_ino == st2.st_ino &&
1343 st.st_dev == st2.st_dev &&
1344 (st2.st_mode & S_IFMT) == S_IFDIR)
1346 strcpy (str, ino_list[i].text);
1348 /* promote it for future use */
1349 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1350 return (str);
1352 else
1354 /* If the inode is different then something's changed,
1355 scrub the entry and start from scratch. */
1356 ino_list[i].valid = False;
1363 /* We don't have the information to hand so rely on traditional methods.
1364 The very slow getcwd, which spawns a process on some systems, or the
1365 not quite so bad getwd. */
1367 if (!Dumb_GetWd(s))
1369 DEBUG(0,("Getwd failed, errno %d\n",errno));
1370 return (NULL);
1373 strcpy(str,s);
1375 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1377 /* add it to the cache */
1378 i = MAX_GETWDCACHE - 1;
1379 string_set(&ino_list[i].text,s);
1380 ino_list[i].dev = st.st_dev;
1381 ino_list[i].inode = st.st_ino;
1382 ino_list[i].valid = True;
1384 /* put it at the top of the list */
1385 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1387 return (str);
1392 /*******************************************************************
1393 reduce a file name, removing .. elements and checking that
1394 it is below dir in the heirachy. This uses GetWd() and so must be run
1395 on the system that has the referenced file system.
1397 widelinks are allowed if widelinks is true
1398 ********************************************************************/
1399 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1401 #ifndef REDUCE_PATHS
1402 return True;
1403 #else
1404 pstring dir2;
1405 pstring wd;
1406 pstring basename;
1407 pstring newname;
1408 char *p=NULL;
1409 BOOL relative = (*s != '/');
1411 *dir2 = *wd = *basename = *newname = 0;
1413 if (widelinks)
1415 unix_clean_name(s);
1416 /* can't have a leading .. */
1417 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1419 DEBUG(3,("Illegal file name? (%s)\n",s));
1420 return(False);
1423 if (strlen(s) == 0)
1424 strcpy(s,"./");
1426 return(True);
1429 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1431 /* remove any double slashes */
1432 string_sub(s,"//","/");
1434 strcpy(basename,s);
1435 p = strrchr(basename,'/');
1437 if (!p)
1438 return(True);
1440 if (!GetWd(wd))
1442 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1443 return(False);
1446 if (ChDir(dir) != 0)
1448 DEBUG(0,("couldn't chdir to %s\n",dir));
1449 return(False);
1452 if (!GetWd(dir2))
1454 DEBUG(0,("couldn't getwd for %s\n",dir));
1455 ChDir(wd);
1456 return(False);
1460 if (p && (p != basename))
1462 *p = 0;
1463 if (strcmp(p+1,".")==0)
1464 p[1]=0;
1465 if (strcmp(p+1,"..")==0)
1466 *p = '/';
1469 if (ChDir(basename) != 0)
1471 ChDir(wd);
1472 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1473 return(False);
1476 if (!GetWd(newname))
1478 ChDir(wd);
1479 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1480 return(False);
1483 if (p && (p != basename))
1485 strcat(newname,"/");
1486 strcat(newname,p+1);
1490 int l = strlen(dir2);
1491 if (dir2[l-1] == '/')
1492 l--;
1494 if (strncmp(newname,dir2,l) != 0)
1496 ChDir(wd);
1497 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1498 return(False);
1501 if (relative)
1503 if (newname[l] == '/')
1504 strcpy(s,newname + l + 1);
1505 else
1506 strcpy(s,newname+l);
1508 else
1509 strcpy(s,newname);
1512 ChDir(wd);
1514 if (strlen(s) == 0)
1515 strcpy(s,"./");
1517 DEBUG(3,("reduced to %s\n",s));
1518 return(True);
1519 #endif
1522 /****************************************************************************
1523 expand some *s
1524 ****************************************************************************/
1525 static void expand_one(char *Mask,int len)
1527 char *p1;
1528 while ((p1 = strchr(Mask,'*')) != NULL)
1530 int lfill = (len+1) - strlen(Mask);
1531 int l1= (p1 - Mask);
1532 pstring tmp;
1533 strcpy(tmp,Mask);
1534 memset(tmp+l1,'?',lfill);
1535 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1536 strcpy(Mask,tmp);
1540 /****************************************************************************
1541 expand a wildcard expression, replacing *s with ?s
1542 ****************************************************************************/
1543 void expand_mask(char *Mask,BOOL doext)
1545 pstring mbeg,mext;
1546 pstring dirpart;
1547 pstring filepart;
1548 BOOL hasdot = False;
1549 char *p1;
1550 BOOL absolute = (*Mask == '\\');
1552 *mbeg = *mext = *dirpart = *filepart = 0;
1554 /* parse the directory and filename */
1555 if (strchr(Mask,'\\'))
1556 dirname_dos(Mask,dirpart);
1558 filename_dos(Mask,filepart);
1560 strcpy(mbeg,filepart);
1561 if ((p1 = strchr(mbeg,'.')) != NULL)
1563 hasdot = True;
1564 *p1 = 0;
1565 p1++;
1566 strcpy(mext,p1);
1568 else
1570 strcpy(mext,"");
1571 if (strlen(mbeg) > 8)
1573 strcpy(mext,mbeg + 8);
1574 mbeg[8] = 0;
1578 if (*mbeg == 0)
1579 strcpy(mbeg,"????????");
1580 if ((*mext == 0) && doext && !hasdot)
1581 strcpy(mext,"???");
1583 if (strequal(mbeg,"*") && *mext==0)
1584 strcpy(mext,"*");
1586 /* expand *'s */
1587 expand_one(mbeg,8);
1588 if (*mext)
1589 expand_one(mext,3);
1591 strcpy(Mask,dirpart);
1592 if (*dirpart || absolute) strcat(Mask,"\\");
1593 strcat(Mask,mbeg);
1594 strcat(Mask,".");
1595 strcat(Mask,mext);
1597 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1601 /****************************************************************************
1602 does a string have any uppercase chars in it?
1603 ****************************************************************************/
1604 BOOL strhasupper(char *s)
1606 while (*s)
1608 #ifdef KANJI
1609 if (is_shift_jis (*s)) {
1610 s += 2;
1611 } else if (is_kana (*s)) {
1612 s++;
1613 } else {
1614 if (isupper(*s)) return(True);
1615 s++;
1617 #else
1618 if (isupper(*s)) return(True);
1619 s++;
1620 #endif /* KANJI */
1622 return(False);
1625 /****************************************************************************
1626 does a string have any lowercase chars in it?
1627 ****************************************************************************/
1628 BOOL strhaslower(char *s)
1630 while (*s)
1632 #ifdef KANJI
1633 if (is_shift_jis (*s)) {
1634 s += 2;
1635 } else if (is_kana (*s)) {
1636 s++;
1637 } else {
1638 if (islower(*s)) return(True);
1639 s++;
1641 #else
1642 if (islower(*s)) return(True);
1643 s++;
1644 #endif /* KANJI */
1646 return(False);
1649 /****************************************************************************
1650 find the number of chars in a string
1651 ****************************************************************************/
1652 int count_chars(char *s,char c)
1654 int count=0;
1655 while (*s)
1657 if (*s == c)
1658 count++;
1659 s++;
1661 return(count);
1665 /****************************************************************************
1666 make a dir struct
1667 ****************************************************************************/
1668 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1670 char *p;
1671 pstring mask2;
1673 strcpy(mask2,mask);
1675 if ((mode & aDIR) != 0)
1676 size = 0;
1678 memset(buf+1,' ',11);
1679 if ((p = strchr(mask2,'.')) != NULL)
1681 *p = 0;
1682 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1683 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1684 *p = '.';
1686 else
1687 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1689 bzero(buf+21,DIR_STRUCT_SIZE-21);
1690 CVAL(buf,21) = mode;
1691 put_dos_date(buf,22,date);
1692 SSVAL(buf,26,size & 0xFFFF);
1693 SSVAL(buf,28,size >> 16);
1694 StrnCpy(buf+30,fname,12);
1695 if (!case_sensitive)
1696 strupper(buf+30);
1697 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1701 /*******************************************************************
1702 close the low 3 fd's and open dev/null in their place
1703 ********************************************************************/
1704 void close_low_fds(void)
1706 int fd;
1707 int i;
1708 close(0); close(1); close(2);
1709 /* try and use up these file descriptors, so silly
1710 library routines writing to stdout etc won't cause havoc */
1711 for (i=0;i<3;i++) {
1712 fd = open("/dev/null",O_RDWR,0);
1713 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1714 if (fd < 0) {
1715 DEBUG(0,("Can't open /dev/null\n"));
1716 return;
1718 if (fd != i) {
1719 DEBUG(0,("Didn't get file descriptor %d\n",i));
1720 return;
1725 /****************************************************************************
1726 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1727 else
1728 if SYSV use O_NDELAY
1729 if BSD use FNDELAY
1730 ****************************************************************************/
1731 int set_blocking(int fd, BOOL set)
1733 int val;
1734 #ifdef O_NONBLOCK
1735 #define FLAG_TO_SET O_NONBLOCK
1736 #else
1737 #ifdef SYSV
1738 #define FLAG_TO_SET O_NDELAY
1739 #else /* BSD */
1740 #define FLAG_TO_SET FNDELAY
1741 #endif
1742 #endif
1744 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1745 return -1;
1746 if(set) /* Turn blocking on - ie. clear nonblock flag */
1747 val &= ~FLAG_TO_SET;
1748 else
1749 val |= FLAG_TO_SET;
1750 return fcntl( fd, F_SETFL, val);
1751 #undef FLAG_TO_SET
1755 /****************************************************************************
1756 write to a socket
1757 ****************************************************************************/
1758 int write_socket(int fd,char *buf,int len)
1760 int ret=0;
1762 if (passive)
1763 return(len);
1764 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1765 ret = write_data(fd,buf,len);
1767 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1768 return(ret);
1771 /****************************************************************************
1772 read from a socket
1773 ****************************************************************************/
1774 int read_udp_socket(int fd,char *buf,int len)
1776 int ret;
1777 struct sockaddr sock;
1778 int socklen;
1780 socklen = sizeof(sock);
1781 bzero((char *)&sock,socklen);
1782 bzero((char *)&lastip,sizeof(lastip));
1783 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1784 if (ret <= 0) {
1785 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1786 return(0);
1789 lastip = *(struct in_addr *) &sock.sa_data[2];
1790 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1792 return(ret);
1795 /****************************************************************************
1796 read data from a device with a timout in msec.
1797 mincount = if timeout, minimum to read before returning
1798 maxcount = number to be read.
1799 ****************************************************************************/
1800 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1802 fd_set fds;
1803 int selrtn;
1804 int readret;
1805 int nread = 0;
1806 struct timeval timeout;
1808 /* just checking .... */
1809 if (maxcnt <= 0) return(0);
1811 smb_read_error = 0;
1813 /* Blocking read */
1814 if (time_out <= 0) {
1815 if (mincnt == 0) mincnt = maxcnt;
1817 while (nread < mincnt) {
1818 readret = read(fd, buf + nread, maxcnt - nread);
1819 if (readret == 0) {
1820 smb_read_error = READ_EOF;
1821 return -1;
1824 if (readret == -1) {
1825 smb_read_error = READ_ERROR;
1826 return -1;
1828 nread += readret;
1830 return(nread);
1833 /* Most difficult - timeout read */
1834 /* If this is ever called on a disk file and
1835 mincnt is greater then the filesize then
1836 system performance will suffer severely as
1837 select always return true on disk files */
1839 /* Set initial timeout */
1840 timeout.tv_sec = time_out / 1000;
1841 timeout.tv_usec = 1000 * (time_out % 1000);
1843 for (nread=0; nread<mincnt; )
1845 FD_ZERO(&fds);
1846 FD_SET(fd,&fds);
1848 selrtn = sys_select(&fds,&timeout);
1850 /* Check if error */
1851 if(selrtn == -1) {
1852 /* something is wrong. Maybe the socket is dead? */
1853 smb_read_error = READ_ERROR;
1854 return -1;
1857 /* Did we timeout ? */
1858 if (selrtn == 0) {
1859 smb_read_error = READ_TIMEOUT;
1860 return -1;
1863 readret = read(fd, buf+nread, maxcnt-nread);
1864 if (readret == 0) {
1865 /* we got EOF on the file descriptor */
1866 smb_read_error = READ_EOF;
1867 return -1;
1870 if (readret == -1) {
1871 /* the descriptor is probably dead */
1872 smb_read_error = READ_ERROR;
1873 return -1;
1876 nread += readret;
1879 /* Return the number we got */
1880 return(nread);
1883 /****************************************************************************
1884 read data from the client. Maxtime is in milliseconds
1885 ****************************************************************************/
1886 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1888 fd_set fds;
1889 int selrtn;
1890 int nread;
1891 struct timeval timeout;
1893 FD_ZERO(&fds);
1894 FD_SET(fd,&fds);
1896 timeout.tv_sec = maxtime / 1000;
1897 timeout.tv_usec = (maxtime % 1000) * 1000;
1899 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1901 if (!FD_ISSET(fd,&fds))
1902 return 0;
1904 nread = read_udp_socket(fd, buffer, bufsize);
1906 /* return the number got */
1907 return(nread);
1910 /*******************************************************************
1911 find the difference in milliseconds between two struct timeval
1912 values
1913 ********************************************************************/
1914 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1916 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1917 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1920 /****************************************************************************
1921 send a keepalive packet (rfc1002)
1922 ****************************************************************************/
1923 BOOL send_keepalive(int client)
1925 unsigned char buf[4];
1927 buf[0] = 0x85;
1928 buf[1] = buf[2] = buf[3] = 0;
1930 return(write_data(client,(char *)buf,4) == 4);
1935 /****************************************************************************
1936 read data from the client, reading exactly N bytes.
1937 ****************************************************************************/
1938 int read_data(int fd,char *buffer,int N)
1940 int ret;
1941 int total=0;
1943 smb_read_error = 0;
1945 while (total < N)
1947 ret = read(fd,buffer + total,N - total);
1948 if (ret == 0) {
1949 smb_read_error = READ_EOF;
1950 return 0;
1952 if (ret == -1) {
1953 smb_read_error = READ_ERROR;
1954 return -1;
1956 total += ret;
1958 return total;
1962 /****************************************************************************
1963 write data to a fd
1964 ****************************************************************************/
1965 int write_data(int fd,char *buffer,int N)
1967 int total=0;
1968 int ret;
1970 while (total < N)
1972 ret = write(fd,buffer + total,N - total);
1974 if (ret == -1) return -1;
1975 if (ret == 0) return total;
1977 total += ret;
1979 return total;
1983 /****************************************************************************
1984 transfer some data between two fd's
1985 ****************************************************************************/
1986 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1988 static char *buf=NULL;
1989 static int size=0;
1990 char *buf1,*abuf;
1991 int total = 0;
1993 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1995 if (size == 0) {
1996 size = lp_readsize();
1997 size = MAX(size,1024);
2000 while (!buf && size>0) {
2001 buf = (char *)Realloc(buf,size+8);
2002 if (!buf) size /= 2;
2005 if (!buf) {
2006 DEBUG(0,("Can't allocate transfer buffer!\n"));
2007 exit(1);
2010 abuf = buf + (align%8);
2012 if (header)
2013 n += headlen;
2015 while (n > 0)
2017 int s = MIN(n,size);
2018 int ret,ret2=0;
2020 ret = 0;
2022 if (header && (headlen >= MIN(s,1024))) {
2023 buf1 = header;
2024 s = headlen;
2025 ret = headlen;
2026 headlen = 0;
2027 header = NULL;
2028 } else {
2029 buf1 = abuf;
2032 if (header && headlen > 0)
2034 ret = MIN(headlen,size);
2035 memcpy(buf1,header,ret);
2036 headlen -= ret;
2037 header += ret;
2038 if (headlen <= 0) header = NULL;
2041 if (s > ret)
2042 ret += read(infd,buf1+ret,s-ret);
2044 if (ret > 0)
2046 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2047 if (ret2 > 0) total += ret2;
2048 /* if we can't write then dump excess data */
2049 if (ret2 != ret)
2050 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2052 if (ret <= 0 || ret2 != ret)
2053 return(total);
2054 n -= ret;
2056 return(total);
2060 /****************************************************************************
2061 read 4 bytes of a smb packet and return the smb length of the packet
2062 possibly store the result in the buffer
2063 ****************************************************************************/
2064 int read_smb_length(int fd,char *inbuf,int timeout)
2066 char *buffer;
2067 char buf[4];
2068 int len=0, msg_type;
2069 BOOL ok=False;
2071 if (inbuf)
2072 buffer = inbuf;
2073 else
2074 buffer = buf;
2076 while (!ok)
2078 if (timeout > 0)
2079 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2080 else
2081 ok = (read_data(fd,buffer,4) == 4);
2083 if (!ok)
2084 return(-1);
2086 len = smb_len(buffer);
2087 msg_type = CVAL(buffer,0);
2089 if (msg_type == 0x85)
2091 DEBUG(5,("Got keepalive packet\n"));
2092 ok = False;
2096 DEBUG(10,("got smb length of %d\n",len));
2098 return(len);
2103 /****************************************************************************
2104 read an smb from a fd and return it's length
2105 The timeout is in milli seconds
2106 ****************************************************************************/
2107 BOOL receive_smb(int fd,char *buffer,int timeout)
2109 int len,ret;
2111 smb_read_error = 0;
2113 bzero(buffer,smb_size + 100);
2115 len = read_smb_length(fd,buffer,timeout);
2116 if (len == -1)
2117 return(False);
2119 if (len > BUFFER_SIZE) {
2120 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2121 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2122 exit(1);
2125 ret = read_data(fd,buffer+4,len);
2126 if (ret != len) {
2127 smb_read_error = READ_ERROR;
2128 return False;
2131 return(True);
2135 /****************************************************************************
2136 send an smb to a fd
2137 ****************************************************************************/
2138 BOOL send_smb(int fd,char *buffer)
2140 int len;
2141 int ret,nwritten=0;
2142 len = smb_len(buffer) + 4;
2144 while (nwritten < len)
2146 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2147 if (ret <= 0)
2149 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2150 close_sockets();
2151 exit(1);
2153 nwritten += ret;
2157 return True;
2161 /****************************************************************************
2162 find a pointer to a netbios name
2163 ****************************************************************************/
2164 char *name_ptr(char *buf,int ofs)
2166 unsigned char c = *(unsigned char *)(buf+ofs);
2168 if ((c & 0xC0) == 0xC0)
2170 uint16 l;
2171 char p[2];
2172 memcpy(p,buf+ofs,2);
2173 p[0] &= ~0xC0;
2174 l = RSVAL(p,0);
2175 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2176 return(buf + l);
2178 else
2179 return(buf+ofs);
2182 /****************************************************************************
2183 extract a netbios name from a buf
2184 ****************************************************************************/
2185 int name_extract(char *buf,int ofs,char *name)
2187 char *p = name_ptr(buf,ofs);
2188 int d = PTR_DIFF(p,buf+ofs);
2189 strcpy(name,"");
2190 if (d < -50 || d > 50) return(0);
2191 return(name_interpret(p,name));
2195 /****************************************************************************
2196 return the total storage length of a mangled name
2197 ****************************************************************************/
2198 int name_len(char *s)
2200 char *s0=s;
2201 unsigned char c = *(unsigned char *)s;
2202 if ((c & 0xC0) == 0xC0)
2203 return(2);
2204 while (*s) s += (*s)+1;
2205 return(PTR_DIFF(s,s0)+1);
2208 /****************************************************************************
2209 send a single packet to a port on another machine
2210 ****************************************************************************/
2211 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2213 BOOL ret;
2214 int out_fd;
2215 struct sockaddr_in sock_out;
2217 if (passive)
2218 return(True);
2220 /* create a socket to write to */
2221 out_fd = socket(AF_INET, type, 0);
2222 if (out_fd == -1)
2224 DEBUG(0,("socket failed"));
2225 return False;
2228 /* set the address and port */
2229 bzero((char *)&sock_out,sizeof(sock_out));
2230 putip((char *)&sock_out.sin_addr,(char *)&ip);
2231 sock_out.sin_port = htons( port );
2232 sock_out.sin_family = AF_INET;
2234 if (DEBUGLEVEL > 0)
2235 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2236 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2238 /* send it */
2239 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2241 if (!ret)
2242 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2243 inet_ntoa(ip),port,errno));
2245 close(out_fd);
2246 return(ret);
2249 /*******************************************************************
2250 sleep for a specified number of milliseconds
2251 ********************************************************************/
2252 void msleep(int t)
2254 int tdiff=0;
2255 struct timeval tval,t1,t2;
2256 fd_set fds;
2258 GetTimeOfDay(&t1);
2259 GetTimeOfDay(&t2);
2261 while (tdiff < t) {
2262 tval.tv_sec = (t-tdiff)/1000;
2263 tval.tv_usec = 1000*((t-tdiff)%1000);
2265 FD_ZERO(&fds);
2266 errno = 0;
2267 sys_select(&fds,&tval);
2269 GetTimeOfDay(&t2);
2270 tdiff = TvalDiff(&t1,&t2);
2274 /****************************************************************************
2275 check if a string is part of a list
2276 ****************************************************************************/
2277 BOOL in_list(char *s,char *list,BOOL casesensitive)
2279 pstring tok;
2280 char *p=list;
2282 if (!list) return(False);
2284 while (next_token(&p,tok,LIST_SEP))
2286 if (casesensitive) {
2287 if (strcmp(tok,s) == 0)
2288 return(True);
2289 } else {
2290 if (StrCaseCmp(tok,s) == 0)
2291 return(True);
2294 return(False);
2297 /* this is used to prevent lots of mallocs of size 1 */
2298 static char *null_string = NULL;
2300 /****************************************************************************
2301 set a string value, allocing the space for the string
2302 ****************************************************************************/
2303 BOOL string_init(char **dest,char *src)
2305 int l;
2306 if (!src)
2307 src = "";
2309 l = strlen(src);
2311 if (l == 0)
2313 if (!null_string)
2314 null_string = (char *)malloc(1);
2316 *null_string = 0;
2317 *dest = null_string;
2319 else
2321 *dest = (char *)malloc(l+1);
2322 strcpy(*dest,src);
2324 return(True);
2327 /****************************************************************************
2328 free a string value
2329 ****************************************************************************/
2330 void string_free(char **s)
2332 if (!s || !(*s)) return;
2333 if (*s == null_string)
2334 *s = NULL;
2335 if (*s) free(*s);
2336 *s = NULL;
2339 /****************************************************************************
2340 set a string value, allocing the space for the string, and deallocating any
2341 existing space
2342 ****************************************************************************/
2343 BOOL string_set(char **dest,char *src)
2345 string_free(dest);
2347 return(string_init(dest,src));
2350 /****************************************************************************
2351 substitute a string for a pattern in another string. Make sure there is
2352 enough room!
2354 This routine looks for pattern in s and replaces it with
2355 insert. It may do multiple replacements.
2357 return True if a substitution was done.
2358 ****************************************************************************/
2359 BOOL string_sub(char *s,char *pattern,char *insert)
2361 BOOL ret = False;
2362 char *p;
2363 int ls,lp,li;
2365 if (!insert || !pattern || !s) return(False);
2367 ls = strlen(s);
2368 lp = strlen(pattern);
2369 li = strlen(insert);
2371 if (!*pattern) return(False);
2373 while (lp <= ls && (p = strstr(s,pattern)))
2375 ret = True;
2376 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2377 memcpy(p,insert,li);
2378 s = p + li;
2379 ls = strlen(s);
2381 return(ret);
2386 /*********************************************************
2387 * Recursive routine that is called by mask_match.
2388 * Does the actual matching.
2389 *********************************************************/
2390 BOOL do_match(char *str, char *regexp, int case_sig)
2392 char *p;
2394 for( p = regexp; *p && *str; ) {
2395 switch(*p) {
2396 case '?':
2397 str++; p++;
2398 break;
2400 case '*':
2401 /* Look for a character matching
2402 the one after the '*' */
2403 p++;
2404 if(!*p)
2405 return True; /* Automatic match */
2406 while(*str) {
2407 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2408 str++;
2409 if(do_match(str,p,case_sig))
2410 return True;
2411 if(!*str)
2412 return False;
2413 else
2414 str++;
2416 return False;
2418 default:
2419 if(case_sig) {
2420 if(*str != *p)
2421 return False;
2422 } else {
2423 if(toupper(*str) != toupper(*p))
2424 return False;
2426 str++, p++;
2427 break;
2430 if(!*p && !*str)
2431 return True;
2433 if (!*p && str[0] == '.' && str[1] == 0)
2434 return(True);
2436 if (!*str && *p == '?')
2438 while (*p == '?') p++;
2439 return(!*p);
2442 if(!*str && (*p == '*' && p[1] == '\0'))
2443 return True;
2444 return False;
2448 /*********************************************************
2449 * Routine to match a given string with a regexp - uses
2450 * simplified regexp that takes * and ? only. Case can be
2451 * significant or not.
2452 *********************************************************/
2453 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2455 char *p;
2456 pstring p1, p2;
2457 fstring ebase,eext,sbase,sext;
2459 BOOL matched;
2461 /* Make local copies of str and regexp */
2462 StrnCpy(p1,regexp,sizeof(pstring)-1);
2463 StrnCpy(p2,str,sizeof(pstring)-1);
2465 if (!strchr(p2,'.')) {
2466 strcat(p2,".");
2470 if (!strchr(p1,'.')) {
2471 strcat(p1,".");
2475 #if 0
2476 if (strchr(p1,'.'))
2478 string_sub(p1,"*.*","*");
2479 string_sub(p1,".*","*");
2481 #endif
2483 /* Remove any *? and ** as they are meaningless */
2484 for(p = p1; *p; p++)
2485 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2486 (void)strcpy( &p[1], &p[2]);
2488 if (strequal(p1,"*")) return(True);
2490 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2492 if (trans2) {
2493 strcpy(ebase,p1);
2494 strcpy(sbase,p2);
2495 } else {
2496 if ((p=strrchr(p1,'.'))) {
2497 *p = 0;
2498 strcpy(ebase,p1);
2499 strcpy(eext,p+1);
2500 } else {
2501 strcpy(ebase,p1);
2502 eext[0] = 0;
2505 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2506 *p = 0;
2507 strcpy(sbase,p2);
2508 strcpy(sext,p+1);
2509 } else {
2510 strcpy(sbase,p2);
2511 strcpy(sext,"");
2515 matched = do_match(sbase,ebase,case_sig) &&
2516 (trans2 || do_match(sext,eext,case_sig));
2518 DEBUG(5,("mask_match returning %d\n", matched));
2520 return matched;
2525 /****************************************************************************
2526 become a daemon, discarding the controlling terminal
2527 ****************************************************************************/
2528 void become_daemon(void)
2530 #ifndef NO_FORK_DEBUG
2531 if (fork())
2532 exit(0);
2534 /* detach from the terminal */
2535 #ifdef USE_SETSID
2536 setsid();
2537 #else /* USE_SETSID */
2538 #ifdef TIOCNOTTY
2540 int i = open("/dev/tty", O_RDWR);
2541 if (i >= 0)
2543 ioctl(i, (int) TIOCNOTTY, (char *)0);
2544 close(i);
2547 #endif /* TIOCNOTTY */
2548 #endif /* USE_SETSID */
2549 /* Close fd's 0,1,2. Needed if started by rsh */
2550 close_low_fds();
2551 #endif /* NO_FORK_DEBUG */
2555 /****************************************************************************
2556 put up a yes/no prompt
2557 ****************************************************************************/
2558 BOOL yesno(char *p)
2560 pstring ans;
2561 printf("%s",p);
2563 if (!fgets(ans,sizeof(ans)-1,stdin))
2564 return(False);
2566 if (*ans == 'y' || *ans == 'Y')
2567 return(True);
2569 return(False);
2572 /****************************************************************************
2573 read a line from a file with possible \ continuation chars.
2574 Blanks at the start or end of a line are stripped.
2575 The string will be allocated if s2 is NULL
2576 ****************************************************************************/
2577 char *fgets_slash(char *s2,int maxlen,FILE *f)
2579 char *s=s2;
2580 int len = 0;
2581 int c;
2582 BOOL start_of_line = True;
2584 if (feof(f))
2585 return(NULL);
2587 if (!s2)
2589 maxlen = MIN(maxlen,8);
2590 s = (char *)Realloc(s,maxlen);
2593 if (!s || maxlen < 2) return(NULL);
2595 *s = 0;
2597 while (len < maxlen-1)
2599 c = getc(f);
2600 switch (c)
2602 case '\r':
2603 break;
2604 case '\n':
2605 while (len > 0 && s[len-1] == ' ')
2607 s[--len] = 0;
2609 if (len > 0 && s[len-1] == '\\')
2611 s[--len] = 0;
2612 start_of_line = True;
2613 break;
2615 return(s);
2616 case EOF:
2617 if (len <= 0 && !s2)
2618 free(s);
2619 return(len>0?s:NULL);
2620 case ' ':
2621 if (start_of_line)
2622 break;
2623 default:
2624 start_of_line = False;
2625 s[len++] = c;
2626 s[len] = 0;
2628 if (!s2 && len > maxlen-3)
2630 maxlen *= 2;
2631 s = (char *)Realloc(s,maxlen);
2632 if (!s) return(NULL);
2635 return(s);
2640 /****************************************************************************
2641 set the length of a file from a filedescriptor.
2642 Returns 0 on success, -1 on failure.
2643 ****************************************************************************/
2644 int set_filelen(int fd, long len)
2646 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2647 extend a file with ftruncate. Provide alternate implementation
2648 for this */
2650 #if FTRUNCATE_CAN_EXTEND
2651 return ftruncate(fd, len);
2652 #else
2653 struct stat st;
2654 char c = 0;
2655 long currpos = lseek(fd, 0L, SEEK_CUR);
2657 if(currpos < 0)
2658 return -1;
2659 /* Do an fstat to see if the file is longer than
2660 the requested size (call ftruncate),
2661 or shorter, in which case seek to len - 1 and write 1
2662 byte of zero */
2663 if(fstat(fd, &st)<0)
2664 return -1;
2666 #ifdef S_ISFIFO
2667 if (S_ISFIFO(st.st_mode)) return 0;
2668 #endif
2670 if(st.st_size == len)
2671 return 0;
2672 if(st.st_size > len)
2673 return ftruncate(fd, len);
2675 if(lseek(fd, len-1, SEEK_SET) != len -1)
2676 return -1;
2677 if(write(fd, &c, 1)!=1)
2678 return -1;
2679 /* Seek to where we were */
2680 lseek(fd, currpos, SEEK_SET);
2681 return 0;
2682 #endif
2686 /****************************************************************************
2687 return the byte checksum of some data
2688 ****************************************************************************/
2689 int byte_checksum(char *buf,int len)
2691 unsigned char *p = (unsigned char *)buf;
2692 int ret = 0;
2693 while (len--)
2694 ret += *p++;
2695 return(ret);
2700 #ifdef HPUX
2701 /****************************************************************************
2702 this is a version of setbuffer() for those machines that only have setvbuf
2703 ****************************************************************************/
2704 void setbuffer(FILE *f,char *buf,int bufsize)
2706 setvbuf(f,buf,_IOFBF,bufsize);
2708 #endif
2711 /****************************************************************************
2712 parse out a directory name from a path name. Assumes dos style filenames.
2713 ****************************************************************************/
2714 char *dirname_dos(char *path,char *buf)
2716 char *p = strrchr(path,'\\');
2718 if (!p)
2719 strcpy(buf,path);
2720 else
2722 *p = 0;
2723 strcpy(buf,path);
2724 *p = '\\';
2727 return(buf);
2731 /****************************************************************************
2732 parse out a filename from a path name. Assumes dos style filenames.
2733 ****************************************************************************/
2734 static char *filename_dos(char *path,char *buf)
2736 char *p = strrchr(path,'\\');
2738 if (!p)
2739 strcpy(buf,path);
2740 else
2741 strcpy(buf,p+1);
2743 return(buf);
2748 /****************************************************************************
2749 expand a pointer to be a particular size
2750 ****************************************************************************/
2751 void *Realloc(void *p,int size)
2753 void *ret=NULL;
2755 if (size == 0) {
2756 if (p) free(p);
2757 DEBUG(5,("Realloc asked for 0 bytes\n"));
2758 return NULL;
2761 if (!p)
2762 ret = (void *)malloc(size);
2763 else
2764 ret = (void *)realloc(p,size);
2766 if (!ret)
2767 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2769 return(ret);
2772 #ifdef NOSTRDUP
2773 /****************************************************************************
2774 duplicate a string
2775 ****************************************************************************/
2776 char *strdup(char *s)
2778 char *ret = NULL;
2779 if (!s) return(NULL);
2780 ret = (char *)malloc(strlen(s)+1);
2781 if (!ret) return(NULL);
2782 strcpy(ret,s);
2783 return(ret);
2785 #endif
2788 /****************************************************************************
2789 Signal handler for SIGPIPE (write on a disconnected socket)
2790 ****************************************************************************/
2791 void Abort(void )
2793 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2794 exit(2);
2797 /****************************************************************************
2798 get my own name and IP
2799 ****************************************************************************/
2800 BOOL get_myname(char *my_name,struct in_addr *ip)
2802 struct hostent *hp;
2803 pstring hostname;
2805 *hostname = 0;
2807 /* get my host name */
2808 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2810 DEBUG(0,("gethostname failed\n"));
2811 return False;
2814 /* get host info */
2815 if ((hp = Get_Hostbyname(hostname)) == 0)
2817 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2818 return False;
2821 if (my_name)
2823 /* split off any parts after an initial . */
2824 char *p = strchr(hostname,'.');
2825 if (p) *p = 0;
2827 strcpy(my_name,hostname);
2830 if (ip)
2831 putip((char *)ip,(char *)hp->h_addr);
2833 return(True);
2837 /****************************************************************************
2838 true if two IP addresses are equal
2839 ****************************************************************************/
2840 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2842 uint32 a1,a2;
2843 a1 = ntohl(ip1.s_addr);
2844 a2 = ntohl(ip2.s_addr);
2845 return(a1 == a2);
2849 /****************************************************************************
2850 open a socket of the specified type, port and address for incoming data
2851 ****************************************************************************/
2852 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2854 struct hostent *hp;
2855 struct sockaddr_in sock;
2856 pstring host_name;
2857 int res;
2859 /* get my host name */
2860 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2861 { DEBUG(0,("gethostname failed\n")); return -1; }
2863 /* get host info */
2864 if ((hp = Get_Hostbyname(host_name)) == 0)
2866 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2867 return -1;
2870 bzero((char *)&sock,sizeof(sock));
2871 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2872 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2873 sock.sin_len = sizeof(sock);
2874 #endif
2875 sock.sin_port = htons( port );
2876 sock.sin_family = hp->h_addrtype;
2877 sock.sin_addr.s_addr = socket_addr;
2878 res = socket(hp->h_addrtype, type, 0);
2879 if (res == -1)
2880 { DEBUG(0,("socket failed\n")); return -1; }
2883 int one=1;
2884 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2887 /* now we've got a socket - we need to bind it */
2888 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2890 if (port) {
2891 if (port == SMB_PORT || port == NMB_PORT)
2892 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2893 port,socket_addr,strerror(errno)));
2894 close(res);
2896 if (dlevel > 0 && port < 1000)
2897 port = 7999;
2899 if (port >= 1000 && port < 9000)
2900 return(open_socket_in(type,port+1,dlevel,socket_addr));
2903 return(-1);
2905 DEBUG(3,("bind succeeded on port %d\n",port));
2907 return res;
2911 /****************************************************************************
2912 create an outgoing socket
2913 **************************************************************************/
2914 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2916 struct sockaddr_in sock_out;
2917 int res,ret;
2918 int connect_loop = 250; /* 250 milliseconds */
2919 int loops = (timeout * 1000) / connect_loop;
2921 /* create a socket to write to */
2922 res = socket(PF_INET, type, 0);
2923 if (res == -1)
2924 { DEBUG(0,("socket error\n")); return -1; }
2926 if (type != SOCK_STREAM) return(res);
2928 bzero((char *)&sock_out,sizeof(sock_out));
2929 putip((char *)&sock_out.sin_addr,(char *)addr);
2931 sock_out.sin_port = htons( port );
2932 sock_out.sin_family = PF_INET;
2934 /* set it non-blocking */
2935 set_blocking(res,False);
2937 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2939 /* and connect it to the destination */
2940 connect_again:
2941 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2943 /* Some systems return EAGAIN when they mean EINPROGRESS */
2944 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2945 errno == EAGAIN) && loops--) {
2946 msleep(connect_loop);
2947 goto connect_again;
2950 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2951 errno == EAGAIN)) {
2952 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2953 close(res);
2954 return -1;
2957 #ifdef EISCONN
2958 if (ret < 0 && errno == EISCONN) {
2959 errno = 0;
2960 ret = 0;
2962 #endif
2964 if (ret < 0) {
2965 DEBUG(1,("error connecting to %s:%d (%s)\n",
2966 inet_ntoa(*addr),port,strerror(errno)));
2967 return -1;
2970 /* set it blocking again */
2971 set_blocking(res,True);
2973 return res;
2977 /****************************************************************************
2978 interpret a protocol description string, with a default
2979 ****************************************************************************/
2980 int interpret_protocol(char *str,int def)
2982 if (strequal(str,"NT1"))
2983 return(PROTOCOL_NT1);
2984 if (strequal(str,"LANMAN2"))
2985 return(PROTOCOL_LANMAN2);
2986 if (strequal(str,"LANMAN1"))
2987 return(PROTOCOL_LANMAN1);
2988 if (strequal(str,"CORE"))
2989 return(PROTOCOL_CORE);
2990 if (strequal(str,"COREPLUS"))
2991 return(PROTOCOL_COREPLUS);
2992 if (strequal(str,"CORE+"))
2993 return(PROTOCOL_COREPLUS);
2995 DEBUG(0,("Unrecognised protocol level %s\n",str));
2997 return(def);
3000 /****************************************************************************
3001 interpret a security level
3002 ****************************************************************************/
3003 int interpret_security(char *str,int def)
3005 if (strequal(str,"SERVER"))
3006 return(SEC_SERVER);
3007 if (strequal(str,"USER"))
3008 return(SEC_USER);
3009 if (strequal(str,"SHARE"))
3010 return(SEC_SHARE);
3012 DEBUG(0,("Unrecognised security level %s\n",str));
3014 return(def);
3018 /****************************************************************************
3019 interpret an internet address or name into an IP address in 4 byte form
3020 ****************************************************************************/
3021 uint32 interpret_addr(char *str)
3023 struct hostent *hp;
3024 uint32 res;
3025 int i;
3026 BOOL pure_address = True;
3028 if (strcmp(str,"0.0.0.0") == 0) return(0);
3029 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3031 for (i=0; pure_address && str[i]; i++)
3032 if (!(isdigit(str[i]) || str[i] == '.'))
3033 pure_address = False;
3035 /* if it's in the form of an IP address then get the lib to interpret it */
3036 if (pure_address) {
3037 res = inet_addr(str);
3038 } else {
3039 /* otherwise assume it's a network name of some sort and use
3040 Get_Hostbyname */
3041 if ((hp = Get_Hostbyname(str)) == 0) {
3042 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3043 return 0;
3045 putip((char *)&res,(char *)hp->h_addr);
3048 if (res == (uint32)-1) return(0);
3050 return(res);
3053 /*******************************************************************
3054 a convenient addition to interpret_addr()
3055 ******************************************************************/
3056 struct in_addr *interpret_addr2(char *str)
3058 static struct in_addr ret;
3059 uint32 a = interpret_addr(str);
3060 ret.s_addr = a;
3061 return(&ret);
3064 /*******************************************************************
3065 check if an IP is the 0.0.0.0
3066 ******************************************************************/
3067 BOOL zero_ip(struct in_addr ip)
3069 uint32 a;
3070 putip((char *)&a,(char *)&ip);
3071 return(a == 0);
3075 /*******************************************************************
3076 matchname - determine if host name matches IP address
3077 ******************************************************************/
3078 static BOOL matchname(char *remotehost,struct in_addr addr)
3080 struct hostent *hp;
3081 int i;
3083 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3084 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3085 return False;
3089 * Make sure that gethostbyname() returns the "correct" host name.
3090 * Unfortunately, gethostbyname("localhost") sometimes yields
3091 * "localhost.domain". Since the latter host name comes from the
3092 * local DNS, we just have to trust it (all bets are off if the local
3093 * DNS is perverted). We always check the address list, though.
3096 if (strcasecmp(remotehost, hp->h_name)
3097 && strcasecmp(remotehost, "localhost")) {
3098 DEBUG(0,("host name/name mismatch: %s != %s",
3099 remotehost, hp->h_name));
3100 return False;
3103 /* Look up the host address in the address list we just got. */
3104 for (i = 0; hp->h_addr_list[i]; i++) {
3105 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3106 return True;
3110 * The host name does not map to the original host address. Perhaps
3111 * someone has compromised a name server. More likely someone botched
3112 * it, but that could be dangerous, too.
3115 DEBUG(0,("host name/address mismatch: %s != %s",
3116 inet_ntoa(addr), hp->h_name));
3117 return False;
3120 /*******************************************************************
3121 Reset the 'done' variables so after a client process is created
3122 from a fork call these calls will be re-done. This should be
3123 expanded if more variables need reseting.
3124 ******************************************************************/
3126 static BOOL global_client_name_done = False;
3127 static BOOL global_client_addr_done = False;
3129 void reset_globals_after_fork()
3131 global_client_name_done = False;
3132 global_client_addr_done = False;
3135 /*******************************************************************
3136 return the DNS name of the client
3137 ******************************************************************/
3138 char *client_name(void)
3140 extern int Client;
3141 struct sockaddr sa;
3142 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3143 int length = sizeof(sa);
3144 static pstring name_buf;
3145 struct hostent *hp;
3147 if (global_client_name_done)
3148 return name_buf;
3150 strcpy(name_buf,"UNKNOWN");
3152 if (getpeername(Client, &sa, &length) < 0) {
3153 DEBUG(0,("getpeername failed\n"));
3154 return name_buf;
3157 /* Look up the remote host name. */
3158 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3159 sizeof(sockin->sin_addr),
3160 AF_INET)) == 0) {
3161 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3162 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3163 } else {
3164 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3165 if (!matchname(name_buf, sockin->sin_addr)) {
3166 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3167 strcpy(name_buf,"UNKNOWN");
3170 global_client_name_done = True;
3171 return name_buf;
3174 /*******************************************************************
3175 return the IP addr of the client as a string
3176 ******************************************************************/
3177 char *client_addr(void)
3179 extern int Client;
3180 struct sockaddr sa;
3181 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3182 int length = sizeof(sa);
3183 static fstring addr_buf;
3185 if (global_client_addr_done)
3186 return addr_buf;
3188 strcpy(addr_buf,"0.0.0.0");
3190 if (getpeername(Client, &sa, &length) < 0) {
3191 DEBUG(0,("getpeername failed\n"));
3192 return addr_buf;
3195 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3197 global_client_addr_done = True;
3198 return addr_buf;
3201 /*******************************************************************
3202 sub strings with useful parameters
3203 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3204 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3205 ********************************************************************/
3206 void standard_sub_basic(char *string)
3208 char *s, *p;
3209 char pidstr[10];
3210 struct passwd *pass;
3212 for (s = string ; (p = strchr(s,'%')) != NULL ; s = p )
3214 switch (*(p+1))
3216 case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3217 string_sub(p,"%G",gidtoname(pass->pw_gid));
3218 else
3219 p += 2;
3220 break;
3221 case 'I' : string_sub(p,"%I",client_addr()); break;
3222 case 'L' : string_sub(p,"%L",local_machine); break;
3223 case 'M' : string_sub(p,"%M",client_name()); break;
3224 case 'R' : string_sub(p,"%R",remote_proto); break;
3225 case 'T' : string_sub(p,"%T",timestring()); break;
3226 case 'U' : string_sub(p,"%U",sesssetup_user); break;
3227 case 'a' : string_sub(p,"%a",remote_arch); break;
3228 case 'd' : sprintf(pidstr,"%d",(int)getpid());
3229 string_sub(p,"%d",pidstr);
3230 break;
3231 case 'h' : string_sub(p,"%h",myhostname); break;
3232 case 'm' : string_sub(p,"%m",remote_machine); break;
3233 case 'v' : string_sub(p,"%v",VERSION); break;
3234 case '\0' : p++; break; /* don't run off end if last character is % */
3235 default : p+=2; break;
3238 return;
3241 /*******************************************************************
3242 are two IPs on the same subnet?
3243 ********************************************************************/
3244 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3246 uint32 net1,net2,nmask;
3248 nmask = ntohl(mask.s_addr);
3249 net1 = ntohl(ip1.s_addr);
3250 net2 = ntohl(ip2.s_addr);
3252 return((net1 & nmask) == (net2 & nmask));
3256 /*******************************************************************
3257 write a string in unicoode format
3258 ********************************************************************/
3259 int PutUniCode(char *dst,char *src)
3261 int ret = 0;
3262 while (*src) {
3263 dst[ret++] = src[0];
3264 dst[ret++] = 0;
3265 src++;
3267 dst[ret++]=0;
3268 dst[ret++]=0;
3269 return(ret);
3272 /****************************************************************************
3273 a wrapper for gethostbyname() that tries with all lower and all upper case
3274 if the initial name fails
3275 ****************************************************************************/
3276 struct hostent *Get_Hostbyname(char *name)
3278 char *name2 = strdup(name);
3279 struct hostent *ret;
3281 if (!name2)
3283 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3284 exit(0);
3287 if (!isalnum(*name2))
3289 free(name2);
3290 return(NULL);
3293 ret = sys_gethostbyname(name2);
3294 if (ret != NULL)
3296 free(name2);
3297 return(ret);
3300 /* try with all lowercase */
3301 strlower(name2);
3302 ret = sys_gethostbyname(name2);
3303 if (ret != NULL)
3305 free(name2);
3306 return(ret);
3309 /* try with all uppercase */
3310 strupper(name2);
3311 ret = sys_gethostbyname(name2);
3312 if (ret != NULL)
3314 free(name2);
3315 return(ret);
3318 /* nothing works :-( */
3319 free(name2);
3320 return(NULL);
3324 /****************************************************************************
3325 check if a process exists. Does this work on all unixes?
3326 ****************************************************************************/
3327 BOOL process_exists(int pid)
3329 #ifdef LINUX
3330 fstring s;
3331 sprintf(s,"/proc/%d",pid);
3332 return(directory_exist(s,NULL));
3333 #else
3335 static BOOL tested=False;
3336 static BOOL ok=False;
3337 fstring s;
3338 if (!tested) {
3339 tested = True;
3340 sprintf(s,"/proc/%05d",(int)getpid());
3341 ok = file_exist(s,NULL);
3343 if (ok) {
3344 sprintf(s,"/proc/%05d",pid);
3345 return(file_exist(s,NULL));
3349 /* CGH 8/16/96 - added ESRCH test */
3350 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3351 #endif
3355 /*******************************************************************
3356 turn a uid into a user name
3357 ********************************************************************/
3358 char *uidtoname(int uid)
3360 static char name[40];
3361 struct passwd *pass = getpwuid(uid);
3362 if (pass) return(pass->pw_name);
3363 sprintf(name,"%d",uid);
3364 return(name);
3367 /*******************************************************************
3368 turn a gid into a group name
3369 ********************************************************************/
3370 char *gidtoname(int gid)
3372 static char name[40];
3373 struct group *grp = getgrgid(gid);
3374 if (grp) return(grp->gr_name);
3375 sprintf(name,"%d",gid);
3376 return(name);
3379 /*******************************************************************
3380 block sigs
3381 ********************************************************************/
3382 void BlockSignals(BOOL block,int signum)
3384 #ifdef USE_SIGBLOCK
3385 int block_mask = sigmask(signum);
3386 static int oldmask = 0;
3387 if (block)
3388 oldmask = sigblock(block_mask);
3389 else
3390 sigsetmask(oldmask);
3391 #elif defined(USE_SIGPROCMASK)
3392 sigset_t set;
3393 sigemptyset(&set);
3394 sigaddset(&set,signum);
3395 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3396 #endif
3399 #if AJT
3400 /*******************************************************************
3401 my own panic function - not suitable for general use
3402 ********************************************************************/
3403 void ajt_panic(void)
3405 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3407 #endif
3409 #ifdef USE_DIRECT
3410 #define DIRECT direct
3411 #else
3412 #define DIRECT dirent
3413 #endif
3415 /*******************************************************************
3416 a readdir wrapper which just returns the file name
3417 also return the inode number if requested
3418 ********************************************************************/
3419 char *readdirname(void *p)
3421 struct DIRECT *ptr;
3422 char *dname;
3424 if (!p) return(NULL);
3426 ptr = (struct DIRECT *)readdir(p);
3427 if (!ptr) return(NULL);
3429 dname = ptr->d_name;
3431 #ifdef NEXT2
3432 if (telldir(p) < 0) return(NULL);
3433 #endif
3435 #ifdef SUNOS5
3436 /* this handles a broken compiler setup, causing a mixture
3437 of BSD and SYSV headers and libraries */
3439 static BOOL broken_readdir = False;
3440 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3442 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3443 broken_readdir = True;
3445 if (broken_readdir)
3446 dname = dname - 2;
3448 #endif
3451 static pstring buf;
3452 strcpy(buf, dname);
3453 unix_to_dos(buf, True);
3454 dname = buf;
3457 return(dname);
3461 * Utility function used to decide if the last component
3462 * of a path matches a (possibly wildcarded) entry in a namelist.
3465 BOOL is_in_path(char *name, name_compare_entry *namelist)
3467 pstring last_component;
3468 char *p;
3470 DEBUG(5, ("is_in_path: %s\n", name));
3472 /* if we have no list it's obviously not in the path */
3473 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3475 DEBUG(5,("is_in_path: no name list.\n"));
3476 return False;
3479 /* Get the last component of the unix name. */
3480 p = strrchr(name, '/');
3481 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3482 last_component[sizeof(last_component)-1] = '\0';
3484 for(; namelist->name != NULL; namelist++)
3486 if(namelist->is_wild)
3488 /* look for a wildcard match. */
3489 if (mask_match(last_component, namelist->name, case_sensitive, False))
3491 DEBUG(5,("is_in_path: mask match succeeded\n"));
3492 return True;
3495 else
3497 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3498 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3500 DEBUG(5,("is_in_path: match succeeded\n"));
3501 return True;
3505 DEBUG(5,("is_in_path: match not found\n"));
3507 return False;
3511 * Strip a '/' separated list into an array of
3512 * name_compare_enties structures suitable for
3513 * passing to is_in_path(). We do this for
3514 * speed so we can pre-parse all the names in the list
3515 * and don't do it for each call to is_in_path().
3516 * namelist is modified here and is assumed to be
3517 * a copy owned by the caller.
3518 * We also check if the entry contains a wildcard to
3519 * remove a potentially expensive call to mask_match
3520 * if possible.
3523 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3525 char *name_end;
3526 char *nameptr = namelist;
3527 int num_entries = 0;
3528 int i;
3530 (*ppname_array) = NULL;
3532 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3533 return;
3535 /* We need to make two passes over the string. The
3536 first to count the number of elements, the second
3537 to split it.
3539 while (*nameptr )
3541 if ( *nameptr == '/' )
3543 /* cope with multiple (useless) /s) */
3544 nameptr++;
3545 continue;
3547 /* find the next / */
3548 name_end = strchr(nameptr, '/');
3550 /* oops - the last check for a / didn't find one. */
3551 if (name_end == NULL)
3552 break;
3554 /* next segment please */
3555 nameptr = name_end + 1;
3556 num_entries++;
3559 if(num_entries == 0)
3560 return;
3562 if(( (*ppname_array) = (name_compare_entry *)malloc(
3563 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3565 DEBUG(0,("set_namearray: malloc fail\n"));
3566 return;
3569 /* Now copy out the names */
3570 nameptr = namelist;
3571 i = 0;
3572 while(*nameptr)
3574 if ( *nameptr == '/' )
3576 /* cope with multiple (useless) /s) */
3577 nameptr++;
3578 continue;
3580 /* find the next / */
3581 if ((name_end = strchr(nameptr, '/')) != NULL)
3583 *name_end = 0;
3586 /* oops - the last check for a / didn't find one. */
3587 if (name_end == NULL)
3588 break;
3590 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3591 (strchr( nameptr, '*')!=NULL));
3592 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3594 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3595 return;
3598 /* next segment please */
3599 nameptr = name_end + 1;
3600 i++;
3603 (*ppname_array)[i].name = NULL;
3605 return;
3608 /****************************************************************************
3609 routine to free a namearray.
3610 ****************************************************************************/
3612 void free_namearray(name_compare_entry *name_array)
3614 if(name_array == 0)
3615 return;
3617 if(name_array->name != NULL)
3618 free(name_array->name);
3620 free((char *)name_array);
3623 /****************************************************************************
3624 routine to do file locking
3625 ****************************************************************************/
3626 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3628 #if HAVE_FCNTL_LOCK
3629 struct flock lock;
3630 int ret;
3632 #if 1
3633 uint32 mask = 0xC0000000;
3635 /* make sure the count is reasonable, we might kill the lockd otherwise */
3636 count &= ~mask;
3638 /* the offset is often strange - remove 2 of its bits if either of
3639 the top two bits are set. Shift the top ones by two bits. This
3640 still allows OLE2 apps to operate, but should stop lockd from
3641 dieing */
3642 if ((offset & mask) != 0)
3643 offset = (offset & ~mask) | ((offset & mask) >> 2);
3644 #else
3645 uint32 mask = ((unsigned)1<<31);
3647 /* interpret negative counts as large numbers */
3648 if (count < 0)
3649 count &= ~mask;
3651 /* no negative offsets */
3652 offset &= ~mask;
3654 /* count + offset must be in range */
3655 while ((offset < 0 || (offset + count < 0)) && mask)
3657 offset &= ~mask;
3658 mask = mask >> 1;
3660 #endif
3663 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3665 lock.l_type = type;
3666 lock.l_whence = SEEK_SET;
3667 lock.l_start = (int)offset;
3668 lock.l_len = (int)count;
3669 lock.l_pid = 0;
3671 errno = 0;
3673 ret = fcntl(fd,op,&lock);
3675 if (errno != 0)
3676 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3678 /* a lock query */
3679 if (op == F_GETLK)
3681 if ((ret != -1) &&
3682 (lock.l_type != F_UNLCK) &&
3683 (lock.l_pid != 0) &&
3684 (lock.l_pid != getpid()))
3686 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3687 return(True);
3690 /* it must be not locked or locked by me */
3691 return(False);
3694 /* a lock set or unset */
3695 if (ret == -1)
3697 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3698 offset,count,op,type,strerror(errno)));
3700 /* perhaps it doesn't support this sort of locking?? */
3701 if (errno == EINVAL)
3703 DEBUG(3,("locking not supported? returning True\n"));
3704 return(True);
3707 return(False);
3710 /* everything went OK */
3711 DEBUG(5,("Lock call successful\n"));
3713 return(True);
3714 #else
3715 return(False);
3716 #endif
3719 /*******************************************************************
3720 lock a file - returning a open file descriptor or -1 on failure
3721 The timeout is in seconds. 0 means no timeout
3722 ********************************************************************/
3723 int file_lock(char *name,int timeout)
3725 int fd = open(name,O_RDWR|O_CREAT,0666);
3726 time_t t=0;
3727 if (fd < 0) return(-1);
3729 #if HAVE_FCNTL_LOCK
3730 if (timeout) t = time(NULL);
3731 while (!timeout || (time(NULL)-t < timeout)) {
3732 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3733 msleep(LOCK_RETRY_TIMEOUT);
3735 return(-1);
3736 #else
3737 return(fd);
3738 #endif
3741 /*******************************************************************
3742 unlock a file locked by file_lock
3743 ********************************************************************/
3744 void file_unlock(int fd)
3746 if (fd<0) return;
3747 #if HAVE_FCNTL_LOCK
3748 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3749 #endif
3750 close(fd);
3753 /*******************************************************************
3754 is the name specified one of my netbios names
3755 returns true is it is equal, false otherwise
3756 ********************************************************************/
3757 BOOL is_myname(const char *s)
3759 int n;
3760 BOOL ret = False;
3762 for (n=0; my_netbios_names[n]; n++) {
3763 if (strequal(my_netbios_names[n], s))
3764 ret=True;
3766 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
3767 return(ret);