Makefile: Added AIX targets from Ole Holm Nielsen <Ole.H.Nielsen@uni-c.dk>
[Samba.git] / source / lib / util.c
blobf31ae390aa481733b81b10e97bee6459db93bc99
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 bcc=0;
999 if (DEBUGLEVEL < 5)
1000 return;
1002 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1003 smb_len(buf),
1004 (int)CVAL(buf,smb_com),
1005 (int)CVAL(buf,smb_rcls),
1006 (int)CVAL(buf,smb_reh),
1007 (int)SVAL(buf,smb_err),
1008 (int)CVAL(buf,smb_flg),
1009 (int)SVAL(buf,smb_flg2)));
1010 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1011 (int)SVAL(buf,smb_tid),
1012 (int)SVAL(buf,smb_pid),
1013 (int)SVAL(buf,smb_uid),
1014 (int)SVAL(buf,smb_mid),
1015 (int)CVAL(buf,smb_wct)));
1016 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1017 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1018 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1019 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1020 DEBUG(5,("smb_bcc=%d\n",bcc));
1021 if (DEBUGLEVEL < 10)
1022 return;
1023 for (i=0;i<MIN(bcc,128);i++)
1024 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1025 DEBUG(10,("\n"));
1028 /*******************************************************************
1029 return the length of an smb packet
1030 ********************************************************************/
1031 int smb_len(char *buf)
1033 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1036 /*******************************************************************
1037 set the length of an smb packet
1038 ********************************************************************/
1039 void _smb_setlen(char *buf,int len)
1041 buf[0] = 0;
1042 buf[1] = (len&0x10000)>>16;
1043 buf[2] = (len&0xFF00)>>8;
1044 buf[3] = len&0xFF;
1047 /*******************************************************************
1048 set the length and marker of an smb packet
1049 ********************************************************************/
1050 void smb_setlen(char *buf,int len)
1052 _smb_setlen(buf,len);
1054 CVAL(buf,4) = 0xFF;
1055 CVAL(buf,5) = 'S';
1056 CVAL(buf,6) = 'M';
1057 CVAL(buf,7) = 'B';
1060 /*******************************************************************
1061 setup the word count and byte count for a smb message
1062 ********************************************************************/
1063 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1065 if (zero)
1066 bzero(buf + smb_size,num_words*2 + num_bytes);
1067 CVAL(buf,smb_wct) = num_words;
1068 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1069 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1070 return (smb_size + num_words*2 + num_bytes);
1073 /*******************************************************************
1074 return the number of smb words
1075 ********************************************************************/
1076 int smb_numwords(char *buf)
1078 return (CVAL(buf,smb_wct));
1081 /*******************************************************************
1082 return the size of the smb_buf region of a message
1083 ********************************************************************/
1084 int smb_buflen(char *buf)
1086 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1089 /*******************************************************************
1090 return a pointer to the smb_buf data area
1091 ********************************************************************/
1092 int smb_buf_ofs(char *buf)
1094 return (smb_size + CVAL(buf,smb_wct)*2);
1097 /*******************************************************************
1098 return a pointer to the smb_buf data area
1099 ********************************************************************/
1100 char *smb_buf(char *buf)
1102 return (buf + smb_buf_ofs(buf));
1105 /*******************************************************************
1106 return the SMB offset into an SMB buffer
1107 ********************************************************************/
1108 int smb_offset(char *p,char *buf)
1110 return(PTR_DIFF(p,buf+4) + chain_size);
1114 /*******************************************************************
1115 skip past some strings in a buffer
1116 ********************************************************************/
1117 char *skip_string(char *buf,int n)
1119 while (n--)
1120 buf += strlen(buf) + 1;
1121 return(buf);
1124 /*******************************************************************
1125 trim the specified elements off the front and back of a string
1126 ********************************************************************/
1127 BOOL trim_string(char *s,char *front,char *back)
1129 BOOL ret = False;
1130 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1132 char *p = s;
1133 ret = True;
1134 while (1)
1136 if (!(*p = p[strlen(front)]))
1137 break;
1138 p++;
1141 while (back && *back && strlen(s) >= strlen(back) &&
1142 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1144 ret = True;
1145 s[strlen(s)-strlen(back)] = 0;
1147 return(ret);
1151 /*******************************************************************
1152 reduce a file name, removing .. elements.
1153 ********************************************************************/
1154 void dos_clean_name(char *s)
1156 char *p=NULL;
1158 DEBUG(3,("dos_clean_name [%s]\n",s));
1160 /* remove any double slashes */
1161 string_sub(s, "\\\\", "\\");
1163 while ((p = strstr(s,"\\..\\")) != NULL)
1165 pstring s1;
1167 *p = 0;
1168 strcpy(s1,p+3);
1170 if ((p=strrchr(s,'\\')) != NULL)
1171 *p = 0;
1172 else
1173 *s = 0;
1174 strcat(s,s1);
1177 trim_string(s,NULL,"\\..");
1179 string_sub(s, "\\.\\", "\\");
1182 /*******************************************************************
1183 reduce a file name, removing .. elements.
1184 ********************************************************************/
1185 void unix_clean_name(char *s)
1187 char *p=NULL;
1189 DEBUG(3,("unix_clean_name [%s]\n",s));
1191 /* remove any double slashes */
1192 string_sub(s, "//","/");
1194 /* Remove leading ./ characters */
1195 if(strncmp(s, "./", 2) == 0) {
1196 trim_string(s, "./", NULL);
1197 if(*s == 0)
1198 strcpy(s,"./");
1201 while ((p = strstr(s,"/../")) != NULL)
1203 pstring s1;
1205 *p = 0;
1206 strcpy(s1,p+3);
1208 if ((p=strrchr(s,'/')) != NULL)
1209 *p = 0;
1210 else
1211 *s = 0;
1212 strcat(s,s1);
1215 trim_string(s,NULL,"/..");
1219 /*******************************************************************
1220 a wrapper for the normal chdir() function
1221 ********************************************************************/
1222 int ChDir(char *path)
1224 int res;
1225 static pstring LastDir="";
1227 if (strcsequal(path,".")) return(0);
1229 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1230 DEBUG(3,("chdir to %s\n",path));
1231 res = sys_chdir(path);
1232 if (!res)
1233 strcpy(LastDir,path);
1234 return(res);
1238 /*******************************************************************
1239 return the absolute current directory path. A dumb version.
1240 ********************************************************************/
1241 static char *Dumb_GetWd(char *s)
1243 #ifdef USE_GETCWD
1244 return ((char *)getcwd(s,sizeof(pstring)));
1245 #else
1246 return ((char *)getwd(s));
1247 #endif
1251 /* number of list structures for a caching GetWd function. */
1252 #define MAX_GETWDCACHE (50)
1254 struct
1256 ino_t inode;
1257 dev_t dev;
1258 char *text;
1259 BOOL valid;
1260 } ino_list[MAX_GETWDCACHE];
1262 BOOL use_getwd_cache=True;
1264 /*******************************************************************
1265 return the absolute current directory path
1266 ********************************************************************/
1267 char *GetWd(char *str)
1269 pstring s;
1270 static BOOL getwd_cache_init = False;
1271 struct stat st, st2;
1272 int i;
1274 *s = 0;
1276 if (!use_getwd_cache)
1277 return(Dumb_GetWd(str));
1279 /* init the cache */
1280 if (!getwd_cache_init)
1282 getwd_cache_init = True;
1283 for (i=0;i<MAX_GETWDCACHE;i++)
1285 string_init(&ino_list[i].text,"");
1286 ino_list[i].valid = False;
1290 /* Get the inode of the current directory, if this doesn't work we're
1291 in trouble :-) */
1293 if (stat(".",&st) == -1)
1295 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1296 return(Dumb_GetWd(str));
1300 for (i=0; i<MAX_GETWDCACHE; i++)
1301 if (ino_list[i].valid)
1304 /* If we have found an entry with a matching inode and dev number
1305 then find the inode number for the directory in the cached string.
1306 If this agrees with that returned by the stat for the current
1307 directory then all is o.k. (but make sure it is a directory all
1308 the same...) */
1310 if (st.st_ino == ino_list[i].inode &&
1311 st.st_dev == ino_list[i].dev)
1313 if (stat(ino_list[i].text,&st2) == 0)
1315 if (st.st_ino == st2.st_ino &&
1316 st.st_dev == st2.st_dev &&
1317 (st2.st_mode & S_IFMT) == S_IFDIR)
1319 strcpy (str, ino_list[i].text);
1321 /* promote it for future use */
1322 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1323 return (str);
1325 else
1327 /* If the inode is different then something's changed,
1328 scrub the entry and start from scratch. */
1329 ino_list[i].valid = False;
1336 /* We don't have the information to hand so rely on traditional methods.
1337 The very slow getcwd, which spawns a process on some systems, or the
1338 not quite so bad getwd. */
1340 if (!Dumb_GetWd(s))
1342 DEBUG(0,("Getwd failed, errno %d\n",errno));
1343 return (NULL);
1346 strcpy(str,s);
1348 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1350 /* add it to the cache */
1351 i = MAX_GETWDCACHE - 1;
1352 string_set(&ino_list[i].text,s);
1353 ino_list[i].dev = st.st_dev;
1354 ino_list[i].inode = st.st_ino;
1355 ino_list[i].valid = True;
1357 /* put it at the top of the list */
1358 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1360 return (str);
1365 /*******************************************************************
1366 reduce a file name, removing .. elements and checking that
1367 it is below dir in the heirachy. This uses GetWd() and so must be run
1368 on the system that has the referenced file system.
1370 widelinks are allowed if widelinks is true
1371 ********************************************************************/
1372 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1374 #ifndef REDUCE_PATHS
1375 return True;
1376 #else
1377 pstring dir2;
1378 pstring wd;
1379 pstring basename;
1380 pstring newname;
1381 char *p=NULL;
1382 BOOL relative = (*s != '/');
1384 *dir2 = *wd = *basename = *newname = 0;
1386 if (widelinks)
1388 unix_clean_name(s);
1389 /* can't have a leading .. */
1390 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1392 DEBUG(3,("Illegal file name? (%s)\n",s));
1393 return(False);
1396 if (strlen(s) == 0)
1397 strcpy(s,"./");
1399 return(True);
1402 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1404 /* remove any double slashes */
1405 string_sub(s,"//","/");
1407 strcpy(basename,s);
1408 p = strrchr(basename,'/');
1410 if (!p)
1411 return(True);
1413 if (!GetWd(wd))
1415 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1416 return(False);
1419 if (ChDir(dir) != 0)
1421 DEBUG(0,("couldn't chdir to %s\n",dir));
1422 return(False);
1425 if (!GetWd(dir2))
1427 DEBUG(0,("couldn't getwd for %s\n",dir));
1428 ChDir(wd);
1429 return(False);
1433 if (p && (p != basename))
1435 *p = 0;
1436 if (strcmp(p+1,".")==0)
1437 p[1]=0;
1438 if (strcmp(p+1,"..")==0)
1439 *p = '/';
1442 if (ChDir(basename) != 0)
1444 ChDir(wd);
1445 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1446 return(False);
1449 if (!GetWd(newname))
1451 ChDir(wd);
1452 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1453 return(False);
1456 if (p && (p != basename))
1458 strcat(newname,"/");
1459 strcat(newname,p+1);
1463 int l = strlen(dir2);
1464 if (dir2[l-1] == '/')
1465 l--;
1467 if (strncmp(newname,dir2,l) != 0)
1469 ChDir(wd);
1470 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1471 return(False);
1474 if (relative)
1476 if (newname[l] == '/')
1477 strcpy(s,newname + l + 1);
1478 else
1479 strcpy(s,newname+l);
1481 else
1482 strcpy(s,newname);
1485 ChDir(wd);
1487 if (strlen(s) == 0)
1488 strcpy(s,"./");
1490 DEBUG(3,("reduced to %s\n",s));
1491 return(True);
1492 #endif
1495 /****************************************************************************
1496 expand some *s
1497 ****************************************************************************/
1498 static void expand_one(char *Mask,int len)
1500 char *p1;
1501 while ((p1 = strchr(Mask,'*')) != NULL)
1503 int lfill = (len+1) - strlen(Mask);
1504 int l1= (p1 - Mask);
1505 pstring tmp;
1506 strcpy(tmp,Mask);
1507 memset(tmp+l1,'?',lfill);
1508 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1509 strcpy(Mask,tmp);
1513 /****************************************************************************
1514 expand a wildcard expression, replacing *s with ?s
1515 ****************************************************************************/
1516 void expand_mask(char *Mask,BOOL doext)
1518 pstring mbeg,mext;
1519 pstring dirpart;
1520 pstring filepart;
1521 BOOL hasdot = False;
1522 char *p1;
1523 BOOL absolute = (*Mask == '\\');
1525 *mbeg = *mext = *dirpart = *filepart = 0;
1527 /* parse the directory and filename */
1528 if (strchr(Mask,'\\'))
1529 dirname_dos(Mask,dirpart);
1531 filename_dos(Mask,filepart);
1533 strcpy(mbeg,filepart);
1534 if ((p1 = strchr(mbeg,'.')) != NULL)
1536 hasdot = True;
1537 *p1 = 0;
1538 p1++;
1539 strcpy(mext,p1);
1541 else
1543 strcpy(mext,"");
1544 if (strlen(mbeg) > 8)
1546 strcpy(mext,mbeg + 8);
1547 mbeg[8] = 0;
1551 if (*mbeg == 0)
1552 strcpy(mbeg,"????????");
1553 if ((*mext == 0) && doext && !hasdot)
1554 strcpy(mext,"???");
1556 if (strequal(mbeg,"*") && *mext==0)
1557 strcpy(mext,"*");
1559 /* expand *'s */
1560 expand_one(mbeg,8);
1561 if (*mext)
1562 expand_one(mext,3);
1564 strcpy(Mask,dirpart);
1565 if (*dirpart || absolute) strcat(Mask,"\\");
1566 strcat(Mask,mbeg);
1567 strcat(Mask,".");
1568 strcat(Mask,mext);
1570 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1574 /****************************************************************************
1575 does a string have any uppercase chars in it?
1576 ****************************************************************************/
1577 BOOL strhasupper(char *s)
1579 while (*s)
1581 #ifdef KANJI
1582 if (is_shift_jis (*s)) {
1583 s += 2;
1584 } else if (is_kana (*s)) {
1585 s++;
1586 } else {
1587 if (isupper(*s)) return(True);
1588 s++;
1590 #else
1591 if (isupper(*s)) return(True);
1592 s++;
1593 #endif /* KANJI */
1595 return(False);
1598 /****************************************************************************
1599 does a string have any lowercase chars in it?
1600 ****************************************************************************/
1601 BOOL strhaslower(char *s)
1603 while (*s)
1605 #ifdef KANJI
1606 if (is_shift_jis (*s)) {
1607 s += 2;
1608 } else if (is_kana (*s)) {
1609 s++;
1610 } else {
1611 if (islower(*s)) return(True);
1612 s++;
1614 #else
1615 if (islower(*s)) return(True);
1616 s++;
1617 #endif /* KANJI */
1619 return(False);
1622 /****************************************************************************
1623 find the number of chars in a string
1624 ****************************************************************************/
1625 int count_chars(char *s,char c)
1627 int count=0;
1628 while (*s)
1630 if (*s == c)
1631 count++;
1632 s++;
1634 return(count);
1638 /****************************************************************************
1639 make a dir struct
1640 ****************************************************************************/
1641 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1643 char *p;
1644 pstring mask2;
1646 strcpy(mask2,mask);
1648 if ((mode & aDIR) != 0)
1649 size = 0;
1651 memset(buf+1,' ',11);
1652 if ((p = strchr(mask2,'.')) != NULL)
1654 *p = 0;
1655 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1656 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1657 *p = '.';
1659 else
1660 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1662 bzero(buf+21,DIR_STRUCT_SIZE-21);
1663 CVAL(buf,21) = mode;
1664 put_dos_date(buf,22,date);
1665 SSVAL(buf,26,size & 0xFFFF);
1666 SSVAL(buf,28,size >> 16);
1667 StrnCpy(buf+30,fname,12);
1668 if (!case_sensitive)
1669 strupper(buf+30);
1670 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1674 /*******************************************************************
1675 close the low 3 fd's and open dev/null in their place
1676 ********************************************************************/
1677 void close_low_fds(void)
1679 int fd;
1680 int i;
1681 close(0); close(1); close(2);
1682 /* try and use up these file descriptors, so silly
1683 library routines writing to stdout etc won't cause havoc */
1684 for (i=0;i<3;i++) {
1685 fd = open("/dev/null",O_RDWR,0);
1686 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1687 if (fd < 0) {
1688 DEBUG(0,("Can't open /dev/null\n"));
1689 return;
1691 if (fd != i) {
1692 DEBUG(0,("Didn't get file descriptor %d\n",i));
1693 return;
1698 /****************************************************************************
1699 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1700 else
1701 if SYSV use O_NDELAY
1702 if BSD use FNDELAY
1703 ****************************************************************************/
1704 int set_blocking(int fd, int set)
1706 int val;
1707 #ifdef O_NONBLOCK
1708 #define FLAG_TO_SET O_NONBLOCK
1709 #else
1710 #ifdef SYSV
1711 #define FLAG_TO_SET O_NDELAY
1712 #else /* BSD */
1713 #define FLAG_TO_SET FNDELAY
1714 #endif
1715 #endif
1717 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1718 return -1;
1719 if(set) /* Turn blocking on - ie. clear nonblock flag */
1720 val &= ~FLAG_TO_SET;
1721 else
1722 val |= FLAG_TO_SET;
1723 return fcntl( fd, F_SETFL, val);
1724 #undef FLAG_TO_SET
1728 /****************************************************************************
1729 write to a socket
1730 ****************************************************************************/
1731 int write_socket(int fd,char *buf,int len)
1733 int ret=0;
1735 if (passive)
1736 return(len);
1737 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1738 ret = write_data(fd,buf,len);
1740 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1741 return(ret);
1744 /****************************************************************************
1745 read from a socket
1746 ****************************************************************************/
1747 int read_udp_socket(int fd,char *buf,int len)
1749 int ret;
1750 struct sockaddr sock;
1751 int socklen;
1753 socklen = sizeof(sock);
1754 bzero((char *)&sock,socklen);
1755 bzero((char *)&lastip,sizeof(lastip));
1756 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1757 if (ret <= 0) {
1758 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1759 return(0);
1762 lastip = *(struct in_addr *) &sock.sa_data[2];
1763 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1765 return(ret);
1768 /****************************************************************************
1769 read data from a device with a timout in msec.
1770 mincount = if timeout, minimum to read before returning
1771 maxcount = number to be read.
1772 ****************************************************************************/
1773 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1775 fd_set fds;
1776 int selrtn;
1777 int readret;
1778 int nread = 0;
1779 struct timeval timeout;
1781 /* just checking .... */
1782 if (maxcnt <= 0) return(0);
1784 smb_read_error = 0;
1786 /* Blocking read */
1787 if (time_out <= 0) {
1788 if (mincnt == 0) mincnt = maxcnt;
1790 while (nread < mincnt) {
1791 readret = read(fd, buf + nread, maxcnt - nread);
1792 if (readret == 0) {
1793 smb_read_error = READ_EOF;
1794 return -1;
1797 if (readret == -1) {
1798 smb_read_error = READ_ERROR;
1799 return -1;
1801 nread += readret;
1803 return(nread);
1806 /* Most difficult - timeout read */
1807 /* If this is ever called on a disk file and
1808 mincnt is greater then the filesize then
1809 system performance will suffer severely as
1810 select always return true on disk files */
1812 /* Set initial timeout */
1813 timeout.tv_sec = time_out / 1000;
1814 timeout.tv_usec = 1000 * (time_out % 1000);
1816 for (nread=0; nread<mincnt; )
1818 FD_ZERO(&fds);
1819 FD_SET(fd,&fds);
1821 selrtn = sys_select(&fds,&timeout);
1823 /* Check if error */
1824 if(selrtn == -1) {
1825 /* something is wrong. Maybe the socket is dead? */
1826 smb_read_error = READ_ERROR;
1827 return -1;
1830 /* Did we timeout ? */
1831 if (selrtn == 0) {
1832 smb_read_error = READ_TIMEOUT;
1833 return -1;
1836 readret = read(fd, buf+nread, maxcnt-nread);
1837 if (readret == 0) {
1838 /* we got EOF on the file descriptor */
1839 smb_read_error = READ_EOF;
1840 return -1;
1843 if (readret == -1) {
1844 /* the descriptor is probably dead */
1845 smb_read_error = READ_ERROR;
1846 return -1;
1849 nread += readret;
1852 /* Return the number we got */
1853 return(nread);
1856 /****************************************************************************
1857 read data from the client. Maxtime is in milliseconds
1858 ****************************************************************************/
1859 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1861 fd_set fds;
1862 int selrtn;
1863 int nread;
1864 struct timeval timeout;
1866 FD_ZERO(&fds);
1867 FD_SET(fd,&fds);
1869 timeout.tv_sec = maxtime / 1000;
1870 timeout.tv_usec = (maxtime % 1000) * 1000;
1872 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1874 if (!FD_ISSET(fd,&fds))
1875 return 0;
1877 nread = read_udp_socket(fd, buffer, bufsize);
1879 /* return the number got */
1880 return(nread);
1883 /*******************************************************************
1884 find the difference in milliseconds between two struct timeval
1885 values
1886 ********************************************************************/
1887 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1889 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1890 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1893 /****************************************************************************
1894 send a keepalive packet (rfc1002)
1895 ****************************************************************************/
1896 BOOL send_keepalive(int client)
1898 unsigned char buf[4];
1900 buf[0] = 0x85;
1901 buf[1] = buf[2] = buf[3] = 0;
1903 return(write_data(client,(char *)buf,4) == 4);
1908 /****************************************************************************
1909 read data from the client, reading exactly N bytes.
1910 ****************************************************************************/
1911 int read_data(int fd,char *buffer,int N)
1913 int ret;
1914 int total=0;
1916 smb_read_error = 0;
1918 while (total < N)
1920 ret = read(fd,buffer + total,N - total);
1921 if (ret == 0) {
1922 smb_read_error = READ_EOF;
1923 return 0;
1925 if (ret == -1) {
1926 smb_read_error = READ_ERROR;
1927 return -1;
1929 total += ret;
1931 return total;
1935 /****************************************************************************
1936 write data to a fd
1937 ****************************************************************************/
1938 int write_data(int fd,char *buffer,int N)
1940 int total=0;
1941 int ret;
1943 while (total < N)
1945 ret = write(fd,buffer + total,N - total);
1947 if (ret == -1) return -1;
1948 if (ret == 0) return total;
1950 total += ret;
1952 return total;
1956 /****************************************************************************
1957 transfer some data between two fd's
1958 ****************************************************************************/
1959 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1961 static char *buf=NULL;
1962 static int size=0;
1963 char *buf1,*abuf;
1964 int total = 0;
1966 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1968 if (size == 0) {
1969 size = lp_readsize();
1970 size = MAX(size,1024);
1973 while (!buf && size>0) {
1974 buf = (char *)Realloc(buf,size+8);
1975 if (!buf) size /= 2;
1978 if (!buf) {
1979 DEBUG(0,("Can't allocate transfer buffer!\n"));
1980 exit(1);
1983 abuf = buf + (align%8);
1985 if (header)
1986 n += headlen;
1988 while (n > 0)
1990 int s = MIN(n,size);
1991 int ret,ret2=0;
1993 ret = 0;
1995 if (header && (headlen >= MIN(s,1024))) {
1996 buf1 = header;
1997 s = headlen;
1998 ret = headlen;
1999 headlen = 0;
2000 header = NULL;
2001 } else {
2002 buf1 = abuf;
2005 if (header && headlen > 0)
2007 ret = MIN(headlen,size);
2008 memcpy(buf1,header,ret);
2009 headlen -= ret;
2010 header += ret;
2011 if (headlen <= 0) header = NULL;
2014 if (s > ret)
2015 ret += read(infd,buf1+ret,s-ret);
2017 if (ret > 0)
2019 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2020 if (ret2 > 0) total += ret2;
2021 /* if we can't write then dump excess data */
2022 if (ret2 != ret)
2023 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2025 if (ret <= 0 || ret2 != ret)
2026 return(total);
2027 n -= ret;
2029 return(total);
2033 /****************************************************************************
2034 read 4 bytes of a smb packet and return the smb length of the packet
2035 possibly store the result in the buffer
2036 ****************************************************************************/
2037 int read_smb_length(int fd,char *inbuf,int timeout)
2039 char *buffer;
2040 char buf[4];
2041 int len=0, msg_type;
2042 BOOL ok=False;
2044 if (inbuf)
2045 buffer = inbuf;
2046 else
2047 buffer = buf;
2049 while (!ok)
2051 if (timeout > 0)
2052 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2053 else
2054 ok = (read_data(fd,buffer,4) == 4);
2056 if (!ok)
2057 return(-1);
2059 len = smb_len(buffer);
2060 msg_type = CVAL(buffer,0);
2062 if (msg_type == 0x85)
2064 DEBUG(5,("Got keepalive packet\n"));
2065 ok = False;
2069 DEBUG(10,("got smb length of %d\n",len));
2071 return(len);
2076 /****************************************************************************
2077 read an smb from a fd and return it's length
2078 The timeout is in milli seconds
2079 ****************************************************************************/
2080 BOOL receive_smb(int fd,char *buffer,int timeout)
2082 int len,ret;
2084 smb_read_error = 0;
2086 bzero(buffer,smb_size + 100);
2088 len = read_smb_length(fd,buffer,timeout);
2089 if (len == -1)
2090 return(False);
2092 if (len > BUFFER_SIZE) {
2093 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2094 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2095 exit(1);
2098 ret = read_data(fd,buffer+4,len);
2099 if (ret != len) {
2100 smb_read_error = READ_ERROR;
2101 return False;
2104 return(True);
2108 /****************************************************************************
2109 send an smb to a fd
2110 ****************************************************************************/
2111 BOOL send_smb(int fd,char *buffer)
2113 int len;
2114 int ret,nwritten=0;
2115 len = smb_len(buffer) + 4;
2117 while (nwritten < len)
2119 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2120 if (ret <= 0)
2122 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2123 close_sockets();
2124 exit(1);
2126 nwritten += ret;
2130 return True;
2134 /****************************************************************************
2135 find a pointer to a netbios name
2136 ****************************************************************************/
2137 char *name_ptr(char *buf,int ofs)
2139 unsigned char c = *(unsigned char *)(buf+ofs);
2141 if ((c & 0xC0) == 0xC0)
2143 uint16 l;
2144 char p[2];
2145 memcpy(p,buf+ofs,2);
2146 p[0] &= ~0xC0;
2147 l = RSVAL(p,0);
2148 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2149 return(buf + l);
2151 else
2152 return(buf+ofs);
2155 /****************************************************************************
2156 extract a netbios name from a buf
2157 ****************************************************************************/
2158 int name_extract(char *buf,int ofs,char *name)
2160 char *p = name_ptr(buf,ofs);
2161 int d = PTR_DIFF(p,buf+ofs);
2162 strcpy(name,"");
2163 if (d < -50 || d > 50) return(0);
2164 return(name_interpret(p,name));
2168 /****************************************************************************
2169 return the total storage length of a mangled name
2170 ****************************************************************************/
2171 int name_len(char *s)
2173 char *s0=s;
2174 unsigned char c = *(unsigned char *)s;
2175 if ((c & 0xC0) == 0xC0)
2176 return(2);
2177 while (*s) s += (*s)+1;
2178 return(PTR_DIFF(s,s0)+1);
2181 /****************************************************************************
2182 send a single packet to a port on another machine
2183 ****************************************************************************/
2184 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2186 BOOL ret;
2187 int out_fd;
2188 struct sockaddr_in sock_out;
2190 if (passive)
2191 return(True);
2193 /* create a socket to write to */
2194 out_fd = socket(AF_INET, type, 0);
2195 if (out_fd == -1)
2197 DEBUG(0,("socket failed"));
2198 return False;
2201 /* set the address and port */
2202 bzero((char *)&sock_out,sizeof(sock_out));
2203 putip((char *)&sock_out.sin_addr,(char *)&ip);
2204 sock_out.sin_port = htons( port );
2205 sock_out.sin_family = AF_INET;
2207 if (DEBUGLEVEL > 0)
2208 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2209 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2211 /* send it */
2212 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2214 if (!ret)
2215 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2216 inet_ntoa(ip),port,errno));
2218 close(out_fd);
2219 return(ret);
2222 /*******************************************************************
2223 sleep for a specified number of milliseconds
2224 ********************************************************************/
2225 void msleep(int t)
2227 int tdiff=0;
2228 struct timeval tval,t1,t2;
2229 fd_set fds;
2231 GetTimeOfDay(&t1);
2232 GetTimeOfDay(&t2);
2234 while (tdiff < t) {
2235 tval.tv_sec = (t-tdiff)/1000;
2236 tval.tv_usec = 1000*((t-tdiff)%1000);
2238 FD_ZERO(&fds);
2239 errno = 0;
2240 sys_select(&fds,&tval);
2242 GetTimeOfDay(&t2);
2243 tdiff = TvalDiff(&t1,&t2);
2247 /****************************************************************************
2248 check if a string is part of a list
2249 ****************************************************************************/
2250 BOOL in_list(char *s,char *list,BOOL casesensitive)
2252 pstring tok;
2253 char *p=list;
2255 if (!list) return(False);
2257 while (next_token(&p,tok,LIST_SEP))
2259 if (casesensitive) {
2260 if (strcmp(tok,s) == 0)
2261 return(True);
2262 } else {
2263 if (StrCaseCmp(tok,s) == 0)
2264 return(True);
2267 return(False);
2270 /* this is used to prevent lots of mallocs of size 1 */
2271 static char *null_string = NULL;
2273 /****************************************************************************
2274 set a string value, allocing the space for the string
2275 ****************************************************************************/
2276 BOOL string_init(char **dest,char *src)
2278 int l;
2279 if (!src)
2280 src = "";
2282 l = strlen(src);
2284 if (l == 0)
2286 if (!null_string)
2287 null_string = (char *)malloc(1);
2289 *null_string = 0;
2290 *dest = null_string;
2292 else
2294 *dest = (char *)malloc(l+1);
2295 strcpy(*dest,src);
2297 return(True);
2300 /****************************************************************************
2301 free a string value
2302 ****************************************************************************/
2303 void string_free(char **s)
2305 if (!s || !(*s)) return;
2306 if (*s == null_string)
2307 *s = NULL;
2308 if (*s) free(*s);
2309 *s = NULL;
2312 /****************************************************************************
2313 set a string value, allocing the space for the string, and deallocating any
2314 existing space
2315 ****************************************************************************/
2316 BOOL string_set(char **dest,char *src)
2318 string_free(dest);
2320 return(string_init(dest,src));
2323 /****************************************************************************
2324 substitute a string for a pattern in another string. Make sure there is
2325 enough room!
2327 This routine looks for pattern in s and replaces it with
2328 insert. It may do multiple replacements.
2330 return True if a substitution was done.
2331 ****************************************************************************/
2332 BOOL string_sub(char *s,char *pattern,char *insert)
2334 BOOL ret = False;
2335 char *p;
2336 int ls,lp,li;
2338 if (!insert || !pattern || !s) return(False);
2340 ls = strlen(s);
2341 lp = strlen(pattern);
2342 li = strlen(insert);
2344 if (!*pattern) return(False);
2346 while (lp <= ls && (p = strstr(s,pattern)))
2348 ret = True;
2349 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2350 memcpy(p,insert,li);
2351 s = p + li;
2352 ls = strlen(s);
2354 return(ret);
2359 /*********************************************************
2360 * Recursive routine that is called by mask_match.
2361 * Does the actual matching.
2362 *********************************************************/
2363 BOOL do_match(char *str, char *regexp, int case_sig)
2365 char *p;
2367 for( p = regexp; *p && *str; ) {
2368 switch(*p) {
2369 case '?':
2370 str++; p++;
2371 break;
2373 case '*':
2374 /* Look for a character matching
2375 the one after the '*' */
2376 p++;
2377 if(!*p)
2378 return True; /* Automatic match */
2379 while(*str) {
2380 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2381 str++;
2382 if(do_match(str,p,case_sig))
2383 return True;
2384 if(!*str)
2385 return False;
2386 else
2387 str++;
2389 return False;
2391 default:
2392 if(case_sig) {
2393 if(*str != *p)
2394 return False;
2395 } else {
2396 if(toupper(*str) != toupper(*p))
2397 return False;
2399 str++, p++;
2400 break;
2403 if(!*p && !*str)
2404 return True;
2406 if (!*p && str[0] == '.' && str[1] == 0)
2407 return(True);
2409 if (!*str && *p == '?')
2411 while (*p == '?') p++;
2412 return(!*p);
2415 if(!*str && (*p == '*' && p[1] == '\0'))
2416 return True;
2417 return False;
2421 /*********************************************************
2422 * Routine to match a given string with a regexp - uses
2423 * simplified regexp that takes * and ? only. Case can be
2424 * significant or not.
2425 *********************************************************/
2426 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2428 char *p;
2429 pstring p1, p2;
2430 fstring ebase,eext,sbase,sext;
2432 BOOL matched;
2434 /* Make local copies of str and regexp */
2435 StrnCpy(p1,regexp,sizeof(pstring)-1);
2436 StrnCpy(p2,str,sizeof(pstring)-1);
2438 if (!strchr(p2,'.')) {
2439 strcat(p2,".");
2443 if (!strchr(p1,'.')) {
2444 strcat(p1,".");
2448 #if 0
2449 if (strchr(p1,'.'))
2451 string_sub(p1,"*.*","*");
2452 string_sub(p1,".*","*");
2454 #endif
2456 /* Remove any *? and ** as they are meaningless */
2457 for(p = p1; *p; p++)
2458 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2459 (void)strcpy( &p[1], &p[2]);
2461 if (strequal(p1,"*")) return(True);
2463 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2465 if (trans2) {
2466 strcpy(ebase,p1);
2467 strcpy(sbase,p2);
2468 } else {
2469 if ((p=strrchr(p1,'.'))) {
2470 *p = 0;
2471 strcpy(ebase,p1);
2472 strcpy(eext,p+1);
2473 } else {
2474 strcpy(ebase,p1);
2475 eext[0] = 0;
2478 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2479 *p = 0;
2480 strcpy(sbase,p2);
2481 strcpy(sext,p+1);
2482 } else {
2483 strcpy(sbase,p2);
2484 strcpy(sext,"");
2488 matched = do_match(sbase,ebase,case_sig) &&
2489 (trans2 || do_match(sext,eext,case_sig));
2491 DEBUG(5,("mask_match returning %d\n", matched));
2493 return matched;
2498 /****************************************************************************
2499 become a daemon, discarding the controlling terminal
2500 ****************************************************************************/
2501 void become_daemon(void)
2503 #ifndef NO_FORK_DEBUG
2504 if (fork())
2505 exit(0);
2507 /* detach from the terminal */
2508 #ifdef USE_SETSID
2509 setsid();
2510 #else
2511 #ifdef TIOCNOTTY
2513 int i = open("/dev/tty", O_RDWR);
2514 if (i >= 0)
2516 ioctl(i, (int) TIOCNOTTY, (char *)0);
2517 close(i);
2520 #endif
2521 #endif
2522 #endif
2526 /****************************************************************************
2527 put up a yes/no prompt
2528 ****************************************************************************/
2529 BOOL yesno(char *p)
2531 pstring ans;
2532 printf("%s",p);
2534 if (!fgets(ans,sizeof(ans)-1,stdin))
2535 return(False);
2537 if (*ans == 'y' || *ans == 'Y')
2538 return(True);
2540 return(False);
2543 /****************************************************************************
2544 read a line from a file with possible \ continuation chars.
2545 Blanks at the start or end of a line are stripped.
2546 The string will be allocated if s2 is NULL
2547 ****************************************************************************/
2548 char *fgets_slash(char *s2,int maxlen,FILE *f)
2550 char *s=s2;
2551 int len = 0;
2552 int c;
2553 BOOL start_of_line = True;
2555 if (feof(f))
2556 return(NULL);
2558 if (!s2)
2560 maxlen = MIN(maxlen,8);
2561 s = (char *)Realloc(s,maxlen);
2564 if (!s || maxlen < 2) return(NULL);
2566 *s = 0;
2568 while (len < maxlen-1)
2570 c = getc(f);
2571 switch (c)
2573 case '\r':
2574 break;
2575 case '\n':
2576 while (len > 0 && s[len-1] == ' ')
2578 s[--len] = 0;
2580 if (len > 0 && s[len-1] == '\\')
2582 s[--len] = 0;
2583 start_of_line = True;
2584 break;
2586 return(s);
2587 case EOF:
2588 if (len <= 0 && !s2)
2589 free(s);
2590 return(len>0?s:NULL);
2591 case ' ':
2592 if (start_of_line)
2593 break;
2594 default:
2595 start_of_line = False;
2596 s[len++] = c;
2597 s[len] = 0;
2599 if (!s2 && len > maxlen-3)
2601 maxlen *= 2;
2602 s = (char *)Realloc(s,maxlen);
2603 if (!s) return(NULL);
2606 return(s);
2611 /****************************************************************************
2612 set the length of a file from a filedescriptor.
2613 Returns 0 on success, -1 on failure.
2614 ****************************************************************************/
2615 int set_filelen(int fd, long len)
2617 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2618 extend a file with ftruncate. Provide alternate implementation
2619 for this */
2621 #if FTRUNCATE_CAN_EXTEND
2622 return ftruncate(fd, len);
2623 #else
2624 struct stat st;
2625 char c = 0;
2626 long currpos = lseek(fd, 0L, SEEK_CUR);
2628 if(currpos < 0)
2629 return -1;
2630 /* Do an fstat to see if the file is longer than
2631 the requested size (call ftruncate),
2632 or shorter, in which case seek to len - 1 and write 1
2633 byte of zero */
2634 if(fstat(fd, &st)<0)
2635 return -1;
2637 #ifdef S_ISFIFO
2638 if (S_ISFIFO(st.st_mode)) return 0;
2639 #endif
2641 if(st.st_size == len)
2642 return 0;
2643 if(st.st_size > len)
2644 return ftruncate(fd, len);
2646 if(lseek(fd, len-1, SEEK_SET) != len -1)
2647 return -1;
2648 if(write(fd, &c, 1)!=1)
2649 return -1;
2650 /* Seek to where we were */
2651 lseek(fd, currpos, SEEK_SET);
2652 return 0;
2653 #endif
2657 /****************************************************************************
2658 return the byte checksum of some data
2659 ****************************************************************************/
2660 int byte_checksum(char *buf,int len)
2662 unsigned char *p = (unsigned char *)buf;
2663 int ret = 0;
2664 while (len--)
2665 ret += *p++;
2666 return(ret);
2671 #ifdef HPUX
2672 /****************************************************************************
2673 this is a version of setbuffer() for those machines that only have setvbuf
2674 ****************************************************************************/
2675 void setbuffer(FILE *f,char *buf,int bufsize)
2677 setvbuf(f,buf,_IOFBF,bufsize);
2679 #endif
2682 /****************************************************************************
2683 parse out a directory name from a path name. Assumes dos style filenames.
2684 ****************************************************************************/
2685 char *dirname_dos(char *path,char *buf)
2687 char *p = strrchr(path,'\\');
2689 if (!p)
2690 strcpy(buf,path);
2691 else
2693 *p = 0;
2694 strcpy(buf,path);
2695 *p = '\\';
2698 return(buf);
2702 /****************************************************************************
2703 parse out a filename from a path name. Assumes dos style filenames.
2704 ****************************************************************************/
2705 static char *filename_dos(char *path,char *buf)
2707 char *p = strrchr(path,'\\');
2709 if (!p)
2710 strcpy(buf,path);
2711 else
2712 strcpy(buf,p+1);
2714 return(buf);
2719 /****************************************************************************
2720 expand a pointer to be a particular size
2721 ****************************************************************************/
2722 void *Realloc(void *p,int size)
2724 void *ret=NULL;
2726 if (size == 0) {
2727 if (p) free(p);
2728 DEBUG(5,("Realloc asked for 0 bytes\n"));
2729 return NULL;
2732 if (!p)
2733 ret = (void *)malloc(size);
2734 else
2735 ret = (void *)realloc(p,size);
2737 if (!ret)
2738 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2740 return(ret);
2743 #ifdef NOSTRDUP
2744 /****************************************************************************
2745 duplicate a string
2746 ****************************************************************************/
2747 char *strdup(char *s)
2749 char *ret = NULL;
2750 if (!s) return(NULL);
2751 ret = (char *)malloc(strlen(s)+1);
2752 if (!ret) return(NULL);
2753 strcpy(ret,s);
2754 return(ret);
2756 #endif
2759 /****************************************************************************
2760 Signal handler for SIGPIPE (write on a disconnected socket)
2761 ****************************************************************************/
2762 void Abort(void )
2764 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2765 exit(2);
2768 /****************************************************************************
2769 get my own name and IP
2770 ****************************************************************************/
2771 BOOL get_myname(char *my_name,struct in_addr *ip)
2773 struct hostent *hp;
2774 pstring hostname;
2776 *hostname = 0;
2778 /* get my host name */
2779 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2781 DEBUG(0,("gethostname failed\n"));
2782 return False;
2785 /* get host info */
2786 if ((hp = Get_Hostbyname(hostname)) == 0)
2788 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2789 return False;
2792 if (my_name)
2794 /* split off any parts after an initial . */
2795 char *p = strchr(hostname,'.');
2796 if (p) *p = 0;
2798 strcpy(my_name,hostname);
2801 if (ip)
2802 putip((char *)ip,(char *)hp->h_addr);
2804 return(True);
2808 /****************************************************************************
2809 true if two IP addresses are equal
2810 ****************************************************************************/
2811 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2813 uint32 a1,a2;
2814 a1 = ntohl(ip1.s_addr);
2815 a2 = ntohl(ip2.s_addr);
2816 return(a1 == a2);
2820 /****************************************************************************
2821 open a socket of the specified type, port and address for incoming data
2822 ****************************************************************************/
2823 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2825 struct hostent *hp;
2826 struct sockaddr_in sock;
2827 pstring host_name;
2828 int res;
2830 /* get my host name */
2831 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2832 { DEBUG(0,("gethostname failed\n")); return -1; }
2834 /* get host info */
2835 if ((hp = Get_Hostbyname(host_name)) == 0)
2837 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2838 return -1;
2841 bzero((char *)&sock,sizeof(sock));
2842 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2843 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2844 sock.sin_len = sizeof(sock);
2845 #endif
2846 sock.sin_port = htons( port );
2847 sock.sin_family = hp->h_addrtype;
2848 sock.sin_addr.s_addr = socket_addr;
2849 res = socket(hp->h_addrtype, type, 0);
2850 if (res == -1)
2851 { DEBUG(0,("socket failed\n")); return -1; }
2854 int one=1;
2855 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2858 /* now we've got a socket - we need to bind it */
2859 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2861 if (port) {
2862 if (port == SMB_PORT || port == NMB_PORT)
2863 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2864 port,socket_addr,strerror(errno)));
2865 close(res);
2867 if (dlevel > 0 && port < 1000)
2868 port = 7999;
2870 if (port >= 1000 && port < 9000)
2871 return(open_socket_in(type,port+1,dlevel,socket_addr));
2874 return(-1);
2876 DEBUG(3,("bind succeeded on port %d\n",port));
2878 return res;
2882 /****************************************************************************
2883 create an outgoing socket
2884 **************************************************************************/
2885 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2887 struct sockaddr_in sock_out;
2888 int res,ret;
2889 int connect_loop = 250; /* 250 milliseconds */
2890 int loops = (timeout * 1000) / connect_loop;
2892 /* create a socket to write to */
2893 res = socket(PF_INET, type, 0);
2894 if (res == -1)
2895 { DEBUG(0,("socket error\n")); return -1; }
2897 if (type != SOCK_STREAM) return(res);
2899 bzero((char *)&sock_out,sizeof(sock_out));
2900 putip((char *)&sock_out.sin_addr,(char *)addr);
2902 sock_out.sin_port = htons( port );
2903 sock_out.sin_family = PF_INET;
2905 /* set it non-blocking */
2906 set_blocking(res,0);
2908 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2910 /* and connect it to the destination */
2911 connect_again:
2912 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2914 /* Some systems return EAGAIN when they mean EINPROGRESS */
2915 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2916 errno == EAGAIN) && loops--) {
2917 msleep(connect_loop);
2918 goto connect_again;
2921 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
2922 errno == EAGAIN)) {
2923 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2924 close(res);
2925 return -1;
2928 #ifdef EISCONN
2929 if (ret < 0 && errno == EISCONN) {
2930 errno = 0;
2931 ret = 0;
2933 #endif
2935 if (ret < 0) {
2936 DEBUG(1,("error connecting to %s:%d (%s)\n",
2937 inet_ntoa(*addr),port,strerror(errno)));
2938 return -1;
2941 /* set it blocking again */
2942 set_blocking(res,1);
2944 return res;
2948 /****************************************************************************
2949 interpret a protocol description string, with a default
2950 ****************************************************************************/
2951 int interpret_protocol(char *str,int def)
2953 if (strequal(str,"NT1"))
2954 return(PROTOCOL_NT1);
2955 if (strequal(str,"LANMAN2"))
2956 return(PROTOCOL_LANMAN2);
2957 if (strequal(str,"LANMAN1"))
2958 return(PROTOCOL_LANMAN1);
2959 if (strequal(str,"CORE"))
2960 return(PROTOCOL_CORE);
2961 if (strequal(str,"COREPLUS"))
2962 return(PROTOCOL_COREPLUS);
2963 if (strequal(str,"CORE+"))
2964 return(PROTOCOL_COREPLUS);
2966 DEBUG(0,("Unrecognised protocol level %s\n",str));
2968 return(def);
2971 /****************************************************************************
2972 interpret a security level
2973 ****************************************************************************/
2974 int interpret_security(char *str,int def)
2976 if (strequal(str,"SERVER"))
2977 return(SEC_SERVER);
2978 if (strequal(str,"USER"))
2979 return(SEC_USER);
2980 if (strequal(str,"SHARE"))
2981 return(SEC_SHARE);
2983 DEBUG(0,("Unrecognised security level %s\n",str));
2985 return(def);
2989 /****************************************************************************
2990 interpret an internet address or name into an IP address in 4 byte form
2991 ****************************************************************************/
2992 uint32 interpret_addr(char *str)
2994 struct hostent *hp;
2995 uint32 res;
2996 int i;
2997 BOOL pure_address = True;
2999 if (strcmp(str,"0.0.0.0") == 0) return(0);
3000 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3002 for (i=0; pure_address && str[i]; i++)
3003 if (!(isdigit(str[i]) || str[i] == '.'))
3004 pure_address = False;
3006 /* if it's in the form of an IP address then get the lib to interpret it */
3007 if (pure_address) {
3008 res = inet_addr(str);
3009 } else {
3010 /* otherwise assume it's a network name of some sort and use
3011 Get_Hostbyname */
3012 if ((hp = Get_Hostbyname(str)) == 0) {
3013 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3014 return 0;
3016 putip((char *)&res,(char *)hp->h_addr);
3019 if (res == (uint32)-1) return(0);
3021 return(res);
3024 /*******************************************************************
3025 a convenient addition to interpret_addr()
3026 ******************************************************************/
3027 struct in_addr *interpret_addr2(char *str)
3029 static struct in_addr ret;
3030 uint32 a = interpret_addr(str);
3031 ret.s_addr = a;
3032 return(&ret);
3035 /*******************************************************************
3036 check if an IP is the 0.0.0.0
3037 ******************************************************************/
3038 BOOL zero_ip(struct in_addr ip)
3040 uint32 a;
3041 putip((char *)&a,(char *)&ip);
3042 return(a == 0);
3046 /*******************************************************************
3047 matchname - determine if host name matches IP address
3048 ******************************************************************/
3049 static BOOL matchname(char *remotehost,struct in_addr addr)
3051 struct hostent *hp;
3052 int i;
3054 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3055 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3056 return False;
3060 * Make sure that gethostbyname() returns the "correct" host name.
3061 * Unfortunately, gethostbyname("localhost") sometimes yields
3062 * "localhost.domain". Since the latter host name comes from the
3063 * local DNS, we just have to trust it (all bets are off if the local
3064 * DNS is perverted). We always check the address list, though.
3067 if (strcasecmp(remotehost, hp->h_name)
3068 && strcasecmp(remotehost, "localhost")) {
3069 DEBUG(0,("host name/name mismatch: %s != %s",
3070 remotehost, hp->h_name));
3071 return False;
3074 /* Look up the host address in the address list we just got. */
3075 for (i = 0; hp->h_addr_list[i]; i++) {
3076 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3077 return True;
3081 * The host name does not map to the original host address. Perhaps
3082 * someone has compromised a name server. More likely someone botched
3083 * it, but that could be dangerous, too.
3086 DEBUG(0,("host name/address mismatch: %s != %s",
3087 inet_ntoa(addr), hp->h_name));
3088 return False;
3091 /*******************************************************************
3092 Reset the 'done' variables so after a client process is created
3093 from a fork call these calls will be re-done. This should be
3094 expanded if more variables need reseting.
3095 ******************************************************************/
3097 static BOOL global_client_name_done = False;
3098 static BOOL global_client_addr_done = False;
3100 void reset_globals_after_fork()
3102 global_client_name_done = False;
3103 global_client_addr_done = False;
3106 /*******************************************************************
3107 return the DNS name of the client
3108 ******************************************************************/
3109 char *client_name(void)
3111 extern int Client;
3112 struct sockaddr sa;
3113 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3114 int length = sizeof(sa);
3115 static pstring name_buf;
3116 struct hostent *hp;
3118 if (global_client_name_done)
3119 return name_buf;
3121 strcpy(name_buf,"UNKNOWN");
3123 if (getpeername(Client, &sa, &length) < 0) {
3124 DEBUG(0,("getpeername failed\n"));
3125 return name_buf;
3128 /* Look up the remote host name. */
3129 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3130 sizeof(sockin->sin_addr),
3131 AF_INET)) == 0) {
3132 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3133 StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
3134 } else {
3135 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3136 if (!matchname(name_buf, sockin->sin_addr)) {
3137 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
3138 strcpy(name_buf,"UNKNOWN");
3141 global_client_name_done = True;
3142 return name_buf;
3145 /*******************************************************************
3146 return the IP addr of the client as a string
3147 ******************************************************************/
3148 char *client_addr(void)
3150 extern int Client;
3151 struct sockaddr sa;
3152 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3153 int length = sizeof(sa);
3154 static fstring addr_buf;
3156 if (global_client_addr_done)
3157 return addr_buf;
3159 strcpy(addr_buf,"0.0.0.0");
3161 if (getpeername(Client, &sa, &length) < 0) {
3162 DEBUG(0,("getpeername failed\n"));
3163 return addr_buf;
3166 strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3168 global_client_addr_done = True;
3169 return addr_buf;
3172 /*******************************************************************
3173 sub strings with useful parameters
3174 ********************************************************************/
3175 void standard_sub_basic(char *s)
3177 if (!strchr(s,'%')) return;
3179 string_sub(s,"%R",remote_proto);
3180 string_sub(s,"%a",remote_arch);
3181 string_sub(s,"%m",remote_machine);
3182 string_sub(s,"%L",local_machine);
3184 if (!strchr(s,'%')) return;
3186 string_sub(s,"%v",VERSION);
3187 string_sub(s,"%h",myhostname);
3188 string_sub(s,"%U",sesssetup_user);
3190 if (!strchr(s,'%')) return;
3192 string_sub(s,"%I",client_addr());
3193 if (strstr(s,"%M"))
3194 string_sub(s,"%M",client_name());
3195 string_sub(s,"%T",timestring());
3197 if (!strchr(s,'%')) return;
3200 char pidstr[10];
3201 sprintf(pidstr,"%d",(int)getpid());
3202 string_sub(s,"%d",pidstr);
3205 if (!strchr(s,'%')) return;
3208 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3209 if (pass) {
3210 string_sub(s,"%G",gidtoname(pass->pw_gid));
3216 /*******************************************************************
3217 are two IPs on the same subnet?
3218 ********************************************************************/
3219 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3221 uint32 net1,net2,nmask;
3223 nmask = ntohl(mask.s_addr);
3224 net1 = ntohl(ip1.s_addr);
3225 net2 = ntohl(ip2.s_addr);
3227 return((net1 & nmask) == (net2 & nmask));
3231 /*******************************************************************
3232 write a string in unicoode format
3233 ********************************************************************/
3234 int PutUniCode(char *dst,char *src)
3236 int ret = 0;
3237 while (*src) {
3238 dst[ret++] = src[0];
3239 dst[ret++] = 0;
3240 src++;
3242 dst[ret++]=0;
3243 dst[ret++]=0;
3244 return(ret);
3247 /****************************************************************************
3248 a wrapper for gethostbyname() that tries with all lower and all upper case
3249 if the initial name fails
3250 ****************************************************************************/
3251 struct hostent *Get_Hostbyname(char *name)
3253 char *name2 = strdup(name);
3254 struct hostent *ret;
3256 if (!name2)
3258 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3259 exit(0);
3262 if (!isalnum(*name2))
3264 free(name2);
3265 return(NULL);
3268 ret = sys_gethostbyname(name2);
3269 if (ret != NULL)
3271 free(name2);
3272 return(ret);
3275 /* try with all lowercase */
3276 strlower(name2);
3277 ret = sys_gethostbyname(name2);
3278 if (ret != NULL)
3280 free(name2);
3281 return(ret);
3284 /* try with all uppercase */
3285 strupper(name2);
3286 ret = sys_gethostbyname(name2);
3287 if (ret != NULL)
3289 free(name2);
3290 return(ret);
3293 /* nothing works :-( */
3294 free(name2);
3295 return(NULL);
3299 /****************************************************************************
3300 check if a process exists. Does this work on all unixes?
3301 ****************************************************************************/
3302 BOOL process_exists(int pid)
3304 #ifdef LINUX
3305 fstring s;
3306 sprintf(s,"/proc/%d",pid);
3307 return(directory_exist(s,NULL));
3308 #else
3310 static BOOL tested=False;
3311 static BOOL ok=False;
3312 fstring s;
3313 if (!tested) {
3314 tested = True;
3315 sprintf(s,"/proc/%05d",(int)getpid());
3316 ok = file_exist(s,NULL);
3318 if (ok) {
3319 sprintf(s,"/proc/%05d",pid);
3320 return(file_exist(s,NULL));
3324 /* CGH 8/16/96 - added ESRCH test */
3325 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3326 #endif
3330 /*******************************************************************
3331 turn a uid into a user name
3332 ********************************************************************/
3333 char *uidtoname(int uid)
3335 static char name[40];
3336 struct passwd *pass = getpwuid(uid);
3337 if (pass) return(pass->pw_name);
3338 sprintf(name,"%d",uid);
3339 return(name);
3342 /*******************************************************************
3343 turn a gid into a group name
3344 ********************************************************************/
3345 char *gidtoname(int gid)
3347 static char name[40];
3348 struct group *grp = getgrgid(gid);
3349 if (grp) return(grp->gr_name);
3350 sprintf(name,"%d",gid);
3351 return(name);
3354 /*******************************************************************
3355 block sigs
3356 ********************************************************************/
3357 void BlockSignals(BOOL block,int signum)
3359 #ifdef USE_SIGBLOCK
3360 int block_mask = sigmask(signum);
3361 static int oldmask = 0;
3362 if (block)
3363 oldmask = sigblock(block_mask);
3364 else
3365 sigsetmask(oldmask);
3366 #elif defined(USE_SIGPROCMASK)
3367 sigset_t set;
3368 sigemptyset(&set);
3369 sigaddset(&set,signum);
3370 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3371 #endif
3374 #if AJT
3375 /*******************************************************************
3376 my own panic function - not suitable for general use
3377 ********************************************************************/
3378 void ajt_panic(void)
3380 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3382 #endif
3384 #ifdef USE_DIRECT
3385 #define DIRECT direct
3386 #else
3387 #define DIRECT dirent
3388 #endif
3390 /*******************************************************************
3391 a readdir wrapper which just returns the file name
3392 also return the inode number if requested
3393 ********************************************************************/
3394 char *readdirname(void *p)
3396 struct DIRECT *ptr;
3397 char *dname;
3399 if (!p) return(NULL);
3401 ptr = (struct DIRECT *)readdir(p);
3402 if (!ptr) return(NULL);
3404 dname = ptr->d_name;
3406 #ifdef NEXT2
3407 if (telldir(p) < 0) return(NULL);
3408 #endif
3410 #ifdef SUNOS5
3411 /* this handles a broken compiler setup, causing a mixture
3412 of BSD and SYSV headers and libraries */
3414 static BOOL broken_readdir = False;
3415 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3417 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3418 broken_readdir = True;
3420 if (broken_readdir)
3421 dname = dname - 2;
3423 #endif
3426 static pstring buf;
3427 strcpy(buf, dname);
3428 unix_to_dos(buf, True);
3429 dname = buf;
3432 return(dname);
3436 * Utility function used by is_hidden_path() and is_vetoed_name()
3437 * to decide if the last component of a path matches a (possibly
3438 * wildcarded) entry in a namelist.
3441 static BOOL is_in_path(char *name, char *namelist)
3443 pstring last_component;
3444 char *p;
3445 char *nameptr = namelist;
3446 char *name_end;
3448 DEBUG(5, ("is_in_path: %s list: %s\n", name, namelist));
3450 /* if we have no list it's obviously not in the path */
3451 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
3453 DEBUG(5,("is_in_path: no name list. return False\n"));
3454 return False;
3457 /* Get the last component of the unix name. */
3458 p = strrchr(name, '/');
3459 strncpy(last_component, p ? p : name, sizeof(last_component)-1);
3460 last_component[sizeof(last_component)-1] = '\0';
3462 /* now, we need to find the names one by one and check them
3463 they can contain spaces and all sorts of stuff so we
3464 separate them with of all things '\' which can never be in a filename
3465 I could use "" but then I have to break them all out
3466 maybe such a routine exists somewhere?
3469 /* lkcl 03jul97 - the separator character used to be a '/'.
3470 i changed it to a '\', after examining the code, and seeing
3471 that unix_convert is called before check_path and dos_mode.
3472 unix_convert changes, in the path, all dos '\'s to unix '/'s.
3474 the alternatives are:
3476 1) move all check_path and dos_mode calls to before the
3477 unix_convert calls.
3479 2) have a corresponding dos_convert call, which can be used
3480 in here to reverse '/'s into '\'s and vice-versa. users
3481 would specify the lp_veto_files and lp_hide_files parameters
3482 in dos mode path format ('\' for directory separator), with a
3483 list separator of '/', and they would be swapped inside this
3484 function, before making the search.
3488 while (*nameptr)
3490 if ( *nameptr == '\\' )
3492 /* cope with multiple (useless) \s) */
3493 nameptr++;
3494 continue;
3496 /* find the next \ */
3497 if ((name_end = strchr(nameptr,'\\')) != NULL)
3499 *name_end = 0;
3502 /* look for a match. */
3503 if (mask_match(last_component, nameptr, case_sensitive, False))
3505 DEBUG(5,("is_in_path: mask match succeeded\n"));
3506 return True;
3509 /* oops - the last check for a \ didn't find one. */
3510 if (name_end == NULL)
3512 DEBUG(5,("is_in_path: last name. failed\n"));
3513 return False;
3516 /* next segment please */
3517 nameptr = name_end + 1;
3520 DEBUG(5,("is_in_path: not found\n"));
3522 return False;
3525 BOOL is_hidden_path(int snum, char *name)
3527 return is_in_path(name, lp_hide_files(snum));
3530 BOOL is_vetoed_name(int snum, char *name)
3532 return is_in_path(name, lp_veto_files(snum));
3535 /****************************************************************************
3536 routine to do file locking
3537 ****************************************************************************/
3538 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
3540 #if HAVE_FCNTL_LOCK
3541 struct flock lock;
3542 int ret;
3544 #if 1
3545 uint32 mask = 0xC0000000;
3547 /* make sure the count is reasonable, we might kill the lockd otherwise */
3548 count &= ~mask;
3550 /* the offset is often strange - remove 2 of its bits if either of
3551 the top two bits are set. Shift the top ones by two bits. This
3552 still allows OLE2 apps to operate, but should stop lockd from
3553 dieing */
3554 if ((offset & mask) != 0)
3555 offset = (offset & ~mask) | ((offset & mask) >> 2);
3556 #else
3557 uint32 mask = ((unsigned)1<<31);
3559 /* interpret negative counts as large numbers */
3560 if (count < 0)
3561 count &= ~mask;
3563 /* no negative offsets */
3564 offset &= ~mask;
3566 /* count + offset must be in range */
3567 while ((offset < 0 || (offset + count < 0)) && mask)
3569 offset &= ~mask;
3570 mask = mask >> 1;
3572 #endif
3575 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
3577 lock.l_type = type;
3578 lock.l_whence = SEEK_SET;
3579 lock.l_start = (int)offset;
3580 lock.l_len = (int)count;
3581 lock.l_pid = 0;
3583 errno = 0;
3585 ret = fcntl(fd,op,&lock);
3587 if (errno != 0)
3588 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
3590 /* a lock query */
3591 if (op == F_GETLK)
3593 if ((ret != -1) &&
3594 (lock.l_type != F_UNLCK) &&
3595 (lock.l_pid != 0) &&
3596 (lock.l_pid != getpid()))
3598 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
3599 return(True);
3602 /* it must be not locked or locked by me */
3603 return(False);
3606 /* a lock set or unset */
3607 if (ret == -1)
3609 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3610 offset,count,op,type,strerror(errno)));
3612 /* perhaps it doesn't support this sort of locking?? */
3613 if (errno == EINVAL)
3615 DEBUG(3,("locking not supported? returning True\n"));
3616 return(True);
3619 return(False);
3622 /* everything went OK */
3623 DEBUG(5,("Lock call successful\n"));
3625 return(True);
3626 #else
3627 return(False);
3628 #endif
3631 /*******************************************************************
3632 lock a file - returning a open file descriptor or -1 on failure
3633 The timeout is in seconds. 0 means no timeout
3634 ********************************************************************/
3635 int file_lock(char *name,int timeout)
3637 int fd = open(name,O_RDWR|O_CREAT,0666);
3638 time_t t=0;
3639 if (fd < 0) return(-1);
3641 #if HAVE_FCNTL_LOCK
3642 if (timeout) t = time(NULL);
3643 while (!timeout || (time(NULL)-t < timeout)) {
3644 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
3645 msleep(LOCK_RETRY_TIMEOUT);
3647 return(-1);
3648 #else
3649 return(fd);
3650 #endif
3653 /*******************************************************************
3654 unlock a file locked by file_lock
3655 ********************************************************************/
3656 void file_unlock(int fd)
3658 if (fd<0) return;
3659 #if HAVE_FCNTL_LOCK
3660 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
3661 #endif
3662 close(fd);