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.
816 return toupper (*s
) - toupper (*t
);
817 else if (is_sj_alph (*s
) && is_sj_alph (*t
))
819 diff
= sj_toupper2 (*(s
+1)) - sj_toupper2 (*(t
+1));
825 else if (is_shift_jis (*s
) && is_shift_jis (*t
))
827 diff
= ((int) (unsigned char) *s
) - ((int) (unsigned char) *t
);
830 diff
= ((int) (unsigned char) *(s
+1)) - ((int) (unsigned char) *(t
+1));
836 else if (is_shift_jis (*s
))
838 else if (is_shift_jis (*t
))
842 diff
= toupper (*s
) - toupper (*t
);
850 while (*s
&& *t
&& toupper(*s
) == toupper(*t
))
855 return(toupper(*s
) - toupper(*t
));
859 /*******************************************************************
860 case insensitive string compararison, length limited
861 ********************************************************************/
862 int StrnCaseCmp(const char *s
, const char *t
, int n
)
864 /* compare until we run out of string, either t or s, or chars */
865 /* We *must* use toupper rather than tolower here due to the
866 asynchronous upper to lower mapping.
873 return toupper (*s
) - toupper (*t
);
874 else if (is_sj_alph (*s
) && is_sj_alph (*t
))
876 diff
= sj_toupper2 (*(s
+1)) - sj_toupper2 (*(t
+1));
883 else if (is_shift_jis (*s
) && is_shift_jis (*t
))
885 diff
= ((int) (unsigned char) *s
) - ((int) (unsigned char) *t
);
888 diff
= ((int) (unsigned char) *(s
+1)) - ((int) (unsigned char) *(t
+1));
895 else if (is_shift_jis (*s
))
897 else if (is_shift_jis (*t
))
901 diff
= toupper (*s
) - toupper (*t
);
911 while (n
-- && *s
&& *t
&& toupper(*s
) == toupper(*t
))
916 /* not run out of chars - strings are different lengths */
917 if (n
) return(toupper(*s
) - toupper(*t
));
919 /* identical up to where we run out of chars, and strings are same length */
924 /*******************************************************************
926 ********************************************************************/
927 BOOL
strequal(const char *s1
, const char *s2
)
929 if (s1
== s2
) return(True
);
930 if (!s1
|| !s2
) return(False
);
932 return(StrCaseCmp(s1
,s2
)==0);
935 /*******************************************************************
936 compare 2 strings up to and including the nth char.
937 ******************************************************************/
938 BOOL
strnequal(const char *s1
,const char *s2
,int n
)
940 if (s1
== s2
) return(True
);
941 if (!s1
|| !s2
|| !n
) return(False
);
943 return(StrnCaseCmp(s1
,s2
,n
)==0);
946 /*******************************************************************
947 compare 2 strings (case sensitive)
948 ********************************************************************/
949 BOOL
strcsequal(char *s1
,char *s2
)
951 if (s1
== s2
) return(True
);
952 if (!s1
|| !s2
) return(False
);
954 return(strcmp(s1
,s2
)==0);
958 /*******************************************************************
959 convert a string to lower case
960 ********************************************************************/
961 void strlower(char *s
)
966 if (is_shift_jis (*s
)) {
967 if (is_sj_upper (s
[0], s
[1])) {
968 s
[1] = sj_tolower2 (s
[1]);
971 } else if (is_kana (*s
)) {
986 /*******************************************************************
987 convert a string to upper case
988 ********************************************************************/
989 void strupper(char *s
)
994 if (is_shift_jis (*s
)) {
995 if (is_sj_lower (s
[0], s
[1])) {
996 s
[1] = sj_toupper2 (s
[1]);
999 } else if (is_kana (*s
)) {
1014 /*******************************************************************
1015 convert a string to "normal" form
1016 ********************************************************************/
1017 void strnorm(char *s
)
1019 if (case_default
== CASE_UPPER
)
1025 /*******************************************************************
1026 check if a string is in "normal" case
1027 ********************************************************************/
1028 BOOL
strisnormal(char *s
)
1030 if (case_default
== CASE_UPPER
)
1031 return(!strhaslower(s
));
1033 return(!strhasupper(s
));
1037 /****************************************************************************
1039 ****************************************************************************/
1040 void string_replace(char *s
,char oldc
,char newc
)
1045 if (is_shift_jis (*s
)) {
1047 } else if (is_kana (*s
)) {
1062 /****************************************************************************
1063 make a file into unix format
1064 ****************************************************************************/
1065 void unix_format(char *fname
)
1068 string_replace(fname
,'\\','/');
1072 strcpy(namecopy
,fname
);
1074 strcat(fname
,namecopy
);
1078 /****************************************************************************
1079 make a file into dos format
1080 ****************************************************************************/
1081 void dos_format(char *fname
)
1083 string_replace(fname
,'/','\\');
1087 /*******************************************************************
1088 show a smb message structure
1089 ********************************************************************/
1090 void show_msg(char *buf
)
1098 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1100 (int)CVAL(buf
,smb_com
),
1101 (int)CVAL(buf
,smb_rcls
),
1102 (int)CVAL(buf
,smb_reh
),
1103 (int)SVAL(buf
,smb_err
),
1104 (int)CVAL(buf
,smb_flg
),
1105 (int)SVAL(buf
,smb_flg2
)));
1106 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1107 (int)SVAL(buf
,smb_tid
),
1108 (int)SVAL(buf
,smb_pid
),
1109 (int)SVAL(buf
,smb_uid
),
1110 (int)SVAL(buf
,smb_mid
),
1111 (int)CVAL(buf
,smb_wct
)));
1112 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
1113 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i
,
1114 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
1115 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
1116 DEBUG(5,("smb_bcc=%d\n",bcc
));
1117 if (DEBUGLEVEL
< 10)
1119 for (i
= 0; i
< MIN(bcc
, 256); i
+= 16)
1121 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1124 DEBUG(10,("%2X ",CVAL(smb_buf(buf
),i
+j
)));
1125 if (j
== 7) DEBUG(10, (" "));
1130 for (j
= 0; j
< 16 && i
+j
< MIN(bcc
,256); j
++)
1132 unsigned char c
= CVAL(smb_buf(buf
),i
+j
);
1133 if (c
< 32 || c
> 128) c
= '.';
1136 if (j
== 7) DEBUG(10, (" "));
1143 /*******************************************************************
1144 return the length of an smb packet
1145 ********************************************************************/
1146 int smb_len(char *buf
)
1148 return( PVAL(buf
,3) | (PVAL(buf
,2)<<8) | ((PVAL(buf
,1)&1)<<16) );
1151 /*******************************************************************
1152 set the length of an smb packet
1153 ********************************************************************/
1154 void _smb_setlen(char *buf
,int len
)
1157 buf
[1] = (len
&0x10000)>>16;
1158 buf
[2] = (len
&0xFF00)>>8;
1162 /*******************************************************************
1163 set the length and marker of an smb packet
1164 ********************************************************************/
1165 void smb_setlen(char *buf
,int len
)
1167 _smb_setlen(buf
,len
);
1175 /*******************************************************************
1176 setup the word count and byte count for a smb message
1177 ********************************************************************/
1178 int set_message(char *buf
,int num_words
,int num_bytes
,BOOL zero
)
1181 bzero(buf
+ smb_size
,num_words
*2 + num_bytes
);
1182 CVAL(buf
,smb_wct
) = num_words
;
1183 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1184 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1185 return (smb_size
+ num_words
*2 + num_bytes
);
1188 /*******************************************************************
1189 return the number of smb words
1190 ********************************************************************/
1191 int smb_numwords(char *buf
)
1193 return (CVAL(buf
,smb_wct
));
1196 /*******************************************************************
1197 return the size of the smb_buf region of a message
1198 ********************************************************************/
1199 int smb_buflen(char *buf
)
1201 return(SVAL(buf
,smb_vwv0
+ smb_numwords(buf
)*2));
1204 /*******************************************************************
1205 return a pointer to the smb_buf data area
1206 ********************************************************************/
1207 int smb_buf_ofs(char *buf
)
1209 return (smb_size
+ CVAL(buf
,smb_wct
)*2);
1212 /*******************************************************************
1213 return a pointer to the smb_buf data area
1214 ********************************************************************/
1215 char *smb_buf(char *buf
)
1217 return (buf
+ smb_buf_ofs(buf
));
1220 /*******************************************************************
1221 return the SMB offset into an SMB buffer
1222 ********************************************************************/
1223 int smb_offset(char *p
,char *buf
)
1225 return(PTR_DIFF(p
,buf
+4) + chain_size
);
1229 /*******************************************************************
1230 skip past some strings in a buffer
1231 ********************************************************************/
1232 char *skip_string(char *buf
,int n
)
1235 buf
+= strlen(buf
) + 1;
1239 /*******************************************************************
1240 trim the specified elements off the front and back of a string
1241 ********************************************************************/
1242 BOOL
trim_string(char *s
,char *front
,char *back
)
1245 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1251 if (!(*p
= p
[strlen(front
)]))
1256 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1257 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1260 s
[strlen(s
)-strlen(back
)] = 0;
1266 /*******************************************************************
1267 reduce a file name, removing .. elements.
1268 ********************************************************************/
1269 void dos_clean_name(char *s
)
1273 DEBUG(3,("dos_clean_name [%s]\n",s
));
1275 /* remove any double slashes */
1276 string_sub(s
, "\\\\", "\\");
1278 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1285 if ((p
=strrchr(s
,'\\')) != NULL
)
1292 trim_string(s
,NULL
,"\\..");
1294 string_sub(s
, "\\.\\", "\\");
1297 /*******************************************************************
1298 reduce a file name, removing .. elements.
1299 ********************************************************************/
1300 void unix_clean_name(char *s
)
1304 DEBUG(3,("unix_clean_name [%s]\n",s
));
1306 /* remove any double slashes */
1307 string_sub(s
, "//","/");
1309 /* Remove leading ./ characters */
1310 if(strncmp(s
, "./", 2) == 0) {
1311 trim_string(s
, "./", NULL
);
1316 while ((p
= strstr(s
,"/../")) != NULL
)
1323 if ((p
=strrchr(s
,'/')) != NULL
)
1330 trim_string(s
,NULL
,"/..");
1334 /*******************************************************************
1335 a wrapper for the normal chdir() function
1336 ********************************************************************/
1337 int ChDir(char *path
)
1340 static pstring LastDir
="";
1342 if (strcsequal(path
,".")) return(0);
1344 if (*path
== '/' && strcsequal(LastDir
,path
)) return(0);
1345 DEBUG(3,("chdir to %s\n",path
));
1346 res
= sys_chdir(path
);
1348 strcpy(LastDir
,path
);
1352 /* number of list structures for a caching GetWd function. */
1353 #define MAX_GETWDCACHE (50)
1361 } ino_list
[MAX_GETWDCACHE
];
1363 BOOL use_getwd_cache
=True
;
1365 /*******************************************************************
1366 return the absolute current directory path
1367 ********************************************************************/
1368 char *GetWd(char *str
)
1371 static BOOL getwd_cache_init
= False
;
1372 struct stat st
, st2
;
1377 if (!use_getwd_cache
)
1378 return(sys_getwd(str
));
1380 /* init the cache */
1381 if (!getwd_cache_init
)
1383 getwd_cache_init
= True
;
1384 for (i
=0;i
<MAX_GETWDCACHE
;i
++)
1386 string_init(&ino_list
[i
].text
,"");
1387 ino_list
[i
].valid
= False
;
1391 /* Get the inode of the current directory, if this doesn't work we're
1394 if (stat(".",&st
) == -1)
1396 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1397 return(sys_getwd(str
));
1401 for (i
=0; i
<MAX_GETWDCACHE
; i
++)
1402 if (ino_list
[i
].valid
)
1405 /* If we have found an entry with a matching inode and dev number
1406 then find the inode number for the directory in the cached string.
1407 If this agrees with that returned by the stat for the current
1408 directory then all is o.k. (but make sure it is a directory all
1411 if (st
.st_ino
== ino_list
[i
].inode
&&
1412 st
.st_dev
== ino_list
[i
].dev
)
1414 if (stat(ino_list
[i
].text
,&st2
) == 0)
1416 if (st
.st_ino
== st2
.st_ino
&&
1417 st
.st_dev
== st2
.st_dev
&&
1418 (st2
.st_mode
& S_IFMT
) == S_IFDIR
)
1420 strcpy (str
, ino_list
[i
].text
);
1422 /* promote it for future use */
1423 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1428 /* If the inode is different then something's changed,
1429 scrub the entry and start from scratch. */
1430 ino_list
[i
].valid
= False
;
1437 /* We don't have the information to hand so rely on traditional methods.
1438 The very slow getcwd, which spawns a process on some systems, or the
1439 not quite so bad getwd. */
1443 DEBUG(0,("Getwd failed, errno %d\n",errno
));
1449 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s
,(int)st
.st_ino
,(int)st
.st_dev
));
1451 /* add it to the cache */
1452 i
= MAX_GETWDCACHE
- 1;
1453 string_set(&ino_list
[i
].text
,s
);
1454 ino_list
[i
].dev
= st
.st_dev
;
1455 ino_list
[i
].inode
= st
.st_ino
;
1456 ino_list
[i
].valid
= True
;
1458 /* put it at the top of the list */
1459 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1466 /*******************************************************************
1467 reduce a file name, removing .. elements and checking that
1468 it is below dir in the heirachy. This uses GetWd() and so must be run
1469 on the system that has the referenced file system.
1471 widelinks are allowed if widelinks is true
1472 ********************************************************************/
1473 BOOL
reduce_name(char *s
,char *dir
,BOOL widelinks
)
1475 #ifndef REDUCE_PATHS
1483 BOOL relative
= (*s
!= '/');
1485 *dir2
= *wd
= *basename
= *newname
= 0;
1490 /* can't have a leading .. */
1491 if (strncmp(s
,"..",2) == 0 && (s
[2]==0 || s
[2]=='/'))
1493 DEBUG(3,("Illegal file name? (%s)\n",s
));
1503 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1505 /* remove any double slashes */
1506 string_sub(s
,"//","/");
1509 p
= strrchr(basename
,'/');
1516 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1520 if (ChDir(dir
) != 0)
1522 DEBUG(0,("couldn't chdir to %s\n",dir
));
1528 DEBUG(0,("couldn't getwd for %s\n",dir
));
1534 if (p
&& (p
!= basename
))
1537 if (strcmp(p
+1,".")==0)
1539 if (strcmp(p
+1,"..")==0)
1543 if (ChDir(basename
) != 0)
1546 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,basename
));
1550 if (!GetWd(newname
))
1553 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1557 if (p
&& (p
!= basename
))
1559 strcat(newname
,"/");
1560 strcat(newname
,p
+1);
1564 int l
= strlen(dir2
);
1565 if (dir2
[l
-1] == '/')
1568 if (strncmp(newname
,dir2
,l
) != 0)
1571 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1577 if (newname
[l
] == '/')
1578 strcpy(s
,newname
+ l
+ 1);
1580 strcpy(s
,newname
+l
);
1591 DEBUG(3,("reduced to %s\n",s
));
1596 /****************************************************************************
1598 ****************************************************************************/
1599 static void expand_one(char *Mask
,int len
)
1602 while ((p1
= strchr(Mask
,'*')) != NULL
)
1604 int lfill
= (len
+1) - strlen(Mask
);
1605 int l1
= (p1
- Mask
);
1608 memset(tmp
+l1
,'?',lfill
);
1609 strcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1614 /****************************************************************************
1615 expand a wildcard expression, replacing *s with ?s
1616 ****************************************************************************/
1617 void expand_mask(char *Mask
,BOOL doext
)
1622 BOOL hasdot
= False
;
1624 BOOL absolute
= (*Mask
== '\\');
1626 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
1628 /* parse the directory and filename */
1629 if (strchr(Mask
,'\\'))
1630 dirname_dos(Mask
,dirpart
);
1632 filename_dos(Mask
,filepart
);
1634 strcpy(mbeg
,filepart
);
1635 if ((p1
= strchr(mbeg
,'.')) != NULL
)
1645 if (strlen(mbeg
) > 8)
1647 strcpy(mext
,mbeg
+ 8);
1653 strcpy(mbeg
,"????????");
1654 if ((*mext
== 0) && doext
&& !hasdot
)
1657 if (strequal(mbeg
,"*") && *mext
==0)
1665 strcpy(Mask
,dirpart
);
1666 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
1671 DEBUG(6,("Mask expanded to [%s]\n",Mask
));
1675 /****************************************************************************
1676 does a string have any uppercase chars in it?
1677 ****************************************************************************/
1678 BOOL
strhasupper(char *s
)
1683 if (is_shift_jis (*s
)) {
1685 } else if (is_kana (*s
)) {
1688 if (isupper(*s
)) return(True
);
1692 if (isupper(*s
)) return(True
);
1699 /****************************************************************************
1700 does a string have any lowercase chars in it?
1701 ****************************************************************************/
1702 BOOL
strhaslower(char *s
)
1707 if (is_shift_jis (*s
)) {
1708 if (is_sj_upper (s
[0], s
[1])) return(True
);
1709 if (is_sj_lower (s
[0], s
[1])) return (True
);
1711 } else if (is_kana (*s
)) {
1714 if (islower(*s
)) return(True
);
1718 if (islower(*s
)) return(True
);
1725 /****************************************************************************
1726 find the number of chars in a string
1727 ****************************************************************************/
1728 int count_chars(char *s
,char c
)
1734 if (is_shift_jis (*s
))
1755 /****************************************************************************
1757 ****************************************************************************/
1758 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1765 if ((mode
& aDIR
) != 0)
1768 memset(buf
+1,' ',11);
1769 if ((p
= strchr(mask2
,'.')) != NULL
)
1772 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1773 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
1777 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),11));
1779 bzero(buf
+21,DIR_STRUCT_SIZE
-21);
1780 CVAL(buf
,21) = mode
;
1781 put_dos_date(buf
,22,date
);
1782 SSVAL(buf
,26,size
& 0xFFFF);
1783 SSVAL(buf
,28,size
>> 16);
1784 StrnCpy(buf
+30,fname
,12);
1785 if (!case_sensitive
)
1787 DEBUG(8,("put name [%s] into dir struct\n",buf
+30));
1791 /*******************************************************************
1792 close the low 3 fd's and open dev/null in their place
1793 ********************************************************************/
1794 void close_low_fds(void)
1798 close(0); close(1); close(2);
1799 /* try and use up these file descriptors, so silly
1800 library routines writing to stdout etc won't cause havoc */
1802 fd
= open("/dev/null",O_RDWR
,0);
1803 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
1805 DEBUG(0,("Can't open /dev/null\n"));
1809 DEBUG(0,("Didn't get file descriptor %d\n",i
));
1815 /****************************************************************************
1816 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1818 if SYSV use O_NDELAY
1820 ****************************************************************************/
1821 int set_blocking(int fd
, BOOL set
)
1825 #define FLAG_TO_SET O_NONBLOCK
1828 #define FLAG_TO_SET O_NDELAY
1830 #define FLAG_TO_SET FNDELAY
1834 if((val
= fcntl(fd
, F_GETFL
, 0)) == -1)
1836 if(set
) /* Turn blocking on - ie. clear nonblock flag */
1837 val
&= ~FLAG_TO_SET
;
1840 return fcntl( fd
, F_SETFL
, val
);
1845 /****************************************************************************
1847 ****************************************************************************/
1848 int write_socket(int fd
,char *buf
,int len
)
1854 DEBUG(6,("write_socket(%d,%d)\n",fd
,len
));
1855 ret
= write_data(fd
,buf
,len
);
1857 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,len
,ret
));
1861 /****************************************************************************
1863 ****************************************************************************/
1864 int read_udp_socket(int fd
,char *buf
,int len
)
1867 struct sockaddr sock
;
1870 socklen
= sizeof(sock
);
1871 bzero((char *)&sock
,socklen
);
1872 bzero((char *)&lastip
,sizeof(lastip
));
1873 ret
= recvfrom(fd
,buf
,len
,0,&sock
,&socklen
);
1875 DEBUG(2,("read socket failed. ERRNO=%d\n",errno
));
1879 lastip
= *(struct in_addr
*) &sock
.sa_data
[2];
1880 lastport
= ntohs(((struct sockaddr_in
*)&sock
)->sin_port
);
1885 /****************************************************************************
1886 read data from a device with a timout in msec.
1887 mincount = if timeout, minimum to read before returning
1888 maxcount = number to be read.
1889 ****************************************************************************/
1890 int read_with_timeout(int fd
,char *buf
,int mincnt
,int maxcnt
,long time_out
)
1896 struct timeval timeout
;
1898 /* just checking .... */
1899 if (maxcnt
<= 0) return(0);
1904 if (time_out
<= 0) {
1905 if (mincnt
== 0) mincnt
= maxcnt
;
1907 while (nread
< mincnt
) {
1908 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
1910 smb_read_error
= READ_EOF
;
1914 if (readret
== -1) {
1915 smb_read_error
= READ_ERROR
;
1923 /* Most difficult - timeout read */
1924 /* If this is ever called on a disk file and
1925 mincnt is greater then the filesize then
1926 system performance will suffer severely as
1927 select always return true on disk files */
1929 /* Set initial timeout */
1930 timeout
.tv_sec
= time_out
/ 1000;
1931 timeout
.tv_usec
= 1000 * (time_out
% 1000);
1933 for (nread
=0; nread
<mincnt
; )
1938 selrtn
= sys_select(&fds
,&timeout
);
1940 /* Check if error */
1942 /* something is wrong. Maybe the socket is dead? */
1943 smb_read_error
= READ_ERROR
;
1947 /* Did we timeout ? */
1949 smb_read_error
= READ_TIMEOUT
;
1953 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
1955 /* we got EOF on the file descriptor */
1956 smb_read_error
= READ_EOF
;
1960 if (readret
== -1) {
1961 /* the descriptor is probably dead */
1962 smb_read_error
= READ_ERROR
;
1969 /* Return the number we got */
1973 /****************************************************************************
1974 read data from the client. Maxtime is in milliseconds
1975 ****************************************************************************/
1976 int read_max_udp(int fd
,char *buffer
,int bufsize
,int maxtime
)
1981 struct timeval timeout
;
1986 timeout
.tv_sec
= maxtime
/ 1000;
1987 timeout
.tv_usec
= (maxtime
% 1000) * 1000;
1989 selrtn
= sys_select(&fds
,maxtime
>0?&timeout
:NULL
);
1991 if (!FD_ISSET(fd
,&fds
))
1994 nread
= read_udp_socket(fd
, buffer
, bufsize
);
1996 /* return the number got */
2000 /*******************************************************************
2001 find the difference in milliseconds between two struct timeval
2003 ********************************************************************/
2004 int TvalDiff(struct timeval
*tvalold
,struct timeval
*tvalnew
)
2006 return((tvalnew
->tv_sec
- tvalold
->tv_sec
)*1000 +
2007 ((int)tvalnew
->tv_usec
- (int)tvalold
->tv_usec
)/1000);
2010 /****************************************************************************
2011 send a keepalive packet (rfc1002)
2012 ****************************************************************************/
2013 BOOL
send_keepalive(int client
)
2015 unsigned char buf
[4];
2018 buf
[1] = buf
[2] = buf
[3] = 0;
2020 return(write_data(client
,(char *)buf
,4) == 4);
2025 /****************************************************************************
2026 read data from the client, reading exactly N bytes.
2027 ****************************************************************************/
2028 int read_data(int fd
,char *buffer
,int N
)
2037 ret
= read(fd
,buffer
+ total
,N
- total
);
2039 smb_read_error
= READ_EOF
;
2043 smb_read_error
= READ_ERROR
;
2052 /****************************************************************************
2054 ****************************************************************************/
2055 int write_data(int fd
,char *buffer
,int N
)
2062 ret
= write(fd
,buffer
+ total
,N
- total
);
2064 if (ret
== -1) return -1;
2065 if (ret
== 0) return total
;
2073 /****************************************************************************
2074 transfer some data between two fd's
2075 ****************************************************************************/
2076 int transfer_file(int infd
,int outfd
,int n
,char *header
,int headlen
,int align
)
2078 static char *buf
=NULL
;
2083 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
2086 size
= lp_readsize();
2087 size
= MAX(size
,1024);
2090 while (!buf
&& size
>0) {
2091 buf
= (char *)Realloc(buf
,size
+8);
2092 if (!buf
) size
/= 2;
2096 DEBUG(0,("Can't allocate transfer buffer!\n"));
2100 abuf
= buf
+ (align
%8);
2107 int s
= MIN(n
,size
);
2112 if (header
&& (headlen
>= MIN(s
,1024))) {
2122 if (header
&& headlen
> 0)
2124 ret
= MIN(headlen
,size
);
2125 memcpy(buf1
,header
,ret
);
2128 if (headlen
<= 0) header
= NULL
;
2132 ret
+= read(infd
,buf1
+ret
,s
-ret
);
2136 ret2
= (outfd
>=0?write_data(outfd
,buf1
,ret
):ret
);
2137 if (ret2
> 0) total
+= ret2
;
2138 /* if we can't write then dump excess data */
2140 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
2142 if (ret
<= 0 || ret2
!= ret
)
2150 /****************************************************************************
2151 read 4 bytes of a smb packet and return the smb length of the packet
2152 possibly store the result in the buffer
2153 ****************************************************************************/
2154 int read_smb_length(int fd
,char *inbuf
,int timeout
)
2158 int len
=0, msg_type
;
2169 ok
= (read_with_timeout(fd
,buffer
,4,4,timeout
) == 4);
2171 ok
= (read_data(fd
,buffer
,4) == 4);
2176 len
= smb_len(buffer
);
2177 msg_type
= CVAL(buffer
,0);
2179 if (msg_type
== 0x85)
2181 DEBUG(5,("Got keepalive packet\n"));
2186 DEBUG(10,("got smb length of %d\n",len
));
2193 /****************************************************************************
2194 read an smb from a fd and return it's length
2195 The timeout is in milli seconds
2196 ****************************************************************************/
2197 BOOL
receive_smb(int fd
,char *buffer
,int timeout
)
2203 bzero(buffer
,smb_size
+ 100);
2205 len
= read_smb_length(fd
,buffer
,timeout
);
2209 if (len
> BUFFER_SIZE
) {
2210 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2211 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2215 ret
= read_data(fd
,buffer
+4,len
);
2217 smb_read_error
= READ_ERROR
;
2225 /****************************************************************************
2227 ****************************************************************************/
2228 BOOL
send_smb(int fd
,char *buffer
)
2232 len
= smb_len(buffer
) + 4;
2234 while (nwritten
< len
)
2236 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2239 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
2251 /****************************************************************************
2252 find a pointer to a netbios name
2253 ****************************************************************************/
2254 char *name_ptr(char *buf
,int ofs
)
2256 unsigned char c
= *(unsigned char *)(buf
+ofs
);
2258 if ((c
& 0xC0) == 0xC0)
2262 memcpy(p
,buf
+ofs
,2);
2265 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
2272 /****************************************************************************
2273 extract a netbios name from a buf
2274 ****************************************************************************/
2275 int name_extract(char *buf
,int ofs
,char *name
)
2277 char *p
= name_ptr(buf
,ofs
);
2278 int d
= PTR_DIFF(p
,buf
+ofs
);
2280 if (d
< -50 || d
> 50) return(0);
2281 return(name_interpret(p
,name
));
2285 /****************************************************************************
2286 return the total storage length of a mangled name
2287 ****************************************************************************/
2288 int name_len(char *s
)
2291 unsigned char c
= *(unsigned char *)s
;
2292 if ((c
& 0xC0) == 0xC0)
2294 while (*s
) s
+= (*s
)+1;
2295 return(PTR_DIFF(s
,s0
)+1);
2298 /****************************************************************************
2299 send a single packet to a port on another machine
2300 ****************************************************************************/
2301 BOOL
send_one_packet(char *buf
,int len
,struct in_addr ip
,int port
,int type
)
2305 struct sockaddr_in sock_out
;
2310 /* create a socket to write to */
2311 out_fd
= socket(AF_INET
, type
, 0);
2314 DEBUG(0,("socket failed"));
2318 /* set the address and port */
2319 bzero((char *)&sock_out
,sizeof(sock_out
));
2320 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
2321 sock_out
.sin_port
= htons( port
);
2322 sock_out
.sin_family
= AF_INET
;
2325 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2326 len
,inet_ntoa(ip
),port
,type
==SOCK_DGRAM
?"DGRAM":"STREAM"));
2329 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2332 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2333 inet_ntoa(ip
),port
,errno
));
2339 /*******************************************************************
2340 sleep for a specified number of milliseconds
2341 ********************************************************************/
2345 struct timeval tval
,t1
,t2
;
2352 tval
.tv_sec
= (t
-tdiff
)/1000;
2353 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2357 sys_select(&fds
,&tval
);
2360 tdiff
= TvalDiff(&t1
,&t2
);
2364 /****************************************************************************
2365 check if a string is part of a list
2366 ****************************************************************************/
2367 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
2372 if (!list
) return(False
);
2374 while (next_token(&p
,tok
,LIST_SEP
))
2376 if (casesensitive
) {
2377 if (strcmp(tok
,s
) == 0)
2380 if (StrCaseCmp(tok
,s
) == 0)
2387 /* this is used to prevent lots of mallocs of size 1 */
2388 static char *null_string
= NULL
;
2390 /****************************************************************************
2391 set a string value, allocing the space for the string
2392 ****************************************************************************/
2393 BOOL
string_init(char **dest
,char *src
)
2404 null_string
= (char *)malloc(1);
2407 *dest
= null_string
;
2411 *dest
= (char *)malloc(l
+1);
2417 /****************************************************************************
2419 ****************************************************************************/
2420 void string_free(char **s
)
2422 if (!s
|| !(*s
)) return;
2423 if (*s
== null_string
)
2429 /****************************************************************************
2430 set a string value, allocing the space for the string, and deallocating any
2432 ****************************************************************************/
2433 BOOL
string_set(char **dest
,char *src
)
2437 return(string_init(dest
,src
));
2440 /****************************************************************************
2441 substitute a string for a pattern in another string. Make sure there is
2444 This routine looks for pattern in s and replaces it with
2445 insert. It may do multiple replacements.
2447 return True if a substitution was done.
2448 ****************************************************************************/
2449 BOOL
string_sub(char *s
,char *pattern
,char *insert
)
2455 if (!insert
|| !pattern
|| !s
) return(False
);
2458 lp
= strlen(pattern
);
2459 li
= strlen(insert
);
2461 if (!*pattern
) return(False
);
2463 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2466 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2467 memcpy(p
,insert
,li
);
2476 /*********************************************************
2477 * Recursive routine that is called by mask_match.
2478 * Does the actual matching.
2479 *********************************************************/
2480 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
2484 for( p
= regexp
; *p
&& *str
; ) {
2491 /* Look for a character matching
2492 the one after the '*' */
2495 return True
; /* Automatic match */
2497 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2499 if(do_match(str
,p
,case_sig
))
2513 if(toupper(*str
) != toupper(*p
))
2523 if (!*p
&& str
[0] == '.' && str
[1] == 0)
2526 if (!*str
&& *p
== '?')
2528 while (*p
== '?') p
++;
2532 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
2538 /*********************************************************
2539 * Routine to match a given string with a regexp - uses
2540 * simplified regexp that takes * and ? only. Case can be
2541 * significant or not.
2542 *********************************************************/
2543 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
2547 fstring ebase
,eext
,sbase
,sext
;
2551 /* Make local copies of str and regexp */
2552 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
2553 StrnCpy(p2
,str
,sizeof(pstring
)-1);
2555 if (!strchr(p2
,'.')) {
2560 if (!strchr(p1,'.')) {
2568 string_sub(p1
,"*.*","*");
2569 string_sub(p1
,".*","*");
2573 /* Remove any *? and ** as they are meaningless */
2574 for(p
= p1
; *p
; p
++)
2575 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
2576 (void)strcpy( &p
[1], &p
[2]);
2578 if (strequal(p1
,"*")) return(True
);
2580 DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
2586 if ((p
=strrchr(p1
,'.'))) {
2595 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
2605 matched
= do_match(sbase
,ebase
,case_sig
) &&
2606 (trans2
|| do_match(sext
,eext
,case_sig
));
2608 DEBUG(5,("mask_match returning %d\n", matched
));
2615 /****************************************************************************
2616 become a daemon, discarding the controlling terminal
2617 ****************************************************************************/
2618 void become_daemon(void)
2620 #ifndef NO_FORK_DEBUG
2624 /* detach from the terminal */
2627 #else /* USE_SETSID */
2630 int i
= open("/dev/tty", O_RDWR
);
2633 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
2637 #endif /* TIOCNOTTY */
2638 #endif /* USE_SETSID */
2639 /* Close fd's 0,1,2. Needed if started by rsh */
2641 #endif /* NO_FORK_DEBUG */
2645 /****************************************************************************
2646 put up a yes/no prompt
2647 ****************************************************************************/
2653 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
2656 if (*ans
== 'y' || *ans
== 'Y')
2662 /****************************************************************************
2663 read a line from a file with possible \ continuation chars.
2664 Blanks at the start or end of a line are stripped.
2665 The string will be allocated if s2 is NULL
2666 ****************************************************************************/
2667 char *fgets_slash(char *s2
,int maxlen
,FILE *f
)
2672 BOOL start_of_line
= True
;
2679 maxlen
= MIN(maxlen
,8);
2680 s
= (char *)Realloc(s
,maxlen
);
2683 if (!s
|| maxlen
< 2) return(NULL
);
2687 while (len
< maxlen
-1)
2695 while (len
> 0 && s
[len
-1] == ' ')
2699 if (len
> 0 && s
[len
-1] == '\\')
2702 start_of_line
= True
;
2707 if (len
<= 0 && !s2
)
2709 return(len
>0?s
:NULL
);
2714 start_of_line
= False
;
2718 if (!s2
&& len
> maxlen
-3)
2721 s
= (char *)Realloc(s
,maxlen
);
2722 if (!s
) return(NULL
);
2730 /****************************************************************************
2731 set the length of a file from a filedescriptor.
2732 Returns 0 on success, -1 on failure.
2733 ****************************************************************************/
2734 int set_filelen(int fd
, long len
)
2736 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2737 extend a file with ftruncate. Provide alternate implementation
2740 #if FTRUNCATE_CAN_EXTEND
2741 return ftruncate(fd
, len
);
2745 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
2749 /* Do an fstat to see if the file is longer than
2750 the requested size (call ftruncate),
2751 or shorter, in which case seek to len - 1 and write 1
2753 if(fstat(fd
, &st
)<0)
2757 if (S_ISFIFO(st
.st_mode
)) return 0;
2760 if(st
.st_size
== len
)
2762 if(st
.st_size
> len
)
2763 return ftruncate(fd
, len
);
2765 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
2767 if(write(fd
, &c
, 1)!=1)
2769 /* Seek to where we were */
2770 lseek(fd
, currpos
, SEEK_SET
);
2776 /****************************************************************************
2777 return the byte checksum of some data
2778 ****************************************************************************/
2779 int byte_checksum(char *buf
,int len
)
2781 unsigned char *p
= (unsigned char *)buf
;
2791 /****************************************************************************
2792 this is a version of setbuffer() for those machines that only have setvbuf
2793 ****************************************************************************/
2794 void setbuffer(FILE *f
,char *buf
,int bufsize
)
2796 setvbuf(f
,buf
,_IOFBF
,bufsize
);
2801 /****************************************************************************
2802 parse out a directory name from a path name. Assumes dos style filenames.
2803 ****************************************************************************/
2804 char *dirname_dos(char *path
,char *buf
)
2806 char *p
= strrchr(path
,'\\');
2821 /****************************************************************************
2822 parse out a filename from a path name. Assumes dos style filenames.
2823 ****************************************************************************/
2824 static char *filename_dos(char *path
,char *buf
)
2826 char *p
= strrchr(path
,'\\');
2838 /****************************************************************************
2839 expand a pointer to be a particular size
2840 ****************************************************************************/
2841 void *Realloc(void *p
,int size
)
2847 DEBUG(5,("Realloc asked for 0 bytes\n"));
2852 ret
= (void *)malloc(size
);
2854 ret
= (void *)realloc(p
,size
);
2857 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
2863 /****************************************************************************
2865 ****************************************************************************/
2866 char *strdup(char *s
)
2869 if (!s
) return(NULL
);
2870 ret
= (char *)malloc(strlen(s
)+1);
2871 if (!ret
) return(NULL
);
2878 /****************************************************************************
2879 Signal handler for SIGPIPE (write on a disconnected socket)
2880 ****************************************************************************/
2883 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
2887 /****************************************************************************
2888 get my own name and IP
2889 ****************************************************************************/
2890 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
2897 /* get my host name */
2898 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
2900 DEBUG(0,("gethostname failed\n"));
2905 if ((hp
= Get_Hostbyname(hostname
)) == 0)
2907 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
2913 /* split off any parts after an initial . */
2914 char *p
= strchr(hostname
,'.');
2917 strcpy(my_name
,hostname
);
2921 putip((char *)ip
,(char *)hp
->h_addr
);
2927 /****************************************************************************
2928 true if two IP addresses are equal
2929 ****************************************************************************/
2930 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
2933 a1
= ntohl(ip1
.s_addr
);
2934 a2
= ntohl(ip2
.s_addr
);
2939 /****************************************************************************
2940 open a socket of the specified type, port and address for incoming data
2941 ****************************************************************************/
2942 int open_socket_in(int type
, int port
, int dlevel
,uint32 socket_addr
)
2945 struct sockaddr_in sock
;
2949 /* get my host name */
2950 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
2951 { DEBUG(0,("gethostname failed\n")); return -1; }
2954 if ((hp
= Get_Hostbyname(host_name
)) == 0)
2956 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
2960 bzero((char *)&sock
,sizeof(sock
));
2961 memcpy((char *)&sock
.sin_addr
,(char *)hp
->h_addr
, hp
->h_length
);
2962 #if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
2963 sock
.sin_len
= sizeof(sock
);
2965 sock
.sin_port
= htons( port
);
2966 sock
.sin_family
= hp
->h_addrtype
;
2967 sock
.sin_addr
.s_addr
= socket_addr
;
2968 res
= socket(hp
->h_addrtype
, type
, 0);
2970 { DEBUG(0,("socket failed\n")); return -1; }
2974 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
2977 /* now we've got a socket - we need to bind it */
2978 if (bind(res
, (struct sockaddr
* ) &sock
,sizeof(sock
)) < 0)
2981 if (port
== SMB_PORT
|| port
== NMB_PORT
)
2982 DEBUG(dlevel
,("bind failed on port %d socket_addr=%x (%s)\n",
2983 port
,socket_addr
,strerror(errno
)));
2986 if (dlevel
> 0 && port
< 1000)
2989 if (port
>= 1000 && port
< 9000)
2990 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
2995 DEBUG(3,("bind succeeded on port %d\n",port
));
3001 /****************************************************************************
3002 create an outgoing socket
3003 **************************************************************************/
3004 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
3006 struct sockaddr_in sock_out
;
3008 int connect_loop
= 250; /* 250 milliseconds */
3009 int loops
= (timeout
* 1000) / connect_loop
;
3011 /* create a socket to write to */
3012 res
= socket(PF_INET
, type
, 0);
3014 { DEBUG(0,("socket error\n")); return -1; }
3016 if (type
!= SOCK_STREAM
) return(res
);
3018 bzero((char *)&sock_out
,sizeof(sock_out
));
3019 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
3021 sock_out
.sin_port
= htons( port
);
3022 sock_out
.sin_family
= PF_INET
;
3024 /* set it non-blocking */
3025 set_blocking(res
,False
);
3027 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
3029 /* and connect it to the destination */
3031 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
3033 /* Some systems return EAGAIN when they mean EINPROGRESS */
3034 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
3035 errno
== EAGAIN
) && loops
--) {
3036 msleep(connect_loop
);
3040 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
3042 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
3048 if (ret
< 0 && errno
== EISCONN
) {
3055 DEBUG(1,("error connecting to %s:%d (%s)\n",
3056 inet_ntoa(*addr
),port
,strerror(errno
)));
3060 /* set it blocking again */
3061 set_blocking(res
,True
);
3067 /****************************************************************************
3068 interpret a protocol description string, with a default
3069 ****************************************************************************/
3070 int interpret_protocol(char *str
,int def
)
3072 if (strequal(str
,"NT1"))
3073 return(PROTOCOL_NT1
);
3074 if (strequal(str
,"LANMAN2"))
3075 return(PROTOCOL_LANMAN2
);
3076 if (strequal(str
,"LANMAN1"))
3077 return(PROTOCOL_LANMAN1
);
3078 if (strequal(str
,"CORE"))
3079 return(PROTOCOL_CORE
);
3080 if (strequal(str
,"COREPLUS"))
3081 return(PROTOCOL_COREPLUS
);
3082 if (strequal(str
,"CORE+"))
3083 return(PROTOCOL_COREPLUS
);
3085 DEBUG(0,("Unrecognised protocol level %s\n",str
));
3090 /****************************************************************************
3091 interpret a security level
3092 ****************************************************************************/
3093 int interpret_security(char *str
,int def
)
3095 if (strequal(str
,"SERVER"))
3097 if (strequal(str
,"USER"))
3099 if (strequal(str
,"SHARE"))
3102 DEBUG(0,("Unrecognised security level %s\n",str
));
3108 /****************************************************************************
3109 interpret an internet address or name into an IP address in 4 byte form
3110 ****************************************************************************/
3111 uint32
interpret_addr(char *str
)
3116 BOOL pure_address
= True
;
3118 if (strcmp(str
,"0.0.0.0") == 0) return(0);
3119 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
3121 for (i
=0; pure_address
&& str
[i
]; i
++)
3122 if (!(isdigit(str
[i
]) || str
[i
] == '.'))
3123 pure_address
= False
;
3125 /* if it's in the form of an IP address then get the lib to interpret it */
3127 res
= inet_addr(str
);
3129 /* otherwise assume it's a network name of some sort and use
3131 if ((hp
= Get_Hostbyname(str
)) == 0) {
3132 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
3135 putip((char *)&res
,(char *)hp
->h_addr
);
3138 if (res
== (uint32
)-1) return(0);
3143 /*******************************************************************
3144 a convenient addition to interpret_addr()
3145 ******************************************************************/
3146 struct in_addr
*interpret_addr2(char *str
)
3148 static struct in_addr ret
;
3149 uint32 a
= interpret_addr(str
);
3154 /*******************************************************************
3155 check if an IP is the 0.0.0.0
3156 ******************************************************************/
3157 BOOL
zero_ip(struct in_addr ip
)
3160 putip((char *)&a
,(char *)&ip
);
3165 /*******************************************************************
3166 matchname - determine if host name matches IP address
3167 ******************************************************************/
3168 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
3173 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
3174 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost
));
3179 * Make sure that gethostbyname() returns the "correct" host name.
3180 * Unfortunately, gethostbyname("localhost") sometimes yields
3181 * "localhost.domain". Since the latter host name comes from the
3182 * local DNS, we just have to trust it (all bets are off if the local
3183 * DNS is perverted). We always check the address list, though.
3186 if (strcasecmp(remotehost
, hp
->h_name
)
3187 && strcasecmp(remotehost
, "localhost")) {
3188 DEBUG(0,("host name/name mismatch: %s != %s",
3189 remotehost
, hp
->h_name
));
3193 /* Look up the host address in the address list we just got. */
3194 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
3195 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
3200 * The host name does not map to the original host address. Perhaps
3201 * someone has compromised a name server. More likely someone botched
3202 * it, but that could be dangerous, too.
3205 DEBUG(0,("host name/address mismatch: %s != %s",
3206 inet_ntoa(addr
), hp
->h_name
));
3210 /*******************************************************************
3211 Reset the 'done' variables so after a client process is created
3212 from a fork call these calls will be re-done. This should be
3213 expanded if more variables need reseting.
3214 ******************************************************************/
3216 static BOOL global_client_name_done
= False
;
3217 static BOOL global_client_addr_done
= False
;
3219 void reset_globals_after_fork()
3221 global_client_name_done
= False
;
3222 global_client_addr_done
= False
;
3225 /*******************************************************************
3226 return the DNS name of the client
3227 ******************************************************************/
3228 char *client_name(void)
3232 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3233 int length
= sizeof(sa
);
3234 static pstring name_buf
;
3237 if (global_client_name_done
)
3240 strcpy(name_buf
,"UNKNOWN");
3242 if (getpeername(Client
, &sa
, &length
) < 0) {
3243 DEBUG(0,("getpeername failed\n"));
3247 /* Look up the remote host name. */
3248 if ((hp
= gethostbyaddr((char *) &sockin
->sin_addr
,
3249 sizeof(sockin
->sin_addr
),
3251 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
3252 StrnCpy(name_buf
,client_addr(),sizeof(name_buf
) - 1);
3254 StrnCpy(name_buf
,(char *)hp
->h_name
,sizeof(name_buf
) - 1);
3255 if (!matchname(name_buf
, sockin
->sin_addr
)) {
3256 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,client_addr()));
3257 strcpy(name_buf
,"UNKNOWN");
3260 global_client_name_done
= True
;
3264 /*******************************************************************
3265 return the IP addr of the client as a string
3266 ******************************************************************/
3267 char *client_addr(void)
3271 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3272 int length
= sizeof(sa
);
3273 static fstring addr_buf
;
3275 if (global_client_addr_done
)
3278 strcpy(addr_buf
,"0.0.0.0");
3280 if (getpeername(Client
, &sa
, &length
) < 0) {
3281 DEBUG(0,("getpeername failed\n"));
3285 strcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
3287 global_client_addr_done
= True
;
3291 /*******************************************************************
3292 sub strings with useful parameters
3293 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3294 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3295 ********************************************************************/
3296 void standard_sub_basic(char *string
)
3300 struct passwd
*pass
;
3302 for (s
= string
; (p
= strchr(s
,'%')) != NULL
; s
= p
)
3306 case 'G' : if ((pass
= Get_Pwnam(sesssetup_user
,False
))!=NULL
)
3307 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
3311 case 'I' : string_sub(p
,"%I",client_addr()); break;
3312 case 'L' : string_sub(p
,"%L",local_machine
); break;
3313 case 'M' : string_sub(p
,"%M",client_name()); break;
3314 case 'R' : string_sub(p
,"%R",remote_proto
); break;
3315 case 'T' : string_sub(p
,"%T",timestring()); break;
3316 case 'U' : string_sub(p
,"%U",sesssetup_user
); break;
3317 case 'a' : string_sub(p
,"%a",remote_arch
); break;
3318 case 'd' : sprintf(pidstr
,"%d",(int)getpid());
3319 string_sub(p
,"%d",pidstr
);
3321 case 'h' : string_sub(p
,"%h",myhostname
); break;
3322 case 'm' : string_sub(p
,"%m",remote_machine
); break;
3323 case 'v' : string_sub(p
,"%v",VERSION
); break;
3324 case '\0' : p
++; break; /* don't run off end if last character is % */
3325 default : p
+=2; break;
3331 /*******************************************************************
3332 are two IPs on the same subnet?
3333 ********************************************************************/
3334 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
3336 uint32 net1
,net2
,nmask
;
3338 nmask
= ntohl(mask
.s_addr
);
3339 net1
= ntohl(ip1
.s_addr
);
3340 net2
= ntohl(ip2
.s_addr
);
3342 return((net1
& nmask
) == (net2
& nmask
));
3346 /*******************************************************************
3347 write a string in unicoode format
3348 ********************************************************************/
3349 int PutUniCode(char *dst
,char *src
)
3353 dst
[ret
++] = src
[0];
3362 /****************************************************************************
3363 a wrapper for gethostbyname() that tries with all lower and all upper case
3364 if the initial name fails
3365 ****************************************************************************/
3366 struct hostent
*Get_Hostbyname(char *name
)
3368 char *name2
= strdup(name
);
3369 struct hostent
*ret
;
3373 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3377 if (!isalnum(*name2
))
3383 ret
= sys_gethostbyname(name2
);
3390 /* try with all lowercase */
3392 ret
= sys_gethostbyname(name2
);
3399 /* try with all uppercase */
3401 ret
= sys_gethostbyname(name2
);
3408 /* nothing works :-( */
3414 /****************************************************************************
3415 check if a process exists. Does this work on all unixes?
3416 ****************************************************************************/
3417 BOOL
process_exists(int pid
)
3421 sprintf(s
,"/proc/%d",pid
);
3422 return(directory_exist(s
,NULL
));
3425 static BOOL tested
=False
;
3426 static BOOL ok
=False
;
3430 sprintf(s
,"/proc/%05d",(int)getpid());
3431 ok
= file_exist(s
,NULL
);
3434 sprintf(s
,"/proc/%05d",pid
);
3435 return(file_exist(s
,NULL
));
3439 /* CGH 8/16/96 - added ESRCH test */
3440 return(pid
== getpid() || kill(pid
,0) == 0 || errno
!= ESRCH
);
3445 /*******************************************************************
3446 turn a uid into a user name
3447 ********************************************************************/
3448 char *uidtoname(int uid
)
3450 static char name
[40];
3451 struct passwd
*pass
= getpwuid(uid
);
3452 if (pass
) return(pass
->pw_name
);
3453 sprintf(name
,"%d",uid
);
3457 /*******************************************************************
3458 turn a gid into a group name
3459 ********************************************************************/
3460 char *gidtoname(int gid
)
3462 static char name
[40];
3463 struct group
*grp
= getgrgid(gid
);
3464 if (grp
) return(grp
->gr_name
);
3465 sprintf(name
,"%d",gid
);
3469 /*******************************************************************
3471 ********************************************************************/
3472 void BlockSignals(BOOL block
,int signum
)
3475 int block_mask
= sigmask(signum
);
3476 static int oldmask
= 0;
3478 oldmask
= sigblock(block_mask
);
3480 sigsetmask(oldmask
);
3481 #elif defined(USE_SIGPROCMASK)
3484 sigaddset(&set
,signum
);
3485 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
3490 /*******************************************************************
3491 my own panic function - not suitable for general use
3492 ********************************************************************/
3493 void ajt_panic(void)
3495 system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
3500 #define DIRECT direct
3502 #define DIRECT dirent
3505 /*******************************************************************
3506 a readdir wrapper which just returns the file name
3507 also return the inode number if requested
3508 ********************************************************************/
3509 char *readdirname(void *p
)
3514 if (!p
) return(NULL
);
3516 ptr
= (struct DIRECT
*)readdir(p
);
3517 if (!ptr
) return(NULL
);
3519 dname
= ptr
->d_name
;
3522 if (telldir(p
) < 0) return(NULL
);
3526 /* this handles a broken compiler setup, causing a mixture
3527 of BSD and SYSV headers and libraries */
3529 static BOOL broken_readdir
= False
;
3530 if (!broken_readdir
&& !(*(dname
)) && strequal("..",dname
-2))
3532 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
3533 broken_readdir
= True
;
3543 unix_to_dos(buf
, True
);
3551 * Utility function used to decide if the last component
3552 * of a path matches a (possibly wildcarded) entry in a namelist.
3555 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
3557 pstring last_component
;
3560 DEBUG(5, ("is_in_path: %s\n", name
));
3562 /* if we have no list it's obviously not in the path */
3563 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
3565 DEBUG(5,("is_in_path: no name list.\n"));
3569 /* Get the last component of the unix name. */
3570 p
= strrchr(name
, '/');
3571 strncpy(last_component
, p
? p
: name
, sizeof(last_component
)-1);
3572 last_component
[sizeof(last_component
)-1] = '\0';
3574 for(; namelist
->name
!= NULL
; namelist
++)
3576 if(namelist
->is_wild
)
3578 /* look for a wildcard match. */
3579 if (mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
3581 DEBUG(5,("is_in_path: mask match succeeded\n"));
3587 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
3588 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
3590 DEBUG(5,("is_in_path: match succeeded\n"));
3595 DEBUG(5,("is_in_path: match not found\n"));
3601 * Strip a '/' separated list into an array of
3602 * name_compare_enties structures suitable for
3603 * passing to is_in_path(). We do this for
3604 * speed so we can pre-parse all the names in the list
3605 * and don't do it for each call to is_in_path().
3606 * namelist is modified here and is assumed to be
3607 * a copy owned by the caller.
3608 * We also check if the entry contains a wildcard to
3609 * remove a potentially expensive call to mask_match
3613 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
3616 char *nameptr
= namelist
;
3617 int num_entries
= 0;
3620 (*ppname_array
) = NULL
;
3622 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
3625 /* We need to make two passes over the string. The
3626 first to count the number of elements, the second
3631 if ( *nameptr
== '/' )
3633 /* cope with multiple (useless) /s) */
3637 /* find the next / */
3638 name_end
= strchr(nameptr
, '/');
3640 /* oops - the last check for a / didn't find one. */
3641 if (name_end
== NULL
)
3644 /* next segment please */
3645 nameptr
= name_end
+ 1;
3649 if(num_entries
== 0)
3652 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
3653 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
3655 DEBUG(0,("set_namearray: malloc fail\n"));
3659 /* Now copy out the names */
3664 if ( *nameptr
== '/' )
3666 /* cope with multiple (useless) /s) */
3670 /* find the next / */
3671 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
3676 /* oops - the last check for a / didn't find one. */
3677 if (name_end
== NULL
)
3680 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
3681 (strchr( nameptr
, '*')!=NULL
));
3682 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
3684 DEBUG(0,("set_namearray: malloc fail (1)\n"));
3688 /* next segment please */
3689 nameptr
= name_end
+ 1;
3693 (*ppname_array
)[i
].name
= NULL
;
3698 /****************************************************************************
3699 routine to free a namearray.
3700 ****************************************************************************/
3702 void free_namearray(name_compare_entry
*name_array
)
3707 if(name_array
->name
!= NULL
)
3708 free(name_array
->name
);
3710 free((char *)name_array
);
3713 /****************************************************************************
3714 routine to do file locking
3715 ****************************************************************************/
3716 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
3723 uint32 mask
= 0xC0000000;
3725 /* make sure the count is reasonable, we might kill the lockd otherwise */
3728 /* the offset is often strange - remove 2 of its bits if either of
3729 the top two bits are set. Shift the top ones by two bits. This
3730 still allows OLE2 apps to operate, but should stop lockd from
3732 if ((offset
& mask
) != 0)
3733 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
3735 uint32 mask
= ((unsigned)1<<31);
3737 /* interpret negative counts as large numbers */
3741 /* no negative offsets */
3744 /* count + offset must be in range */
3745 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
3753 DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
3756 lock
.l_whence
= SEEK_SET
;
3757 lock
.l_start
= (int)offset
;
3758 lock
.l_len
= (int)count
;
3763 ret
= fcntl(fd
,op
,&lock
);
3766 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
3772 (lock
.l_type
!= F_UNLCK
) &&
3773 (lock
.l_pid
!= 0) &&
3774 (lock
.l_pid
!= getpid()))
3776 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
3780 /* it must be not locked or locked by me */
3784 /* a lock set or unset */
3787 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
3788 offset
,count
,op
,type
,strerror(errno
)));
3790 /* perhaps it doesn't support this sort of locking?? */
3791 if (errno
== EINVAL
)
3793 DEBUG(3,("locking not supported? returning True\n"));
3800 /* everything went OK */
3801 DEBUG(5,("Lock call successful\n"));
3809 /*******************************************************************
3810 lock a file - returning a open file descriptor or -1 on failure
3811 The timeout is in seconds. 0 means no timeout
3812 ********************************************************************/
3813 int file_lock(char *name
,int timeout
)
3815 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
3817 if (fd
< 0) return(-1);
3820 if (timeout
) t
= time(NULL
);
3821 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
3822 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
3823 msleep(LOCK_RETRY_TIMEOUT
);
3831 /*******************************************************************
3832 unlock a file locked by file_lock
3833 ********************************************************************/
3834 void file_unlock(int fd
)
3838 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
3843 /*******************************************************************
3844 is the name specified one of my netbios names
3845 returns true is it is equal, false otherwise
3846 ********************************************************************/
3847 BOOL
is_myname(const char *s
)
3852 for (n
=0; my_netbios_names
[n
]; n
++) {
3853 if (strequal(my_netbios_names
[n
], s
))
3856 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));