Changes to allow Samba to return the same error code as Windows NT.
[Samba.git] / source / lib / util.c
bloba048c8b3a7555c67048e7cc252aafc44cce5035f
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 BOOL ret;
760 if (!st) st = &st2;
762 if (sys_stat(dname,st) != 0)
763 return(False);
765 ret = S_ISDIR(st->st_mode);
766 if(!ret)
767 errno = ENOTDIR;
768 return ret;
771 /*******************************************************************
772 returns the size in bytes of the named file
773 ********************************************************************/
774 uint32 file_size(char *file_name)
776 struct stat buf;
777 buf.st_size = 0;
778 sys_stat(file_name,&buf);
779 return(buf.st_size);
782 /*******************************************************************
783 return a string representing an attribute for a file
784 ********************************************************************/
785 char *attrib_string(int mode)
787 static char attrstr[10];
789 attrstr[0] = 0;
791 if (mode & aVOLID) strcat(attrstr,"V");
792 if (mode & aDIR) strcat(attrstr,"D");
793 if (mode & aARCH) strcat(attrstr,"A");
794 if (mode & aHIDDEN) strcat(attrstr,"H");
795 if (mode & aSYSTEM) strcat(attrstr,"S");
796 if (mode & aRONLY) strcat(attrstr,"R");
798 return(attrstr);
802 /*******************************************************************
803 case insensitive string compararison
804 ********************************************************************/
805 int StrCaseCmp(const char *s, const char *t)
807 /* compare until we run out of string, either t or s, or find a difference */
808 /* We *must* use toupper rather than tolower here due to the
809 asynchronous upper to lower mapping.
811 while (*s && *t && toupper(*s) == toupper(*t))
813 s++; t++;
816 return(toupper(*s) - toupper(*t));
819 /*******************************************************************
820 case insensitive string compararison, length limited
821 ********************************************************************/
822 int StrnCaseCmp(const char *s, const char *t, int n)
824 /* compare until we run out of string, either t or s, or chars */
825 /* We *must* use toupper rather than tolower here due to the
826 asynchronous upper to lower mapping.
828 while (n-- && *s && *t && toupper(*s) == toupper(*t))
830 s++; t++;
833 /* not run out of chars - strings are different lengths */
834 if (n) return(toupper(*s) - toupper(*t));
836 /* identical up to where we run out of chars, and strings are same length */
837 return(0);
840 /*******************************************************************
841 compare 2 strings
842 ********************************************************************/
843 BOOL strequal(const char *s1, const char *s2)
845 if (s1 == s2) return(True);
846 if (!s1 || !s2) return(False);
848 return(StrCaseCmp(s1,s2)==0);
851 /*******************************************************************
852 compare 2 strings up to and including the nth char.
853 ******************************************************************/
854 BOOL strnequal(const char *s1,const char *s2,int n)
856 if (s1 == s2) return(True);
857 if (!s1 || !s2 || !n) return(False);
859 return(StrnCaseCmp(s1,s2,n)==0);
862 /*******************************************************************
863 compare 2 strings (case sensitive)
864 ********************************************************************/
865 BOOL strcsequal(char *s1,char *s2)
867 if (s1 == s2) return(True);
868 if (!s1 || !s2) return(False);
870 return(strcmp(s1,s2)==0);
874 /*******************************************************************
875 convert a string to lower case
876 ********************************************************************/
877 void strlower(char *s)
879 while (*s)
881 #ifdef KANJI
882 if (is_shift_jis (*s)) {
883 s += 2;
884 } else if (is_kana (*s)) {
885 s++;
886 } else {
887 if (isupper(*s))
888 *s = tolower(*s);
889 s++;
891 #else
892 if (isupper(*s))
893 *s = tolower(*s);
894 s++;
895 #endif /* KANJI */
899 /*******************************************************************
900 convert a string to upper case
901 ********************************************************************/
902 void strupper(char *s)
904 while (*s)
906 #ifdef KANJI
907 if (is_shift_jis (*s)) {
908 s += 2;
909 } else if (is_kana (*s)) {
910 s++;
911 } else {
912 if (islower(*s))
913 *s = toupper(*s);
914 s++;
916 #else
917 if (islower(*s))
918 *s = toupper(*s);
919 s++;
920 #endif
924 /*******************************************************************
925 convert a string to "normal" form
926 ********************************************************************/
927 void strnorm(char *s)
929 if (case_default == CASE_UPPER)
930 strupper(s);
931 else
932 strlower(s);
935 /*******************************************************************
936 check if a string is in "normal" case
937 ********************************************************************/
938 BOOL strisnormal(char *s)
940 if (case_default == CASE_UPPER)
941 return(!strhaslower(s));
943 return(!strhasupper(s));
947 /****************************************************************************
948 string replace
949 ****************************************************************************/
950 void string_replace(char *s,char oldc,char newc)
952 while (*s)
954 #ifdef KANJI
955 if (is_shift_jis (*s)) {
956 s += 2;
957 } else if (is_kana (*s)) {
958 s++;
959 } else {
960 if (oldc == *s)
961 *s = newc;
962 s++;
964 #else
965 if (oldc == *s)
966 *s = newc;
967 s++;
968 #endif /* KANJI */
972 /****************************************************************************
973 make a file into unix format
974 ****************************************************************************/
975 void unix_format(char *fname)
977 pstring namecopy;
978 string_replace(fname,'\\','/');
980 if (*fname == '/')
982 strcpy(namecopy,fname);
983 strcpy(fname,".");
984 strcat(fname,namecopy);
988 /****************************************************************************
989 make a file into dos format
990 ****************************************************************************/
991 void dos_format(char *fname)
993 string_replace(fname,'/','\\');
997 /*******************************************************************
998 show a smb message structure
999 ********************************************************************/
1000 void show_msg(char *buf)
1002 int i;
1003 int j;
1004 int bcc=0;
1005 if (DEBUGLEVEL < 5)
1006 return;
1008 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1009 smb_len(buf),
1010 (int)CVAL(buf,smb_com),
1011 (int)CVAL(buf,smb_rcls),
1012 (int)CVAL(buf,smb_reh),
1013 (int)SVAL(buf,smb_err),
1014 (int)CVAL(buf,smb_flg),
1015 (int)SVAL(buf,smb_flg2)));
1016 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1017 (int)SVAL(buf,smb_tid),
1018 (int)SVAL(buf,smb_pid),
1019 (int)SVAL(buf,smb_uid),
1020 (int)SVAL(buf,smb_mid),
1021 (int)CVAL(buf,smb_wct)));
1022 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1023 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1024 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1025 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1026 DEBUG(5,("smb_bcc=%d\n",bcc));
1027 if (DEBUGLEVEL < 10)
1028 return;
1029 for (i = 0; i < MIN(bcc, 256); i += 16)
1031 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1034 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1035 if (j == 7) DEBUG(10, (" "));
1038 DEBUG(10,(" "));
1040 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1042 unsigned char c = CVAL(smb_buf(buf),i+j);
1043 if (c < 32 || c > 128) c = '.';
1044 DEBUG(10,("%c",c));
1046 if (j == 7) DEBUG(10, (" "));
1049 DEBUG(10,("\n"));
1053 /*******************************************************************
1054 return the length of an smb packet
1055 ********************************************************************/
1056 int smb_len(char *buf)
1058 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1061 /*******************************************************************
1062 set the length of an smb packet
1063 ********************************************************************/
1064 void _smb_setlen(char *buf,int len)
1066 buf[0] = 0;
1067 buf[1] = (len&0x10000)>>16;
1068 buf[2] = (len&0xFF00)>>8;
1069 buf[3] = len&0xFF;
1072 /*******************************************************************
1073 set the length and marker of an smb packet
1074 ********************************************************************/
1075 void smb_setlen(char *buf,int len)
1077 _smb_setlen(buf,len);
1079 CVAL(buf,4) = 0xFF;
1080 CVAL(buf,5) = 'S';
1081 CVAL(buf,6) = 'M';
1082 CVAL(buf,7) = 'B';
1085 /*******************************************************************
1086 setup the word count and byte count for a smb message
1087 ********************************************************************/
1088 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1090 if (zero)
1091 bzero(buf + smb_size,num_words*2 + num_bytes);
1092 CVAL(buf,smb_wct) = num_words;
1093 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1094 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1095 return (smb_size + num_words*2 + num_bytes);
1098 /*******************************************************************
1099 return the number of smb words
1100 ********************************************************************/
1101 int smb_numwords(char *buf)
1103 return (CVAL(buf,smb_wct));
1106 /*******************************************************************
1107 return the size of the smb_buf region of a message
1108 ********************************************************************/
1109 int smb_buflen(char *buf)
1111 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1114 /*******************************************************************
1115 return a pointer to the smb_buf data area
1116 ********************************************************************/
1117 int smb_buf_ofs(char *buf)
1119 return (smb_size + CVAL(buf,smb_wct)*2);
1122 /*******************************************************************
1123 return a pointer to the smb_buf data area
1124 ********************************************************************/
1125 char *smb_buf(char *buf)
1127 return (buf + smb_buf_ofs(buf));
1130 /*******************************************************************
1131 return the SMB offset into an SMB buffer
1132 ********************************************************************/
1133 int smb_offset(char *p,char *buf)
1135 return(PTR_DIFF(p,buf+4) + chain_size);
1139 /*******************************************************************
1140 skip past some strings in a buffer
1141 ********************************************************************/
1142 char *skip_string(char *buf,int n)
1144 while (n--)
1145 buf += strlen(buf) + 1;
1146 return(buf);
1149 /*******************************************************************
1150 trim the specified elements off the front and back of a string
1151 ********************************************************************/
1152 BOOL trim_string(char *s,char *front,char *back)
1154 BOOL ret = False;
1155 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1157 char *p = s;
1158 ret = True;
1159 while (1)
1161 if (!(*p = p[strlen(front)]))
1162 break;
1163 p++;
1166 while (back && *back && strlen(s) >= strlen(back) &&
1167 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1169 ret = True;
1170 s[strlen(s)-strlen(back)] = 0;
1172 return(ret);
1176 /*******************************************************************
1177 reduce a file name, removing .. elements.
1178 ********************************************************************/
1179 void dos_clean_name(char *s)
1181 char *p=NULL;
1183 DEBUG(3,("dos_clean_name [%s]\n",s));
1185 /* remove any double slashes */
1186 string_sub(s, "\\\\", "\\");
1188 while ((p = strstr(s,"\\..\\")) != NULL)
1190 pstring s1;
1192 *p = 0;
1193 strcpy(s1,p+3);
1195 if ((p=strrchr(s,'\\')) != NULL)
1196 *p = 0;
1197 else
1198 *s = 0;
1199 strcat(s,s1);
1202 trim_string(s,NULL,"\\..");
1204 string_sub(s, "\\.\\", "\\");
1207 /*******************************************************************
1208 reduce a file name, removing .. elements.
1209 ********************************************************************/
1210 void unix_clean_name(char *s)
1212 char *p=NULL;
1214 DEBUG(3,("unix_clean_name [%s]\n",s));
1216 /* remove any double slashes */
1217 string_sub(s, "//","/");
1219 /* Remove leading ./ characters */
1220 if(strncmp(s, "./", 2) == 0) {
1221 trim_string(s, "./", NULL);
1222 if(*s == 0)
1223 strcpy(s,"./");
1226 while ((p = strstr(s,"/../")) != NULL)
1228 pstring s1;
1230 *p = 0;
1231 strcpy(s1,p+3);
1233 if ((p=strrchr(s,'/')) != NULL)
1234 *p = 0;
1235 else
1236 *s = 0;
1237 strcat(s,s1);
1240 trim_string(s,NULL,"/..");
1244 /*******************************************************************
1245 a wrapper for the normal chdir() function
1246 ********************************************************************/
1247 int ChDir(char *path)
1249 int res;
1250 static pstring LastDir="";
1252 if (strcsequal(path,".")) return(0);
1254 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1255 DEBUG(3,("chdir to %s\n",path));
1256 res = sys_chdir(path);
1257 if (!res)
1258 strcpy(LastDir,path);
1259 return(res);
1263 /*******************************************************************
1264 return the absolute current directory path. A dumb version.
1265 ********************************************************************/
1266 static char *Dumb_GetWd(char *s)
1268 char *p;
1269 #ifdef USE_GETCWD
1270 p = (char *)getcwd(s,sizeof(pstring));
1271 #else
1272 p = (char *)getwd(s));
1273 #endif
1274 if(!p)
1275 return NULL;
1277 /* Ensure we always return in dos format. */
1278 unix_to_dos(p,True);
1279 return p;
1283 /* number of list structures for a caching GetWd function. */
1284 #define MAX_GETWDCACHE (50)
1286 struct
1288 ino_t inode;
1289 dev_t dev;
1290 char *text;
1291 BOOL valid;
1292 } ino_list[MAX_GETWDCACHE];
1294 BOOL use_getwd_cache=True;
1296 /*******************************************************************
1297 return the absolute current directory path
1298 ********************************************************************/
1299 char *GetWd(char *str)
1301 pstring s;
1302 static BOOL getwd_cache_init = False;
1303 struct stat st, st2;
1304 int i;
1306 *s = 0;
1308 if (!use_getwd_cache)
1309 return(Dumb_GetWd(str));
1311 /* init the cache */
1312 if (!getwd_cache_init)
1314 getwd_cache_init = True;
1315 for (i=0;i<MAX_GETWDCACHE;i++)
1317 string_init(&ino_list[i].text,"");
1318 ino_list[i].valid = False;
1322 /* Get the inode of the current directory, if this doesn't work we're
1323 in trouble :-) */
1325 if (stat(".",&st) == -1)
1327 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1328 return(Dumb_GetWd(str));
1332 for (i=0; i<MAX_GETWDCACHE; i++)
1333 if (ino_list[i].valid)
1336 /* If we have found an entry with a matching inode and dev number
1337 then find the inode number for the directory in the cached string.
1338 If this agrees with that returned by the stat for the current
1339 directory then all is o.k. (but make sure it is a directory all
1340 the same...) */
1342 if (st.st_ino == ino_list[i].inode &&
1343 st.st_dev == ino_list[i].dev)
1345 if (stat(ino_list[i].text,&st2) == 0)
1347 if (st.st_ino == st2.st_ino &&
1348 st.st_dev == st2.st_dev &&
1349 (st2.st_mode & S_IFMT) == S_IFDIR)
1351 strcpy (str, ino_list[i].text);
1353 /* promote it for future use */
1354 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1355 return (str);
1357 else
1359 /* If the inode is different then something's changed,
1360 scrub the entry and start from scratch. */
1361 ino_list[i].valid = False;
1368 /* We don't have the information to hand so rely on traditional methods.
1369 The very slow getcwd, which spawns a process on some systems, or the
1370 not quite so bad getwd. */
1372 if (!Dumb_GetWd(s))
1374 DEBUG(0,("Getwd failed, errno %d\n",errno));
1375 return (NULL);
1378 strcpy(str,s);
1380 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1382 /* add it to the cache */
1383 i = MAX_GETWDCACHE - 1;
1384 string_set(&ino_list[i].text,s);
1385 ino_list[i].dev = st.st_dev;
1386 ino_list[i].inode = st.st_ino;
1387 ino_list[i].valid = True;
1389 /* put it at the top of the list */
1390 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1392 return (str);
1397 /*******************************************************************
1398 reduce a file name, removing .. elements and checking that
1399 it is below dir in the heirachy. This uses GetWd() and so must be run
1400 on the system that has the referenced file system.
1402 widelinks are allowed if widelinks is true
1403 ********************************************************************/
1404 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1406 #ifndef REDUCE_PATHS
1407 return True;
1408 #else
1409 pstring dir2;
1410 pstring wd;
1411 pstring basename;
1412 pstring newname;
1413 char *p=NULL;
1414 BOOL relative = (*s != '/');
1416 *dir2 = *wd = *basename = *newname = 0;
1418 if (widelinks)
1420 unix_clean_name(s);
1421 /* can't have a leading .. */
1422 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1424 DEBUG(3,("Illegal file name? (%s)\n",s));
1425 return(False);
1428 if (strlen(s) == 0)
1429 strcpy(s,"./");
1431 return(True);
1434 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1436 /* remove any double slashes */
1437 string_sub(s,"//","/");
1439 strcpy(basename,s);
1440 p = strrchr(basename,'/');
1442 if (!p)
1443 return(True);
1445 if (!GetWd(wd))
1447 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1448 return(False);
1451 if (ChDir(dir) != 0)
1453 DEBUG(0,("couldn't chdir to %s\n",dir));
1454 return(False);
1457 if (!GetWd(dir2))
1459 DEBUG(0,("couldn't getwd for %s\n",dir));
1460 ChDir(wd);
1461 return(False);
1465 if (p && (p != basename))
1467 *p = 0;
1468 if (strcmp(p+1,".")==0)
1469 p[1]=0;
1470 if (strcmp(p+1,"..")==0)
1471 *p = '/';
1474 if (ChDir(basename) != 0)
1476 ChDir(wd);
1477 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1478 return(False);
1481 if (!GetWd(newname))
1483 ChDir(wd);
1484 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1485 return(False);
1488 if (p && (p != basename))
1490 strcat(newname,"/");
1491 strcat(newname,p+1);
1495 int l = strlen(dir2);
1496 if (dir2[l-1] == '/')
1497 l--;
1499 if (strncmp(newname,dir2,l) != 0)
1501 ChDir(wd);
1502 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1503 return(False);
1506 if (relative)
1508 if (newname[l] == '/')
1509 strcpy(s,newname + l + 1);
1510 else
1511 strcpy(s,newname+l);
1513 else
1514 strcpy(s,newname);
1517 ChDir(wd);
1519 if (strlen(s) == 0)
1520 strcpy(s,"./");
1522 DEBUG(3,("reduced to %s\n",s));
1523 return(True);
1524 #endif
1527 /****************************************************************************
1528 expand some *s
1529 ****************************************************************************/
1530 static void expand_one(char *Mask,int len)
1532 char *p1;
1533 while ((p1 = strchr(Mask,'*')) != NULL)
1535 int lfill = (len+1) - strlen(Mask);
1536 int l1= (p1 - Mask);
1537 pstring tmp;
1538 strcpy(tmp,Mask);
1539 memset(tmp+l1,'?',lfill);
1540 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1541 strcpy(Mask,tmp);
1545 /****************************************************************************
1546 expand a wildcard expression, replacing *s with ?s
1547 ****************************************************************************/
1548 void expand_mask(char *Mask,BOOL doext)
1550 pstring mbeg,mext;
1551 pstring dirpart;
1552 pstring filepart;
1553 BOOL hasdot = False;
1554 char *p1;
1555 BOOL absolute = (*Mask == '\\');
1557 *mbeg = *mext = *dirpart = *filepart = 0;
1559 /* parse the directory and filename */
1560 if (strchr(Mask,'\\'))
1561 dirname_dos(Mask,dirpart);
1563 filename_dos(Mask,filepart);
1565 strcpy(mbeg,filepart);
1566 if ((p1 = strchr(mbeg,'.')) != NULL)
1568 hasdot = True;
1569 *p1 = 0;
1570 p1++;
1571 strcpy(mext,p1);
1573 else
1575 strcpy(mext,"");
1576 if (strlen(mbeg) > 8)
1578 strcpy(mext,mbeg + 8);
1579 mbeg[8] = 0;
1583 if (*mbeg == 0)
1584 strcpy(mbeg,"????????");
1585 if ((*mext == 0) && doext && !hasdot)
1586 strcpy(mext,"???");
1588 if (strequal(mbeg,"*") && *mext==0)
1589 strcpy(mext,"*");
1591 /* expand *'s */
1592 expand_one(mbeg,8);
1593 if (*mext)
1594 expand_one(mext,3);
1596 strcpy(Mask,dirpart);
1597 if (*dirpart || absolute) strcat(Mask,"\\");
1598 strcat(Mask,mbeg);
1599 strcat(Mask,".");
1600 strcat(Mask,mext);
1602 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1606 /****************************************************************************
1607 does a string have any uppercase chars in it?
1608 ****************************************************************************/
1609 BOOL strhasupper(char *s)
1611 while (*s)
1613 #ifdef KANJI
1614 if (is_shift_jis (*s)) {
1615 s += 2;
1616 } else if (is_kana (*s)) {
1617 s++;
1618 } else {
1619 if (isupper(*s)) return(True);
1620 s++;
1622 #else
1623 if (isupper(*s)) return(True);
1624 s++;
1625 #endif /* KANJI */
1627 return(False);
1630 /****************************************************************************
1631 does a string have any lowercase chars in it?
1632 ****************************************************************************/
1633 BOOL strhaslower(char *s)
1635 while (*s)
1637 #ifdef KANJI
1638 if (is_shift_jis (*s)) {
1639 s += 2;
1640 } else if (is_kana (*s)) {
1641 s++;
1642 } else {
1643 if (islower(*s)) return(True);
1644 s++;
1646 #else
1647 if (islower(*s)) return(True);
1648 s++;
1649 #endif /* KANJI */
1651 return(False);
1654 /****************************************************************************
1655 find the number of chars in a string
1656 ****************************************************************************/
1657 int count_chars(char *s,char c)
1659 int count=0;
1660 while (*s)
1662 if (*s == c)
1663 count++;
1664 s++;
1666 return(count);
1670 /****************************************************************************
1671 make a dir struct
1672 ****************************************************************************/
1673 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1675 char *p;
1676 pstring mask2;
1678 strcpy(mask2,mask);
1680 if ((mode & aDIR) != 0)
1681 size = 0;
1683 memset(buf+1,' ',11);
1684 if ((p = strchr(mask2,'.')) != NULL)
1686 *p = 0;
1687 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1688 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1689 *p = '.';
1691 else
1692 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1694 bzero(buf+21,DIR_STRUCT_SIZE-21);
1695 CVAL(buf,21) = mode;
1696 put_dos_date(buf,22,date);
1697 SSVAL(buf,26,size & 0xFFFF);
1698 SSVAL(buf,28,size >> 16);
1699 StrnCpy(buf+30,fname,12);
1700 if (!case_sensitive)
1701 strupper(buf+30);
1702 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1706 /*******************************************************************
1707 close the low 3 fd's and open dev/null in their place
1708 ********************************************************************/
1709 void close_low_fds(void)
1711 int fd;
1712 int i;
1713 close(0); close(1); close(2);
1714 /* try and use up these file descriptors, so silly
1715 library routines writing to stdout etc won't cause havoc */
1716 for (i=0;i<3;i++) {
1717 fd = open("/dev/null",O_RDWR,0);
1718 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1719 if (fd < 0) {
1720 DEBUG(0,("Can't open /dev/null\n"));
1721 return;
1723 if (fd != i) {
1724 DEBUG(0,("Didn't get file descriptor %d\n",i));
1725 return;
1730 /****************************************************************************
1731 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1732 else
1733 if SYSV use O_NDELAY
1734 if BSD use FNDELAY
1735 ****************************************************************************/
1736 int set_blocking(int fd, BOOL set)
1738 int val;
1739 #ifdef O_NONBLOCK
1740 #define FLAG_TO_SET O_NONBLOCK
1741 #else
1742 #ifdef SYSV
1743 #define FLAG_TO_SET O_NDELAY
1744 #else /* BSD */
1745 #define FLAG_TO_SET FNDELAY
1746 #endif
1747 #endif
1749 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1750 return -1;
1751 if(set) /* Turn blocking on - ie. clear nonblock flag */
1752 val &= ~FLAG_TO_SET;
1753 else
1754 val |= FLAG_TO_SET;
1755 return fcntl( fd, F_SETFL, val);
1756 #undef FLAG_TO_SET
1760 /****************************************************************************
1761 write to a socket
1762 ****************************************************************************/
1763 int write_socket(int fd,char *buf,int len)
1765 int ret=0;
1767 if (passive)
1768 return(len);
1769 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1770 ret = write_data(fd,buf,len);
1772 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1773 return(ret);
1776 /****************************************************************************
1777 read from a socket
1778 ****************************************************************************/
1779 int read_udp_socket(int fd,char *buf,int len)
1781 int ret;
1782 struct sockaddr sock;
1783 int socklen;
1785 socklen = sizeof(sock);
1786 bzero((char *)&sock,socklen);
1787 bzero((char *)&lastip,sizeof(lastip));
1788 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1789 if (ret <= 0) {
1790 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1791 return(0);
1794 lastip = *(struct in_addr *) &sock.sa_data[2];
1795 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1797 return(ret);
1800 /****************************************************************************
1801 read data from a device with a timout in msec.
1802 mincount = if timeout, minimum to read before returning
1803 maxcount = number to be read.
1804 ****************************************************************************/
1805 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1807 fd_set fds;
1808 int selrtn;
1809 int readret;
1810 int nread = 0;
1811 struct timeval timeout;
1813 /* just checking .... */
1814 if (maxcnt <= 0) return(0);
1816 smb_read_error = 0;
1818 /* Blocking read */
1819 if (time_out <= 0) {
1820 if (mincnt == 0) mincnt = maxcnt;
1822 while (nread < mincnt) {
1823 readret = read(fd, buf + nread, maxcnt - nread);
1824 if (readret == 0) {
1825 smb_read_error = READ_EOF;
1826 return -1;
1829 if (readret == -1) {
1830 smb_read_error = READ_ERROR;
1831 return -1;
1833 nread += readret;
1835 return(nread);
1838 /* Most difficult - timeout read */
1839 /* If this is ever called on a disk file and
1840 mincnt is greater then the filesize then
1841 system performance will suffer severely as
1842 select always return true on disk files */
1844 /* Set initial timeout */
1845 timeout.tv_sec = time_out / 1000;
1846 timeout.tv_usec = 1000 * (time_out % 1000);
1848 for (nread=0; nread<mincnt; )
1850 FD_ZERO(&fds);
1851 FD_SET(fd,&fds);
1853 selrtn = sys_select(&fds,&timeout);
1855 /* Check if error */
1856 if(selrtn == -1) {
1857 /* something is wrong. Maybe the socket is dead? */
1858 smb_read_error = READ_ERROR;
1859 return -1;
1862 /* Did we timeout ? */
1863 if (selrtn == 0) {
1864 smb_read_error = READ_TIMEOUT;
1865 return -1;
1868 readret = read(fd, buf+nread, maxcnt-nread);
1869 if (readret == 0) {
1870 /* we got EOF on the file descriptor */
1871 smb_read_error = READ_EOF;
1872 return -1;
1875 if (readret == -1) {
1876 /* the descriptor is probably dead */
1877 smb_read_error = READ_ERROR;
1878 return -1;
1881 nread += readret;
1884 /* Return the number we got */
1885 return(nread);
1888 /****************************************************************************
1889 read data from the client. Maxtime is in milliseconds
1890 ****************************************************************************/
1891 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1893 fd_set fds;
1894 int selrtn;
1895 int nread;
1896 struct timeval timeout;
1898 FD_ZERO(&fds);
1899 FD_SET(fd,&fds);
1901 timeout.tv_sec = maxtime / 1000;
1902 timeout.tv_usec = (maxtime % 1000) * 1000;
1904 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1906 if (!FD_ISSET(fd,&fds))
1907 return 0;
1909 nread = read_udp_socket(fd, buffer, bufsize);
1911 /* return the number got */
1912 return(nread);
1915 /*******************************************************************
1916 find the difference in milliseconds between two struct timeval
1917 values
1918 ********************************************************************/
1919 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1921 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1922 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1925 /****************************************************************************
1926 send a keepalive packet (rfc1002)
1927 ****************************************************************************/
1928 BOOL send_keepalive(int client)
1930 unsigned char buf[4];
1932 buf[0] = 0x85;
1933 buf[1] = buf[2] = buf[3] = 0;
1935 return(write_data(client,(char *)buf,4) == 4);
1940 /****************************************************************************
1941 read data from the client, reading exactly N bytes.
1942 ****************************************************************************/
1943 int read_data(int fd,char *buffer,int N)
1945 int ret;
1946 int total=0;
1948 smb_read_error = 0;
1950 while (total < N)
1952 ret = read(fd,buffer + total,N - total);
1953 if (ret == 0) {
1954 smb_read_error = READ_EOF;
1955 return 0;
1957 if (ret == -1) {
1958 smb_read_error = READ_ERROR;
1959 return -1;
1961 total += ret;
1963 return total;
1967 /****************************************************************************
1968 write data to a fd
1969 ****************************************************************************/
1970 int write_data(int fd,char *buffer,int N)
1972 int total=0;
1973 int ret;
1975 while (total < N)
1977 ret = write(fd,buffer + total,N - total);
1979 if (ret == -1) return -1;
1980 if (ret == 0) return total;
1982 total += ret;
1984 return total;
1988 /****************************************************************************
1989 transfer some data between two fd's
1990 ****************************************************************************/
1991 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1993 static char *buf=NULL;
1994 static int size=0;
1995 char *buf1,*abuf;
1996 int total = 0;
1998 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2000 if (size == 0) {
2001 size = lp_readsize();
2002 size = MAX(size,1024);
2005 while (!buf && size>0) {
2006 buf = (char *)Realloc(buf,size+8);
2007 if (!buf) size /= 2;
2010 if (!buf) {
2011 DEBUG(0,("Can't allocate transfer buffer!\n"));
2012 exit(1);
2015 abuf = buf + (align%8);
2017 if (header)
2018 n += headlen;
2020 while (n > 0)
2022 int s = MIN(n,size);
2023 int ret,ret2=0;
2025 ret = 0;
2027 if (header && (headlen >= MIN(s,1024))) {
2028 buf1 = header;
2029 s = headlen;
2030 ret = headlen;
2031 headlen = 0;
2032 header = NULL;
2033 } else {
2034 buf1 = abuf;
2037 if (header && headlen > 0)
2039 ret = MIN(headlen,size);
2040 memcpy(buf1,header,ret);
2041 headlen -= ret;
2042 header += ret;
2043 if (headlen <= 0) header = NULL;
2046 if (s > ret)
2047 ret += read(infd,buf1+ret,s-ret);
2049 if (ret > 0)
2051 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2052 if (ret2 > 0) total += ret2;
2053 /* if we can't write then dump excess data */
2054 if (ret2 != ret)
2055 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2057 if (ret <= 0 || ret2 != ret)
2058 return(total);
2059 n -= ret;
2061 return(total);
2065 /****************************************************************************
2066 read 4 bytes of a smb packet and return the smb length of the packet
2067 possibly store the result in the buffer
2068 ****************************************************************************/
2069 int read_smb_length(int fd,char *inbuf,int timeout)
2071 char *buffer;
2072 char buf[4];
2073 int len=0, msg_type;
2074 BOOL ok=False;
2076 if (inbuf)
2077 buffer = inbuf;
2078 else
2079 buffer = buf;
2081 while (!ok)
2083 if (timeout > 0)
2084 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2085 else
2086 ok = (read_data(fd,buffer,4) == 4);
2088 if (!ok)
2089 return(-1);
2091 len = smb_len(buffer);
2092 msg_type = CVAL(buffer,0);
2094 if (msg_type == 0x85)
2096 DEBUG(5,("Got keepalive packet\n"));
2097 ok = False;
2101 DEBUG(10,("got smb length of %d\n",len));
2103 return(len);
2108 /****************************************************************************
2109 read an smb from a fd and return it's length
2110 The timeout is in milli seconds
2111 ****************************************************************************/
2112 BOOL receive_smb(int fd,char *buffer,int timeout)
2114 int len,ret;
2116 smb_read_error = 0;
2118 bzero(buffer,smb_size + 100);
2120 len = read_smb_length(fd,buffer,timeout);
2121 if (len == -1)
2122 return(False);
2124 if (len > BUFFER_SIZE) {
2125 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2126 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2127 exit(1);
2130 ret = read_data(fd,buffer+4,len);
2131 if (ret != len) {
2132 smb_read_error = READ_ERROR;
2133 return False;
2136 return(True);
2140 /****************************************************************************
2141 send an smb to a fd
2142 ****************************************************************************/
2143 BOOL send_smb(int fd,char *buffer)
2145 int len;
2146 int ret,nwritten=0;
2147 len = smb_len(buffer) + 4;
2149 while (nwritten < len)
2151 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2152 if (ret <= 0)
2154 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2155 close_sockets();
2156 exit(1);
2158 nwritten += ret;
2162 return True;
2166 /****************************************************************************
2167 find a pointer to a netbios name
2168 ****************************************************************************/
2169 char *name_ptr(char *buf,int ofs)
2171 unsigned char c = *(unsigned char *)(buf+ofs);
2173 if ((c & 0xC0) == 0xC0)
2175 uint16 l;
2176 char p[2];
2177 memcpy(p,buf+ofs,2);
2178 p[0] &= ~0xC0;
2179 l = RSVAL(p,0);
2180 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2181 return(buf + l);
2183 else
2184 return(buf+ofs);
2187 /****************************************************************************
2188 extract a netbios name from a buf
2189 ****************************************************************************/
2190 int name_extract(char *buf,int ofs,char *name)
2192 char *p = name_ptr(buf,ofs);
2193 int d = PTR_DIFF(p,buf+ofs);
2194 strcpy(name,"");
2195 if (d < -50 || d > 50) return(0);
2196 return(name_interpret(p,name));
2200 /****************************************************************************
2201 return the total storage length of a mangled name
2202 ****************************************************************************/
2203 int name_len(char *s)
2205 char *s0=s;
2206 unsigned char c = *(unsigned char *)s;
2207 if ((c & 0xC0) == 0xC0)
2208 return(2);
2209 while (*s) s += (*s)+1;
2210 return(PTR_DIFF(s,s0)+1);
2213 /****************************************************************************
2214 send a single packet to a port on another machine
2215 ****************************************************************************/
2216 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2218 BOOL ret;
2219 int out_fd;
2220 struct sockaddr_in sock_out;
2222 if (passive)
2223 return(True);
2225 /* create a socket to write to */
2226 out_fd = socket(AF_INET, type, 0);
2227 if (out_fd == -1)
2229 DEBUG(0,("socket failed"));
2230 return False;
2233 /* set the address and port */
2234 bzero((char *)&sock_out,sizeof(sock_out));
2235 putip((char *)&sock_out.sin_addr,(char *)&ip);
2236 sock_out.sin_port = htons( port );
2237 sock_out.sin_family = AF_INET;
2239 if (DEBUGLEVEL > 0)
2240 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2241 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2243 /* send it */
2244 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2246 if (!ret)
2247 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2248 inet_ntoa(ip),port,errno));
2250 close(out_fd);
2251 return(ret);
2254 /*******************************************************************
2255 sleep for a specified number of milliseconds
2256 ********************************************************************/
2257 void msleep(int t)
2259 int tdiff=0;
2260 struct timeval tval,t1,t2;
2261 fd_set fds;
2263 GetTimeOfDay(&t1);
2264 GetTimeOfDay(&t2);
2266 while (tdiff < t) {
2267 tval.tv_sec = (t-tdiff)/1000;
2268 tval.tv_usec = 1000*((t-tdiff)%1000);
2270 FD_ZERO(&fds);
2271 errno = 0;
2272 sys_select(&fds,&tval);
2274 GetTimeOfDay(&t2);
2275 tdiff = TvalDiff(&t1,&t2);
2279 /****************************************************************************
2280 check if a string is part of a list
2281 ****************************************************************************/
2282 BOOL in_list(char *s,char *list,BOOL casesensitive)
2284 pstring tok;
2285 char *p=list;
2287 if (!list) return(False);
2289 while (next_token(&p,tok,LIST_SEP))
2291 if (casesensitive) {
2292 if (strcmp(tok,s) == 0)
2293 return(True);
2294 } else {
2295 if (StrCaseCmp(tok,s) == 0)
2296 return(True);
2299 return(False);
2302 /* this is used to prevent lots of mallocs of size 1 */
2303 static char *null_string = NULL;
2305 /****************************************************************************
2306 set a string value, allocing the space for the string
2307 ****************************************************************************/
2308 BOOL string_init(char **dest,char *src)
2310 int l;
2311 if (!src)
2312 src = "";
2314 l = strlen(src);
2316 if (l == 0)
2318 if (!null_string)
2319 null_string = (char *)malloc(1);
2321 *null_string = 0;
2322 *dest = null_string;
2324 else
2326 *dest = (char *)malloc(l+1);
2327 strcpy(*dest,src);
2329 return(True);
2332 /****************************************************************************
2333 free a string value
2334 ****************************************************************************/
2335 void string_free(char **s)
2337 if (!s || !(*s)) return;
2338 if (*s == null_string)
2339 *s = NULL;
2340 if (*s) free(*s);
2341 *s = NULL;
2344 /****************************************************************************
2345 set a string value, allocing the space for the string, and deallocating any
2346 existing space
2347 ****************************************************************************/
2348 BOOL string_set(char **dest,char *src)
2350 string_free(dest);
2352 return(string_init(dest,src));
2355 /****************************************************************************
2356 substitute a string for a pattern in another string. Make sure there is
2357 enough room!
2359 This routine looks for pattern in s and replaces it with
2360 insert. It may do multiple replacements.
2362 return True if a substitution was done.
2363 ****************************************************************************/
2364 BOOL string_sub(char *s,char *pattern,char *insert)
2366 BOOL ret = False;
2367 char *p;
2368 int ls,lp,li;
2370 if (!insert || !pattern || !s) return(False);
2372 ls = strlen(s);
2373 lp = strlen(pattern);
2374 li = strlen(insert);
2376 if (!*pattern) return(False);
2378 while (lp <= ls && (p = strstr(s,pattern)))
2380 ret = True;
2381 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2382 memcpy(p,insert,li);
2383 s = p + li;
2384 ls = strlen(s);
2386 return(ret);
2391 /*********************************************************
2392 * Recursive routine that is called by mask_match.
2393 * Does the actual matching.
2394 *********************************************************/
2395 BOOL do_match(char *str, char *regexp, int case_sig)
2397 char *p;
2399 for( p = regexp; *p && *str; ) {
2400 switch(*p) {
2401 case '?':
2402 str++; p++;
2403 break;
2405 case '*':
2406 /* Look for a character matching
2407 the one after the '*' */
2408 p++;
2409 if(!*p)
2410 return True; /* Automatic match */
2411 while(*str) {
2412 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2413 str++;
2414 if(do_match(str,p,case_sig))
2415 return True;
2416 if(!*str)
2417 return False;
2418 else
2419 str++;
2421 return False;
2423 default:
2424 if(case_sig) {
2425 if(*str != *p)
2426 return False;
2427 } else {
2428 if(toupper(*str) != toupper(*p))
2429 return False;
2431 str++, p++;
2432 break;
2435 if(!*p && !*str)
2436 return True;
2438 if (!*p && str[0] == '.' && str[1] == 0)
2439 return(True);
2441 if (!*str && *p == '?')
2443 while (*p == '?') p++;
2444 return(!*p);
2447 if(!*str && (*p == '*' && p[1] == '\0'))
2448 return True;
2449 return False;
2453 /*********************************************************
2454 * Routine to match a given string with a regexp - uses
2455 * simplified regexp that takes * and ? only. Case can be
2456 * significant or not.
2457 *********************************************************/
2458 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2460 char *p;
2461 pstring p1, p2;
2462 fstring ebase,eext,sbase,sext;
2464 BOOL matched;
2466 /* Make local copies of str and regexp */
2467 StrnCpy(p1,regexp,sizeof(pstring)-1);
2468 StrnCpy(p2,str,sizeof(pstring)-1);
2470 if (!strchr(p2,'.')) {
2471 strcat(p2,".");
2475 if (!strchr(p1,'.')) {
2476 strcat(p1,".");
2480 #if 0
2481 if (strchr(p1,'.'))
2483 string_sub(p1,"*.*","*");
2484 string_sub(p1,".*","*");
2486 #endif
2488 /* Remove any *? and ** as they are meaningless */
2489 for(p = p1; *p; p++)
2490 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2491 (void)strcpy( &p[1], &p[2]);
2493 if (strequal(p1,"*")) return(True);
2495 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2497 if (trans2) {
2498 strcpy(ebase,p1);
2499 strcpy(sbase,p2);
2500 } else {
2501 if ((p=strrchr(p1,'.'))) {
2502 *p = 0;
2503 strcpy(ebase,p1);
2504 strcpy(eext,p+1);
2505 } else {
2506 strcpy(ebase,p1);
2507 eext[0] = 0;
2510 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2511 *p = 0;
2512 strcpy(sbase,p2);
2513 strcpy(sext,p+1);
2514 } else {
2515 strcpy(sbase,p2);
2516 strcpy(sext,"");
2520 matched = do_match(sbase,ebase,case_sig) &&
2521 (trans2 || do_match(sext,eext,case_sig));
2523 DEBUG(5,("mask_match returning %d\n", matched));
2525 return matched;
2530 /****************************************************************************
2531 become a daemon, discarding the controlling terminal
2532 ****************************************************************************/
2533 void become_daemon(void)
2535 #ifndef NO_FORK_DEBUG
2536 if (fork())
2537 exit(0);
2539 /* detach from the terminal */
2540 #ifdef USE_SETSID
2541 setsid();
2542 #else /* USE_SETSID */
2543 #ifdef TIOCNOTTY
2545 int i = open("/dev/tty", O_RDWR);
2546 if (i >= 0)
2548 ioctl(i, (int) TIOCNOTTY, (char *)0);
2549 close(i);
2552 #endif /* TIOCNOTTY */
2553 #endif /* USE_SETSID */
2554 /* Close fd's 0,1,2. Needed if started by rsh */
2555 close_low_fds();
2556 #endif /* NO_FORK_DEBUG */
2560 /****************************************************************************
2561 put up a yes/no prompt
2562 ****************************************************************************/
2563 BOOL yesno(char *p)
2565 pstring ans;
2566 printf("%s",p);
2568 if (!fgets(ans,sizeof(ans)-1,stdin))
2569 return(False);
2571 if (*ans == 'y' || *ans == 'Y')
2572 return(True);
2574 return(False);
2577 /****************************************************************************
2578 read a line from a file with possible \ continuation chars.
2579 Blanks at the start or end of a line are stripped.
2580 The string will be allocated if s2 is NULL
2581 ****************************************************************************/
2582 char *fgets_slash(char *s2,int maxlen,FILE *f)
2584 char *s=s2;
2585 int len = 0;
2586 int c;
2587 BOOL start_of_line = True;
2589 if (feof(f))
2590 return(NULL);
2592 if (!s2)
2594 maxlen = MIN(maxlen,8);
2595 s = (char *)Realloc(s,maxlen);
2598 if (!s || maxlen < 2) return(NULL);
2600 *s = 0;
2602 while (len < maxlen-1)
2604 c = getc(f);
2605 switch (c)
2607 case '\r':
2608 break;
2609 case '\n':
2610 while (len > 0 && s[len-1] == ' ')
2612 s[--len] = 0;
2614 if (len > 0 && s[len-1] == '\\')
2616 s[--len] = 0;
2617 start_of_line = True;
2618 break;
2620 return(s);
2621 case EOF:
2622 if (len <= 0 && !s2)
2623 free(s);
2624 return(len>0?s:NULL);
2625 case ' ':
2626 if (start_of_line)
2627 break;
2628 default:
2629 start_of_line = False;
2630 s[len++] = c;
2631 s[len] = 0;
2633 if (!s2 && len > maxlen-3)
2635 maxlen *= 2;
2636 s = (char *)Realloc(s,maxlen);
2637 if (!s) return(NULL);
2640 return(s);
2645 /****************************************************************************
2646 set the length of a file from a filedescriptor.
2647 Returns 0 on success, -1 on failure.
2648 ****************************************************************************/
2649 int set_filelen(int fd, long len)
2651 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2652 extend a file with ftruncate. Provide alternate implementation
2653 for this */
2655 #if FTRUNCATE_CAN_EXTEND
2656 return ftruncate(fd, len);
2657 #else
2658 struct stat st;
2659 char c = 0;
2660 long currpos = lseek(fd, 0L, SEEK_CUR);
2662 if(currpos < 0)
2663 return -1;
2664 /* Do an fstat to see if the file is longer than
2665 the requested size (call ftruncate),
2666 or shorter, in which case seek to len - 1 and write 1
2667 byte of zero */
2668 if(fstat(fd, &st)<0)
2669 return -1;
2671 #ifdef S_ISFIFO
2672 if (S_ISFIFO(st.st_mode)) return 0;
2673 #endif
2675 if(st.st_size == len)
2676 return 0;
2677 if(st.st_size > len)
2678 return ftruncate(fd, len);
2680 if(lseek(fd, len-1, SEEK_SET) != len -1)
2681 return -1;
2682 if(write(fd, &c, 1)!=1)
2683 return -1;
2684 /* Seek to where we were */
2685 lseek(fd, currpos, SEEK_SET);
2686 return 0;
2687 #endif
2691 /****************************************************************************
2692 return the byte checksum of some data
2693 ****************************************************************************/
2694 int byte_checksum(char *buf,int len)
2696 unsigned char *p = (unsigned char *)buf;
2697 int ret = 0;
2698 while (len--)
2699 ret += *p++;
2700 return(ret);
2705 #ifdef HPUX
2706 /****************************************************************************
2707 this is a version of setbuffer() for those machines that only have setvbuf
2708 ****************************************************************************/
2709 void setbuffer(FILE *f,char *buf,int bufsize)
2711 setvbuf(f,buf,_IOFBF,bufsize);
2713 #endif
2716 /****************************************************************************
2717 parse out a directory name from a path name. Assumes dos style filenames.
2718 ****************************************************************************/
2719 char *dirname_dos(char *path,char *buf)
2721 char *p = strrchr(path,'\\');
2723 if (!p)
2724 strcpy(buf,path);
2725 else
2727 *p = 0;
2728 strcpy(buf,path);
2729 *p = '\\';
2732 return(buf);
2736 /****************************************************************************
2737 parse out a filename from a path name. Assumes dos style filenames.
2738 ****************************************************************************/
2739 static char *filename_dos(char *path,char *buf)
2741 char *p = strrchr(path,'\\');
2743 if (!p)
2744 strcpy(buf,path);
2745 else
2746 strcpy(buf,p+1);
2748 return(buf);
2753 /****************************************************************************
2754 expand a pointer to be a particular size
2755 ****************************************************************************/
2756 void *Realloc(void *p,int size)
2758 void *ret=NULL;
2760 if (size == 0) {
2761 if (p) free(p);
2762 DEBUG(5,("Realloc asked for 0 bytes\n"));
2763 return NULL;
2766 if (!p)
2767 ret = (void *)malloc(size);
2768 else
2769 ret = (void *)realloc(p,size);
2771 if (!ret)
2772 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2774 return(ret);
2777 #ifdef NOSTRDUP
2778 /****************************************************************************
2779 duplicate a string
2780 ****************************************************************************/
2781 char *strdup(char *s)
2783 char *ret = NULL;
2784 if (!s) return(NULL);
2785 ret = (char *)malloc(strlen(s)+1);
2786 if (!ret) return(NULL);
2787 strcpy(ret,s);
2788 return(ret);
2790 #endif
2793 /****************************************************************************
2794 Signal handler for SIGPIPE (write on a disconnected socket)
2795 ****************************************************************************/
2796 void Abort(void )
2798 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2799 exit(2);
2802 /****************************************************************************
2803 get my own name and IP
2804 ****************************************************************************/
2805 BOOL get_myname(char *my_name,struct in_addr *ip)
2807 struct hostent *hp;
2808 pstring hostname;
2810 *hostname = 0;
2812 /* get my host name */
2813 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2815 DEBUG(0,("gethostname failed\n"));
2816 return False;
2819 /* get host info */
2820 if ((hp = Get_Hostbyname(hostname)) == 0)
2822 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2823 return False;
2826 if (my_name)
2828 /* split off any parts after an initial . */
2829 char *p = strchr(hostname,'.');
2830 if (p) *p = 0;
2832 strcpy(my_name,hostname);
2835 if (ip)
2836 putip((char *)ip,(char *)hp->h_addr);
2838 return(True);
2842 /****************************************************************************
2843 true if two IP addresses are equal
2844 ****************************************************************************/
2845 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2847 uint32 a1,a2;
2848 a1 = ntohl(ip1.s_addr);
2849 a2 = ntohl(ip2.s_addr);
2850 return(a1 == a2);
2854 /****************************************************************************
2855 open a socket of the specified type, port and address for incoming data
2856 ****************************************************************************/
2857 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2859 struct hostent *hp;
2860 struct sockaddr_in sock;
2861 pstring host_name;
2862 int res;
2864 /* get my host name */
2865 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2866 { DEBUG(0,("gethostname failed\n")); return -1; }
2868 /* get host info */
2869 if ((hp = Get_Hostbyname(host_name)) == 0)
2871 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2872 return -1;
2875 bzero((char *)&sock,sizeof(sock));
2876 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2877 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2878 sock.sin_len = sizeof(sock);
2879 #endif
2880 sock.sin_port = htons( port );
2881 sock.sin_family = hp->h_addrtype;
2882 sock.sin_addr.s_addr = socket_addr;
2883 res = socket(hp->h_addrtype, type, 0);
2884 if (res == -1)
2885 { DEBUG(0,("socket failed\n")); return -1; }
2888 int one=1;
2889 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2892 /* now we've got a socket - we need to bind it */
2893 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2895 if (port) {
2896 if (port == SMB_PORT || port == NMB_PORT)
2897 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2898 port,socket_addr,strerror(errno)));
2899 close(res);
2901 if (dlevel > 0 && port < 1000)
2902 port = 7999;
2904 if (port >= 1000 && port < 9000)
2905 return(open_socket_in(type,port+1,dlevel,socket_addr));
2908 return(-1);
2910 DEBUG(3,("bind succeeded on port %d\n",port));
2912 return res;
2916 /****************************************************************************
2917 create an outgoing socket
2918 **************************************************************************/
2919 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2921 struct sockaddr_in sock_out;
2922 int res,ret;
2923 int connect_loop = 250; /* 250 milliseconds */
2924 int loops = (timeout * 1000) / connect_loop;
2926 /* create a socket to write to */
2927 res = socket(PF_INET, type, 0);
2928 if (res == -1)
2929 { DEBUG(0,("socket error\n")); return -1; }
2931 if (type != SOCK_STREAM) return(res);
2933 bzero((char *)&sock_out,sizeof(sock_out));
2934 putip((char *)&sock_out.sin_addr,(char *)addr);
2936 sock_out.sin_port = htons( port );
2937 sock_out.sin_family = PF_INET;
2939 /* set it non-blocking */
2940 set_blocking(res,False);
2942 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2944 /* and connect it to the destination */
2945 connect_again:
2946 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2948 /* Some systems return EAGAIN when they mean EINPROGRESS */
2949 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2950 errno == EAGAIN) && loops--) {
2951 msleep(connect_loop);
2952 goto connect_again;
2955 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2956 errno == EAGAIN)) {
2957 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2958 close(res);
2959 return -1;
2962 #ifdef EISCONN
2963 if (ret < 0 && errno == EISCONN) {
2964 errno = 0;
2965 ret = 0;
2967 #endif
2969 if (ret < 0) {
2970 DEBUG(1,("error connecting to %s:%d (%s)\n",
2971 inet_ntoa(*addr),port,strerror(errno)));
2972 return -1;
2975 /* set it blocking again */
2976 set_blocking(res,True);
2978 return res;
2982 /****************************************************************************
2983 interpret a protocol description string, with a default
2984 ****************************************************************************/
2985 int interpret_protocol(char *str,int def)
2987 if (strequal(str,"NT1"))
2988 return(PROTOCOL_NT1);
2989 if (strequal(str,"LANMAN2"))
2990 return(PROTOCOL_LANMAN2);
2991 if (strequal(str,"LANMAN1"))
2992 return(PROTOCOL_LANMAN1);
2993 if (strequal(str,"CORE"))
2994 return(PROTOCOL_CORE);
2995 if (strequal(str,"COREPLUS"))
2996 return(PROTOCOL_COREPLUS);
2997 if (strequal(str,"CORE+"))
2998 return(PROTOCOL_COREPLUS);
3000 DEBUG(0,("Unrecognised protocol level %s\n",str));
3002 return(def);
3005 /****************************************************************************
3006 interpret a security level
3007 ****************************************************************************/
3008 int interpret_security(char *str,int def)
3010 if (strequal(str,"SERVER"))
3011 return(SEC_SERVER);
3012 if (strequal(str,"USER"))
3013 return(SEC_USER);
3014 if (strequal(str,"SHARE"))
3015 return(SEC_SHARE);
3017 DEBUG(0,("Unrecognised security level %s\n",str));
3019 return(def);
3023 /****************************************************************************
3024 interpret an internet address or name into an IP address in 4 byte form
3025 ****************************************************************************/
3026 uint32 interpret_addr(char *str)
3028 struct hostent *hp;
3029 uint32 res;
3030 int i;
3031 BOOL pure_address = True;
3033 if (strcmp(str,"0.0.0.0") == 0) return(0);
3034 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3036 for (i=0; pure_address && str[i]; i++)
3037 if (!(isdigit(str[i]) || str[i] == '.'))
3038 pure_address = False;
3040 /* if it's in the form of an IP address then get the lib to interpret it */
3041 if (pure_address) {
3042 res = inet_addr(str);
3043 } else {
3044 /* otherwise assume it's a network name of some sort and use
3045 Get_Hostbyname */
3046 if ((hp = Get_Hostbyname(str)) == 0) {
3047 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3048 return 0;
3050 putip((char *)&res,(char *)hp->h_addr);
3053 if (res == (uint32)-1) return(0);
3055 return(res);
3058 /*******************************************************************
3059 a convenient addition to interpret_addr()
3060 ******************************************************************/
3061 struct in_addr *interpret_addr2(char *str)
3063 static struct in_addr ret;
3064 uint32 a = interpret_addr(str);
3065 ret.s_addr = a;
3066 return(&ret);
3069 /*******************************************************************
3070 check if an IP is the 0.0.0.0
3071 ******************************************************************/
3072 BOOL zero_ip(struct in_addr ip)
3074 uint32 a;
3075 putip((char *)&a,(char *)&ip);
3076 return(a == 0);
3080 /*******************************************************************
3081 matchname - determine if host name matches IP address
3082 ******************************************************************/
3083 static BOOL matchname(char *remotehost,struct in_addr addr)
3085 struct hostent *hp;
3086 int i;
3088 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3089 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3090 return False;
3094 * Make sure that gethostbyname() returns the "correct" host name.
3095 * Unfortunately, gethostbyname("localhost") sometimes yields
3096 * "localhost.domain". Since the latter host name comes from the
3097 * local DNS, we just have to trust it (all bets are off if the local
3098 * DNS is perverted). We always check the address list, though.
3101 if (strcasecmp(remotehost, hp->h_name)
3102 && strcasecmp(remotehost, "localhost")) {
3103 DEBUG(0,("host name/name mismatch: %s != %s",
3104 remotehost, hp->h_name));
3105 return False;
3108 /* Look up the host address in the address list we just got. */
3109 for (i = 0; hp->h_addr_list[i]; i++) {
3110 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3111 return True;
3115 * The host name does not map to the original host address. Perhaps
3116 * someone has compromised a name server. More likely someone botched
3117 * it, but that could be dangerous, too.
3120 DEBUG(0,("host name/address mismatch: %s != %s",
3121 inet_ntoa(addr), hp->h_name));
3122 return False;
3125 /*******************************************************************
3126 Reset the 'done' variables so after a client process is created
3127 from a fork call these calls will be re-done. This should be
3128 expanded if more variables need reseting.
3129 ******************************************************************/
3131 static BOOL global_client_name_done = False;
3132 static BOOL global_client_addr_done = False;
3134 void reset_globals_after_fork()
3136 global_client_name_done = False;
3137 global_client_addr_done = False;
3140 /*******************************************************************
3141 return the DNS name of the client
3142 ******************************************************************/
3143 char *client_name(void)
3145 extern int Client;
3146 struct sockaddr sa;
3147 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3148 int length = sizeof(sa);
3149 static pstring name_buf;
3150 struct hostent *hp;
3152 if (global_client_name_done)
3153 return name_buf;
3155 strcpy(name_buf,"UNKNOWN");
3157 if (getpeername(Client, &sa, &length) < 0) {
3158 DEBUG(0,("getpeername failed\n"));
3159 return name_buf;
3162 /* Look up the remote host name. */
3163 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3164 sizeof(sockin->sin_addr),
3165 AF_INET)) == 0) {
3166 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3167 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3168 } else {
3169 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3170 if (!matchname(name_buf, sockin->sin_addr)) {
3171 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3172 strcpy(name_buf,"UNKNOWN");
3175 global_client_name_done = True;
3176 return name_buf;
3179 /*******************************************************************
3180 return the IP addr of the client as a string
3181 ******************************************************************/
3182 char *client_addr(void)
3184 extern int Client;
3185 struct sockaddr sa;
3186 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3187 int length = sizeof(sa);
3188 static fstring addr_buf;
3190 if (global_client_addr_done)
3191 return addr_buf;
3193 strcpy(addr_buf,"0.0.0.0");
3195 if (getpeername(Client, &sa, &length) < 0) {
3196 DEBUG(0,("getpeername failed\n"));
3197 return addr_buf;
3200 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3202 global_client_addr_done = True;
3203 return addr_buf;
3206 /*******************************************************************
3207 sub strings with useful parameters
3208 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3209 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3210 ********************************************************************/
3211 void standard_sub_basic(char *string)
3213 char *s, *p;
3214 char pidstr[10];
3215 struct passwd *pass;
3217 for (s = string ; (p = strchr(s,'%')) != NULL ; s = p )
3219 switch (*(p+1))
3221 case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
3222 string_sub(p,"%G",gidtoname(pass->pw_gid));
3223 else
3224 p += 2;
3225 break;
3226 case 'I' : string_sub(p,"%I",client_addr()); break;
3227 case 'L' : string_sub(p,"%L",local_machine); break;
3228 case 'M' : string_sub(p,"%M",client_name()); break;
3229 case 'R' : string_sub(p,"%R",remote_proto); break;
3230 case 'T' : string_sub(p,"%T",timestring()); break;
3231 case 'U' : string_sub(p,"%U",sesssetup_user); break;
3232 case 'a' : string_sub(p,"%a",remote_arch); break;
3233 case 'd' : sprintf(pidstr,"%d",(int)getpid());
3234 string_sub(p,"%d",pidstr);
3235 break;
3236 case 'h' : string_sub(p,"%h",myhostname); break;
3237 case 'm' : string_sub(p,"%m",remote_machine); break;
3238 case 'v' : string_sub(p,"%v",VERSION); break;
3239 case '\0' : p++; break; /* don't run off end if last character is % */
3240 default : p+=2; break;
3243 return;
3246 /*******************************************************************
3247 are two IPs on the same subnet?
3248 ********************************************************************/
3249 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3251 uint32 net1,net2,nmask;
3253 nmask = ntohl(mask.s_addr);
3254 net1 = ntohl(ip1.s_addr);
3255 net2 = ntohl(ip2.s_addr);
3257 return((net1 & nmask) == (net2 & nmask));
3261 /*******************************************************************
3262 write a string in unicoode format
3263 ********************************************************************/
3264 int PutUniCode(char *dst,char *src)
3266 int ret = 0;
3267 while (*src) {
3268 dst[ret++] = src[0];
3269 dst[ret++] = 0;
3270 src++;
3272 dst[ret++]=0;
3273 dst[ret++]=0;
3274 return(ret);
3277 /****************************************************************************
3278 a wrapper for gethostbyname() that tries with all lower and all upper case
3279 if the initial name fails
3280 ****************************************************************************/
3281 struct hostent *Get_Hostbyname(char *name)
3283 char *name2 = strdup(name);
3284 struct hostent *ret;
3286 if (!name2)
3288 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3289 exit(0);
3292 if (!isalnum(*name2))
3294 free(name2);
3295 return(NULL);
3298 ret = sys_gethostbyname(name2);
3299 if (ret != NULL)
3301 free(name2);
3302 return(ret);
3305 /* try with all lowercase */
3306 strlower(name2);
3307 ret = sys_gethostbyname(name2);
3308 if (ret != NULL)
3310 free(name2);
3311 return(ret);
3314 /* try with all uppercase */
3315 strupper(name2);
3316 ret = sys_gethostbyname(name2);
3317 if (ret != NULL)
3319 free(name2);
3320 return(ret);
3323 /* nothing works :-( */
3324 free(name2);
3325 return(NULL);
3329 /****************************************************************************
3330 check if a process exists. Does this work on all unixes?
3331 ****************************************************************************/
3332 BOOL process_exists(int pid)
3334 #ifdef LINUX
3335 fstring s;
3336 sprintf(s,"/proc/%d",pid);
3337 return(directory_exist(s,NULL));
3338 #else
3340 static BOOL tested=False;
3341 static BOOL ok=False;
3342 fstring s;
3343 if (!tested) {
3344 tested = True;
3345 sprintf(s,"/proc/%05d",(int)getpid());
3346 ok = file_exist(s,NULL);
3348 if (ok) {
3349 sprintf(s,"/proc/%05d",pid);
3350 return(file_exist(s,NULL));
3354 /* CGH 8/16/96 - added ESRCH test */
3355 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3356 #endif
3360 /*******************************************************************
3361 turn a uid into a user name
3362 ********************************************************************/
3363 char *uidtoname(int uid)
3365 static char name[40];
3366 struct passwd *pass = getpwuid(uid);
3367 if (pass) return(pass->pw_name);
3368 sprintf(name,"%d",uid);
3369 return(name);
3372 /*******************************************************************
3373 turn a gid into a group name
3374 ********************************************************************/
3375 char *gidtoname(int gid)
3377 static char name[40];
3378 struct group *grp = getgrgid(gid);
3379 if (grp) return(grp->gr_name);
3380 sprintf(name,"%d",gid);
3381 return(name);
3384 /*******************************************************************
3385 block sigs
3386 ********************************************************************/
3387 void BlockSignals(BOOL block,int signum)
3389 #ifdef USE_SIGBLOCK
3390 int block_mask = sigmask(signum);
3391 static int oldmask = 0;
3392 if (block)
3393 oldmask = sigblock(block_mask);
3394 else
3395 sigsetmask(oldmask);
3396 #elif defined(USE_SIGPROCMASK)
3397 sigset_t set;
3398 sigemptyset(&set);
3399 sigaddset(&set,signum);
3400 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3401 #endif
3404 #if AJT
3405 /*******************************************************************
3406 my own panic function - not suitable for general use
3407 ********************************************************************/
3408 void ajt_panic(void)
3410 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3412 #endif
3414 #ifdef USE_DIRECT
3415 #define DIRECT direct
3416 #else
3417 #define DIRECT dirent
3418 #endif
3420 /*******************************************************************
3421 a readdir wrapper which just returns the file name
3422 also return the inode number if requested
3423 ********************************************************************/
3424 char *readdirname(void *p)
3426 struct DIRECT *ptr;
3427 char *dname;
3429 if (!p) return(NULL);
3431 ptr = (struct DIRECT *)readdir(p);
3432 if (!ptr) return(NULL);
3434 dname = ptr->d_name;
3436 #ifdef NEXT2
3437 if (telldir(p) < 0) return(NULL);
3438 #endif
3440 #ifdef SUNOS5
3441 /* this handles a broken compiler setup, causing a mixture
3442 of BSD and SYSV headers and libraries */
3444 static BOOL broken_readdir = False;
3445 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3447 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3448 broken_readdir = True;
3450 if (broken_readdir)
3451 dname = dname - 2;
3453 #endif
3456 static pstring buf;
3457 strcpy(buf, dname);
3458 unix_to_dos(buf, True);
3459 dname = buf;
3462 return(dname);
3466 * Utility function used to decide if the last component
3467 * of a path matches a (possibly wildcarded) entry in a namelist.
3470 BOOL is_in_path(char *name, name_compare_entry *namelist)
3472 pstring last_component;
3473 char *p;
3475 DEBUG(5, ("is_in_path: %s\n", name));
3477 /* if we have no list it's obviously not in the path */
3478 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
3480 DEBUG(5,("is_in_path: no name list.\n"));
3481 return False;
3484 /* Get the last component of the unix name. */
3485 p = strrchr(name, '/');
3486 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3487 last_component[sizeof(last_component)-1] = '\0';
3489 for(; namelist->name != NULL; namelist++)
3491 if(namelist->is_wild)
3493 /* look for a wildcard match. */
3494 if (mask_match(last_component, namelist->name, case_sensitive, False))
3496 DEBUG(5,("is_in_path: mask match succeeded\n"));
3497 return True;
3500 else
3502 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
3503 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
3505 DEBUG(5,("is_in_path: match succeeded\n"));
3506 return True;
3510 DEBUG(5,("is_in_path: match not found\n"));
3512 return False;
3516 * Strip a '/' separated list into an array of
3517 * name_compare_enties structures suitable for
3518 * passing to is_in_path(). We do this for
3519 * speed so we can pre-parse all the names in the list
3520 * and don't do it for each call to is_in_path().
3521 * namelist is modified here and is assumed to be
3522 * a copy owned by the caller.
3523 * We also check if the entry contains a wildcard to
3524 * remove a potentially expensive call to mask_match
3525 * if possible.
3528 void set_namearray(name_compare_entry **ppname_array, char *namelist)
3530 char *name_end;
3531 char *nameptr = namelist;
3532 int num_entries = 0;
3533 int i;
3535 (*ppname_array) = NULL;
3537 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3538 return;
3540 /* We need to make two passes over the string. The
3541 first to count the number of elements, the second
3542 to split it.
3544 while (*nameptr )
3546 if ( *nameptr == '/' )
3548 /* cope with multiple (useless) /s) */
3549 nameptr++;
3550 continue;
3552 /* find the next / */
3553 name_end = strchr(nameptr, '/');
3555 /* oops - the last check for a / didn't find one. */
3556 if (name_end == NULL)
3557 break;
3559 /* next segment please */
3560 nameptr = name_end + 1;
3561 num_entries++;
3564 if(num_entries == 0)
3565 return;
3567 if(( (*ppname_array) = (name_compare_entry *)malloc(
3568 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
3570 DEBUG(0,("set_namearray: malloc fail\n"));
3571 return;
3574 /* Now copy out the names */
3575 nameptr = namelist;
3576 i = 0;
3577 while(*nameptr)
3579 if ( *nameptr == '/' )
3581 /* cope with multiple (useless) /s) */
3582 nameptr++;
3583 continue;
3585 /* find the next / */
3586 if ((name_end = strchr(nameptr, '/')) != NULL)
3588 *name_end = 0;
3591 /* oops - the last check for a / didn't find one. */
3592 if (name_end == NULL)
3593 break;
3595 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
3596 (strchr( nameptr, '*')!=NULL));
3597 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
3599 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3600 return;
3603 /* next segment please */
3604 nameptr = name_end + 1;
3605 i++;
3608 (*ppname_array)[i].name = NULL;
3610 return;
3613 /****************************************************************************
3614 routine to free a namearray.
3615 ****************************************************************************/
3617 void free_namearray(name_compare_entry *name_array)
3619 if(name_array == 0)
3620 return;
3622 if(name_array->name != NULL)
3623 free(name_array->name);
3625 free((char *)name_array);
3628 /****************************************************************************
3629 routine to do file locking
3630 ****************************************************************************/
3631 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3633 #if HAVE_FCNTL_LOCK
3634 struct flock lock;
3635 int ret;
3637 #if 1
3638 uint32 mask = 0xC0000000;
3640 /* make sure the count is reasonable, we might kill the lockd otherwise */
3641 count &= ~mask;
3643 /* the offset is often strange - remove 2 of its bits if either of
3644 the top two bits are set. Shift the top ones by two bits. This
3645 still allows OLE2 apps to operate, but should stop lockd from
3646 dieing */
3647 if ((offset & mask) != 0)
3648 offset = (offset & ~mask) | ((offset & mask) >> 2);
3649 #else
3650 uint32 mask = ((unsigned)1<<31);
3652 /* interpret negative counts as large numbers */
3653 if (count < 0)
3654 count &= ~mask;
3656 /* no negative offsets */
3657 offset &= ~mask;
3659 /* count + offset must be in range */
3660 while ((offset < 0 || (offset + count < 0)) && mask)
3662 offset &= ~mask;
3663 mask = mask >> 1;
3665 #endif
3668 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3670 lock.l_type = type;
3671 lock.l_whence = SEEK_SET;
3672 lock.l_start = (int)offset;
3673 lock.l_len = (int)count;
3674 lock.l_pid = 0;
3676 errno = 0;
3678 ret = fcntl(fd,op,&lock);
3680 if (errno != 0)
3681 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3683 /* a lock query */
3684 if (op == F_GETLK)
3686 if ((ret != -1) &&
3687 (lock.l_type != F_UNLCK) &&
3688 (lock.l_pid != 0) &&
3689 (lock.l_pid != getpid()))
3691 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3692 return(True);
3695 /* it must be not locked or locked by me */
3696 return(False);
3699 /* a lock set or unset */
3700 if (ret == -1)
3702 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3703 offset,count,op,type,strerror(errno)));
3705 /* perhaps it doesn't support this sort of locking?? */
3706 if (errno == EINVAL)
3708 DEBUG(3,("locking not supported? returning True\n"));
3709 return(True);
3712 return(False);
3715 /* everything went OK */
3716 DEBUG(5,("Lock call successful\n"));
3718 return(True);
3719 #else
3720 return(False);
3721 #endif
3724 /*******************************************************************
3725 lock a file - returning a open file descriptor or -1 on failure
3726 The timeout is in seconds. 0 means no timeout
3727 ********************************************************************/
3728 int file_lock(char *name,int timeout)
3730 int fd = open(name,O_RDWR|O_CREAT,0666);
3731 time_t t=0;
3732 if (fd < 0) return(-1);
3734 #if HAVE_FCNTL_LOCK
3735 if (timeout) t = time(NULL);
3736 while (!timeout || (time(NULL)-t < timeout)) {
3737 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3738 msleep(LOCK_RETRY_TIMEOUT);
3740 return(-1);
3741 #else
3742 return(fd);
3743 #endif
3746 /*******************************************************************
3747 unlock a file locked by file_lock
3748 ********************************************************************/
3749 void file_unlock(int fd)
3751 if (fd<0) return;
3752 #if HAVE_FCNTL_LOCK
3753 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3754 #endif
3755 close(fd);
3758 /*******************************************************************
3759 is the name specified one of my netbios names
3760 returns true is it is equal, false otherwise
3761 ********************************************************************/
3762 BOOL is_myname(const char *s)
3764 int n;
3765 BOOL ret = False;
3767 for (n=0; my_netbios_names[n]; n++) {
3768 if (strequal(my_netbios_names[n], s))
3769 ret=True;
3771 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
3772 return(ret);