- fix client for pathworks 4 access
[Samba.git] / source / lib / util.c
blob31ad3da31cb7c07f65bd3701f7c758a86333ac89
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1995
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 /* info on the client */
42 struct from_host Client_info=
43 {"UNKNOWN","0.0.0.0",NULL};
45 /* the last IP received from */
46 struct in_addr lastip;
48 /* the last port received from */
49 int lastport=0;
51 /* this is used by the chaining code */
52 int chain_size = 0;
54 int trans_num = 0;
57 case handling on filenames
59 int case_default = CASE_LOWER;
61 pstring debugf = "/tmp/log.samba";
62 int syslog_level;
64 /* the following control case operations - they are put here so the
65 client can link easily */
66 BOOL case_sensitive;
67 BOOL case_preserve;
68 BOOL use_mangled_map = False;
69 BOOL short_case_preserve;
70 BOOL case_mangle;
72 fstring remote_machine="";
73 fstring local_machine="";
74 fstring remote_arch="UNKNOWN";
75 fstring remote_proto="UNKNOWN";
76 pstring myhostname="";
77 pstring user_socket_options="";
78 pstring sesssetup_user="";
79 pstring myname = "";
81 int smb_read_error = 0;
83 static char *filename_dos(char *path,char *buf);
85 static BOOL stdout_logging = False;
88 /*******************************************************************
89 get ready for syslog stuff
90 ******************************************************************/
91 void setup_logging(char *pname,BOOL interactive)
93 #ifdef SYSLOG
94 if (!interactive) {
95 char *p = strrchr(pname,'/');
96 if (p) pname = p+1;
97 openlog(pname, LOG_PID, LOG_DAEMON);
99 #endif
100 if (interactive) {
101 stdout_logging = True;
102 dbf = stdout;
107 BOOL append_log=False;
110 /****************************************************************************
111 reopen the log files
112 ****************************************************************************/
113 void reopen_logs(void)
115 extern FILE *dbf;
116 pstring fname;
118 if (DEBUGLEVEL > 0)
120 strcpy(fname,debugf);
121 if (lp_loaded() && (*lp_logfile()))
122 strcpy(fname,lp_logfile());
124 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
126 strcpy(debugf,fname);
127 if (dbf) fclose(dbf);
128 if (append_log)
129 dbf = fopen(debugf,"a");
130 else
131 dbf = fopen(debugf,"w");
132 if (dbf) setbuf(dbf,NULL);
135 else
137 if (dbf)
139 fclose(dbf);
140 dbf = NULL;
146 /*******************************************************************
147 check if the log has grown too big
148 ********************************************************************/
149 static void check_log_size(void)
151 static int debug_count=0;
152 int maxlog;
153 struct stat st;
155 if (debug_count++ < 100) return;
157 maxlog = lp_max_log_size() * 1024;
158 if (!dbf || maxlog <= 0) return;
160 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
161 fclose(dbf); dbf = NULL;
162 reopen_logs();
163 if (dbf && file_size(debugf) > maxlog) {
164 pstring name;
165 fclose(dbf); dbf = NULL;
166 sprintf(name,"%s.old",debugf);
167 sys_rename(debugf,name);
168 reopen_logs();
171 debug_count=0;
175 /*******************************************************************
176 write an debug message on the debugfile. This is called by the DEBUG
177 macro
178 ********************************************************************/
179 #ifdef __STDC__
180 int Debug1(char *format_str, ...)
182 #else
183 int Debug1(va_alist)
184 va_dcl
186 char *format_str;
187 #endif
188 va_list ap;
190 if (stdout_logging) {
191 #ifdef __STDC__
192 va_start(ap, format_str);
193 #else
194 va_start(ap);
195 format_str = va_arg(ap,char *);
196 #endif
197 vfprintf(dbf,format_str,ap);
198 va_end(ap);
199 return(0);
202 #ifdef SYSLOG
203 if (!lp_syslog_only())
204 #endif
206 if (!dbf)
208 dbf = fopen(debugf,"w");
209 if (dbf)
210 setbuf(dbf,NULL);
211 else
212 return(0);
216 #ifdef SYSLOG
217 if (syslog_level < lp_syslog())
220 * map debug levels to syslog() priorities
221 * note that not all DEBUG(0, ...) calls are
222 * necessarily errors
224 static int priority_map[] = {
225 LOG_ERR, /* 0 */
226 LOG_WARNING, /* 1 */
227 LOG_NOTICE, /* 2 */
228 LOG_INFO, /* 3 */
230 int priority;
231 pstring msgbuf;
233 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
234 syslog_level < 0)
235 priority = LOG_DEBUG;
236 else
237 priority = priority_map[syslog_level];
239 #ifdef __STDC__
240 va_start(ap, format_str);
241 #else
242 va_start(ap);
243 format_str = va_arg(ap,char *);
244 #endif
245 vsprintf(msgbuf, format_str, ap);
246 va_end(ap);
248 msgbuf[255] = '\0';
249 syslog(priority, "%s", msgbuf);
251 #endif
253 #ifdef SYSLOG
254 if (!lp_syslog_only())
255 #endif
257 #ifdef __STDC__
258 va_start(ap, format_str);
259 #else
260 va_start(ap);
261 format_str = va_arg(ap,char *);
262 #endif
263 vfprintf(dbf,format_str,ap);
264 va_end(ap);
265 fflush(dbf);
268 check_log_size();
270 return(0);
273 /****************************************************************************
274 determine if a file descriptor is in fact a socket
275 ****************************************************************************/
276 BOOL is_a_socket(int fd)
278 int v,l;
279 l = sizeof(int);
280 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
284 static char *last_ptr=NULL;
286 /****************************************************************************
287 Get the next token from a string, return False if none found
288 handles double-quotes.
289 Based on a routine by GJC@VILLAGE.COM.
290 Extensively modified by Andrew.Tridgell@anu.edu.au
291 ****************************************************************************/
292 BOOL next_token(char **ptr,char *buff,char *sep)
294 char *s;
295 BOOL quoted;
297 if (!ptr) ptr = &last_ptr;
298 if (!ptr) return(False);
300 s = *ptr;
302 /* default to simple separators */
303 if (!sep) sep = " \t\n\r";
305 /* find the first non sep char */
306 while(*s && strchr(sep,*s)) s++;
308 /* nothing left? */
309 if (! *s) return(False);
311 /* copy over the token */
312 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
314 if (*s == '\"')
315 quoted = !quoted;
316 else
317 *buff++ = *s;
320 *ptr = (*s) ? s+1 : s;
321 *buff = 0;
322 last_ptr = *ptr;
324 return(True);
327 /****************************************************************************
328 Convert list of tokens to array; dependent on above routine.
329 Uses last_ptr from above - bit of a hack.
330 ****************************************************************************/
331 char **toktocliplist(int *ctok, char *sep)
333 char *s=last_ptr;
334 int ictok=0;
335 char **ret, **iret;
337 if (!sep) sep = " \t\n\r";
339 while(*s && strchr(sep,*s)) s++;
341 /* nothing left? */
342 if (!*s) return(NULL);
344 do {
345 ictok++;
346 while(*s && (!strchr(sep,*s))) s++;
347 while(*s && strchr(sep,*s)) *s++=0;
348 } while(*s);
350 *ctok=ictok;
351 s=last_ptr;
353 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
355 while(ictok--) {
356 *iret++=s;
357 while(*s++);
358 while(!*s) s++;
361 return ret;
364 #ifndef HAVE_MEMMOVE
365 /*******************************************************************
366 safely copies memory, ensuring no overlap problems.
367 this is only used if the machine does not have it's own memmove().
368 this is not the fastest algorithm in town, but it will do for our
369 needs.
370 ********************************************************************/
371 void *MemMove(void *dest,void *src,int size)
373 unsigned long d,s;
374 int i;
375 if (dest==src || !size) return(dest);
377 d = (unsigned long)dest;
378 s = (unsigned long)src;
380 if ((d >= (s+size)) || (s >= (d+size))) {
381 /* no overlap */
382 memcpy(dest,src,size);
383 return(dest);
386 if (d < s)
388 /* we can forward copy */
389 if (s-d >= sizeof(int) &&
390 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
391 /* do it all as words */
392 int *idest = (int *)dest;
393 int *isrc = (int *)src;
394 size /= sizeof(int);
395 for (i=0;i<size;i++) idest[i] = isrc[i];
396 } else {
397 /* simplest */
398 char *cdest = (char *)dest;
399 char *csrc = (char *)src;
400 for (i=0;i<size;i++) cdest[i] = csrc[i];
403 else
405 /* must backward copy */
406 if (d-s >= sizeof(int) &&
407 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
408 /* do it all as words */
409 int *idest = (int *)dest;
410 int *isrc = (int *)src;
411 size /= sizeof(int);
412 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
413 } else {
414 /* simplest */
415 char *cdest = (char *)dest;
416 char *csrc = (char *)src;
417 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
420 return(dest);
422 #endif
425 /****************************************************************************
426 prompte a dptr (to make it recently used)
427 ****************************************************************************/
428 void array_promote(char *array,int elsize,int element)
430 char *p;
431 if (element == 0)
432 return;
434 p = (char *)malloc(elsize);
436 if (!p)
438 DEBUG(5,("Ahh! Can't malloc\n"));
439 return;
441 memcpy(p,array + element * elsize, elsize);
442 memmove(array + elsize,array,elsize*element);
443 memcpy(array,p,elsize);
444 free(p);
447 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
449 struct
451 char *name;
452 int level;
453 int option;
454 int value;
455 int opttype;
456 } socket_options[] = {
457 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
458 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
459 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
460 #ifdef TCP_NODELAY
461 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
462 #endif
463 #ifdef IPTOS_LOWDELAY
464 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
465 #endif
466 #ifdef IPTOS_THROUGHPUT
467 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
468 #endif
469 #ifdef SO_SNDBUF
470 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
471 #endif
472 #ifdef SO_RCVBUF
473 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
474 #endif
475 #ifdef SO_SNDLOWAT
476 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
477 #endif
478 #ifdef SO_RCVLOWAT
479 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
480 #endif
481 #ifdef SO_SNDTIMEO
482 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
483 #endif
484 #ifdef SO_RCVTIMEO
485 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
486 #endif
487 {NULL,0,0,0,0}};
491 /****************************************************************************
492 set user socket options
493 ****************************************************************************/
494 void set_socket_options(int fd, char *options)
496 string tok;
498 while (next_token(&options,tok," \t,"))
500 int ret=0,i;
501 int value = 1;
502 char *p;
503 BOOL got_value = False;
505 if ((p = strchr(tok,'=')))
507 *p = 0;
508 value = atoi(p+1);
509 got_value = True;
512 for (i=0;socket_options[i].name;i++)
513 if (strequal(socket_options[i].name,tok))
514 break;
516 if (!socket_options[i].name)
518 DEBUG(0,("Unknown socket option %s\n",tok));
519 continue;
522 switch (socket_options[i].opttype)
524 case OPT_BOOL:
525 case OPT_INT:
526 ret = setsockopt(fd,socket_options[i].level,
527 socket_options[i].option,(char *)&value,sizeof(int));
528 break;
530 case OPT_ON:
531 if (got_value)
532 DEBUG(0,("syntax error - %s does not take a value\n",tok));
535 int on = socket_options[i].value;
536 ret = setsockopt(fd,socket_options[i].level,
537 socket_options[i].option,(char *)&on,sizeof(int));
539 break;
542 if (ret != 0)
543 DEBUG(0,("Failed to set socket option %s\n",tok));
549 /****************************************************************************
550 close the socket communication
551 ****************************************************************************/
552 void close_sockets(void )
554 close(Client);
555 Client = 0;
558 /****************************************************************************
559 determine whether we are in the specified group
560 ****************************************************************************/
561 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
563 int i;
565 if (group == current_gid) return(True);
567 for (i=0;i<ngroups;i++)
568 if (group == groups[i])
569 return(True);
571 return(False);
574 /****************************************************************************
575 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
576 ****************************************************************************/
577 char *StrCpy(char *dest,char *src)
579 char *d = dest;
581 #if AJT
582 /* I don't want to get lazy with these ... */
583 if (!dest || !src) {
584 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
585 ajt_panic();
587 #endif
589 if (!dest) return(NULL);
590 if (!src) {
591 *dest = 0;
592 return(dest);
594 while ((*d++ = *src++)) ;
595 return(dest);
598 /****************************************************************************
599 line strncpy but always null terminates. Make sure there is room!
600 ****************************************************************************/
601 char *StrnCpy(char *dest,const char *src,int n)
603 char *d = dest;
604 if (!dest) return(NULL);
605 if (!src) {
606 *dest = 0;
607 return(dest);
609 while (n-- && (*d++ = *src++)) ;
610 *d = 0;
611 return(dest);
615 /*******************************************************************
616 copy an IP address from one buffer to another
617 ********************************************************************/
618 void putip(void *dest,void *src)
620 memcpy(dest,src,4);
624 /****************************************************************************
625 interpret the weird netbios "name". Return the name type
626 ****************************************************************************/
627 static int name_interpret(char *in,char *out)
629 int ret;
630 int len = (*in++) / 2;
632 *out=0;
634 if (len > 30 || len<1) return(0);
636 while (len--)
638 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
639 *out = 0;
640 return(0);
642 *out = ((in[0]-'A')<<4) + (in[1]-'A');
643 in += 2;
644 out++;
646 *out = 0;
647 ret = out[-1];
649 #ifdef NETBIOS_SCOPE
650 /* Handle any scope names */
651 while(*in)
653 *out++ = '.'; /* Scope names are separated by periods */
654 len = *(unsigned char *)in++;
655 StrnCpy(out, in, len);
656 out += len;
657 *out=0;
658 in += len;
660 #endif
661 return(ret);
664 /****************************************************************************
665 mangle a name into netbios format
666 ****************************************************************************/
667 int name_mangle(char *In,char *Out,char name_type)
669 fstring name;
670 char buf[20];
671 char *in = (char *)&buf[0];
672 char *out = (char *)Out;
673 char *p, *label;
674 int i;
676 if (In[0] != '*') {
677 StrnCpy(name,In,sizeof(name)-1);
678 sprintf(buf,"%-15.15s%c",name,name_type);
679 } else {
680 buf[0]='*';
681 memset(&buf[1],0,16);
684 *out++ = 32;
685 for (i=0;i<16;i++) {
686 char c = toupper(in[i]);
687 out[i*2] = (c>>4) + 'A';
688 out[i*2+1] = (c & 0xF) + 'A';
690 out[32]=0;
691 out += 32;
693 label = scope;
694 while (*label)
696 p = strchr(label, '.');
697 if (p == 0)
698 p = label + strlen(label);
699 *out++ = p - label;
700 memcpy(out, label, p - label);
701 out += p - label;
702 label += p - label + (*p == '.');
704 *out = 0;
705 return(name_len(Out));
709 /*******************************************************************
710 check if a file exists
711 ********************************************************************/
712 BOOL file_exist(char *fname,struct stat *sbuf)
714 struct stat st;
715 if (!sbuf) sbuf = &st;
717 if (sys_stat(fname,sbuf) != 0)
718 return(False);
720 return(S_ISREG(sbuf->st_mode));
723 /*******************************************************************
724 check a files mod time
725 ********************************************************************/
726 time_t file_modtime(char *fname)
728 struct stat st;
730 if (sys_stat(fname,&st) != 0)
731 return(0);
733 return(st.st_mtime);
736 /*******************************************************************
737 check if a directory exists
738 ********************************************************************/
739 BOOL directory_exist(char *dname,struct stat *st)
741 struct stat st2;
742 if (!st) st = &st2;
744 if (sys_stat(dname,st) != 0)
745 return(False);
747 return(S_ISDIR(st->st_mode));
750 /*******************************************************************
751 returns the size in bytes of the named file
752 ********************************************************************/
753 uint32 file_size(char *file_name)
755 struct stat buf;
756 buf.st_size = 0;
757 sys_stat(file_name,&buf);
758 return(buf.st_size);
761 /*******************************************************************
762 return a string representing an attribute for a file
763 ********************************************************************/
764 char *attrib_string(int mode)
766 static char attrstr[10];
768 attrstr[0] = 0;
770 if (mode & aVOLID) strcat(attrstr,"V");
771 if (mode & aDIR) strcat(attrstr,"D");
772 if (mode & aARCH) strcat(attrstr,"A");
773 if (mode & aHIDDEN) strcat(attrstr,"H");
774 if (mode & aSYSTEM) strcat(attrstr,"S");
775 if (mode & aRONLY) strcat(attrstr,"R");
777 return(attrstr);
781 /*******************************************************************
782 case insensitive string compararison
783 ********************************************************************/
784 int StrCaseCmp(char *s, char *t)
786 for (; tolower(*s) == tolower(*t); ++s, ++t)
787 if (!*s) return 0;
789 return tolower(*s) - tolower(*t);
792 /*******************************************************************
793 case insensitive string compararison, length limited
794 ********************************************************************/
795 int StrnCaseCmp(char *s, char *t, int n)
797 while (n-- && *s && *t) {
798 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
799 s++; t++;
801 if (n) return(tolower(*s) - tolower(*t));
803 return(0);
806 /*******************************************************************
807 compare 2 strings
808 ********************************************************************/
809 BOOL strequal(char *s1,char *s2)
811 if (s1 == s2) return(True);
812 if (!s1 || !s2) return(False);
814 return(StrCaseCmp(s1,s2)==0);
817 /*******************************************************************
818 compare 2 strings up to and including the nth char.
819 ******************************************************************/
820 BOOL strnequal(char *s1,char *s2,int n)
822 if (s1 == s2) return(True);
823 if (!s1 || !s2 || !n) return(False);
825 return(StrnCaseCmp(s1,s2,n)==0);
828 /*******************************************************************
829 compare 2 strings (case sensitive)
830 ********************************************************************/
831 BOOL strcsequal(char *s1,char *s2)
833 if (s1 == s2) return(True);
834 if (!s1 || !s2) return(False);
836 return(strcmp(s1,s2)==0);
840 /*******************************************************************
841 convert a string to lower case
842 ********************************************************************/
843 void strlower(char *s)
845 while (*s)
847 #ifdef KANJI
848 if (is_shift_jis (*s)) {
849 s += 2;
850 } else if (is_kana (*s)) {
851 s++;
852 } else {
853 if (isupper(*s))
854 *s = tolower(*s);
855 s++;
857 #else
858 if (isupper(*s))
859 *s = tolower(*s);
860 s++;
861 #endif /* KANJI */
865 /*******************************************************************
866 convert a string to upper case
867 ********************************************************************/
868 void strupper(char *s)
870 while (*s)
872 #ifdef KANJI
873 if (is_shift_jis (*s)) {
874 s += 2;
875 } else if (is_kana (*s)) {
876 s++;
877 } else {
878 if (islower(*s))
879 *s = toupper(*s);
880 s++;
882 #else
883 if (islower(*s))
884 *s = toupper(*s);
885 s++;
886 #endif
890 /*******************************************************************
891 convert a string to "normal" form
892 ********************************************************************/
893 void strnorm(char *s)
895 if (case_default == CASE_UPPER)
896 strupper(s);
897 else
898 strlower(s);
901 /*******************************************************************
902 check if a string is in "normal" case
903 ********************************************************************/
904 BOOL strisnormal(char *s)
906 if (case_default == CASE_UPPER)
907 return(!strhaslower(s));
909 return(!strhasupper(s));
913 /****************************************************************************
914 string replace
915 ****************************************************************************/
916 void string_replace(char *s,char oldc,char newc)
918 while (*s)
920 #ifdef KANJI
921 if (is_shift_jis (*s)) {
922 s += 2;
923 } else if (is_kana (*s)) {
924 s++;
925 } else {
926 if (oldc == *s)
927 *s = newc;
928 s++;
930 #else
931 if (oldc == *s)
932 *s = newc;
933 s++;
934 #endif /* KANJI */
938 /****************************************************************************
939 make a file into unix format
940 ****************************************************************************/
941 void unix_format(char *fname)
943 pstring namecopy;
944 string_replace(fname,'\\','/');
945 #ifndef KANJI
946 dos2unix_format(fname, True);
947 #endif /* KANJI */
949 if (*fname == '/')
951 strcpy(namecopy,fname);
952 strcpy(fname,".");
953 strcat(fname,namecopy);
957 /****************************************************************************
958 make a file into dos format
959 ****************************************************************************/
960 void dos_format(char *fname)
962 #ifndef KANJI
963 unix2dos_format(fname, True);
964 #endif /* KANJI */
965 string_replace(fname,'/','\\');
969 /*******************************************************************
970 show a smb message structure
971 ********************************************************************/
972 void show_msg(char *buf)
974 int i;
975 int bcc=0;
976 if (DEBUGLEVEL < 5)
977 return;
979 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
980 smb_len(buf),
981 (int)CVAL(buf,smb_com),
982 (int)CVAL(buf,smb_rcls),
983 (int)CVAL(buf,smb_reh),
984 (int)SVAL(buf,smb_err),
985 (int)CVAL(buf,smb_flg),
986 (int)SVAL(buf,smb_flg2)));
987 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
988 (int)SVAL(buf,smb_tid),
989 (int)SVAL(buf,smb_pid),
990 (int)SVAL(buf,smb_uid),
991 (int)SVAL(buf,smb_mid),
992 (int)CVAL(buf,smb_wct)));
993 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
994 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
995 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
996 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
997 DEBUG(5,("smb_bcc=%d\n",bcc));
998 if (DEBUGLEVEL < 10)
999 return;
1000 for (i=0;i<MIN(bcc,128);i++)
1001 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1002 DEBUG(10,("\n"));
1005 /*******************************************************************
1006 return the length of an smb packet
1007 ********************************************************************/
1008 int smb_len(char *buf)
1010 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1013 /*******************************************************************
1014 set the length of an smb packet
1015 ********************************************************************/
1016 void _smb_setlen(char *buf,int len)
1018 buf[0] = 0;
1019 buf[1] = (len&0x10000)>>16;
1020 buf[2] = (len&0xFF00)>>8;
1021 buf[3] = len&0xFF;
1024 /*******************************************************************
1025 set the length and marker of an smb packet
1026 ********************************************************************/
1027 void smb_setlen(char *buf,int len)
1029 _smb_setlen(buf,len);
1031 CVAL(buf,4) = 0xFF;
1032 CVAL(buf,5) = 'S';
1033 CVAL(buf,6) = 'M';
1034 CVAL(buf,7) = 'B';
1037 /*******************************************************************
1038 setup the word count and byte count for a smb message
1039 ********************************************************************/
1040 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1042 if (zero)
1043 bzero(buf + smb_size,num_words*2 + num_bytes);
1044 CVAL(buf,smb_wct) = num_words;
1045 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1046 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1047 return (smb_size + num_words*2 + num_bytes);
1050 /*******************************************************************
1051 return the number of smb words
1052 ********************************************************************/
1053 int smb_numwords(char *buf)
1055 return (CVAL(buf,smb_wct));
1058 /*******************************************************************
1059 return the size of the smb_buf region of a message
1060 ********************************************************************/
1061 int smb_buflen(char *buf)
1063 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1066 /*******************************************************************
1067 return a pointer to the smb_buf data area
1068 ********************************************************************/
1069 int smb_buf_ofs(char *buf)
1071 return (smb_size + CVAL(buf,smb_wct)*2);
1074 /*******************************************************************
1075 return a pointer to the smb_buf data area
1076 ********************************************************************/
1077 char *smb_buf(char *buf)
1079 return (buf + smb_buf_ofs(buf));
1082 /*******************************************************************
1083 return the SMB offset into an SMB buffer
1084 ********************************************************************/
1085 int smb_offset(char *p,char *buf)
1087 return(PTR_DIFF(p,buf+4) + chain_size);
1091 /*******************************************************************
1092 skip past some strings in a buffer
1093 ********************************************************************/
1094 char *skip_string(char *buf,int n)
1096 while (n--)
1097 buf += strlen(buf) + 1;
1098 return(buf);
1101 /*******************************************************************
1102 trim the specified elements off the front and back of a string
1103 ********************************************************************/
1104 BOOL trim_string(char *s,char *front,char *back)
1106 BOOL ret = False;
1107 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1109 char *p = s;
1110 ret = True;
1111 while (1)
1113 if (!(*p = p[strlen(front)]))
1114 break;
1115 p++;
1118 while (back && *back && strlen(s) >= strlen(back) &&
1119 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1121 ret = True;
1122 s[strlen(s)-strlen(back)] = 0;
1124 return(ret);
1128 /*******************************************************************
1129 reduce a file name, removing .. elements.
1130 ********************************************************************/
1131 void dos_clean_name(char *s)
1133 char *p=NULL;
1135 DEBUG(3,("dos_clean_name [%s]\n",s));
1137 /* remove any double slashes */
1138 string_sub(s, "\\\\", "\\");
1140 while ((p = strstr(s,"\\..\\")) != NULL)
1142 pstring s1;
1144 *p = 0;
1145 strcpy(s1,p+3);
1147 if ((p=strrchr(s,'\\')) != NULL)
1148 *p = 0;
1149 else
1150 *s = 0;
1151 strcat(s,s1);
1154 trim_string(s,NULL,"\\..");
1156 string_sub(s, "\\.\\", "\\");
1159 /*******************************************************************
1160 reduce a file name, removing .. elements.
1161 ********************************************************************/
1162 void unix_clean_name(char *s)
1164 char *p=NULL;
1166 DEBUG(3,("unix_clean_name [%s]\n",s));
1168 /* remove any double slashes */
1169 string_sub(s, "//","/");
1171 while ((p = strstr(s,"/../")) != NULL)
1173 pstring s1;
1175 *p = 0;
1176 strcpy(s1,p+3);
1178 if ((p=strrchr(s,'/')) != NULL)
1179 *p = 0;
1180 else
1181 *s = 0;
1182 strcat(s,s1);
1185 trim_string(s,NULL,"/..");
1189 /*******************************************************************
1190 a wrapper for the normal chdir() function
1191 ********************************************************************/
1192 int ChDir(char *path)
1194 int res;
1195 static pstring LastDir="";
1197 if (strcsequal(path,".")) return(0);
1199 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1200 DEBUG(3,("chdir to %s\n",path));
1201 res = sys_chdir(path);
1202 if (!res)
1203 strcpy(LastDir,path);
1204 return(res);
1208 /*******************************************************************
1209 return the absolute current directory path. A dumb version.
1210 ********************************************************************/
1211 static char *Dumb_GetWd(char *s)
1213 #ifdef USE_GETCWD
1214 return ((char *)getcwd(s,sizeof(pstring)));
1215 #else
1216 return ((char *)getwd(s));
1217 #endif
1221 /* number of list structures for a caching GetWd function. */
1222 #define MAX_GETWDCACHE (50)
1224 struct
1226 ino_t inode;
1227 dev_t dev;
1228 char *text;
1229 BOOL valid;
1230 } ino_list[MAX_GETWDCACHE];
1232 BOOL use_getwd_cache=True;
1234 /*******************************************************************
1235 return the absolute current directory path
1236 ********************************************************************/
1237 char *GetWd(char *str)
1239 pstring s;
1240 static BOOL getwd_cache_init = False;
1241 struct stat st, st2;
1242 int i;
1244 *s = 0;
1246 if (!use_getwd_cache)
1247 return(Dumb_GetWd(str));
1249 /* init the cache */
1250 if (!getwd_cache_init)
1252 getwd_cache_init = True;
1253 for (i=0;i<MAX_GETWDCACHE;i++)
1255 string_init(&ino_list[i].text,"");
1256 ino_list[i].valid = False;
1260 /* Get the inode of the current directory, if this doesn't work we're
1261 in trouble :-) */
1263 if (stat(".",&st) == -1)
1265 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1266 return(Dumb_GetWd(str));
1270 for (i=0; i<MAX_GETWDCACHE; i++)
1271 if (ino_list[i].valid)
1274 /* If we have found an entry with a matching inode and dev number
1275 then find the inode number for the directory in the cached string.
1276 If this agrees with that returned by the stat for the current
1277 directory then all is o.k. (but make sure it is a directory all
1278 the same...) */
1280 if (st.st_ino == ino_list[i].inode &&
1281 st.st_dev == ino_list[i].dev)
1283 if (stat(ino_list[i].text,&st2) == 0)
1285 if (st.st_ino == st2.st_ino &&
1286 st.st_dev == st2.st_dev &&
1287 (st2.st_mode & S_IFMT) == S_IFDIR)
1289 strcpy (str, ino_list[i].text);
1291 /* promote it for future use */
1292 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1293 return (str);
1295 else
1297 /* If the inode is different then something's changed,
1298 scrub the entry and start from scratch. */
1299 ino_list[i].valid = False;
1306 /* We don't have the information to hand so rely on traditional methods.
1307 The very slow getcwd, which spawns a process on some systems, or the
1308 not quite so bad getwd. */
1310 if (!Dumb_GetWd(s))
1312 DEBUG(0,("Getwd failed, errno %d\n",errno));
1313 return (NULL);
1316 strcpy(str,s);
1318 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1320 /* add it to the cache */
1321 i = MAX_GETWDCACHE - 1;
1322 string_set(&ino_list[i].text,s);
1323 ino_list[i].dev = st.st_dev;
1324 ino_list[i].inode = st.st_ino;
1325 ino_list[i].valid = True;
1327 /* put it at the top of the list */
1328 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1330 return (str);
1335 /*******************************************************************
1336 reduce a file name, removing .. elements and checking that
1337 it is below dir in the heirachy. This uses GetWd() and so must be run
1338 on the system that has the referenced file system.
1340 widelinks are allowed if widelinks is true
1341 ********************************************************************/
1342 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1344 #ifndef REDUCE_PATHS
1345 return True;
1346 #else
1347 pstring dir2;
1348 pstring wd;
1349 pstring basename;
1350 pstring newname;
1351 char *p=NULL;
1352 BOOL relative = (*s != '/');
1354 *dir2 = *wd = *basename = *newname = 0;
1356 if (widelinks)
1358 unix_clean_name(s);
1359 /* can't have a leading .. */
1360 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1362 DEBUG(3,("Illegal file name? (%s)\n",s));
1363 return(False);
1365 return(True);
1368 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1370 /* remove any double slashes */
1371 string_sub(s,"//","/");
1373 strcpy(basename,s);
1374 p = strrchr(basename,'/');
1376 if (!p)
1377 return(True);
1379 if (!GetWd(wd))
1381 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1382 return(False);
1385 if (ChDir(dir) != 0)
1387 DEBUG(0,("couldn't chdir to %s\n",dir));
1388 return(False);
1391 if (!GetWd(dir2))
1393 DEBUG(0,("couldn't getwd for %s\n",dir));
1394 ChDir(wd);
1395 return(False);
1399 if (p && (p != basename))
1401 *p = 0;
1402 if (strcmp(p+1,".")==0)
1403 p[1]=0;
1404 if (strcmp(p+1,"..")==0)
1405 *p = '/';
1408 if (ChDir(basename) != 0)
1410 ChDir(wd);
1411 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1412 return(False);
1415 if (!GetWd(newname))
1417 ChDir(wd);
1418 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1419 return(False);
1422 if (p && (p != basename))
1424 strcat(newname,"/");
1425 strcat(newname,p+1);
1429 int l = strlen(dir2);
1430 if (dir2[l-1] == '/')
1431 l--;
1433 if (strncmp(newname,dir2,l) != 0)
1435 ChDir(wd);
1436 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1437 return(False);
1440 if (relative)
1442 if (newname[l] == '/')
1443 strcpy(s,newname + l + 1);
1444 else
1445 strcpy(s,newname+l);
1447 else
1448 strcpy(s,newname);
1451 ChDir(wd);
1453 if (strlen(s) == 0)
1454 strcpy(s,"./");
1456 DEBUG(3,("reduced to %s\n",s));
1457 return(True);
1458 #endif
1461 /****************************************************************************
1462 expand some *s
1463 ****************************************************************************/
1464 static void expand_one(char *Mask,int len)
1466 char *p1;
1467 while ((p1 = strchr(Mask,'*')) != NULL)
1469 int lfill = (len+1) - strlen(Mask);
1470 int l1= (p1 - Mask);
1471 pstring tmp;
1472 strcpy(tmp,Mask);
1473 memset(tmp+l1,'?',lfill);
1474 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1475 strcpy(Mask,tmp);
1479 /****************************************************************************
1480 expand a wildcard expression, replacing *s with ?s
1481 ****************************************************************************/
1482 void expand_mask(char *Mask,BOOL doext)
1484 pstring mbeg,mext;
1485 pstring dirpart;
1486 pstring filepart;
1487 BOOL hasdot = False;
1488 char *p1;
1489 BOOL absolute = (*Mask == '\\');
1491 *mbeg = *mext = *dirpart = *filepart = 0;
1493 /* parse the directory and filename */
1494 if (strchr(Mask,'\\'))
1495 dirname_dos(Mask,dirpart);
1497 filename_dos(Mask,filepart);
1499 strcpy(mbeg,filepart);
1500 if ((p1 = strchr(mbeg,'.')) != NULL)
1502 hasdot = True;
1503 *p1 = 0;
1504 p1++;
1505 strcpy(mext,p1);
1507 else
1509 strcpy(mext,"");
1510 if (strlen(mbeg) > 8)
1512 strcpy(mext,mbeg + 8);
1513 mbeg[8] = 0;
1517 if (*mbeg == 0)
1518 strcpy(mbeg,"????????");
1519 if ((*mext == 0) && doext && !hasdot)
1520 strcpy(mext,"???");
1522 if (strequal(mbeg,"*") && *mext==0)
1523 strcpy(mext,"*");
1525 /* expand *'s */
1526 expand_one(mbeg,8);
1527 if (*mext)
1528 expand_one(mext,3);
1530 strcpy(Mask,dirpart);
1531 if (*dirpart || absolute) strcat(Mask,"\\");
1532 strcat(Mask,mbeg);
1533 strcat(Mask,".");
1534 strcat(Mask,mext);
1536 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1540 /****************************************************************************
1541 does a string have any uppercase chars in it?
1542 ****************************************************************************/
1543 BOOL strhasupper(char *s)
1545 while (*s)
1547 #ifdef KANJI
1548 if (is_shift_jis (*s)) {
1549 s += 2;
1550 } else if (is_kana (*s)) {
1551 s++;
1552 } else {
1553 if (isupper(*s)) return(True);
1554 s++;
1556 #else
1557 if (isupper(*s)) return(True);
1558 s++;
1559 #endif /* KANJI */
1561 return(False);
1564 /****************************************************************************
1565 does a string have any lowercase chars in it?
1566 ****************************************************************************/
1567 BOOL strhaslower(char *s)
1569 while (*s)
1571 #ifdef KANJI
1572 if (is_shift_jis (*s)) {
1573 s += 2;
1574 } else if (is_kana (*s)) {
1575 s++;
1576 } else {
1577 if (islower(*s)) return(True);
1578 s++;
1580 #else
1581 if (islower(*s)) return(True);
1582 s++;
1583 #endif /* KANJI */
1585 return(False);
1588 /****************************************************************************
1589 find the number of chars in a string
1590 ****************************************************************************/
1591 int count_chars(char *s,char c)
1593 int count=0;
1594 while (*s)
1596 if (*s == c)
1597 count++;
1598 s++;
1600 return(count);
1604 /****************************************************************************
1605 make a dir struct
1606 ****************************************************************************/
1607 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1609 char *p;
1610 pstring mask2;
1612 strcpy(mask2,mask);
1614 if ((mode & aDIR) != 0)
1615 size = 0;
1617 memset(buf+1,' ',11);
1618 if ((p = strchr(mask2,'.')) != NULL)
1620 *p = 0;
1621 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1622 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1623 *p = '.';
1625 else
1626 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1628 bzero(buf+21,DIR_STRUCT_SIZE-21);
1629 CVAL(buf,21) = mode;
1630 put_dos_date(buf,22,date);
1631 SSVAL(buf,26,size & 0xFFFF);
1632 SSVAL(buf,28,size >> 16);
1633 StrnCpy(buf+30,fname,12);
1634 if (!case_sensitive)
1635 strupper(buf+30);
1636 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1640 /*******************************************************************
1641 close the low 3 fd's and open dev/null in their place
1642 ********************************************************************/
1643 void close_low_fds(void)
1645 int fd;
1646 int i;
1647 close(0); close(1); close(2);
1648 /* try and use up these file descriptors, so silly
1649 library routines writing to stdout etc won't cause havoc */
1650 for (i=0;i<3;i++) {
1651 fd = open("/dev/null",O_RDWR,0);
1652 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1653 if (fd < 0) {
1654 DEBUG(0,("Can't open /dev/null\n"));
1655 return;
1657 if (fd != i) {
1658 DEBUG(0,("Didn't get file descriptor %d\n",i));
1659 return;
1664 /****************************************************************************
1665 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1666 else
1667 if SYSV use O_NDELAY
1668 if BSD use FNDELAY
1669 ****************************************************************************/
1670 int set_blocking(int fd, int set)
1672 int val;
1673 #ifdef O_NONBLOCK
1674 #define FLAG_TO_SET O_NONBLOCK
1675 #else
1676 #ifdef SYSV
1677 #define FLAG_TO_SET O_NDELAY
1678 #else /* BSD */
1679 #define FLAG_TO_SET FNDELAY
1680 #endif
1681 #endif
1683 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1684 return -1;
1685 if(set) /* Turn blocking on - ie. clear nonblock flag */
1686 val &= ~FLAG_TO_SET;
1687 else
1688 val |= FLAG_TO_SET;
1689 return fcntl( fd, F_SETFL, val);
1690 #undef FLAG_TO_SET
1694 /****************************************************************************
1695 write to a socket
1696 ****************************************************************************/
1697 int write_socket(int fd,char *buf,int len)
1699 int ret=0;
1701 if (passive)
1702 return(len);
1703 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1704 ret = write_data(fd,buf,len);
1706 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1707 return(ret);
1710 /****************************************************************************
1711 read from a socket
1712 ****************************************************************************/
1713 int read_udp_socket(int fd,char *buf,int len)
1715 int ret;
1716 struct sockaddr sock;
1717 int socklen;
1719 socklen = sizeof(sock);
1720 bzero((char *)&sock,socklen);
1721 bzero((char *)&lastip,sizeof(lastip));
1722 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1723 if (ret <= 0) {
1724 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1725 return(0);
1728 lastip = *(struct in_addr *) &sock.sa_data[2];
1729 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1731 return(ret);
1734 /****************************************************************************
1735 read data from a device with a timout in msec.
1736 mincount = if timeout, minimum to read before returning
1737 maxcount = number to be read.
1738 ****************************************************************************/
1739 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1741 fd_set fds;
1742 int selrtn;
1743 int readret;
1744 int nread = 0;
1745 struct timeval timeout;
1747 /* just checking .... */
1748 if (maxcnt <= 0) return(0);
1750 smb_read_error = 0;
1752 /* Blocking read */
1753 if (time_out <= 0) {
1754 if (mincnt == 0) mincnt = maxcnt;
1756 while (nread < mincnt) {
1757 readret = read(fd, buf + nread, maxcnt - nread);
1758 if (readret == 0) {
1759 smb_read_error = READ_EOF;
1760 return -1;
1763 if (readret == -1) {
1764 smb_read_error = READ_ERROR;
1765 return -1;
1767 nread += readret;
1769 return(nread);
1772 /* Most difficult - timeout read */
1773 /* If this is ever called on a disk file and
1774 mincnt is greater then the filesize then
1775 system performance will suffer severely as
1776 select always return true on disk files */
1778 /* Set initial timeout */
1779 timeout.tv_sec = time_out / 1000;
1780 timeout.tv_usec = 1000 * (time_out % 1000);
1782 for (nread=0; nread<mincnt; )
1784 FD_ZERO(&fds);
1785 FD_SET(fd,&fds);
1787 selrtn = sys_select(&fds,&timeout);
1789 /* Check if error */
1790 if(selrtn == -1) {
1791 /* something is wrong. Maybe the socket is dead? */
1792 smb_read_error = READ_ERROR;
1793 return -1;
1796 /* Did we timeout ? */
1797 if (selrtn == 0) {
1798 smb_read_error = READ_TIMEOUT;
1799 return -1;
1802 readret = read(fd, buf+nread, maxcnt-nread);
1803 if (readret == 0) {
1804 /* we got EOF on the file descriptor */
1805 smb_read_error = READ_EOF;
1806 return -1;
1809 if (readret == -1) {
1810 /* the descriptor is probably dead */
1811 smb_read_error = READ_ERROR;
1812 return -1;
1815 nread += readret;
1818 /* Return the number we got */
1819 return(nread);
1822 /****************************************************************************
1823 read data from the client. Maxtime is in milliseconds
1824 ****************************************************************************/
1825 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1827 fd_set fds;
1828 int selrtn;
1829 int nread;
1830 struct timeval timeout;
1832 FD_ZERO(&fds);
1833 FD_SET(fd,&fds);
1835 timeout.tv_sec = maxtime / 1000;
1836 timeout.tv_usec = (maxtime % 1000) * 1000;
1838 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1840 if (!FD_ISSET(fd,&fds))
1841 return 0;
1843 nread = read_udp_socket(fd, buffer, bufsize);
1845 /* return the number got */
1846 return(nread);
1849 /*******************************************************************
1850 find the difference in milliseconds between two struct timeval
1851 values
1852 ********************************************************************/
1853 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1855 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1856 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1859 /****************************************************************************
1860 send a keepalive packet (rfc1002)
1861 ****************************************************************************/
1862 BOOL send_keepalive(int client)
1864 unsigned char buf[4];
1866 buf[0] = 0x85;
1867 buf[1] = buf[2] = buf[3] = 0;
1869 return(write_data(client,(char *)buf,4) == 4);
1874 /****************************************************************************
1875 read data from the client, reading exactly N bytes.
1876 ****************************************************************************/
1877 int read_data(int fd,char *buffer,int N)
1879 int ret;
1880 int total=0;
1882 smb_read_error = 0;
1884 while (total < N)
1886 ret = read(fd,buffer + total,N - total);
1887 if (ret == 0) {
1888 smb_read_error = READ_EOF;
1889 return 0;
1891 if (ret == -1) {
1892 smb_read_error = READ_ERROR;
1893 return -1;
1895 total += ret;
1897 return total;
1901 /****************************************************************************
1902 write data to a fd
1903 ****************************************************************************/
1904 int write_data(int fd,char *buffer,int N)
1906 int total=0;
1907 int ret;
1909 while (total < N)
1911 ret = write(fd,buffer + total,N - total);
1913 if (ret == -1) return -1;
1914 if (ret == 0) return total;
1916 total += ret;
1918 return total;
1922 /****************************************************************************
1923 transfer some data between two fd's
1924 ****************************************************************************/
1925 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1927 static char *buf=NULL;
1928 static int size=0;
1929 char *buf1,*abuf;
1930 int total = 0;
1932 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1934 if (size == 0) {
1935 size = lp_readsize();
1936 size = MAX(size,1024);
1939 while (!buf && size>0) {
1940 buf = (char *)Realloc(buf,size+8);
1941 if (!buf) size /= 2;
1944 if (!buf) {
1945 DEBUG(0,("Can't allocate transfer buffer!\n"));
1946 exit(1);
1949 abuf = buf + (align%8);
1951 if (header)
1952 n += headlen;
1954 while (n > 0)
1956 int s = MIN(n,size);
1957 int ret,ret2=0;
1959 ret = 0;
1961 if (header && (headlen >= MIN(s,1024))) {
1962 buf1 = header;
1963 s = headlen;
1964 ret = headlen;
1965 headlen = 0;
1966 header = NULL;
1967 } else {
1968 buf1 = abuf;
1971 if (header && headlen > 0)
1973 ret = MIN(headlen,size);
1974 memcpy(buf1,header,ret);
1975 headlen -= ret;
1976 header += ret;
1977 if (headlen <= 0) header = NULL;
1980 if (s > ret)
1981 ret += read(infd,buf1+ret,s-ret);
1983 if (ret > 0)
1985 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1986 if (ret2 > 0) total += ret2;
1987 /* if we can't write then dump excess data */
1988 if (ret2 != ret)
1989 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1991 if (ret <= 0 || ret2 != ret)
1992 return(total);
1993 n -= ret;
1995 return(total);
1999 /****************************************************************************
2000 read 4 bytes of a smb packet and return the smb length of the packet
2001 possibly store the result in the buffer
2002 ****************************************************************************/
2003 int read_smb_length(int fd,char *inbuf,int timeout)
2005 char *buffer;
2006 char buf[4];
2007 int len=0, msg_type;
2008 BOOL ok=False;
2010 if (inbuf)
2011 buffer = inbuf;
2012 else
2013 buffer = buf;
2015 while (!ok)
2017 if (timeout > 0)
2018 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
2019 else
2020 ok = (read_data(fd,buffer,4) == 4);
2022 if (!ok)
2023 return(-1);
2025 len = smb_len(buffer);
2026 msg_type = CVAL(buffer,0);
2028 if (msg_type == 0x85)
2030 DEBUG(5,("Got keepalive packet\n"));
2031 ok = False;
2035 DEBUG(10,("got smb length of %d\n",len));
2037 return(len);
2042 /****************************************************************************
2043 read an smb from a fd and return it's length
2044 The timeout is in milli seconds
2045 ****************************************************************************/
2046 BOOL receive_smb(int fd,char *buffer,int timeout)
2048 int len,ret;
2050 smb_read_error = 0;
2052 bzero(buffer,smb_size + 100);
2054 len = read_smb_length(fd,buffer,timeout);
2055 if (len == -1)
2056 return(False);
2058 if (len > BUFFER_SIZE) {
2059 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2060 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2061 exit(1);
2064 ret = read_data(fd,buffer+4,len);
2065 if (ret != len) {
2066 smb_read_error = READ_ERROR;
2067 return False;
2070 return(True);
2074 /****************************************************************************
2075 send an smb to a fd
2076 ****************************************************************************/
2077 BOOL send_smb(int fd,char *buffer)
2079 int len;
2080 int ret,nwritten=0;
2081 len = smb_len(buffer) + 4;
2083 while (nwritten < len)
2085 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2086 if (ret <= 0)
2088 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2089 close_sockets();
2090 exit(1);
2092 nwritten += ret;
2096 return True;
2100 /****************************************************************************
2101 find a pointer to a netbios name
2102 ****************************************************************************/
2103 char *name_ptr(char *buf,int ofs)
2105 unsigned char c = *(unsigned char *)(buf+ofs);
2107 if ((c & 0xC0) == 0xC0)
2109 uint16 l;
2110 char p[2];
2111 memcpy(p,buf+ofs,2);
2112 p[0] &= ~0xC0;
2113 l = RSVAL(p,0);
2114 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2115 return(buf + l);
2117 else
2118 return(buf+ofs);
2121 /****************************************************************************
2122 extract a netbios name from a buf
2123 ****************************************************************************/
2124 int name_extract(char *buf,int ofs,char *name)
2126 char *p = name_ptr(buf,ofs);
2127 int d = PTR_DIFF(p,buf+ofs);
2128 strcpy(name,"");
2129 if (d < -50 || d > 50) return(0);
2130 return(name_interpret(p,name));
2134 /****************************************************************************
2135 return the total storage length of a mangled name
2136 ****************************************************************************/
2137 int name_len(char *s)
2139 char *s0=s;
2140 unsigned char c = *(unsigned char *)s;
2141 if ((c & 0xC0) == 0xC0)
2142 return(2);
2143 while (*s) s += (*s)+1;
2144 return(PTR_DIFF(s,s0)+1);
2147 /****************************************************************************
2148 send a single packet to a port on another machine
2149 ****************************************************************************/
2150 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2152 BOOL ret;
2153 int out_fd;
2154 struct sockaddr_in sock_out;
2156 if (passive)
2157 return(True);
2159 /* create a socket to write to */
2160 out_fd = socket(AF_INET, type, 0);
2161 if (out_fd == -1)
2163 DEBUG(0,("socket failed"));
2164 return False;
2167 /* set the address and port */
2168 bzero((char *)&sock_out,sizeof(sock_out));
2169 putip((char *)&sock_out.sin_addr,(char *)&ip);
2170 sock_out.sin_port = htons( port );
2171 sock_out.sin_family = AF_INET;
2173 if (DEBUGLEVEL > 0)
2174 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2175 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2177 /* send it */
2178 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2180 if (!ret)
2181 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2182 inet_ntoa(ip),port,errno));
2184 close(out_fd);
2185 return(ret);
2188 /*******************************************************************
2189 sleep for a specified number of milliseconds
2190 ********************************************************************/
2191 void msleep(int t)
2193 int tdiff=0;
2194 struct timeval tval,t1,t2;
2195 fd_set fds;
2197 GetTimeOfDay(&t1);
2198 GetTimeOfDay(&t2);
2200 while (tdiff < t) {
2201 tval.tv_sec = (t-tdiff)/1000;
2202 tval.tv_usec = 1000*((t-tdiff)%1000);
2204 FD_ZERO(&fds);
2205 errno = 0;
2206 sys_select(&fds,&tval);
2208 GetTimeOfDay(&t2);
2209 tdiff = TvalDiff(&t1,&t2);
2213 /****************************************************************************
2214 check if a string is part of a list
2215 ****************************************************************************/
2216 BOOL in_list(char *s,char *list,BOOL casesensitive)
2218 pstring tok;
2219 char *p=list;
2221 if (!list) return(False);
2223 while (next_token(&p,tok,LIST_SEP))
2225 if (casesensitive) {
2226 if (strcmp(tok,s) == 0)
2227 return(True);
2228 } else {
2229 if (StrCaseCmp(tok,s) == 0)
2230 return(True);
2233 return(False);
2236 /* this is used to prevent lots of mallocs of size 1 */
2237 static char *null_string = NULL;
2239 /****************************************************************************
2240 set a string value, allocing the space for the string
2241 ****************************************************************************/
2242 BOOL string_init(char **dest,char *src)
2244 int l;
2245 if (!src)
2246 src = "";
2248 l = strlen(src);
2250 if (l == 0)
2252 if (!null_string)
2253 null_string = (char *)malloc(1);
2255 *null_string = 0;
2256 *dest = null_string;
2258 else
2260 *dest = (char *)malloc(l+1);
2261 strcpy(*dest,src);
2263 return(True);
2266 /****************************************************************************
2267 free a string value
2268 ****************************************************************************/
2269 void string_free(char **s)
2271 if (!s || !(*s)) return;
2272 if (*s == null_string)
2273 *s = NULL;
2274 if (*s) free(*s);
2275 *s = NULL;
2278 /****************************************************************************
2279 set a string value, allocing the space for the string, and deallocating any
2280 existing space
2281 ****************************************************************************/
2282 BOOL string_set(char **dest,char *src)
2284 string_free(dest);
2286 return(string_init(dest,src));
2289 /****************************************************************************
2290 substitute a string for a pattern in another string. Make sure there is
2291 enough room!
2293 This routine looks for pattern in s and replaces it with
2294 insert. It may do multiple replacements.
2296 return True if a substitution was done.
2297 ****************************************************************************/
2298 BOOL string_sub(char *s,char *pattern,char *insert)
2300 BOOL ret = False;
2301 char *p;
2302 int ls,lp,li;
2304 if (!insert || !pattern || !s) return(False);
2306 ls = strlen(s);
2307 lp = strlen(pattern);
2308 li = strlen(insert);
2310 if (!*pattern) return(False);
2312 while (lp <= ls && (p = strstr(s,pattern)))
2314 ret = True;
2315 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2316 memcpy(p,insert,li);
2317 s = p + li;
2318 ls = strlen(s);
2320 return(ret);
2325 /*********************************************************
2326 * Recursive routine that is called by mask_match.
2327 * Does the actual matching.
2328 *********************************************************/
2329 BOOL do_match(char *str, char *regexp, int case_sig)
2331 char *p;
2333 for( p = regexp; *p && *str; ) {
2334 switch(*p) {
2335 case '?':
2336 str++; p++;
2337 break;
2339 case '*':
2340 /* Look for a character matching
2341 the one after the '*' */
2342 p++;
2343 if(!*p)
2344 return True; /* Automatic match */
2345 while(*str) {
2346 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2347 str++;
2348 if(do_match(str,p,case_sig))
2349 return True;
2350 if(!*str)
2351 return False;
2352 else
2353 str++;
2355 return False;
2357 default:
2358 if(case_sig) {
2359 if(*str != *p)
2360 return False;
2361 } else {
2362 if(toupper(*str) != toupper(*p))
2363 return False;
2365 str++, p++;
2366 break;
2369 if(!*p && !*str)
2370 return True;
2372 if (!*p && str[0] == '.' && str[1] == 0)
2373 return(True);
2375 if (!*str && *p == '?')
2377 while (*p == '?') p++;
2378 return(!*p);
2381 if(!*str && (*p == '*' && p[1] == '\0'))
2382 return True;
2383 return False;
2387 /*********************************************************
2388 * Routine to match a given string with a regexp - uses
2389 * simplified regexp that takes * and ? only. Case can be
2390 * significant or not.
2391 *********************************************************/
2392 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2394 char *p;
2395 pstring p1, p2;
2396 fstring ebase,eext,sbase,sext;
2398 BOOL matched;
2400 /* Make local copies of str and regexp */
2401 StrnCpy(p1,regexp,sizeof(pstring)-1);
2402 StrnCpy(p2,str,sizeof(pstring)-1);
2404 if (!strchr(p2,'.')) {
2405 strcat(p2,".");
2409 if (!strchr(p1,'.')) {
2410 strcat(p1,".");
2414 #if 0
2415 if (strchr(p1,'.'))
2417 string_sub(p1,"*.*","*");
2418 string_sub(p1,".*","*");
2420 #endif
2422 /* Remove any *? and ** as they are meaningless */
2423 for(p = p1; *p; p++)
2424 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2425 (void)strcpy( &p[1], &p[2]);
2427 if (strequal(p1,"*")) return(True);
2429 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2431 if (trans2) {
2432 strcpy(ebase,p1);
2433 strcpy(sbase,p2);
2434 } else {
2435 if ((p=strrchr(p1,'.'))) {
2436 *p = 0;
2437 strcpy(ebase,p1);
2438 strcpy(eext,p+1);
2439 } else {
2440 strcpy(ebase,p1);
2441 eext[0] = 0;
2444 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2445 *p = 0;
2446 strcpy(sbase,p2);
2447 strcpy(sext,p+1);
2448 } else {
2449 strcpy(sbase,p2);
2450 strcpy(sext,"");
2454 matched = do_match(sbase,ebase,case_sig) &&
2455 (trans2 || do_match(sext,eext,case_sig));
2457 DEBUG(5,("mask_match returning %d\n", matched));
2459 return matched;
2464 /****************************************************************************
2465 become a daemon, discarding the controlling terminal
2466 ****************************************************************************/
2467 void become_daemon(void)
2469 #ifndef NO_FORK_DEBUG
2470 if (fork())
2471 exit(0);
2473 /* detach from the terminal */
2474 #ifdef USE_SETSID
2475 setsid();
2476 #else
2477 #ifdef TIOCNOTTY
2479 int i = open("/dev/tty", O_RDWR);
2480 if (i >= 0)
2482 ioctl(i, (int) TIOCNOTTY, (char *)0);
2483 close(i);
2486 #endif
2487 #endif
2488 #endif
2492 /****************************************************************************
2493 put up a yes/no prompt
2494 ****************************************************************************/
2495 BOOL yesno(char *p)
2497 pstring ans;
2498 printf("%s",p);
2500 if (!fgets(ans,sizeof(ans)-1,stdin))
2501 return(False);
2503 if (*ans == 'y' || *ans == 'Y')
2504 return(True);
2506 return(False);
2509 /****************************************************************************
2510 read a line from a file with possible \ continuation chars.
2511 Blanks at the start or end of a line are stripped.
2512 The string will be allocated if s2 is NULL
2513 ****************************************************************************/
2514 char *fgets_slash(char *s2,int maxlen,FILE *f)
2516 char *s=s2;
2517 int len = 0;
2518 int c;
2519 BOOL start_of_line = True;
2521 if (feof(f))
2522 return(NULL);
2524 if (!s2)
2526 maxlen = MIN(maxlen,8);
2527 s = (char *)Realloc(s,maxlen);
2530 if (!s || maxlen < 2) return(NULL);
2532 *s = 0;
2534 while (len < maxlen-1)
2536 c = getc(f);
2537 switch (c)
2539 case '\r':
2540 break;
2541 case '\n':
2542 while (len > 0 && s[len-1] == ' ')
2544 s[--len] = 0;
2546 if (len > 0 && s[len-1] == '\\')
2548 s[--len] = 0;
2549 start_of_line = True;
2550 break;
2552 return(s);
2553 case EOF:
2554 if (len <= 0 && !s2)
2555 free(s);
2556 return(len>0?s:NULL);
2557 case ' ':
2558 if (start_of_line)
2559 break;
2560 default:
2561 start_of_line = False;
2562 s[len++] = c;
2563 s[len] = 0;
2565 if (!s2 && len > maxlen-3)
2567 maxlen *= 2;
2568 s = (char *)Realloc(s,maxlen);
2569 if (!s) return(NULL);
2572 return(s);
2577 /****************************************************************************
2578 set the length of a file from a filedescriptor.
2579 Returns 0 on success, -1 on failure.
2580 ****************************************************************************/
2581 int set_filelen(int fd, long len)
2583 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2584 extend a file with ftruncate. Provide alternate implementation
2585 for this */
2587 #if FTRUNCATE_CAN_EXTEND
2588 return ftruncate(fd, len);
2589 #else
2590 struct stat st;
2591 char c = 0;
2592 long currpos = lseek(fd, 0L, SEEK_CUR);
2594 if(currpos < 0)
2595 return -1;
2596 /* Do an fstat to see if the file is longer than
2597 the requested size (call ftruncate),
2598 or shorter, in which case seek to len - 1 and write 1
2599 byte of zero */
2600 if(fstat(fd, &st)<0)
2601 return -1;
2603 #ifdef S_ISFIFO
2604 if (S_ISFIFO(st.st_mode)) return 0;
2605 #endif
2607 if(st.st_size == len)
2608 return 0;
2609 if(st.st_size > len)
2610 return ftruncate(fd, len);
2612 if(lseek(fd, len-1, SEEK_SET) != len -1)
2613 return -1;
2614 if(write(fd, &c, 1)!=1)
2615 return -1;
2616 /* Seek to where we were */
2617 lseek(fd, currpos, SEEK_SET);
2618 return 0;
2619 #endif
2623 /****************************************************************************
2624 return the byte checksum of some data
2625 ****************************************************************************/
2626 int byte_checksum(char *buf,int len)
2628 unsigned char *p = (unsigned char *)buf;
2629 int ret = 0;
2630 while (len--)
2631 ret += *p++;
2632 return(ret);
2637 #ifdef HPUX
2638 /****************************************************************************
2639 this is a version of setbuffer() for those machines that only have setvbuf
2640 ****************************************************************************/
2641 void setbuffer(FILE *f,char *buf,int bufsize)
2643 setvbuf(f,buf,_IOFBF,bufsize);
2645 #endif
2648 /****************************************************************************
2649 parse out a directory name from a path name. Assumes dos style filenames.
2650 ****************************************************************************/
2651 char *dirname_dos(char *path,char *buf)
2653 char *p = strrchr(path,'\\');
2655 if (!p)
2656 strcpy(buf,path);
2657 else
2659 *p = 0;
2660 strcpy(buf,path);
2661 *p = '\\';
2664 return(buf);
2668 /****************************************************************************
2669 parse out a filename from a path name. Assumes dos style filenames.
2670 ****************************************************************************/
2671 static char *filename_dos(char *path,char *buf)
2673 char *p = strrchr(path,'\\');
2675 if (!p)
2676 strcpy(buf,path);
2677 else
2678 strcpy(buf,p+1);
2680 return(buf);
2685 /****************************************************************************
2686 expand a pointer to be a particular size
2687 ****************************************************************************/
2688 void *Realloc(void *p,int size)
2690 void *ret=NULL;
2692 if (size == 0) {
2693 if (p) free(p);
2694 DEBUG(5,("Realloc asked for 0 bytes\n"));
2695 return NULL;
2698 if (!p)
2699 ret = (void *)malloc(size);
2700 else
2701 ret = (void *)realloc(p,size);
2703 if (!ret)
2704 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2706 return(ret);
2709 #ifdef NOSTRDUP
2710 /****************************************************************************
2711 duplicate a string
2712 ****************************************************************************/
2713 char *strdup(char *s)
2715 char *ret = NULL;
2716 if (!s) return(NULL);
2717 ret = (char *)malloc(strlen(s)+1);
2718 if (!ret) return(NULL);
2719 strcpy(ret,s);
2720 return(ret);
2722 #endif
2725 /****************************************************************************
2726 Signal handler for SIGPIPE (write on a disconnected socket)
2727 ****************************************************************************/
2728 void Abort(void )
2730 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2731 exit(2);
2734 /****************************************************************************
2735 get my own name and IP
2736 ****************************************************************************/
2737 BOOL get_myname(char *my_name,struct in_addr *ip)
2739 struct hostent *hp;
2740 pstring hostname;
2742 *hostname = 0;
2744 /* get my host name */
2745 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2747 DEBUG(0,("gethostname failed\n"));
2748 return False;
2751 /* get host info */
2752 if ((hp = Get_Hostbyname(hostname)) == 0)
2754 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2755 return False;
2758 if (my_name)
2760 /* split off any parts after an initial . */
2761 char *p = strchr(hostname,'.');
2762 if (p) *p = 0;
2764 strcpy(my_name,hostname);
2767 if (ip)
2768 putip((char *)ip,(char *)hp->h_addr);
2770 return(True);
2774 /****************************************************************************
2775 true if two IP addresses are equal
2776 ****************************************************************************/
2777 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2779 uint32 a1,a2;
2780 a1 = ntohl(ip1.s_addr);
2781 a2 = ntohl(ip2.s_addr);
2782 return(a1 == a2);
2786 /****************************************************************************
2787 open a socket of the specified type, port and address for incoming data
2788 ****************************************************************************/
2789 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2791 struct hostent *hp;
2792 struct sockaddr_in sock;
2793 pstring host_name;
2794 int res;
2796 /* get my host name */
2797 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2798 { DEBUG(0,("gethostname failed\n")); return -1; }
2800 /* get host info */
2801 if ((hp = Get_Hostbyname(host_name)) == 0)
2803 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2804 return -1;
2807 bzero((char *)&sock,sizeof(sock));
2808 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2809 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2810 sock.sin_len = sizeof(sock);
2811 #endif
2812 sock.sin_port = htons( port );
2813 sock.sin_family = hp->h_addrtype;
2814 sock.sin_addr.s_addr = socket_addr;
2815 res = socket(hp->h_addrtype, type, 0);
2816 if (res == -1)
2817 { DEBUG(0,("socket failed\n")); return -1; }
2820 int one=1;
2821 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2824 /* now we've got a socket - we need to bind it */
2825 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2827 if (port) {
2828 if (port == SMB_PORT || port == NMB_PORT)
2829 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2830 port,socket_addr,strerror(errno)));
2831 close(res);
2833 if (dlevel > 0 && port < 1000)
2834 port = 7999;
2836 if (port >= 1000 && port < 9000)
2837 return(open_socket_in(type,port+1,dlevel,socket_addr));
2840 return(-1);
2842 DEBUG(3,("bind succeeded on port %d\n",port));
2844 return res;
2848 /****************************************************************************
2849 create an outgoing socket
2850 **************************************************************************/
2851 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
2853 struct sockaddr_in sock_out;
2854 int res,ret;
2855 int connect_loop = 250; /* 250 milliseconds */
2856 int loops = (timeout * 1000) / connect_loop;
2858 /* create a socket to write to */
2859 res = socket(PF_INET, type, 0);
2860 if (res == -1)
2861 { DEBUG(0,("socket error\n")); return -1; }
2863 if (type != SOCK_STREAM) return(res);
2865 bzero((char *)&sock_out,sizeof(sock_out));
2866 putip((char *)&sock_out.sin_addr,(char *)addr);
2868 sock_out.sin_port = htons( port );
2869 sock_out.sin_family = PF_INET;
2871 /* set it non-blocking */
2872 set_blocking(res,0);
2874 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2876 /* and connect it to the destination */
2877 connect_again:
2878 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
2880 if (ret < 0 && errno == EINPROGRESS && loops--) {
2881 msleep(connect_loop);
2882 goto connect_again;
2885 if (ret < 0 && errno == EINPROGRESS) {
2886 DEBUG(2,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
2887 close(res);
2888 return -1;
2891 #ifdef EISCONN
2892 if (ret < 0 && errno == EISCONN) {
2893 errno = 0;
2894 ret = 0;
2896 #endif
2898 if (ret < 0) {
2899 DEBUG(2,("error connecting to %s:%d (%s)\n",
2900 inet_ntoa(*addr),port,strerror(errno)));
2901 return -1;
2904 /* set it blocking again */
2905 set_blocking(res,1);
2907 return res;
2911 /****************************************************************************
2912 interpret a protocol description string, with a default
2913 ****************************************************************************/
2914 int interpret_protocol(char *str,int def)
2916 if (strequal(str,"NT1"))
2917 return(PROTOCOL_NT1);
2918 if (strequal(str,"LANMAN2"))
2919 return(PROTOCOL_LANMAN2);
2920 if (strequal(str,"LANMAN1"))
2921 return(PROTOCOL_LANMAN1);
2922 if (strequal(str,"CORE"))
2923 return(PROTOCOL_CORE);
2924 if (strequal(str,"COREPLUS"))
2925 return(PROTOCOL_COREPLUS);
2926 if (strequal(str,"CORE+"))
2927 return(PROTOCOL_COREPLUS);
2929 DEBUG(0,("Unrecognised protocol level %s\n",str));
2931 return(def);
2934 /****************************************************************************
2935 interpret a security level
2936 ****************************************************************************/
2937 int interpret_security(char *str,int def)
2939 if (strequal(str,"SERVER"))
2940 return(SEC_SERVER);
2941 if (strequal(str,"USER"))
2942 return(SEC_USER);
2943 if (strequal(str,"SHARE"))
2944 return(SEC_SHARE);
2946 DEBUG(0,("Unrecognised security level %s\n",str));
2948 return(def);
2952 /****************************************************************************
2953 interpret an internet address or name into an IP address in 4 byte form
2954 ****************************************************************************/
2955 uint32 interpret_addr(char *str)
2957 struct hostent *hp;
2958 uint32 res;
2959 int i;
2960 BOOL pure_address = True;
2962 if (strcmp(str,"0.0.0.0") == 0) return(0);
2963 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2965 for (i=0; pure_address && str[i]; i++)
2966 if (!(isdigit(str[i]) || str[i] == '.'))
2967 pure_address = False;
2969 /* if it's in the form of an IP address then get the lib to interpret it */
2970 if (pure_address) {
2971 res = inet_addr(str);
2972 } else {
2973 /* otherwise assume it's a network name of some sort and use
2974 Get_Hostbyname */
2975 if ((hp = Get_Hostbyname(str)) == 0) {
2976 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2977 return 0;
2979 putip((char *)&res,(char *)hp->h_addr);
2982 if (res == (uint32)-1) return(0);
2984 return(res);
2987 /*******************************************************************
2988 a convenient addition to interpret_addr()
2989 ******************************************************************/
2990 struct in_addr *interpret_addr2(char *str)
2992 static struct in_addr ret;
2993 uint32 a = interpret_addr(str);
2994 ret.s_addr = a;
2995 return(&ret);
2998 /*******************************************************************
2999 check if an IP is the 0.0.0.0
3000 ******************************************************************/
3001 BOOL zero_ip(struct in_addr ip)
3003 uint32 a;
3004 putip((char *)&a,(char *)&ip);
3005 return(a == 0);
3008 /*******************************************************************
3009 sub strings with useful parameters
3010 ********************************************************************/
3011 void standard_sub_basic(char *s)
3013 if (!strchr(s,'%')) return;
3015 string_sub(s,"%R",remote_proto);
3016 string_sub(s,"%a",remote_arch);
3017 string_sub(s,"%m",remote_machine);
3018 string_sub(s,"%L",local_machine);
3020 if (!strchr(s,'%')) return;
3022 string_sub(s,"%v",VERSION);
3023 string_sub(s,"%h",myhostname);
3024 string_sub(s,"%U",sesssetup_user);
3026 if (!strchr(s,'%')) return;
3028 string_sub(s,"%I",Client_info.addr);
3029 string_sub(s,"%M",Client_info.name);
3030 string_sub(s,"%T",timestring());
3032 if (!strchr(s,'%')) return;
3035 char pidstr[10];
3036 sprintf(pidstr,"%d",(int)getpid());
3037 string_sub(s,"%d",pidstr);
3040 if (!strchr(s,'%')) return;
3043 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
3044 if (pass) {
3045 string_sub(s,"%G",gidtoname(pass->pw_gid));
3051 /*******************************************************************
3052 are two IPs on the same subnet?
3053 ********************************************************************/
3054 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3056 uint32 net1,net2,nmask;
3058 nmask = ntohl(mask.s_addr);
3059 net1 = ntohl(ip1.s_addr);
3060 net2 = ntohl(ip2.s_addr);
3062 return((net1 & nmask) == (net2 & nmask));
3066 /*******************************************************************
3067 write a string in unicoode format
3068 ********************************************************************/
3069 int PutUniCode(char *dst,char *src)
3071 int ret = 0;
3072 while (*src) {
3073 dst[ret++] = src[0];
3074 dst[ret++] = 0;
3075 src++;
3077 dst[ret++]=0;
3078 dst[ret++]=0;
3079 return(ret);
3082 /****************************************************************************
3083 a wrapper for gethostbyname() that tries with all lower and all upper case
3084 if the initial name fails
3085 ****************************************************************************/
3086 struct hostent *Get_Hostbyname(char *name)
3088 char *name2 = strdup(name);
3089 struct hostent *ret;
3091 if (!name2)
3093 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3094 exit(0);
3097 if (!isalnum(*name2))
3099 free(name2);
3100 return(NULL);
3103 ret = gethostbyname(name2);
3104 if (ret != NULL)
3106 free(name2);
3107 return(ret);
3110 /* try with all lowercase */
3111 strlower(name2);
3112 ret = gethostbyname(name2);
3113 if (ret != NULL)
3115 free(name2);
3116 return(ret);
3119 /* try with all uppercase */
3120 strupper(name2);
3121 ret = gethostbyname(name2);
3122 if (ret != NULL)
3124 free(name2);
3125 return(ret);
3128 /* nothing works :-( */
3129 free(name2);
3130 return(NULL);
3134 /****************************************************************************
3135 check if a process exists. Does this work on all unixes?
3136 ****************************************************************************/
3137 BOOL process_exists(int pid)
3139 #ifdef LINUX
3140 fstring s;
3141 sprintf(s,"/proc/%d",pid);
3142 return(directory_exist(s,NULL));
3143 #else
3145 static BOOL tested=False;
3146 static BOOL ok=False;
3147 fstring s;
3148 if (!tested) {
3149 tested = True;
3150 sprintf(s,"/proc/%05d",getpid());
3151 ok = file_exist(s,NULL);
3153 if (ok) {
3154 sprintf(s,"/proc/%05d",pid);
3155 return(file_exist(s,NULL));
3159 /* CGH 8/16/96 - added ESRCH test */
3160 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3161 #endif
3165 /*******************************************************************
3166 turn a uid into a user name
3167 ********************************************************************/
3168 char *uidtoname(int uid)
3170 static char name[40];
3171 struct passwd *pass = getpwuid(uid);
3172 if (pass) return(pass->pw_name);
3173 sprintf(name,"%d",uid);
3174 return(name);
3177 /*******************************************************************
3178 turn a gid into a group name
3179 ********************************************************************/
3180 char *gidtoname(int gid)
3182 static char name[40];
3183 struct group *grp = getgrgid(gid);
3184 if (grp) return(grp->gr_name);
3185 sprintf(name,"%d",gid);
3186 return(name);
3189 /*******************************************************************
3190 block sigs
3191 ********************************************************************/
3192 void BlockSignals(BOOL block,int signum)
3194 #ifdef USE_SIGBLOCK
3195 int block_mask = sigmask(signum);
3196 static int oldmask = 0;
3197 if (block)
3198 oldmask = sigblock(block_mask);
3199 else
3200 sigsetmask(oldmask);
3201 #elif defined(USE_SIGPROCMASK)
3202 sigset_t set;
3203 sigemptyset(&set);
3204 sigaddset(&set,signum);
3205 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3206 #endif
3209 #if AJT
3210 /*******************************************************************
3211 my own panic function - not suitable for general use
3212 ********************************************************************/
3213 void ajt_panic(void)
3215 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3217 #endif
3219 #ifdef USE_DIRECT
3220 #define DIRECT direct
3221 #else
3222 #define DIRECT dirent
3223 #endif
3225 /*******************************************************************
3226 a readdir wrapper which just returns the file name
3227 also return the inode number if requested
3228 ********************************************************************/
3229 char *readdirname(void *p)
3231 struct DIRECT *ptr;
3232 char *dname;
3234 if (!p) return(NULL);
3236 ptr = (struct DIRECT *)readdir(p);
3237 if (!ptr) return(NULL);
3239 dname = ptr->d_name;
3241 #ifdef KANJI
3243 static pstring buf;
3244 strcpy(buf, dname);
3245 unix_to_dos(buf, True);
3246 dname = buf;
3248 #endif
3250 #ifdef NEXT2
3251 if (telldir(p) < 0) return(NULL);
3252 #endif
3254 #ifdef SUNOS5
3255 /* this handles a broken compiler setup, causing a mixture
3256 of BSD and SYSV headers and libraries */
3258 static BOOL broken_readdir = False;
3259 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3261 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3262 broken_readdir = True;
3264 if (broken_readdir)
3265 return(dname-2);
3267 #endif
3269 return(dname);