- new handling of ST_TYPE bits, they are now consolidated much more in
[Samba.git] / source / lib / util.c
blob2fedded3292ccb213688bd02d3485bc6ced63d48
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 {NULL,0,0,0,0}};
485 /****************************************************************************
486 set user socket options
487 ****************************************************************************/
488 void set_socket_options(int fd, char *options)
490 string tok;
492 while (next_token(&options,tok," \t,"))
494 int ret=0,i;
495 int value = 1;
496 char *p;
497 BOOL got_value = False;
499 if ((p = strchr(tok,'=')))
501 *p = 0;
502 value = atoi(p+1);
503 got_value = True;
506 for (i=0;socket_options[i].name;i++)
507 if (strequal(socket_options[i].name,tok))
508 break;
510 if (!socket_options[i].name)
512 DEBUG(0,("Unknown socket option %s\n",tok));
513 continue;
516 switch (socket_options[i].opttype)
518 case OPT_BOOL:
519 case OPT_INT:
520 ret = setsockopt(fd,socket_options[i].level,
521 socket_options[i].option,(char *)&value,sizeof(int));
522 break;
524 case OPT_ON:
525 if (got_value)
526 DEBUG(0,("syntax error - %s does not take a value\n",tok));
529 int on = socket_options[i].value;
530 ret = setsockopt(fd,socket_options[i].level,
531 socket_options[i].option,(char *)&on,sizeof(int));
533 break;
536 if (ret != 0)
537 DEBUG(0,("Failed to set socket option %s\n",tok));
543 /****************************************************************************
544 close the socket communication
545 ****************************************************************************/
546 void close_sockets(void )
548 close(Client);
549 Client = 0;
552 /****************************************************************************
553 determine whether we are in the specified group
554 ****************************************************************************/
555 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
557 int i;
559 if (group == current_gid) return(True);
561 for (i=0;i<ngroups;i++)
562 if (group == groups[i])
563 return(True);
565 return(False);
568 /****************************************************************************
569 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
570 ****************************************************************************/
571 char *StrCpy(char *dest,char *src)
573 char *d = dest;
575 #if AJT
576 /* I don't want to get lazy with these ... */
577 if (!dest || !src) {
578 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
579 ajt_panic();
581 #endif
583 if (!dest) return(NULL);
584 if (!src) {
585 *dest = 0;
586 return(dest);
588 while ((*d++ = *src++)) ;
589 return(dest);
592 /****************************************************************************
593 line strncpy but always null terminates. Make sure there is room!
594 ****************************************************************************/
595 char *StrnCpy(char *dest,const char *src,int n)
597 char *d = dest;
598 if (!dest) return(NULL);
599 if (!src) {
600 *dest = 0;
601 return(dest);
603 while (n-- && (*d++ = *src++)) ;
604 *d = 0;
605 return(dest);
609 /*******************************************************************
610 copy an IP address from one buffer to another
611 ********************************************************************/
612 void putip(void *dest,void *src)
614 memcpy(dest,src,4);
618 /****************************************************************************
619 interpret the weird netbios "name". Return the name type
620 ****************************************************************************/
621 static int name_interpret(char *in,char *out)
623 int ret;
624 int len = (*in++) / 2;
626 *out=0;
628 if (len > 30 || len<1) return(0);
630 while (len--)
632 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
633 *out = 0;
634 return(0);
636 *out = ((in[0]-'A')<<4) + (in[1]-'A');
637 in += 2;
638 out++;
640 *out = 0;
641 ret = out[-1];
643 #ifdef NETBIOS_SCOPE
644 /* Handle any scope names */
645 while(*in)
647 *out++ = '.'; /* Scope names are separated by periods */
648 len = *(unsigned char *)in++;
649 StrnCpy(out, in, len);
650 out += len;
651 *out=0;
652 in += len;
654 #endif
655 return(ret);
658 /****************************************************************************
659 mangle a name into netbios format
660 ****************************************************************************/
661 int name_mangle(char *In,char *Out,char name_type)
663 fstring name;
664 char buf[20];
665 char *in = (char *)&buf[0];
666 char *out = (char *)Out;
667 char *p, *label;
668 int i;
670 if (In[0] != '*') {
671 StrnCpy(name,In,sizeof(name)-1);
672 sprintf(buf,"%-15.15s%c",name,name_type);
673 } else {
674 buf[0]='*';
675 memset(&buf[1],0,16);
678 *out++ = 32;
679 for (i=0;i<16;i++) {
680 char c = toupper(in[i]);
681 out[i*2] = (c>>4) + 'A';
682 out[i*2+1] = (c & 0xF) + 'A';
684 out[32]=0;
685 out += 32;
687 label = scope;
688 while (*label)
690 p = strchr(label, '.');
691 if (p == 0)
692 p = label + strlen(label);
693 *out++ = p - label;
694 memcpy(out, label, p - label);
695 out += p - label;
696 label += p - label + (*p == '.');
698 *out = 0;
699 return(name_len(Out));
703 /*******************************************************************
704 check if a file exists
705 ********************************************************************/
706 BOOL file_exist(char *fname,struct stat *sbuf)
708 struct stat st;
709 if (!sbuf) sbuf = &st;
711 if (sys_stat(fname,sbuf) != 0)
712 return(False);
714 return(S_ISREG(sbuf->st_mode));
717 /*******************************************************************
718 check a files mod time
719 ********************************************************************/
720 time_t file_modtime(char *fname)
722 struct stat st;
724 if (sys_stat(fname,&st) != 0)
725 return(0);
727 return(st.st_mtime);
730 /*******************************************************************
731 check if a directory exists
732 ********************************************************************/
733 BOOL directory_exist(char *dname,struct stat *st)
735 struct stat st2;
736 if (!st) st = &st2;
738 if (sys_stat(dname,st) != 0)
739 return(False);
741 return(S_ISDIR(st->st_mode));
744 /*******************************************************************
745 returns the size in bytes of the named file
746 ********************************************************************/
747 uint32 file_size(char *file_name)
749 struct stat buf;
750 buf.st_size = 0;
751 sys_stat(file_name,&buf);
752 return(buf.st_size);
755 /*******************************************************************
756 return a string representing an attribute for a file
757 ********************************************************************/
758 char *attrib_string(int mode)
760 static char attrstr[10];
762 attrstr[0] = 0;
764 if (mode & aVOLID) strcat(attrstr,"V");
765 if (mode & aDIR) strcat(attrstr,"D");
766 if (mode & aARCH) strcat(attrstr,"A");
767 if (mode & aHIDDEN) strcat(attrstr,"H");
768 if (mode & aSYSTEM) strcat(attrstr,"S");
769 if (mode & aRONLY) strcat(attrstr,"R");
771 return(attrstr);
775 /*******************************************************************
776 case insensitive string compararison
777 ********************************************************************/
778 int StrCaseCmp(char *s, char *t)
780 for (; tolower(*s) == tolower(*t); ++s, ++t)
781 if (!*s) return 0;
783 return tolower(*s) - tolower(*t);
786 /*******************************************************************
787 case insensitive string compararison, length limited
788 ********************************************************************/
789 int StrnCaseCmp(char *s, char *t, int n)
791 while (n-- && *s && *t) {
792 if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
793 s++; t++;
795 if (n) return(tolower(*s) - tolower(*t));
797 return(0);
800 /*******************************************************************
801 compare 2 strings
802 ********************************************************************/
803 BOOL strequal(char *s1,char *s2)
805 if (s1 == s2) return(True);
806 if (!s1 || !s2) return(False);
808 return(StrCaseCmp(s1,s2)==0);
811 /*******************************************************************
812 compare 2 strings up to and including the nth char.
813 ******************************************************************/
814 BOOL strnequal(char *s1,char *s2,int n)
816 if (s1 == s2) return(True);
817 if (!s1 || !s2 || !n) return(False);
819 return(StrnCaseCmp(s1,s2,n)==0);
822 /*******************************************************************
823 compare 2 strings (case sensitive)
824 ********************************************************************/
825 BOOL strcsequal(char *s1,char *s2)
827 if (s1 == s2) return(True);
828 if (!s1 || !s2) return(False);
830 return(strcmp(s1,s2)==0);
834 /*******************************************************************
835 convert a string to lower case
836 ********************************************************************/
837 void strlower(char *s)
839 while (*s)
841 #ifdef KANJI
842 if (is_shift_jis (*s)) {
843 s += 2;
844 } else if (is_kana (*s)) {
845 s++;
846 } else {
847 if (isupper(*s))
848 *s = tolower(*s);
849 s++;
851 #else
852 if (isupper(*s))
853 *s = tolower(*s);
854 s++;
855 #endif /* KANJI */
859 /*******************************************************************
860 convert a string to upper case
861 ********************************************************************/
862 void strupper(char *s)
864 while (*s)
866 #ifdef KANJI
867 if (is_shift_jis (*s)) {
868 s += 2;
869 } else if (is_kana (*s)) {
870 s++;
871 } else {
872 if (islower(*s))
873 *s = toupper(*s);
874 s++;
876 #else
877 if (islower(*s))
878 *s = toupper(*s);
879 s++;
880 #endif
884 /*******************************************************************
885 convert a string to "normal" form
886 ********************************************************************/
887 void strnorm(char *s)
889 if (case_default == CASE_UPPER)
890 strupper(s);
891 else
892 strlower(s);
895 /*******************************************************************
896 check if a string is in "normal" case
897 ********************************************************************/
898 BOOL strisnormal(char *s)
900 if (case_default == CASE_UPPER)
901 return(!strhaslower(s));
903 return(!strhasupper(s));
907 /****************************************************************************
908 string replace
909 ****************************************************************************/
910 void string_replace(char *s,char oldc,char newc)
912 while (*s)
914 #ifdef KANJI
915 if (is_shift_jis (*s)) {
916 s += 2;
917 } else if (is_kana (*s)) {
918 s++;
919 } else {
920 if (oldc == *s)
921 *s = newc;
922 s++;
924 #else
925 if (oldc == *s)
926 *s = newc;
927 s++;
928 #endif /* KANJI */
932 /****************************************************************************
933 make a file into unix format
934 ****************************************************************************/
935 void unix_format(char *fname)
937 pstring namecopy;
938 string_replace(fname,'\\','/');
939 #ifndef KANJI
940 dos2unix_format(fname, True);
941 #endif /* KANJI */
943 if (*fname == '/')
945 strcpy(namecopy,fname);
946 strcpy(fname,".");
947 strcat(fname,namecopy);
951 /****************************************************************************
952 make a file into dos format
953 ****************************************************************************/
954 void dos_format(char *fname)
956 #ifndef KANJI
957 unix2dos_format(fname, True);
958 #endif /* KANJI */
959 string_replace(fname,'/','\\');
963 /*******************************************************************
964 show a smb message structure
965 ********************************************************************/
966 void show_msg(char *buf)
968 int i;
969 int bcc=0;
970 if (DEBUGLEVEL < 5)
971 return;
973 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
974 smb_len(buf),
975 (int)CVAL(buf,smb_com),
976 (int)CVAL(buf,smb_rcls),
977 (int)CVAL(buf,smb_reh),
978 (int)SVAL(buf,smb_err),
979 (int)CVAL(buf,smb_flg),
980 (int)SVAL(buf,smb_flg2)));
981 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
982 (int)SVAL(buf,smb_tid),
983 (int)SVAL(buf,smb_pid),
984 (int)SVAL(buf,smb_uid),
985 (int)SVAL(buf,smb_mid),
986 (int)CVAL(buf,smb_wct)));
987 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
988 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
989 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
990 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
991 DEBUG(5,("smb_bcc=%d\n",bcc));
992 if (DEBUGLEVEL < 10)
993 return;
994 for (i=0;i<MIN(bcc,128);i++)
995 DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
996 DEBUG(10,("\n"));
999 /*******************************************************************
1000 return the length of an smb packet
1001 ********************************************************************/
1002 int smb_len(char *buf)
1004 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1007 /*******************************************************************
1008 set the length of an smb packet
1009 ********************************************************************/
1010 void _smb_setlen(char *buf,int len)
1012 buf[0] = 0;
1013 buf[1] = (len&0x10000)>>16;
1014 buf[2] = (len&0xFF00)>>8;
1015 buf[3] = len&0xFF;
1018 /*******************************************************************
1019 set the length and marker of an smb packet
1020 ********************************************************************/
1021 void smb_setlen(char *buf,int len)
1023 _smb_setlen(buf,len);
1025 CVAL(buf,4) = 0xFF;
1026 CVAL(buf,5) = 'S';
1027 CVAL(buf,6) = 'M';
1028 CVAL(buf,7) = 'B';
1031 /*******************************************************************
1032 setup the word count and byte count for a smb message
1033 ********************************************************************/
1034 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1036 if (zero)
1037 bzero(buf + smb_size,num_words*2 + num_bytes);
1038 CVAL(buf,smb_wct) = num_words;
1039 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1040 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1041 return (smb_size + num_words*2 + num_bytes);
1044 /*******************************************************************
1045 return the number of smb words
1046 ********************************************************************/
1047 int smb_numwords(char *buf)
1049 return (CVAL(buf,smb_wct));
1052 /*******************************************************************
1053 return the size of the smb_buf region of a message
1054 ********************************************************************/
1055 int smb_buflen(char *buf)
1057 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1060 /*******************************************************************
1061 return a pointer to the smb_buf data area
1062 ********************************************************************/
1063 int smb_buf_ofs(char *buf)
1065 return (smb_size + CVAL(buf,smb_wct)*2);
1068 /*******************************************************************
1069 return a pointer to the smb_buf data area
1070 ********************************************************************/
1071 char *smb_buf(char *buf)
1073 return (buf + smb_buf_ofs(buf));
1076 /*******************************************************************
1077 return the SMB offset into an SMB buffer
1078 ********************************************************************/
1079 int smb_offset(char *p,char *buf)
1081 return(PTR_DIFF(p,buf+4) + chain_size);
1085 /*******************************************************************
1086 skip past some strings in a buffer
1087 ********************************************************************/
1088 char *skip_string(char *buf,int n)
1090 while (n--)
1091 buf += strlen(buf) + 1;
1092 return(buf);
1095 /*******************************************************************
1096 trim the specified elements off the front and back of a string
1097 ********************************************************************/
1098 BOOL trim_string(char *s,char *front,char *back)
1100 BOOL ret = False;
1101 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1103 char *p = s;
1104 ret = True;
1105 while (1)
1107 if (!(*p = p[strlen(front)]))
1108 break;
1109 p++;
1112 while (back && *back && strlen(s) >= strlen(back) &&
1113 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1115 ret = True;
1116 s[strlen(s)-strlen(back)] = 0;
1118 return(ret);
1122 /*******************************************************************
1123 reduce a file name, removing .. elements.
1124 ********************************************************************/
1125 void dos_clean_name(char *s)
1127 char *p=NULL;
1129 DEBUG(3,("dos_clean_name [%s]\n",s));
1131 /* remove any double slashes */
1132 string_sub(s, "\\\\", "\\");
1134 while ((p = strstr(s,"\\..\\")) != NULL)
1136 pstring s1;
1138 *p = 0;
1139 strcpy(s1,p+3);
1141 if ((p=strrchr(s,'\\')) != NULL)
1142 *p = 0;
1143 else
1144 *s = 0;
1145 strcat(s,s1);
1148 trim_string(s,NULL,"\\..");
1150 string_sub(s, "\\.\\", "\\");
1153 /*******************************************************************
1154 reduce a file name, removing .. elements.
1155 ********************************************************************/
1156 void unix_clean_name(char *s)
1158 char *p=NULL;
1160 DEBUG(3,("unix_clean_name [%s]\n",s));
1162 /* remove any double slashes */
1163 string_sub(s, "//","/");
1165 while ((p = strstr(s,"/../")) != NULL)
1167 pstring s1;
1169 *p = 0;
1170 strcpy(s1,p+3);
1172 if ((p=strrchr(s,'/')) != NULL)
1173 *p = 0;
1174 else
1175 *s = 0;
1176 strcat(s,s1);
1179 trim_string(s,NULL,"/..");
1183 /*******************************************************************
1184 a wrapper for the normal chdir() function
1185 ********************************************************************/
1186 int ChDir(char *path)
1188 int res;
1189 static pstring LastDir="";
1191 if (strcsequal(path,".")) return(0);
1193 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1194 DEBUG(3,("chdir to %s\n",path));
1195 res = sys_chdir(path);
1196 if (!res)
1197 strcpy(LastDir,path);
1198 return(res);
1202 /*******************************************************************
1203 return the absolute current directory path. A dumb version.
1204 ********************************************************************/
1205 static char *Dumb_GetWd(char *s)
1207 #ifdef USE_GETCWD
1208 return ((char *)getcwd(s,sizeof(pstring)));
1209 #else
1210 return ((char *)getwd(s));
1211 #endif
1215 /* number of list structures for a caching GetWd function. */
1216 #define MAX_GETWDCACHE (50)
1218 struct
1220 ino_t inode;
1221 dev_t dev;
1222 char *text;
1223 BOOL valid;
1224 } ino_list[MAX_GETWDCACHE];
1226 BOOL use_getwd_cache=True;
1228 /*******************************************************************
1229 return the absolute current directory path
1230 ********************************************************************/
1231 char *GetWd(char *str)
1233 pstring s;
1234 static BOOL getwd_cache_init = False;
1235 struct stat st, st2;
1236 int i;
1238 *s = 0;
1240 if (!use_getwd_cache)
1241 return(Dumb_GetWd(str));
1243 /* init the cache */
1244 if (!getwd_cache_init)
1246 getwd_cache_init = True;
1247 for (i=0;i<MAX_GETWDCACHE;i++)
1249 string_init(&ino_list[i].text,"");
1250 ino_list[i].valid = False;
1254 /* Get the inode of the current directory, if this doesn't work we're
1255 in trouble :-) */
1257 if (stat(".",&st) == -1)
1259 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1260 return(Dumb_GetWd(str));
1264 for (i=0; i<MAX_GETWDCACHE; i++)
1265 if (ino_list[i].valid)
1268 /* If we have found an entry with a matching inode and dev number
1269 then find the inode number for the directory in the cached string.
1270 If this agrees with that returned by the stat for the current
1271 directory then all is o.k. (but make sure it is a directory all
1272 the same...) */
1274 if (st.st_ino == ino_list[i].inode &&
1275 st.st_dev == ino_list[i].dev)
1277 if (stat(ino_list[i].text,&st2) == 0)
1279 if (st.st_ino == st2.st_ino &&
1280 st.st_dev == st2.st_dev &&
1281 (st2.st_mode & S_IFMT) == S_IFDIR)
1283 strcpy (str, ino_list[i].text);
1285 /* promote it for future use */
1286 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1287 return (str);
1289 else
1291 /* If the inode is different then something's changed,
1292 scrub the entry and start from scratch. */
1293 ino_list[i].valid = False;
1300 /* We don't have the information to hand so rely on traditional methods.
1301 The very slow getcwd, which spawns a process on some systems, or the
1302 not quite so bad getwd. */
1304 if (!Dumb_GetWd(s))
1306 DEBUG(0,("Getwd failed, errno %d\n",errno));
1307 return (NULL);
1310 strcpy(str,s);
1312 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1314 /* add it to the cache */
1315 i = MAX_GETWDCACHE - 1;
1316 string_set(&ino_list[i].text,s);
1317 ino_list[i].dev = st.st_dev;
1318 ino_list[i].inode = st.st_ino;
1319 ino_list[i].valid = True;
1321 /* put it at the top of the list */
1322 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1324 return (str);
1329 /*******************************************************************
1330 reduce a file name, removing .. elements and checking that
1331 it is below dir in the heirachy. This uses GetWd() and so must be run
1332 on the system that has the referenced file system.
1334 widelinks are allowed if widelinks is true
1335 ********************************************************************/
1336 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1338 #ifndef REDUCE_PATHS
1339 return True;
1340 #else
1341 pstring dir2;
1342 pstring wd;
1343 pstring basename;
1344 pstring newname;
1345 char *p=NULL;
1346 BOOL relative = (*s != '/');
1348 *dir2 = *wd = *basename = *newname = 0;
1350 if (widelinks)
1352 unix_clean_name(s);
1353 /* can't have a leading .. */
1354 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1356 DEBUG(3,("Illegal file name? (%s)\n",s));
1357 return(False);
1359 return(True);
1362 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1364 /* remove any double slashes */
1365 string_sub(s,"//","/");
1367 strcpy(basename,s);
1368 p = strrchr(basename,'/');
1370 if (!p)
1371 return(True);
1373 if (!GetWd(wd))
1375 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1376 return(False);
1379 if (ChDir(dir) != 0)
1381 DEBUG(0,("couldn't chdir to %s\n",dir));
1382 return(False);
1385 if (!GetWd(dir2))
1387 DEBUG(0,("couldn't getwd for %s\n",dir));
1388 ChDir(wd);
1389 return(False);
1393 if (p && (p != basename))
1395 *p = 0;
1396 if (strcmp(p+1,".")==0)
1397 p[1]=0;
1398 if (strcmp(p+1,"..")==0)
1399 *p = '/';
1402 if (ChDir(basename) != 0)
1404 ChDir(wd);
1405 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1406 return(False);
1409 if (!GetWd(newname))
1411 ChDir(wd);
1412 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1413 return(False);
1416 if (p && (p != basename))
1418 strcat(newname,"/");
1419 strcat(newname,p+1);
1423 int l = strlen(dir2);
1424 if (dir2[l-1] == '/')
1425 l--;
1427 if (strncmp(newname,dir2,l) != 0)
1429 ChDir(wd);
1430 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1431 return(False);
1434 if (relative)
1436 if (newname[l] == '/')
1437 strcpy(s,newname + l + 1);
1438 else
1439 strcpy(s,newname+l);
1441 else
1442 strcpy(s,newname);
1445 ChDir(wd);
1447 if (strlen(s) == 0)
1448 strcpy(s,"./");
1450 DEBUG(3,("reduced to %s\n",s));
1451 return(True);
1452 #endif
1455 /****************************************************************************
1456 expand some *s
1457 ****************************************************************************/
1458 static void expand_one(char *Mask,int len)
1460 char *p1;
1461 while ((p1 = strchr(Mask,'*')) != NULL)
1463 int lfill = (len+1) - strlen(Mask);
1464 int l1= (p1 - Mask);
1465 pstring tmp;
1466 strcpy(tmp,Mask);
1467 memset(tmp+l1,'?',lfill);
1468 strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1469 strcpy(Mask,tmp);
1473 /****************************************************************************
1474 expand a wildcard expression, replacing *s with ?s
1475 ****************************************************************************/
1476 void expand_mask(char *Mask,BOOL doext)
1478 pstring mbeg,mext;
1479 pstring dirpart;
1480 pstring filepart;
1481 BOOL hasdot = False;
1482 char *p1;
1483 BOOL absolute = (*Mask == '\\');
1485 *mbeg = *mext = *dirpart = *filepart = 0;
1487 /* parse the directory and filename */
1488 if (strchr(Mask,'\\'))
1489 dirname_dos(Mask,dirpart);
1491 filename_dos(Mask,filepart);
1493 strcpy(mbeg,filepart);
1494 if ((p1 = strchr(mbeg,'.')) != NULL)
1496 hasdot = True;
1497 *p1 = 0;
1498 p1++;
1499 strcpy(mext,p1);
1501 else
1503 strcpy(mext,"");
1504 if (strlen(mbeg) > 8)
1506 strcpy(mext,mbeg + 8);
1507 mbeg[8] = 0;
1511 if (*mbeg == 0)
1512 strcpy(mbeg,"????????");
1513 if ((*mext == 0) && doext && !hasdot)
1514 strcpy(mext,"???");
1516 if (strequal(mbeg,"*") && *mext==0)
1517 strcpy(mext,"*");
1519 /* expand *'s */
1520 expand_one(mbeg,8);
1521 if (*mext)
1522 expand_one(mext,3);
1524 strcpy(Mask,dirpart);
1525 if (*dirpart || absolute) strcat(Mask,"\\");
1526 strcat(Mask,mbeg);
1527 strcat(Mask,".");
1528 strcat(Mask,mext);
1530 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1534 /****************************************************************************
1535 does a string have any uppercase chars in it?
1536 ****************************************************************************/
1537 BOOL strhasupper(char *s)
1539 while (*s)
1541 #ifdef KANJI
1542 if (is_shift_jis (*s)) {
1543 s += 2;
1544 } else if (is_kana (*s)) {
1545 s++;
1546 } else {
1547 if (isupper(*s)) return(True);
1548 s++;
1550 #else
1551 if (isupper(*s)) return(True);
1552 s++;
1553 #endif /* KANJI */
1555 return(False);
1558 /****************************************************************************
1559 does a string have any lowercase chars in it?
1560 ****************************************************************************/
1561 BOOL strhaslower(char *s)
1563 while (*s)
1565 #ifdef KANJI
1566 if (is_shift_jis (*s)) {
1567 s += 2;
1568 } else if (is_kana (*s)) {
1569 s++;
1570 } else {
1571 if (islower(*s)) return(True);
1572 s++;
1574 #else
1575 if (islower(*s)) return(True);
1576 s++;
1577 #endif /* KANJI */
1579 return(False);
1582 /****************************************************************************
1583 find the number of chars in a string
1584 ****************************************************************************/
1585 int count_chars(char *s,char c)
1587 int count=0;
1588 while (*s)
1590 if (*s == c)
1591 count++;
1592 s++;
1594 return(count);
1598 /****************************************************************************
1599 make a dir struct
1600 ****************************************************************************/
1601 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1603 char *p;
1604 pstring mask2;
1606 strcpy(mask2,mask);
1608 if ((mode & aDIR) != 0)
1609 size = 0;
1611 memset(buf+1,' ',11);
1612 if ((p = strchr(mask2,'.')) != NULL)
1614 *p = 0;
1615 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1616 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1617 *p = '.';
1619 else
1620 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1622 bzero(buf+21,DIR_STRUCT_SIZE-21);
1623 CVAL(buf,21) = mode;
1624 put_dos_date(buf,22,date);
1625 SSVAL(buf,26,size & 0xFFFF);
1626 SSVAL(buf,28,size >> 16);
1627 StrnCpy(buf+30,fname,12);
1628 if (!case_sensitive)
1629 strupper(buf+30);
1630 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1634 /*******************************************************************
1635 close the low 3 fd's and open dev/null in their place
1636 ********************************************************************/
1637 void close_low_fds(void)
1639 int fd;
1640 int i;
1641 close(0); close(1); close(2);
1642 /* try and use up these file descriptors, so silly
1643 library routines writing to stdout etc won't cause havoc */
1644 for (i=0;i<3;i++) {
1645 fd = open("/dev/null",O_RDWR,0);
1646 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1647 if (fd < 0) {
1648 DEBUG(0,("Can't open /dev/null\n"));
1649 return;
1651 if (fd != i) {
1652 DEBUG(0,("Didn't get file descriptor %d\n",i));
1653 return;
1659 /****************************************************************************
1660 write to a socket
1661 ****************************************************************************/
1662 int write_socket(int fd,char *buf,int len)
1664 int ret=0;
1666 if (passive)
1667 return(len);
1668 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1669 ret = write_data(fd,buf,len);
1671 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1672 return(ret);
1675 /****************************************************************************
1676 read from a socket
1677 ****************************************************************************/
1678 int read_udp_socket(int fd,char *buf,int len)
1680 int ret;
1681 struct sockaddr sock;
1682 int socklen;
1684 socklen = sizeof(sock);
1685 bzero((char *)&sock,socklen);
1686 bzero((char *)&lastip,sizeof(lastip));
1687 ret = recvfrom(fd,buf,len,0,&sock,&socklen);
1688 if (ret <= 0) {
1689 DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
1690 return(0);
1693 lastip = *(struct in_addr *) &sock.sa_data[2];
1694 lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
1696 return(ret);
1699 /****************************************************************************
1700 read data from a device with a timout in msec.
1701 mincount = if timeout, minimum to read before returning
1702 maxcount = number to be read.
1703 ****************************************************************************/
1704 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
1706 fd_set fds;
1707 int selrtn;
1708 int readret;
1709 int nread = 0;
1710 struct timeval timeout;
1712 /* just checking .... */
1713 if (maxcnt <= 0) return(0);
1715 smb_read_error = 0;
1717 /* Blocking read */
1718 if (time_out <= 0) {
1719 if (mincnt == 0) mincnt = maxcnt;
1721 while (nread < mincnt) {
1722 readret = read(fd, buf + nread, maxcnt - nread);
1723 if (readret == 0) {
1724 smb_read_error = READ_EOF;
1725 return -1;
1728 if (readret == -1) {
1729 smb_read_error = READ_ERROR;
1730 return -1;
1732 nread += readret;
1734 return(nread);
1737 /* Most difficult - timeout read */
1738 /* If this is ever called on a disk file and
1739 mincnt is greater then the filesize then
1740 system performance will suffer severely as
1741 select always return true on disk files */
1743 /* Set initial timeout */
1744 timeout.tv_sec = time_out / 1000;
1745 timeout.tv_usec = 1000 * (time_out % 1000);
1747 for (nread=0; nread<mincnt; )
1749 FD_ZERO(&fds);
1750 FD_SET(fd,&fds);
1752 selrtn = sys_select(&fds,&timeout);
1754 /* Check if error */
1755 if(selrtn == -1) {
1756 /* something is wrong. Maybe the socket is dead? */
1757 smb_read_error = READ_ERROR;
1758 return -1;
1761 /* Did we timeout ? */
1762 if (selrtn == 0) {
1763 smb_read_error = READ_TIMEOUT;
1764 return -1;
1767 readret = read(fd, buf+nread, maxcnt-nread);
1768 if (readret == 0) {
1769 /* we got EOF on the file descriptor */
1770 smb_read_error = READ_EOF;
1771 return -1;
1774 if (readret == -1) {
1775 /* the descriptor is probably dead */
1776 smb_read_error = READ_ERROR;
1777 return -1;
1780 nread += readret;
1783 /* Return the number we got */
1784 return(nread);
1787 /****************************************************************************
1788 read data from the client. Maxtime is in milliseconds
1789 ****************************************************************************/
1790 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
1792 fd_set fds;
1793 int selrtn;
1794 int nread;
1795 struct timeval timeout;
1797 FD_ZERO(&fds);
1798 FD_SET(fd,&fds);
1800 timeout.tv_sec = maxtime / 1000;
1801 timeout.tv_usec = (maxtime % 1000) * 1000;
1803 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
1805 if (!FD_ISSET(fd,&fds))
1806 return 0;
1808 nread = read_udp_socket(fd, buffer, bufsize);
1810 /* return the number got */
1811 return(nread);
1814 /*******************************************************************
1815 find the difference in milliseconds between two struct timeval
1816 values
1817 ********************************************************************/
1818 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1820 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1821 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1824 /****************************************************************************
1825 send a keepalive packet (rfc1002)
1826 ****************************************************************************/
1827 BOOL send_keepalive(int client)
1829 unsigned char buf[4];
1831 buf[0] = 0x85;
1832 buf[1] = buf[2] = buf[3] = 0;
1834 return(write_data(client,(char *)buf,4) == 4);
1839 /****************************************************************************
1840 read data from the client, reading exactly N bytes.
1841 ****************************************************************************/
1842 int read_data(int fd,char *buffer,int N)
1844 int ret;
1845 int total=0;
1847 smb_read_error = 0;
1849 while (total < N)
1851 ret = read(fd,buffer + total,N - total);
1852 if (ret == 0) {
1853 smb_read_error = READ_EOF;
1854 return 0;
1856 if (ret == -1) {
1857 smb_read_error = READ_ERROR;
1858 return -1;
1860 total += ret;
1862 return total;
1866 /****************************************************************************
1867 write data to a fd
1868 ****************************************************************************/
1869 int write_data(int fd,char *buffer,int N)
1871 int total=0;
1872 int ret;
1874 while (total < N)
1876 ret = write(fd,buffer + total,N - total);
1878 if (ret == -1) return -1;
1879 if (ret == 0) return total;
1881 total += ret;
1883 return total;
1887 /****************************************************************************
1888 transfer some data between two fd's
1889 ****************************************************************************/
1890 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
1892 static char *buf=NULL;
1893 static int size=0;
1894 char *buf1,*abuf;
1895 int total = 0;
1897 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
1899 if (size == 0) {
1900 size = lp_readsize();
1901 size = MAX(size,1024);
1904 while (!buf && size>0) {
1905 buf = (char *)Realloc(buf,size+8);
1906 if (!buf) size /= 2;
1909 if (!buf) {
1910 DEBUG(0,("Can't allocate transfer buffer!\n"));
1911 exit(1);
1914 abuf = buf + (align%8);
1916 if (header)
1917 n += headlen;
1919 while (n > 0)
1921 int s = MIN(n,size);
1922 int ret,ret2=0;
1924 ret = 0;
1926 if (header && (headlen >= MIN(s,1024))) {
1927 buf1 = header;
1928 s = headlen;
1929 ret = headlen;
1930 headlen = 0;
1931 header = NULL;
1932 } else {
1933 buf1 = abuf;
1936 if (header && headlen > 0)
1938 ret = MIN(headlen,size);
1939 memcpy(buf1,header,ret);
1940 headlen -= ret;
1941 header += ret;
1942 if (headlen <= 0) header = NULL;
1945 if (s > ret)
1946 ret += read(infd,buf1+ret,s-ret);
1948 if (ret > 0)
1950 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
1951 if (ret2 > 0) total += ret2;
1952 /* if we can't write then dump excess data */
1953 if (ret2 != ret)
1954 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
1956 if (ret <= 0 || ret2 != ret)
1957 return(total);
1958 n -= ret;
1960 return(total);
1964 /****************************************************************************
1965 read 4 bytes of a smb packet and return the smb length of the packet
1966 possibly store the result in the buffer
1967 ****************************************************************************/
1968 int read_smb_length(int fd,char *inbuf,int timeout)
1970 char *buffer;
1971 char buf[4];
1972 int len=0, msg_type;
1973 BOOL ok=False;
1975 if (inbuf)
1976 buffer = inbuf;
1977 else
1978 buffer = buf;
1980 while (!ok)
1982 if (timeout > 0)
1983 ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
1984 else
1985 ok = (read_data(fd,buffer,4) == 4);
1987 if (!ok)
1988 return(-1);
1990 len = smb_len(buffer);
1991 msg_type = CVAL(buffer,0);
1993 if (msg_type == 0x85)
1995 DEBUG(5,("Got keepalive packet\n"));
1996 ok = False;
2000 DEBUG(10,("got smb length of %d\n",len));
2002 return(len);
2007 /****************************************************************************
2008 read an smb from a fd and return it's length
2009 The timeout is in milli seconds
2010 ****************************************************************************/
2011 BOOL receive_smb(int fd,char *buffer,int timeout)
2013 int len,ret;
2015 smb_read_error = 0;
2017 bzero(buffer,smb_size + 100);
2019 len = read_smb_length(fd,buffer,timeout);
2020 if (len == -1)
2021 return(False);
2023 if (len > BUFFER_SIZE) {
2024 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2025 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2026 exit(1);
2029 ret = read_data(fd,buffer+4,len);
2030 if (ret != len) {
2031 smb_read_error = READ_ERROR;
2032 return False;
2035 return(True);
2039 /****************************************************************************
2040 send an smb to a fd
2041 ****************************************************************************/
2042 BOOL send_smb(int fd,char *buffer)
2044 int len;
2045 int ret,nwritten=0;
2046 len = smb_len(buffer) + 4;
2048 while (nwritten < len)
2050 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2051 if (ret <= 0)
2053 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2054 close_sockets();
2055 exit(1);
2057 nwritten += ret;
2061 return True;
2065 /****************************************************************************
2066 find a pointer to a netbios name
2067 ****************************************************************************/
2068 char *name_ptr(char *buf,int ofs)
2070 unsigned char c = *(unsigned char *)(buf+ofs);
2072 if ((c & 0xC0) == 0xC0)
2074 uint16 l;
2075 char p[2];
2076 memcpy(p,buf+ofs,2);
2077 p[0] &= ~0xC0;
2078 l = RSVAL(p,0);
2079 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2080 return(buf + l);
2082 else
2083 return(buf+ofs);
2086 /****************************************************************************
2087 extract a netbios name from a buf
2088 ****************************************************************************/
2089 int name_extract(char *buf,int ofs,char *name)
2091 char *p = name_ptr(buf,ofs);
2092 int d = PTR_DIFF(p,buf+ofs);
2093 strcpy(name,"");
2094 if (d < -50 || d > 50) return(0);
2095 return(name_interpret(p,name));
2099 /****************************************************************************
2100 return the total storage length of a mangled name
2101 ****************************************************************************/
2102 int name_len(char *s)
2104 char *s0=s;
2105 unsigned char c = *(unsigned char *)s;
2106 if ((c & 0xC0) == 0xC0)
2107 return(2);
2108 while (*s) s += (*s)+1;
2109 return(PTR_DIFF(s,s0)+1);
2112 /****************************************************************************
2113 send a single packet to a port on another machine
2114 ****************************************************************************/
2115 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2117 BOOL ret;
2118 int out_fd;
2119 struct sockaddr_in sock_out;
2121 if (passive)
2122 return(True);
2124 /* create a socket to write to */
2125 out_fd = socket(AF_INET, type, 0);
2126 if (out_fd == -1)
2128 DEBUG(0,("socket failed"));
2129 return False;
2132 /* set the address and port */
2133 bzero((char *)&sock_out,sizeof(sock_out));
2134 putip((char *)&sock_out.sin_addr,(char *)&ip);
2135 sock_out.sin_port = htons( port );
2136 sock_out.sin_family = AF_INET;
2138 if (DEBUGLEVEL > 0)
2139 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2140 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2142 /* send it */
2143 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2145 if (!ret)
2146 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2147 inet_ntoa(ip),port,errno));
2149 close(out_fd);
2150 return(ret);
2153 /*******************************************************************
2154 sleep for a specified number of milliseconds
2155 ********************************************************************/
2156 void msleep(int t)
2158 int tdiff=0;
2159 struct timeval tval,t1,t2;
2160 fd_set fds;
2162 GetTimeOfDay(&t1);
2163 GetTimeOfDay(&t2);
2165 while (tdiff < t) {
2166 tval.tv_sec = (t-tdiff)/1000;
2167 tval.tv_usec = 1000*((t-tdiff)%1000);
2169 FD_ZERO(&fds);
2170 errno = 0;
2171 sys_select(&fds,&tval);
2173 GetTimeOfDay(&t2);
2174 tdiff = TvalDiff(&t1,&t2);
2178 /****************************************************************************
2179 check if a string is part of a list
2180 ****************************************************************************/
2181 BOOL in_list(char *s,char *list,BOOL casesensitive)
2183 pstring tok;
2184 char *p=list;
2186 if (!list) return(False);
2188 while (next_token(&p,tok,LIST_SEP))
2190 if (casesensitive) {
2191 if (strcmp(tok,s) == 0)
2192 return(True);
2193 } else {
2194 if (StrCaseCmp(tok,s) == 0)
2195 return(True);
2198 return(False);
2201 /* this is used to prevent lots of mallocs of size 1 */
2202 static char *null_string = NULL;
2204 /****************************************************************************
2205 set a string value, allocing the space for the string
2206 ****************************************************************************/
2207 BOOL string_init(char **dest,char *src)
2209 int l;
2210 if (!src)
2211 src = "";
2213 l = strlen(src);
2215 if (l == 0)
2217 if (!null_string)
2218 null_string = (char *)malloc(1);
2220 *null_string = 0;
2221 *dest = null_string;
2223 else
2225 *dest = (char *)malloc(l+1);
2226 strcpy(*dest,src);
2228 return(True);
2231 /****************************************************************************
2232 free a string value
2233 ****************************************************************************/
2234 void string_free(char **s)
2236 if (!s || !(*s)) return;
2237 if (*s == null_string)
2238 *s = NULL;
2239 if (*s) free(*s);
2240 *s = NULL;
2243 /****************************************************************************
2244 set a string value, allocing the space for the string, and deallocating any
2245 existing space
2246 ****************************************************************************/
2247 BOOL string_set(char **dest,char *src)
2249 string_free(dest);
2251 return(string_init(dest,src));
2254 /****************************************************************************
2255 substitute a string for a pattern in another string. Make sure there is
2256 enough room!
2258 This routine looks for pattern in s and replaces it with
2259 insert. It may do multiple replacements.
2261 return True if a substitution was done.
2262 ****************************************************************************/
2263 BOOL string_sub(char *s,char *pattern,char *insert)
2265 BOOL ret = False;
2266 char *p;
2267 int ls,lp,li;
2269 if (!insert || !pattern || !s) return(False);
2271 ls = strlen(s);
2272 lp = strlen(pattern);
2273 li = strlen(insert);
2275 if (!*pattern) return(False);
2277 while (lp <= ls && (p = strstr(s,pattern)))
2279 ret = True;
2280 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2281 memcpy(p,insert,li);
2282 s = p + li;
2283 ls = strlen(s);
2285 return(ret);
2290 /*********************************************************
2291 * Recursive routine that is called by mask_match.
2292 * Does the actual matching.
2293 *********************************************************/
2294 BOOL do_match(char *str, char *regexp, int case_sig)
2296 char *p;
2298 for( p = regexp; *p && *str; ) {
2299 switch(*p) {
2300 case '?':
2301 str++; p++;
2302 break;
2304 case '*':
2305 /* Look for a character matching
2306 the one after the '*' */
2307 p++;
2308 if(!*p)
2309 return True; /* Automatic match */
2310 while(*str) {
2311 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2312 str++;
2313 if(do_match(str,p,case_sig))
2314 return True;
2315 if(!*str)
2316 return False;
2317 else
2318 str++;
2320 return False;
2322 default:
2323 if(case_sig) {
2324 if(*str != *p)
2325 return False;
2326 } else {
2327 if(toupper(*str) != toupper(*p))
2328 return False;
2330 str++, p++;
2331 break;
2334 if(!*p && !*str)
2335 return True;
2337 if (!*p && str[0] == '.' && str[1] == 0)
2338 return(True);
2340 if (!*str && *p == '?')
2342 while (*p == '?') p++;
2343 return(!*p);
2346 if(!*str && (*p == '*' && p[1] == '\0'))
2347 return True;
2348 return False;
2352 /*********************************************************
2353 * Routine to match a given string with a regexp - uses
2354 * simplified regexp that takes * and ? only. Case can be
2355 * significant or not.
2356 *********************************************************/
2357 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2359 char *p;
2360 pstring p1, p2;
2361 fstring ebase,eext,sbase,sext;
2363 BOOL matched;
2365 /* Make local copies of str and regexp */
2366 StrnCpy(p1,regexp,sizeof(pstring)-1);
2367 StrnCpy(p2,str,sizeof(pstring)-1);
2369 if (!strchr(p2,'.')) {
2370 strcat(p2,".");
2374 if (!strchr(p1,'.')) {
2375 strcat(p1,".");
2379 #if 0
2380 if (strchr(p1,'.'))
2382 string_sub(p1,"*.*","*");
2383 string_sub(p1,".*","*");
2385 #endif
2387 /* Remove any *? and ** as they are meaningless */
2388 for(p = p1; *p; p++)
2389 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2390 (void)strcpy( &p[1], &p[2]);
2392 if (strequal(p1,"*")) return(True);
2394 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2396 if (trans2) {
2397 strcpy(ebase,p1);
2398 strcpy(sbase,p2);
2399 } else {
2400 if ((p=strrchr(p1,'.'))) {
2401 *p = 0;
2402 strcpy(ebase,p1);
2403 strcpy(eext,p+1);
2404 } else {
2405 strcpy(ebase,p1);
2406 eext[0] = 0;
2409 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2410 *p = 0;
2411 strcpy(sbase,p2);
2412 strcpy(sext,p+1);
2413 } else {
2414 strcpy(sbase,p2);
2415 strcpy(sext,"");
2419 matched = do_match(sbase,ebase,case_sig) &&
2420 (trans2 || do_match(sext,eext,case_sig));
2422 DEBUG(5,("mask_match returning %d\n", matched));
2424 return matched;
2429 /****************************************************************************
2430 become a daemon, discarding the controlling terminal
2431 ****************************************************************************/
2432 void become_daemon(void)
2434 #ifndef NO_FORK_DEBUG
2435 if (fork())
2436 exit(0);
2438 /* detach from the terminal */
2439 #ifdef USE_SETSID
2440 setsid();
2441 #else
2442 #ifdef TIOCNOTTY
2444 int i = open("/dev/tty", O_RDWR);
2445 if (i >= 0)
2447 ioctl(i, (int) TIOCNOTTY, (char *)0);
2448 close(i);
2451 #endif
2452 #endif
2453 #endif
2457 /****************************************************************************
2458 put up a yes/no prompt
2459 ****************************************************************************/
2460 BOOL yesno(char *p)
2462 pstring ans;
2463 printf("%s",p);
2465 if (!fgets(ans,sizeof(ans)-1,stdin))
2466 return(False);
2468 if (*ans == 'y' || *ans == 'Y')
2469 return(True);
2471 return(False);
2474 /****************************************************************************
2475 read a line from a file with possible \ continuation chars.
2476 Blanks at the start or end of a line are stripped.
2477 The string will be allocated if s2 is NULL
2478 ****************************************************************************/
2479 char *fgets_slash(char *s2,int maxlen,FILE *f)
2481 char *s=s2;
2482 int len = 0;
2483 int c;
2484 BOOL start_of_line = True;
2486 if (feof(f))
2487 return(NULL);
2489 if (!s2)
2491 maxlen = MIN(maxlen,8);
2492 s = (char *)Realloc(s,maxlen);
2495 if (!s || maxlen < 2) return(NULL);
2497 *s = 0;
2499 while (len < maxlen-1)
2501 c = getc(f);
2502 switch (c)
2504 case '\r':
2505 break;
2506 case '\n':
2507 while (len > 0 && s[len-1] == ' ')
2509 s[--len] = 0;
2511 if (len > 0 && s[len-1] == '\\')
2513 s[--len] = 0;
2514 start_of_line = True;
2515 break;
2517 return(s);
2518 case EOF:
2519 if (len <= 0 && !s2)
2520 free(s);
2521 return(len>0?s:NULL);
2522 case ' ':
2523 if (start_of_line)
2524 break;
2525 default:
2526 start_of_line = False;
2527 s[len++] = c;
2528 s[len] = 0;
2530 if (!s2 && len > maxlen-3)
2532 maxlen *= 2;
2533 s = (char *)Realloc(s,maxlen);
2534 if (!s) return(NULL);
2537 return(s);
2542 /****************************************************************************
2543 set the length of a file from a filedescriptor.
2544 Returns 0 on success, -1 on failure.
2545 ****************************************************************************/
2546 int set_filelen(int fd, long len)
2548 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2549 extend a file with ftruncate. Provide alternate implementation
2550 for this */
2552 #if FTRUNCATE_CAN_EXTEND
2553 return ftruncate(fd, len);
2554 #else
2555 struct stat st;
2556 char c = 0;
2557 long currpos = lseek(fd, 0L, SEEK_CUR);
2559 if(currpos < 0)
2560 return -1;
2561 /* Do an fstat to see if the file is longer than
2562 the requested size (call ftruncate),
2563 or shorter, in which case seek to len - 1 and write 1
2564 byte of zero */
2565 if(fstat(fd, &st)<0)
2566 return -1;
2568 #ifdef S_ISFIFO
2569 if (S_ISFIFO(st.st_mode)) return 0;
2570 #endif
2572 if(st.st_size == len)
2573 return 0;
2574 if(st.st_size > len)
2575 return ftruncate(fd, len);
2577 if(lseek(fd, len-1, SEEK_SET) != len -1)
2578 return -1;
2579 if(write(fd, &c, 1)!=1)
2580 return -1;
2581 /* Seek to where we were */
2582 lseek(fd, currpos, SEEK_SET);
2583 return 0;
2584 #endif
2588 /****************************************************************************
2589 return the byte checksum of some data
2590 ****************************************************************************/
2591 int byte_checksum(char *buf,int len)
2593 unsigned char *p = (unsigned char *)buf;
2594 int ret = 0;
2595 while (len--)
2596 ret += *p++;
2597 return(ret);
2602 #ifdef HPUX
2603 /****************************************************************************
2604 this is a version of setbuffer() for those machines that only have setvbuf
2605 ****************************************************************************/
2606 void setbuffer(FILE *f,char *buf,int bufsize)
2608 setvbuf(f,buf,_IOFBF,bufsize);
2610 #endif
2613 /****************************************************************************
2614 parse out a directory name from a path name. Assumes dos style filenames.
2615 ****************************************************************************/
2616 char *dirname_dos(char *path,char *buf)
2618 char *p = strrchr(path,'\\');
2620 if (!p)
2621 strcpy(buf,path);
2622 else
2624 *p = 0;
2625 strcpy(buf,path);
2626 *p = '\\';
2629 return(buf);
2633 /****************************************************************************
2634 parse out a filename from a path name. Assumes dos style filenames.
2635 ****************************************************************************/
2636 static char *filename_dos(char *path,char *buf)
2638 char *p = strrchr(path,'\\');
2640 if (!p)
2641 strcpy(buf,path);
2642 else
2643 strcpy(buf,p+1);
2645 return(buf);
2650 /****************************************************************************
2651 expand a pointer to be a particular size
2652 ****************************************************************************/
2653 void *Realloc(void *p,int size)
2655 void *ret=NULL;
2657 if (size == 0) {
2658 if (p) free(p);
2659 DEBUG(5,("Realloc asked for 0 bytes\n"));
2660 return NULL;
2663 if (!p)
2664 ret = (void *)malloc(size);
2665 else
2666 ret = (void *)realloc(p,size);
2668 if (!ret)
2669 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
2671 return(ret);
2674 #ifdef NOSTRDUP
2675 /****************************************************************************
2676 duplicate a string
2677 ****************************************************************************/
2678 char *strdup(char *s)
2680 char *ret = NULL;
2681 if (!s) return(NULL);
2682 ret = (char *)malloc(strlen(s)+1);
2683 if (!ret) return(NULL);
2684 strcpy(ret,s);
2685 return(ret);
2687 #endif
2690 /****************************************************************************
2691 Signal handler for SIGPIPE (write on a disconnected socket)
2692 ****************************************************************************/
2693 void Abort(void )
2695 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2696 exit(2);
2699 /****************************************************************************
2700 get my own name and IP
2701 ****************************************************************************/
2702 BOOL get_myname(char *my_name,struct in_addr *ip)
2704 struct hostent *hp;
2705 pstring hostname;
2707 *hostname = 0;
2709 /* get my host name */
2710 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
2712 DEBUG(0,("gethostname failed\n"));
2713 return False;
2716 /* get host info */
2717 if ((hp = Get_Hostbyname(hostname)) == 0)
2719 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
2720 return False;
2723 if (my_name)
2725 /* split off any parts after an initial . */
2726 char *p = strchr(hostname,'.');
2727 if (p) *p = 0;
2729 strcpy(my_name,hostname);
2732 if (ip)
2733 putip((char *)ip,(char *)hp->h_addr);
2735 return(True);
2739 /****************************************************************************
2740 true if two IP addresses are equal
2741 ****************************************************************************/
2742 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
2744 uint32 a1,a2;
2745 a1 = ntohl(ip1.s_addr);
2746 a2 = ntohl(ip2.s_addr);
2747 return(a1 == a2);
2751 /****************************************************************************
2752 open a socket of the specified type, port and address for incoming data
2753 ****************************************************************************/
2754 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
2756 struct hostent *hp;
2757 struct sockaddr_in sock;
2758 pstring host_name;
2759 int res;
2761 /* get my host name */
2762 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
2763 { DEBUG(0,("gethostname failed\n")); return -1; }
2765 /* get host info */
2766 if ((hp = Get_Hostbyname(host_name)) == 0)
2768 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
2769 return -1;
2772 bzero((char *)&sock,sizeof(sock));
2773 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
2774 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2775 sock.sin_len = sizeof(sock);
2776 #endif
2777 sock.sin_port = htons( port );
2778 sock.sin_family = hp->h_addrtype;
2779 sock.sin_addr.s_addr = socket_addr;
2780 res = socket(hp->h_addrtype, type, 0);
2781 if (res == -1)
2782 { DEBUG(0,("socket failed\n")); return -1; }
2785 int one=1;
2786 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
2789 /* now we've got a socket - we need to bind it */
2790 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
2792 if (port) {
2793 if (port == SMB_PORT || port == NMB_PORT)
2794 DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
2795 port,socket_addr,strerror(errno)));
2796 close(res);
2798 if (dlevel > 0 && port < 1000)
2799 port = 7999;
2801 if (port >= 1000 && port < 9000)
2802 return(open_socket_in(type,port+1,dlevel,socket_addr));
2805 return(-1);
2807 DEBUG(3,("bind succeeded on port %d\n",port));
2809 return res;
2813 /****************************************************************************
2814 create an outgoing socket
2815 **************************************************************************/
2816 int open_socket_out(int type, struct in_addr *addr, int port )
2818 struct sockaddr_in sock_out;
2819 int res;
2821 /* create a socket to write to */
2822 res = socket(PF_INET, type, 0);
2823 if (res == -1)
2824 { DEBUG(0,("socket error\n")); return -1; }
2826 if (type != SOCK_STREAM) return(res);
2828 bzero((char *)&sock_out,sizeof(sock_out));
2829 putip((char *)&sock_out.sin_addr,(char *)addr);
2831 sock_out.sin_port = htons( port );
2832 sock_out.sin_family = PF_INET;
2834 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
2836 /* and connect it to the destination */
2837 if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
2838 DEBUG(0,("connect error: %s\n",strerror(errno)));
2839 close(res);
2840 return(-1);
2843 return res;
2847 /****************************************************************************
2848 interpret a protocol description string, with a default
2849 ****************************************************************************/
2850 int interpret_protocol(char *str,int def)
2852 if (strequal(str,"NT1"))
2853 return(PROTOCOL_NT1);
2854 if (strequal(str,"LANMAN2"))
2855 return(PROTOCOL_LANMAN2);
2856 if (strequal(str,"LANMAN1"))
2857 return(PROTOCOL_LANMAN1);
2858 if (strequal(str,"CORE"))
2859 return(PROTOCOL_CORE);
2860 if (strequal(str,"COREPLUS"))
2861 return(PROTOCOL_COREPLUS);
2862 if (strequal(str,"CORE+"))
2863 return(PROTOCOL_COREPLUS);
2865 DEBUG(0,("Unrecognised protocol level %s\n",str));
2867 return(def);
2870 /****************************************************************************
2871 interpret a security level
2872 ****************************************************************************/
2873 int interpret_security(char *str,int def)
2875 if (strequal(str,"SERVER"))
2876 return(SEC_SERVER);
2877 if (strequal(str,"USER"))
2878 return(SEC_USER);
2879 if (strequal(str,"SHARE"))
2880 return(SEC_SHARE);
2882 DEBUG(0,("Unrecognised security level %s\n",str));
2884 return(def);
2888 /****************************************************************************
2889 interpret an internet address or name into an IP address in 4 byte form
2890 ****************************************************************************/
2891 uint32 interpret_addr(char *str)
2893 struct hostent *hp;
2894 uint32 res;
2895 int i;
2896 BOOL pure_address = True;
2898 if (strcmp(str,"0.0.0.0") == 0) return(0);
2899 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
2901 for (i=0; pure_address && str[i]; i++)
2902 if (!(isdigit(str[i]) || str[i] == '.'))
2903 pure_address = False;
2905 /* if it's in the form of an IP address then get the lib to interpret it */
2906 if (pure_address) {
2907 res = inet_addr(str);
2908 } else {
2909 /* otherwise assume it's a network name of some sort and use
2910 Get_Hostbyname */
2911 if ((hp = Get_Hostbyname(str)) == 0) {
2912 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
2913 return 0;
2915 putip((char *)&res,(char *)hp->h_addr);
2918 if (res == (uint32)-1) return(0);
2920 return(res);
2923 /*******************************************************************
2924 a convenient addition to interpret_addr()
2925 ******************************************************************/
2926 struct in_addr *interpret_addr2(char *str)
2928 static struct in_addr ret;
2929 uint32 a = interpret_addr(str);
2930 ret.s_addr = a;
2931 return(&ret);
2934 /*******************************************************************
2935 check if an IP is the 0.0.0.0
2936 ******************************************************************/
2937 BOOL zero_ip(struct in_addr ip)
2939 uint32 a;
2940 putip((char *)&a,(char *)&ip);
2941 return(a == 0);
2944 /*******************************************************************
2945 sub strings with useful parameters
2946 ********************************************************************/
2947 void standard_sub_basic(char *s)
2949 if (!strchr(s,'%')) return;
2951 string_sub(s,"%R",remote_proto);
2952 string_sub(s,"%a",remote_arch);
2953 string_sub(s,"%m",remote_machine);
2954 string_sub(s,"%L",local_machine);
2956 if (!strchr(s,'%')) return;
2958 string_sub(s,"%v",VERSION);
2959 string_sub(s,"%h",myhostname);
2960 string_sub(s,"%U",sesssetup_user);
2962 if (!strchr(s,'%')) return;
2964 string_sub(s,"%I",Client_info.addr);
2965 string_sub(s,"%M",Client_info.name);
2966 string_sub(s,"%T",timestring());
2968 if (!strchr(s,'%')) return;
2971 char pidstr[10];
2972 sprintf(pidstr,"%d",(int)getpid());
2973 string_sub(s,"%d",pidstr);
2976 if (!strchr(s,'%')) return;
2979 struct passwd *pass = Get_Pwnam(sesssetup_user,False);
2980 if (pass) {
2981 string_sub(s,"%G",gidtoname(pass->pw_gid));
2987 /*******************************************************************
2988 are two IPs on the same subnet?
2989 ********************************************************************/
2990 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
2992 uint32 net1,net2,nmask;
2994 nmask = ntohl(mask.s_addr);
2995 net1 = ntohl(ip1.s_addr);
2996 net2 = ntohl(ip2.s_addr);
2998 return((net1 & nmask) == (net2 & nmask));
3002 /*******************************************************************
3003 write a string in unicoode format
3004 ********************************************************************/
3005 int PutUniCode(char *dst,char *src)
3007 int ret = 0;
3008 while (*src) {
3009 dst[ret++] = src[0];
3010 dst[ret++] = 0;
3011 src++;
3013 dst[ret++]=0;
3014 dst[ret++]=0;
3015 return(ret);
3018 /****************************************************************************
3019 a wrapper for gethostbyname() that tries with all lower and all upper case
3020 if the initial name fails
3021 ****************************************************************************/
3022 struct hostent *Get_Hostbyname(char *name)
3024 char *name2 = strdup(name);
3025 struct hostent *ret;
3027 if (!name2)
3029 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3030 exit(0);
3033 if (!isalnum(*name2))
3035 free(name2);
3036 return(NULL);
3039 ret = gethostbyname(name2);
3040 if (ret != NULL)
3042 free(name2);
3043 return(ret);
3046 /* try with all lowercase */
3047 strlower(name2);
3048 ret = gethostbyname(name2);
3049 if (ret != NULL)
3051 free(name2);
3052 return(ret);
3055 /* try with all uppercase */
3056 strupper(name2);
3057 ret = gethostbyname(name2);
3058 if (ret != NULL)
3060 free(name2);
3061 return(ret);
3064 /* nothing works :-( */
3065 free(name2);
3066 return(NULL);
3070 /****************************************************************************
3071 check if a process exists. Does this work on all unixes?
3072 ****************************************************************************/
3073 BOOL process_exists(int pid)
3075 #ifdef LINUX
3076 fstring s;
3077 sprintf(s,"/proc/%d",pid);
3078 return(directory_exist(s,NULL));
3079 #else
3081 static BOOL tested=False;
3082 static BOOL ok=False;
3083 fstring s;
3084 if (!tested) {
3085 tested = True;
3086 sprintf(s,"/proc/%05d",getpid());
3087 ok = file_exist(s,NULL);
3089 if (ok) {
3090 sprintf(s,"/proc/%05d",pid);
3091 return(file_exist(s,NULL));
3095 /* CGH 8/16/96 - added ESRCH test */
3096 return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
3097 #endif
3101 /*******************************************************************
3102 turn a uid into a user name
3103 ********************************************************************/
3104 char *uidtoname(int uid)
3106 static char name[40];
3107 struct passwd *pass = getpwuid(uid);
3108 if (pass) return(pass->pw_name);
3109 sprintf(name,"%d",uid);
3110 return(name);
3113 /*******************************************************************
3114 turn a gid into a group name
3115 ********************************************************************/
3116 char *gidtoname(int gid)
3118 static char name[40];
3119 struct group *grp = getgrgid(gid);
3120 if (grp) return(grp->gr_name);
3121 sprintf(name,"%d",gid);
3122 return(name);
3125 /*******************************************************************
3126 block sigs
3127 ********************************************************************/
3128 void BlockSignals(BOOL block,int signum)
3130 #ifdef USE_SIGBLOCK
3131 int block_mask = sigmask(signum);
3132 static int oldmask = 0;
3133 if (block)
3134 oldmask = sigblock(block_mask);
3135 else
3136 sigsetmask(oldmask);
3137 #elif defined(USE_SIGPROCMASK)
3138 sigset_t set;
3139 sigemptyset(&set);
3140 sigaddset(&set,signum);
3141 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
3142 #endif
3145 #if AJT
3146 /*******************************************************************
3147 my own panic function - not suitable for general use
3148 ********************************************************************/
3149 void ajt_panic(void)
3151 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3153 #endif
3155 #ifdef USE_DIRECT
3156 #define DIRECT direct
3157 #else
3158 #define DIRECT dirent
3159 #endif
3161 /*******************************************************************
3162 a readdir wrapper which just returns the file name
3163 also return the inode number if requested
3164 ********************************************************************/
3165 char *readdirname(void *p)
3167 struct DIRECT *ptr;
3168 char *dname;
3170 if (!p) return(NULL);
3172 ptr = (struct DIRECT *)readdir(p);
3173 if (!ptr) return(NULL);
3175 dname = ptr->d_name;
3177 #ifdef KANJI
3179 static pstring buf;
3180 strcpy(buf, dname);
3181 unix_to_dos(buf, True);
3182 dname = buf;
3184 #endif
3186 #ifdef NEXT2
3187 if (telldir(p) < 0) return(NULL);
3188 #endif
3190 #ifdef SUNOS5
3191 /* this handles a broken compiler setup, causing a mixture
3192 of BSD and SYSV headers and libraries */
3194 static BOOL broken_readdir = False;
3195 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
3197 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3198 broken_readdir = True;
3200 if (broken_readdir)
3201 return(dname-2);
3203 #endif
3205 return(dname);