2 Unix SMB/Netbios implementation.
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.
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 */
38 /* the client file descriptor */
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 */
51 /* this is used by the chaining code */
57 case handling on filenames
59 int case_default
= CASE_LOWER
;
61 pstring debugf
= "/tmp/log.samba";
64 /* the following control case operations - they are put here so the
65 client can link easily */
68 BOOL use_mangled_map
= False
;
69 BOOL short_case_preserve
;
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
="";
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
)
95 char *p
= strrchr(pname
,'/');
97 openlog(pname
, LOG_PID
, LOG_DAEMON
);
101 stdout_logging
= True
;
107 BOOL append_log
=False
;
110 /****************************************************************************
112 ****************************************************************************/
113 void reopen_logs(void)
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
);
129 dbf
= fopen(debugf
,"a");
131 dbf
= fopen(debugf
,"w");
132 if (dbf
) setbuf(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;
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
;
163 if (dbf
&& file_size(debugf
) > maxlog
) {
165 fclose(dbf
); dbf
= NULL
;
166 sprintf(name
,"%s.old",debugf
);
167 sys_rename(debugf
,name
);
175 /*******************************************************************
176 write an debug message on the debugfile. This is called by the DEBUG
178 ********************************************************************/
180 int Debug1(char *format_str
, ...)
190 if (stdout_logging
) {
192 va_start(ap
, format_str
);
195 format_str
= va_arg(ap
,char *);
197 vfprintf(dbf
,format_str
,ap
);
203 if (!lp_syslog_only())
208 dbf
= fopen(debugf
,"w");
217 if (syslog_level
< lp_syslog())
220 * map debug levels to syslog() priorities
221 * note that not all DEBUG(0, ...) calls are
224 static int priority_map
[] = {
233 if (syslog_level
>= sizeof(priority_map
) / sizeof(priority_map
[0]) ||
235 priority
= LOG_DEBUG
;
237 priority
= priority_map
[syslog_level
];
240 va_start(ap
, format_str
);
243 format_str
= va_arg(ap
,char *);
245 vsprintf(msgbuf
, format_str
, ap
);
249 syslog(priority
, "%s", msgbuf
);
254 if (!lp_syslog_only())
258 va_start(ap
, format_str
);
261 format_str
= va_arg(ap
,char *);
263 vfprintf(dbf
,format_str
,ap
);
273 /****************************************************************************
274 determine if a file descriptor is in fact a socket
275 ****************************************************************************/
276 BOOL
is_a_socket(int fd
)
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
)
297 if (!ptr
) ptr
= &last_ptr
;
298 if (!ptr
) return(False
);
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
++;
309 if (! *s
) return(False
);
311 /* copy over the token */
312 for (quoted
= False
; *s
&& (quoted
|| !strchr(sep
,*s
)); s
++)
320 *ptr
= (*s
) ? s
+1 : s
;
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
)
337 if (!sep
) sep
= " \t\n\r";
339 while(*s
&& strchr(sep
,*s
)) s
++;
342 if (!*s
) return(NULL
);
346 while(*s
&& (!strchr(sep
,*s
))) s
++;
347 while(*s
&& strchr(sep
,*s
)) *s
++=0;
353 if (!(ret
=iret
=malloc(ictok
*sizeof(char *)))) return NULL
;
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
370 ********************************************************************/
371 void *MemMove(void *dest
,void *src
,int size
)
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
))) {
382 memcpy(dest
,src
,size
);
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
;
395 for (i
=0;i
<size
;i
++) idest
[i
] = isrc
[i
];
398 char *cdest
= (char *)dest
;
399 char *csrc
= (char *)src
;
400 for (i
=0;i
<size
;i
++) cdest
[i
] = csrc
[i
];
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
;
412 for (i
=size
-1;i
>=0;i
--) idest
[i
] = isrc
[i
];
415 char *cdest
= (char *)dest
;
416 char *csrc
= (char *)src
;
417 for (i
=size
-1;i
>=0;i
--) cdest
[i
] = csrc
[i
];
425 /****************************************************************************
426 prompte a dptr (to make it recently used)
427 ****************************************************************************/
428 void array_promote(char *array
,int elsize
,int element
)
434 p
= (char *)malloc(elsize
);
438 DEBUG(5,("Ahh! Can't malloc\n"));
441 memcpy(p
,array
+ element
* elsize
, elsize
);
442 memmove(array
+ elsize
,array
,elsize
*element
);
443 memcpy(array
,p
,elsize
);
447 enum SOCK_OPT_TYPES
{OPT_BOOL
,OPT_INT
,OPT_ON
};
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
},
461 {"TCP_NODELAY", IPPROTO_TCP
, TCP_NODELAY
, 0, OPT_BOOL
},
463 #ifdef IPTOS_LOWDELAY
464 {"IPTOS_LOWDELAY", IPPROTO_IP
, IP_TOS
, IPTOS_LOWDELAY
, OPT_ON
},
466 #ifdef IPTOS_THROUGHPUT
467 {"IPTOS_THROUGHPUT", IPPROTO_IP
, IP_TOS
, IPTOS_THROUGHPUT
, OPT_ON
},
470 {"SO_SNDBUF", SOL_SOCKET
, SO_SNDBUF
, 0, OPT_INT
},
473 {"SO_RCVBUF", SOL_SOCKET
, SO_RCVBUF
, 0, OPT_INT
},
476 {"SO_SNDLOWAT", SOL_SOCKET
, SO_SNDLOWAT
, 0, OPT_INT
},
479 {"SO_RCVLOWAT", SOL_SOCKET
, SO_RCVLOWAT
, 0, OPT_INT
},
485 /****************************************************************************
486 set user socket options
487 ****************************************************************************/
488 void set_socket_options(int fd
, char *options
)
492 while (next_token(&options
,tok
," \t,"))
497 BOOL got_value
= False
;
499 if ((p
= strchr(tok
,'=')))
506 for (i
=0;socket_options
[i
].name
;i
++)
507 if (strequal(socket_options
[i
].name
,tok
))
510 if (!socket_options
[i
].name
)
512 DEBUG(0,("Unknown socket option %s\n",tok
));
516 switch (socket_options
[i
].opttype
)
520 ret
= setsockopt(fd
,socket_options
[i
].level
,
521 socket_options
[i
].option
,(char *)&value
,sizeof(int));
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));
537 DEBUG(0,("Failed to set socket option %s\n",tok
));
543 /****************************************************************************
544 close the socket communication
545 ****************************************************************************/
546 void close_sockets(void )
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
)
559 if (group
== current_gid
) return(True
);
561 for (i
=0;i
<ngroups
;i
++)
562 if (group
== groups
[i
])
568 /****************************************************************************
569 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
570 ****************************************************************************/
571 char *StrCpy(char *dest
,char *src
)
576 /* I don't want to get lazy with these ... */
578 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
583 if (!dest
) return(NULL
);
588 while ((*d
++ = *src
++)) ;
592 /****************************************************************************
593 line strncpy but always null terminates. Make sure there is room!
594 ****************************************************************************/
595 char *StrnCpy(char *dest
,const char *src
,int n
)
598 if (!dest
) return(NULL
);
603 while (n
-- && (*d
++ = *src
++)) ;
609 /*******************************************************************
610 copy an IP address from one buffer to another
611 ********************************************************************/
612 void putip(void *dest
,void *src
)
618 /****************************************************************************
619 interpret the weird netbios "name". Return the name type
620 ****************************************************************************/
621 static int name_interpret(char *in
,char *out
)
624 int len
= (*in
++) / 2;
628 if (len
> 30 || len
<1) return(0);
632 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
636 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
644 /* Handle any scope names */
647 *out
++ = '.'; /* Scope names are separated by periods */
648 len
= *(unsigned char *)in
++;
649 StrnCpy(out
, in
, len
);
658 /****************************************************************************
659 mangle a name into netbios format
660 ****************************************************************************/
661 int name_mangle(char *In
,char *Out
,char name_type
)
665 char *in
= (char *)&buf
[0];
666 char *out
= (char *)Out
;
671 StrnCpy(name
,In
,sizeof(name
)-1);
672 sprintf(buf
,"%-15.15s%c",name
,name_type
);
675 memset(&buf
[1],0,16);
680 char c
= toupper(in
[i
]);
681 out
[i
*2] = (c
>>4) + 'A';
682 out
[i
*2+1] = (c
& 0xF) + 'A';
690 p
= strchr(label
, '.');
692 p
= label
+ strlen(label
);
694 memcpy(out
, label
, p
- label
);
696 label
+= p
- label
+ (*p
== '.');
699 return(name_len(Out
));
703 /*******************************************************************
704 check if a file exists
705 ********************************************************************/
706 BOOL
file_exist(char *fname
,struct stat
*sbuf
)
709 if (!sbuf
) sbuf
= &st
;
711 if (sys_stat(fname
,sbuf
) != 0)
714 return(S_ISREG(sbuf
->st_mode
));
717 /*******************************************************************
718 check a files mod time
719 ********************************************************************/
720 time_t file_modtime(char *fname
)
724 if (sys_stat(fname
,&st
) != 0)
730 /*******************************************************************
731 check if a directory exists
732 ********************************************************************/
733 BOOL
directory_exist(char *dname
,struct stat
*st
)
738 if (sys_stat(dname
,st
) != 0)
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
)
751 sys_stat(file_name
,&buf
);
755 /*******************************************************************
756 return a string representing an attribute for a file
757 ********************************************************************/
758 char *attrib_string(int mode
)
760 static char attrstr
[10];
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");
775 /*******************************************************************
776 case insensitive string compararison
777 ********************************************************************/
778 int StrCaseCmp(char *s
, char *t
)
780 for (; tolower(*s
) == tolower(*t
); ++s
, ++t
)
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
));
795 if (n
) return(tolower(*s
) - tolower(*t
));
800 /*******************************************************************
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
)
842 if (is_shift_jis (*s
)) {
844 } else if (is_kana (*s
)) {
859 /*******************************************************************
860 convert a string to upper case
861 ********************************************************************/
862 void strupper(char *s
)
867 if (is_shift_jis (*s
)) {
869 } else if (is_kana (*s
)) {
884 /*******************************************************************
885 convert a string to "normal" form
886 ********************************************************************/
887 void strnorm(char *s
)
889 if (case_default
== CASE_UPPER
)
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 /****************************************************************************
909 ****************************************************************************/
910 void string_replace(char *s
,char oldc
,char newc
)
915 if (is_shift_jis (*s
)) {
917 } else if (is_kana (*s
)) {
932 /****************************************************************************
933 make a file into unix format
934 ****************************************************************************/
935 void unix_format(char *fname
)
938 string_replace(fname
,'\\','/');
940 dos2unix_format(fname
, True
);
945 strcpy(namecopy
,fname
);
947 strcat(fname
,namecopy
);
951 /****************************************************************************
952 make a file into dos format
953 ****************************************************************************/
954 void dos_format(char *fname
)
957 unix2dos_format(fname
, True
);
959 string_replace(fname
,'/','\\');
963 /*******************************************************************
964 show a smb message structure
965 ********************************************************************/
966 void show_msg(char *buf
)
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",
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
));
994 for (i
=0;i
<MIN(bcc
,128);i
++)
995 DEBUG(10,("%X ",CVAL(smb_buf(buf
),i
)));
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
)
1013 buf
[1] = (len
&0x10000)>>16;
1014 buf
[2] = (len
&0xFF00)>>8;
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
);
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
)
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
)
1091 buf
+= strlen(buf
) + 1;
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
)
1101 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1107 if (!(*p
= p
[strlen(front
)]))
1112 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1113 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1116 s
[strlen(s
)-strlen(back
)] = 0;
1122 /*******************************************************************
1123 reduce a file name, removing .. elements.
1124 ********************************************************************/
1125 void dos_clean_name(char *s
)
1129 DEBUG(3,("dos_clean_name [%s]\n",s
));
1131 /* remove any double slashes */
1132 string_sub(s
, "\\\\", "\\");
1134 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1141 if ((p
=strrchr(s
,'\\')) != NULL
)
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
)
1160 DEBUG(3,("unix_clean_name [%s]\n",s
));
1162 /* remove any double slashes */
1163 string_sub(s
, "//","/");
1165 while ((p
= strstr(s
,"/../")) != NULL
)
1172 if ((p
=strrchr(s
,'/')) != NULL
)
1179 trim_string(s
,NULL
,"/..");
1183 /*******************************************************************
1184 a wrapper for the normal chdir() function
1185 ********************************************************************/
1186 int ChDir(char *path
)
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
);
1197 strcpy(LastDir
,path
);
1202 /*******************************************************************
1203 return the absolute current directory path. A dumb version.
1204 ********************************************************************/
1205 static char *Dumb_GetWd(char *s
)
1208 return ((char *)getcwd(s
,sizeof(pstring
)));
1210 return ((char *)getwd(s
));
1215 /* number of list structures for a caching GetWd function. */
1216 #define MAX_GETWDCACHE (50)
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
)
1234 static BOOL getwd_cache_init
= False
;
1235 struct stat st
, st2
;
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
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
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
);
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. */
1306 DEBUG(0,("Getwd failed, errno %d\n",errno
));
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
);
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
1346 BOOL relative
= (*s
!= '/');
1348 *dir2
= *wd
= *basename
= *newname
= 0;
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
));
1362 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1364 /* remove any double slashes */
1365 string_sub(s
,"//","/");
1368 p
= strrchr(basename
,'/');
1375 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1379 if (ChDir(dir
) != 0)
1381 DEBUG(0,("couldn't chdir to %s\n",dir
));
1387 DEBUG(0,("couldn't getwd for %s\n",dir
));
1393 if (p
&& (p
!= basename
))
1396 if (strcmp(p
+1,".")==0)
1398 if (strcmp(p
+1,"..")==0)
1402 if (ChDir(basename
) != 0)
1405 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,basename
));
1409 if (!GetWd(newname
))
1412 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1416 if (p
&& (p
!= basename
))
1418 strcat(newname
,"/");
1419 strcat(newname
,p
+1);
1423 int l
= strlen(dir2
);
1424 if (dir2
[l
-1] == '/')
1427 if (strncmp(newname
,dir2
,l
) != 0)
1430 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1436 if (newname
[l
] == '/')
1437 strcpy(s
,newname
+ l
+ 1);
1439 strcpy(s
,newname
+l
);
1450 DEBUG(3,("reduced to %s\n",s
));
1455 /****************************************************************************
1457 ****************************************************************************/
1458 static void expand_one(char *Mask
,int len
)
1461 while ((p1
= strchr(Mask
,'*')) != NULL
)
1463 int lfill
= (len
+1) - strlen(Mask
);
1464 int l1
= (p1
- Mask
);
1467 memset(tmp
+l1
,'?',lfill
);
1468 strcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1473 /****************************************************************************
1474 expand a wildcard expression, replacing *s with ?s
1475 ****************************************************************************/
1476 void expand_mask(char *Mask
,BOOL doext
)
1481 BOOL hasdot
= False
;
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
)
1504 if (strlen(mbeg
) > 8)
1506 strcpy(mext
,mbeg
+ 8);
1512 strcpy(mbeg
,"????????");
1513 if ((*mext
== 0) && doext
&& !hasdot
)
1516 if (strequal(mbeg
,"*") && *mext
==0)
1524 strcpy(Mask
,dirpart
);
1525 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
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
)
1542 if (is_shift_jis (*s
)) {
1544 } else if (is_kana (*s
)) {
1547 if (isupper(*s
)) return(True
);
1551 if (isupper(*s
)) return(True
);
1558 /****************************************************************************
1559 does a string have any lowercase chars in it?
1560 ****************************************************************************/
1561 BOOL
strhaslower(char *s
)
1566 if (is_shift_jis (*s
)) {
1568 } else if (is_kana (*s
)) {
1571 if (islower(*s
)) return(True
);
1575 if (islower(*s
)) return(True
);
1582 /****************************************************************************
1583 find the number of chars in a string
1584 ****************************************************************************/
1585 int count_chars(char *s
,char c
)
1598 /****************************************************************************
1600 ****************************************************************************/
1601 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1608 if ((mode
& aDIR
) != 0)
1611 memset(buf
+1,' ',11);
1612 if ((p
= strchr(mask2
,'.')) != NULL
)
1615 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1616 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
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
)
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)
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 */
1645 fd
= open("/dev/null",O_RDWR
,0);
1646 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
1648 DEBUG(0,("Can't open /dev/null\n"));
1652 DEBUG(0,("Didn't get file descriptor %d\n",i
));
1659 /****************************************************************************
1661 ****************************************************************************/
1662 int write_socket(int fd
,char *buf
,int 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
));
1675 /****************************************************************************
1677 ****************************************************************************/
1678 int read_udp_socket(int fd
,char *buf
,int len
)
1681 struct sockaddr sock
;
1684 socklen
= sizeof(sock
);
1685 bzero((char *)&sock
,socklen
);
1686 bzero((char *)&lastip
,sizeof(lastip
));
1687 ret
= recvfrom(fd
,buf
,len
,0,&sock
,&socklen
);
1689 DEBUG(2,("read socket failed. ERRNO=%d\n",errno
));
1693 lastip
= *(struct in_addr
*) &sock
.sa_data
[2];
1694 lastport
= ntohs(((struct sockaddr_in
*)&sock
)->sin_port
);
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
)
1710 struct timeval timeout
;
1712 /* just checking .... */
1713 if (maxcnt
<= 0) return(0);
1718 if (time_out
<= 0) {
1719 if (mincnt
== 0) mincnt
= maxcnt
;
1721 while (nread
< mincnt
) {
1722 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
1724 smb_read_error
= READ_EOF
;
1728 if (readret
== -1) {
1729 smb_read_error
= READ_ERROR
;
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
; )
1752 selrtn
= sys_select(&fds
,&timeout
);
1754 /* Check if error */
1756 /* something is wrong. Maybe the socket is dead? */
1757 smb_read_error
= READ_ERROR
;
1761 /* Did we timeout ? */
1763 smb_read_error
= READ_TIMEOUT
;
1767 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
1769 /* we got EOF on the file descriptor */
1770 smb_read_error
= READ_EOF
;
1774 if (readret
== -1) {
1775 /* the descriptor is probably dead */
1776 smb_read_error
= READ_ERROR
;
1783 /* Return the number we got */
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
)
1795 struct timeval timeout
;
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
))
1808 nread
= read_udp_socket(fd
, buffer
, bufsize
);
1810 /* return the number got */
1814 /*******************************************************************
1815 find the difference in milliseconds between two struct timeval
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];
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
)
1851 ret
= read(fd
,buffer
+ total
,N
- total
);
1853 smb_read_error
= READ_EOF
;
1857 smb_read_error
= READ_ERROR
;
1866 /****************************************************************************
1868 ****************************************************************************/
1869 int write_data(int fd
,char *buffer
,int N
)
1876 ret
= write(fd
,buffer
+ total
,N
- total
);
1878 if (ret
== -1) return -1;
1879 if (ret
== 0) 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
;
1897 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
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;
1910 DEBUG(0,("Can't allocate transfer buffer!\n"));
1914 abuf
= buf
+ (align
%8);
1921 int s
= MIN(n
,size
);
1926 if (header
&& (headlen
>= MIN(s
,1024))) {
1936 if (header
&& headlen
> 0)
1938 ret
= MIN(headlen
,size
);
1939 memcpy(buf1
,header
,ret
);
1942 if (headlen
<= 0) header
= NULL
;
1946 ret
+= read(infd
,buf1
+ret
,s
-ret
);
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 */
1954 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
1956 if (ret
<= 0 || ret2
!= ret
)
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
)
1972 int len
=0, msg_type
;
1983 ok
= (read_with_timeout(fd
,buffer
,4,4,timeout
) == 4);
1985 ok
= (read_data(fd
,buffer
,4) == 4);
1990 len
= smb_len(buffer
);
1991 msg_type
= CVAL(buffer
,0);
1993 if (msg_type
== 0x85)
1995 DEBUG(5,("Got keepalive packet\n"));
2000 DEBUG(10,("got smb length of %d\n",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
)
2017 bzero(buffer
,smb_size
+ 100);
2019 len
= read_smb_length(fd
,buffer
,timeout
);
2023 if (len
> BUFFER_SIZE
) {
2024 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2025 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2029 ret
= read_data(fd
,buffer
+4,len
);
2031 smb_read_error
= READ_ERROR
;
2039 /****************************************************************************
2041 ****************************************************************************/
2042 BOOL
send_smb(int fd
,char *buffer
)
2046 len
= smb_len(buffer
) + 4;
2048 while (nwritten
< len
)
2050 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2053 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
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)
2076 memcpy(p
,buf
+ofs
,2);
2079 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
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
);
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
)
2105 unsigned char c
= *(unsigned char *)s
;
2106 if ((c
& 0xC0) == 0xC0)
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
)
2119 struct sockaddr_in sock_out
;
2124 /* create a socket to write to */
2125 out_fd
= socket(AF_INET
, type
, 0);
2128 DEBUG(0,("socket failed"));
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
;
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"));
2143 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2146 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2147 inet_ntoa(ip
),port
,errno
));
2153 /*******************************************************************
2154 sleep for a specified number of milliseconds
2155 ********************************************************************/
2159 struct timeval tval
,t1
,t2
;
2166 tval
.tv_sec
= (t
-tdiff
)/1000;
2167 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2171 sys_select(&fds
,&tval
);
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
)
2186 if (!list
) return(False
);
2188 while (next_token(&p
,tok
,LIST_SEP
))
2190 if (casesensitive
) {
2191 if (strcmp(tok
,s
) == 0)
2194 if (StrCaseCmp(tok
,s
) == 0)
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
)
2218 null_string
= (char *)malloc(1);
2221 *dest
= null_string
;
2225 *dest
= (char *)malloc(l
+1);
2231 /****************************************************************************
2233 ****************************************************************************/
2234 void string_free(char **s
)
2236 if (!s
|| !(*s
)) return;
2237 if (*s
== null_string
)
2243 /****************************************************************************
2244 set a string value, allocing the space for the string, and deallocating any
2246 ****************************************************************************/
2247 BOOL
string_set(char **dest
,char *src
)
2251 return(string_init(dest
,src
));
2254 /****************************************************************************
2255 substitute a string for a pattern in another string. Make sure there is
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
)
2269 if (!insert
|| !pattern
|| !s
) return(False
);
2272 lp
= strlen(pattern
);
2273 li
= strlen(insert
);
2275 if (!*pattern
) return(False
);
2277 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2280 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2281 memcpy(p
,insert
,li
);
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
)
2298 for( p
= regexp
; *p
&& *str
; ) {
2305 /* Look for a character matching
2306 the one after the '*' */
2309 return True
; /* Automatic match */
2311 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2313 if(do_match(str
,p
,case_sig
))
2327 if(toupper(*str
) != toupper(*p
))
2337 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2340 if (!*str
&& *p
== '?')
2342 while (*p
== '?') p
++;
2346 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
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
)
2361 fstring ebase
,eext
,sbase
,sext
;
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
,'.')) {
2374 if (!strchr(p1,'.')) {
2382 string_sub(p1
,"*.*","*");
2383 string_sub(p1
,".*","*");
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
));
2400 if ((p
=strrchr(p1
,'.'))) {
2409 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
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
));
2429 /****************************************************************************
2430 become a daemon, discarding the controlling terminal
2431 ****************************************************************************/
2432 void become_daemon(void)
2434 #ifndef NO_FORK_DEBUG
2438 /* detach from the terminal */
2444 int i
= open("/dev/tty", O_RDWR
);
2447 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
2457 /****************************************************************************
2458 put up a yes/no prompt
2459 ****************************************************************************/
2465 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
2468 if (*ans
== 'y' || *ans
== 'Y')
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
)
2484 BOOL start_of_line
= True
;
2491 maxlen
= MIN(maxlen
,8);
2492 s
= (char *)Realloc(s
,maxlen
);
2495 if (!s
|| maxlen
< 2) return(NULL
);
2499 while (len
< maxlen
-1)
2507 while (len
> 0 && s
[len
-1] == ' ')
2511 if (len
> 0 && s
[len
-1] == '\\')
2514 start_of_line
= True
;
2519 if (len
<= 0 && !s2
)
2521 return(len
>0?s
:NULL
);
2526 start_of_line
= False
;
2530 if (!s2
&& len
> maxlen
-3)
2533 s
= (char *)Realloc(s
,maxlen
);
2534 if (!s
) return(NULL
);
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
2552 #if FTRUNCATE_CAN_EXTEND
2553 return ftruncate(fd
, len
);
2557 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
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
2565 if(fstat(fd
, &st
)<0)
2569 if (S_ISFIFO(st
.st_mode
)) return 0;
2572 if(st
.st_size
== len
)
2574 if(st
.st_size
> len
)
2575 return ftruncate(fd
, len
);
2577 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
2579 if(write(fd
, &c
, 1)!=1)
2581 /* Seek to where we were */
2582 lseek(fd
, currpos
, SEEK_SET
);
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
;
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
);
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
,'\\');
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
,'\\');
2650 /****************************************************************************
2651 expand a pointer to be a particular size
2652 ****************************************************************************/
2653 void *Realloc(void *p
,int size
)
2659 DEBUG(5,("Realloc asked for 0 bytes\n"));
2664 ret
= (void *)malloc(size
);
2666 ret
= (void *)realloc(p
,size
);
2669 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
2675 /****************************************************************************
2677 ****************************************************************************/
2678 char *strdup(char *s
)
2681 if (!s
) return(NULL
);
2682 ret
= (char *)malloc(strlen(s
)+1);
2683 if (!ret
) return(NULL
);
2690 /****************************************************************************
2691 Signal handler for SIGPIPE (write on a disconnected socket)
2692 ****************************************************************************/
2695 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2699 /****************************************************************************
2700 get my own name and IP
2701 ****************************************************************************/
2702 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
2709 /* get my host name */
2710 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
2712 DEBUG(0,("gethostname failed\n"));
2717 if ((hp
= Get_Hostbyname(hostname
)) == 0)
2719 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
2725 /* split off any parts after an initial . */
2726 char *p
= strchr(hostname
,'.');
2729 strcpy(my_name
,hostname
);
2733 putip((char *)ip
,(char *)hp
->h_addr
);
2739 /****************************************************************************
2740 true if two IP addresses are equal
2741 ****************************************************************************/
2742 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
2745 a1
= ntohl(ip1
.s_addr
);
2746 a2
= ntohl(ip2
.s_addr
);
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
)
2757 struct sockaddr_in sock
;
2761 /* get my host name */
2762 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
2763 { DEBUG(0,("gethostname failed\n")); return -1; }
2766 if ((hp
= Get_Hostbyname(host_name
)) == 0)
2768 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
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
);
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);
2782 { DEBUG(0,("socket failed\n")); return -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)
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
)));
2798 if (dlevel
> 0 && port
< 1000)
2801 if (port
>= 1000 && port
< 9000)
2802 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
2807 DEBUG(3,("bind succeeded on port %d\n",port
));
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
;
2821 /* create a socket to write to */
2822 res
= socket(PF_INET
, type
, 0);
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
)));
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
));
2870 /****************************************************************************
2871 interpret a security level
2872 ****************************************************************************/
2873 int interpret_security(char *str
,int def
)
2875 if (strequal(str
,"SERVER"))
2877 if (strequal(str
,"USER"))
2879 if (strequal(str
,"SHARE"))
2882 DEBUG(0,("Unrecognised security level %s\n",str
));
2888 /****************************************************************************
2889 interpret an internet address or name into an IP address in 4 byte form
2890 ****************************************************************************/
2891 uint32
interpret_addr(char *str
)
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 */
2907 res
= inet_addr(str
);
2909 /* otherwise assume it's a network name of some sort and use
2911 if ((hp
= Get_Hostbyname(str
)) == 0) {
2912 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
2915 putip((char *)&res
,(char *)hp
->h_addr
);
2918 if (res
== (uint32
)-1) return(0);
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
);
2934 /*******************************************************************
2935 check if an IP is the 0.0.0.0
2936 ******************************************************************/
2937 BOOL
zero_ip(struct in_addr ip
)
2940 putip((char *)&a
,(char *)&ip
);
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;
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
);
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
)
3009 dst
[ret
++] = src
[0];
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
;
3029 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3033 if (!isalnum(*name2
))
3039 ret
= gethostbyname(name2
);
3046 /* try with all lowercase */
3048 ret
= gethostbyname(name2
);
3055 /* try with all uppercase */
3057 ret
= gethostbyname(name2
);
3064 /* nothing works :-( */
3070 /****************************************************************************
3071 check if a process exists. Does this work on all unixes?
3072 ****************************************************************************/
3073 BOOL
process_exists(int pid
)
3077 sprintf(s
,"/proc/%d",pid
);
3078 return(directory_exist(s
,NULL
));
3081 static BOOL tested
=False
;
3082 static BOOL ok
=False
;
3086 sprintf(s
,"/proc/%05d",getpid());
3087 ok
= file_exist(s
,NULL
);
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
);
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
);
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
);
3125 /*******************************************************************
3127 ********************************************************************/
3128 void BlockSignals(BOOL block
,int signum
)
3131 int block_mask
= sigmask(signum
);
3132 static int oldmask
= 0;
3134 oldmask
= sigblock(block_mask
);
3136 sigsetmask(oldmask
);
3137 #elif defined(USE_SIGPROCMASK)
3140 sigaddset(&set
,signum
);
3141 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
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");
3156 #define DIRECT direct
3158 #define DIRECT dirent
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
)
3170 if (!p
) return(NULL
);
3172 ptr
= (struct DIRECT
*)readdir(p
);
3173 if (!ptr
) return(NULL
);
3175 dname
= ptr
->d_name
;
3181 unix_to_dos(buf
, True
);
3187 if (telldir(p
) < 0) return(NULL
);
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
;