Rolled back Lukes changes. Not quite ready for prime time.
[Samba.git] / source / lib / util.c
blob9ebfdca88ea87c0c8bbbd27d995d0f2d336cf366
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 = "";
78 int smb_read_error = 0;
80 static char *filename_dos(char *path,char *buf);
82 static BOOL stdout_logging = False;
85 /*******************************************************************
86 get ready for syslog stuff
87 ******************************************************************/
88 void setup_logging(char *pname,BOOL interactive)
90 #ifdef SYSLOG
91 if (!interactive) {
92 char *p = strrchr(pname,'/');
93 if (p) pname = p+1;
94 openlog(pname, LOG_PID, LOG_DAEMON);
96 #endif
97 if (interactive) {
98 stdout_logging = True;
99 dbf = stdout;
104 BOOL append_log=False;
107 /****************************************************************************
108 reopen the log files
109 ****************************************************************************/
110 void reopen_logs(void)
112 extern FILE *dbf;
113 pstring fname;
115 if (DEBUGLEVEL > 0)
117 strcpy(fname,debugf);
118 if (lp_loaded() && (*lp_logfile()))
119 strcpy(fname,lp_logfile());
121 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
123 int oldumask = umask(022);
124 strcpy(debugf,fname);
125 if (dbf) fclose(dbf);
126 if (append_log)
127 dbf = fopen(debugf,"a");
128 else
129 dbf = fopen(debugf,"w");
130 if (dbf) setbuf(dbf,NULL);
131 umask(oldumask);
134 else
136 if (dbf)
138 fclose(dbf);
139 dbf = NULL;
145 /*******************************************************************
146 check if the log has grown too big
147 ********************************************************************/
148 static void check_log_size(void)
150 static int debug_count=0;
151 int maxlog;
152 struct stat st;
154 if (debug_count++ < 100) return;
156 maxlog = lp_max_log_size() * 1024;
157 if (!dbf || maxlog <= 0) return;
159 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
160 fclose(dbf); dbf = NULL;
161 reopen_logs();
162 if (dbf && file_size(debugf) > maxlog) {
163 pstring name;
164 fclose(dbf); dbf = NULL;
165 sprintf(name,"%s.old",debugf);
166 sys_rename(debugf,name);
167 reopen_logs();
170 debug_count=0;
174 /*******************************************************************
175 write an debug message on the debugfile. This is called by the DEBUG
176 macro
177 ********************************************************************/
178 #ifdef __STDC__
179 int Debug1(char *format_str, ...)
181 #else
182 int Debug1(va_alist)
183 va_dcl
185 char *format_str;
186 #endif
187 va_list ap;
189 if (stdout_logging) {
190 #ifdef __STDC__
191 va_start(ap, format_str);
192 #else
193 va_start(ap);
194 format_str = va_arg(ap,char *);
195 #endif
196 vfprintf(dbf,format_str,ap);
197 va_end(ap);
198 return(0);
201 #ifdef SYSLOG
202 if (!lp_syslog_only())
203 #endif
205 if (!dbf)
207 int oldumask = umask(022);
208 dbf = fopen(debugf,"w");
209 umask(oldumask);
210 if (dbf)
211 setbuf(dbf,NULL);
212 else
213 return(0);
217 #ifdef SYSLOG
218 if (syslog_level < lp_syslog())
221 * map debug levels to syslog() priorities
222 * note that not all DEBUG(0, ...) calls are
223 * necessarily errors
225 static int priority_map[] = {
226 LOG_ERR, /* 0 */
227 LOG_WARNING, /* 1 */
228 LOG_NOTICE, /* 2 */
229 LOG_INFO, /* 3 */
231 int priority;
232 pstring msgbuf;
234 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
235 syslog_level < 0)
236 priority = LOG_DEBUG;
237 else
238 priority = priority_map[syslog_level];
240 #ifdef __STDC__
241 va_start(ap, format_str);
242 #else
243 va_start(ap);
244 format_str = va_arg(ap,char *);
245 #endif
246 vsprintf(msgbuf, format_str, ap);
247 va_end(ap);
249 msgbuf[255] = '\0';
250 syslog(priority, "%s", msgbuf);
252 #endif
254 #ifdef SYSLOG
255 if (!lp_syslog_only())
256 #endif
258 #ifdef __STDC__
259 va_start(ap, format_str);
260 #else
261 va_start(ap);
262 format_str = va_arg(ap,char *);
263 #endif
264 vfprintf(dbf,format_str,ap);
265 va_end(ap);
266 fflush(dbf);
269 check_log_size();
271 return(0);
274 /****************************************************************************
275 find a suitable temporary directory. The result should be copied immediately
276 as it may be overwritten by a subsequent call
277 ****************************************************************************/
278 char *tmpdir(void)
280 char *p;
281 if ((p = getenv("TMPDIR"))) {
282 return p;
284 return "/tmp";
289 /****************************************************************************
290 determine if a file descriptor is in fact a socket
291 ****************************************************************************/
292 BOOL is_a_socket(int fd)
294 int v,l;
295 l = sizeof(int);
296 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
300 static char *last_ptr=NULL;
302 /****************************************************************************
303 Get the next token from a string, return False if none found
304 handles double-quotes.
305 Based on a routine by GJC@VILLAGE.COM.
306 Extensively modified by Andrew.Tridgell@anu.edu.au
307 ****************************************************************************/
308 BOOL next_token(char **ptr,char *buff,char *sep)
310 char *s;
311 BOOL quoted;
313 if (!ptr) ptr = &last_ptr;
314 if (!ptr) return(False);
316 s = *ptr;
318 /* default to simple separators */
319 if (!sep) sep = " \t\n\r";
321 /* find the first non sep char */
322 while(*s && strchr(sep,*s)) s++;
324 /* nothing left? */
325 if (! *s) return(False);
327 /* copy over the token */
328 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
330 if (*s == '\"')
331 quoted = !quoted;
332 else
333 *buff++ = *s;
336 *ptr = (*s) ? s+1 : s;
337 *buff = 0;
338 last_ptr = *ptr;
340 return(True);
343 /****************************************************************************
344 Convert list of tokens to array; dependent on above routine.
345 Uses last_ptr from above - bit of a hack.
346 ****************************************************************************/
347 char **toktocliplist(int *ctok, char *sep)
349 char *s=last_ptr;
350 int ictok=0;
351 char **ret, **iret;
353 if (!sep) sep = " \t\n\r";
355 while(*s && strchr(sep,*s)) s++;
357 /* nothing left? */
358 if (!*s) return(NULL);
360 do {
361 ictok++;
362 while(*s && (!strchr(sep,*s))) s++;
363 while(*s && strchr(sep,*s)) *s++=0;
364 } while(*s);
366 *ctok=ictok;
367 s=last_ptr;
369 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
371 while(ictok--) {
372 *iret++=s;
373 while(*s++);
374 while(!*s) s++;
377 return ret;
380 #ifndef HAVE_MEMMOVE
381 /*******************************************************************
382 safely copies memory, ensuring no overlap problems.
383 this is only used if the machine does not have it's own memmove().
384 this is not the fastest algorithm in town, but it will do for our
385 needs.
386 ********************************************************************/
387 void *MemMove(void *dest,void *src,int size)
389 unsigned long d,s;
390 int i;
391 if (dest==src || !size) return(dest);
393 d = (unsigned long)dest;
394 s = (unsigned long)src;
396 if ((d >= (s+size)) || (s >= (d+size))) {
397 /* no overlap */
398 memcpy(dest,src,size);
399 return(dest);
402 if (d < s)
404 /* we can forward copy */
405 if (s-d >= sizeof(int) &&
406 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
407 /* do it all as words */
408 int *idest = (int *)dest;
409 int *isrc = (int *)src;
410 size /= sizeof(int);
411 for (i=0;i<size;i++) idest[i] = isrc[i];
412 } else {
413 /* simplest */
414 char *cdest = (char *)dest;
415 char *csrc = (char *)src;
416 for (i=0;i<size;i++) cdest[i] = csrc[i];
419 else
421 /* must backward copy */
422 if (d-s >= sizeof(int) &&
423 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
424 /* do it all as words */
425 int *idest = (int *)dest;
426 int *isrc = (int *)src;
427 size /= sizeof(int);
428 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
429 } else {
430 /* simplest */
431 char *cdest = (char *)dest;
432 char *csrc = (char *)src;
433 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
436 return(dest);
438 #endif
441 /****************************************************************************
442 prompte a dptr (to make it recently used)
443 ****************************************************************************/
444 void array_promote(char *array,int elsize,int element)
446 char *p;
447 if (element == 0)
448 return;
450 p = (char *)malloc(elsize);
452 if (!p)
454 DEBUG(5,("Ahh! Can't malloc\n"));
455 return;
457 memcpy(p,array + element * elsize, elsize);
458 memmove(array + elsize,array,elsize*element);
459 memcpy(array,p,elsize);
460 free(p);
463 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
465 struct
467 char *name;
468 int level;
469 int option;
470 int value;
471 int opttype;
472 } socket_options[] = {
473 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
474 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
475 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
476 #ifdef TCP_NODELAY
477 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
478 #endif
479 #ifdef IPTOS_LOWDELAY
480 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
481 #endif
482 #ifdef IPTOS_THROUGHPUT
483 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
484 #endif
485 #ifdef SO_SNDBUF
486 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
487 #endif
488 #ifdef SO_RCVBUF
489 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
490 #endif
491 #ifdef SO_SNDLOWAT
492 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
493 #endif
494 #ifdef SO_RCVLOWAT
495 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
496 #endif
497 #ifdef SO_SNDTIMEO
498 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
499 #endif
500 #ifdef SO_RCVTIMEO
501 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
502 #endif
503 {NULL,0,0,0,0}};
507 /****************************************************************************
508 set user socket options
509 ****************************************************************************/
510 void set_socket_options(int fd, char *options)
512 string tok;
514 while (next_token(&options,tok," \t,"))
516 int ret=0,i;
517 int value = 1;
518 char *p;
519 BOOL got_value = False;
521 if ((p = strchr(tok,'=')))
523 *p = 0;
524 value = atoi(p+1);
525 got_value = True;
528 for (i=0;socket_options[i].name;i++)
529 if (strequal(socket_options[i].name,tok))
530 break;
532 if (!socket_options[i].name)
534 DEBUG(0,("Unknown socket option %s\n",tok));
535 continue;
538 switch (socket_options[i].opttype)
540 case OPT_BOOL:
541 case OPT_INT:
542 ret = setsockopt(fd,socket_options[i].level,
543 socket_options[i].option,(char *)&value,sizeof(int));
544 break;
546 case OPT_ON:
547 if (got_value)
548 DEBUG(0,("syntax error - %s does not take a value\n",tok));
551 int on = socket_options[i].value;
552 ret = setsockopt(fd,socket_options[i].level,
553 socket_options[i].option,(char *)&on,sizeof(int));
555 break;
558 if (ret != 0)
559 DEBUG(0,("Failed to set socket option %s\n",tok));
565 /****************************************************************************
566 close the socket communication
567 ****************************************************************************/
568 void close_sockets(void )
570 close(Client);
571 Client = 0;
574 /****************************************************************************
575 determine whether we are in the specified group
576 ****************************************************************************/
577 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
579 int i;
581 if (group == current_gid) return(True);
583 for (i=0;i<ngroups;i++)
584 if (group == groups[i])
585 return(True);
587 return(False);
590 /****************************************************************************
591 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
592 ****************************************************************************/
593 char *StrCpy(char *dest,char *src)
595 char *d = dest;
597 #if AJT
598 /* I don't want to get lazy with these ... */
599 if (!dest || !src) {
600 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
601 ajt_panic();
603 #endif
605 if (!dest) return(NULL);
606 if (!src) {
607 *dest = 0;
608 return(dest);
610 while ((*d++ = *src++)) ;
611 return(dest);
614 /****************************************************************************
615 line strncpy but always null terminates. Make sure there is room!
616 ****************************************************************************/
617 char *StrnCpy(char *dest,char *src,int n)
619 char *d = dest;
620 if (!dest) return(NULL);
621 if (!src) {
622 *dest = 0;
623 return(dest);
625 while (n-- && (*d++ = *src++)) ;
626 *d = 0;
627 return(dest);
631 /*******************************************************************
632 copy an IP address from one buffer to another
633 ********************************************************************/
634 void putip(void *dest,void *src)
636 memcpy(dest,src,4);
640 /****************************************************************************
641 interpret the weird netbios "name". Return the name type
642 ****************************************************************************/
643 static int name_interpret(char *in,char *out)
645 int ret;
646 int len = (*in++) / 2;
648 *out=0;
650 if (len > 30 || len<1) return(0);
652 while (len--)
654 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
655 *out = 0;
656 return(0);
658 *out = ((in[0]-'A')<<4) + (in[1]-'A');
659 in += 2;
660 out++;
662 *out = 0;
663 ret = out[-1];
665 #ifdef NETBIOS_SCOPE
666 /* Handle any scope names */
667 while(*in)
669 *out++ = '.'; /* Scope names are separated by periods */
670 len = *(unsigned char *)in++;
671 StrnCpy(out, in, len);
672 out += len;
673 *out=0;
674 in += len;
676 #endif
677 return(ret);
680 /****************************************************************************
681 mangle a name into netbios format
682 ****************************************************************************/
683 int name_mangle(char *In,char *Out,char name_type)
685 fstring name;
686 char buf[20];
687 char *in = (char *)&buf[0];
688 char *out = (char *)Out;
689 char *p, *label;
690 int i;
692 if (In[0] != '*') {
693 StrnCpy(name,In,sizeof(name)-1);
694 sprintf(buf,"%-15.15s%c",name,name_type);
695 } else {
696 buf[0]='*';
697 memset(&buf[1],0,16);
700 *out++ = 32;
701 for (i=0;i<16;i++) {
702 char c = toupper(in[i]);
703 out[i*2] = (c>>4) + 'A';
704 out[i*2+1] = (c & 0xF) + 'A';
706 out[32]=0;
707 out += 32;
709 label = scope;
710 while (*label)
712 p = strchr(label, '.');
713 if (p == 0)
714 p = label + strlen(label);
715 *out++ = p - label;
716 memcpy(out, label, p - label);
717 out += p - label;
718 label += p - label + (*p == '.');
720 *out = 0;
721 return(name_len(Out));
725 /*******************************************************************
726 check if a file exists
727 ********************************************************************/
728 BOOL file_exist(char *fname,struct stat *sbuf)
730 struct stat st;
731 if (!sbuf) sbuf = &st;
733 if (sys_stat(fname,sbuf) != 0)
734 return(False);
736 return(S_ISREG(sbuf->st_mode));
739 /*******************************************************************
740 check a files mod time
741 ********************************************************************/
742 time_t file_modtime(char *fname)
744 struct stat st;
746 if (sys_stat(fname,&st) != 0)
747 return(0);
749 return(st.st_mtime);
752 /*******************************************************************
753 check if a directory exists
754 ********************************************************************/
755 BOOL directory_exist(char *dname,struct stat *st)
757 struct stat st2;
758 if (!st) st = &st2;
760 if (sys_stat(dname,st) != 0)
761 return(False);
763 return(S_ISDIR(st->st_mode));
766 /*******************************************************************
767 returns the size in bytes of the named file
768 ********************************************************************/
769 uint32 file_size(char *file_name)
771 struct stat buf;
772 buf.st_size = 0;
773 sys_stat(file_name,&buf);
774 return(buf.st_size);
777 /*******************************************************************
778 return a string representing an attribute for a file
779 ********************************************************************/
780 char *attrib_string(int mode)
782 static char attrstr[10];
784 attrstr[0] = 0;
786 if (mode & aVOLID) strcat(attrstr,"V");
787 if (mode & aDIR) strcat(attrstr,"D");
788 if (mode & aARCH) strcat(attrstr,"A");
789 if (mode & aHIDDEN) strcat(attrstr,"H");
790 if (mode & aSYSTEM) strcat(attrstr,"S");
791 if (mode & aRONLY) strcat(attrstr,"R");
793 return(attrstr);
797 /*******************************************************************
798 case insensitive string compararison
799 ********************************************************************/
800 int StrCaseCmp(const char *s, const char *t)
802 /* compare until we run out of string, either t or s, or find a difference */
803 while (*s && *t && tolower(*s) == tolower(*t))
805 s++; t++;
808 return(tolower(*s) - tolower(*t));
811 /*******************************************************************
812 case insensitive string compararison, length limited
813 ********************************************************************/
814 int StrnCaseCmp(const char *s, const char *t, int n)
816 /* compare until we run out of string, either t or s, or chars */
817 while (n-- && *s && *t && tolower(*s) == tolower(*t))
819 s++; t++;
822 /* not run out of chars - strings are different lengths */
823 if (n) return(tolower(*s) - tolower(*t));
825 /* identical up to where we run out of chars, and strings are same length */
826 return(0);
829 /*******************************************************************
830 compare 2 strings
831 ********************************************************************/
832 BOOL strequal(char *s1,char *s2)
834 if (s1 == s2) return(True);
835 if (!s1 || !s2) return(False);
837 return(StrCaseCmp(s1,s2)==0);
840 /*******************************************************************
841 compare 2 strings up to and including the nth char.
842 ******************************************************************/
843 BOOL strnequal(char *s1,char *s2,int n)
845 if (s1 == s2) return(True);
846 if (!s1 || !s2 || !n) return(False);
848 return(StrnCaseCmp(s1,s2,n)==0);
851 /*******************************************************************
852 compare 2 strings (case sensitive)
853 ********************************************************************/
854 BOOL strcsequal(char *s1,char *s2)
856 if (s1 == s2) return(True);
857 if (!s1 || !s2) return(False);
859 return(strcmp(s1,s2)==0);
863 /*******************************************************************
864 convert a string to lower case
865 ********************************************************************/
866 void strlower(char *s)
868 while (*s)
870 #ifdef KANJI
871 if (is_shift_jis (*s)) {
872 s += 2;
873 } else if (is_kana (*s)) {
874 s++;
875 } else {
876 if (isupper(*s))
877 *s = tolower(*s);
878 s++;
880 #else
881 if (isupper(*s))
882 *s = tolower(*s);
883 s++;
884 #endif /* KANJI */
888 /*******************************************************************
889 convert a string to upper case
890 ********************************************************************/
891 void strupper(char *s)
893 while (*s)
895 #ifdef KANJI
896 if (is_shift_jis (*s)) {
897 s += 2;
898 } else if (is_kana (*s)) {
899 s++;
900 } else {
901 if (islower(*s))
902 *s = toupper(*s);
903 s++;
905 #else
906 if (islower(*s))
907 *s = toupper(*s);
908 s++;
909 #endif
913 /*******************************************************************
914 convert a string to "normal" form
915 ********************************************************************/
916 void strnorm(char *s)
918 if (case_default == CASE_UPPER)
919 strupper(s);
920 else
921 strlower(s);
924 /*******************************************************************
925 check if a string is in "normal" case
926 ********************************************************************/
927 BOOL strisnormal(char *s)
929 if (case_default == CASE_UPPER)
930 return(!strhaslower(s));
932 return(!strhasupper(s));
936 /****************************************************************************
937 string replace
938 ****************************************************************************/
939 void string_replace(char *s,char oldc,char newc)
941 while (*s)
943 #ifdef KANJI
944 if (is_shift_jis (*s)) {
945 s += 2;
946 } else if (is_kana (*s)) {
947 s++;
948 } else {
949 if (oldc == *s)
950 *s = newc;
951 s++;
953 #else
954 if (oldc == *s)
955 *s = newc;
956 s++;
957 #endif /* KANJI */
961 /****************************************************************************
962 make a file into unix format
963 ****************************************************************************/
964 void unix_format(char *fname)
966 pstring namecopy;
967 string_replace(fname,'\\','/');
969 if (*fname == '/')
971 strcpy(namecopy,fname);
972 strcpy(fname,".");
973 strcat(fname,namecopy);
977 /****************************************************************************
978 make a file into dos format
979 ****************************************************************************/
980 void dos_format(char *fname)
982 string_replace(fname,'/','\\');
986 /*******************************************************************
987 show a smb message structure
988 ********************************************************************/
989 void show_msg(char *buf)
991 int i;
992 int bcc=0;
993 if (DEBUGLEVEL < 5)
994 return;
996 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
997 smb_len(buf),
998 (int)CVAL(buf,smb_com),
999 (int)CVAL(buf,smb_rcls),
1000 (int)CVAL(buf,smb_reh),
1001 (int)SVAL(buf,smb_err),
1002 (int)CVAL(buf,smb_flg),
1003 (int)SVAL(buf,smb_flg2)));
1004 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1005 (int)SVAL(buf,smb_tid),
1006 (int)SVAL(buf,smb_pid),
1007 (int)SVAL(buf,smb_uid),
1008 (int)SVAL(buf,smb_mid),
1009 (int)CVAL(buf,smb_wct)));
1010 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1011 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1012 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1013 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1014 DEBUG(5,("smb_bcc=%d\n",bcc));
1015 if (DEBUGLEVEL < 10)
1016 return;
1017 for (i=0;i<MIN(bcc,128);i++)
1018 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1019 DEBUG(10,("\n"));
1022 /*******************************************************************
1023 return the length of an smb packet
1024 ********************************************************************/
1025 int smb_len(char *buf)
1027 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1030 /*******************************************************************
1031 set the length of an smb packet
1032 ********************************************************************/
1033 void _smb_setlen(char *buf,int len)
1035 buf[0] = 0;
1036 buf[1] = (len&0x10000)>>16;
1037 buf[2] = (len&0xFF00)>>8;
1038 buf[3] = len&0xFF;
1041 /*******************************************************************
1042 set the length and marker of an smb packet
1043 ********************************************************************/
1044 void smb_setlen(char *buf,int len)
1046 _smb_setlen(buf,len);
1048 CVAL(buf,4) = 0xFF;
1049 CVAL(buf,5) = 'S';
1050 CVAL(buf,6) = 'M';
1051 CVAL(buf,7) = 'B';
1054 /*******************************************************************
1055 setup the word count and byte count for a smb message
1056 ********************************************************************/
1057 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1059 if (zero)
1060 bzero(buf + smb_size,num_words*2 + num_bytes);
1061 CVAL(buf,smb_wct) = num_words;
1062 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1063 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1064 return (smb_size + num_words*2 + num_bytes);
1067 /*******************************************************************
1068 return the number of smb words
1069 ********************************************************************/
1070 int smb_numwords(char *buf)
1072 return (CVAL(buf,smb_wct));
1075 /*******************************************************************
1076 return the size of the smb_buf region of a message
1077 ********************************************************************/
1078 int smb_buflen(char *buf)
1080 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1083 /*******************************************************************
1084 return a pointer to the smb_buf data area
1085 ********************************************************************/
1086 int smb_buf_ofs(char *buf)
1088 return (smb_size + CVAL(buf,smb_wct)*2);
1091 /*******************************************************************
1092 return a pointer to the smb_buf data area
1093 ********************************************************************/
1094 char *smb_buf(char *buf)
1096 return (buf + smb_buf_ofs(buf));
1099 /*******************************************************************
1100 return the SMB offset into an SMB buffer
1101 ********************************************************************/
1102 int smb_offset(char *p,char *buf)
1104 return(PTR_DIFF(p,buf+4) + chain_size);
1108 /*******************************************************************
1109 skip past some strings in a buffer
1110 ********************************************************************/
1111 char *skip_string(char *buf,int n)
1113 while (n--)
1114 buf += strlen(buf) + 1;
1115 return(buf);
1118 /*******************************************************************
1119 trim the specified elements off the front and back of a string
1120 ********************************************************************/
1121 BOOL trim_string(char *s,char *front,char *back)
1123 BOOL ret = False;
1124 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1126 char *p = s;
1127 ret = True;
1128 while (1)
1130 if (!(*p = p[strlen(front)]))
1131 break;
1132 p++;
1135 while (back && *back && strlen(s) >= strlen(back) &&
1136 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1138 ret = True;
1139 s[strlen(s)-strlen(back)] = 0;
1141 return(ret);
1145 /*******************************************************************
1146 reduce a file name, removing .. elements.
1147 ********************************************************************/
1148 void dos_clean_name(char *s)
1150 char *p=NULL;
1152 DEBUG(3,("dos_clean_name [%s]\n",s));
1154 /* remove any double slashes */
1155 string_sub(s, "\\\\", "\\");
1157 while ((p = strstr(s,"\\..\\")) != NULL)
1159 pstring s1;
1161 *p = 0;
1162 strcpy(s1,p+3);
1164 if ((p=strrchr(s,'\\')) != NULL)
1165 *p = 0;
1166 else
1167 *s = 0;
1168 strcat(s,s1);
1171 trim_string(s,NULL,"\\..");
1173 string_sub(s, "\\.\\", "\\");
1176 /*******************************************************************
1177 reduce a file name, removing .. elements.
1178 ********************************************************************/
1179 void unix_clean_name(char *s)
1181 char *p=NULL;
1183 DEBUG(3,("unix_clean_name [%s]\n",s));
1185 /* remove any double slashes */
1186 string_sub(s, "//","/");
1188 /* Remove leading ./ characters */
1189 if(strncmp(s, "./", 2) == 0) {
1190 trim_string(s, "./", NULL);
1191 if(*s == 0)
1192 strcpy(s,"./");
1195 while ((p = strstr(s,"/../")) != NULL)
1197 pstring s1;
1199 *p = 0;
1200 strcpy(s1,p+3);
1202 if ((p=strrchr(s,'/')) != NULL)
1203 *p = 0;
1204 else
1205 *s = 0;
1206 strcat(s,s1);
1209 trim_string(s,NULL,"/..");
1213 /*******************************************************************
1214 a wrapper for the normal chdir() function
1215 ********************************************************************/
1216 int ChDir(char *path)
1218 int res;
1219 static pstring LastDir="";
1221 if (strcsequal(path,".")) return(0);
1223 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1224 DEBUG(3,("chdir to %s\n",path));
1225 res = sys_chdir(path);
1226 if (!res)
1227 strcpy(LastDir,path);
1228 return(res);
1232 /*******************************************************************
1233 return the absolute current directory path. A dumb version.
1234 ********************************************************************/
1235 static char *Dumb_GetWd(char *s)
1237 #ifdef USE_GETCWD
1238 return ((char *)getcwd(s,sizeof(pstring)));
1239 #else
1240 return ((char *)getwd(s));
1241 #endif
1245 /* number of list structures for a caching GetWd function. */
1246 #define MAX_GETWDCACHE (50)
1248 struct
1250 ino_t inode;
1251 dev_t dev;
1252 char *text;
1253 BOOL valid;
1254 } ino_list[MAX_GETWDCACHE];
1256 BOOL use_getwd_cache=True;
1258 /*******************************************************************
1259 return the absolute current directory path
1260 ********************************************************************/
1261 char *GetWd(char *str)
1263 pstring s;
1264 static BOOL getwd_cache_init = False;
1265 struct stat st, st2;
1266 int i;
1268 *s = 0;
1270 if (!use_getwd_cache)
1271 return(Dumb_GetWd(str));
1273 /* init the cache */
1274 if (!getwd_cache_init)
1276 getwd_cache_init = True;
1277 for (i=0;i<MAX_GETWDCACHE;i++)
1279 string_init(&ino_list[i].text,"");
1280 ino_list[i].valid = False;
1284 /* Get the inode of the current directory, if this doesn't work we're
1285 in trouble :-) */
1287 if (stat(".",&st) == -1)
1289 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1290 return(Dumb_GetWd(str));
1294 for (i=0; i<MAX_GETWDCACHE; i++)
1295 if (ino_list[i].valid)
1298 /* If we have found an entry with a matching inode and dev number
1299 then find the inode number for the directory in the cached string.
1300 If this agrees with that returned by the stat for the current
1301 directory then all is o.k. (but make sure it is a directory all
1302 the same...) */
1304 if (st.st_ino == ino_list[i].inode &&
1305 st.st_dev == ino_list[i].dev)
1307 if (stat(ino_list[i].text,&st2) == 0)
1309 if (st.st_ino == st2.st_ino &&
1310 st.st_dev == st2.st_dev &&
1311 (st2.st_mode & S_IFMT) == S_IFDIR)
1313 strcpy (str, ino_list[i].text);
1315 /* promote it for future use */
1316 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1317 return (str);
1319 else
1321 /* If the inode is different then something's changed,
1322 scrub the entry and start from scratch. */
1323 ino_list[i].valid = False;
1330 /* We don't have the information to hand so rely on traditional methods.
1331 The very slow getcwd, which spawns a process on some systems, or the
1332 not quite so bad getwd. */
1334 if (!Dumb_GetWd(s))
1336 DEBUG(0,("Getwd failed, errno %d\n",errno));
1337 return (NULL);
1340 strcpy(str,s);
1342 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1344 /* add it to the cache */
1345 i = MAX_GETWDCACHE - 1;
1346 string_set(&ino_list[i].text,s);
1347 ino_list[i].dev = st.st_dev;
1348 ino_list[i].inode = st.st_ino;
1349 ino_list[i].valid = True;
1351 /* put it at the top of the list */
1352 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1354 return (str);
1359 /*******************************************************************
1360 reduce a file name, removing .. elements and checking that
1361 it is below dir in the heirachy. This uses GetWd() and so must be run
1362 on the system that has the referenced file system.
1364 widelinks are allowed if widelinks is true
1365 ********************************************************************/
1366 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1368 #ifndef REDUCE_PATHS
1369 return True;
1370 #else
1371 pstring dir2;
1372 pstring wd;
1373 pstring basename;
1374 pstring newname;
1375 char *p=NULL;
1376 BOOL relative = (*s != '/');
1378 *dir2 = *wd = *basename = *newname = 0;
1380 if (widelinks)
1382 unix_clean_name(s);
1383 /* can't have a leading .. */
1384 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1386 DEBUG(3,("Illegal file name? (%s)\n",s));
1387 return(False);
1390 if (strlen(s) == 0)
1391 strcpy(s,"./");
1393 return(True);
1396 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1398 /* remove any double slashes */
1399 string_sub(s,"//","/");
1401 strcpy(basename,s);
1402 p = strrchr(basename,'/');
1404 if (!p)
1405 return(True);
1407 if (!GetWd(wd))
1409 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1410 return(False);
1413 if (ChDir(dir) != 0)
1415 DEBUG(0,("couldn't chdir to %s\n",dir));
1416 return(False);
1419 if (!GetWd(dir2))
1421 DEBUG(0,("couldn't getwd for %s\n",dir));
1422 ChDir(wd);
1423 return(False);
1427 if (p && (p != basename))
1429 *p = 0;
1430 if (strcmp(p+1,".")==0)
1431 p[1]=0;
1432 if (strcmp(p+1,"..")==0)
1433 *p = '/';
1436 if (ChDir(basename) != 0)
1438 ChDir(wd);
1439 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1440 return(False);
1443 if (!GetWd(newname))
1445 ChDir(wd);
1446 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1447 return(False);
1450 if (p && (p != basename))
1452 strcat(newname,"/");
1453 strcat(newname,p+1);
1457 int l = strlen(dir2);
1458 if (dir2[l-1] == '/')
1459 l--;
1461 if (strncmp(newname,dir2,l) != 0)
1463 ChDir(wd);
1464 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1465 return(False);
1468 if (relative)
1470 if (newname[l] == '/')
1471 strcpy(s,newname + l + 1);
1472 else
1473 strcpy(s,newname+l);
1475 else
1476 strcpy(s,newname);
1479 ChDir(wd);
1481 if (strlen(s) == 0)
1482 strcpy(s,"./");
1484 DEBUG(3,("reduced to %s\n",s));
1485 return(True);
1486 #endif
1489 /****************************************************************************
1490 expand some *s
1491 ****************************************************************************/
1492 static void expand_one(char *Mask,int len)
1494 char *p1;
1495 while ((p1 = strchr(Mask,'*')) != NULL)
1497 int lfill = (len+1) - strlen(Mask);
1498 int l1= (p1 - Mask);
1499 pstring tmp;
1500 strcpy(tmp,Mask);
1501 memset(tmp+l1,'?',lfill);
1502 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1503 strcpy(Mask,tmp);
1507 /****************************************************************************
1508 expand a wildcard expression, replacing *s with ?s
1509 ****************************************************************************/
1510 void expand_mask(char *Mask,BOOL doext)
1512 pstring mbeg,mext;
1513 pstring dirpart;
1514 pstring filepart;
1515 BOOL hasdot = False;
1516 char *p1;
1517 BOOL absolute = (*Mask == '\\');
1519 *mbeg = *mext = *dirpart = *filepart = 0;
1521 /* parse the directory and filename */
1522 if (strchr(Mask,'\\'))
1523 dirname_dos(Mask,dirpart);
1525 filename_dos(Mask,filepart);
1527 strcpy(mbeg,filepart);
1528 if ((p1 = strchr(mbeg,'.')) != NULL)
1530 hasdot = True;
1531 *p1 = 0;
1532 p1++;
1533 strcpy(mext,p1);
1535 else
1537 strcpy(mext,"");
1538 if (strlen(mbeg) > 8)
1540 strcpy(mext,mbeg + 8);
1541 mbeg[8] = 0;
1545 if (*mbeg == 0)
1546 strcpy(mbeg,"????????");
1547 if ((*mext == 0) && doext && !hasdot)
1548 strcpy(mext,"???");
1550 if (strequal(mbeg,"*") && *mext==0)
1551 strcpy(mext,"*");
1553 /* expand *'s */
1554 expand_one(mbeg,8);
1555 if (*mext)
1556 expand_one(mext,3);
1558 strcpy(Mask,dirpart);
1559 if (*dirpart || absolute) strcat(Mask,"\\");
1560 strcat(Mask,mbeg);
1561 strcat(Mask,".");
1562 strcat(Mask,mext);
1564 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1568 /****************************************************************************
1569 does a string have any uppercase chars in it?
1570 ****************************************************************************/
1571 BOOL strhasupper(char *s)
1573 while (*s)
1575 #ifdef KANJI
1576 if (is_shift_jis (*s)) {
1577 s += 2;
1578 } else if (is_kana (*s)) {
1579 s++;
1580 } else {
1581 if (isupper(*s)) return(True);
1582 s++;
1584 #else
1585 if (isupper(*s)) return(True);
1586 s++;
1587 #endif /* KANJI */
1589 return(False);
1592 /****************************************************************************
1593 does a string have any lowercase chars in it?
1594 ****************************************************************************/
1595 BOOL strhaslower(char *s)
1597 while (*s)
1599 #ifdef KANJI
1600 if (is_shift_jis (*s)) {
1601 s += 2;
1602 } else if (is_kana (*s)) {
1603 s++;
1604 } else {
1605 if (islower(*s)) return(True);
1606 s++;
1608 #else
1609 if (islower(*s)) return(True);
1610 s++;
1611 #endif /* KANJI */
1613 return(False);
1616 /****************************************************************************
1617 find the number of chars in a string
1618 ****************************************************************************/
1619 int count_chars(char *s,char c)
1621 int count=0;
1622 while (*s)
1624 if (*s == c)
1625 count++;
1626 s++;
1628 return(count);
1632 /****************************************************************************
1633 make a dir struct
1634 ****************************************************************************/
1635 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1637 char *p;
1638 pstring mask2;
1640 strcpy(mask2,mask);
1642 if ((mode & aDIR) != 0)
1643 size = 0;
1645 memset(buf+1,' ',11);
1646 if ((p = strchr(mask2,'.')) != NULL)
1648 *p = 0;
1649 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1650 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1651 *p = '.';
1653 else
1654 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1656 bzero(buf+21,DIR_STRUCT_SIZE-21);
1657 CVAL(buf,21) = mode;
1658 put_dos_date(buf,22,date);
1659 SSVAL(buf,26,size & 0xFFFF);
1660 SSVAL(buf,28,size >> 16);
1661 StrnCpy(buf+30,fname,12);
1662 if (!case_sensitive)
1663 strupper(buf+30);
1664 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1668 /*******************************************************************
1669 close the low 3 fd's and open dev/null in their place
1670 ********************************************************************/
1671 void close_low_fds(void)
1673 int fd;
1674 int i;
1675 close(0); close(1); close(2);
1676 /* try and use up these file descriptors, so silly
1677 library routines writing to stdout etc won't cause havoc */
1678 for (i=0;i<3;i++) {
1679 fd = open("/dev/null",O_RDWR,0);
1680 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1681 if (fd < 0) {
1682 DEBUG(0,("Can't open /dev/null\n"));
1683 return;
1685 if (fd != i) {
1686 DEBUG(0,("Didn't get file descriptor %d\n",i));
1687 return;
1692 /****************************************************************************
1693 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1694 else
1695 if SYSV use O_NDELAY
1696 if BSD use FNDELAY
1697 ****************************************************************************/
1698 int set_blocking(int fd, int set)
1700 int val;
1701 #ifdef O_NONBLOCK
1702 #define FLAG_TO_SET O_NONBLOCK
1703 #else
1704 #ifdef SYSV
1705 #define FLAG_TO_SET O_NDELAY
1706 #else /* BSD */
1707 #define FLAG_TO_SET FNDELAY
1708 #endif
1709 #endif
1711 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1712 return -1;
1713 if(set) /* Turn blocking on - ie. clear nonblock flag */
1714 val &= ~FLAG_TO_SET;
1715 else
1716 val |= FLAG_TO_SET;
1717 return fcntl( fd, F_SETFL, val);
1718 #undef FLAG_TO_SET
1722 /****************************************************************************
1723 write to a socket
1724 ****************************************************************************/
1725 int write_socket(int fd,char *buf,int len)
1727 int ret=0;
1729 if (passive)
1730 return(len);
1731 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1732 ret = write_data(fd,buf,len);
1734 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1735 return(ret);
1738 /****************************************************************************
1739 read from a socket
1740 ****************************************************************************/
1741 int read_udp_socket(int fd,char *buf,int len)
1743 int ret;
1744 struct sockaddr sock;
1745 int socklen;
1747 socklen = sizeof(sock);
1748 bzero((char *)&sock,socklen);
1749 bzero((char *)&lastip,sizeof(lastip));
1750 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1751 if (ret <= 0) {
1752 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1753 return(0);
1756 lastip = *(struct in_addr *) &sock.sa_data[2];
1757 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1759 return(ret);
1762 /****************************************************************************
1763 read data from a device with a timout in msec.
1764 mincount = if timeout, minimum to read before returning
1765 maxcount = number to be read.
1766 ****************************************************************************/
1767 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1769 fd_set fds;
1770 int selrtn;
1771 int readret;
1772 int nread = 0;
1773 struct timeval timeout;
1775 /* just checking .... */
1776 if (maxcnt <= 0) return(0);
1778 smb_read_error = 0;
1780 /* Blocking read */
1781 if (time_out <= 0) {
1782 if (mincnt == 0) mincnt = maxcnt;
1784 while (nread < mincnt) {
1785 readret = read(fd, buf + nread, maxcnt - nread);
1786 if (readret == 0) {
1787 smb_read_error = READ_EOF;
1788 return -1;
1791 if (readret == -1) {
1792 smb_read_error = READ_ERROR;
1793 return -1;
1795 nread += readret;
1797 return(nread);
1800 /* Most difficult - timeout read */
1801 /* If this is ever called on a disk file and
1802 mincnt is greater then the filesize then
1803 system performance will suffer severely as
1804 select always return true on disk files */
1806 /* Set initial timeout */
1807 timeout.tv_sec = time_out / 1000;
1808 timeout.tv_usec = 1000 * (time_out % 1000);
1810 for (nread=0; nread<mincnt; )
1812 FD_ZERO(&fds);
1813 FD_SET(fd,&fds);
1815 selrtn = sys_select(&fds,&timeout);
1817 /* Check if error */
1818 if(selrtn == -1) {
1819 /* something is wrong. Maybe the socket is dead? */
1820 smb_read_error = READ_ERROR;
1821 return -1;
1824 /* Did we timeout ? */
1825 if (selrtn == 0) {
1826 smb_read_error = READ_TIMEOUT;
1827 return -1;
1830 readret = read(fd, buf+nread, maxcnt-nread);
1831 if (readret == 0) {
1832 /* we got EOF on the file descriptor */
1833 smb_read_error = READ_EOF;
1834 return -1;
1837 if (readret == -1) {
1838 /* the descriptor is probably dead */
1839 smb_read_error = READ_ERROR;
1840 return -1;
1843 nread += readret;
1846 /* Return the number we got */
1847 return(nread);
1850 /****************************************************************************
1851 read data from the client. Maxtime is in milliseconds
1852 ****************************************************************************/
1853 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1855 fd_set fds;
1856 int selrtn;
1857 int nread;
1858 struct timeval timeout;
1860 FD_ZERO(&fds);
1861 FD_SET(fd,&fds);
1863 timeout.tv_sec = maxtime / 1000;
1864 timeout.tv_usec = (maxtime % 1000) * 1000;
1866 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1868 if (!FD_ISSET(fd,&fds))
1869 return 0;
1871 nread = read_udp_socket(fd, buffer, bufsize);
1873 /* return the number got */
1874 return(nread);
1877 /*******************************************************************
1878 find the difference in milliseconds between two struct timeval
1879 values
1880 ********************************************************************/
1881 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1883 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1884 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1887 /****************************************************************************
1888 send a keepalive packet (rfc1002)
1889 ****************************************************************************/
1890 BOOL send_keepalive(int client)
1892 unsigned char buf[4];
1894 buf[0] = 0x85;
1895 buf[1] = buf[2] = buf[3] = 0;
1897 return(write_data(client,(char *)buf,4) == 4);
1902 /****************************************************************************
1903 read data from the client, reading exactly N bytes.
1904 ****************************************************************************/
1905 int read_data(int fd,char *buffer,int N)
1907 int ret;
1908 int total=0;
1910 smb_read_error = 0;
1912 while (total < N)
1914 ret = read(fd,buffer + total,N - total);
1915 if (ret == 0) {
1916 smb_read_error = READ_EOF;
1917 return 0;
1919 if (ret == -1) {
1920 smb_read_error = READ_ERROR;
1921 return -1;
1923 total += ret;
1925 return total;
1929 /****************************************************************************
1930 write data to a fd
1931 ****************************************************************************/
1932 int write_data(int fd,char *buffer,int N)
1934 int total=0;
1935 int ret;
1937 while (total < N)
1939 ret = write(fd,buffer + total,N - total);
1941 if (ret == -1) return -1;
1942 if (ret == 0) return total;
1944 total += ret;
1946 return total;
1950 /****************************************************************************
1951 transfer some data between two fd's
1952 ****************************************************************************/
1953 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1955 static char *buf=NULL;
1956 static int size=0;
1957 char *buf1,*abuf;
1958 int total = 0;
1960 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1962 if (size == 0) {
1963 size = lp_readsize();
1964 size = MAX(size,1024);
1967 while (!buf && size>0) {
1968 buf = (char *)Realloc(buf,size+8);
1969 if (!buf) size /= 2;
1972 if (!buf) {
1973 DEBUG(0,("Can't allocate transfer buffer!\n"));
1974 exit(1);
1977 abuf = buf + (align%8);
1979 if (header)
1980 n += headlen;
1982 while (n > 0)
1984 int s = MIN(n,size);
1985 int ret,ret2=0;
1987 ret = 0;
1989 if (header && (headlen >= MIN(s,1024))) {
1990 buf1 = header;
1991 s = headlen;
1992 ret = headlen;
1993 headlen = 0;
1994 header = NULL;
1995 } else {
1996 buf1 = abuf;
1999 if (header && headlen > 0)
2001 ret = MIN(headlen,size);
2002 memcpy(buf1,header,ret);
2003 headlen -= ret;
2004 header += ret;
2005 if (headlen <= 0) header = NULL;
2008 if (s > ret)
2009 ret += read(infd,buf1+ret,s-ret);
2011 if (ret > 0)
2013 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2014 if (ret2 > 0) total += ret2;
2015 /* if we can't write then dump excess data */
2016 if (ret2 != ret)
2017 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2019 if (ret <= 0 || ret2 != ret)
2020 return(total);
2021 n -= ret;
2023 return(total);
2027 /****************************************************************************
2028 read 4 bytes of a smb packet and return the smb length of the packet
2029 possibly store the result in the buffer
2030 ****************************************************************************/
2031 int read_smb_length(int fd,char *inbuf,int timeout)
2033 char *buffer;
2034 char buf[4];
2035 int len=0, msg_type;
2036 BOOL ok=False;
2038 if (inbuf)
2039 buffer = inbuf;
2040 else
2041 buffer = buf;
2043 while (!ok)
2045 if (timeout > 0)
2046 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2047 else
2048 ok = (read_data(fd,buffer,4) == 4);
2050 if (!ok)
2051 return(-1);
2053 len = smb_len(buffer);
2054 msg_type = CVAL(buffer,0);
2056 if (msg_type == 0x85)
2058 DEBUG(5,("Got keepalive packet\n"));
2059 ok = False;
2063 DEBUG(10,("got smb length of %d\n",len));
2065 return(len);
2070 /****************************************************************************
2071 read an smb from a fd and return it's length
2072 The timeout is in milli seconds
2073 ****************************************************************************/
2074 BOOL receive_smb(int fd,char *buffer,int timeout)
2076 int len,ret;
2078 smb_read_error = 0;
2080 bzero(buffer,smb_size + 100);
2082 len = read_smb_length(fd,buffer,timeout);
2083 if (len == -1)
2084 return(False);
2086 if (len > BUFFER_SIZE) {
2087 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2088 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2089 exit(1);
2092 ret = read_data(fd,buffer+4,len);
2093 if (ret != len) {
2094 smb_read_error = READ_ERROR;
2095 return False;
2098 return(True);
2102 /****************************************************************************
2103 send an smb to a fd
2104 ****************************************************************************/
2105 BOOL send_smb(int fd,char *buffer)
2107 int len;
2108 int ret,nwritten=0;
2109 len = smb_len(buffer) + 4;
2111 while (nwritten < len)
2113 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2114 if (ret <= 0)
2116 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2117 close_sockets();
2118 exit(1);
2120 nwritten += ret;
2124 return True;
2128 /****************************************************************************
2129 find a pointer to a netbios name
2130 ****************************************************************************/
2131 char *name_ptr(char *buf,int ofs)
2133 unsigned char c = *(unsigned char *)(buf+ofs);
2135 if ((c & 0xC0) == 0xC0)
2137 uint16 l;
2138 char p[2];
2139 memcpy(p,buf+ofs,2);
2140 p[0] &= ~0xC0;
2141 l = RSVAL(p,0);
2142 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2143 return(buf + l);
2145 else
2146 return(buf+ofs);
2149 /****************************************************************************
2150 extract a netbios name from a buf
2151 ****************************************************************************/
2152 int name_extract(char *buf,int ofs,char *name)
2154 char *p = name_ptr(buf,ofs);
2155 int d = PTR_DIFF(p,buf+ofs);
2156 strcpy(name,"");
2157 if (d < -50 || d > 50) return(0);
2158 return(name_interpret(p,name));
2162 /****************************************************************************
2163 return the total storage length of a mangled name
2164 ****************************************************************************/
2165 int name_len(char *s)
2167 char *s0=s;
2168 unsigned char c = *(unsigned char *)s;
2169 if ((c & 0xC0) == 0xC0)
2170 return(2);
2171 while (*s) s += (*s)+1;
2172 return(PTR_DIFF(s,s0)+1);
2175 /****************************************************************************
2176 send a single packet to a port on another machine
2177 ****************************************************************************/
2178 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2180 BOOL ret;
2181 int out_fd;
2182 struct sockaddr_in sock_out;
2184 if (passive)
2185 return(True);
2187 /* create a socket to write to */
2188 out_fd = socket(AF_INET, type, 0);
2189 if (out_fd == -1)
2191 DEBUG(0,("socket failed"));
2192 return False;
2195 /* set the address and port */
2196 bzero((char *)&sock_out,sizeof(sock_out));
2197 putip((char *)&sock_out.sin_addr,(char *)&ip);
2198 sock_out.sin_port = htons( port );
2199 sock_out.sin_family = AF_INET;
2201 if (DEBUGLEVEL > 0)
2202 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2203 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2205 /* send it */
2206 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2208 if (!ret)
2209 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2210 inet_ntoa(ip),port,errno));
2212 close(out_fd);
2213 return(ret);
2216 /*******************************************************************
2217 sleep for a specified number of milliseconds
2218 ********************************************************************/
2219 void msleep(int t)
2221 int tdiff=0;
2222 struct timeval tval,t1,t2;
2223 fd_set fds;
2225 GetTimeOfDay(&t1);
2226 GetTimeOfDay(&t2);
2228 while (tdiff < t) {
2229 tval.tv_sec = (t-tdiff)/1000;
2230 tval.tv_usec = 1000*((t-tdiff)%1000);
2232 FD_ZERO(&fds);
2233 errno = 0;
2234 sys_select(&fds,&tval);
2236 GetTimeOfDay(&t2);
2237 tdiff = TvalDiff(&t1,&t2);
2241 /****************************************************************************
2242 check if a string is part of a list
2243 ****************************************************************************/
2244 BOOL in_list(char *s,char *list,BOOL casesensitive)
2246 pstring tok;
2247 char *p=list;
2249 if (!list) return(False);
2251 while (next_token(&p,tok,LIST_SEP))
2253 if (casesensitive) {
2254 if (strcmp(tok,s) == 0)
2255 return(True);
2256 } else {
2257 if (StrCaseCmp(tok,s) == 0)
2258 return(True);
2261 return(False);
2264 /* this is used to prevent lots of mallocs of size 1 */
2265 static char *null_string = NULL;
2267 /****************************************************************************
2268 set a string value, allocing the space for the string
2269 ****************************************************************************/
2270 BOOL string_init(char **dest,char *src)
2272 int l;
2273 if (!src)
2274 src = "";
2276 l = strlen(src);
2278 if (l == 0)
2280 if (!null_string)
2281 null_string = (char *)malloc(1);
2283 *null_string = 0;
2284 *dest = null_string;
2286 else
2288 *dest = (char *)malloc(l+1);
2289 strcpy(*dest,src);
2291 return(True);
2294 /****************************************************************************
2295 free a string value
2296 ****************************************************************************/
2297 void string_free(char **s)
2299 if (!s || !(*s)) return;
2300 if (*s == null_string)
2301 *s = NULL;
2302 if (*s) free(*s);
2303 *s = NULL;
2306 /****************************************************************************
2307 set a string value, allocing the space for the string, and deallocating any
2308 existing space
2309 ****************************************************************************/
2310 BOOL string_set(char **dest,char *src)
2312 string_free(dest);
2314 return(string_init(dest,src));
2317 /****************************************************************************
2318 substitute a string for a pattern in another string. Make sure there is
2319 enough room!
2321 This routine looks for pattern in s and replaces it with
2322 insert. It may do multiple replacements.
2324 return True if a substitution was done.
2325 ****************************************************************************/
2326 BOOL string_sub(char *s,char *pattern,char *insert)
2328 BOOL ret = False;
2329 char *p;
2330 int ls,lp,li;
2332 if (!insert || !pattern || !s) return(False);
2334 ls = strlen(s);
2335 lp = strlen(pattern);
2336 li = strlen(insert);
2338 if (!*pattern) return(False);
2340 while (lp <= ls && (p = strstr(s,pattern)))
2342 ret = True;
2343 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2344 memcpy(p,insert,li);
2345 s = p + li;
2346 ls = strlen(s);
2348 return(ret);
2353 /*********************************************************
2354 * Recursive routine that is called by mask_match.
2355 * Does the actual matching.
2356 *********************************************************/
2357 BOOL do_match(char *str, char *regexp, int case_sig)
2359 char *p;
2361 for( p = regexp; *p && *str; ) {
2362 switch(*p) {
2363 case '?':
2364 str++; p++;
2365 break;
2367 case '*':
2368 /* Look for a character matching
2369 the one after the '*' */
2370 p++;
2371 if(!*p)
2372 return True; /* Automatic match */
2373 while(*str) {
2374 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2375 str++;
2376 if(do_match(str,p,case_sig))
2377 return True;
2378 if(!*str)
2379 return False;
2380 else
2381 str++;
2383 return False;
2385 default:
2386 if(case_sig) {
2387 if(*str != *p)
2388 return False;
2389 } else {
2390 if(toupper(*str) != toupper(*p))
2391 return False;
2393 str++, p++;
2394 break;
2397 if(!*p && !*str)
2398 return True;
2400 if (!*p && str[0] == '.' && str[1] == 0)
2401 return(True);
2403 if (!*str && *p == '?')
2405 while (*p == '?') p++;
2406 return(!*p);
2409 if(!*str && (*p == '*' && p[1] == '\0'))
2410 return True;
2411 return False;
2415 /*********************************************************
2416 * Routine to match a given string with a regexp - uses
2417 * simplified regexp that takes * and ? only. Case can be
2418 * significant or not.
2419 *********************************************************/
2420 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2422 char *p;
2423 pstring p1, p2;
2424 fstring ebase,eext,sbase,sext;
2426 BOOL matched;
2428 /* Make local copies of str and regexp */
2429 StrnCpy(p1,regexp,sizeof(pstring)-1);
2430 StrnCpy(p2,str,sizeof(pstring)-1);
2432 if (!strchr(p2,'.')) {
2433 strcat(p2,".");
2437 if (!strchr(p1,'.')) {
2438 strcat(p1,".");
2442 #if 0
2443 if (strchr(p1,'.'))
2445 string_sub(p1,"*.*","*");
2446 string_sub(p1,".*","*");
2448 #endif
2450 /* Remove any *? and ** as they are meaningless */
2451 for(p = p1; *p; p++)
2452 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2453 (void)strcpy( &p[1], &p[2]);
2455 if (strequal(p1,"*")) return(True);
2457 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2459 if (trans2) {
2460 strcpy(ebase,p1);
2461 strcpy(sbase,p2);
2462 } else {
2463 if ((p=strrchr(p1,'.'))) {
2464 *p = 0;
2465 strcpy(ebase,p1);
2466 strcpy(eext,p+1);
2467 } else {
2468 strcpy(ebase,p1);
2469 eext[0] = 0;
2472 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2473 *p = 0;
2474 strcpy(sbase,p2);
2475 strcpy(sext,p+1);
2476 } else {
2477 strcpy(sbase,p2);
2478 strcpy(sext,"");
2482 matched = do_match(sbase,ebase,case_sig) &&
2483 (trans2 || do_match(sext,eext,case_sig));
2485 DEBUG(5,("mask_match returning %d\n", matched));
2487 return matched;
2492 /****************************************************************************
2493 become a daemon, discarding the controlling terminal
2494 ****************************************************************************/
2495 void become_daemon(void)
2497 #ifndef NO_FORK_DEBUG
2498 if (fork())
2499 exit(0);
2501 /* detach from the terminal */
2502 #ifdef USE_SETSID
2503 setsid();
2504 #else
2505 #ifdef TIOCNOTTY
2507 int i = open("/dev/tty", O_RDWR);
2508 if (i >= 0)
2510 ioctl(i, (int) TIOCNOTTY, (char *)0);
2511 close(i);
2514 #endif
2515 #endif
2516 #endif
2520 /****************************************************************************
2521 put up a yes/no prompt
2522 ****************************************************************************/
2523 BOOL yesno(char *p)
2525 pstring ans;
2526 printf("%s",p);
2528 if (!fgets(ans,sizeof(ans)-1,stdin))
2529 return(False);
2531 if (*ans == 'y' || *ans == 'Y')
2532 return(True);
2534 return(False);
2537 /****************************************************************************
2538 read a line from a file with possible \ continuation chars.
2539 Blanks at the start or end of a line are stripped.
2540 The string will be allocated if s2 is NULL
2541 ****************************************************************************/
2542 char *fgets_slash(char *s2,int maxlen,FILE *f)
2544 char *s=s2;
2545 int len = 0;
2546 int c;
2547 BOOL start_of_line = True;
2549 if (feof(f))
2550 return(NULL);
2552 if (!s2)
2554 maxlen = MIN(maxlen,8);
2555 s = (char *)Realloc(s,maxlen);
2558 if (!s || maxlen < 2) return(NULL);
2560 *s = 0;
2562 while (len < maxlen-1)
2564 c = getc(f);
2565 switch (c)
2567 case '\r':
2568 break;
2569 case '\n':
2570 while (len > 0 && s[len-1] == ' ')
2572 s[--len] = 0;
2574 if (len > 0 && s[len-1] == '\\')
2576 s[--len] = 0;
2577 start_of_line = True;
2578 break;
2580 return(s);
2581 case EOF:
2582 if (len <= 0 && !s2)
2583 free(s);
2584 return(len>0?s:NULL);
2585 case ' ':
2586 if (start_of_line)
2587 break;
2588 default:
2589 start_of_line = False;
2590 s[len++] = c;
2591 s[len] = 0;
2593 if (!s2 && len > maxlen-3)
2595 maxlen *= 2;
2596 s = (char *)Realloc(s,maxlen);
2597 if (!s) return(NULL);
2600 return(s);
2605 /****************************************************************************
2606 set the length of a file from a filedescriptor.
2607 Returns 0 on success, -1 on failure.
2608 ****************************************************************************/
2609 int set_filelen(int fd, long len)
2611 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2612 extend a file with ftruncate. Provide alternate implementation
2613 for this */
2615 #if FTRUNCATE_CAN_EXTEND
2616 return ftruncate(fd, len);
2617 #else
2618 struct stat st;
2619 char c = 0;
2620 long currpos = lseek(fd, 0L, SEEK_CUR);
2622 if(currpos < 0)
2623 return -1;
2624 /* Do an fstat to see if the file is longer than
2625 the requested size (call ftruncate),
2626 or shorter, in which case seek to len - 1 and write 1
2627 byte of zero */
2628 if(fstat(fd, &st)<0)
2629 return -1;
2631 #ifdef S_ISFIFO
2632 if (S_ISFIFO(st.st_mode)) return 0;
2633 #endif
2635 if(st.st_size == len)
2636 return 0;
2637 if(st.st_size > len)
2638 return ftruncate(fd, len);
2640 if(lseek(fd, len-1, SEEK_SET) != len -1)
2641 return -1;
2642 if(write(fd, &c, 1)!=1)
2643 return -1;
2644 /* Seek to where we were */
2645 lseek(fd, currpos, SEEK_SET);
2646 return 0;
2647 #endif
2651 /****************************************************************************
2652 return the byte checksum of some data
2653 ****************************************************************************/
2654 int byte_checksum(char *buf,int len)
2656 unsigned char *p = (unsigned char *)buf;
2657 int ret = 0;
2658 while (len--)
2659 ret += *p++;
2660 return(ret);
2665 #ifdef HPUX
2666 /****************************************************************************
2667 this is a version of setbuffer() for those machines that only have setvbuf
2668 ****************************************************************************/
2669 void setbuffer(FILE *f,char *buf,int bufsize)
2671 setvbuf(f,buf,_IOFBF,bufsize);
2673 #endif
2676 /****************************************************************************
2677 parse out a directory name from a path name. Assumes dos style filenames.
2678 ****************************************************************************/
2679 char *dirname_dos(char *path,char *buf)
2681 char *p = strrchr(path,'\\');
2683 if (!p)
2684 strcpy(buf,path);
2685 else
2687 *p = 0;
2688 strcpy(buf,path);
2689 *p = '\\';
2692 return(buf);
2696 /****************************************************************************
2697 parse out a filename from a path name. Assumes dos style filenames.
2698 ****************************************************************************/
2699 static char *filename_dos(char *path,char *buf)
2701 char *p = strrchr(path,'\\');
2703 if (!p)
2704 strcpy(buf,path);
2705 else
2706 strcpy(buf,p+1);
2708 return(buf);
2713 /****************************************************************************
2714 expand a pointer to be a particular size
2715 ****************************************************************************/
2716 void *Realloc(void *p,int size)
2718 void *ret=NULL;
2720 if (size == 0) {
2721 if (p) free(p);
2722 DEBUG(5,("Realloc asked for 0 bytes\n"));
2723 return NULL;
2726 if (!p)
2727 ret = (void *)malloc(size);
2728 else
2729 ret = (void *)realloc(p,size);
2731 if (!ret)
2732 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2734 return(ret);
2737 #ifdef NOSTRDUP
2738 /****************************************************************************
2739 duplicate a string
2740 ****************************************************************************/
2741 char *strdup(char *s)
2743 char *ret = NULL;
2744 if (!s) return(NULL);
2745 ret = (char *)malloc(strlen(s)+1);
2746 if (!ret) return(NULL);
2747 strcpy(ret,s);
2748 return(ret);
2750 #endif
2753 /****************************************************************************
2754 Signal handler for SIGPIPE (write on a disconnected socket)
2755 ****************************************************************************/
2756 void Abort(void )
2758 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2759 exit(2);
2762 /****************************************************************************
2763 get my own name and IP
2764 ****************************************************************************/
2765 BOOL get_myname(char *my_name,struct in_addr *ip)
2767 struct hostent *hp;
2768 pstring hostname;
2770 *hostname = 0;
2772 /* get my host name */
2773 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2775 DEBUG(0,("gethostname failed\n"));
2776 return False;
2779 /* get host info */
2780 if ((hp = Get_Hostbyname(hostname)) == 0)
2782 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2783 return False;
2786 if (my_name)
2788 /* split off any parts after an initial . */
2789 char *p = strchr(hostname,'.');
2790 if (p) *p = 0;
2792 strcpy(my_name,hostname);
2795 if (ip)
2796 putip((char *)ip,(char *)hp->h_addr);
2798 return(True);
2802 /****************************************************************************
2803 true if two IP addresses are equal
2804 ****************************************************************************/
2805 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2807 uint32 a1,a2;
2808 a1 = ntohl(ip1.s_addr);
2809 a2 = ntohl(ip2.s_addr);
2810 return(a1 == a2);
2814 /****************************************************************************
2815 open a socket of the specified type, port and address for incoming data
2816 ****************************************************************************/
2817 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2819 struct hostent *hp;
2820 struct sockaddr_in sock;
2821 pstring host_name;
2822 int res;
2824 /* get my host name */
2825 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2826 { DEBUG(0,("gethostname failed\n")); return -1; }
2828 /* get host info */
2829 if ((hp = Get_Hostbyname(host_name)) == 0)
2831 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2832 return -1;
2835 bzero((char *)&sock,sizeof(sock));
2836 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2837 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2838 sock.sin_len = sizeof(sock);
2839 #endif
2840 sock.sin_port = htons( port );
2841 sock.sin_family = hp->h_addrtype;
2842 sock.sin_addr.s_addr = socket_addr;
2843 res = socket(hp->h_addrtype, type, 0);
2844 if (res == -1)
2845 { DEBUG(0,("socket failed\n")); return -1; }
2848 int one=1;
2849 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2852 /* now we've got a socket - we need to bind it */
2853 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2855 if (port) {
2856 if (port == SMB_PORT || port == NMB_PORT)
2857 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2858 port,socket_addr,strerror(errno)));
2859 close(res);
2861 if (dlevel > 0 && port < 1000)
2862 port = 7999;
2864 if (port >= 1000 && port < 9000)
2865 return(open_socket_in(type,port+1,dlevel,socket_addr));
2868 return(-1);
2870 DEBUG(3,("bind succeeded on port %d\n",port));
2872 return res;
2876 /****************************************************************************
2877 create an outgoing socket
2878 **************************************************************************/
2879 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2881 struct sockaddr_in sock_out;
2882 int res,ret;
2883 int connect_loop = 250; /* 250 milliseconds */
2884 int loops = (timeout * 1000) / connect_loop;
2886 /* create a socket to write to */
2887 res = socket(PF_INET, type, 0);
2888 if (res == -1)
2889 { DEBUG(0,("socket error\n")); return -1; }
2891 if (type != SOCK_STREAM) return(res);
2893 bzero((char *)&sock_out,sizeof(sock_out));
2894 putip((char *)&sock_out.sin_addr,(char *)addr);
2896 sock_out.sin_port = htons( port );
2897 sock_out.sin_family = PF_INET;
2899 /* set it non-blocking */
2900 set_blocking(res,0);
2902 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2904 /* and connect it to the destination */
2905 connect_again:
2906 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2908 /* Some systems return EAGAIN when they mean EINPROGRESS */
2909 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2910 errno == EAGAIN) && loops--) {
2911 msleep(connect_loop);
2912 goto connect_again;
2915 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2916 errno == EAGAIN)) {
2917 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2918 close(res);
2919 return -1;
2922 #ifdef EISCONN
2923 if (ret < 0 && errno == EISCONN) {
2924 errno = 0;
2925 ret = 0;
2927 #endif
2929 if (ret < 0) {
2930 DEBUG(1,("error connecting to %s:%d (%s)\n",
2931 inet_ntoa(*addr),port,strerror(errno)));
2932 return -1;
2935 /* set it blocking again */
2936 set_blocking(res,1);
2938 return res;
2942 /****************************************************************************
2943 interpret a protocol description string, with a default
2944 ****************************************************************************/
2945 int interpret_protocol(char *str,int def)
2947 if (strequal(str,"NT1"))
2948 return(PROTOCOL_NT1);
2949 if (strequal(str,"LANMAN2"))
2950 return(PROTOCOL_LANMAN2);
2951 if (strequal(str,"LANMAN1"))
2952 return(PROTOCOL_LANMAN1);
2953 if (strequal(str,"CORE"))
2954 return(PROTOCOL_CORE);
2955 if (strequal(str,"COREPLUS"))
2956 return(PROTOCOL_COREPLUS);
2957 if (strequal(str,"CORE+"))
2958 return(PROTOCOL_COREPLUS);
2960 DEBUG(0,("Unrecognised protocol level %s\n",str));
2962 return(def);
2965 /****************************************************************************
2966 interpret a security level
2967 ****************************************************************************/
2968 int interpret_security(char *str,int def)
2970 if (strequal(str,"SERVER"))
2971 return(SEC_SERVER);
2972 if (strequal(str,"USER"))
2973 return(SEC_USER);
2974 if (strequal(str,"SHARE"))
2975 return(SEC_SHARE);
2977 DEBUG(0,("Unrecognised security level %s\n",str));
2979 return(def);
2983 /****************************************************************************
2984 interpret an internet address or name into an IP address in 4 byte form
2985 ****************************************************************************/
2986 uint32 interpret_addr(char *str)
2988 struct hostent *hp;
2989 uint32 res;
2990 int i;
2991 BOOL pure_address = True;
2993 if (strcmp(str,"0.0.0.0") == 0) return(0);
2994 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2996 for (i=0; pure_address && str[i]; i++)
2997 if (!(isdigit(str[i]) || str[i] == '.'))
2998 pure_address = False;
3000 /* if it's in the form of an IP address then get the lib to interpret it */
3001 if (pure_address) {
3002 res = inet_addr(str);
3003 } else {
3004 /* otherwise assume it's a network name of some sort and use
3005 Get_Hostbyname */
3006 if ((hp = Get_Hostbyname(str)) == 0) {
3007 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3008 return 0;
3010 putip((char *)&res,(char *)hp->h_addr);
3013 if (res == (uint32)-1) return(0);
3015 return(res);
3018 /*******************************************************************
3019 a convenient addition to interpret_addr()
3020 ******************************************************************/
3021 struct in_addr *interpret_addr2(char *str)
3023 static struct in_addr ret;
3024 uint32 a = interpret_addr(str);
3025 ret.s_addr = a;
3026 return(&ret);
3029 /*******************************************************************
3030 check if an IP is the 0.0.0.0
3031 ******************************************************************/
3032 BOOL zero_ip(struct in_addr ip)
3034 uint32 a;
3035 putip((char *)&a,(char *)&ip);
3036 return(a == 0);
3040 /*******************************************************************
3041 matchname - determine if host name matches IP address
3042 ******************************************************************/
3043 static BOOL matchname(char *remotehost,struct in_addr addr)
3045 struct hostent *hp;
3046 int i;
3048 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3049 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3050 return False;
3054 * Make sure that gethostbyname() returns the "correct" host name.
3055 * Unfortunately, gethostbyname("localhost") sometimes yields
3056 * "localhost.domain". Since the latter host name comes from the
3057 * local DNS, we just have to trust it (all bets are off if the local
3058 * DNS is perverted). We always check the address list, though.
3061 if (strcasecmp(remotehost, hp->h_name)
3062 && strcasecmp(remotehost, "localhost")) {
3063 DEBUG(0,("host name/name mismatch: %s != %s",
3064 remotehost, hp->h_name));
3065 return False;
3068 /* Look up the host address in the address list we just got. */
3069 for (i = 0; hp->h_addr_list[i]; i++) {
3070 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3071 return True;
3075 * The host name does not map to the original host address. Perhaps
3076 * someone has compromised a name server. More likely someone botched
3077 * it, but that could be dangerous, too.
3080 DEBUG(0,("host name/address mismatch: %s != %s",
3081 inet_ntoa(addr), hp->h_name));
3082 return False;
3085 /*******************************************************************
3086 Reset the 'done' variables so after a client process is created
3087 from a fork call these calls will be re-done. This should be
3088 expanded if more variables need reseting.
3089 ******************************************************************/
3091 static BOOL global_client_name_done = False;
3092 static BOOL global_client_addr_done = False;
3094 void reset_globals_after_fork()
3096 global_client_name_done = False;
3097 global_client_addr_done = False;
3100 /*******************************************************************
3101 return the DNS name of the client
3102 ******************************************************************/
3103 char *client_name(void)
3105 extern int Client;
3106 struct sockaddr sa;
3107 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3108 int length = sizeof(sa);
3109 static pstring name_buf;
3110 struct hostent *hp;
3112 if (global_client_name_done)
3113 return name_buf;
3115 strcpy(name_buf,"UNKNOWN");
3117 if (getpeername(Client, &sa, &length) < 0) {
3118 DEBUG(0,("getpeername failed\n"));
3119 return name_buf;
3122 /* Look up the remote host name. */
3123 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3124 sizeof(sockin->sin_addr),
3125 AF_INET)) == 0) {
3126 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3127 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3128 } else {
3129 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3130 if (!matchname(name_buf, sockin->sin_addr)) {
3131 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3132 strcpy(name_buf,"UNKNOWN");
3135 global_client_name_done = True;
3136 return name_buf;
3139 /*******************************************************************
3140 return the IP addr of the client as a string
3141 ******************************************************************/
3142 char *client_addr(void)
3144 extern int Client;
3145 struct sockaddr sa;
3146 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3147 int length = sizeof(sa);
3148 static fstring addr_buf;
3150 if (global_client_addr_done)
3151 return addr_buf;
3153 strcpy(addr_buf,"0.0.0.0");
3155 if (getpeername(Client, &sa, &length) < 0) {
3156 DEBUG(0,("getpeername failed\n"));
3157 return addr_buf;
3160 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3162 global_client_addr_done = True;
3163 return addr_buf;
3166 /*******************************************************************
3167 sub strings with useful parameters
3168 ********************************************************************/
3169 void standard_sub_basic(char *s)
3171 if (!strchr(s,'%')) return;
3173 string_sub(s,"%R",remote_proto);
3174 string_sub(s,"%a",remote_arch);
3175 string_sub(s,"%m",remote_machine);
3176 string_sub(s,"%L",local_machine);
3178 if (!strchr(s,'%')) return;
3180 string_sub(s,"%v",VERSION);
3181 string_sub(s,"%h",myhostname);
3182 string_sub(s,"%U",sesssetup_user);
3184 if (!strchr(s,'%')) return;
3186 string_sub(s,"%I",client_addr());
3187 if (strstr(s,"%M"))
3188 string_sub(s,"%M",client_name());
3189 string_sub(s,"%T",timestring());
3191 if (!strchr(s,'%')) return;
3194 char pidstr[10];
3195 sprintf(pidstr,"%d",(int)getpid());
3196 string_sub(s,"%d",pidstr);
3199 if (!strchr(s,'%')) return;
3202 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3203 if (pass) {
3204 string_sub(s,"%G",gidtoname(pass->pw_gid));
3210 /*******************************************************************
3211 are two IPs on the same subnet?
3212 ********************************************************************/
3213 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3215 uint32 net1,net2,nmask;
3217 nmask = ntohl(mask.s_addr);
3218 net1 = ntohl(ip1.s_addr);
3219 net2 = ntohl(ip2.s_addr);
3221 return((net1 & nmask) == (net2 & nmask));
3225 /*******************************************************************
3226 write a string in unicoode format
3227 ********************************************************************/
3228 int PutUniCode(char *dst,char *src)
3230 int ret = 0;
3231 while (*src) {
3232 dst[ret++] = src[0];
3233 dst[ret++] = 0;
3234 src++;
3236 dst[ret++]=0;
3237 dst[ret++]=0;
3238 return(ret);
3241 /****************************************************************************
3242 a wrapper for gethostbyname() that tries with all lower and all upper case
3243 if the initial name fails
3244 ****************************************************************************/
3245 struct hostent *Get_Hostbyname(char *name)
3247 char *name2 = strdup(name);
3248 struct hostent *ret;
3250 if (!name2)
3252 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3253 exit(0);
3256 if (!isalnum(*name2))
3258 free(name2);
3259 return(NULL);
3262 ret = sys_gethostbyname(name2);
3263 if (ret != NULL)
3265 free(name2);
3266 return(ret);
3269 /* try with all lowercase */
3270 strlower(name2);
3271 ret = sys_gethostbyname(name2);
3272 if (ret != NULL)
3274 free(name2);
3275 return(ret);
3278 /* try with all uppercase */
3279 strupper(name2);
3280 ret = sys_gethostbyname(name2);
3281 if (ret != NULL)
3283 free(name2);
3284 return(ret);
3287 /* nothing works :-( */
3288 free(name2);
3289 return(NULL);
3293 /****************************************************************************
3294 check if a process exists. Does this work on all unixes?
3295 ****************************************************************************/
3296 BOOL process_exists(int pid)
3298 #ifdef LINUX
3299 fstring s;
3300 sprintf(s,"/proc/%d",pid);
3301 return(directory_exist(s,NULL));
3302 #else
3304 static BOOL tested=False;
3305 static BOOL ok=False;
3306 fstring s;
3307 if (!tested) {
3308 tested = True;
3309 sprintf(s,"/proc/%05d",(int)getpid());
3310 ok = file_exist(s,NULL);
3312 if (ok) {
3313 sprintf(s,"/proc/%05d",pid);
3314 return(file_exist(s,NULL));
3318 /* CGH 8/16/96 - added ESRCH test */
3319 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3320 #endif
3324 /*******************************************************************
3325 turn a uid into a user name
3326 ********************************************************************/
3327 char *uidtoname(int uid)
3329 static char name[40];
3330 struct passwd *pass = getpwuid(uid);
3331 if (pass) return(pass->pw_name);
3332 sprintf(name,"%d",uid);
3333 return(name);
3336 /*******************************************************************
3337 turn a gid into a group name
3338 ********************************************************************/
3339 char *gidtoname(int gid)
3341 static char name[40];
3342 struct group *grp = getgrgid(gid);
3343 if (grp) return(grp->gr_name);
3344 sprintf(name,"%d",gid);
3345 return(name);
3348 /*******************************************************************
3349 block sigs
3350 ********************************************************************/
3351 void BlockSignals(BOOL block,int signum)
3353 #ifdef USE_SIGBLOCK
3354 int block_mask = sigmask(signum);
3355 static int oldmask = 0;
3356 if (block)
3357 oldmask = sigblock(block_mask);
3358 else
3359 sigsetmask(oldmask);
3360 #elif defined(USE_SIGPROCMASK)
3361 sigset_t set;
3362 sigemptyset(&set);
3363 sigaddset(&set,signum);
3364 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3365 #endif
3368 #if AJT
3369 /*******************************************************************
3370 my own panic function - not suitable for general use
3371 ********************************************************************/
3372 void ajt_panic(void)
3374 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3376 #endif
3378 #ifdef USE_DIRECT
3379 #define DIRECT direct
3380 #else
3381 #define DIRECT dirent
3382 #endif
3384 /*******************************************************************
3385 a readdir wrapper which just returns the file name
3386 also return the inode number if requested
3387 ********************************************************************/
3388 char *readdirname(void *p)
3390 struct DIRECT *ptr;
3391 char *dname;
3393 if (!p) return(NULL);
3395 ptr = (struct DIRECT *)readdir(p);
3396 if (!ptr) return(NULL);
3398 dname = ptr->d_name;
3401 static pstring buf;
3402 strcpy(buf, dname);
3403 unix_to_dos(buf, True);
3404 dname = buf;
3407 #ifdef NEXT2
3408 if (telldir(p) < 0) return(NULL);
3409 #endif
3411 #ifdef SUNOS5
3412 /* this handles a broken compiler setup, causing a mixture
3413 of BSD and SYSV headers and libraries */
3415 static BOOL broken_readdir = False;
3416 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3418 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3419 broken_readdir = True;
3421 if (broken_readdir)
3422 return(dname-2);
3424 #endif
3426 return(dname);
3430 BOOL is_vetoed_name(char *name)
3432 char *namelist = lp_veto_files();
3433 char *nameptr = namelist;
3434 char *name_end;
3436 /* if we have no list it's obviously not vetoed */
3437 if((nameptr == NULL ) || (*nameptr == '\0'))
3438 return 0;
3440 /* if the name doesn't exist in the list, it's obviously ok too */
3441 if(strstr(namelist,name) == NULL )
3442 return 0;
3444 /* now, we need to find the names one by one and check them
3445 they can contain spaces and all sorts of stuff so we
3446 separate them with of all things '/' which can never be in a filename
3447 I could use "" but then I have to break them all out
3448 maybe such a routine exists somewhere?
3450 while(*nameptr)
3452 if ( *nameptr == '/' )
3454 nameptr++;
3455 continue;
3457 if((name_end = strchr(nameptr,'/'))!=NULL)
3459 *name_end = 0;
3461 /* a match! it's veto'd */
3462 if(strcmp(name,nameptr) == 0)
3463 return 1;
3464 if(name_end == NULL)
3465 return 0;
3466 /* next segment please */
3467 nameptr = name_end + 1;
3469 return 0;
3472 BOOL is_vetoed_path(char *name)
3474 char *namelist = lp_veto_files();
3475 char *nameptr = namelist;
3476 char *sub;
3477 char *name_end;
3478 int len;
3480 /* if we have no list it's obviously not vetoed */
3481 if((nameptr == NULL ) || (*nameptr == '\0'))
3482 return 0;
3485 /* now, we need to find the names one by one and check them
3486 they can contain spaces and all sorts of stuff so we
3487 separate them with of all things '/' which can never be in a filename
3488 I could use "" but then I have to break them all out
3489 maybe such a routine exists somewhere?
3491 while(*nameptr)
3493 if ( *nameptr == '/' )
3495 nameptr++;
3496 continue;
3498 if((name_end = strchr(nameptr,'/'))!=NULL)
3500 *name_end = 0;
3503 len = strlen(nameptr);
3504 sub = name;
3505 /* If the name doesn't exist in the path, try the next name.. */
3506 while( sub && ((sub = strstr(sub,nameptr)) != NULL))
3508 /* Is it a whole component? */
3509 if(((sub == name) || (sub[-1] == '/'))
3510 && ((sub[len] == '\0') || (sub[len] == '/')))
3512 return 1;
3514 /* skip to the next component of the path */
3515 sub =strchr(sub,'/');
3517 if(name_end == NULL)
3518 return 0;
3519 /* next segment please */
3520 nameptr = name_end + 1;
3522 return 0;
3525 /****************************************************************************
3526 routine to do file locking
3527 ****************************************************************************/
3528 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3530 #if HAVE_FCNTL_LOCK
3531 struct flock lock;
3532 int ret;
3534 #if 1
3535 uint32 mask = 0xC0000000;
3537 /* make sure the count is reasonable, we might kill the lockd otherwise */
3538 count &= ~mask;
3540 /* the offset is often strange - remove 2 of its bits if either of
3541 the top two bits are set. Shift the top ones by two bits. This
3542 still allows OLE2 apps to operate, but should stop lockd from
3543 dieing */
3544 if ((offset & mask) != 0)
3545 offset = (offset & ~mask) | ((offset & mask) >> 2);
3546 #else
3547 uint32 mask = ((unsigned)1<<31);
3549 /* interpret negative counts as large numbers */
3550 if (count < 0)
3551 count &= ~mask;
3553 /* no negative offsets */
3554 offset &= ~mask;
3556 /* count + offset must be in range */
3557 while ((offset < 0 || (offset + count < 0)) && mask)
3559 offset &= ~mask;
3560 mask = mask >> 1;
3562 #endif
3565 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3567 lock.l_type = type;
3568 lock.l_whence = SEEK_SET;
3569 lock.l_start = (int)offset;
3570 lock.l_len = (int)count;
3571 lock.l_pid = 0;
3573 errno = 0;
3575 ret = fcntl(fd,op,&lock);
3577 if (errno != 0)
3578 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3580 /* a lock query */
3581 if (op == F_GETLK)
3583 if ((ret != -1) &&
3584 (lock.l_type != F_UNLCK) &&
3585 (lock.l_pid != 0) &&
3586 (lock.l_pid != getpid()))
3588 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3589 return(True);
3592 /* it must be not locked or locked by me */
3593 return(False);
3596 /* a lock set or unset */
3597 if (ret == -1)
3599 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3600 offset,count,op,type,strerror(errno)));
3602 /* perhaps it doesn't support this sort of locking?? */
3603 if (errno == EINVAL)
3605 DEBUG(3,("locking not supported? returning True\n"));
3606 return(True);
3609 return(False);
3612 /* everything went OK */
3613 DEBUG(5,("Lock call successful\n"));
3615 return(True);
3616 #else
3617 return(False);
3618 #endif
3621 /*******************************************************************
3622 lock a file - returning a open file descriptor or -1 on failure
3623 The timeout is in seconds. 0 means no timeout
3624 ********************************************************************/
3625 int file_lock(char *name,int timeout)
3627 int fd = open(name,O_RDWR|O_CREAT,0666);
3628 time_t t=0;
3629 if (fd < 0) return(-1);
3631 #if HAVE_FCNTL_LOCK
3632 if (timeout) t = time(NULL);
3633 while (!timeout || (time(NULL)-t < timeout)) {
3634 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3635 msleep(LOCK_RETRY_TIMEOUT);
3637 return(-1);
3638 #else
3639 return(fd);
3640 #endif
3643 /*******************************************************************
3644 unlock a file locked by file_lock
3645 ********************************************************************/
3646 void file_unlock(int fd)
3648 if (fd<0) return;
3649 #if HAVE_FCNTL_LOCK
3650 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3651 #endif
3652 close(fd);