added pretty printing of data section to show_msg(), for debug log level 10.
[Samba.git] / source / lib / util.c
blobb7ad0bb5bcef46b7066645d6d751c825f32b8993
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 /* We *must* use toupper rather than tolower here due to the
804 asynchronous upper to lower mapping.
806 while (*s && *t && toupper(*s) == toupper(*t))
808 s++; t++;
811 return(toupper(*s) - toupper(*t));
814 /*******************************************************************
815 case insensitive string compararison, length limited
816 ********************************************************************/
817 int StrnCaseCmp(const char *s, const char *t, int n)
819 /* compare until we run out of string, either t or s, or chars */
820 /* We *must* use toupper rather than tolower here due to the
821 asynchronous upper to lower mapping.
823 while (n-- && *s && *t && toupper(*s) == toupper(*t))
825 s++; t++;
828 /* not run out of chars - strings are different lengths */
829 if (n) return(toupper(*s) - toupper(*t));
831 /* identical up to where we run out of chars, and strings are same length */
832 return(0);
835 /*******************************************************************
836 compare 2 strings
837 ********************************************************************/
838 BOOL strequal(char *s1,char *s2)
840 if (s1 == s2) return(True);
841 if (!s1 || !s2) return(False);
843 return(StrCaseCmp(s1,s2)==0);
846 /*******************************************************************
847 compare 2 strings up to and including the nth char.
848 ******************************************************************/
849 BOOL strnequal(char *s1,char *s2,int n)
851 if (s1 == s2) return(True);
852 if (!s1 || !s2 || !n) return(False);
854 return(StrnCaseCmp(s1,s2,n)==0);
857 /*******************************************************************
858 compare 2 strings (case sensitive)
859 ********************************************************************/
860 BOOL strcsequal(char *s1,char *s2)
862 if (s1 == s2) return(True);
863 if (!s1 || !s2) return(False);
865 return(strcmp(s1,s2)==0);
869 /*******************************************************************
870 convert a string to lower case
871 ********************************************************************/
872 void strlower(char *s)
874 while (*s)
876 #ifdef KANJI
877 if (is_shift_jis (*s)) {
878 s += 2;
879 } else if (is_kana (*s)) {
880 s++;
881 } else {
882 if (isupper(*s))
883 *s = tolower(*s);
884 s++;
886 #else
887 if (isupper(*s))
888 *s = tolower(*s);
889 s++;
890 #endif /* KANJI */
894 /*******************************************************************
895 convert a string to upper case
896 ********************************************************************/
897 void strupper(char *s)
899 while (*s)
901 #ifdef KANJI
902 if (is_shift_jis (*s)) {
903 s += 2;
904 } else if (is_kana (*s)) {
905 s++;
906 } else {
907 if (islower(*s))
908 *s = toupper(*s);
909 s++;
911 #else
912 if (islower(*s))
913 *s = toupper(*s);
914 s++;
915 #endif
919 /*******************************************************************
920 convert a string to "normal" form
921 ********************************************************************/
922 void strnorm(char *s)
924 if (case_default == CASE_UPPER)
925 strupper(s);
926 else
927 strlower(s);
930 /*******************************************************************
931 check if a string is in "normal" case
932 ********************************************************************/
933 BOOL strisnormal(char *s)
935 if (case_default == CASE_UPPER)
936 return(!strhaslower(s));
938 return(!strhasupper(s));
942 /****************************************************************************
943 string replace
944 ****************************************************************************/
945 void string_replace(char *s,char oldc,char newc)
947 while (*s)
949 #ifdef KANJI
950 if (is_shift_jis (*s)) {
951 s += 2;
952 } else if (is_kana (*s)) {
953 s++;
954 } else {
955 if (oldc == *s)
956 *s = newc;
957 s++;
959 #else
960 if (oldc == *s)
961 *s = newc;
962 s++;
963 #endif /* KANJI */
967 /****************************************************************************
968 make a file into unix format
969 ****************************************************************************/
970 void unix_format(char *fname)
972 pstring namecopy;
973 string_replace(fname,'\\','/');
975 if (*fname == '/')
977 strcpy(namecopy,fname);
978 strcpy(fname,".");
979 strcat(fname,namecopy);
983 /****************************************************************************
984 make a file into dos format
985 ****************************************************************************/
986 void dos_format(char *fname)
988 string_replace(fname,'/','\\');
992 /*******************************************************************
993 show a smb message structure
994 ********************************************************************/
995 void show_msg(char *buf)
997 int i;
998 int j;
999 int bcc=0;
1000 if (DEBUGLEVEL < 5)
1001 return;
1003 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1004 smb_len(buf),
1005 (int)CVAL(buf,smb_com),
1006 (int)CVAL(buf,smb_rcls),
1007 (int)CVAL(buf,smb_reh),
1008 (int)SVAL(buf,smb_err),
1009 (int)CVAL(buf,smb_flg),
1010 (int)SVAL(buf,smb_flg2)));
1011 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1012 (int)SVAL(buf,smb_tid),
1013 (int)SVAL(buf,smb_pid),
1014 (int)SVAL(buf,smb_uid),
1015 (int)SVAL(buf,smb_mid),
1016 (int)CVAL(buf,smb_wct)));
1017 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1018 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1019 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1020 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1021 DEBUG(5,("smb_bcc=%d\n",bcc));
1022 if (DEBUGLEVEL < 10)
1023 return;
1024 for (i = 0; i < MIN(bcc, 256); i += 16)
1026 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1029 DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
1030 if (j == 7) DEBUG(10, (" "));
1033 DEBUG(10,(" "));
1035 for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
1037 unsigned char c = CVAL(smb_buf(buf),i+j);
1038 if (c < 32 || c > 128) c = '.';
1039 DEBUG(10,("%c",c));
1041 if (j == 7) DEBUG(10, (" "));
1044 DEBUG(10,("\n"));
1048 /*******************************************************************
1049 return the length of an smb packet
1050 ********************************************************************/
1051 int smb_len(char *buf)
1053 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1056 /*******************************************************************
1057 set the length of an smb packet
1058 ********************************************************************/
1059 void _smb_setlen(char *buf,int len)
1061 buf[0] = 0;
1062 buf[1] = (len&0x10000)>>16;
1063 buf[2] = (len&0xFF00)>>8;
1064 buf[3] = len&0xFF;
1067 /*******************************************************************
1068 set the length and marker of an smb packet
1069 ********************************************************************/
1070 void smb_setlen(char *buf,int len)
1072 _smb_setlen(buf,len);
1074 CVAL(buf,4) = 0xFF;
1075 CVAL(buf,5) = 'S';
1076 CVAL(buf,6) = 'M';
1077 CVAL(buf,7) = 'B';
1080 /*******************************************************************
1081 setup the word count and byte count for a smb message
1082 ********************************************************************/
1083 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1085 if (zero)
1086 bzero(buf + smb_size,num_words*2 + num_bytes);
1087 CVAL(buf,smb_wct) = num_words;
1088 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1089 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1090 return (smb_size + num_words*2 + num_bytes);
1093 /*******************************************************************
1094 return the number of smb words
1095 ********************************************************************/
1096 int smb_numwords(char *buf)
1098 return (CVAL(buf,smb_wct));
1101 /*******************************************************************
1102 return the size of the smb_buf region of a message
1103 ********************************************************************/
1104 int smb_buflen(char *buf)
1106 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1109 /*******************************************************************
1110 return a pointer to the smb_buf data area
1111 ********************************************************************/
1112 int smb_buf_ofs(char *buf)
1114 return (smb_size + CVAL(buf,smb_wct)*2);
1117 /*******************************************************************
1118 return a pointer to the smb_buf data area
1119 ********************************************************************/
1120 char *smb_buf(char *buf)
1122 return (buf + smb_buf_ofs(buf));
1125 /*******************************************************************
1126 return the SMB offset into an SMB buffer
1127 ********************************************************************/
1128 int smb_offset(char *p,char *buf)
1130 return(PTR_DIFF(p,buf+4) + chain_size);
1134 /*******************************************************************
1135 skip past some strings in a buffer
1136 ********************************************************************/
1137 char *skip_string(char *buf,int n)
1139 while (n--)
1140 buf += strlen(buf) + 1;
1141 return(buf);
1144 /*******************************************************************
1145 trim the specified elements off the front and back of a string
1146 ********************************************************************/
1147 BOOL trim_string(char *s,char *front,char *back)
1149 BOOL ret = False;
1150 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1152 char *p = s;
1153 ret = True;
1154 while (1)
1156 if (!(*p = p[strlen(front)]))
1157 break;
1158 p++;
1161 while (back && *back && strlen(s) >= strlen(back) &&
1162 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1164 ret = True;
1165 s[strlen(s)-strlen(back)] = 0;
1167 return(ret);
1171 /*******************************************************************
1172 reduce a file name, removing .. elements.
1173 ********************************************************************/
1174 void dos_clean_name(char *s)
1176 char *p=NULL;
1178 DEBUG(3,("dos_clean_name [%s]\n",s));
1180 /* remove any double slashes */
1181 string_sub(s, "\\\\", "\\");
1183 while ((p = strstr(s,"\\..\\")) != NULL)
1185 pstring s1;
1187 *p = 0;
1188 strcpy(s1,p+3);
1190 if ((p=strrchr(s,'\\')) != NULL)
1191 *p = 0;
1192 else
1193 *s = 0;
1194 strcat(s,s1);
1197 trim_string(s,NULL,"\\..");
1199 string_sub(s, "\\.\\", "\\");
1202 /*******************************************************************
1203 reduce a file name, removing .. elements.
1204 ********************************************************************/
1205 void unix_clean_name(char *s)
1207 char *p=NULL;
1209 DEBUG(3,("unix_clean_name [%s]\n",s));
1211 /* remove any double slashes */
1212 string_sub(s, "//","/");
1214 /* Remove leading ./ characters */
1215 if(strncmp(s, "./", 2) == 0) {
1216 trim_string(s, "./", NULL);
1217 if(*s == 0)
1218 strcpy(s,"./");
1221 while ((p = strstr(s,"/../")) != NULL)
1223 pstring s1;
1225 *p = 0;
1226 strcpy(s1,p+3);
1228 if ((p=strrchr(s,'/')) != NULL)
1229 *p = 0;
1230 else
1231 *s = 0;
1232 strcat(s,s1);
1235 trim_string(s,NULL,"/..");
1239 /*******************************************************************
1240 a wrapper for the normal chdir() function
1241 ********************************************************************/
1242 int ChDir(char *path)
1244 int res;
1245 static pstring LastDir="";
1247 if (strcsequal(path,".")) return(0);
1249 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1250 DEBUG(3,("chdir to %s\n",path));
1251 res = sys_chdir(path);
1252 if (!res)
1253 strcpy(LastDir,path);
1254 return(res);
1258 /*******************************************************************
1259 return the absolute current directory path. A dumb version.
1260 ********************************************************************/
1261 static char *Dumb_GetWd(char *s)
1263 #ifdef USE_GETCWD
1264 return ((char *)getcwd(s,sizeof(pstring)));
1265 #else
1266 return ((char *)getwd(s));
1267 #endif
1271 /* number of list structures for a caching GetWd function. */
1272 #define MAX_GETWDCACHE (50)
1274 struct
1276 ino_t inode;
1277 dev_t dev;
1278 char *text;
1279 BOOL valid;
1280 } ino_list[MAX_GETWDCACHE];
1282 BOOL use_getwd_cache=True;
1284 /*******************************************************************
1285 return the absolute current directory path
1286 ********************************************************************/
1287 char *GetWd(char *str)
1289 pstring s;
1290 static BOOL getwd_cache_init = False;
1291 struct stat st, st2;
1292 int i;
1294 *s = 0;
1296 if (!use_getwd_cache)
1297 return(Dumb_GetWd(str));
1299 /* init the cache */
1300 if (!getwd_cache_init)
1302 getwd_cache_init = True;
1303 for (i=0;i<MAX_GETWDCACHE;i++)
1305 string_init(&ino_list[i].text,"");
1306 ino_list[i].valid = False;
1310 /* Get the inode of the current directory, if this doesn't work we're
1311 in trouble :-) */
1313 if (stat(".",&st) == -1)
1315 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1316 return(Dumb_GetWd(str));
1320 for (i=0; i<MAX_GETWDCACHE; i++)
1321 if (ino_list[i].valid)
1324 /* If we have found an entry with a matching inode and dev number
1325 then find the inode number for the directory in the cached string.
1326 If this agrees with that returned by the stat for the current
1327 directory then all is o.k. (but make sure it is a directory all
1328 the same...) */
1330 if (st.st_ino == ino_list[i].inode &&
1331 st.st_dev == ino_list[i].dev)
1333 if (stat(ino_list[i].text,&st2) == 0)
1335 if (st.st_ino == st2.st_ino &&
1336 st.st_dev == st2.st_dev &&
1337 (st2.st_mode & S_IFMT) == S_IFDIR)
1339 strcpy (str, ino_list[i].text);
1341 /* promote it for future use */
1342 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1343 return (str);
1345 else
1347 /* If the inode is different then something's changed,
1348 scrub the entry and start from scratch. */
1349 ino_list[i].valid = False;
1356 /* We don't have the information to hand so rely on traditional methods.
1357 The very slow getcwd, which spawns a process on some systems, or the
1358 not quite so bad getwd. */
1360 if (!Dumb_GetWd(s))
1362 DEBUG(0,("Getwd failed, errno %d\n",errno));
1363 return (NULL);
1366 strcpy(str,s);
1368 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1370 /* add it to the cache */
1371 i = MAX_GETWDCACHE - 1;
1372 string_set(&ino_list[i].text,s);
1373 ino_list[i].dev = st.st_dev;
1374 ino_list[i].inode = st.st_ino;
1375 ino_list[i].valid = True;
1377 /* put it at the top of the list */
1378 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1380 return (str);
1385 /*******************************************************************
1386 reduce a file name, removing .. elements and checking that
1387 it is below dir in the heirachy. This uses GetWd() and so must be run
1388 on the system that has the referenced file system.
1390 widelinks are allowed if widelinks is true
1391 ********************************************************************/
1392 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1394 #ifndef REDUCE_PATHS
1395 return True;
1396 #else
1397 pstring dir2;
1398 pstring wd;
1399 pstring basename;
1400 pstring newname;
1401 char *p=NULL;
1402 BOOL relative = (*s != '/');
1404 *dir2 = *wd = *basename = *newname = 0;
1406 if (widelinks)
1408 unix_clean_name(s);
1409 /* can't have a leading .. */
1410 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1412 DEBUG(3,("Illegal file name? (%s)\n",s));
1413 return(False);
1416 if (strlen(s) == 0)
1417 strcpy(s,"./");
1419 return(True);
1422 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1424 /* remove any double slashes */
1425 string_sub(s,"//","/");
1427 strcpy(basename,s);
1428 p = strrchr(basename,'/');
1430 if (!p)
1431 return(True);
1433 if (!GetWd(wd))
1435 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1436 return(False);
1439 if (ChDir(dir) != 0)
1441 DEBUG(0,("couldn't chdir to %s\n",dir));
1442 return(False);
1445 if (!GetWd(dir2))
1447 DEBUG(0,("couldn't getwd for %s\n",dir));
1448 ChDir(wd);
1449 return(False);
1453 if (p && (p != basename))
1455 *p = 0;
1456 if (strcmp(p+1,".")==0)
1457 p[1]=0;
1458 if (strcmp(p+1,"..")==0)
1459 *p = '/';
1462 if (ChDir(basename) != 0)
1464 ChDir(wd);
1465 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1466 return(False);
1469 if (!GetWd(newname))
1471 ChDir(wd);
1472 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1473 return(False);
1476 if (p && (p != basename))
1478 strcat(newname,"/");
1479 strcat(newname,p+1);
1483 int l = strlen(dir2);
1484 if (dir2[l-1] == '/')
1485 l--;
1487 if (strncmp(newname,dir2,l) != 0)
1489 ChDir(wd);
1490 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1491 return(False);
1494 if (relative)
1496 if (newname[l] == '/')
1497 strcpy(s,newname + l + 1);
1498 else
1499 strcpy(s,newname+l);
1501 else
1502 strcpy(s,newname);
1505 ChDir(wd);
1507 if (strlen(s) == 0)
1508 strcpy(s,"./");
1510 DEBUG(3,("reduced to %s\n",s));
1511 return(True);
1512 #endif
1515 /****************************************************************************
1516 expand some *s
1517 ****************************************************************************/
1518 static void expand_one(char *Mask,int len)
1520 char *p1;
1521 while ((p1 = strchr(Mask,'*')) != NULL)
1523 int lfill = (len+1) - strlen(Mask);
1524 int l1= (p1 - Mask);
1525 pstring tmp;
1526 strcpy(tmp,Mask);
1527 memset(tmp+l1,'?',lfill);
1528 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1529 strcpy(Mask,tmp);
1533 /****************************************************************************
1534 expand a wildcard expression, replacing *s with ?s
1535 ****************************************************************************/
1536 void expand_mask(char *Mask,BOOL doext)
1538 pstring mbeg,mext;
1539 pstring dirpart;
1540 pstring filepart;
1541 BOOL hasdot = False;
1542 char *p1;
1543 BOOL absolute = (*Mask == '\\');
1545 *mbeg = *mext = *dirpart = *filepart = 0;
1547 /* parse the directory and filename */
1548 if (strchr(Mask,'\\'))
1549 dirname_dos(Mask,dirpart);
1551 filename_dos(Mask,filepart);
1553 strcpy(mbeg,filepart);
1554 if ((p1 = strchr(mbeg,'.')) != NULL)
1556 hasdot = True;
1557 *p1 = 0;
1558 p1++;
1559 strcpy(mext,p1);
1561 else
1563 strcpy(mext,"");
1564 if (strlen(mbeg) > 8)
1566 strcpy(mext,mbeg + 8);
1567 mbeg[8] = 0;
1571 if (*mbeg == 0)
1572 strcpy(mbeg,"????????");
1573 if ((*mext == 0) && doext && !hasdot)
1574 strcpy(mext,"???");
1576 if (strequal(mbeg,"*") && *mext==0)
1577 strcpy(mext,"*");
1579 /* expand *'s */
1580 expand_one(mbeg,8);
1581 if (*mext)
1582 expand_one(mext,3);
1584 strcpy(Mask,dirpart);
1585 if (*dirpart || absolute) strcat(Mask,"\\");
1586 strcat(Mask,mbeg);
1587 strcat(Mask,".");
1588 strcat(Mask,mext);
1590 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1594 /****************************************************************************
1595 does a string have any uppercase chars in it?
1596 ****************************************************************************/
1597 BOOL strhasupper(char *s)
1599 while (*s)
1601 #ifdef KANJI
1602 if (is_shift_jis (*s)) {
1603 s += 2;
1604 } else if (is_kana (*s)) {
1605 s++;
1606 } else {
1607 if (isupper(*s)) return(True);
1608 s++;
1610 #else
1611 if (isupper(*s)) return(True);
1612 s++;
1613 #endif /* KANJI */
1615 return(False);
1618 /****************************************************************************
1619 does a string have any lowercase chars in it?
1620 ****************************************************************************/
1621 BOOL strhaslower(char *s)
1623 while (*s)
1625 #ifdef KANJI
1626 if (is_shift_jis (*s)) {
1627 s += 2;
1628 } else if (is_kana (*s)) {
1629 s++;
1630 } else {
1631 if (islower(*s)) return(True);
1632 s++;
1634 #else
1635 if (islower(*s)) return(True);
1636 s++;
1637 #endif /* KANJI */
1639 return(False);
1642 /****************************************************************************
1643 find the number of chars in a string
1644 ****************************************************************************/
1645 int count_chars(char *s,char c)
1647 int count=0;
1648 while (*s)
1650 if (*s == c)
1651 count++;
1652 s++;
1654 return(count);
1658 /****************************************************************************
1659 make a dir struct
1660 ****************************************************************************/
1661 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1663 char *p;
1664 pstring mask2;
1666 strcpy(mask2,mask);
1668 if ((mode & aDIR) != 0)
1669 size = 0;
1671 memset(buf+1,' ',11);
1672 if ((p = strchr(mask2,'.')) != NULL)
1674 *p = 0;
1675 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1676 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1677 *p = '.';
1679 else
1680 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1682 bzero(buf+21,DIR_STRUCT_SIZE-21);
1683 CVAL(buf,21) = mode;
1684 put_dos_date(buf,22,date);
1685 SSVAL(buf,26,size & 0xFFFF);
1686 SSVAL(buf,28,size >> 16);
1687 StrnCpy(buf+30,fname,12);
1688 if (!case_sensitive)
1689 strupper(buf+30);
1690 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1694 /*******************************************************************
1695 close the low 3 fd's and open dev/null in their place
1696 ********************************************************************/
1697 void close_low_fds(void)
1699 int fd;
1700 int i;
1701 close(0); close(1); close(2);
1702 /* try and use up these file descriptors, so silly
1703 library routines writing to stdout etc won't cause havoc */
1704 for (i=0;i<3;i++) {
1705 fd = open("/dev/null",O_RDWR,0);
1706 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1707 if (fd < 0) {
1708 DEBUG(0,("Can't open /dev/null\n"));
1709 return;
1711 if (fd != i) {
1712 DEBUG(0,("Didn't get file descriptor %d\n",i));
1713 return;
1718 /****************************************************************************
1719 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1720 else
1721 if SYSV use O_NDELAY
1722 if BSD use FNDELAY
1723 ****************************************************************************/
1724 int set_blocking(int fd, int set)
1726 int val;
1727 #ifdef O_NONBLOCK
1728 #define FLAG_TO_SET O_NONBLOCK
1729 #else
1730 #ifdef SYSV
1731 #define FLAG_TO_SET O_NDELAY
1732 #else /* BSD */
1733 #define FLAG_TO_SET FNDELAY
1734 #endif
1735 #endif
1737 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1738 return -1;
1739 if(set) /* Turn blocking on - ie. clear nonblock flag */
1740 val &= ~FLAG_TO_SET;
1741 else
1742 val |= FLAG_TO_SET;
1743 return fcntl( fd, F_SETFL, val);
1744 #undef FLAG_TO_SET
1748 /****************************************************************************
1749 write to a socket
1750 ****************************************************************************/
1751 int write_socket(int fd,char *buf,int len)
1753 int ret=0;
1755 if (passive)
1756 return(len);
1757 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1758 ret = write_data(fd,buf,len);
1760 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1761 return(ret);
1764 /****************************************************************************
1765 read from a socket
1766 ****************************************************************************/
1767 int read_udp_socket(int fd,char *buf,int len)
1769 int ret;
1770 struct sockaddr sock;
1771 int socklen;
1773 socklen = sizeof(sock);
1774 bzero((char *)&sock,socklen);
1775 bzero((char *)&lastip,sizeof(lastip));
1776 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1777 if (ret <= 0) {
1778 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1779 return(0);
1782 lastip = *(struct in_addr *) &sock.sa_data[2];
1783 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1785 return(ret);
1788 /****************************************************************************
1789 read data from a device with a timout in msec.
1790 mincount = if timeout, minimum to read before returning
1791 maxcount = number to be read.
1792 ****************************************************************************/
1793 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1795 fd_set fds;
1796 int selrtn;
1797 int readret;
1798 int nread = 0;
1799 struct timeval timeout;
1801 /* just checking .... */
1802 if (maxcnt <= 0) return(0);
1804 smb_read_error = 0;
1806 /* Blocking read */
1807 if (time_out <= 0) {
1808 if (mincnt == 0) mincnt = maxcnt;
1810 while (nread < mincnt) {
1811 readret = read(fd, buf + nread, maxcnt - nread);
1812 if (readret == 0) {
1813 smb_read_error = READ_EOF;
1814 return -1;
1817 if (readret == -1) {
1818 smb_read_error = READ_ERROR;
1819 return -1;
1821 nread += readret;
1823 return(nread);
1826 /* Most difficult - timeout read */
1827 /* If this is ever called on a disk file and
1828 mincnt is greater then the filesize then
1829 system performance will suffer severely as
1830 select always return true on disk files */
1832 /* Set initial timeout */
1833 timeout.tv_sec = time_out / 1000;
1834 timeout.tv_usec = 1000 * (time_out % 1000);
1836 for (nread=0; nread<mincnt; )
1838 FD_ZERO(&fds);
1839 FD_SET(fd,&fds);
1841 selrtn = sys_select(&fds,&timeout);
1843 /* Check if error */
1844 if(selrtn == -1) {
1845 /* something is wrong. Maybe the socket is dead? */
1846 smb_read_error = READ_ERROR;
1847 return -1;
1850 /* Did we timeout ? */
1851 if (selrtn == 0) {
1852 smb_read_error = READ_TIMEOUT;
1853 return -1;
1856 readret = read(fd, buf+nread, maxcnt-nread);
1857 if (readret == 0) {
1858 /* we got EOF on the file descriptor */
1859 smb_read_error = READ_EOF;
1860 return -1;
1863 if (readret == -1) {
1864 /* the descriptor is probably dead */
1865 smb_read_error = READ_ERROR;
1866 return -1;
1869 nread += readret;
1872 /* Return the number we got */
1873 return(nread);
1876 /****************************************************************************
1877 read data from the client. Maxtime is in milliseconds
1878 ****************************************************************************/
1879 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1881 fd_set fds;
1882 int selrtn;
1883 int nread;
1884 struct timeval timeout;
1886 FD_ZERO(&fds);
1887 FD_SET(fd,&fds);
1889 timeout.tv_sec = maxtime / 1000;
1890 timeout.tv_usec = (maxtime % 1000) * 1000;
1892 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1894 if (!FD_ISSET(fd,&fds))
1895 return 0;
1897 nread = read_udp_socket(fd, buffer, bufsize);
1899 /* return the number got */
1900 return(nread);
1903 /*******************************************************************
1904 find the difference in milliseconds between two struct timeval
1905 values
1906 ********************************************************************/
1907 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1909 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1910 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1913 /****************************************************************************
1914 send a keepalive packet (rfc1002)
1915 ****************************************************************************/
1916 BOOL send_keepalive(int client)
1918 unsigned char buf[4];
1920 buf[0] = 0x85;
1921 buf[1] = buf[2] = buf[3] = 0;
1923 return(write_data(client,(char *)buf,4) == 4);
1928 /****************************************************************************
1929 read data from the client, reading exactly N bytes.
1930 ****************************************************************************/
1931 int read_data(int fd,char *buffer,int N)
1933 int ret;
1934 int total=0;
1936 smb_read_error = 0;
1938 while (total < N)
1940 ret = read(fd,buffer + total,N - total);
1941 if (ret == 0) {
1942 smb_read_error = READ_EOF;
1943 return 0;
1945 if (ret == -1) {
1946 smb_read_error = READ_ERROR;
1947 return -1;
1949 total += ret;
1951 return total;
1955 /****************************************************************************
1956 write data to a fd
1957 ****************************************************************************/
1958 int write_data(int fd,char *buffer,int N)
1960 int total=0;
1961 int ret;
1963 while (total < N)
1965 ret = write(fd,buffer + total,N - total);
1967 if (ret == -1) return -1;
1968 if (ret == 0) return total;
1970 total += ret;
1972 return total;
1976 /****************************************************************************
1977 transfer some data between two fd's
1978 ****************************************************************************/
1979 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1981 static char *buf=NULL;
1982 static int size=0;
1983 char *buf1,*abuf;
1984 int total = 0;
1986 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1988 if (size == 0) {
1989 size = lp_readsize();
1990 size = MAX(size,1024);
1993 while (!buf && size>0) {
1994 buf = (char *)Realloc(buf,size+8);
1995 if (!buf) size /= 2;
1998 if (!buf) {
1999 DEBUG(0,("Can't allocate transfer buffer!\n"));
2000 exit(1);
2003 abuf = buf + (align%8);
2005 if (header)
2006 n += headlen;
2008 while (n > 0)
2010 int s = MIN(n,size);
2011 int ret,ret2=0;
2013 ret = 0;
2015 if (header && (headlen >= MIN(s,1024))) {
2016 buf1 = header;
2017 s = headlen;
2018 ret = headlen;
2019 headlen = 0;
2020 header = NULL;
2021 } else {
2022 buf1 = abuf;
2025 if (header && headlen > 0)
2027 ret = MIN(headlen,size);
2028 memcpy(buf1,header,ret);
2029 headlen -= ret;
2030 header += ret;
2031 if (headlen <= 0) header = NULL;
2034 if (s > ret)
2035 ret += read(infd,buf1+ret,s-ret);
2037 if (ret > 0)
2039 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2040 if (ret2 > 0) total += ret2;
2041 /* if we can't write then dump excess data */
2042 if (ret2 != ret)
2043 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2045 if (ret <= 0 || ret2 != ret)
2046 return(total);
2047 n -= ret;
2049 return(total);
2053 /****************************************************************************
2054 read 4 bytes of a smb packet and return the smb length of the packet
2055 possibly store the result in the buffer
2056 ****************************************************************************/
2057 int read_smb_length(int fd,char *inbuf,int timeout)
2059 char *buffer;
2060 char buf[4];
2061 int len=0, msg_type;
2062 BOOL ok=False;
2064 if (inbuf)
2065 buffer = inbuf;
2066 else
2067 buffer = buf;
2069 while (!ok)
2071 if (timeout > 0)
2072 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2073 else
2074 ok = (read_data(fd,buffer,4) == 4);
2076 if (!ok)
2077 return(-1);
2079 len = smb_len(buffer);
2080 msg_type = CVAL(buffer,0);
2082 if (msg_type == 0x85)
2084 DEBUG(5,("Got keepalive packet\n"));
2085 ok = False;
2089 DEBUG(10,("got smb length of %d\n",len));
2091 return(len);
2096 /****************************************************************************
2097 read an smb from a fd and return it's length
2098 The timeout is in milli seconds
2099 ****************************************************************************/
2100 BOOL receive_smb(int fd,char *buffer,int timeout)
2102 int len,ret;
2104 smb_read_error = 0;
2106 bzero(buffer,smb_size + 100);
2108 len = read_smb_length(fd,buffer,timeout);
2109 if (len == -1)
2110 return(False);
2112 if (len > BUFFER_SIZE) {
2113 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2114 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2115 exit(1);
2118 ret = read_data(fd,buffer+4,len);
2119 if (ret != len) {
2120 smb_read_error = READ_ERROR;
2121 return False;
2124 return(True);
2128 /****************************************************************************
2129 send an smb to a fd
2130 ****************************************************************************/
2131 BOOL send_smb(int fd,char *buffer)
2133 int len;
2134 int ret,nwritten=0;
2135 len = smb_len(buffer) + 4;
2137 while (nwritten < len)
2139 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2140 if (ret <= 0)
2142 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2143 close_sockets();
2144 exit(1);
2146 nwritten += ret;
2150 return True;
2154 /****************************************************************************
2155 find a pointer to a netbios name
2156 ****************************************************************************/
2157 char *name_ptr(char *buf,int ofs)
2159 unsigned char c = *(unsigned char *)(buf+ofs);
2161 if ((c & 0xC0) == 0xC0)
2163 uint16 l;
2164 char p[2];
2165 memcpy(p,buf+ofs,2);
2166 p[0] &= ~0xC0;
2167 l = RSVAL(p,0);
2168 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2169 return(buf + l);
2171 else
2172 return(buf+ofs);
2175 /****************************************************************************
2176 extract a netbios name from a buf
2177 ****************************************************************************/
2178 int name_extract(char *buf,int ofs,char *name)
2180 char *p = name_ptr(buf,ofs);
2181 int d = PTR_DIFF(p,buf+ofs);
2182 strcpy(name,"");
2183 if (d < -50 || d > 50) return(0);
2184 return(name_interpret(p,name));
2188 /****************************************************************************
2189 return the total storage length of a mangled name
2190 ****************************************************************************/
2191 int name_len(char *s)
2193 char *s0=s;
2194 unsigned char c = *(unsigned char *)s;
2195 if ((c & 0xC0) == 0xC0)
2196 return(2);
2197 while (*s) s += (*s)+1;
2198 return(PTR_DIFF(s,s0)+1);
2201 /****************************************************************************
2202 send a single packet to a port on another machine
2203 ****************************************************************************/
2204 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2206 BOOL ret;
2207 int out_fd;
2208 struct sockaddr_in sock_out;
2210 if (passive)
2211 return(True);
2213 /* create a socket to write to */
2214 out_fd = socket(AF_INET, type, 0);
2215 if (out_fd == -1)
2217 DEBUG(0,("socket failed"));
2218 return False;
2221 /* set the address and port */
2222 bzero((char *)&sock_out,sizeof(sock_out));
2223 putip((char *)&sock_out.sin_addr,(char *)&ip);
2224 sock_out.sin_port = htons( port );
2225 sock_out.sin_family = AF_INET;
2227 if (DEBUGLEVEL > 0)
2228 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2229 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2231 /* send it */
2232 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2234 if (!ret)
2235 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2236 inet_ntoa(ip),port,errno));
2238 close(out_fd);
2239 return(ret);
2242 /*******************************************************************
2243 sleep for a specified number of milliseconds
2244 ********************************************************************/
2245 void msleep(int t)
2247 int tdiff=0;
2248 struct timeval tval,t1,t2;
2249 fd_set fds;
2251 GetTimeOfDay(&t1);
2252 GetTimeOfDay(&t2);
2254 while (tdiff < t) {
2255 tval.tv_sec = (t-tdiff)/1000;
2256 tval.tv_usec = 1000*((t-tdiff)%1000);
2258 FD_ZERO(&fds);
2259 errno = 0;
2260 sys_select(&fds,&tval);
2262 GetTimeOfDay(&t2);
2263 tdiff = TvalDiff(&t1,&t2);
2267 /****************************************************************************
2268 check if a string is part of a list
2269 ****************************************************************************/
2270 BOOL in_list(char *s,char *list,BOOL casesensitive)
2272 pstring tok;
2273 char *p=list;
2275 if (!list) return(False);
2277 while (next_token(&p,tok,LIST_SEP))
2279 if (casesensitive) {
2280 if (strcmp(tok,s) == 0)
2281 return(True);
2282 } else {
2283 if (StrCaseCmp(tok,s) == 0)
2284 return(True);
2287 return(False);
2290 /* this is used to prevent lots of mallocs of size 1 */
2291 static char *null_string = NULL;
2293 /****************************************************************************
2294 set a string value, allocing the space for the string
2295 ****************************************************************************/
2296 BOOL string_init(char **dest,char *src)
2298 int l;
2299 if (!src)
2300 src = "";
2302 l = strlen(src);
2304 if (l == 0)
2306 if (!null_string)
2307 null_string = (char *)malloc(1);
2309 *null_string = 0;
2310 *dest = null_string;
2312 else
2314 *dest = (char *)malloc(l+1);
2315 strcpy(*dest,src);
2317 return(True);
2320 /****************************************************************************
2321 free a string value
2322 ****************************************************************************/
2323 void string_free(char **s)
2325 if (!s || !(*s)) return;
2326 if (*s == null_string)
2327 *s = NULL;
2328 if (*s) free(*s);
2329 *s = NULL;
2332 /****************************************************************************
2333 set a string value, allocing the space for the string, and deallocating any
2334 existing space
2335 ****************************************************************************/
2336 BOOL string_set(char **dest,char *src)
2338 string_free(dest);
2340 return(string_init(dest,src));
2343 /****************************************************************************
2344 substitute a string for a pattern in another string. Make sure there is
2345 enough room!
2347 This routine looks for pattern in s and replaces it with
2348 insert. It may do multiple replacements.
2350 return True if a substitution was done.
2351 ****************************************************************************/
2352 BOOL string_sub(char *s,char *pattern,char *insert)
2354 BOOL ret = False;
2355 char *p;
2356 int ls,lp,li;
2358 if (!insert || !pattern || !s) return(False);
2360 ls = strlen(s);
2361 lp = strlen(pattern);
2362 li = strlen(insert);
2364 if (!*pattern) return(False);
2366 while (lp <= ls && (p = strstr(s,pattern)))
2368 ret = True;
2369 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2370 memcpy(p,insert,li);
2371 s = p + li;
2372 ls = strlen(s);
2374 return(ret);
2379 /*********************************************************
2380 * Recursive routine that is called by mask_match.
2381 * Does the actual matching.
2382 *********************************************************/
2383 BOOL do_match(char *str, char *regexp, int case_sig)
2385 char *p;
2387 for( p = regexp; *p && *str; ) {
2388 switch(*p) {
2389 case '?':
2390 str++; p++;
2391 break;
2393 case '*':
2394 /* Look for a character matching
2395 the one after the '*' */
2396 p++;
2397 if(!*p)
2398 return True; /* Automatic match */
2399 while(*str) {
2400 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2401 str++;
2402 if(do_match(str,p,case_sig))
2403 return True;
2404 if(!*str)
2405 return False;
2406 else
2407 str++;
2409 return False;
2411 default:
2412 if(case_sig) {
2413 if(*str != *p)
2414 return False;
2415 } else {
2416 if(toupper(*str) != toupper(*p))
2417 return False;
2419 str++, p++;
2420 break;
2423 if(!*p && !*str)
2424 return True;
2426 if (!*p && str[0] == '.' && str[1] == 0)
2427 return(True);
2429 if (!*str && *p == '?')
2431 while (*p == '?') p++;
2432 return(!*p);
2435 if(!*str && (*p == '*' && p[1] == '\0'))
2436 return True;
2437 return False;
2441 /*********************************************************
2442 * Routine to match a given string with a regexp - uses
2443 * simplified regexp that takes * and ? only. Case can be
2444 * significant or not.
2445 *********************************************************/
2446 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2448 char *p;
2449 pstring p1, p2;
2450 fstring ebase,eext,sbase,sext;
2452 BOOL matched;
2454 /* Make local copies of str and regexp */
2455 StrnCpy(p1,regexp,sizeof(pstring)-1);
2456 StrnCpy(p2,str,sizeof(pstring)-1);
2458 if (!strchr(p2,'.')) {
2459 strcat(p2,".");
2463 if (!strchr(p1,'.')) {
2464 strcat(p1,".");
2468 #if 0
2469 if (strchr(p1,'.'))
2471 string_sub(p1,"*.*","*");
2472 string_sub(p1,".*","*");
2474 #endif
2476 /* Remove any *? and ** as they are meaningless */
2477 for(p = p1; *p; p++)
2478 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2479 (void)strcpy( &p[1], &p[2]);
2481 if (strequal(p1,"*")) return(True);
2483 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2485 if (trans2) {
2486 strcpy(ebase,p1);
2487 strcpy(sbase,p2);
2488 } else {
2489 if ((p=strrchr(p1,'.'))) {
2490 *p = 0;
2491 strcpy(ebase,p1);
2492 strcpy(eext,p+1);
2493 } else {
2494 strcpy(ebase,p1);
2495 eext[0] = 0;
2498 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2499 *p = 0;
2500 strcpy(sbase,p2);
2501 strcpy(sext,p+1);
2502 } else {
2503 strcpy(sbase,p2);
2504 strcpy(sext,"");
2508 matched = do_match(sbase,ebase,case_sig) &&
2509 (trans2 || do_match(sext,eext,case_sig));
2511 DEBUG(5,("mask_match returning %d\n", matched));
2513 return matched;
2518 /****************************************************************************
2519 become a daemon, discarding the controlling terminal
2520 ****************************************************************************/
2521 void become_daemon(void)
2523 #ifndef NO_FORK_DEBUG
2524 if (fork())
2525 exit(0);
2527 /* detach from the terminal */
2528 #ifdef USE_SETSID
2529 setsid();
2530 #else
2531 #ifdef TIOCNOTTY
2533 int i = open("/dev/tty", O_RDWR);
2534 if (i >= 0)
2536 ioctl(i, (int) TIOCNOTTY, (char *)0);
2537 close(i);
2540 #endif
2541 #endif
2542 #endif
2546 /****************************************************************************
2547 put up a yes/no prompt
2548 ****************************************************************************/
2549 BOOL yesno(char *p)
2551 pstring ans;
2552 printf("%s",p);
2554 if (!fgets(ans,sizeof(ans)-1,stdin))
2555 return(False);
2557 if (*ans == 'y' || *ans == 'Y')
2558 return(True);
2560 return(False);
2563 /****************************************************************************
2564 read a line from a file with possible \ continuation chars.
2565 Blanks at the start or end of a line are stripped.
2566 The string will be allocated if s2 is NULL
2567 ****************************************************************************/
2568 char *fgets_slash(char *s2,int maxlen,FILE *f)
2570 char *s=s2;
2571 int len = 0;
2572 int c;
2573 BOOL start_of_line = True;
2575 if (feof(f))
2576 return(NULL);
2578 if (!s2)
2580 maxlen = MIN(maxlen,8);
2581 s = (char *)Realloc(s,maxlen);
2584 if (!s || maxlen < 2) return(NULL);
2586 *s = 0;
2588 while (len < maxlen-1)
2590 c = getc(f);
2591 switch (c)
2593 case '\r':
2594 break;
2595 case '\n':
2596 while (len > 0 && s[len-1] == ' ')
2598 s[--len] = 0;
2600 if (len > 0 && s[len-1] == '\\')
2602 s[--len] = 0;
2603 start_of_line = True;
2604 break;
2606 return(s);
2607 case EOF:
2608 if (len <= 0 && !s2)
2609 free(s);
2610 return(len>0?s:NULL);
2611 case ' ':
2612 if (start_of_line)
2613 break;
2614 default:
2615 start_of_line = False;
2616 s[len++] = c;
2617 s[len] = 0;
2619 if (!s2 && len > maxlen-3)
2621 maxlen *= 2;
2622 s = (char *)Realloc(s,maxlen);
2623 if (!s) return(NULL);
2626 return(s);
2631 /****************************************************************************
2632 set the length of a file from a filedescriptor.
2633 Returns 0 on success, -1 on failure.
2634 ****************************************************************************/
2635 int set_filelen(int fd, long len)
2637 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2638 extend a file with ftruncate. Provide alternate implementation
2639 for this */
2641 #if FTRUNCATE_CAN_EXTEND
2642 return ftruncate(fd, len);
2643 #else
2644 struct stat st;
2645 char c = 0;
2646 long currpos = lseek(fd, 0L, SEEK_CUR);
2648 if(currpos < 0)
2649 return -1;
2650 /* Do an fstat to see if the file is longer than
2651 the requested size (call ftruncate),
2652 or shorter, in which case seek to len - 1 and write 1
2653 byte of zero */
2654 if(fstat(fd, &st)<0)
2655 return -1;
2657 #ifdef S_ISFIFO
2658 if (S_ISFIFO(st.st_mode)) return 0;
2659 #endif
2661 if(st.st_size == len)
2662 return 0;
2663 if(st.st_size > len)
2664 return ftruncate(fd, len);
2666 if(lseek(fd, len-1, SEEK_SET) != len -1)
2667 return -1;
2668 if(write(fd, &c, 1)!=1)
2669 return -1;
2670 /* Seek to where we were */
2671 lseek(fd, currpos, SEEK_SET);
2672 return 0;
2673 #endif
2677 /****************************************************************************
2678 return the byte checksum of some data
2679 ****************************************************************************/
2680 int byte_checksum(char *buf,int len)
2682 unsigned char *p = (unsigned char *)buf;
2683 int ret = 0;
2684 while (len--)
2685 ret += *p++;
2686 return(ret);
2691 #ifdef HPUX
2692 /****************************************************************************
2693 this is a version of setbuffer() for those machines that only have setvbuf
2694 ****************************************************************************/
2695 void setbuffer(FILE *f,char *buf,int bufsize)
2697 setvbuf(f,buf,_IOFBF,bufsize);
2699 #endif
2702 /****************************************************************************
2703 parse out a directory name from a path name. Assumes dos style filenames.
2704 ****************************************************************************/
2705 char *dirname_dos(char *path,char *buf)
2707 char *p = strrchr(path,'\\');
2709 if (!p)
2710 strcpy(buf,path);
2711 else
2713 *p = 0;
2714 strcpy(buf,path);
2715 *p = '\\';
2718 return(buf);
2722 /****************************************************************************
2723 parse out a filename from a path name. Assumes dos style filenames.
2724 ****************************************************************************/
2725 static char *filename_dos(char *path,char *buf)
2727 char *p = strrchr(path,'\\');
2729 if (!p)
2730 strcpy(buf,path);
2731 else
2732 strcpy(buf,p+1);
2734 return(buf);
2739 /****************************************************************************
2740 expand a pointer to be a particular size
2741 ****************************************************************************/
2742 void *Realloc(void *p,int size)
2744 void *ret=NULL;
2746 if (size == 0) {
2747 if (p) free(p);
2748 DEBUG(5,("Realloc asked for 0 bytes\n"));
2749 return NULL;
2752 if (!p)
2753 ret = (void *)malloc(size);
2754 else
2755 ret = (void *)realloc(p,size);
2757 if (!ret)
2758 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2760 return(ret);
2763 #ifdef NOSTRDUP
2764 /****************************************************************************
2765 duplicate a string
2766 ****************************************************************************/
2767 char *strdup(char *s)
2769 char *ret = NULL;
2770 if (!s) return(NULL);
2771 ret = (char *)malloc(strlen(s)+1);
2772 if (!ret) return(NULL);
2773 strcpy(ret,s);
2774 return(ret);
2776 #endif
2779 /****************************************************************************
2780 Signal handler for SIGPIPE (write on a disconnected socket)
2781 ****************************************************************************/
2782 void Abort(void )
2784 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2785 exit(2);
2788 /****************************************************************************
2789 get my own name and IP
2790 ****************************************************************************/
2791 BOOL get_myname(char *my_name,struct in_addr *ip)
2793 struct hostent *hp;
2794 pstring hostname;
2796 *hostname = 0;
2798 /* get my host name */
2799 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2801 DEBUG(0,("gethostname failed\n"));
2802 return False;
2805 /* get host info */
2806 if ((hp = Get_Hostbyname(hostname)) == 0)
2808 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2809 return False;
2812 if (my_name)
2814 /* split off any parts after an initial . */
2815 char *p = strchr(hostname,'.');
2816 if (p) *p = 0;
2818 strcpy(my_name,hostname);
2821 if (ip)
2822 putip((char *)ip,(char *)hp->h_addr);
2824 return(True);
2828 /****************************************************************************
2829 true if two IP addresses are equal
2830 ****************************************************************************/
2831 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2833 uint32 a1,a2;
2834 a1 = ntohl(ip1.s_addr);
2835 a2 = ntohl(ip2.s_addr);
2836 return(a1 == a2);
2840 /****************************************************************************
2841 open a socket of the specified type, port and address for incoming data
2842 ****************************************************************************/
2843 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2845 struct hostent *hp;
2846 struct sockaddr_in sock;
2847 pstring host_name;
2848 int res;
2850 /* get my host name */
2851 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2852 { DEBUG(0,("gethostname failed\n")); return -1; }
2854 /* get host info */
2855 if ((hp = Get_Hostbyname(host_name)) == 0)
2857 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2858 return -1;
2861 bzero((char *)&sock,sizeof(sock));
2862 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2863 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2864 sock.sin_len = sizeof(sock);
2865 #endif
2866 sock.sin_port = htons( port );
2867 sock.sin_family = hp->h_addrtype;
2868 sock.sin_addr.s_addr = socket_addr;
2869 res = socket(hp->h_addrtype, type, 0);
2870 if (res == -1)
2871 { DEBUG(0,("socket failed\n")); return -1; }
2874 int one=1;
2875 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2878 /* now we've got a socket - we need to bind it */
2879 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2881 if (port) {
2882 if (port == SMB_PORT || port == NMB_PORT)
2883 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2884 port,socket_addr,strerror(errno)));
2885 close(res);
2887 if (dlevel > 0 && port < 1000)
2888 port = 7999;
2890 if (port >= 1000 && port < 9000)
2891 return(open_socket_in(type,port+1,dlevel,socket_addr));
2894 return(-1);
2896 DEBUG(3,("bind succeeded on port %d\n",port));
2898 return res;
2902 /****************************************************************************
2903 create an outgoing socket
2904 **************************************************************************/
2905 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2907 struct sockaddr_in sock_out;
2908 int res,ret;
2909 int connect_loop = 250; /* 250 milliseconds */
2910 int loops = (timeout * 1000) / connect_loop;
2912 /* create a socket to write to */
2913 res = socket(PF_INET, type, 0);
2914 if (res == -1)
2915 { DEBUG(0,("socket error\n")); return -1; }
2917 if (type != SOCK_STREAM) return(res);
2919 bzero((char *)&sock_out,sizeof(sock_out));
2920 putip((char *)&sock_out.sin_addr,(char *)addr);
2922 sock_out.sin_port = htons( port );
2923 sock_out.sin_family = PF_INET;
2925 /* set it non-blocking */
2926 set_blocking(res,0);
2928 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2930 /* and connect it to the destination */
2931 connect_again:
2932 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2934 /* Some systems return EAGAIN when they mean EINPROGRESS */
2935 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2936 errno == EAGAIN) && loops--) {
2937 msleep(connect_loop);
2938 goto connect_again;
2941 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2942 errno == EAGAIN)) {
2943 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2944 close(res);
2945 return -1;
2948 #ifdef EISCONN
2949 if (ret < 0 && errno == EISCONN) {
2950 errno = 0;
2951 ret = 0;
2953 #endif
2955 if (ret < 0) {
2956 DEBUG(1,("error connecting to %s:%d (%s)\n",
2957 inet_ntoa(*addr),port,strerror(errno)));
2958 return -1;
2961 /* set it blocking again */
2962 set_blocking(res,1);
2964 return res;
2968 /****************************************************************************
2969 interpret a protocol description string, with a default
2970 ****************************************************************************/
2971 int interpret_protocol(char *str,int def)
2973 if (strequal(str,"NT1"))
2974 return(PROTOCOL_NT1);
2975 if (strequal(str,"LANMAN2"))
2976 return(PROTOCOL_LANMAN2);
2977 if (strequal(str,"LANMAN1"))
2978 return(PROTOCOL_LANMAN1);
2979 if (strequal(str,"CORE"))
2980 return(PROTOCOL_CORE);
2981 if (strequal(str,"COREPLUS"))
2982 return(PROTOCOL_COREPLUS);
2983 if (strequal(str,"CORE+"))
2984 return(PROTOCOL_COREPLUS);
2986 DEBUG(0,("Unrecognised protocol level %s\n",str));
2988 return(def);
2991 /****************************************************************************
2992 interpret a security level
2993 ****************************************************************************/
2994 int interpret_security(char *str,int def)
2996 if (strequal(str,"SERVER"))
2997 return(SEC_SERVER);
2998 if (strequal(str,"USER"))
2999 return(SEC_USER);
3000 if (strequal(str,"SHARE"))
3001 return(SEC_SHARE);
3003 DEBUG(0,("Unrecognised security level %s\n",str));
3005 return(def);
3009 /****************************************************************************
3010 interpret an internet address or name into an IP address in 4 byte form
3011 ****************************************************************************/
3012 uint32 interpret_addr(char *str)
3014 struct hostent *hp;
3015 uint32 res;
3016 int i;
3017 BOOL pure_address = True;
3019 if (strcmp(str,"0.0.0.0") == 0) return(0);
3020 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3022 for (i=0; pure_address && str[i]; i++)
3023 if (!(isdigit(str[i]) || str[i] == '.'))
3024 pure_address = False;
3026 /* if it's in the form of an IP address then get the lib to interpret it */
3027 if (pure_address) {
3028 res = inet_addr(str);
3029 } else {
3030 /* otherwise assume it's a network name of some sort and use
3031 Get_Hostbyname */
3032 if ((hp = Get_Hostbyname(str)) == 0) {
3033 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3034 return 0;
3036 putip((char *)&res,(char *)hp->h_addr);
3039 if (res == (uint32)-1) return(0);
3041 return(res);
3044 /*******************************************************************
3045 a convenient addition to interpret_addr()
3046 ******************************************************************/
3047 struct in_addr *interpret_addr2(char *str)
3049 static struct in_addr ret;
3050 uint32 a = interpret_addr(str);
3051 ret.s_addr = a;
3052 return(&ret);
3055 /*******************************************************************
3056 check if an IP is the 0.0.0.0
3057 ******************************************************************/
3058 BOOL zero_ip(struct in_addr ip)
3060 uint32 a;
3061 putip((char *)&a,(char *)&ip);
3062 return(a == 0);
3066 /*******************************************************************
3067 matchname - determine if host name matches IP address
3068 ******************************************************************/
3069 static BOOL matchname(char *remotehost,struct in_addr addr)
3071 struct hostent *hp;
3072 int i;
3074 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3075 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3076 return False;
3080 * Make sure that gethostbyname() returns the "correct" host name.
3081 * Unfortunately, gethostbyname("localhost") sometimes yields
3082 * "localhost.domain". Since the latter host name comes from the
3083 * local DNS, we just have to trust it (all bets are off if the local
3084 * DNS is perverted). We always check the address list, though.
3087 if (strcasecmp(remotehost, hp->h_name)
3088 && strcasecmp(remotehost, "localhost")) {
3089 DEBUG(0,("host name/name mismatch: %s != %s",
3090 remotehost, hp->h_name));
3091 return False;
3094 /* Look up the host address in the address list we just got. */
3095 for (i = 0; hp->h_addr_list[i]; i++) {
3096 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3097 return True;
3101 * The host name does not map to the original host address. Perhaps
3102 * someone has compromised a name server. More likely someone botched
3103 * it, but that could be dangerous, too.
3106 DEBUG(0,("host name/address mismatch: %s != %s",
3107 inet_ntoa(addr), hp->h_name));
3108 return False;
3111 /*******************************************************************
3112 Reset the 'done' variables so after a client process is created
3113 from a fork call these calls will be re-done. This should be
3114 expanded if more variables need reseting.
3115 ******************************************************************/
3117 static BOOL global_client_name_done = False;
3118 static BOOL global_client_addr_done = False;
3120 void reset_globals_after_fork()
3122 global_client_name_done = False;
3123 global_client_addr_done = False;
3126 /*******************************************************************
3127 return the DNS name of the client
3128 ******************************************************************/
3129 char *client_name(void)
3131 extern int Client;
3132 struct sockaddr sa;
3133 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3134 int length = sizeof(sa);
3135 static pstring name_buf;
3136 struct hostent *hp;
3138 if (global_client_name_done)
3139 return name_buf;
3141 strcpy(name_buf,"UNKNOWN");
3143 if (getpeername(Client, &sa, &length) < 0) {
3144 DEBUG(0,("getpeername failed\n"));
3145 return name_buf;
3148 /* Look up the remote host name. */
3149 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3150 sizeof(sockin->sin_addr),
3151 AF_INET)) == 0) {
3152 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3153 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3154 } else {
3155 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3156 if (!matchname(name_buf, sockin->sin_addr)) {
3157 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3158 strcpy(name_buf,"UNKNOWN");
3161 global_client_name_done = True;
3162 return name_buf;
3165 /*******************************************************************
3166 return the IP addr of the client as a string
3167 ******************************************************************/
3168 char *client_addr(void)
3170 extern int Client;
3171 struct sockaddr sa;
3172 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3173 int length = sizeof(sa);
3174 static fstring addr_buf;
3176 if (global_client_addr_done)
3177 return addr_buf;
3179 strcpy(addr_buf,"0.0.0.0");
3181 if (getpeername(Client, &sa, &length) < 0) {
3182 DEBUG(0,("getpeername failed\n"));
3183 return addr_buf;
3186 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3188 global_client_addr_done = True;
3189 return addr_buf;
3192 /*******************************************************************
3193 sub strings with useful parameters
3194 ********************************************************************/
3195 void standard_sub_basic(char *s)
3197 if (!strchr(s,'%')) return;
3199 string_sub(s,"%R",remote_proto);
3200 string_sub(s,"%a",remote_arch);
3201 string_sub(s,"%m",remote_machine);
3202 string_sub(s,"%L",local_machine);
3204 if (!strchr(s,'%')) return;
3206 string_sub(s,"%v",VERSION);
3207 string_sub(s,"%h",myhostname);
3208 string_sub(s,"%U",sesssetup_user);
3210 if (!strchr(s,'%')) return;
3212 string_sub(s,"%I",client_addr());
3213 if (strstr(s,"%M"))
3214 string_sub(s,"%M",client_name());
3215 string_sub(s,"%T",timestring());
3217 if (!strchr(s,'%')) return;
3220 char pidstr[10];
3221 sprintf(pidstr,"%d",(int)getpid());
3222 string_sub(s,"%d",pidstr);
3225 if (!strchr(s,'%')) return;
3228 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3229 if (pass) {
3230 string_sub(s,"%G",gidtoname(pass->pw_gid));
3236 /*******************************************************************
3237 are two IPs on the same subnet?
3238 ********************************************************************/
3239 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3241 uint32 net1,net2,nmask;
3243 nmask = ntohl(mask.s_addr);
3244 net1 = ntohl(ip1.s_addr);
3245 net2 = ntohl(ip2.s_addr);
3247 return((net1 & nmask) == (net2 & nmask));
3251 /*******************************************************************
3252 write a string in unicoode format
3253 ********************************************************************/
3254 int PutUniCode(char *dst,char *src)
3256 int ret = 0;
3257 while (*src) {
3258 dst[ret++] = src[0];
3259 dst[ret++] = 0;
3260 src++;
3262 dst[ret++]=0;
3263 dst[ret++]=0;
3264 return(ret);
3267 /****************************************************************************
3268 a wrapper for gethostbyname() that tries with all lower and all upper case
3269 if the initial name fails
3270 ****************************************************************************/
3271 struct hostent *Get_Hostbyname(char *name)
3273 char *name2 = strdup(name);
3274 struct hostent *ret;
3276 if (!name2)
3278 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3279 exit(0);
3282 if (!isalnum(*name2))
3284 free(name2);
3285 return(NULL);
3288 ret = sys_gethostbyname(name2);
3289 if (ret != NULL)
3291 free(name2);
3292 return(ret);
3295 /* try with all lowercase */
3296 strlower(name2);
3297 ret = sys_gethostbyname(name2);
3298 if (ret != NULL)
3300 free(name2);
3301 return(ret);
3304 /* try with all uppercase */
3305 strupper(name2);
3306 ret = sys_gethostbyname(name2);
3307 if (ret != NULL)
3309 free(name2);
3310 return(ret);
3313 /* nothing works :-( */
3314 free(name2);
3315 return(NULL);
3319 /****************************************************************************
3320 check if a process exists. Does this work on all unixes?
3321 ****************************************************************************/
3322 BOOL process_exists(int pid)
3324 #ifdef LINUX
3325 fstring s;
3326 sprintf(s,"/proc/%d",pid);
3327 return(directory_exist(s,NULL));
3328 #else
3330 static BOOL tested=False;
3331 static BOOL ok=False;
3332 fstring s;
3333 if (!tested) {
3334 tested = True;
3335 sprintf(s,"/proc/%05d",(int)getpid());
3336 ok = file_exist(s,NULL);
3338 if (ok) {
3339 sprintf(s,"/proc/%05d",pid);
3340 return(file_exist(s,NULL));
3344 /* CGH 8/16/96 - added ESRCH test */
3345 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3346 #endif
3350 /*******************************************************************
3351 turn a uid into a user name
3352 ********************************************************************/
3353 char *uidtoname(int uid)
3355 static char name[40];
3356 struct passwd *pass = getpwuid(uid);
3357 if (pass) return(pass->pw_name);
3358 sprintf(name,"%d",uid);
3359 return(name);
3362 /*******************************************************************
3363 turn a gid into a group name
3364 ********************************************************************/
3365 char *gidtoname(int gid)
3367 static char name[40];
3368 struct group *grp = getgrgid(gid);
3369 if (grp) return(grp->gr_name);
3370 sprintf(name,"%d",gid);
3371 return(name);
3374 /*******************************************************************
3375 block sigs
3376 ********************************************************************/
3377 void BlockSignals(BOOL block,int signum)
3379 #ifdef USE_SIGBLOCK
3380 int block_mask = sigmask(signum);
3381 static int oldmask = 0;
3382 if (block)
3383 oldmask = sigblock(block_mask);
3384 else
3385 sigsetmask(oldmask);
3386 #elif defined(USE_SIGPROCMASK)
3387 sigset_t set;
3388 sigemptyset(&set);
3389 sigaddset(&set,signum);
3390 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3391 #endif
3394 #if AJT
3395 /*******************************************************************
3396 my own panic function - not suitable for general use
3397 ********************************************************************/
3398 void ajt_panic(void)
3400 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3402 #endif
3404 #ifdef USE_DIRECT
3405 #define DIRECT direct
3406 #else
3407 #define DIRECT dirent
3408 #endif
3410 /*******************************************************************
3411 a readdir wrapper which just returns the file name
3412 also return the inode number if requested
3413 ********************************************************************/
3414 char *readdirname(void *p)
3416 struct DIRECT *ptr;
3417 char *dname;
3419 if (!p) return(NULL);
3421 ptr = (struct DIRECT *)readdir(p);
3422 if (!ptr) return(NULL);
3424 dname = ptr->d_name;
3426 #ifdef NEXT2
3427 if (telldir(p) < 0) return(NULL);
3428 #endif
3430 #ifdef SUNOS5
3431 /* this handles a broken compiler setup, causing a mixture
3432 of BSD and SYSV headers and libraries */
3434 static BOOL broken_readdir = False;
3435 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3437 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3438 broken_readdir = True;
3440 if (broken_readdir)
3441 dname = dname - 2;
3443 #endif
3446 static pstring buf;
3447 strcpy(buf, dname);
3448 unix_to_dos(buf, True);
3449 dname = buf;
3452 return(dname);
3456 * Utility function used by is_hidden_path() and is_vetoed_name()
3457 * to decide if the last component of a path matches a (possibly
3458 * wildcarded) entry in a namelist.
3461 static BOOL is_in_path(char *name, char *namelist)
3463 pstring last_component;
3464 char *p;
3465 char *nameptr = namelist;
3466 char *name_end;
3468 DEBUG(5, ("is_in_path: %s list: %s\n", name, namelist));
3470 /* if we have no list it's obviously not in the path */
3471 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3473 DEBUG(5,("is_in_path: no name list. return False\n"));
3474 return False;
3477 /* Get the last component of the unix name. */
3478 p = strrchr(name, '/');
3479 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3480 last_component[sizeof(last_component)-1] = '\0';
3482 /* now, we need to find the names one by one and check them
3483 they can contain spaces and all sorts of stuff so we
3484 separate them with of all things '\' which can never be in a filename
3485 I could use "" but then I have to break them all out
3486 maybe such a routine exists somewhere?
3489 /* lkcl 03jul97 - the separator character used to be a '/'.
3490 i changed it to a '\', after examining the code, and seeing
3491 that unix_convert is called before check_path and dos_mode.
3492 unix_convert changes, in the path, all dos '\'s to unix '/'s.
3494 the alternatives are:
3496 1) move all check_path and dos_mode calls to before the
3497 unix_convert calls.
3499 2) have a corresponding dos_convert call, which can be used
3500 in here to reverse '/'s into '\'s and vice-versa. users
3501 would specify the lp_veto_files and lp_hide_files parameters
3502 in dos mode path format ('\' for directory separator), with a
3503 list separator of '/', and they would be swapped inside this
3504 function, before making the search.
3508 while (*nameptr)
3510 if ( *nameptr == '\\' )
3512 /* cope with multiple (useless) \s) */
3513 nameptr++;
3514 continue;
3516 /* find the next \ */
3517 if ((name_end = strchr(nameptr,'\\')) != NULL)
3519 *name_end = 0;
3522 /* look for a match. */
3523 if (mask_match(last_component, nameptr, case_sensitive, False))
3525 DEBUG(5,("is_in_path: mask match succeeded\n"));
3526 return True;
3529 /* oops - the last check for a \ didn't find one. */
3530 if (name_end == NULL)
3532 DEBUG(5,("is_in_path: last name. failed\n"));
3533 return False;
3536 /* next segment please */
3537 nameptr = name_end + 1;
3540 DEBUG(5,("is_in_path: not found\n"));
3542 return False;
3545 BOOL is_hidden_path(int snum, char *name)
3547 return is_in_path(name, lp_hide_files(snum));
3550 BOOL is_vetoed_name(int snum, char *name)
3552 return is_in_path(name, lp_veto_files(snum));
3555 /****************************************************************************
3556 routine to do file locking
3557 ****************************************************************************/
3558 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3560 #if HAVE_FCNTL_LOCK
3561 struct flock lock;
3562 int ret;
3564 #if 1
3565 uint32 mask = 0xC0000000;
3567 /* make sure the count is reasonable, we might kill the lockd otherwise */
3568 count &= ~mask;
3570 /* the offset is often strange - remove 2 of its bits if either of
3571 the top two bits are set. Shift the top ones by two bits. This
3572 still allows OLE2 apps to operate, but should stop lockd from
3573 dieing */
3574 if ((offset & mask) != 0)
3575 offset = (offset & ~mask) | ((offset & mask) >> 2);
3576 #else
3577 uint32 mask = ((unsigned)1<<31);
3579 /* interpret negative counts as large numbers */
3580 if (count < 0)
3581 count &= ~mask;
3583 /* no negative offsets */
3584 offset &= ~mask;
3586 /* count + offset must be in range */
3587 while ((offset < 0 || (offset + count < 0)) && mask)
3589 offset &= ~mask;
3590 mask = mask >> 1;
3592 #endif
3595 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3597 lock.l_type = type;
3598 lock.l_whence = SEEK_SET;
3599 lock.l_start = (int)offset;
3600 lock.l_len = (int)count;
3601 lock.l_pid = 0;
3603 errno = 0;
3605 ret = fcntl(fd,op,&lock);
3607 if (errno != 0)
3608 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3610 /* a lock query */
3611 if (op == F_GETLK)
3613 if ((ret != -1) &&
3614 (lock.l_type != F_UNLCK) &&
3615 (lock.l_pid != 0) &&
3616 (lock.l_pid != getpid()))
3618 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3619 return(True);
3622 /* it must be not locked or locked by me */
3623 return(False);
3626 /* a lock set or unset */
3627 if (ret == -1)
3629 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3630 offset,count,op,type,strerror(errno)));
3632 /* perhaps it doesn't support this sort of locking?? */
3633 if (errno == EINVAL)
3635 DEBUG(3,("locking not supported? returning True\n"));
3636 return(True);
3639 return(False);
3642 /* everything went OK */
3643 DEBUG(5,("Lock call successful\n"));
3645 return(True);
3646 #else
3647 return(False);
3648 #endif
3651 /*******************************************************************
3652 lock a file - returning a open file descriptor or -1 on failure
3653 The timeout is in seconds. 0 means no timeout
3654 ********************************************************************/
3655 int file_lock(char *name,int timeout)
3657 int fd = open(name,O_RDWR|O_CREAT,0666);
3658 time_t t=0;
3659 if (fd < 0) return(-1);
3661 #if HAVE_FCNTL_LOCK
3662 if (timeout) t = time(NULL);
3663 while (!timeout || (time(NULL)-t < timeout)) {
3664 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3665 msleep(LOCK_RETRY_TIMEOUT);
3667 return(-1);
3668 #else
3669 return(fd);
3670 #endif
3673 /*******************************************************************
3674 unlock a file locked by file_lock
3675 ********************************************************************/
3676 void file_unlock(int fd)
3678 if (fd<0) return;
3679 #if HAVE_FCNTL_LOCK
3680 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3681 #endif
3682 close(fd);