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
)
762 if (sys_stat(dname
,st
) != 0)
765 ret
= S_ISDIR(st
->st_mode
);
771 /*******************************************************************
772 returns the size in bytes of the named file
773 ********************************************************************/
774 uint32
file_size(char *file_name
)
778 sys_stat(file_name
,&buf
);
782 /*******************************************************************
783 return a string representing an attribute for a file
784 ********************************************************************/
785 char *attrib_string(int mode
)
787 static char attrstr
[10];
791 if (mode
& aVOLID
) strcat(attrstr
,"V");
792 if (mode
& aDIR
) strcat(attrstr
,"D");
793 if (mode
& aARCH
) strcat(attrstr
,"A");
794 if (mode
& aHIDDEN
) strcat(attrstr
,"H");
795 if (mode
& aSYSTEM
) strcat(attrstr
,"S");
796 if (mode
& aRONLY
) strcat(attrstr
,"R");
802 /*******************************************************************
803 case insensitive string compararison
804 ********************************************************************/
805 int StrCaseCmp(const char *s
, const char *t
)
807 /* compare until we run out of string, either t or s, or find a difference */
808 /* We *must* use toupper rather than tolower here due to the
809 asynchronous upper to lower mapping.
811 while (*s
&& *t
&& toupper(*s
) == toupper(*t
))
816 return(toupper(*s
) - toupper(*t
));
819 /*******************************************************************
820 case insensitive string compararison, length limited
821 ********************************************************************/
822 int StrnCaseCmp(const char *s
, const char *t
, int n
)
824 /* compare until we run out of string, either t or s, or chars */
825 /* We *must* use toupper rather than tolower here due to the
826 asynchronous upper to lower mapping.
828 while (n
-- && *s
&& *t
&& toupper(*s
) == toupper(*t
))
833 /* not run out of chars - strings are different lengths */
834 if (n
) return(toupper(*s
) - toupper(*t
));
836 /* identical up to where we run out of chars, and strings are same length */
840 /*******************************************************************
842 ********************************************************************/
843 BOOL
strequal(const char *s1
, const char *s2
)
845 if (s1
== s2
) return(True
);
846 if (!s1
|| !s2
) return(False
);
848 return(StrCaseCmp(s1
,s2
)==0);
851 /*******************************************************************
852 compare 2 strings up to and including the nth char.
853 ******************************************************************/
854 BOOL
strnequal(const char *s1
,const char *s2
,int n
)
856 if (s1
== s2
) return(True
);
857 if (!s1
|| !s2
|| !n
) return(False
);
859 return(StrnCaseCmp(s1
,s2
,n
)==0);
862 /*******************************************************************
863 compare 2 strings (case sensitive)
864 ********************************************************************/
865 BOOL
strcsequal(char *s1
,char *s2
)
867 if (s1
== s2
) return(True
);
868 if (!s1
|| !s2
) return(False
);
870 return(strcmp(s1
,s2
)==0);
874 /*******************************************************************
875 convert a string to lower case
876 ********************************************************************/
877 void strlower(char *s
)
882 if (is_shift_jis (*s
)) {
884 } else if (is_kana (*s
)) {
899 /*******************************************************************
900 convert a string to upper case
901 ********************************************************************/
902 void strupper(char *s
)
907 if (is_shift_jis (*s
)) {
909 } else if (is_kana (*s
)) {
924 /*******************************************************************
925 convert a string to "normal" form
926 ********************************************************************/
927 void strnorm(char *s
)
929 if (case_default
== CASE_UPPER
)
935 /*******************************************************************
936 check if a string is in "normal" case
937 ********************************************************************/
938 BOOL
strisnormal(char *s
)
940 if (case_default
== CASE_UPPER
)
941 return(!strhaslower(s
));
943 return(!strhasupper(s
));
947 /****************************************************************************
949 ****************************************************************************/
950 void string_replace(char *s
,char oldc
,char newc
)
955 if (is_shift_jis (*s
)) {
957 } else if (is_kana (*s
)) {
972 /****************************************************************************
973 make a file into unix format
974 ****************************************************************************/
975 void unix_format(char *fname
)
978 string_replace(fname
,'\\','/');
982 strcpy(namecopy
,fname
);
984 strcat(fname
,namecopy
);
988 /****************************************************************************
989 make a file into dos format
990 ****************************************************************************/
991 void dos_format(char *fname
)
993 string_replace(fname
,'/','\\');
997 /*******************************************************************
998 show a smb message structure
999 ********************************************************************/
1000 void show_msg(char *buf
)
1008 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1010 (int)CVAL(buf
,smb_com
),
1011 (int)CVAL(buf
,smb_rcls
),
1012 (int)CVAL(buf
,smb_reh
),
1013 (int)SVAL(buf
,smb_err
),
1014 (int)CVAL(buf
,smb_flg
),
1015 (int)SVAL(buf
,smb_flg2
)));
1016 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1017 (int)SVAL(buf
,smb_tid
),
1018 (int)SVAL(buf
,smb_pid
),
1019 (int)SVAL(buf
,smb_uid
),
1020 (int)SVAL(buf
,smb_mid
),
1021 (int)CVAL(buf
,smb_wct
)));
1022 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
1023 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i
,
1024 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
1025 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
1026 DEBUG(5,("smb_bcc=%d\n",bcc
));
1027 if (DEBUGLEVEL
< 10)
1029 for (i
= 0; i
< MIN(bcc
, 256); i
+= 16)
1031 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1034 DEBUG(10,("%2X ",CVAL(smb_buf(buf
),i
+j
)));
1035 if (j
== 7) DEBUG(10, (" "));
1040 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1042 unsigned char c
= CVAL(smb_buf(buf
),i
+j
);
1043 if (c
< 32 || c
> 128) c
= '.';
1046 if (j
== 7) DEBUG(10, (" "));
1053 /*******************************************************************
1054 return the length of an smb packet
1055 ********************************************************************/
1056 int smb_len(char *buf
)
1058 return( PVAL(buf
,3) | (PVAL(buf
,2)<<8) | ((PVAL(buf
,1)&1)<<16) );
1061 /*******************************************************************
1062 set the length of an smb packet
1063 ********************************************************************/
1064 void _smb_setlen(char *buf
,int len
)
1067 buf
[1] = (len
&0x10000)>>16;
1068 buf
[2] = (len
&0xFF00)>>8;
1072 /*******************************************************************
1073 set the length and marker of an smb packet
1074 ********************************************************************/
1075 void smb_setlen(char *buf
,int len
)
1077 _smb_setlen(buf
,len
);
1085 /*******************************************************************
1086 setup the word count and byte count for a smb message
1087 ********************************************************************/
1088 int set_message(char *buf
,int num_words
,int num_bytes
,BOOL zero
)
1091 bzero(buf
+ smb_size
,num_words
*2 + num_bytes
);
1092 CVAL(buf
,smb_wct
) = num_words
;
1093 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1094 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1095 return (smb_size
+ num_words
*2 + num_bytes
);
1098 /*******************************************************************
1099 return the number of smb words
1100 ********************************************************************/
1101 int smb_numwords(char *buf
)
1103 return (CVAL(buf
,smb_wct
));
1106 /*******************************************************************
1107 return the size of the smb_buf region of a message
1108 ********************************************************************/
1109 int smb_buflen(char *buf
)
1111 return(SVAL(buf
,smb_vwv0
+ smb_numwords(buf
)*2));
1114 /*******************************************************************
1115 return a pointer to the smb_buf data area
1116 ********************************************************************/
1117 int smb_buf_ofs(char *buf
)
1119 return (smb_size
+ CVAL(buf
,smb_wct
)*2);
1122 /*******************************************************************
1123 return a pointer to the smb_buf data area
1124 ********************************************************************/
1125 char *smb_buf(char *buf
)
1127 return (buf
+ smb_buf_ofs(buf
));
1130 /*******************************************************************
1131 return the SMB offset into an SMB buffer
1132 ********************************************************************/
1133 int smb_offset(char *p
,char *buf
)
1135 return(PTR_DIFF(p
,buf
+4) + chain_size
);
1139 /*******************************************************************
1140 skip past some strings in a buffer
1141 ********************************************************************/
1142 char *skip_string(char *buf
,int n
)
1145 buf
+= strlen(buf
) + 1;
1149 /*******************************************************************
1150 trim the specified elements off the front and back of a string
1151 ********************************************************************/
1152 BOOL
trim_string(char *s
,char *front
,char *back
)
1155 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1161 if (!(*p
= p
[strlen(front
)]))
1166 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1167 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1170 s
[strlen(s
)-strlen(back
)] = 0;
1176 /*******************************************************************
1177 reduce a file name, removing .. elements.
1178 ********************************************************************/
1179 void dos_clean_name(char *s
)
1183 DEBUG(3,("dos_clean_name [%s]\n",s
));
1185 /* remove any double slashes */
1186 string_sub(s
, "\\\\", "\\");
1188 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1195 if ((p
=strrchr(s
,'\\')) != NULL
)
1202 trim_string(s
,NULL
,"\\..");
1204 string_sub(s
, "\\.\\", "\\");
1207 /*******************************************************************
1208 reduce a file name, removing .. elements.
1209 ********************************************************************/
1210 void unix_clean_name(char *s
)
1214 DEBUG(3,("unix_clean_name [%s]\n",s
));
1216 /* remove any double slashes */
1217 string_sub(s
, "//","/");
1219 /* Remove leading ./ characters */
1220 if(strncmp(s
, "./", 2) == 0) {
1221 trim_string(s
, "./", NULL
);
1226 while ((p
= strstr(s
,"/../")) != NULL
)
1233 if ((p
=strrchr(s
,'/')) != NULL
)
1240 trim_string(s
,NULL
,"/..");
1244 /*******************************************************************
1245 a wrapper for the normal chdir() function
1246 ********************************************************************/
1247 int ChDir(char *path
)
1250 static pstring LastDir
="";
1252 if (strcsequal(path
,".")) return(0);
1254 if (*path
== '/' && strcsequal(LastDir
,path
)) return(0);
1255 DEBUG(3,("chdir to %s\n",path
));
1256 res
= sys_chdir(path
);
1258 strcpy(LastDir
,path
);
1263 /*******************************************************************
1264 return the absolute current directory path. A dumb version.
1265 ********************************************************************/
1266 static char *Dumb_GetWd(char *s
)
1270 p
= (char *)getcwd(s
,sizeof(pstring
));
1272 p
= (char *)getwd(s
));
1277 /* Ensure we always return in dos format. */
1278 unix_to_dos(p
,True
);
1283 /* number of list structures for a caching GetWd function. */
1284 #define MAX_GETWDCACHE (50)
1292 } ino_list
[MAX_GETWDCACHE
];
1294 BOOL use_getwd_cache
=True
;
1296 /*******************************************************************
1297 return the absolute current directory path
1298 ********************************************************************/
1299 char *GetWd(char *str
)
1302 static BOOL getwd_cache_init
= False
;
1303 struct stat st
, st2
;
1308 if (!use_getwd_cache
)
1309 return(Dumb_GetWd(str
));
1311 /* init the cache */
1312 if (!getwd_cache_init
)
1314 getwd_cache_init
= True
;
1315 for (i
=0;i
<MAX_GETWDCACHE
;i
++)
1317 string_init(&ino_list
[i
].text
,"");
1318 ino_list
[i
].valid
= False
;
1322 /* Get the inode of the current directory, if this doesn't work we're
1325 if (stat(".",&st
) == -1)
1327 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1328 return(Dumb_GetWd(str
));
1332 for (i
=0; i
<MAX_GETWDCACHE
; i
++)
1333 if (ino_list
[i
].valid
)
1336 /* If we have found an entry with a matching inode and dev number
1337 then find the inode number for the directory in the cached string.
1338 If this agrees with that returned by the stat for the current
1339 directory then all is o.k. (but make sure it is a directory all
1342 if (st
.st_ino
== ino_list
[i
].inode
&&
1343 st
.st_dev
== ino_list
[i
].dev
)
1345 if (stat(ino_list
[i
].text
,&st2
) == 0)
1347 if (st
.st_ino
== st2
.st_ino
&&
1348 st
.st_dev
== st2
.st_dev
&&
1349 (st2
.st_mode
& S_IFMT
) == S_IFDIR
)
1351 strcpy (str
, ino_list
[i
].text
);
1353 /* promote it for future use */
1354 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1359 /* If the inode is different then something's changed,
1360 scrub the entry and start from scratch. */
1361 ino_list
[i
].valid
= False
;
1368 /* We don't have the information to hand so rely on traditional methods.
1369 The very slow getcwd, which spawns a process on some systems, or the
1370 not quite so bad getwd. */
1374 DEBUG(0,("Getwd failed, errno %d\n",errno
));
1380 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s
,(int)st
.st_ino
,(int)st
.st_dev
));
1382 /* add it to the cache */
1383 i
= MAX_GETWDCACHE
- 1;
1384 string_set(&ino_list
[i
].text
,s
);
1385 ino_list
[i
].dev
= st
.st_dev
;
1386 ino_list
[i
].inode
= st
.st_ino
;
1387 ino_list
[i
].valid
= True
;
1389 /* put it at the top of the list */
1390 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1397 /*******************************************************************
1398 reduce a file name, removing .. elements and checking that
1399 it is below dir in the heirachy. This uses GetWd() and so must be run
1400 on the system that has the referenced file system.
1402 widelinks are allowed if widelinks is true
1403 ********************************************************************/
1404 BOOL
reduce_name(char *s
,char *dir
,BOOL widelinks
)
1406 #ifndef REDUCE_PATHS
1414 BOOL relative
= (*s
!= '/');
1416 *dir2
= *wd
= *basename
= *newname
= 0;
1421 /* can't have a leading .. */
1422 if (strncmp(s
,"..",2) == 0 && (s
[2]==0 || s
[2]=='/'))
1424 DEBUG(3,("Illegal file name? (%s)\n",s
));
1434 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1436 /* remove any double slashes */
1437 string_sub(s
,"//","/");
1440 p
= strrchr(basename
,'/');
1447 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1451 if (ChDir(dir
) != 0)
1453 DEBUG(0,("couldn't chdir to %s\n",dir
));
1459 DEBUG(0,("couldn't getwd for %s\n",dir
));
1465 if (p
&& (p
!= basename
))
1468 if (strcmp(p
+1,".")==0)
1470 if (strcmp(p
+1,"..")==0)
1474 if (ChDir(basename
) != 0)
1477 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,basename
));
1481 if (!GetWd(newname
))
1484 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1488 if (p
&& (p
!= basename
))
1490 strcat(newname
,"/");
1491 strcat(newname
,p
+1);
1495 int l
= strlen(dir2
);
1496 if (dir2
[l
-1] == '/')
1499 if (strncmp(newname
,dir2
,l
) != 0)
1502 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1508 if (newname
[l
] == '/')
1509 strcpy(s
,newname
+ l
+ 1);
1511 strcpy(s
,newname
+l
);
1522 DEBUG(3,("reduced to %s\n",s
));
1527 /****************************************************************************
1529 ****************************************************************************/
1530 static void expand_one(char *Mask
,int len
)
1533 while ((p1
= strchr(Mask
,'*')) != NULL
)
1535 int lfill
= (len
+1) - strlen(Mask
);
1536 int l1
= (p1
- Mask
);
1539 memset(tmp
+l1
,'?',lfill
);
1540 strcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1545 /****************************************************************************
1546 expand a wildcard expression, replacing *s with ?s
1547 ****************************************************************************/
1548 void expand_mask(char *Mask
,BOOL doext
)
1553 BOOL hasdot
= False
;
1555 BOOL absolute
= (*Mask
== '\\');
1557 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
1559 /* parse the directory and filename */
1560 if (strchr(Mask
,'\\'))
1561 dirname_dos(Mask
,dirpart
);
1563 filename_dos(Mask
,filepart
);
1565 strcpy(mbeg
,filepart
);
1566 if ((p1
= strchr(mbeg
,'.')) != NULL
)
1576 if (strlen(mbeg
) > 8)
1578 strcpy(mext
,mbeg
+ 8);
1584 strcpy(mbeg
,"????????");
1585 if ((*mext
== 0) && doext
&& !hasdot
)
1588 if (strequal(mbeg
,"*") && *mext
==0)
1596 strcpy(Mask
,dirpart
);
1597 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
1602 DEBUG(6,("Mask expanded to [%s]\n",Mask
));
1606 /****************************************************************************
1607 does a string have any uppercase chars in it?
1608 ****************************************************************************/
1609 BOOL
strhasupper(char *s
)
1614 if (is_shift_jis (*s
)) {
1616 } else if (is_kana (*s
)) {
1619 if (isupper(*s
)) return(True
);
1623 if (isupper(*s
)) return(True
);
1630 /****************************************************************************
1631 does a string have any lowercase chars in it?
1632 ****************************************************************************/
1633 BOOL
strhaslower(char *s
)
1638 if (is_shift_jis (*s
)) {
1640 } else if (is_kana (*s
)) {
1643 if (islower(*s
)) return(True
);
1647 if (islower(*s
)) return(True
);
1654 /****************************************************************************
1655 find the number of chars in a string
1656 ****************************************************************************/
1657 int count_chars(char *s
,char c
)
1670 /****************************************************************************
1672 ****************************************************************************/
1673 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1680 if ((mode
& aDIR
) != 0)
1683 memset(buf
+1,' ',11);
1684 if ((p
= strchr(mask2
,'.')) != NULL
)
1687 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1688 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
1692 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),11));
1694 bzero(buf
+21,DIR_STRUCT_SIZE
-21);
1695 CVAL(buf
,21) = mode
;
1696 put_dos_date(buf
,22,date
);
1697 SSVAL(buf
,26,size
& 0xFFFF);
1698 SSVAL(buf
,28,size
>> 16);
1699 StrnCpy(buf
+30,fname
,12);
1700 if (!case_sensitive
)
1702 DEBUG(8,("put name [%s] into dir struct\n",buf
+30));
1706 /*******************************************************************
1707 close the low 3 fd's and open dev/null in their place
1708 ********************************************************************/
1709 void close_low_fds(void)
1713 close(0); close(1); close(2);
1714 /* try and use up these file descriptors, so silly
1715 library routines writing to stdout etc won't cause havoc */
1717 fd
= open("/dev/null",O_RDWR
,0);
1718 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
1720 DEBUG(0,("Can't open /dev/null\n"));
1724 DEBUG(0,("Didn't get file descriptor %d\n",i
));
1730 /****************************************************************************
1731 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1733 if SYSV use O_NDELAY
1735 ****************************************************************************/
1736 int set_blocking(int fd
, BOOL set
)
1740 #define FLAG_TO_SET O_NONBLOCK
1743 #define FLAG_TO_SET O_NDELAY
1745 #define FLAG_TO_SET FNDELAY
1749 if((val
= fcntl(fd
, F_GETFL
, 0)) == -1)
1751 if(set
) /* Turn blocking on - ie. clear nonblock flag */
1752 val
&= ~FLAG_TO_SET
;
1755 return fcntl( fd
, F_SETFL
, val
);
1760 /****************************************************************************
1762 ****************************************************************************/
1763 int write_socket(int fd
,char *buf
,int len
)
1769 DEBUG(6,("write_socket(%d,%d)\n",fd
,len
));
1770 ret
= write_data(fd
,buf
,len
);
1772 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,len
,ret
));
1776 /****************************************************************************
1778 ****************************************************************************/
1779 int read_udp_socket(int fd
,char *buf
,int len
)
1782 struct sockaddr sock
;
1785 socklen
= sizeof(sock
);
1786 bzero((char *)&sock
,socklen
);
1787 bzero((char *)&lastip
,sizeof(lastip
));
1788 ret
= recvfrom(fd
,buf
,len
,0,&sock
,&socklen
);
1790 DEBUG(2,("read socket failed. ERRNO=%d\n",errno
));
1794 lastip
= *(struct in_addr
*) &sock
.sa_data
[2];
1795 lastport
= ntohs(((struct sockaddr_in
*)&sock
)->sin_port
);
1800 /****************************************************************************
1801 read data from a device with a timout in msec.
1802 mincount = if timeout, minimum to read before returning
1803 maxcount = number to be read.
1804 ****************************************************************************/
1805 int read_with_timeout(int fd
,char *buf
,int mincnt
,int maxcnt
,long time_out
)
1811 struct timeval timeout
;
1813 /* just checking .... */
1814 if (maxcnt
<= 0) return(0);
1819 if (time_out
<= 0) {
1820 if (mincnt
== 0) mincnt
= maxcnt
;
1822 while (nread
< mincnt
) {
1823 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
1825 smb_read_error
= READ_EOF
;
1829 if (readret
== -1) {
1830 smb_read_error
= READ_ERROR
;
1838 /* Most difficult - timeout read */
1839 /* If this is ever called on a disk file and
1840 mincnt is greater then the filesize then
1841 system performance will suffer severely as
1842 select always return true on disk files */
1844 /* Set initial timeout */
1845 timeout
.tv_sec
= time_out
/ 1000;
1846 timeout
.tv_usec
= 1000 * (time_out
% 1000);
1848 for (nread
=0; nread
<mincnt
; )
1853 selrtn
= sys_select(&fds
,&timeout
);
1855 /* Check if error */
1857 /* something is wrong. Maybe the socket is dead? */
1858 smb_read_error
= READ_ERROR
;
1862 /* Did we timeout ? */
1864 smb_read_error
= READ_TIMEOUT
;
1868 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
1870 /* we got EOF on the file descriptor */
1871 smb_read_error
= READ_EOF
;
1875 if (readret
== -1) {
1876 /* the descriptor is probably dead */
1877 smb_read_error
= READ_ERROR
;
1884 /* Return the number we got */
1888 /****************************************************************************
1889 read data from the client. Maxtime is in milliseconds
1890 ****************************************************************************/
1891 int read_max_udp(int fd
,char *buffer
,int bufsize
,int maxtime
)
1896 struct timeval timeout
;
1901 timeout
.tv_sec
= maxtime
/ 1000;
1902 timeout
.tv_usec
= (maxtime
% 1000) * 1000;
1904 selrtn
= sys_select(&fds
,maxtime
>0?&timeout
:NULL
);
1906 if (!FD_ISSET(fd
,&fds
))
1909 nread
= read_udp_socket(fd
, buffer
, bufsize
);
1911 /* return the number got */
1915 /*******************************************************************
1916 find the difference in milliseconds between two struct timeval
1918 ********************************************************************/
1919 int TvalDiff(struct timeval
*tvalold
,struct timeval
*tvalnew
)
1921 return((tvalnew
->tv_sec
- tvalold
->tv_sec
)*1000 +
1922 ((int)tvalnew
->tv_usec
- (int)tvalold
->tv_usec
)/1000);
1925 /****************************************************************************
1926 send a keepalive packet (rfc1002)
1927 ****************************************************************************/
1928 BOOL
send_keepalive(int client
)
1930 unsigned char buf
[4];
1933 buf
[1] = buf
[2] = buf
[3] = 0;
1935 return(write_data(client
,(char *)buf
,4) == 4);
1940 /****************************************************************************
1941 read data from the client, reading exactly N bytes.
1942 ****************************************************************************/
1943 int read_data(int fd
,char *buffer
,int N
)
1952 ret
= read(fd
,buffer
+ total
,N
- total
);
1954 smb_read_error
= READ_EOF
;
1958 smb_read_error
= READ_ERROR
;
1967 /****************************************************************************
1969 ****************************************************************************/
1970 int write_data(int fd
,char *buffer
,int N
)
1977 ret
= write(fd
,buffer
+ total
,N
- total
);
1979 if (ret
== -1) return -1;
1980 if (ret
== 0) return total
;
1988 /****************************************************************************
1989 transfer some data between two fd's
1990 ****************************************************************************/
1991 int transfer_file(int infd
,int outfd
,int n
,char *header
,int headlen
,int align
)
1993 static char *buf
=NULL
;
1998 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
2001 size
= lp_readsize();
2002 size
= MAX(size
,1024);
2005 while (!buf
&& size
>0) {
2006 buf
= (char *)Realloc(buf
,size
+8);
2007 if (!buf
) size
/= 2;
2011 DEBUG(0,("Can't allocate transfer buffer!\n"));
2015 abuf
= buf
+ (align
%8);
2022 int s
= MIN(n
,size
);
2027 if (header
&& (headlen
>= MIN(s
,1024))) {
2037 if (header
&& headlen
> 0)
2039 ret
= MIN(headlen
,size
);
2040 memcpy(buf1
,header
,ret
);
2043 if (headlen
<= 0) header
= NULL
;
2047 ret
+= read(infd
,buf1
+ret
,s
-ret
);
2051 ret2
= (outfd
>=0?write_data(outfd
,buf1
,ret
):ret
);
2052 if (ret2
> 0) total
+= ret2
;
2053 /* if we can't write then dump excess data */
2055 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
2057 if (ret
<= 0 || ret2
!= ret
)
2065 /****************************************************************************
2066 read 4 bytes of a smb packet and return the smb length of the packet
2067 possibly store the result in the buffer
2068 ****************************************************************************/
2069 int read_smb_length(int fd
,char *inbuf
,int timeout
)
2073 int len
=0, msg_type
;
2084 ok
= (read_with_timeout(fd
,buffer
,4,4,timeout
) == 4);
2086 ok
= (read_data(fd
,buffer
,4) == 4);
2091 len
= smb_len(buffer
);
2092 msg_type
= CVAL(buffer
,0);
2094 if (msg_type
== 0x85)
2096 DEBUG(5,("Got keepalive packet\n"));
2101 DEBUG(10,("got smb length of %d\n",len
));
2108 /****************************************************************************
2109 read an smb from a fd and return it's length
2110 The timeout is in milli seconds
2111 ****************************************************************************/
2112 BOOL
receive_smb(int fd
,char *buffer
,int timeout
)
2118 bzero(buffer
,smb_size
+ 100);
2120 len
= read_smb_length(fd
,buffer
,timeout
);
2124 if (len
> BUFFER_SIZE
) {
2125 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2126 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2130 ret
= read_data(fd
,buffer
+4,len
);
2132 smb_read_error
= READ_ERROR
;
2140 /****************************************************************************
2142 ****************************************************************************/
2143 BOOL
send_smb(int fd
,char *buffer
)
2147 len
= smb_len(buffer
) + 4;
2149 while (nwritten
< len
)
2151 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2154 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
2166 /****************************************************************************
2167 find a pointer to a netbios name
2168 ****************************************************************************/
2169 char *name_ptr(char *buf
,int ofs
)
2171 unsigned char c
= *(unsigned char *)(buf
+ofs
);
2173 if ((c
& 0xC0) == 0xC0)
2177 memcpy(p
,buf
+ofs
,2);
2180 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
2187 /****************************************************************************
2188 extract a netbios name from a buf
2189 ****************************************************************************/
2190 int name_extract(char *buf
,int ofs
,char *name
)
2192 char *p
= name_ptr(buf
,ofs
);
2193 int d
= PTR_DIFF(p
,buf
+ofs
);
2195 if (d
< -50 || d
> 50) return(0);
2196 return(name_interpret(p
,name
));
2200 /****************************************************************************
2201 return the total storage length of a mangled name
2202 ****************************************************************************/
2203 int name_len(char *s
)
2206 unsigned char c
= *(unsigned char *)s
;
2207 if ((c
& 0xC0) == 0xC0)
2209 while (*s
) s
+= (*s
)+1;
2210 return(PTR_DIFF(s
,s0
)+1);
2213 /****************************************************************************
2214 send a single packet to a port on another machine
2215 ****************************************************************************/
2216 BOOL
send_one_packet(char *buf
,int len
,struct in_addr ip
,int port
,int type
)
2220 struct sockaddr_in sock_out
;
2225 /* create a socket to write to */
2226 out_fd
= socket(AF_INET
, type
, 0);
2229 DEBUG(0,("socket failed"));
2233 /* set the address and port */
2234 bzero((char *)&sock_out
,sizeof(sock_out
));
2235 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
2236 sock_out
.sin_port
= htons( port
);
2237 sock_out
.sin_family
= AF_INET
;
2240 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2241 len
,inet_ntoa(ip
),port
,type
==SOCK_DGRAM
?"DGRAM":"STREAM"));
2244 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2247 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2248 inet_ntoa(ip
),port
,errno
));
2254 /*******************************************************************
2255 sleep for a specified number of milliseconds
2256 ********************************************************************/
2260 struct timeval tval
,t1
,t2
;
2267 tval
.tv_sec
= (t
-tdiff
)/1000;
2268 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2272 sys_select(&fds
,&tval
);
2275 tdiff
= TvalDiff(&t1
,&t2
);
2279 /****************************************************************************
2280 check if a string is part of a list
2281 ****************************************************************************/
2282 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
2287 if (!list
) return(False
);
2289 while (next_token(&p
,tok
,LIST_SEP
))
2291 if (casesensitive
) {
2292 if (strcmp(tok
,s
) == 0)
2295 if (StrCaseCmp(tok
,s
) == 0)
2302 /* this is used to prevent lots of mallocs of size 1 */
2303 static char *null_string
= NULL
;
2305 /****************************************************************************
2306 set a string value, allocing the space for the string
2307 ****************************************************************************/
2308 BOOL
string_init(char **dest
,char *src
)
2319 null_string
= (char *)malloc(1);
2322 *dest
= null_string
;
2326 *dest
= (char *)malloc(l
+1);
2332 /****************************************************************************
2334 ****************************************************************************/
2335 void string_free(char **s
)
2337 if (!s
|| !(*s
)) return;
2338 if (*s
== null_string
)
2344 /****************************************************************************
2345 set a string value, allocing the space for the string, and deallocating any
2347 ****************************************************************************/
2348 BOOL
string_set(char **dest
,char *src
)
2352 return(string_init(dest
,src
));
2355 /****************************************************************************
2356 substitute a string for a pattern in another string. Make sure there is
2359 This routine looks for pattern in s and replaces it with
2360 insert. It may do multiple replacements.
2362 return True if a substitution was done.
2363 ****************************************************************************/
2364 BOOL
string_sub(char *s
,char *pattern
,char *insert
)
2370 if (!insert
|| !pattern
|| !s
) return(False
);
2373 lp
= strlen(pattern
);
2374 li
= strlen(insert
);
2376 if (!*pattern
) return(False
);
2378 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2381 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2382 memcpy(p
,insert
,li
);
2391 /*********************************************************
2392 * Recursive routine that is called by mask_match.
2393 * Does the actual matching.
2394 *********************************************************/
2395 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
2399 for( p
= regexp
; *p
&& *str
; ) {
2406 /* Look for a character matching
2407 the one after the '*' */
2410 return True
; /* Automatic match */
2412 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2414 if(do_match(str
,p
,case_sig
))
2428 if(toupper(*str
) != toupper(*p
))
2438 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2441 if (!*str
&& *p
== '?')
2443 while (*p
== '?') p
++;
2447 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2453 /*********************************************************
2454 * Routine to match a given string with a regexp - uses
2455 * simplified regexp that takes * and ? only. Case can be
2456 * significant or not.
2457 *********************************************************/
2458 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
2462 fstring ebase
,eext
,sbase
,sext
;
2466 /* Make local copies of str and regexp */
2467 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
2468 StrnCpy(p2
,str
,sizeof(pstring
)-1);
2470 if (!strchr(p2
,'.')) {
2475 if (!strchr(p1,'.')) {
2483 string_sub(p1
,"*.*","*");
2484 string_sub(p1
,".*","*");
2488 /* Remove any *? and ** as they are meaningless */
2489 for(p
= p1
; *p
; p
++)
2490 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
2491 (void)strcpy( &p
[1], &p
[2]);
2493 if (strequal(p1
,"*")) return(True
);
2495 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
2501 if ((p
=strrchr(p1
,'.'))) {
2510 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
2520 matched
= do_match(sbase
,ebase
,case_sig
) &&
2521 (trans2
|| do_match(sext
,eext
,case_sig
));
2523 DEBUG(5,("mask_match returning %d\n", matched
));
2530 /****************************************************************************
2531 become a daemon, discarding the controlling terminal
2532 ****************************************************************************/
2533 void become_daemon(void)
2535 #ifndef NO_FORK_DEBUG
2539 /* detach from the terminal */
2542 #else /* USE_SETSID */
2545 int i
= open("/dev/tty", O_RDWR
);
2548 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
2552 #endif /* TIOCNOTTY */
2553 #endif /* USE_SETSID */
2554 /* Close fd's 0,1,2. Needed if started by rsh */
2556 #endif /* NO_FORK_DEBUG */
2560 /****************************************************************************
2561 put up a yes/no prompt
2562 ****************************************************************************/
2568 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
2571 if (*ans
== 'y' || *ans
== 'Y')
2577 /****************************************************************************
2578 read a line from a file with possible \ continuation chars.
2579 Blanks at the start or end of a line are stripped.
2580 The string will be allocated if s2 is NULL
2581 ****************************************************************************/
2582 char *fgets_slash(char *s2
,int maxlen
,FILE *f
)
2587 BOOL start_of_line
= True
;
2594 maxlen
= MIN(maxlen
,8);
2595 s
= (char *)Realloc(s
,maxlen
);
2598 if (!s
|| maxlen
< 2) return(NULL
);
2602 while (len
< maxlen
-1)
2610 while (len
> 0 && s
[len
-1] == ' ')
2614 if (len
> 0 && s
[len
-1] == '\\')
2617 start_of_line
= True
;
2622 if (len
<= 0 && !s2
)
2624 return(len
>0?s
:NULL
);
2629 start_of_line
= False
;
2633 if (!s2
&& len
> maxlen
-3)
2636 s
= (char *)Realloc(s
,maxlen
);
2637 if (!s
) return(NULL
);
2645 /****************************************************************************
2646 set the length of a file from a filedescriptor.
2647 Returns 0 on success, -1 on failure.
2648 ****************************************************************************/
2649 int set_filelen(int fd
, long len
)
2651 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2652 extend a file with ftruncate. Provide alternate implementation
2655 #if FTRUNCATE_CAN_EXTEND
2656 return ftruncate(fd
, len
);
2660 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
2664 /* Do an fstat to see if the file is longer than
2665 the requested size (call ftruncate),
2666 or shorter, in which case seek to len - 1 and write 1
2668 if(fstat(fd
, &st
)<0)
2672 if (S_ISFIFO(st
.st_mode
)) return 0;
2675 if(st
.st_size
== len
)
2677 if(st
.st_size
> len
)
2678 return ftruncate(fd
, len
);
2680 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
2682 if(write(fd
, &c
, 1)!=1)
2684 /* Seek to where we were */
2685 lseek(fd
, currpos
, SEEK_SET
);
2691 /****************************************************************************
2692 return the byte checksum of some data
2693 ****************************************************************************/
2694 int byte_checksum(char *buf
,int len
)
2696 unsigned char *p
= (unsigned char *)buf
;
2706 /****************************************************************************
2707 this is a version of setbuffer() for those machines that only have setvbuf
2708 ****************************************************************************/
2709 void setbuffer(FILE *f
,char *buf
,int bufsize
)
2711 setvbuf(f
,buf
,_IOFBF
,bufsize
);
2716 /****************************************************************************
2717 parse out a directory name from a path name. Assumes dos style filenames.
2718 ****************************************************************************/
2719 char *dirname_dos(char *path
,char *buf
)
2721 char *p
= strrchr(path
,'\\');
2736 /****************************************************************************
2737 parse out a filename from a path name. Assumes dos style filenames.
2738 ****************************************************************************/
2739 static char *filename_dos(char *path
,char *buf
)
2741 char *p
= strrchr(path
,'\\');
2753 /****************************************************************************
2754 expand a pointer to be a particular size
2755 ****************************************************************************/
2756 void *Realloc(void *p
,int size
)
2762 DEBUG(5,("Realloc asked for 0 bytes\n"));
2767 ret
= (void *)malloc(size
);
2769 ret
= (void *)realloc(p
,size
);
2772 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
2778 /****************************************************************************
2780 ****************************************************************************/
2781 char *strdup(char *s
)
2784 if (!s
) return(NULL
);
2785 ret
= (char *)malloc(strlen(s
)+1);
2786 if (!ret
) return(NULL
);
2793 /****************************************************************************
2794 Signal handler for SIGPIPE (write on a disconnected socket)
2795 ****************************************************************************/
2798 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2802 /****************************************************************************
2803 get my own name and IP
2804 ****************************************************************************/
2805 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
2812 /* get my host name */
2813 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
2815 DEBUG(0,("gethostname failed\n"));
2820 if ((hp
= Get_Hostbyname(hostname
)) == 0)
2822 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
2828 /* split off any parts after an initial . */
2829 char *p
= strchr(hostname
,'.');
2832 strcpy(my_name
,hostname
);
2836 putip((char *)ip
,(char *)hp
->h_addr
);
2842 /****************************************************************************
2843 true if two IP addresses are equal
2844 ****************************************************************************/
2845 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
2848 a1
= ntohl(ip1
.s_addr
);
2849 a2
= ntohl(ip2
.s_addr
);
2854 /****************************************************************************
2855 open a socket of the specified type, port and address for incoming data
2856 ****************************************************************************/
2857 int open_socket_in(int type
, int port
, int dlevel
,uint32 socket_addr
)
2860 struct sockaddr_in sock
;
2864 /* get my host name */
2865 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
2866 { DEBUG(0,("gethostname failed\n")); return -1; }
2869 if ((hp
= Get_Hostbyname(host_name
)) == 0)
2871 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
2875 bzero((char *)&sock
,sizeof(sock
));
2876 memcpy((char *)&sock
.sin_addr
,(char *)hp
->h_addr
, hp
->h_length
);
2877 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2878 sock
.sin_len
= sizeof(sock
);
2880 sock
.sin_port
= htons( port
);
2881 sock
.sin_family
= hp
->h_addrtype
;
2882 sock
.sin_addr
.s_addr
= socket_addr
;
2883 res
= socket(hp
->h_addrtype
, type
, 0);
2885 { DEBUG(0,("socket failed\n")); return -1; }
2889 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
2892 /* now we've got a socket - we need to bind it */
2893 if (bind(res
, (struct sockaddr
* ) &sock
,sizeof(sock
)) < 0)
2896 if (port
== SMB_PORT
|| port
== NMB_PORT
)
2897 DEBUG(dlevel
,("bind failed on port %d socket_addr=%x (%s)\n",
2898 port
,socket_addr
,strerror(errno
)));
2901 if (dlevel
> 0 && port
< 1000)
2904 if (port
>= 1000 && port
< 9000)
2905 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
2910 DEBUG(3,("bind succeeded on port %d\n",port
));
2916 /****************************************************************************
2917 create an outgoing socket
2918 **************************************************************************/
2919 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
2921 struct sockaddr_in sock_out
;
2923 int connect_loop
= 250; /* 250 milliseconds */
2924 int loops
= (timeout
* 1000) / connect_loop
;
2926 /* create a socket to write to */
2927 res
= socket(PF_INET
, type
, 0);
2929 { DEBUG(0,("socket error\n")); return -1; }
2931 if (type
!= SOCK_STREAM
) return(res
);
2933 bzero((char *)&sock_out
,sizeof(sock_out
));
2934 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
2936 sock_out
.sin_port
= htons( port
);
2937 sock_out
.sin_family
= PF_INET
;
2939 /* set it non-blocking */
2940 set_blocking(res
,False
);
2942 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
2944 /* and connect it to the destination */
2946 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
2948 /* Some systems return EAGAIN when they mean EINPROGRESS */
2949 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2950 errno
== EAGAIN
) && loops
--) {
2951 msleep(connect_loop
);
2955 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
2957 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
2963 if (ret
< 0 && errno
== EISCONN
) {
2970 DEBUG(1,("error connecting to %s:%d (%s)\n",
2971 inet_ntoa(*addr
),port
,strerror(errno
)));
2975 /* set it blocking again */
2976 set_blocking(res
,True
);
2982 /****************************************************************************
2983 interpret a protocol description string, with a default
2984 ****************************************************************************/
2985 int interpret_protocol(char *str
,int def
)
2987 if (strequal(str
,"NT1"))
2988 return(PROTOCOL_NT1
);
2989 if (strequal(str
,"LANMAN2"))
2990 return(PROTOCOL_LANMAN2
);
2991 if (strequal(str
,"LANMAN1"))
2992 return(PROTOCOL_LANMAN1
);
2993 if (strequal(str
,"CORE"))
2994 return(PROTOCOL_CORE
);
2995 if (strequal(str
,"COREPLUS"))
2996 return(PROTOCOL_COREPLUS
);
2997 if (strequal(str
,"CORE+"))
2998 return(PROTOCOL_COREPLUS
);
3000 DEBUG(0,("Unrecognised protocol level %s\n",str
));
3005 /****************************************************************************
3006 interpret a security level
3007 ****************************************************************************/
3008 int interpret_security(char *str
,int def
)
3010 if (strequal(str
,"SERVER"))
3012 if (strequal(str
,"USER"))
3014 if (strequal(str
,"SHARE"))
3017 DEBUG(0,("Unrecognised security level %s\n",str
));
3023 /****************************************************************************
3024 interpret an internet address or name into an IP address in 4 byte form
3025 ****************************************************************************/
3026 uint32
interpret_addr(char *str
)
3031 BOOL pure_address
= True
;
3033 if (strcmp(str
,"0.0.0.0") == 0) return(0);
3034 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
3036 for (i
=0; pure_address
&& str
[i
]; i
++)
3037 if (!(isdigit(str
[i
]) || str
[i
] == '.'))
3038 pure_address
= False
;
3040 /* if it's in the form of an IP address then get the lib to interpret it */
3042 res
= inet_addr(str
);
3044 /* otherwise assume it's a network name of some sort and use
3046 if ((hp
= Get_Hostbyname(str
)) == 0) {
3047 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
3050 putip((char *)&res
,(char *)hp
->h_addr
);
3053 if (res
== (uint32
)-1) return(0);
3058 /*******************************************************************
3059 a convenient addition to interpret_addr()
3060 ******************************************************************/
3061 struct in_addr
*interpret_addr2(char *str
)
3063 static struct in_addr ret
;
3064 uint32 a
= interpret_addr(str
);
3069 /*******************************************************************
3070 check if an IP is the 0.0.0.0
3071 ******************************************************************/
3072 BOOL
zero_ip(struct in_addr ip
)
3075 putip((char *)&a
,(char *)&ip
);
3080 /*******************************************************************
3081 matchname - determine if host name matches IP address
3082 ******************************************************************/
3083 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
3088 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
3089 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost
));
3094 * Make sure that gethostbyname() returns the "correct" host name.
3095 * Unfortunately, gethostbyname("localhost") sometimes yields
3096 * "localhost.domain". Since the latter host name comes from the
3097 * local DNS, we just have to trust it (all bets are off if the local
3098 * DNS is perverted). We always check the address list, though.
3101 if (strcasecmp(remotehost
, hp
->h_name
)
3102 && strcasecmp(remotehost
, "localhost")) {
3103 DEBUG(0,("host name/name mismatch: %s != %s",
3104 remotehost
, hp
->h_name
));
3108 /* Look up the host address in the address list we just got. */
3109 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
3110 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
3115 * The host name does not map to the original host address. Perhaps
3116 * someone has compromised a name server. More likely someone botched
3117 * it, but that could be dangerous, too.
3120 DEBUG(0,("host name/address mismatch: %s != %s",
3121 inet_ntoa(addr
), hp
->h_name
));
3125 /*******************************************************************
3126 Reset the 'done' variables so after a client process is created
3127 from a fork call these calls will be re-done. This should be
3128 expanded if more variables need reseting.
3129 ******************************************************************/
3131 static BOOL global_client_name_done
= False
;
3132 static BOOL global_client_addr_done
= False
;
3134 void reset_globals_after_fork()
3136 global_client_name_done
= False
;
3137 global_client_addr_done
= False
;
3140 /*******************************************************************
3141 return the DNS name of the client
3142 ******************************************************************/
3143 char *client_name(void)
3147 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3148 int length
= sizeof(sa
);
3149 static pstring name_buf
;
3152 if (global_client_name_done
)
3155 strcpy(name_buf
,"UNKNOWN");
3157 if (getpeername(Client
, &sa
, &length
) < 0) {
3158 DEBUG(0,("getpeername failed\n"));
3162 /* Look up the remote host name. */
3163 if ((hp
= gethostbyaddr((char *) &sockin
->sin_addr
,
3164 sizeof(sockin
->sin_addr
),
3166 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3167 StrnCpy(name_buf
,client_addr(),sizeof(name_buf
) - 1);
3169 StrnCpy(name_buf
,(char *)hp
->h_name
,sizeof(name_buf
) - 1);
3170 if (!matchname(name_buf
, sockin
->sin_addr
)) {
3171 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,client_addr()));
3172 strcpy(name_buf
,"UNKNOWN");
3175 global_client_name_done
= True
;
3179 /*******************************************************************
3180 return the IP addr of the client as a string
3181 ******************************************************************/
3182 char *client_addr(void)
3186 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3187 int length
= sizeof(sa
);
3188 static fstring addr_buf
;
3190 if (global_client_addr_done
)
3193 strcpy(addr_buf
,"0.0.0.0");
3195 if (getpeername(Client
, &sa
, &length
) < 0) {
3196 DEBUG(0,("getpeername failed\n"));
3200 strcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
3202 global_client_addr_done
= True
;
3206 /*******************************************************************
3207 sub strings with useful parameters
3208 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3209 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3210 ********************************************************************/
3211 void standard_sub_basic(char *string
)
3215 struct passwd
*pass
;
3217 for (s
= string
; (p
= strchr(s
,'%')) != NULL
; s
= p
)
3221 case 'G' : if ((pass
= Get_Pwnam(sesssetup_user
,False
))!=NULL
)
3222 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
3226 case 'I' : string_sub(p
,"%I",client_addr()); break;
3227 case 'L' : string_sub(p
,"%L",local_machine
); break;
3228 case 'M' : string_sub(p
,"%M",client_name()); break;
3229 case 'R' : string_sub(p
,"%R",remote_proto
); break;
3230 case 'T' : string_sub(p
,"%T",timestring()); break;
3231 case 'U' : string_sub(p
,"%U",sesssetup_user
); break;
3232 case 'a' : string_sub(p
,"%a",remote_arch
); break;
3233 case 'd' : sprintf(pidstr
,"%d",(int)getpid());
3234 string_sub(p
,"%d",pidstr
);
3236 case 'h' : string_sub(p
,"%h",myhostname
); break;
3237 case 'm' : string_sub(p
,"%m",remote_machine
); break;
3238 case 'v' : string_sub(p
,"%v",VERSION
); break;
3239 case '\0' : p
++; break; /* don't run off end if last character is % */
3240 default : p
+=2; break;
3246 /*******************************************************************
3247 are two IPs on the same subnet?
3248 ********************************************************************/
3249 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
3251 uint32 net1
,net2
,nmask
;
3253 nmask
= ntohl(mask
.s_addr
);
3254 net1
= ntohl(ip1
.s_addr
);
3255 net2
= ntohl(ip2
.s_addr
);
3257 return((net1
& nmask
) == (net2
& nmask
));
3261 /*******************************************************************
3262 write a string in unicoode format
3263 ********************************************************************/
3264 int PutUniCode(char *dst
,char *src
)
3268 dst
[ret
++] = src
[0];
3277 /****************************************************************************
3278 a wrapper for gethostbyname() that tries with all lower and all upper case
3279 if the initial name fails
3280 ****************************************************************************/
3281 struct hostent
*Get_Hostbyname(char *name
)
3283 char *name2
= strdup(name
);
3284 struct hostent
*ret
;
3288 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3292 if (!isalnum(*name2
))
3298 ret
= sys_gethostbyname(name2
);
3305 /* try with all lowercase */
3307 ret
= sys_gethostbyname(name2
);
3314 /* try with all uppercase */
3316 ret
= sys_gethostbyname(name2
);
3323 /* nothing works :-( */
3329 /****************************************************************************
3330 check if a process exists. Does this work on all unixes?
3331 ****************************************************************************/
3332 BOOL
process_exists(int pid
)
3336 sprintf(s
,"/proc/%d",pid
);
3337 return(directory_exist(s
,NULL
));
3340 static BOOL tested
=False
;
3341 static BOOL ok
=False
;
3345 sprintf(s
,"/proc/%05d",(int)getpid());
3346 ok
= file_exist(s
,NULL
);
3349 sprintf(s
,"/proc/%05d",pid
);
3350 return(file_exist(s
,NULL
));
3354 /* CGH 8/16/96 - added ESRCH test */
3355 return(pid
== getpid() || kill(pid
,0) == 0 || errno
!= ESRCH
);
3360 /*******************************************************************
3361 turn a uid into a user name
3362 ********************************************************************/
3363 char *uidtoname(int uid
)
3365 static char name
[40];
3366 struct passwd
*pass
= getpwuid(uid
);
3367 if (pass
) return(pass
->pw_name
);
3368 sprintf(name
,"%d",uid
);
3372 /*******************************************************************
3373 turn a gid into a group name
3374 ********************************************************************/
3375 char *gidtoname(int gid
)
3377 static char name
[40];
3378 struct group
*grp
= getgrgid(gid
);
3379 if (grp
) return(grp
->gr_name
);
3380 sprintf(name
,"%d",gid
);
3384 /*******************************************************************
3386 ********************************************************************/
3387 void BlockSignals(BOOL block
,int signum
)
3390 int block_mask
= sigmask(signum
);
3391 static int oldmask
= 0;
3393 oldmask
= sigblock(block_mask
);
3395 sigsetmask(oldmask
);
3396 #elif defined(USE_SIGPROCMASK)
3399 sigaddset(&set
,signum
);
3400 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
3405 /*******************************************************************
3406 my own panic function - not suitable for general use
3407 ********************************************************************/
3408 void ajt_panic(void)
3410 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3415 #define DIRECT direct
3417 #define DIRECT dirent
3420 /*******************************************************************
3421 a readdir wrapper which just returns the file name
3422 also return the inode number if requested
3423 ********************************************************************/
3424 char *readdirname(void *p
)
3429 if (!p
) return(NULL
);
3431 ptr
= (struct DIRECT
*)readdir(p
);
3432 if (!ptr
) return(NULL
);
3434 dname
= ptr
->d_name
;
3437 if (telldir(p
) < 0) return(NULL
);
3441 /* this handles a broken compiler setup, causing a mixture
3442 of BSD and SYSV headers and libraries */
3444 static BOOL broken_readdir
= False
;
3445 if (!broken_readdir
&& !(*(dname
)) && strequal("..",dname
-2))
3447 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3448 broken_readdir
= True
;
3458 unix_to_dos(buf
, True
);
3466 * Utility function used to decide if the last component
3467 * of a path matches a (possibly wildcarded) entry in a namelist.
3470 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
3472 pstring last_component
;
3475 DEBUG(5, ("is_in_path: %s\n", name
));
3477 /* if we have no list it's obviously not in the path */
3478 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
3480 DEBUG(5,("is_in_path: no name list.\n"));
3484 /* Get the last component of the unix name. */
3485 p
= strrchr(name
, '/');
3486 strncpy(last_component
, p
? p
: name
, sizeof(last_component
)-1);
3487 last_component
[sizeof(last_component
)-1] = '\0';
3489 for(; namelist
->name
!= NULL
; namelist
++)
3491 if(namelist
->is_wild
)
3493 /* look for a wildcard match. */
3494 if (mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
3496 DEBUG(5,("is_in_path: mask match succeeded\n"));
3502 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
3503 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
3505 DEBUG(5,("is_in_path: match succeeded\n"));
3510 DEBUG(5,("is_in_path: match not found\n"));
3516 * Strip a '/' separated list into an array of
3517 * name_compare_enties structures suitable for
3518 * passing to is_in_path(). We do this for
3519 * speed so we can pre-parse all the names in the list
3520 * and don't do it for each call to is_in_path().
3521 * namelist is modified here and is assumed to be
3522 * a copy owned by the caller.
3523 * We also check if the entry contains a wildcard to
3524 * remove a potentially expensive call to mask_match
3528 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
3531 char *nameptr
= namelist
;
3532 int num_entries
= 0;
3535 (*ppname_array
) = NULL
;
3537 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
3540 /* We need to make two passes over the string. The
3541 first to count the number of elements, the second
3546 if ( *nameptr
== '/' )
3548 /* cope with multiple (useless) /s) */
3552 /* find the next / */
3553 name_end
= strchr(nameptr
, '/');
3555 /* oops - the last check for a / didn't find one. */
3556 if (name_end
== NULL
)
3559 /* next segment please */
3560 nameptr
= name_end
+ 1;
3564 if(num_entries
== 0)
3567 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
3568 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
3570 DEBUG(0,("set_namearray: malloc fail\n"));
3574 /* Now copy out the names */
3579 if ( *nameptr
== '/' )
3581 /* cope with multiple (useless) /s) */
3585 /* find the next / */
3586 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
3591 /* oops - the last check for a / didn't find one. */
3592 if (name_end
== NULL
)
3595 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
3596 (strchr( nameptr
, '*')!=NULL
));
3597 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
3599 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3603 /* next segment please */
3604 nameptr
= name_end
+ 1;
3608 (*ppname_array
)[i
].name
= NULL
;
3613 /****************************************************************************
3614 routine to free a namearray.
3615 ****************************************************************************/
3617 void free_namearray(name_compare_entry
*name_array
)
3622 if(name_array
->name
!= NULL
)
3623 free(name_array
->name
);
3625 free((char *)name_array
);
3628 /****************************************************************************
3629 routine to do file locking
3630 ****************************************************************************/
3631 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
3638 uint32 mask
= 0xC0000000;
3640 /* make sure the count is reasonable, we might kill the lockd otherwise */
3643 /* the offset is often strange - remove 2 of its bits if either of
3644 the top two bits are set. Shift the top ones by two bits. This
3645 still allows OLE2 apps to operate, but should stop lockd from
3647 if ((offset
& mask
) != 0)
3648 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
3650 uint32 mask
= ((unsigned)1<<31);
3652 /* interpret negative counts as large numbers */
3656 /* no negative offsets */
3659 /* count + offset must be in range */
3660 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
3668 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
3671 lock
.l_whence
= SEEK_SET
;
3672 lock
.l_start
= (int)offset
;
3673 lock
.l_len
= (int)count
;
3678 ret
= fcntl(fd
,op
,&lock
);
3681 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
3687 (lock
.l_type
!= F_UNLCK
) &&
3688 (lock
.l_pid
!= 0) &&
3689 (lock
.l_pid
!= getpid()))
3691 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
3695 /* it must be not locked or locked by me */
3699 /* a lock set or unset */
3702 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3703 offset
,count
,op
,type
,strerror(errno
)));
3705 /* perhaps it doesn't support this sort of locking?? */
3706 if (errno
== EINVAL
)
3708 DEBUG(3,("locking not supported? returning True\n"));
3715 /* everything went OK */
3716 DEBUG(5,("Lock call successful\n"));
3724 /*******************************************************************
3725 lock a file - returning a open file descriptor or -1 on failure
3726 The timeout is in seconds. 0 means no timeout
3727 ********************************************************************/
3728 int file_lock(char *name
,int timeout
)
3730 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
3732 if (fd
< 0) return(-1);
3735 if (timeout
) t
= time(NULL
);
3736 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
3737 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
3738 msleep(LOCK_RETRY_TIMEOUT
);
3746 /*******************************************************************
3747 unlock a file locked by file_lock
3748 ********************************************************************/
3749 void file_unlock(int fd
)
3753 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
3758 /*******************************************************************
3759 is the name specified one of my netbios names
3760 returns true is it is equal, false otherwise
3761 ********************************************************************/
3762 BOOL
is_myname(const char *s
)
3767 for (n
=0; my_netbios_names
[n
]; n
++) {
3768 if (strequal(my_netbios_names
[n
], s
))
3771 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));