2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 /* the last IP received from */
42 struct in_addr lastip
;
44 /* the last port received from */
47 /* this is used by the chaining code */
53 case handling on filenames
55 int case_default
= CASE_LOWER
;
60 /* the following control case operations - they are put here so the
61 client can link easily */
64 BOOL use_mangled_map
= False
;
65 BOOL short_case_preserve
;
68 fstring remote_machine
="";
69 fstring local_machine
="";
70 fstring remote_arch
="UNKNOWN";
71 fstring remote_proto
="UNKNOWN";
72 pstring myhostname
="";
73 pstring user_socket_options
="";
74 pstring sesssetup_user
="";
76 fstring myworkgroup
= "";
77 char **my_netbios_names
;
79 int smb_read_error
= 0;
81 static BOOL stdout_logging
= False
;
83 static char *filename_dos(char *path
,char *buf
);
85 /*******************************************************************
86 get ready for syslog stuff
87 ******************************************************************/
88 void setup_logging(char *pname
,BOOL interactive
)
92 char *p
= strrchr(pname
,'/');
94 openlog(pname
, LOG_PID
, LOG_DAEMON
);
98 stdout_logging
= True
;
104 BOOL append_log
=False
;
107 /****************************************************************************
109 ****************************************************************************/
110 void reopen_logs(void)
117 strcpy(fname
,debugf
);
118 if (lp_loaded() && (*lp_logfile()))
119 strcpy(fname
,lp_logfile());
121 if (!strcsequal(fname
,debugf
) || !dbf
|| !file_exist(debugf
,NULL
))
123 int oldumask
= umask(022);
124 strcpy(debugf
,fname
);
125 if (dbf
) fclose(dbf
);
127 dbf
= fopen(debugf
,"a");
129 dbf
= fopen(debugf
,"w");
130 if (dbf
) setbuf(dbf
,NULL
);
145 /*******************************************************************
146 check if the log has grown too big
147 ********************************************************************/
148 static void check_log_size(void)
150 static int debug_count
=0;
154 if (debug_count
++ < 100) return;
156 maxlog
= lp_max_log_size() * 1024;
157 if (!dbf
|| maxlog
<= 0) return;
159 if (fstat(fileno(dbf
),&st
) == 0 && st
.st_size
> maxlog
) {
160 fclose(dbf
); dbf
= NULL
;
162 if (dbf
&& file_size(debugf
) > maxlog
) {
164 fclose(dbf
); dbf
= NULL
;
165 sprintf(name
,"%s.old",debugf
);
166 sys_rename(debugf
,name
);
174 /*******************************************************************
175 write an debug message on the debugfile. This is called by the DEBUG
177 ********************************************************************/
179 int Debug1(char *format_str
, ...)
189 if (stdout_logging
) {
191 va_start(ap
, format_str
);
194 format_str
= va_arg(ap
,char *);
196 vfprintf(dbf
,format_str
,ap
);
202 if (!lp_syslog_only())
207 int oldumask
= umask(022);
208 dbf
= fopen(debugf
,"w");
218 if (syslog_level
< lp_syslog())
221 * map debug levels to syslog() priorities
222 * note that not all DEBUG(0, ...) calls are
225 static int priority_map
[] = {
234 if (syslog_level
>= sizeof(priority_map
) / sizeof(priority_map
[0]) ||
236 priority
= LOG_DEBUG
;
238 priority
= priority_map
[syslog_level
];
241 va_start(ap
, format_str
);
244 format_str
= va_arg(ap
,char *);
246 vsprintf(msgbuf
, format_str
, ap
);
250 syslog(priority
, "%s", msgbuf
);
255 if (!lp_syslog_only())
259 va_start(ap
, format_str
);
262 format_str
= va_arg(ap
,char *);
264 vfprintf(dbf
,format_str
,ap
);
274 /****************************************************************************
275 find a suitable temporary directory. The result should be copied immediately
276 as it may be overwritten by a subsequent call
277 ****************************************************************************/
281 if ((p
= getenv("TMPDIR"))) {
289 /****************************************************************************
290 determine if a file descriptor is in fact a socket
291 ****************************************************************************/
292 BOOL
is_a_socket(int fd
)
296 return(getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (char *)&v
, &l
) == 0);
300 static char *last_ptr
=NULL
;
302 /****************************************************************************
303 Get the next token from a string, return False if none found
304 handles double-quotes.
305 Based on a routine by GJC@VILLAGE.COM.
306 Extensively modified by Andrew.Tridgell@anu.edu.au
307 ****************************************************************************/
308 BOOL
next_token(char **ptr
,char *buff
,char *sep
)
313 if (!ptr
) ptr
= &last_ptr
;
314 if (!ptr
) return(False
);
318 /* default to simple separators */
319 if (!sep
) sep
= " \t\n\r";
321 /* find the first non sep char */
322 while(*s
&& strchr(sep
,*s
)) s
++;
325 if (! *s
) return(False
);
327 /* copy over the token */
328 for (quoted
= False
; *s
&& (quoted
|| !strchr(sep
,*s
)); s
++)
336 *ptr
= (*s
) ? s
+1 : s
;
343 /****************************************************************************
344 Convert list of tokens to array; dependent on above routine.
345 Uses last_ptr from above - bit of a hack.
346 ****************************************************************************/
347 char **toktocliplist(int *ctok
, char *sep
)
353 if (!sep
) sep
= " \t\n\r";
355 while(*s
&& strchr(sep
,*s
)) s
++;
358 if (!*s
) return(NULL
);
362 while(*s
&& (!strchr(sep
,*s
))) s
++;
363 while(*s
&& strchr(sep
,*s
)) *s
++=0;
369 if (!(ret
=iret
=malloc(ictok
*sizeof(char *)))) return NULL
;
381 /*******************************************************************
382 safely copies memory, ensuring no overlap problems.
383 this is only used if the machine does not have it's own memmove().
384 this is not the fastest algorithm in town, but it will do for our
386 ********************************************************************/
387 void *MemMove(void *dest
,void *src
,int size
)
391 if (dest
==src
|| !size
) return(dest
);
393 d
= (unsigned long)dest
;
394 s
= (unsigned long)src
;
396 if ((d
>= (s
+size
)) || (s
>= (d
+size
))) {
398 memcpy(dest
,src
,size
);
404 /* we can forward copy */
405 if (s
-d
>= sizeof(int) &&
406 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
407 /* do it all as words */
408 int *idest
= (int *)dest
;
409 int *isrc
= (int *)src
;
411 for (i
=0;i
<size
;i
++) idest
[i
] = isrc
[i
];
414 char *cdest
= (char *)dest
;
415 char *csrc
= (char *)src
;
416 for (i
=0;i
<size
;i
++) cdest
[i
] = csrc
[i
];
421 /* must backward copy */
422 if (d
-s
>= sizeof(int) &&
423 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
424 /* do it all as words */
425 int *idest
= (int *)dest
;
426 int *isrc
= (int *)src
;
428 for (i
=size
-1;i
>=0;i
--) idest
[i
] = isrc
[i
];
431 char *cdest
= (char *)dest
;
432 char *csrc
= (char *)src
;
433 for (i
=size
-1;i
>=0;i
--) cdest
[i
] = csrc
[i
];
441 /****************************************************************************
442 prompte a dptr (to make it recently used)
443 ****************************************************************************/
444 void array_promote(char *array
,int elsize
,int element
)
450 p
= (char *)malloc(elsize
);
454 DEBUG(5,("Ahh! Can't malloc\n"));
457 memcpy(p
,array
+ element
* elsize
, elsize
);
458 memmove(array
+ elsize
,array
,elsize
*element
);
459 memcpy(array
,p
,elsize
);
463 enum SOCK_OPT_TYPES
{OPT_BOOL
,OPT_INT
,OPT_ON
};
472 } socket_options
[] = {
473 {"SO_KEEPALIVE", SOL_SOCKET
, SO_KEEPALIVE
, 0, OPT_BOOL
},
474 {"SO_REUSEADDR", SOL_SOCKET
, SO_REUSEADDR
, 0, OPT_BOOL
},
475 {"SO_BROADCAST", SOL_SOCKET
, SO_BROADCAST
, 0, OPT_BOOL
},
477 {"TCP_NODELAY", IPPROTO_TCP
, TCP_NODELAY
, 0, OPT_BOOL
},
479 #ifdef IPTOS_LOWDELAY
480 {"IPTOS_LOWDELAY", IPPROTO_IP
, IP_TOS
, IPTOS_LOWDELAY
, OPT_ON
},
482 #ifdef IPTOS_THROUGHPUT
483 {"IPTOS_THROUGHPUT", IPPROTO_IP
, IP_TOS
, IPTOS_THROUGHPUT
, OPT_ON
},
486 {"SO_SNDBUF", SOL_SOCKET
, SO_SNDBUF
, 0, OPT_INT
},
489 {"SO_RCVBUF", SOL_SOCKET
, SO_RCVBUF
, 0, OPT_INT
},
492 {"SO_SNDLOWAT", SOL_SOCKET
, SO_SNDLOWAT
, 0, OPT_INT
},
495 {"SO_RCVLOWAT", SOL_SOCKET
, SO_RCVLOWAT
, 0, OPT_INT
},
498 {"SO_SNDTIMEO", SOL_SOCKET
, SO_SNDTIMEO
, 0, OPT_INT
},
501 {"SO_RCVTIMEO", SOL_SOCKET
, SO_RCVTIMEO
, 0, OPT_INT
},
507 /****************************************************************************
508 set user socket options
509 ****************************************************************************/
510 void set_socket_options(int fd
, char *options
)
514 while (next_token(&options
,tok
," \t,"))
519 BOOL got_value
= False
;
521 if ((p
= strchr(tok
,'=')))
528 for (i
=0;socket_options
[i
].name
;i
++)
529 if (strequal(socket_options
[i
].name
,tok
))
532 if (!socket_options
[i
].name
)
534 DEBUG(0,("Unknown socket option %s\n",tok
));
538 switch (socket_options
[i
].opttype
)
542 ret
= setsockopt(fd
,socket_options
[i
].level
,
543 socket_options
[i
].option
,(char *)&value
,sizeof(int));
548 DEBUG(0,("syntax error - %s does not take a value\n",tok
));
551 int on
= socket_options
[i
].value
;
552 ret
= setsockopt(fd
,socket_options
[i
].level
,
553 socket_options
[i
].option
,(char *)&on
,sizeof(int));
559 DEBUG(0,("Failed to set socket option %s\n",tok
));
565 /****************************************************************************
566 close the socket communication
567 ****************************************************************************/
568 void close_sockets(void )
574 /****************************************************************************
575 determine whether we are in the specified group
576 ****************************************************************************/
577 BOOL
in_group(gid_t group
, int current_gid
, int ngroups
, int *groups
)
581 if (group
== current_gid
) return(True
);
583 for (i
=0;i
<ngroups
;i
++)
584 if (group
== groups
[i
])
590 /****************************************************************************
591 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
592 ****************************************************************************/
593 char *StrCpy(char *dest
,char *src
)
598 /* I don't want to get lazy with these ... */
600 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
605 if (!dest
) return(NULL
);
610 while ((*d
++ = *src
++)) ;
614 /****************************************************************************
615 line strncpy but always null terminates. Make sure there is room!
616 ****************************************************************************/
617 char *StrnCpy(char *dest
,char *src
,int n
)
620 if (!dest
) return(NULL
);
625 while (n
-- && (*d
++ = *src
++)) ;
631 /*******************************************************************
632 copy an IP address from one buffer to another
633 ********************************************************************/
634 void putip(void *dest
,void *src
)
640 /****************************************************************************
641 interpret the weird netbios "name". Return the name type
642 ****************************************************************************/
643 static int name_interpret(char *in
,char *out
)
646 int len
= (*in
++) / 2;
650 if (len
> 30 || len
<1) return(0);
654 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
658 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
666 /* Handle any scope names */
669 *out
++ = '.'; /* Scope names are separated by periods */
670 len
= *(unsigned char *)in
++;
671 StrnCpy(out
, in
, len
);
680 /****************************************************************************
681 mangle a name into netbios format
682 ****************************************************************************/
683 int name_mangle(char *In
,char *Out
,char name_type
)
687 char *in
= (char *)&buf
[0];
688 char *out
= (char *)Out
;
693 StrnCpy(name
,In
,sizeof(name
)-1);
694 sprintf(buf
,"%-15.15s%c",name
,name_type
);
697 memset(&buf
[1],0,16);
702 char c
= toupper(in
[i
]);
703 out
[i
*2] = (c
>>4) + 'A';
704 out
[i
*2+1] = (c
& 0xF) + 'A';
712 p
= strchr(label
, '.');
714 p
= label
+ strlen(label
);
716 memcpy(out
, label
, p
- label
);
718 label
+= p
- label
+ (*p
== '.');
721 return(name_len(Out
));
725 /*******************************************************************
726 check if a file exists
727 ********************************************************************/
728 BOOL
file_exist(char *fname
,struct stat
*sbuf
)
731 if (!sbuf
) sbuf
= &st
;
733 if (sys_stat(fname
,sbuf
) != 0)
736 return(S_ISREG(sbuf
->st_mode
));
739 /*******************************************************************
740 check a files mod time
741 ********************************************************************/
742 time_t file_modtime(char *fname
)
746 if (sys_stat(fname
,&st
) != 0)
752 /*******************************************************************
753 check if a directory exists
754 ********************************************************************/
755 BOOL
directory_exist(char *dname
,struct stat
*st
)
760 if (sys_stat(dname
,st
) != 0)
763 return(S_ISDIR(st
->st_mode
));
766 /*******************************************************************
767 returns the size in bytes of the named file
768 ********************************************************************/
769 uint32
file_size(char *file_name
)
773 sys_stat(file_name
,&buf
);
777 /*******************************************************************
778 return a string representing an attribute for a file
779 ********************************************************************/
780 char *attrib_string(int mode
)
782 static char attrstr
[10];
786 if (mode
& aVOLID
) strcat(attrstr
,"V");
787 if (mode
& aDIR
) strcat(attrstr
,"D");
788 if (mode
& aARCH
) strcat(attrstr
,"A");
789 if (mode
& aHIDDEN
) strcat(attrstr
,"H");
790 if (mode
& aSYSTEM
) strcat(attrstr
,"S");
791 if (mode
& aRONLY
) strcat(attrstr
,"R");
797 /*******************************************************************
798 case insensitive string compararison
799 ********************************************************************/
800 int StrCaseCmp(const char *s
, const char *t
)
802 /* compare until we run out of string, either t or s, or find a difference */
803 /* We *must* use toupper rather than tolower here due to the
804 asynchronous upper to lower mapping.
806 while (*s
&& *t
&& toupper(*s
) == toupper(*t
))
811 return(toupper(*s
) - toupper(*t
));
814 /*******************************************************************
815 case insensitive string compararison, length limited
816 ********************************************************************/
817 int StrnCaseCmp(const char *s
, const char *t
, int n
)
819 /* compare until we run out of string, either t or s, or chars */
820 /* We *must* use toupper rather than tolower here due to the
821 asynchronous upper to lower mapping.
823 while (n
-- && *s
&& *t
&& toupper(*s
) == toupper(*t
))
828 /* not run out of chars - strings are different lengths */
829 if (n
) return(toupper(*s
) - toupper(*t
));
831 /* identical up to where we run out of chars, and strings are same length */
835 /*******************************************************************
837 ********************************************************************/
838 BOOL
strequal(const char *s1
, const char *s2
)
840 if (s1
== s2
) return(True
);
841 if (!s1
|| !s2
) return(False
);
843 return(StrCaseCmp(s1
,s2
)==0);
846 /*******************************************************************
847 compare 2 strings up to and including the nth char.
848 ******************************************************************/
849 BOOL
strnequal(const char *s1
,const char *s2
,int n
)
851 if (s1
== s2
) return(True
);
852 if (!s1
|| !s2
|| !n
) return(False
);
854 return(StrnCaseCmp(s1
,s2
,n
)==0);
857 /*******************************************************************
858 compare 2 strings (case sensitive)
859 ********************************************************************/
860 BOOL
strcsequal(char *s1
,char *s2
)
862 if (s1
== s2
) return(True
);
863 if (!s1
|| !s2
) return(False
);
865 return(strcmp(s1
,s2
)==0);
869 /*******************************************************************
870 convert a string to lower case
871 ********************************************************************/
872 void strlower(char *s
)
877 if (is_shift_jis (*s
)) {
879 } else if (is_kana (*s
)) {
894 /*******************************************************************
895 convert a string to upper case
896 ********************************************************************/
897 void strupper(char *s
)
902 if (is_shift_jis (*s
)) {
904 } else if (is_kana (*s
)) {
919 /*******************************************************************
920 convert a string to "normal" form
921 ********************************************************************/
922 void strnorm(char *s
)
924 if (case_default
== CASE_UPPER
)
930 /*******************************************************************
931 check if a string is in "normal" case
932 ********************************************************************/
933 BOOL
strisnormal(char *s
)
935 if (case_default
== CASE_UPPER
)
936 return(!strhaslower(s
));
938 return(!strhasupper(s
));
942 /****************************************************************************
944 ****************************************************************************/
945 void string_replace(char *s
,char oldc
,char newc
)
950 if (is_shift_jis (*s
)) {
952 } else if (is_kana (*s
)) {
967 /****************************************************************************
968 make a file into unix format
969 ****************************************************************************/
970 void unix_format(char *fname
)
973 string_replace(fname
,'\\','/');
977 strcpy(namecopy
,fname
);
979 strcat(fname
,namecopy
);
983 /****************************************************************************
984 make a file into dos format
985 ****************************************************************************/
986 void dos_format(char *fname
)
988 string_replace(fname
,'/','\\');
992 /*******************************************************************
993 show a smb message structure
994 ********************************************************************/
995 void show_msg(char *buf
)
1003 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1005 (int)CVAL(buf
,smb_com
),
1006 (int)CVAL(buf
,smb_rcls
),
1007 (int)CVAL(buf
,smb_reh
),
1008 (int)SVAL(buf
,smb_err
),
1009 (int)CVAL(buf
,smb_flg
),
1010 (int)SVAL(buf
,smb_flg2
)));
1011 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1012 (int)SVAL(buf
,smb_tid
),
1013 (int)SVAL(buf
,smb_pid
),
1014 (int)SVAL(buf
,smb_uid
),
1015 (int)SVAL(buf
,smb_mid
),
1016 (int)CVAL(buf
,smb_wct
)));
1017 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
1018 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i
,
1019 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
1020 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
1021 DEBUG(5,("smb_bcc=%d\n",bcc
));
1022 if (DEBUGLEVEL
< 10)
1024 for (i
= 0; i
< MIN(bcc
, 256); i
+= 16)
1026 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1029 DEBUG(10,("%2X ",CVAL(smb_buf(buf
),i
+j
)));
1030 if (j
== 7) DEBUG(10, (" "));
1035 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1037 unsigned char c
= CVAL(smb_buf(buf
),i
+j
);
1038 if (c
< 32 || c
> 128) c
= '.';
1041 if (j
== 7) DEBUG(10, (" "));
1048 /*******************************************************************
1049 return the length of an smb packet
1050 ********************************************************************/
1051 int smb_len(char *buf
)
1053 return( PVAL(buf
,3) | (PVAL(buf
,2)<<8) | ((PVAL(buf
,1)&1)<<16) );
1056 /*******************************************************************
1057 set the length of an smb packet
1058 ********************************************************************/
1059 void _smb_setlen(char *buf
,int len
)
1062 buf
[1] = (len
&0x10000)>>16;
1063 buf
[2] = (len
&0xFF00)>>8;
1067 /*******************************************************************
1068 set the length and marker of an smb packet
1069 ********************************************************************/
1070 void smb_setlen(char *buf
,int len
)
1072 _smb_setlen(buf
,len
);
1080 /*******************************************************************
1081 setup the word count and byte count for a smb message
1082 ********************************************************************/
1083 int set_message(char *buf
,int num_words
,int num_bytes
,BOOL zero
)
1086 bzero(buf
+ smb_size
,num_words
*2 + num_bytes
);
1087 CVAL(buf
,smb_wct
) = num_words
;
1088 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1089 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1090 return (smb_size
+ num_words
*2 + num_bytes
);
1093 /*******************************************************************
1094 return the number of smb words
1095 ********************************************************************/
1096 int smb_numwords(char *buf
)
1098 return (CVAL(buf
,smb_wct
));
1101 /*******************************************************************
1102 return the size of the smb_buf region of a message
1103 ********************************************************************/
1104 int smb_buflen(char *buf
)
1106 return(SVAL(buf
,smb_vwv0
+ smb_numwords(buf
)*2));
1109 /*******************************************************************
1110 return a pointer to the smb_buf data area
1111 ********************************************************************/
1112 int smb_buf_ofs(char *buf
)
1114 return (smb_size
+ CVAL(buf
,smb_wct
)*2);
1117 /*******************************************************************
1118 return a pointer to the smb_buf data area
1119 ********************************************************************/
1120 char *smb_buf(char *buf
)
1122 return (buf
+ smb_buf_ofs(buf
));
1125 /*******************************************************************
1126 return the SMB offset into an SMB buffer
1127 ********************************************************************/
1128 int smb_offset(char *p
,char *buf
)
1130 return(PTR_DIFF(p
,buf
+4) + chain_size
);
1134 /*******************************************************************
1135 skip past some strings in a buffer
1136 ********************************************************************/
1137 char *skip_string(char *buf
,int n
)
1140 buf
+= strlen(buf
) + 1;
1144 /*******************************************************************
1145 trim the specified elements off the front and back of a string
1146 ********************************************************************/
1147 BOOL
trim_string(char *s
,char *front
,char *back
)
1150 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1156 if (!(*p
= p
[strlen(front
)]))
1161 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1162 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1165 s
[strlen(s
)-strlen(back
)] = 0;
1171 /*******************************************************************
1172 reduce a file name, removing .. elements.
1173 ********************************************************************/
1174 void dos_clean_name(char *s
)
1178 DEBUG(3,("dos_clean_name [%s]\n",s
));
1180 /* remove any double slashes */
1181 string_sub(s
, "\\\\", "\\");
1183 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1190 if ((p
=strrchr(s
,'\\')) != NULL
)
1197 trim_string(s
,NULL
,"\\..");
1199 string_sub(s
, "\\.\\", "\\");
1202 /*******************************************************************
1203 reduce a file name, removing .. elements.
1204 ********************************************************************/
1205 void unix_clean_name(char *s
)
1209 DEBUG(3,("unix_clean_name [%s]\n",s
));
1211 /* remove any double slashes */
1212 string_sub(s
, "//","/");
1214 /* Remove leading ./ characters */
1215 if(strncmp(s
, "./", 2) == 0) {
1216 trim_string(s
, "./", NULL
);
1221 while ((p
= strstr(s
,"/../")) != NULL
)
1228 if ((p
=strrchr(s
,'/')) != NULL
)
1235 trim_string(s
,NULL
,"/..");
1239 /*******************************************************************
1240 a wrapper for the normal chdir() function
1241 ********************************************************************/
1242 int ChDir(char *path
)
1245 static pstring LastDir
="";
1247 if (strcsequal(path
,".")) return(0);
1249 if (*path
== '/' && strcsequal(LastDir
,path
)) return(0);
1250 DEBUG(3,("chdir to %s\n",path
));
1251 res
= sys_chdir(path
);
1253 strcpy(LastDir
,path
);
1258 /*******************************************************************
1259 return the absolute current directory path. A dumb version.
1260 ********************************************************************/
1261 static char *Dumb_GetWd(char *s
)
1264 return ((char *)getcwd(s
,sizeof(pstring
)));
1266 return ((char *)getwd(s
));
1271 /* number of list structures for a caching GetWd function. */
1272 #define MAX_GETWDCACHE (50)
1280 } ino_list
[MAX_GETWDCACHE
];
1282 BOOL use_getwd_cache
=True
;
1284 /*******************************************************************
1285 return the absolute current directory path
1286 ********************************************************************/
1287 char *GetWd(char *str
)
1290 static BOOL getwd_cache_init
= False
;
1291 struct stat st
, st2
;
1296 if (!use_getwd_cache
)
1297 return(Dumb_GetWd(str
));
1299 /* init the cache */
1300 if (!getwd_cache_init
)
1302 getwd_cache_init
= True
;
1303 for (i
=0;i
<MAX_GETWDCACHE
;i
++)
1305 string_init(&ino_list
[i
].text
,"");
1306 ino_list
[i
].valid
= False
;
1310 /* Get the inode of the current directory, if this doesn't work we're
1313 if (stat(".",&st
) == -1)
1315 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1316 return(Dumb_GetWd(str
));
1320 for (i
=0; i
<MAX_GETWDCACHE
; i
++)
1321 if (ino_list
[i
].valid
)
1324 /* If we have found an entry with a matching inode and dev number
1325 then find the inode number for the directory in the cached string.
1326 If this agrees with that returned by the stat for the current
1327 directory then all is o.k. (but make sure it is a directory all
1330 if (st
.st_ino
== ino_list
[i
].inode
&&
1331 st
.st_dev
== ino_list
[i
].dev
)
1333 if (stat(ino_list
[i
].text
,&st2
) == 0)
1335 if (st
.st_ino
== st2
.st_ino
&&
1336 st
.st_dev
== st2
.st_dev
&&
1337 (st2
.st_mode
& S_IFMT
) == S_IFDIR
)
1339 strcpy (str
, ino_list
[i
].text
);
1341 /* promote it for future use */
1342 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1347 /* If the inode is different then something's changed,
1348 scrub the entry and start from scratch. */
1349 ino_list
[i
].valid
= False
;
1356 /* We don't have the information to hand so rely on traditional methods.
1357 The very slow getcwd, which spawns a process on some systems, or the
1358 not quite so bad getwd. */
1362 DEBUG(0,("Getwd failed, errno %d\n",errno
));
1368 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s
,(int)st
.st_ino
,(int)st
.st_dev
));
1370 /* add it to the cache */
1371 i
= MAX_GETWDCACHE
- 1;
1372 string_set(&ino_list
[i
].text
,s
);
1373 ino_list
[i
].dev
= st
.st_dev
;
1374 ino_list
[i
].inode
= st
.st_ino
;
1375 ino_list
[i
].valid
= True
;
1377 /* put it at the top of the list */
1378 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1385 /*******************************************************************
1386 reduce a file name, removing .. elements and checking that
1387 it is below dir in the heirachy. This uses GetWd() and so must be run
1388 on the system that has the referenced file system.
1390 widelinks are allowed if widelinks is true
1391 ********************************************************************/
1392 BOOL
reduce_name(char *s
,char *dir
,BOOL widelinks
)
1394 #ifndef REDUCE_PATHS
1402 BOOL relative
= (*s
!= '/');
1404 *dir2
= *wd
= *basename
= *newname
= 0;
1409 /* can't have a leading .. */
1410 if (strncmp(s
,"..",2) == 0 && (s
[2]==0 || s
[2]=='/'))
1412 DEBUG(3,("Illegal file name? (%s)\n",s
));
1422 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1424 /* remove any double slashes */
1425 string_sub(s
,"//","/");
1428 p
= strrchr(basename
,'/');
1435 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1439 if (ChDir(dir
) != 0)
1441 DEBUG(0,("couldn't chdir to %s\n",dir
));
1447 DEBUG(0,("couldn't getwd for %s\n",dir
));
1453 if (p
&& (p
!= basename
))
1456 if (strcmp(p
+1,".")==0)
1458 if (strcmp(p
+1,"..")==0)
1462 if (ChDir(basename
) != 0)
1465 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,basename
));
1469 if (!GetWd(newname
))
1472 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1476 if (p
&& (p
!= basename
))
1478 strcat(newname
,"/");
1479 strcat(newname
,p
+1);
1483 int l
= strlen(dir2
);
1484 if (dir2
[l
-1] == '/')
1487 if (strncmp(newname
,dir2
,l
) != 0)
1490 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1496 if (newname
[l
] == '/')
1497 strcpy(s
,newname
+ l
+ 1);
1499 strcpy(s
,newname
+l
);
1510 DEBUG(3,("reduced to %s\n",s
));
1515 /****************************************************************************
1517 ****************************************************************************/
1518 static void expand_one(char *Mask
,int len
)
1521 while ((p1
= strchr(Mask
,'*')) != NULL
)
1523 int lfill
= (len
+1) - strlen(Mask
);
1524 int l1
= (p1
- Mask
);
1527 memset(tmp
+l1
,'?',lfill
);
1528 strcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1533 /****************************************************************************
1534 expand a wildcard expression, replacing *s with ?s
1535 ****************************************************************************/
1536 void expand_mask(char *Mask
,BOOL doext
)
1541 BOOL hasdot
= False
;
1543 BOOL absolute
= (*Mask
== '\\');
1545 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
1547 /* parse the directory and filename */
1548 if (strchr(Mask
,'\\'))
1549 dirname_dos(Mask
,dirpart
);
1551 filename_dos(Mask
,filepart
);
1553 strcpy(mbeg
,filepart
);
1554 if ((p1
= strchr(mbeg
,'.')) != NULL
)
1564 if (strlen(mbeg
) > 8)
1566 strcpy(mext
,mbeg
+ 8);
1572 strcpy(mbeg
,"????????");
1573 if ((*mext
== 0) && doext
&& !hasdot
)
1576 if (strequal(mbeg
,"*") && *mext
==0)
1584 strcpy(Mask
,dirpart
);
1585 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
1590 DEBUG(6,("Mask expanded to [%s]\n",Mask
));
1594 /****************************************************************************
1595 does a string have any uppercase chars in it?
1596 ****************************************************************************/
1597 BOOL
strhasupper(char *s
)
1602 if (is_shift_jis (*s
)) {
1604 } else if (is_kana (*s
)) {
1607 if (isupper(*s
)) return(True
);
1611 if (isupper(*s
)) return(True
);
1618 /****************************************************************************
1619 does a string have any lowercase chars in it?
1620 ****************************************************************************/
1621 BOOL
strhaslower(char *s
)
1626 if (is_shift_jis (*s
)) {
1628 } else if (is_kana (*s
)) {
1631 if (islower(*s
)) return(True
);
1635 if (islower(*s
)) return(True
);
1642 /****************************************************************************
1643 find the number of chars in a string
1644 ****************************************************************************/
1645 int count_chars(char *s
,char c
)
1658 /****************************************************************************
1660 ****************************************************************************/
1661 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1668 if ((mode
& aDIR
) != 0)
1671 memset(buf
+1,' ',11);
1672 if ((p
= strchr(mask2
,'.')) != NULL
)
1675 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1676 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
1680 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),11));
1682 bzero(buf
+21,DIR_STRUCT_SIZE
-21);
1683 CVAL(buf
,21) = mode
;
1684 put_dos_date(buf
,22,date
);
1685 SSVAL(buf
,26,size
& 0xFFFF);
1686 SSVAL(buf
,28,size
>> 16);
1687 StrnCpy(buf
+30,fname
,12);
1688 if (!case_sensitive
)
1690 DEBUG(8,("put name [%s] into dir struct\n",buf
+30));
1694 /*******************************************************************
1695 close the low 3 fd's and open dev/null in their place
1696 ********************************************************************/
1697 void close_low_fds(void)
1701 close(0); close(1); close(2);
1702 /* try and use up these file descriptors, so silly
1703 library routines writing to stdout etc won't cause havoc */
1705 fd
= open("/dev/null",O_RDWR
,0);
1706 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
1708 DEBUG(0,("Can't open /dev/null\n"));
1712 DEBUG(0,("Didn't get file descriptor %d\n",i
));
1718 /****************************************************************************
1719 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1721 if SYSV use O_NDELAY
1723 ****************************************************************************/
1724 int set_blocking(int fd
, BOOL set
)
1728 #define FLAG_TO_SET O_NONBLOCK
1731 #define FLAG_TO_SET O_NDELAY
1733 #define FLAG_TO_SET FNDELAY
1737 if((val
= fcntl(fd
, F_GETFL
, 0)) == -1)
1739 if(set
) /* Turn blocking on - ie. clear nonblock flag */
1740 val
&= ~FLAG_TO_SET
;
1743 return fcntl( fd
, F_SETFL
, val
);
1748 /****************************************************************************
1750 ****************************************************************************/
1751 int write_socket(int fd
,char *buf
,int len
)
1757 DEBUG(6,("write_socket(%d,%d)\n",fd
,len
));
1758 ret
= write_data(fd
,buf
,len
);
1760 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,len
,ret
));
1764 /****************************************************************************
1766 ****************************************************************************/
1767 int read_udp_socket(int fd
,char *buf
,int len
)
1770 struct sockaddr sock
;
1773 socklen
= sizeof(sock
);
1774 bzero((char *)&sock
,socklen
);
1775 bzero((char *)&lastip
,sizeof(lastip
));
1776 ret
= recvfrom(fd
,buf
,len
,0,&sock
,&socklen
);
1778 DEBUG(2,("read socket failed. ERRNO=%d\n",errno
));
1782 lastip
= *(struct in_addr
*) &sock
.sa_data
[2];
1783 lastport
= ntohs(((struct sockaddr_in
*)&sock
)->sin_port
);
1788 /****************************************************************************
1789 read data from a device with a timout in msec.
1790 mincount = if timeout, minimum to read before returning
1791 maxcount = number to be read.
1792 ****************************************************************************/
1793 int read_with_timeout(int fd
,char *buf
,int mincnt
,int maxcnt
,long time_out
)
1799 struct timeval timeout
;
1801 /* just checking .... */
1802 if (maxcnt
<= 0) return(0);
1807 if (time_out
<= 0) {
1808 if (mincnt
== 0) mincnt
= maxcnt
;
1810 while (nread
< mincnt
) {
1811 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
1813 smb_read_error
= READ_EOF
;
1817 if (readret
== -1) {
1818 smb_read_error
= READ_ERROR
;
1826 /* Most difficult - timeout read */
1827 /* If this is ever called on a disk file and
1828 mincnt is greater then the filesize then
1829 system performance will suffer severely as
1830 select always return true on disk files */
1832 /* Set initial timeout */
1833 timeout
.tv_sec
= time_out
/ 1000;
1834 timeout
.tv_usec
= 1000 * (time_out
% 1000);
1836 for (nread
=0; nread
<mincnt
; )
1841 selrtn
= sys_select(&fds
,&timeout
);
1843 /* Check if error */
1845 /* something is wrong. Maybe the socket is dead? */
1846 smb_read_error
= READ_ERROR
;
1850 /* Did we timeout ? */
1852 smb_read_error
= READ_TIMEOUT
;
1856 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
1858 /* we got EOF on the file descriptor */
1859 smb_read_error
= READ_EOF
;
1863 if (readret
== -1) {
1864 /* the descriptor is probably dead */
1865 smb_read_error
= READ_ERROR
;
1872 /* Return the number we got */
1876 /****************************************************************************
1877 read data from the client. Maxtime is in milliseconds
1878 ****************************************************************************/
1879 int read_max_udp(int fd
,char *buffer
,int bufsize
,int maxtime
)
1884 struct timeval timeout
;
1889 timeout
.tv_sec
= maxtime
/ 1000;
1890 timeout
.tv_usec
= (maxtime
% 1000) * 1000;
1892 selrtn
= sys_select(&fds
,maxtime
>0?&timeout
:NULL
);
1894 if (!FD_ISSET(fd
,&fds
))
1897 nread
= read_udp_socket(fd
, buffer
, bufsize
);
1899 /* return the number got */
1903 /*******************************************************************
1904 find the difference in milliseconds between two struct timeval
1906 ********************************************************************/
1907 int TvalDiff(struct timeval
*tvalold
,struct timeval
*tvalnew
)
1909 return((tvalnew
->tv_sec
- tvalold
->tv_sec
)*1000 +
1910 ((int)tvalnew
->tv_usec
- (int)tvalold
->tv_usec
)/1000);
1913 /****************************************************************************
1914 send a keepalive packet (rfc1002)
1915 ****************************************************************************/
1916 BOOL
send_keepalive(int client
)
1918 unsigned char buf
[4];
1921 buf
[1] = buf
[2] = buf
[3] = 0;
1923 return(write_data(client
,(char *)buf
,4) == 4);
1928 /****************************************************************************
1929 read data from the client, reading exactly N bytes.
1930 ****************************************************************************/
1931 int read_data(int fd
,char *buffer
,int N
)
1940 ret
= read(fd
,buffer
+ total
,N
- total
);
1942 smb_read_error
= READ_EOF
;
1946 smb_read_error
= READ_ERROR
;
1955 /****************************************************************************
1957 ****************************************************************************/
1958 int write_data(int fd
,char *buffer
,int N
)
1965 ret
= write(fd
,buffer
+ total
,N
- total
);
1967 if (ret
== -1) return -1;
1968 if (ret
== 0) return total
;
1976 /****************************************************************************
1977 transfer some data between two fd's
1978 ****************************************************************************/
1979 int transfer_file(int infd
,int outfd
,int n
,char *header
,int headlen
,int align
)
1981 static char *buf
=NULL
;
1986 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
1989 size
= lp_readsize();
1990 size
= MAX(size
,1024);
1993 while (!buf
&& size
>0) {
1994 buf
= (char *)Realloc(buf
,size
+8);
1995 if (!buf
) size
/= 2;
1999 DEBUG(0,("Can't allocate transfer buffer!\n"));
2003 abuf
= buf
+ (align
%8);
2010 int s
= MIN(n
,size
);
2015 if (header
&& (headlen
>= MIN(s
,1024))) {
2025 if (header
&& headlen
> 0)
2027 ret
= MIN(headlen
,size
);
2028 memcpy(buf1
,header
,ret
);
2031 if (headlen
<= 0) header
= NULL
;
2035 ret
+= read(infd
,buf1
+ret
,s
-ret
);
2039 ret2
= (outfd
>=0?write_data(outfd
,buf1
,ret
):ret
);
2040 if (ret2
> 0) total
+= ret2
;
2041 /* if we can't write then dump excess data */
2043 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
2045 if (ret
<= 0 || ret2
!= ret
)
2053 /****************************************************************************
2054 read 4 bytes of a smb packet and return the smb length of the packet
2055 possibly store the result in the buffer
2056 ****************************************************************************/
2057 int read_smb_length(int fd
,char *inbuf
,int timeout
)
2061 int len
=0, msg_type
;
2072 ok
= (read_with_timeout(fd
,buffer
,4,4,timeout
) == 4);
2074 ok
= (read_data(fd
,buffer
,4) == 4);
2079 len
= smb_len(buffer
);
2080 msg_type
= CVAL(buffer
,0);
2082 if (msg_type
== 0x85)
2084 DEBUG(5,("Got keepalive packet\n"));
2089 DEBUG(10,("got smb length of %d\n",len
));
2096 /****************************************************************************
2097 read an smb from a fd and return it's length
2098 The timeout is in milli seconds
2099 ****************************************************************************/
2100 BOOL
receive_smb(int fd
,char *buffer
,int timeout
)
2106 bzero(buffer
,smb_size
+ 100);
2108 len
= read_smb_length(fd
,buffer
,timeout
);
2112 if (len
> BUFFER_SIZE
) {
2113 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2114 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2118 ret
= read_data(fd
,buffer
+4,len
);
2120 smb_read_error
= READ_ERROR
;
2128 /****************************************************************************
2130 ****************************************************************************/
2131 BOOL
send_smb(int fd
,char *buffer
)
2135 len
= smb_len(buffer
) + 4;
2137 while (nwritten
< len
)
2139 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2142 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
2154 /****************************************************************************
2155 find a pointer to a netbios name
2156 ****************************************************************************/
2157 char *name_ptr(char *buf
,int ofs
)
2159 unsigned char c
= *(unsigned char *)(buf
+ofs
);
2161 if ((c
& 0xC0) == 0xC0)
2165 memcpy(p
,buf
+ofs
,2);
2168 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
2175 /****************************************************************************
2176 extract a netbios name from a buf
2177 ****************************************************************************/
2178 int name_extract(char *buf
,int ofs
,char *name
)
2180 char *p
= name_ptr(buf
,ofs
);
2181 int d
= PTR_DIFF(p
,buf
+ofs
);
2183 if (d
< -50 || d
> 50) return(0);
2184 return(name_interpret(p
,name
));
2188 /****************************************************************************
2189 return the total storage length of a mangled name
2190 ****************************************************************************/
2191 int name_len(char *s
)
2194 unsigned char c
= *(unsigned char *)s
;
2195 if ((c
& 0xC0) == 0xC0)
2197 while (*s
) s
+= (*s
)+1;
2198 return(PTR_DIFF(s
,s0
)+1);
2201 /****************************************************************************
2202 send a single packet to a port on another machine
2203 ****************************************************************************/
2204 BOOL
send_one_packet(char *buf
,int len
,struct in_addr ip
,int port
,int type
)
2208 struct sockaddr_in sock_out
;
2213 /* create a socket to write to */
2214 out_fd
= socket(AF_INET
, type
, 0);
2217 DEBUG(0,("socket failed"));
2221 /* set the address and port */
2222 bzero((char *)&sock_out
,sizeof(sock_out
));
2223 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
2224 sock_out
.sin_port
= htons( port
);
2225 sock_out
.sin_family
= AF_INET
;
2228 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2229 len
,inet_ntoa(ip
),port
,type
==SOCK_DGRAM
?"DGRAM":"STREAM"));
2232 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2235 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2236 inet_ntoa(ip
),port
,errno
));
2242 /*******************************************************************
2243 sleep for a specified number of milliseconds
2244 ********************************************************************/
2248 struct timeval tval
,t1
,t2
;
2255 tval
.tv_sec
= (t
-tdiff
)/1000;
2256 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2260 sys_select(&fds
,&tval
);
2263 tdiff
= TvalDiff(&t1
,&t2
);
2267 /****************************************************************************
2268 check if a string is part of a list
2269 ****************************************************************************/
2270 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
2275 if (!list
) return(False
);
2277 while (next_token(&p
,tok
,LIST_SEP
))
2279 if (casesensitive
) {
2280 if (strcmp(tok
,s
) == 0)
2283 if (StrCaseCmp(tok
,s
) == 0)
2290 /* this is used to prevent lots of mallocs of size 1 */
2291 static char *null_string
= NULL
;
2293 /****************************************************************************
2294 set a string value, allocing the space for the string
2295 ****************************************************************************/
2296 BOOL
string_init(char **dest
,char *src
)
2307 null_string
= (char *)malloc(1);
2310 *dest
= null_string
;
2314 *dest
= (char *)malloc(l
+1);
2320 /****************************************************************************
2322 ****************************************************************************/
2323 void string_free(char **s
)
2325 if (!s
|| !(*s
)) return;
2326 if (*s
== null_string
)
2332 /****************************************************************************
2333 set a string value, allocing the space for the string, and deallocating any
2335 ****************************************************************************/
2336 BOOL
string_set(char **dest
,char *src
)
2340 return(string_init(dest
,src
));
2343 /****************************************************************************
2344 substitute a string for a pattern in another string. Make sure there is
2347 This routine looks for pattern in s and replaces it with
2348 insert. It may do multiple replacements.
2350 return True if a substitution was done.
2351 ****************************************************************************/
2352 BOOL
string_sub(char *s
,char *pattern
,char *insert
)
2358 if (!insert
|| !pattern
|| !s
) return(False
);
2361 lp
= strlen(pattern
);
2362 li
= strlen(insert
);
2364 if (!*pattern
) return(False
);
2366 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2369 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2370 memcpy(p
,insert
,li
);
2379 /*********************************************************
2380 * Recursive routine that is called by mask_match.
2381 * Does the actual matching.
2382 *********************************************************/
2383 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
2387 for( p
= regexp
; *p
&& *str
; ) {
2394 /* Look for a character matching
2395 the one after the '*' */
2398 return True
; /* Automatic match */
2400 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2402 if(do_match(str
,p
,case_sig
))
2416 if(toupper(*str
) != toupper(*p
))
2426 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2429 if (!*str
&& *p
== '?')
2431 while (*p
== '?') p
++;
2435 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2441 /*********************************************************
2442 * Routine to match a given string with a regexp - uses
2443 * simplified regexp that takes * and ? only. Case can be
2444 * significant or not.
2445 *********************************************************/
2446 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
2450 fstring ebase
,eext
,sbase
,sext
;
2454 /* Make local copies of str and regexp */
2455 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
2456 StrnCpy(p2
,str
,sizeof(pstring
)-1);
2458 if (!strchr(p2
,'.')) {
2463 if (!strchr(p1,'.')) {
2471 string_sub(p1
,"*.*","*");
2472 string_sub(p1
,".*","*");
2476 /* Remove any *? and ** as they are meaningless */
2477 for(p
= p1
; *p
; p
++)
2478 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
2479 (void)strcpy( &p
[1], &p
[2]);
2481 if (strequal(p1
,"*")) return(True
);
2483 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
2489 if ((p
=strrchr(p1
,'.'))) {
2498 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
2508 matched
= do_match(sbase
,ebase
,case_sig
) &&
2509 (trans2
|| do_match(sext
,eext
,case_sig
));
2511 DEBUG(5,("mask_match returning %d\n", matched
));
2518 /****************************************************************************
2519 become a daemon, discarding the controlling terminal
2520 ****************************************************************************/
2521 void become_daemon(void)
2523 #ifndef NO_FORK_DEBUG
2527 /* detach from the terminal */
2530 #else /* USE_SETSID */
2533 int i
= open("/dev/tty", O_RDWR
);
2536 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
2540 #endif /* TIOCNOTTY */
2541 #endif /* USE_SETSID */
2542 /* Close fd's 0,1,2. Needed if started by rsh */
2544 #endif /* NO_FORK_DEBUG */
2548 /****************************************************************************
2549 put up a yes/no prompt
2550 ****************************************************************************/
2556 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
2559 if (*ans
== 'y' || *ans
== 'Y')
2565 /****************************************************************************
2566 read a line from a file with possible \ continuation chars.
2567 Blanks at the start or end of a line are stripped.
2568 The string will be allocated if s2 is NULL
2569 ****************************************************************************/
2570 char *fgets_slash(char *s2
,int maxlen
,FILE *f
)
2575 BOOL start_of_line
= True
;
2582 maxlen
= MIN(maxlen
,8);
2583 s
= (char *)Realloc(s
,maxlen
);
2586 if (!s
|| maxlen
< 2) return(NULL
);
2590 while (len
< maxlen
-1)
2598 while (len
> 0 && s
[len
-1] == ' ')
2602 if (len
> 0 && s
[len
-1] == '\\')
2605 start_of_line
= True
;
2610 if (len
<= 0 && !s2
)
2612 return(len
>0?s
:NULL
);
2617 start_of_line
= False
;
2621 if (!s2
&& len
> maxlen
-3)
2624 s
= (char *)Realloc(s
,maxlen
);
2625 if (!s
) return(NULL
);
2633 /****************************************************************************
2634 set the length of a file from a filedescriptor.
2635 Returns 0 on success, -1 on failure.
2636 ****************************************************************************/
2637 int set_filelen(int fd
, long len
)
2639 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2640 extend a file with ftruncate. Provide alternate implementation
2643 #if FTRUNCATE_CAN_EXTEND
2644 return ftruncate(fd
, len
);
2648 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
2652 /* Do an fstat to see if the file is longer than
2653 the requested size (call ftruncate),
2654 or shorter, in which case seek to len - 1 and write 1
2656 if(fstat(fd
, &st
)<0)
2660 if (S_ISFIFO(st
.st_mode
)) return 0;
2663 if(st
.st_size
== len
)
2665 if(st
.st_size
> len
)
2666 return ftruncate(fd
, len
);
2668 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
2670 if(write(fd
, &c
, 1)!=1)
2672 /* Seek to where we were */
2673 lseek(fd
, currpos
, SEEK_SET
);
2679 /****************************************************************************
2680 return the byte checksum of some data
2681 ****************************************************************************/
2682 int byte_checksum(char *buf
,int len
)
2684 unsigned char *p
= (unsigned char *)buf
;
2694 /****************************************************************************
2695 this is a version of setbuffer() for those machines that only have setvbuf
2696 ****************************************************************************/
2697 void setbuffer(FILE *f
,char *buf
,int bufsize
)
2699 setvbuf(f
,buf
,_IOFBF
,bufsize
);
2704 /****************************************************************************
2705 parse out a directory name from a path name. Assumes dos style filenames.
2706 ****************************************************************************/
2707 char *dirname_dos(char *path
,char *buf
)
2709 char *p
= strrchr(path
,'\\');
2724 /****************************************************************************
2725 parse out a filename from a path name. Assumes dos style filenames.
2726 ****************************************************************************/
2727 static char *filename_dos(char *path
,char *buf
)
2729 char *p
= strrchr(path
,'\\');
2741 /****************************************************************************
2742 expand a pointer to be a particular size
2743 ****************************************************************************/
2744 void *Realloc(void *p
,int size
)
2750 DEBUG(5,("Realloc asked for 0 bytes\n"));
2755 ret
= (void *)malloc(size
);
2757 ret
= (void *)realloc(p
,size
);
2760 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
2766 /****************************************************************************
2768 ****************************************************************************/
2769 char *strdup(char *s
)
2772 if (!s
) return(NULL
);
2773 ret
= (char *)malloc(strlen(s
)+1);
2774 if (!ret
) return(NULL
);
2781 /****************************************************************************
2782 Signal handler for SIGPIPE (write on a disconnected socket)
2783 ****************************************************************************/
2786 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2790 /****************************************************************************
2791 get my own name and IP
2792 ****************************************************************************/
2793 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
2800 /* get my host name */
2801 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
2803 DEBUG(0,("gethostname failed\n"));
2808 if ((hp
= Get_Hostbyname(hostname
)) == 0)
2810 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
2816 /* split off any parts after an initial . */
2817 char *p
= strchr(hostname
,'.');
2820 strcpy(my_name
,hostname
);
2824 putip((char *)ip
,(char *)hp
->h_addr
);
2830 /****************************************************************************
2831 true if two IP addresses are equal
2832 ****************************************************************************/
2833 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
2836 a1
= ntohl(ip1
.s_addr
);
2837 a2
= ntohl(ip2
.s_addr
);
2842 /****************************************************************************
2843 open a socket of the specified type, port and address for incoming data
2844 ****************************************************************************/
2845 int open_socket_in(int type
, int port
, int dlevel
,uint32 socket_addr
)
2848 struct sockaddr_in sock
;
2852 /* get my host name */
2853 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
2854 { DEBUG(0,("gethostname failed\n")); return -1; }
2857 if ((hp
= Get_Hostbyname(host_name
)) == 0)
2859 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
2863 bzero((char *)&sock
,sizeof(sock
));
2864 memcpy((char *)&sock
.sin_addr
,(char *)hp
->h_addr
, hp
->h_length
);
2865 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2866 sock
.sin_len
= sizeof(sock
);
2868 sock
.sin_port
= htons( port
);
2869 sock
.sin_family
= hp
->h_addrtype
;
2870 sock
.sin_addr
.s_addr
= socket_addr
;
2871 res
= socket(hp
->h_addrtype
, type
, 0);
2873 { DEBUG(0,("socket failed\n")); return -1; }
2877 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
2880 /* now we've got a socket - we need to bind it */
2881 if (bind(res
, (struct sockaddr
* ) &sock
,sizeof(sock
)) < 0)
2884 if (port
== SMB_PORT
|| port
== NMB_PORT
)
2885 DEBUG(dlevel
,("bind failed on port %d socket_addr=%x (%s)\n",
2886 port
,socket_addr
,strerror(errno
)));
2889 if (dlevel
> 0 && port
< 1000)
2892 if (port
>= 1000 && port
< 9000)
2893 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
2898 DEBUG(3,("bind succeeded on port %d\n",port
));
2904 /****************************************************************************
2905 create an outgoing socket
2906 **************************************************************************/
2907 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
2909 struct sockaddr_in sock_out
;
2911 int connect_loop
= 250; /* 250 milliseconds */
2912 int loops
= (timeout
* 1000) / connect_loop
;
2914 /* create a socket to write to */
2915 res
= socket(PF_INET
, type
, 0);
2917 { DEBUG(0,("socket error\n")); return -1; }
2919 if (type
!= SOCK_STREAM
) return(res
);
2921 bzero((char *)&sock_out
,sizeof(sock_out
));
2922 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
2924 sock_out
.sin_port
= htons( port
);
2925 sock_out
.sin_family
= PF_INET
;
2927 /* set it non-blocking */
2928 set_blocking(res
,False
);
2930 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
2932 /* and connect it to the destination */
2934 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
2936 /* Some systems return EAGAIN when they mean EINPROGRESS */
2937 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2938 errno
== EAGAIN
) && loops
--) {
2939 msleep(connect_loop
);
2943 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2945 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
2951 if (ret
< 0 && errno
== EISCONN
) {
2958 DEBUG(1,("error connecting to %s:%d (%s)\n",
2959 inet_ntoa(*addr
),port
,strerror(errno
)));
2963 /* set it blocking again */
2964 set_blocking(res
,True
);
2970 /****************************************************************************
2971 interpret a protocol description string, with a default
2972 ****************************************************************************/
2973 int interpret_protocol(char *str
,int def
)
2975 if (strequal(str
,"NT1"))
2976 return(PROTOCOL_NT1
);
2977 if (strequal(str
,"LANMAN2"))
2978 return(PROTOCOL_LANMAN2
);
2979 if (strequal(str
,"LANMAN1"))
2980 return(PROTOCOL_LANMAN1
);
2981 if (strequal(str
,"CORE"))
2982 return(PROTOCOL_CORE
);
2983 if (strequal(str
,"COREPLUS"))
2984 return(PROTOCOL_COREPLUS
);
2985 if (strequal(str
,"CORE+"))
2986 return(PROTOCOL_COREPLUS
);
2988 DEBUG(0,("Unrecognised protocol level %s\n",str
));
2993 /****************************************************************************
2994 interpret a security level
2995 ****************************************************************************/
2996 int interpret_security(char *str
,int def
)
2998 if (strequal(str
,"SERVER"))
3000 if (strequal(str
,"USER"))
3002 if (strequal(str
,"SHARE"))
3005 DEBUG(0,("Unrecognised security level %s\n",str
));
3011 /****************************************************************************
3012 interpret an internet address or name into an IP address in 4 byte form
3013 ****************************************************************************/
3014 uint32
interpret_addr(char *str
)
3019 BOOL pure_address
= True
;
3021 if (strcmp(str
,"0.0.0.0") == 0) return(0);
3022 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
3024 for (i
=0; pure_address
&& str
[i
]; i
++)
3025 if (!(isdigit(str
[i
]) || str
[i
] == '.'))
3026 pure_address
= False
;
3028 /* if it's in the form of an IP address then get the lib to interpret it */
3030 res
= inet_addr(str
);
3032 /* otherwise assume it's a network name of some sort and use
3034 if ((hp
= Get_Hostbyname(str
)) == 0) {
3035 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
3038 putip((char *)&res
,(char *)hp
->h_addr
);
3041 if (res
== (uint32
)-1) return(0);
3046 /*******************************************************************
3047 a convenient addition to interpret_addr()
3048 ******************************************************************/
3049 struct in_addr
*interpret_addr2(char *str
)
3051 static struct in_addr ret
;
3052 uint32 a
= interpret_addr(str
);
3057 /*******************************************************************
3058 check if an IP is the 0.0.0.0
3059 ******************************************************************/
3060 BOOL
zero_ip(struct in_addr ip
)
3063 putip((char *)&a
,(char *)&ip
);
3068 /*******************************************************************
3069 matchname - determine if host name matches IP address
3070 ******************************************************************/
3071 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
3076 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
3077 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost
));
3082 * Make sure that gethostbyname() returns the "correct" host name.
3083 * Unfortunately, gethostbyname("localhost") sometimes yields
3084 * "localhost.domain". Since the latter host name comes from the
3085 * local DNS, we just have to trust it (all bets are off if the local
3086 * DNS is perverted). We always check the address list, though.
3089 if (strcasecmp(remotehost
, hp
->h_name
)
3090 && strcasecmp(remotehost
, "localhost")) {
3091 DEBUG(0,("host name/name mismatch: %s != %s",
3092 remotehost
, hp
->h_name
));
3096 /* Look up the host address in the address list we just got. */
3097 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
3098 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
3103 * The host name does not map to the original host address. Perhaps
3104 * someone has compromised a name server. More likely someone botched
3105 * it, but that could be dangerous, too.
3108 DEBUG(0,("host name/address mismatch: %s != %s",
3109 inet_ntoa(addr
), hp
->h_name
));
3113 /*******************************************************************
3114 Reset the 'done' variables so after a client process is created
3115 from a fork call these calls will be re-done. This should be
3116 expanded if more variables need reseting.
3117 ******************************************************************/
3119 static BOOL global_client_name_done
= False
;
3120 static BOOL global_client_addr_done
= False
;
3122 void reset_globals_after_fork()
3124 global_client_name_done
= False
;
3125 global_client_addr_done
= False
;
3128 /*******************************************************************
3129 return the DNS name of the client
3130 ******************************************************************/
3131 char *client_name(void)
3135 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3136 int length
= sizeof(sa
);
3137 static pstring name_buf
;
3140 if (global_client_name_done
)
3143 strcpy(name_buf
,"UNKNOWN");
3145 if (getpeername(Client
, &sa
, &length
) < 0) {
3146 DEBUG(0,("getpeername failed\n"));
3150 /* Look up the remote host name. */
3151 if ((hp
= gethostbyaddr((char *) &sockin
->sin_addr
,
3152 sizeof(sockin
->sin_addr
),
3154 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3155 StrnCpy(name_buf
,client_addr(),sizeof(name_buf
) - 1);
3157 StrnCpy(name_buf
,(char *)hp
->h_name
,sizeof(name_buf
) - 1);
3158 if (!matchname(name_buf
, sockin
->sin_addr
)) {
3159 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,client_addr()));
3160 strcpy(name_buf
,"UNKNOWN");
3163 global_client_name_done
= True
;
3167 /*******************************************************************
3168 return the IP addr of the client as a string
3169 ******************************************************************/
3170 char *client_addr(void)
3174 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3175 int length
= sizeof(sa
);
3176 static fstring addr_buf
;
3178 if (global_client_addr_done
)
3181 strcpy(addr_buf
,"0.0.0.0");
3183 if (getpeername(Client
, &sa
, &length
) < 0) {
3184 DEBUG(0,("getpeername failed\n"));
3188 strcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
3190 global_client_addr_done
= True
;
3194 /*******************************************************************
3195 sub strings with useful parameters
3196 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3197 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3198 ********************************************************************/
3199 void standard_sub_basic(char *string
)
3203 struct passwd
*pass
;
3205 for (s
= string
; (p
= strchr(s
,'%')) != NULL
; s
= p
)
3209 case 'G' : if ((pass
= Get_Pwnam(sesssetup_user
,False
))!=NULL
)
3210 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
3214 case 'I' : string_sub(p
,"%I",client_addr()); break;
3215 case 'L' : string_sub(p
,"%L",local_machine
); break;
3216 case 'M' : string_sub(p
,"%M",client_name()); break;
3217 case 'R' : string_sub(p
,"%R",remote_proto
); break;
3218 case 'T' : string_sub(p
,"%T",timestring()); break;
3219 case 'U' : string_sub(p
,"%U",sesssetup_user
); break;
3220 case 'a' : string_sub(p
,"%a",remote_arch
); break;
3221 case 'd' : sprintf(pidstr
,"%d",(int)getpid());
3222 string_sub(p
,"%d",pidstr
);
3224 case 'h' : string_sub(p
,"%h",myhostname
); break;
3225 case 'm' : string_sub(p
,"%m",remote_machine
); break;
3226 case 'v' : string_sub(p
,"%v",VERSION
); break;
3227 case '\0' : p
++; break; /* don't run off end if last character is % */
3228 default : p
+=2; break;
3234 /*******************************************************************
3235 are two IPs on the same subnet?
3236 ********************************************************************/
3237 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
3239 uint32 net1
,net2
,nmask
;
3241 nmask
= ntohl(mask
.s_addr
);
3242 net1
= ntohl(ip1
.s_addr
);
3243 net2
= ntohl(ip2
.s_addr
);
3245 return((net1
& nmask
) == (net2
& nmask
));
3249 /*******************************************************************
3250 write a string in unicoode format
3251 ********************************************************************/
3252 int PutUniCode(char *dst
,char *src
)
3256 dst
[ret
++] = src
[0];
3265 /****************************************************************************
3266 a wrapper for gethostbyname() that tries with all lower and all upper case
3267 if the initial name fails
3268 ****************************************************************************/
3269 struct hostent
*Get_Hostbyname(char *name
)
3271 char *name2
= strdup(name
);
3272 struct hostent
*ret
;
3276 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3280 if (!isalnum(*name2
))
3286 ret
= sys_gethostbyname(name2
);
3293 /* try with all lowercase */
3295 ret
= sys_gethostbyname(name2
);
3302 /* try with all uppercase */
3304 ret
= sys_gethostbyname(name2
);
3311 /* nothing works :-( */
3317 /****************************************************************************
3318 check if a process exists. Does this work on all unixes?
3319 ****************************************************************************/
3320 BOOL
process_exists(int pid
)
3324 sprintf(s
,"/proc/%d",pid
);
3325 return(directory_exist(s
,NULL
));
3328 static BOOL tested
=False
;
3329 static BOOL ok
=False
;
3333 sprintf(s
,"/proc/%05d",(int)getpid());
3334 ok
= file_exist(s
,NULL
);
3337 sprintf(s
,"/proc/%05d",pid
);
3338 return(file_exist(s
,NULL
));
3342 /* CGH 8/16/96 - added ESRCH test */
3343 return(pid
== getpid() || kill(pid
,0) == 0 || errno
!= ESRCH
);
3348 /*******************************************************************
3349 turn a uid into a user name
3350 ********************************************************************/
3351 char *uidtoname(int uid
)
3353 static char name
[40];
3354 struct passwd
*pass
= getpwuid(uid
);
3355 if (pass
) return(pass
->pw_name
);
3356 sprintf(name
,"%d",uid
);
3360 /*******************************************************************
3361 turn a gid into a group name
3362 ********************************************************************/
3363 char *gidtoname(int gid
)
3365 static char name
[40];
3366 struct group
*grp
= getgrgid(gid
);
3367 if (grp
) return(grp
->gr_name
);
3368 sprintf(name
,"%d",gid
);
3372 /*******************************************************************
3374 ********************************************************************/
3375 void BlockSignals(BOOL block
,int signum
)
3378 int block_mask
= sigmask(signum
);
3379 static int oldmask
= 0;
3381 oldmask
= sigblock(block_mask
);
3383 sigsetmask(oldmask
);
3384 #elif defined(USE_SIGPROCMASK)
3387 sigaddset(&set
,signum
);
3388 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
3393 /*******************************************************************
3394 my own panic function - not suitable for general use
3395 ********************************************************************/
3396 void ajt_panic(void)
3398 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3403 #define DIRECT direct
3405 #define DIRECT dirent
3408 /*******************************************************************
3409 a readdir wrapper which just returns the file name
3410 also return the inode number if requested
3411 ********************************************************************/
3412 char *readdirname(void *p
)
3417 if (!p
) return(NULL
);
3419 ptr
= (struct DIRECT
*)readdir(p
);
3420 if (!ptr
) return(NULL
);
3422 dname
= ptr
->d_name
;
3425 if (telldir(p
) < 0) return(NULL
);
3429 /* this handles a broken compiler setup, causing a mixture
3430 of BSD and SYSV headers and libraries */
3432 static BOOL broken_readdir
= False
;
3433 if (!broken_readdir
&& !(*(dname
)) && strequal("..",dname
-2))
3435 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3436 broken_readdir
= True
;
3446 unix_to_dos(buf
, True
);
3454 * Utility function used to decide if the last component
3455 * of a path matches a (possibly wildcarded) entry in a namelist.
3458 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
3460 pstring last_component
;
3463 DEBUG(5, ("is_in_path: %s\n", name
));
3465 /* if we have no list it's obviously not in the path */
3466 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
3468 DEBUG(5,("is_in_path: no name list.\n"));
3472 /* Get the last component of the unix name. */
3473 p
= strrchr(name
, '/');
3474 strncpy(last_component
, p
? p
: name
, sizeof(last_component
)-1);
3475 last_component
[sizeof(last_component
)-1] = '\0';
3477 for(; namelist
->name
!= NULL
; namelist
++)
3479 if(namelist
->is_wild
)
3481 /* look for a wildcard match. */
3482 if (mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
3484 DEBUG(5,("is_in_path: mask match succeeded\n"));
3490 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
3491 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
3493 DEBUG(5,("is_in_path: match succeeded\n"));
3498 DEBUG(5,("is_in_path: match not found\n"));
3504 * Strip a '/' separated list into an array of
3505 * name_compare_enties structures suitable for
3506 * passing to is_in_path(). We do this for
3507 * speed so we can pre-parse all the names in the list
3508 * and don't do it for each call to is_in_path().
3509 * namelist is modified here and is assumed to be
3510 * a copy owned by the caller.
3511 * We also check if the entry contains a wildcard to
3512 * remove a potentially expensive call to mask_match
3516 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
3519 char *nameptr
= namelist
;
3520 int num_entries
= 0;
3523 (*ppname_array
) = NULL
;
3525 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
3528 /* We need to make two passes over the string. The
3529 first to count the number of elements, the second
3534 if ( *nameptr
== '/' )
3536 /* cope with multiple (useless) /s) */
3540 /* find the next / */
3541 name_end
= strchr(nameptr
, '/');
3543 /* oops - the last check for a / didn't find one. */
3544 if (name_end
== NULL
)
3547 /* next segment please */
3548 nameptr
= name_end
+ 1;
3552 if(num_entries
== 0)
3555 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
3556 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
3558 DEBUG(0,("set_namearray: malloc fail\n"));
3562 /* Now copy out the names */
3567 if ( *nameptr
== '/' )
3569 /* cope with multiple (useless) /s) */
3573 /* find the next / */
3574 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
3579 /* oops - the last check for a / didn't find one. */
3580 if (name_end
== NULL
)
3583 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
3584 (strchr( nameptr
, '*')!=NULL
));
3585 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
3587 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3591 /* next segment please */
3592 nameptr
= name_end
+ 1;
3596 (*ppname_array
)[i
].name
= NULL
;
3601 /****************************************************************************
3602 routine to free a namearray.
3603 ****************************************************************************/
3605 void free_namearray(name_compare_entry
*name_array
)
3610 if(name_array
->name
!= NULL
)
3611 free(name_array
->name
);
3613 free((char *)name_array
);
3616 /****************************************************************************
3617 routine to do file locking
3618 ****************************************************************************/
3619 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
3626 uint32 mask
= 0xC0000000;
3628 /* make sure the count is reasonable, we might kill the lockd otherwise */
3631 /* the offset is often strange - remove 2 of its bits if either of
3632 the top two bits are set. Shift the top ones by two bits. This
3633 still allows OLE2 apps to operate, but should stop lockd from
3635 if ((offset
& mask
) != 0)
3636 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
3638 uint32 mask
= ((unsigned)1<<31);
3640 /* interpret negative counts as large numbers */
3644 /* no negative offsets */
3647 /* count + offset must be in range */
3648 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
3656 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
3659 lock
.l_whence
= SEEK_SET
;
3660 lock
.l_start
= (int)offset
;
3661 lock
.l_len
= (int)count
;
3666 ret
= fcntl(fd
,op
,&lock
);
3669 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
3675 (lock
.l_type
!= F_UNLCK
) &&
3676 (lock
.l_pid
!= 0) &&
3677 (lock
.l_pid
!= getpid()))
3679 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
3683 /* it must be not locked or locked by me */
3687 /* a lock set or unset */
3690 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3691 offset
,count
,op
,type
,strerror(errno
)));
3693 /* perhaps it doesn't support this sort of locking?? */
3694 if (errno
== EINVAL
)
3696 DEBUG(3,("locking not supported? returning True\n"));
3703 /* everything went OK */
3704 DEBUG(5,("Lock call successful\n"));
3712 /*******************************************************************
3713 lock a file - returning a open file descriptor or -1 on failure
3714 The timeout is in seconds. 0 means no timeout
3715 ********************************************************************/
3716 int file_lock(char *name
,int timeout
)
3718 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
3720 if (fd
< 0) return(-1);
3723 if (timeout
) t
= time(NULL
);
3724 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
3725 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
3726 msleep(LOCK_RETRY_TIMEOUT
);
3734 /*******************************************************************
3735 unlock a file locked by file_lock
3736 ********************************************************************/
3737 void file_unlock(int fd
)
3741 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
3746 /*******************************************************************
3747 is the name specified one of my netbios names
3748 returns true is it is equal, false otherwise
3749 ********************************************************************/
3750 BOOL
is_myname(const char *s
)
3755 for (n
=0; my_netbios_names
[n
]; n
++) {
3756 if (strequal(my_netbios_names
[n
], s
))
3759 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));