2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
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.
24 #if (defined(NETGROUP) && defined (AUTOMOUNT))
25 #include "rpcsvc/ypclnt.h"
34 int Protocol
= PROTOCOL_COREPLUS
;
36 /* a default finfo structure to ensure all fields are sensible */
37 file_info def_finfo
= {-1,0,0,0,0,0,0,""};
39 /* these are some file handles where debug info will be stored */
42 /* the client file descriptor */
45 /* the last IP received from */
46 struct in_addr lastip
;
48 /* the last port received from */
51 /* this is used by the chaining code */
57 case handling on filenames
59 int case_default
= CASE_LOWER
;
64 /* the following control case operations - they are put here so the
65 client can link easily */
68 BOOL use_mangled_map
= False
;
69 BOOL short_case_preserve
;
72 fstring remote_machine
="";
73 fstring local_machine
="";
74 fstring remote_arch
="UNKNOWN";
75 static enum remote_arch_types ra_type
= RA_UNKNOWN
;
76 fstring remote_proto
="UNKNOWN";
77 pstring myhostname
="";
78 pstring user_socket_options
="";
80 pstring sesssetup_user
="";
81 pstring samlogon_user
="";
83 BOOL sam_logon_in_ssb
= False
;
86 fstring myworkgroup
= "";
87 char **my_netbios_names
;
89 int smb_read_error
= 0;
91 static BOOL stdout_logging
= False
;
93 static char *filename_dos(char *path
,char *buf
);
96 /******************************************************************************
97 catch a sigusr2 - decrease the debug log level.
98 *****************************************************************************/
101 BlockSignals( True
, SIGUSR2
);
108 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL
) );
110 BlockSignals( False
, SIGUSR2
);
111 #ifndef DONT_REINSTALL_SIG
112 signal(SIGUSR2
, SIGNAL_CAST sig_usr2
);
119 /**************************************************************************** **
120 catch a sigusr1 - increase the debug log level.
121 **************************************************************************** */
124 BlockSignals( True
, SIGUSR1
);
131 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL
) );
133 BlockSignals( False
, SIGUSR1
);
134 #ifndef DONT_REINSTALL_SIG
135 signal(SIGUSR1
, SIGNAL_CAST sig_usr1
);
142 /*******************************************************************
143 get ready for syslog stuff
144 ******************************************************************/
145 void setup_logging(char *pname
,BOOL interactive
)
149 char *p
= strrchr(pname
,'/');
152 openlog(pname
, LOG_PID
, SYSLOG_FACILITY
);
153 #else /* for old systems that have no facility codes. */
154 openlog(pname
, LOG_PID
);
159 stdout_logging
= True
;
165 BOOL append_log
=False
;
168 /****************************************************************************
170 ****************************************************************************/
171 void reopen_logs(void)
177 strcpy(fname
,debugf
);
178 if (lp_loaded() && (*lp_logfile()))
179 strcpy(fname
,lp_logfile());
181 if (!strcsequal(fname
,debugf
) || !dbf
|| !file_exist(debugf
,NULL
))
183 int oldumask
= umask(022);
184 strcpy(debugf
,fname
);
185 if (dbf
) fclose(dbf
);
187 dbf
= fopen(debugf
,"a");
189 dbf
= fopen(debugf
,"w");
190 if (dbf
) setbuf(dbf
,NULL
);
205 /*******************************************************************
206 check if the log has grown too big
207 ********************************************************************/
208 static void check_log_size(void)
210 static int debug_count
=0;
214 if (debug_count
++ < 100 || getuid() != 0) return;
216 maxlog
= lp_max_log_size() * 1024;
217 if (!dbf
|| maxlog
<= 0) return;
219 if (fstat(fileno(dbf
),&st
) == 0 && st
.st_size
> maxlog
) {
220 fclose(dbf
); dbf
= NULL
;
222 if (dbf
&& file_size(debugf
) > maxlog
) {
224 fclose(dbf
); dbf
= NULL
;
225 sprintf(name
,"%s.old",debugf
);
226 sys_rename(debugf
,name
);
234 /*******************************************************************
235 write an debug message on the debugfile. This is called by the DEBUG
237 ********************************************************************/
239 int Debug1(char *format_str
, ...)
248 int old_errno
= errno
;
250 if (stdout_logging
) {
252 va_start(ap
, format_str
);
255 format_str
= va_arg(ap
,char *);
257 vfprintf(dbf
,format_str
,ap
);
264 if (!lp_syslog_only())
268 int oldumask
= umask(022);
269 dbf
= fopen(debugf
,"w");
281 if (syslog_level
< lp_syslog())
284 * map debug levels to syslog() priorities
285 * note that not all DEBUG(0, ...) calls are
288 static int priority_map
[] = {
297 if (syslog_level
>= sizeof(priority_map
) / sizeof(priority_map
[0]) ||
299 priority
= LOG_DEBUG
;
301 priority
= priority_map
[syslog_level
];
304 va_start(ap
, format_str
);
307 format_str
= va_arg(ap
,char *);
309 vsprintf(msgbuf
, format_str
, ap
);
313 syslog(priority
, "%s", msgbuf
);
318 if (!lp_syslog_only())
322 va_start(ap
, format_str
);
325 format_str
= va_arg(ap
,char *);
327 vfprintf(dbf
,format_str
,ap
);
339 /****************************************************************************
340 find a suitable temporary directory. The result should be copied immediately
341 as it may be overwritten by a subsequent call
342 ****************************************************************************/
346 if ((p
= getenv("TMPDIR"))) {
354 /****************************************************************************
355 determine if a file descriptor is in fact a socket
356 ****************************************************************************/
357 BOOL
is_a_socket(int fd
)
361 return(getsockopt(fd
, SOL_SOCKET
, SO_TYPE
, (char *)&v
, &l
) == 0);
365 static char *last_ptr
=NULL
;
367 /****************************************************************************
368 Get the next token from a string, return False if none found
369 handles double-quotes.
370 Based on a routine by GJC@VILLAGE.COM.
371 Extensively modified by Andrew.Tridgell@anu.edu.au
372 ****************************************************************************/
373 BOOL
next_token(char **ptr
,char *buff
,char *sep
)
378 if (!ptr
) ptr
= &last_ptr
;
379 if (!ptr
) return(False
);
383 /* default to simple separators */
384 if (!sep
) sep
= " \t\n\r";
386 /* find the first non sep char */
387 while(*s
&& strchr(sep
,*s
)) s
++;
390 if (! *s
) return(False
);
392 /* copy over the token */
393 for (quoted
= False
; *s
&& (quoted
|| !strchr(sep
,*s
)); s
++)
401 *ptr
= (*s
) ? s
+1 : s
;
408 /****************************************************************************
409 Convert list of tokens to array; dependent on above routine.
410 Uses last_ptr from above - bit of a hack.
411 ****************************************************************************/
412 char **toktocliplist(int *ctok
, char *sep
)
418 if (!sep
) sep
= " \t\n\r";
420 while(*s
&& strchr(sep
,*s
)) s
++;
423 if (!*s
) return(NULL
);
427 while(*s
&& (!strchr(sep
,*s
))) s
++;
428 while(*s
&& strchr(sep
,*s
)) *s
++=0;
434 if (!(ret
=iret
=malloc(ictok
*sizeof(char *)))) return NULL
;
446 /*******************************************************************
447 safely copies memory, ensuring no overlap problems.
448 this is only used if the machine does not have it's own memmove().
449 this is not the fastest algorithm in town, but it will do for our
451 ********************************************************************/
452 void *MemMove(void *dest
,void *src
,int size
)
456 if (dest
==src
|| !size
) return(dest
);
458 d
= (unsigned long)dest
;
459 s
= (unsigned long)src
;
461 if ((d
>= (s
+size
)) || (s
>= (d
+size
))) {
463 memcpy(dest
,src
,size
);
469 /* we can forward copy */
470 if (s
-d
>= sizeof(int) &&
471 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
472 /* do it all as words */
473 int *idest
= (int *)dest
;
474 int *isrc
= (int *)src
;
476 for (i
=0;i
<size
;i
++) idest
[i
] = isrc
[i
];
479 char *cdest
= (char *)dest
;
480 char *csrc
= (char *)src
;
481 for (i
=0;i
<size
;i
++) cdest
[i
] = csrc
[i
];
486 /* must backward copy */
487 if (d
-s
>= sizeof(int) &&
488 !(s
%sizeof(int)) && !(d
%sizeof(int)) && !(size
%sizeof(int))) {
489 /* do it all as words */
490 int *idest
= (int *)dest
;
491 int *isrc
= (int *)src
;
493 for (i
=size
-1;i
>=0;i
--) idest
[i
] = isrc
[i
];
496 char *cdest
= (char *)dest
;
497 char *csrc
= (char *)src
;
498 for (i
=size
-1;i
>=0;i
--) cdest
[i
] = csrc
[i
];
506 /****************************************************************************
507 prompte a dptr (to make it recently used)
508 ****************************************************************************/
509 void array_promote(char *array
,int elsize
,int element
)
515 p
= (char *)malloc(elsize
);
519 DEBUG(5,("Ahh! Can't malloc\n"));
522 memcpy(p
,array
+ element
* elsize
, elsize
);
523 memmove(array
+ elsize
,array
,elsize
*element
);
524 memcpy(array
,p
,elsize
);
528 enum SOCK_OPT_TYPES
{OPT_BOOL
,OPT_INT
,OPT_ON
};
537 } socket_options
[] = {
538 {"SO_KEEPALIVE", SOL_SOCKET
, SO_KEEPALIVE
, 0, OPT_BOOL
},
539 {"SO_REUSEADDR", SOL_SOCKET
, SO_REUSEADDR
, 0, OPT_BOOL
},
540 {"SO_BROADCAST", SOL_SOCKET
, SO_BROADCAST
, 0, OPT_BOOL
},
542 {"TCP_NODELAY", IPPROTO_TCP
, TCP_NODELAY
, 0, OPT_BOOL
},
544 #ifdef IPTOS_LOWDELAY
545 {"IPTOS_LOWDELAY", IPPROTO_IP
, IP_TOS
, IPTOS_LOWDELAY
, OPT_ON
},
547 #ifdef IPTOS_THROUGHPUT
548 {"IPTOS_THROUGHPUT", IPPROTO_IP
, IP_TOS
, IPTOS_THROUGHPUT
, OPT_ON
},
551 {"SO_SNDBUF", SOL_SOCKET
, SO_SNDBUF
, 0, OPT_INT
},
554 {"SO_RCVBUF", SOL_SOCKET
, SO_RCVBUF
, 0, OPT_INT
},
557 {"SO_SNDLOWAT", SOL_SOCKET
, SO_SNDLOWAT
, 0, OPT_INT
},
560 {"SO_RCVLOWAT", SOL_SOCKET
, SO_RCVLOWAT
, 0, OPT_INT
},
563 {"SO_SNDTIMEO", SOL_SOCKET
, SO_SNDTIMEO
, 0, OPT_INT
},
566 {"SO_RCVTIMEO", SOL_SOCKET
, SO_RCVTIMEO
, 0, OPT_INT
},
572 /****************************************************************************
573 set user socket options
574 ****************************************************************************/
575 void set_socket_options(int fd
, char *options
)
579 while (next_token(&options
,tok
," \t,"))
584 BOOL got_value
= False
;
586 if ((p
= strchr(tok
,'=')))
593 for (i
=0;socket_options
[i
].name
;i
++)
594 if (strequal(socket_options
[i
].name
,tok
))
597 if (!socket_options
[i
].name
)
599 DEBUG(0,("Unknown socket option %s\n",tok
));
603 switch (socket_options
[i
].opttype
)
607 ret
= setsockopt(fd
,socket_options
[i
].level
,
608 socket_options
[i
].option
,(char *)&value
,sizeof(int));
613 DEBUG(0,("syntax error - %s does not take a value\n",tok
));
616 int on
= socket_options
[i
].value
;
617 ret
= setsockopt(fd
,socket_options
[i
].level
,
618 socket_options
[i
].option
,(char *)&on
,sizeof(int));
624 DEBUG(0,("Failed to set socket option %s\n",tok
));
630 /****************************************************************************
631 close the socket communication
632 ****************************************************************************/
633 void close_sockets(void )
639 /****************************************************************************
640 determine whether we are in the specified group
641 ****************************************************************************/
642 BOOL
in_group(gid_t group
, int current_gid
, int ngroups
, int *groups
)
646 if (group
== current_gid
) return(True
);
648 for (i
=0;i
<ngroups
;i
++)
649 if (group
== groups
[i
])
655 /****************************************************************************
656 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
657 ****************************************************************************/
658 char *StrCpy(char *dest
,char *src
)
663 /* I don't want to get lazy with these ... */
665 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
670 if (!dest
) return(NULL
);
675 while ((*d
++ = *src
++)) ;
679 /****************************************************************************
680 line strncpy but always null terminates. Make sure there is room!
681 ****************************************************************************/
682 char *StrnCpy(char *dest
,char *src
,int n
)
685 if (!dest
) return(NULL
);
690 while (n
-- && (*d
++ = *src
++)) ;
696 /*******************************************************************
697 copy an IP address from one buffer to another
698 ********************************************************************/
699 void putip(void *dest
,void *src
)
705 /****************************************************************************
706 interpret the weird netbios "name". Return the name type
707 ****************************************************************************/
708 static int name_interpret(char *in
,char *out
)
711 int len
= (*in
++) / 2;
715 if (len
> 30 || len
<1) return(0);
719 if (in
[0] < 'A' || in
[0] > 'P' || in
[1] < 'A' || in
[1] > 'P') {
723 *out
= ((in
[0]-'A')<<4) + (in
[1]-'A');
731 /* Handle any scope names */
734 *out
++ = '.'; /* Scope names are separated by periods */
735 len
= *(unsigned char *)in
++;
736 StrnCpy(out
, in
, len
);
745 /****************************************************************************
746 mangle a name into netbios format
748 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
749 ****************************************************************************/
750 int name_mangle( char *In
, char *Out
, char name_type
)
758 /* Safely copy the input string, In, into buf[]. */
759 (void)memset( buf
, 0, 20 );
763 (void)sprintf( buf
, "%-15.15s%c", In
, name_type
);
765 /* Place the length of the first field into the output buffer. */
769 /* Now convert the name to the rfc1001/1002 format. */
770 for( i
= 0; i
< 16; i
++ )
772 c
= toupper( buf
[i
] );
773 p
[i
*2] = ( (c
>> 4) & 0x000F ) + 'A';
774 p
[(i
*2)+1] = (c
& 0x000F) + 'A';
779 /* Add the scope string. */
780 for( i
= 0, len
= 0; NULL
!= scope
; i
++, len
++ )
788 return( name_len(Out
) );
800 return( name_len(Out
) );
803 /*******************************************************************
804 check if a file exists
805 ********************************************************************/
806 BOOL
file_exist(char *fname
,struct stat
*sbuf
)
809 if (!sbuf
) sbuf
= &st
;
811 if (sys_stat(fname
,sbuf
) != 0)
814 return(S_ISREG(sbuf
->st_mode
));
817 /*******************************************************************
818 check a files mod time
819 ********************************************************************/
820 time_t file_modtime(char *fname
)
824 if (sys_stat(fname
,&st
) != 0)
830 /*******************************************************************
831 check if a directory exists
832 ********************************************************************/
833 BOOL
directory_exist(char *dname
,struct stat
*st
)
840 if (sys_stat(dname
,st
) != 0)
843 ret
= S_ISDIR(st
->st_mode
);
849 /*******************************************************************
850 returns the size in bytes of the named file
851 ********************************************************************/
852 uint32
file_size(char *file_name
)
856 sys_stat(file_name
,&buf
);
860 /*******************************************************************
861 return a string representing an attribute for a file
862 ********************************************************************/
863 char *attrib_string(int mode
)
865 static char attrstr
[10];
869 if (mode
& aVOLID
) strcat(attrstr
,"V");
870 if (mode
& aDIR
) strcat(attrstr
,"D");
871 if (mode
& aARCH
) strcat(attrstr
,"A");
872 if (mode
& aHIDDEN
) strcat(attrstr
,"H");
873 if (mode
& aSYSTEM
) strcat(attrstr
,"S");
874 if (mode
& aRONLY
) strcat(attrstr
,"R");
880 /*******************************************************************
881 case insensitive string compararison
882 ********************************************************************/
883 int StrCaseCmp(char *s
, char *t
)
885 /* compare until we run out of string, either t or s, or find a difference */
886 /* We *must* use toupper rather than tolower here due to the
887 asynchronous upper to lower mapping.
889 #if !defined(KANJI_WIN95_COMPATIBILITY)
891 * For completeness we should put in equivalent code for code pages
892 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
893 * doubt anyone wants Samba to behave differently from Win95 and WinNT
894 * here. They both treat full width ascii characters as case senstive
895 * filenames (ie. they don't do the work we do here).
899 if(lp_client_code_page() == KANJI_CODEPAGE
)
901 /* Win95 treats full width ascii characters as case sensitive. */
906 return toupper (*s
) - toupper (*t
);
907 else if (is_sj_alph (*s
) && is_sj_alph (*t
))
909 diff
= sj_toupper2 (*(s
+1)) - sj_toupper2 (*(t
+1));
915 else if (is_shift_jis (*s
) && is_shift_jis (*t
))
917 diff
= ((int) (unsigned char) *s
) - ((int) (unsigned char) *t
);
920 diff
= ((int) (unsigned char) *(s
+1)) - ((int) (unsigned char) *(t
+1));
926 else if (is_shift_jis (*s
))
928 else if (is_shift_jis (*t
))
932 diff
= toupper (*s
) - toupper (*t
);
941 #endif /* KANJI_WIN95_COMPATIBILITY */
943 while (*s
&& *t
&& toupper(*s
) == toupper(*t
))
949 return(toupper(*s
) - toupper(*t
));
953 /*******************************************************************
954 case insensitive string compararison, length limited
955 ********************************************************************/
956 int StrnCaseCmp(char *s
, char *t
, int n
)
958 /* compare until we run out of string, either t or s, or chars */
959 /* We *must* use toupper rather than tolower here due to the
960 asynchronous upper to lower mapping.
962 #if !defined(KANJI_WIN95_COMPATIBILITY)
964 * For completeness we should put in equivalent code for code pages
965 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
966 * doubt anyone wants Samba to behave differently from Win95 and WinNT
967 * here. They both treat full width ascii characters as case senstive
968 * filenames (ie. they don't do the work we do here).
972 if(lp_client_code_page() == KANJI_CODEPAGE
)
974 /* Win95 treats full width ascii characters as case sensitive. */
979 return toupper (*s
) - toupper (*t
);
980 else if (is_sj_alph (*s
) && is_sj_alph (*t
))
982 diff
= sj_toupper2 (*(s
+1)) - sj_toupper2 (*(t
+1));
989 else if (is_shift_jis (*s
) && is_shift_jis (*t
))
991 diff
= ((int) (unsigned char) *s
) - ((int) (unsigned char) *t
);
994 diff
= ((int) (unsigned char) *(s
+1)) - ((int) (unsigned char) *(t
+1));
1001 else if (is_shift_jis (*s
))
1003 else if (is_shift_jis (*t
))
1007 diff
= toupper (*s
) - toupper (*t
);
1018 #endif /* KANJI_WIN95_COMPATIBILITY */
1020 while (n
&& *s
&& *t
&& toupper(*s
) == toupper(*t
))
1027 /* not run out of chars - strings are different lengths */
1029 return(toupper(*s
) - toupper(*t
));
1031 /* identical up to where we run out of chars,
1032 and strings are same length */
1037 /*******************************************************************
1039 ********************************************************************/
1040 BOOL
strequal(char *s1
, char *s2
)
1042 if (s1
== s2
) return(True
);
1043 if (!s1
|| !s2
) return(False
);
1045 return(StrCaseCmp(s1
,s2
)==0);
1048 /*******************************************************************
1049 compare 2 strings up to and including the nth char.
1050 ******************************************************************/
1051 BOOL
strnequal(char *s1
,char *s2
,int n
)
1053 if (s1
== s2
) return(True
);
1054 if (!s1
|| !s2
|| !n
) return(False
);
1056 return(StrnCaseCmp(s1
,s2
,n
)==0);
1059 /*******************************************************************
1060 compare 2 strings (case sensitive)
1061 ********************************************************************/
1062 BOOL
strcsequal(char *s1
,char *s2
)
1064 if (s1
== s2
) return(True
);
1065 if (!s1
|| !s2
) return(False
);
1067 return(strcmp(s1
,s2
)==0);
1071 /*******************************************************************
1072 convert a string to lower case
1073 ********************************************************************/
1074 void strlower(char *s
)
1078 #if !defined(KANJI_WIN95_COMPATIBILITY)
1080 * For completeness we should put in equivalent code for code pages
1081 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1082 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1083 * here. They both treat full width ascii characters as case senstive
1084 * filenames (ie. they don't do the work we do here).
1088 if(lp_client_code_page() == KANJI_CODEPAGE
)
1090 /* Win95 treats full width ascii characters as case sensitive. */
1091 if (is_shift_jis (*s
))
1093 if (is_sj_upper (s
[0], s
[1]))
1094 s
[1] = sj_tolower2 (s
[1]);
1097 else if (is_kana (*s
))
1109 #endif /* KANJI_WIN95_COMPATIBILITY */
1118 /*******************************************************************
1119 convert a string to upper case
1120 ********************************************************************/
1121 void strupper(char *s
)
1125 #if !defined(KANJI_WIN95_COMPATIBILITY)
1127 * For completeness we should put in equivalent code for code pages
1128 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1129 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1130 * here. They both treat full width ascii characters as case senstive
1131 * filenames (ie. they don't do the work we do here).
1135 if(lp_client_code_page() == KANJI_CODEPAGE
)
1137 /* Win95 treats full width ascii characters as case sensitive. */
1138 if (is_shift_jis (*s
))
1140 if (is_sj_lower (s
[0], s
[1]))
1141 s
[1] = sj_toupper2 (s
[1]);
1144 else if (is_kana (*s
))
1156 #endif /* KANJI_WIN95_COMPATIBILITY */
1165 /*******************************************************************
1166 convert a string to "normal" form
1167 ********************************************************************/
1168 void strnorm(char *s
)
1170 if (case_default
== CASE_UPPER
)
1176 /*******************************************************************
1177 check if a string is in "normal" case
1178 ********************************************************************/
1179 BOOL
strisnormal(char *s
)
1181 if (case_default
== CASE_UPPER
)
1182 return(!strhaslower(s
));
1184 return(!strhasupper(s
));
1188 /****************************************************************************
1190 ****************************************************************************/
1191 void string_replace(char *s
,char oldc
,char newc
)
1195 #if !defined(KANJI_WIN95_COMPATIBILITY)
1197 * For completeness we should put in equivalent code for code pages
1198 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1199 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1200 * here. They both treat full width ascii characters as case senstive
1201 * filenames (ie. they don't do the work we do here).
1205 if(lp_client_code_page() == KANJI_CODEPAGE
)
1207 /* Win95 treats full width ascii characters as case sensitive. */
1208 if (is_shift_jis (*s
))
1210 else if (is_kana (*s
))
1220 #endif /* KANJI_WIN95_COMPATIBILITY */
1229 /****************************************************************************
1230 make a file into unix format
1231 ****************************************************************************/
1232 void unix_format(char *fname
)
1235 string_replace(fname
,'\\','/');
1239 pstrcpy(namecopy
,fname
);
1241 strcat(fname
,namecopy
);
1245 /****************************************************************************
1246 make a file into dos format
1247 ****************************************************************************/
1248 void dos_format(char *fname
)
1250 string_replace(fname
,'/','\\');
1254 /*******************************************************************
1255 show a smb message structure
1256 ********************************************************************/
1257 void show_msg(char *buf
)
1262 if (DEBUGLEVEL
< 5) return;
1264 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1266 (int)CVAL(buf
,smb_com
),
1267 (int)CVAL(buf
,smb_rcls
),
1268 (int)CVAL(buf
,smb_reh
),
1269 (int)SVAL(buf
,smb_err
),
1270 (int)CVAL(buf
,smb_flg
),
1271 (int)SVAL(buf
,smb_flg2
)));
1272 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1273 (int)SVAL(buf
,smb_tid
),
1274 (int)SVAL(buf
,smb_pid
),
1275 (int)SVAL(buf
,smb_uid
),
1276 (int)SVAL(buf
,smb_mid
),
1277 (int)CVAL(buf
,smb_wct
)));
1279 for (i
=0;i
<(int)CVAL(buf
,smb_wct
);i
++)
1280 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i
,
1281 SVAL(buf
,smb_vwv
+2*i
),SVAL(buf
,smb_vwv
+2*i
)));
1283 bcc
= (int)SVAL(buf
,smb_vwv
+2*(CVAL(buf
,smb_wct
)));
1284 DEBUG(5,("smb_bcc=%d\n",bcc
));
1286 if (DEBUGLEVEL
< 10) return;
1288 dump_data(10, smb_buf(buf
), MIN(bcc
, 512));
1291 /*******************************************************************
1292 return the length of an smb packet
1293 ********************************************************************/
1294 int smb_len(char *buf
)
1296 return( PVAL(buf
,3) | (PVAL(buf
,2)<<8) | ((PVAL(buf
,1)&1)<<16) );
1299 /*******************************************************************
1300 set the length of an smb packet
1301 ********************************************************************/
1302 void _smb_setlen(char *buf
,int len
)
1305 buf
[1] = (len
&0x10000)>>16;
1306 buf
[2] = (len
&0xFF00)>>8;
1310 /*******************************************************************
1311 set the length and marker of an smb packet
1312 ********************************************************************/
1313 void smb_setlen(char *buf
,int len
)
1315 _smb_setlen(buf
,len
);
1323 /*******************************************************************
1324 setup the word count and byte count for a smb message
1325 ********************************************************************/
1326 int set_message(char *buf
,int num_words
,int num_bytes
,BOOL zero
)
1329 bzero(buf
+ smb_size
,num_words
*2 + num_bytes
);
1330 CVAL(buf
,smb_wct
) = num_words
;
1331 SSVAL(buf
,smb_vwv
+ num_words
*SIZEOFWORD
,num_bytes
);
1332 smb_setlen(buf
,smb_size
+ num_words
*2 + num_bytes
- 4);
1333 return (smb_size
+ num_words
*2 + num_bytes
);
1336 /*******************************************************************
1337 return the number of smb words
1338 ********************************************************************/
1339 int smb_numwords(char *buf
)
1341 return (CVAL(buf
,smb_wct
));
1344 /*******************************************************************
1345 return the size of the smb_buf region of a message
1346 ********************************************************************/
1347 int smb_buflen(char *buf
)
1349 return(SVAL(buf
,smb_vwv0
+ smb_numwords(buf
)*2));
1352 /*******************************************************************
1353 return a pointer to the smb_buf data area
1354 ********************************************************************/
1355 int smb_buf_ofs(char *buf
)
1357 return (smb_size
+ CVAL(buf
,smb_wct
)*2);
1360 /*******************************************************************
1361 return a pointer to the smb_buf data area
1362 ********************************************************************/
1363 char *smb_buf(char *buf
)
1365 return (buf
+ smb_buf_ofs(buf
));
1368 /*******************************************************************
1369 return the SMB offset into an SMB buffer
1370 ********************************************************************/
1371 int smb_offset(char *p
,char *buf
)
1373 return(PTR_DIFF(p
,buf
+4) + chain_size
);
1377 /*******************************************************************
1378 skip past some strings in a buffer
1379 ********************************************************************/
1380 char *skip_string(char *buf
,int n
)
1383 buf
+= strlen(buf
) + 1;
1387 /*******************************************************************
1388 trim the specified elements off the front and back of a string
1389 ********************************************************************/
1390 BOOL
trim_string(char *s
,char *front
,char *back
)
1393 while (front
&& *front
&& strncmp(s
,front
,strlen(front
)) == 0)
1399 if (!(*p
= p
[strlen(front
)]))
1404 while (back
&& *back
&& strlen(s
) >= strlen(back
) &&
1405 (strncmp(s
+strlen(s
)-strlen(back
),back
,strlen(back
))==0))
1408 s
[strlen(s
)-strlen(back
)] = 0;
1414 /*******************************************************************
1415 reduce a file name, removing .. elements.
1416 ********************************************************************/
1417 void dos_clean_name(char *s
)
1421 DEBUG(3,("dos_clean_name [%s]\n",s
));
1423 /* remove any double slashes */
1424 string_sub(s
, "\\\\", "\\");
1426 while ((p
= strstr(s
,"\\..\\")) != NULL
)
1433 if ((p
=strrchr(s
,'\\')) != NULL
)
1440 trim_string(s
,NULL
,"\\..");
1442 string_sub(s
, "\\.\\", "\\");
1445 /*******************************************************************
1446 reduce a file name, removing .. elements.
1447 ********************************************************************/
1448 void unix_clean_name(char *s
)
1452 DEBUG(3,("unix_clean_name [%s]\n",s
));
1454 /* remove any double slashes */
1455 string_sub(s
, "//","/");
1457 /* Remove leading ./ characters */
1458 if(strncmp(s
, "./", 2) == 0) {
1459 trim_string(s
, "./", NULL
);
1464 while ((p
= strstr(s
,"/../")) != NULL
)
1471 if ((p
=strrchr(s
,'/')) != NULL
)
1478 trim_string(s
,NULL
,"/..");
1482 /*******************************************************************
1483 a wrapper for the normal chdir() function
1484 ********************************************************************/
1485 int ChDir(char *path
)
1488 static pstring LastDir
="";
1490 if (strcsequal(path
,".")) return(0);
1492 if (*path
== '/' && strcsequal(LastDir
,path
)) return(0);
1493 DEBUG(3,("chdir to %s\n",path
));
1494 res
= sys_chdir(path
);
1496 pstrcpy(LastDir
,path
);
1500 /* number of list structures for a caching GetWd function. */
1501 #define MAX_GETWDCACHE (50)
1509 } ino_list
[MAX_GETWDCACHE
];
1511 BOOL use_getwd_cache
=True
;
1513 /*******************************************************************
1514 return the absolute current directory path
1515 ********************************************************************/
1516 char *GetWd(char *str
)
1519 static BOOL getwd_cache_init
= False
;
1520 struct stat st
, st2
;
1525 if (!use_getwd_cache
)
1526 return(sys_getwd(str
));
1528 /* init the cache */
1529 if (!getwd_cache_init
)
1531 getwd_cache_init
= True
;
1532 for (i
=0;i
<MAX_GETWDCACHE
;i
++)
1534 string_init(&ino_list
[i
].text
,"");
1535 ino_list
[i
].valid
= False
;
1539 /* Get the inode of the current directory, if this doesn't work we're
1542 if (stat(".",&st
) == -1)
1544 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1545 return(sys_getwd(str
));
1549 for (i
=0; i
<MAX_GETWDCACHE
; i
++)
1550 if (ino_list
[i
].valid
)
1553 /* If we have found an entry with a matching inode and dev number
1554 then find the inode number for the directory in the cached string.
1555 If this agrees with that returned by the stat for the current
1556 directory then all is o.k. (but make sure it is a directory all
1559 if (st
.st_ino
== ino_list
[i
].inode
&&
1560 st
.st_dev
== ino_list
[i
].dev
)
1562 if (stat(ino_list
[i
].text
,&st2
) == 0)
1564 if (st
.st_ino
== st2
.st_ino
&&
1565 st
.st_dev
== st2
.st_dev
&&
1566 (st2
.st_mode
& S_IFMT
) == S_IFDIR
)
1568 strcpy (str
, ino_list
[i
].text
);
1570 /* promote it for future use */
1571 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1576 /* If the inode is different then something's changed,
1577 scrub the entry and start from scratch. */
1578 ino_list
[i
].valid
= False
;
1585 /* We don't have the information to hand so rely on traditional methods.
1586 The very slow getcwd, which spawns a process on some systems, or the
1587 not quite so bad getwd. */
1591 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno
)));
1597 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s
,(int)st
.st_ino
,(int)st
.st_dev
));
1599 /* add it to the cache */
1600 i
= MAX_GETWDCACHE
- 1;
1601 string_set(&ino_list
[i
].text
,s
);
1602 ino_list
[i
].dev
= st
.st_dev
;
1603 ino_list
[i
].inode
= st
.st_ino
;
1604 ino_list
[i
].valid
= True
;
1606 /* put it at the top of the list */
1607 array_promote((char *)&ino_list
[0],sizeof(ino_list
[0]),i
);
1614 /*******************************************************************
1615 reduce a file name, removing .. elements and checking that
1616 it is below dir in the heirachy. This uses GetWd() and so must be run
1617 on the system that has the referenced file system.
1619 widelinks are allowed if widelinks is true
1620 ********************************************************************/
1621 BOOL
reduce_name(char *s
,char *dir
,BOOL widelinks
)
1623 #ifndef REDUCE_PATHS
1631 BOOL relative
= (*s
!= '/');
1633 *dir2
= *wd
= *base_name
= *newname
= 0;
1638 /* can't have a leading .. */
1639 if (strncmp(s
,"..",2) == 0 && (s
[2]==0 || s
[2]=='/'))
1641 DEBUG(3,("Illegal file name? (%s)\n",s
));
1651 DEBUG(3,("reduce_name [%s] [%s]\n",s
,dir
));
1653 /* remove any double slashes */
1654 string_sub(s
,"//","/");
1656 pstrcpy(base_name
,s
);
1657 p
= strrchr(base_name
,'/');
1664 DEBUG(0,("couldn't getwd for %s %s\n",s
,dir
));
1668 if (ChDir(dir
) != 0)
1670 DEBUG(0,("couldn't chdir to %s\n",dir
));
1676 DEBUG(0,("couldn't getwd for %s\n",dir
));
1682 if (p
&& (p
!= base_name
))
1685 if (strcmp(p
+1,".")==0)
1687 if (strcmp(p
+1,"..")==0)
1691 if (ChDir(base_name
) != 0)
1694 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s
,dir
,base_name
));
1698 if (!GetWd(newname
))
1701 DEBUG(2,("couldn't get wd for %s %s\n",s
,dir2
));
1705 if (p
&& (p
!= base_name
))
1707 strcat(newname
,"/");
1708 strcat(newname
,p
+1);
1712 int l
= strlen(dir2
);
1713 if (dir2
[l
-1] == '/')
1716 if (strncmp(newname
,dir2
,l
) != 0)
1719 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s
,dir2
,newname
,l
));
1725 if (newname
[l
] == '/')
1726 pstrcpy(s
,newname
+ l
+ 1);
1728 pstrcpy(s
,newname
+l
);
1739 DEBUG(3,("reduced to %s\n",s
));
1744 /****************************************************************************
1746 ****************************************************************************/
1747 static void expand_one(char *Mask
,int len
)
1750 while ((p1
= strchr(Mask
,'*')) != NULL
)
1752 int lfill
= (len
+1) - strlen(Mask
);
1753 int l1
= (p1
- Mask
);
1756 memset(tmp
+l1
,'?',lfill
);
1757 pstrcpy(tmp
+ l1
+ lfill
,Mask
+ l1
+ 1);
1762 /****************************************************************************
1763 expand a wildcard expression, replacing *s with ?s
1764 ****************************************************************************/
1765 void expand_mask(char *Mask
,BOOL doext
)
1770 BOOL hasdot
= False
;
1772 BOOL absolute
= (*Mask
== '\\');
1774 *mbeg
= *mext
= *dirpart
= *filepart
= 0;
1776 /* parse the directory and filename */
1777 if (strchr(Mask
,'\\'))
1778 dirname_dos(Mask
,dirpart
);
1780 filename_dos(Mask
,filepart
);
1782 pstrcpy(mbeg
,filepart
);
1783 if ((p1
= strchr(mbeg
,'.')) != NULL
)
1793 if (strlen(mbeg
) > 8)
1795 pstrcpy(mext
,mbeg
+ 8);
1801 strcpy(mbeg
,"????????");
1802 if ((*mext
== 0) && doext
&& !hasdot
)
1805 if (strequal(mbeg
,"*") && *mext
==0)
1813 pstrcpy(Mask
,dirpart
);
1814 if (*dirpart
|| absolute
) strcat(Mask
,"\\");
1819 DEBUG(6,("Mask expanded to [%s]\n",Mask
));
1823 /****************************************************************************
1824 does a string have any uppercase chars in it?
1825 ****************************************************************************/
1826 BOOL
strhasupper(char *s
)
1830 #if !defined(KANJI_WIN95_COMPATIBILITY)
1832 * For completeness we should put in equivalent code for code pages
1833 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1834 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1835 * here. They both treat full width ascii characters as case senstive
1836 * filenames (ie. they don't do the work we do here).
1840 if(lp_client_code_page() == KANJI_CODEPAGE
)
1842 /* Win95 treats full width ascii characters as case sensitive. */
1843 if (is_shift_jis (*s
))
1845 else if (is_kana (*s
))
1855 #endif /* KANJI_WIN95_COMPATIBILITY */
1865 /****************************************************************************
1866 does a string have any lowercase chars in it?
1867 ****************************************************************************/
1868 BOOL
strhaslower(char *s
)
1872 #if !defined(KANJI_WIN95_COMPATIBILITY)
1874 * For completeness we should put in equivalent code for code pages
1875 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1876 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1877 * here. They both treat full width ascii characters as case senstive
1878 * filenames (ie. they don't do the work we do here).
1882 if(lp_client_code_page() == KANJI_CODEPAGE
)
1884 /* Win95 treats full width ascii characters as case sensitive. */
1885 if (is_shift_jis (*s
))
1887 if (is_sj_upper (s
[0], s
[1]))
1889 if (is_sj_lower (s
[0], s
[1]))
1893 else if (is_kana (*s
))
1905 #endif /* KANJI_WIN95_COMPATIBILITY */
1915 /****************************************************************************
1916 find the number of chars in a string
1917 ****************************************************************************/
1918 int count_chars(char *s
,char c
)
1922 #if !defined(KANJI_WIN95_COMPATIBILITY)
1924 * For completeness we should put in equivalent code for code pages
1925 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1926 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1927 * here. They both treat full width ascii characters as case senstive
1928 * filenames (ie. they don't do the work we do here).
1932 if(lp_client_code_page() == KANJI_CODEPAGE
)
1934 /* Win95 treats full width ascii characters as case sensitive. */
1937 if (is_shift_jis (*s
))
1948 #endif /* KANJI_WIN95_COMPATIBILITY */
1961 /****************************************************************************
1963 ****************************************************************************/
1964 void make_dir_struct(char *buf
,char *mask
,char *fname
,unsigned int size
,int mode
,time_t date
)
1969 pstrcpy(mask2
,mask
);
1971 if ((mode
& aDIR
) != 0)
1974 memset(buf
+1,' ',11);
1975 if ((p
= strchr(mask2
,'.')) != NULL
)
1978 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),8));
1979 memcpy(buf
+9,p
+1,MIN(strlen(p
+1),3));
1983 memcpy(buf
+1,mask2
,MIN(strlen(mask2
),11));
1985 bzero(buf
+21,DIR_STRUCT_SIZE
-21);
1986 CVAL(buf
,21) = mode
;
1987 put_dos_date(buf
,22,date
);
1988 SSVAL(buf
,26,size
& 0xFFFF);
1989 SSVAL(buf
,28,size
>> 16);
1990 StrnCpy(buf
+30,fname
,12);
1991 if (!case_sensitive
)
1993 DEBUG(8,("put name [%s] into dir struct\n",buf
+30));
1997 /*******************************************************************
1998 close the low 3 fd's and open dev/null in their place
1999 ********************************************************************/
2000 void close_low_fds(void)
2004 close(0); close(1); close(2);
2005 /* try and use up these file descriptors, so silly
2006 library routines writing to stdout etc won't cause havoc */
2008 fd
= open("/dev/null",O_RDWR
,0);
2009 if (fd
< 0) fd
= open("/dev/null",O_WRONLY
,0);
2011 DEBUG(0,("Can't open /dev/null\n"));
2015 DEBUG(0,("Didn't get file descriptor %d\n",i
));
2021 /****************************************************************************
2022 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2024 if SYSV use O_NDELAY
2026 ****************************************************************************/
2027 int set_blocking(int fd
, BOOL set
)
2031 #define FLAG_TO_SET O_NONBLOCK
2034 #define FLAG_TO_SET O_NDELAY
2036 #define FLAG_TO_SET FNDELAY
2040 if((val
= fcntl(fd
, F_GETFL
, 0)) == -1)
2042 if(set
) /* Turn blocking on - ie. clear nonblock flag */
2043 val
&= ~FLAG_TO_SET
;
2046 return fcntl( fd
, F_SETFL
, val
);
2051 /****************************************************************************
2053 ****************************************************************************/
2054 int write_socket(int fd
,char *buf
,int len
)
2060 DEBUG(6,("write_socket(%d,%d)\n",fd
,len
));
2061 ret
= write_data(fd
,buf
,len
);
2063 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd
,len
,ret
));
2065 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2066 len
, fd
, strerror(errno
) ));
2071 /****************************************************************************
2073 ****************************************************************************/
2074 int read_udp_socket(int fd
,char *buf
,int len
)
2077 struct sockaddr_in sock
;
2080 socklen
= sizeof(sock
);
2081 bzero((char *)&sock
,socklen
);
2082 bzero((char *)&lastip
,sizeof(lastip
));
2083 ret
= recvfrom(fd
,buf
,len
,0,(struct sockaddr
*)&sock
,&socklen
);
2085 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno
)));
2089 lastip
= sock
.sin_addr
;
2090 lastport
= ntohs(sock
.sin_port
);
2092 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2093 inet_ntoa(lastip
), lastport
, ret
));
2098 /****************************************************************************
2099 read data from a device with a timout in msec.
2100 mincount = if timeout, minimum to read before returning
2101 maxcount = number to be read.
2102 ****************************************************************************/
2103 int read_with_timeout(int fd
,char *buf
,int mincnt
,int maxcnt
,long time_out
)
2109 struct timeval timeout
;
2111 /* just checking .... */
2112 if (maxcnt
<= 0) return(0);
2117 if (time_out
<= 0) {
2118 if (mincnt
== 0) mincnt
= maxcnt
;
2120 while (nread
< mincnt
) {
2121 readret
= read(fd
, buf
+ nread
, maxcnt
- nread
);
2123 smb_read_error
= READ_EOF
;
2127 if (readret
== -1) {
2128 smb_read_error
= READ_ERROR
;
2136 /* Most difficult - timeout read */
2137 /* If this is ever called on a disk file and
2138 mincnt is greater then the filesize then
2139 system performance will suffer severely as
2140 select always return true on disk files */
2142 /* Set initial timeout */
2143 timeout
.tv_sec
= time_out
/ 1000;
2144 timeout
.tv_usec
= 1000 * (time_out
% 1000);
2146 for (nread
=0; nread
<mincnt
; )
2151 selrtn
= sys_select(&fds
,&timeout
);
2153 /* Check if error */
2155 /* something is wrong. Maybe the socket is dead? */
2156 smb_read_error
= READ_ERROR
;
2160 /* Did we timeout ? */
2162 smb_read_error
= READ_TIMEOUT
;
2166 readret
= read(fd
, buf
+nread
, maxcnt
-nread
);
2168 /* we got EOF on the file descriptor */
2169 smb_read_error
= READ_EOF
;
2173 if (readret
== -1) {
2174 /* the descriptor is probably dead */
2175 smb_read_error
= READ_ERROR
;
2182 /* Return the number we got */
2186 /****************************************************************************
2187 read data from the client. Maxtime is in milliseconds
2188 ****************************************************************************/
2189 int read_max_udp(int fd
,char *buffer
,int bufsize
,int maxtime
)
2194 struct timeval timeout
;
2199 timeout
.tv_sec
= maxtime
/ 1000;
2200 timeout
.tv_usec
= (maxtime
% 1000) * 1000;
2202 selrtn
= sys_select(&fds
,maxtime
>0?&timeout
:NULL
);
2204 if (!FD_ISSET(fd
,&fds
))
2207 nread
= read_udp_socket(fd
, buffer
, bufsize
);
2209 /* return the number got */
2213 /*******************************************************************
2214 find the difference in milliseconds between two struct timeval
2216 ********************************************************************/
2217 int TvalDiff(struct timeval
*tvalold
,struct timeval
*tvalnew
)
2219 return((tvalnew
->tv_sec
- tvalold
->tv_sec
)*1000 +
2220 ((int)tvalnew
->tv_usec
- (int)tvalold
->tv_usec
)/1000);
2223 /****************************************************************************
2224 send a keepalive packet (rfc1002)
2225 ****************************************************************************/
2226 BOOL
send_keepalive(int client
)
2228 unsigned char buf
[4];
2231 buf
[1] = buf
[2] = buf
[3] = 0;
2233 return(write_data(client
,(char *)buf
,4) == 4);
2238 /****************************************************************************
2239 read data from the client, reading exactly N bytes.
2240 ****************************************************************************/
2241 int read_data(int fd
,char *buffer
,int N
)
2250 ret
= read(fd
,buffer
+ total
,N
- total
);
2252 smb_read_error
= READ_EOF
;
2256 smb_read_error
= READ_ERROR
;
2265 /****************************************************************************
2267 ****************************************************************************/
2268 int write_data(int fd
,char *buffer
,int N
)
2275 ret
= write(fd
,buffer
+ total
,N
- total
);
2277 if (ret
== -1) return -1;
2278 if (ret
== 0) return total
;
2286 /****************************************************************************
2287 transfer some data between two fd's
2288 ****************************************************************************/
2289 int transfer_file(int infd
,int outfd
,int n
,char *header
,int headlen
,int align
)
2291 static char *buf
=NULL
;
2296 DEBUG(4,("transfer_file %d (head=%d) called\n",n
,headlen
));
2299 size
= lp_readsize();
2300 size
= MAX(size
,1024);
2303 while (!buf
&& size
>0) {
2304 buf
= (char *)Realloc(buf
,size
+8);
2305 if (!buf
) size
/= 2;
2309 DEBUG(0,("Can't allocate transfer buffer!\n"));
2313 abuf
= buf
+ (align
%8);
2320 int s
= MIN(n
,size
);
2325 if (header
&& (headlen
>= MIN(s
,1024))) {
2335 if (header
&& headlen
> 0)
2337 ret
= MIN(headlen
,size
);
2338 memcpy(buf1
,header
,ret
);
2341 if (headlen
<= 0) header
= NULL
;
2345 ret
+= read(infd
,buf1
+ret
,s
-ret
);
2349 ret2
= (outfd
>=0?write_data(outfd
,buf1
,ret
):ret
);
2350 if (ret2
> 0) total
+= ret2
;
2351 /* if we can't write then dump excess data */
2353 transfer_file(infd
,-1,n
-(ret
+headlen
),NULL
,0,0);
2355 if (ret
<= 0 || ret2
!= ret
)
2363 /****************************************************************************
2364 read 4 bytes of a smb packet and return the smb length of the packet
2365 store the result in the buffer
2366 This version of the function will return a length of zero on receiving
2368 ****************************************************************************/
2369 static int read_smb_length_return_keepalive(int fd
,char *inbuf
,int timeout
)
2371 int len
=0, msg_type
;
2377 ok
= (read_with_timeout(fd
,inbuf
,4,4,timeout
) == 4);
2379 ok
= (read_data(fd
,inbuf
,4) == 4);
2384 len
= smb_len(inbuf
);
2385 msg_type
= CVAL(inbuf
,0);
2387 if (msg_type
== 0x85)
2388 DEBUG(5,("Got keepalive packet\n"));
2391 DEBUG(10,("got smb length of %d\n",len
));
2396 /****************************************************************************
2397 read 4 bytes of a smb packet and return the smb length of the packet
2398 store the result in the buffer. This version of the function will
2399 never return a session keepalive (length of zero).
2400 ****************************************************************************/
2401 int read_smb_length(int fd
,char *inbuf
,int timeout
)
2407 len
= read_smb_length_return_keepalive(fd
, inbuf
, timeout
);
2412 /* Ignore session keepalives. */
2413 if(CVAL(inbuf
,0) != 0x85)
2420 /****************************************************************************
2421 read an smb from a fd. Note that the buffer *MUST* be of size
2422 BUFFER_SIZE+SAFETY_MARGIN.
2423 The timeout is in milli seconds.
2425 This function will return on a
2426 receipt of a session keepalive packet.
2427 ****************************************************************************/
2428 BOOL
receive_smb(int fd
,char *buffer
, int timeout
)
2434 bzero(buffer
,smb_size
+ 100);
2436 len
= read_smb_length_return_keepalive(fd
,buffer
,timeout
);
2440 if (len
> BUFFER_SIZE
) {
2441 DEBUG(0,("Invalid packet length! (%d bytes).\n",len
));
2442 if (len
> BUFFER_SIZE
+ (SAFETY_MARGIN
/2))
2447 ret
= read_data(fd
,buffer
+4,len
);
2449 smb_read_error
= READ_ERROR
;
2456 /****************************************************************************
2457 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2458 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2459 The timeout is in milli seconds
2461 This is exactly the same as receive_smb except that it never returns
2462 a session keepalive packet (just as receive_smb used to do).
2463 receive_smb was changed to return keepalives as the oplock processing means this call
2464 should never go into a blocking read.
2465 ****************************************************************************/
2467 BOOL
client_receive_smb(int fd
,char *buffer
, int timeout
)
2473 ret
= receive_smb(fd
, buffer
, timeout
);
2478 /* Ignore session keepalive packets. */
2479 if(CVAL(buffer
,0) != 0x85)
2485 /****************************************************************************
2486 read a message from a udp fd.
2487 The timeout is in milli seconds
2488 ****************************************************************************/
2489 BOOL
receive_local_message(int fd
, char *buffer
, int buffer_len
, int timeout
)
2491 struct sockaddr_in from
;
2492 int fromlen
= sizeof(from
);
2506 to
.tv_sec
= timeout
/ 1000;
2507 to
.tv_usec
= (timeout
% 1000) * 1000;
2509 selrtn
= sys_select(&fds
,&to
);
2511 /* Check if error */
2514 /* something is wrong. Maybe the socket is dead? */
2515 smb_read_error
= READ_ERROR
;
2519 /* Did we timeout ? */
2522 smb_read_error
= READ_TIMEOUT
;
2528 * Read a loopback udp message.
2530 msg_len
= recvfrom(fd
, &buffer
[UDP_CMD_HEADER_LEN
],
2531 buffer_len
- UDP_CMD_HEADER_LEN
, 0,
2532 (struct sockaddr
*)&from
, &fromlen
);
2536 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno
)));
2540 /* Validate message length. */
2541 if(msg_len
> (buffer_len
- UDP_CMD_HEADER_LEN
))
2543 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2545 buffer_len
- UDP_CMD_HEADER_LEN
));
2549 /* Validate message from address (must be localhost). */
2550 if(from
.sin_addr
.s_addr
!= htonl(INADDR_LOOPBACK
))
2552 DEBUG(0,("receive_local_message: invalid 'from' address \
2553 (was %x should be 127.0.0.1\n", from
.sin_addr
.s_addr
));
2557 /* Setup the message header */
2558 SIVAL(buffer
,UDP_CMD_LEN_OFFSET
,msg_len
);
2559 SSVAL(buffer
,UDP_CMD_PORT_OFFSET
,ntohs(from
.sin_port
));
2564 /****************************************************************************
2565 structure to hold a linked list of local messages.
2567 ****************************************************************************/
2569 typedef struct _message_list
{
2570 struct _message_list
*msg_next
;
2573 } pending_message_list
;
2575 static pending_message_list
*smb_msg_head
= NULL
;
2577 /****************************************************************************
2578 Function to push a linked list of local messages ready
2580 ****************************************************************************/
2582 static BOOL
push_local_message(pending_message_list
**pml
, char *buf
, int msg_len
)
2584 pending_message_list
*msg
= (pending_message_list
*)
2585 malloc(sizeof(pending_message_list
));
2589 DEBUG(0,("push_message: malloc fail (1)\n"));
2593 msg
->msg_buf
= (char *)malloc(msg_len
);
2594 if(msg
->msg_buf
== NULL
)
2596 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2601 memcpy(msg
->msg_buf
, buf
, msg_len
);
2602 msg
->msg_len
= msg_len
;
2604 msg
->msg_next
= *pml
;
2610 /****************************************************************************
2611 Function to push a linked list of local smb messages ready
2613 ****************************************************************************/
2615 BOOL
push_smb_message(char *buf
, int msg_len
)
2617 return push_local_message(&smb_msg_head
, buf
, msg_len
);
2620 /****************************************************************************
2621 Do a select on an two fd's - with timeout.
2623 If a local udp message has been pushed onto the
2624 queue (this can only happen during oplock break
2625 processing) return this first.
2627 If a pending smb message has been pushed onto the
2628 queue (this can only happen during oplock break
2629 processing) return this next.
2631 If the first smbfd is ready then read an smb from it.
2632 if the second (loopback UDP) fd is ready then read a message
2633 from it and setup the buffer header to identify the length
2635 Returns False on timeout or error.
2638 The timeout is in milli seconds
2639 ****************************************************************************/
2640 BOOL
receive_message_or_smb(int smbfd
, int oplock_fd
,
2641 char *buffer
, int buffer_len
,
2642 int timeout
, BOOL
*got_smb
)
2653 * Check to see if we already have a message on the smb queue.
2654 * If so - copy and return it.
2659 pending_message_list
*msg
= smb_msg_head
;
2660 memcpy(buffer
, msg
->msg_buf
, MIN(buffer_len
, msg
->msg_len
));
2661 smb_msg_head
= msg
->msg_next
;
2663 /* Free the message we just copied. */
2664 free((char *)msg
->msg_buf
);
2668 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2674 FD_SET(oplock_fd
,&fds
);
2676 to
.tv_sec
= timeout
/ 1000;
2677 to
.tv_usec
= (timeout
% 1000) * 1000;
2679 selrtn
= sys_select(&fds
,timeout
>0?&to
:NULL
);
2681 /* Check if error */
2683 /* something is wrong. Maybe the socket is dead? */
2684 smb_read_error
= READ_ERROR
;
2688 /* Did we timeout ? */
2690 smb_read_error
= READ_TIMEOUT
;
2694 if (FD_ISSET(smbfd
,&fds
))
2697 return receive_smb(smbfd
, buffer
, 0);
2701 return receive_local_message(oplock_fd
, buffer
, buffer_len
, 0);
2705 /****************************************************************************
2707 ****************************************************************************/
2708 BOOL
send_smb(int fd
,char *buffer
)
2712 len
= smb_len(buffer
) + 4;
2714 while (nwritten
< len
)
2716 ret
= write_socket(fd
,buffer
+nwritten
,len
- nwritten
);
2719 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len
,ret
));
2731 /****************************************************************************
2732 find a pointer to a netbios name
2733 ****************************************************************************/
2734 char *name_ptr(char *buf
,int ofs
)
2736 unsigned char c
= *(unsigned char *)(buf
+ofs
);
2738 if ((c
& 0xC0) == 0xC0)
2742 memcpy(p
,buf
+ofs
,2);
2745 DEBUG(5,("name ptr to pos %d from %d is %s\n",l
,ofs
,buf
+l
));
2752 /****************************************************************************
2753 extract a netbios name from a buf
2754 ****************************************************************************/
2755 int name_extract(char *buf
,int ofs
,char *name
)
2757 char *p
= name_ptr(buf
,ofs
);
2758 int d
= PTR_DIFF(p
,buf
+ofs
);
2760 if (d
< -50 || d
> 50) return(0);
2761 return(name_interpret(p
,name
));
2764 /****************************************************************************
2765 return the total storage length of a mangled name
2766 ****************************************************************************/
2767 int name_len( char *s
)
2771 /* If the two high bits of the byte are set, return 2. */
2772 if( 0xC0 == (*(unsigned char *)s
& 0xC0) )
2775 /* Add up the length bytes. */
2776 for( len
= 1; (*s
); s
+= (*s
) + 1 )
2784 /****************************************************************************
2785 send a single packet to a port on another machine
2786 ****************************************************************************/
2787 BOOL
send_one_packet(char *buf
,int len
,struct in_addr ip
,int port
,int type
)
2791 struct sockaddr_in sock_out
;
2796 /* create a socket to write to */
2797 out_fd
= socket(AF_INET
, type
, 0);
2800 DEBUG(0,("socket failed"));
2804 /* set the address and port */
2805 bzero((char *)&sock_out
,sizeof(sock_out
));
2806 putip((char *)&sock_out
.sin_addr
,(char *)&ip
);
2807 sock_out
.sin_port
= htons( port
);
2808 sock_out
.sin_family
= AF_INET
;
2811 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2812 len
,inet_ntoa(ip
),port
,type
==SOCK_DGRAM
?"DGRAM":"STREAM"));
2815 ret
= (sendto(out_fd
,buf
,len
,0,(struct sockaddr
*)&sock_out
,sizeof(sock_out
)) >= 0);
2818 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2819 inet_ntoa(ip
),port
,strerror(errno
)));
2825 /*******************************************************************
2826 sleep for a specified number of milliseconds
2827 ********************************************************************/
2831 struct timeval tval
,t1
,t2
;
2838 tval
.tv_sec
= (t
-tdiff
)/1000;
2839 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
2843 sys_select(&fds
,&tval
);
2846 tdiff
= TvalDiff(&t1
,&t2
);
2850 /****************************************************************************
2851 check if a string is part of a list
2852 ****************************************************************************/
2853 BOOL
in_list(char *s
,char *list
,BOOL casesensitive
)
2858 if (!list
) return(False
);
2860 while (next_token(&p
,tok
,LIST_SEP
))
2862 if (casesensitive
) {
2863 if (strcmp(tok
,s
) == 0)
2866 if (StrCaseCmp(tok
,s
) == 0)
2873 /* this is used to prevent lots of mallocs of size 1 */
2874 static char *null_string
= NULL
;
2876 /****************************************************************************
2877 set a string value, allocing the space for the string
2878 ****************************************************************************/
2879 BOOL
string_init(char **dest
,char *src
)
2890 null_string
= (char *)malloc(1);
2893 *dest
= null_string
;
2897 (*dest
) = (char *)malloc(l
+1);
2898 if ((*dest
) == NULL
) {
2899 DEBUG(0,("Out of memory in string_init\n"));
2908 /****************************************************************************
2910 ****************************************************************************/
2911 void string_free(char **s
)
2913 if (!s
|| !(*s
)) return;
2914 if (*s
== null_string
)
2920 /****************************************************************************
2921 set a string value, allocing the space for the string, and deallocating any
2923 ****************************************************************************/
2924 BOOL
string_set(char **dest
,char *src
)
2928 return(string_init(dest
,src
));
2931 /****************************************************************************
2932 substitute a string for a pattern in another string. Make sure there is
2935 This routine looks for pattern in s and replaces it with
2936 insert. It may do multiple replacements.
2938 return True if a substitution was done.
2939 ****************************************************************************/
2940 BOOL
string_sub(char *s
,char *pattern
,char *insert
)
2946 if (!insert
|| !pattern
|| !s
) return(False
);
2949 lp
= strlen(pattern
);
2950 li
= strlen(insert
);
2952 if (!*pattern
) return(False
);
2954 while (lp
<= ls
&& (p
= strstr(s
,pattern
)))
2957 memmove(p
+li
,p
+lp
,ls
+ 1 - (PTR_DIFF(p
,s
) + lp
));
2958 memcpy(p
,insert
,li
);
2967 /*********************************************************
2968 * Recursive routine that is called by mask_match.
2969 * Does the actual matching.
2970 *********************************************************/
2971 BOOL
do_match(char *str
, char *regexp
, int case_sig
)
2975 for( p
= regexp
; *p
&& *str
; ) {
2982 /* Look for a character matching
2983 the one after the '*' */
2986 return True
; /* Automatic match */
2988 while(*str
&& (case_sig
? (*p
!= *str
) : (toupper(*p
)!=toupper(*str
))))
2990 if(do_match(str
,p
,case_sig
))
3004 if(toupper(*str
) != toupper(*p
))
3014 if (!*p
&& str
[0] == '.' && str
[1] == 0)
3017 if (!*str
&& *p
== '?')
3019 while (*p
== '?') p
++;
3023 if(!*str
&& (*p
== '*' && p
[1] == '\0'))
3029 /*********************************************************
3030 * Routine to match a given string with a regexp - uses
3031 * simplified regexp that takes * and ? only. Case can be
3032 * significant or not.
3033 *********************************************************/
3034 BOOL
mask_match(char *str
, char *regexp
, int case_sig
,BOOL trans2
)
3038 fstring ebase
,eext
,sbase
,sext
;
3042 /* Make local copies of str and regexp */
3043 StrnCpy(p1
,regexp
,sizeof(pstring
)-1);
3044 StrnCpy(p2
,str
,sizeof(pstring
)-1);
3046 if (!strchr(p2
,'.')) {
3051 if (!strchr(p1,'.')) {
3059 string_sub(p1
,"*.*","*");
3060 string_sub(p1
,".*","*");
3064 /* Remove any *? and ** as they are meaningless */
3065 for(p
= p1
; *p
; p
++)
3066 while( *p
== '*' && (p
[1] == '?' ||p
[1] == '*'))
3067 (void)strcpy( &p
[1], &p
[2]);
3069 if (strequal(p1
,"*")) return(True
);
3071 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2
, p1
, case_sig
));
3077 if ((p
=strrchr(p1
,'.'))) {
3086 if (!strequal(p2
,".") && !strequal(p2
,"..") && (p
=strrchr(p2
,'.'))) {
3096 matched
= do_match(sbase
,ebase
,case_sig
) &&
3097 (trans2
|| do_match(sext
,eext
,case_sig
));
3099 DEBUG(8,("mask_match returning %d\n", matched
));
3106 /****************************************************************************
3107 become a daemon, discarding the controlling terminal
3108 ****************************************************************************/
3109 void become_daemon(void)
3111 #ifndef NO_FORK_DEBUG
3115 /* detach from the terminal */
3118 #else /* USE_SETSID */
3121 int i
= open("/dev/tty", O_RDWR
);
3124 ioctl(i
, (int) TIOCNOTTY
, (char *)0);
3128 #endif /* TIOCNOTTY */
3129 #endif /* USE_SETSID */
3130 /* Close fd's 0,1,2. Needed if started by rsh */
3132 #endif /* NO_FORK_DEBUG */
3136 /****************************************************************************
3137 put up a yes/no prompt
3138 ****************************************************************************/
3144 if (!fgets(ans
,sizeof(ans
)-1,stdin
))
3147 if (*ans
== 'y' || *ans
== 'Y')
3153 /****************************************************************************
3154 read a line from a file with possible \ continuation chars.
3155 Blanks at the start or end of a line are stripped.
3156 The string will be allocated if s2 is NULL
3157 ****************************************************************************/
3158 char *fgets_slash(char *s2
,int maxlen
,FILE *f
)
3163 BOOL start_of_line
= True
;
3170 maxlen
= MIN(maxlen
,8);
3171 s
= (char *)Realloc(s
,maxlen
);
3174 if (!s
|| maxlen
< 2) return(NULL
);
3178 while (len
< maxlen
-1)
3186 while (len
> 0 && s
[len
-1] == ' ')
3190 if (len
> 0 && s
[len
-1] == '\\')
3193 start_of_line
= True
;
3198 if (len
<= 0 && !s2
)
3200 return(len
>0?s
:NULL
);
3205 start_of_line
= False
;
3209 if (!s2
&& len
> maxlen
-3)
3212 s
= (char *)Realloc(s
,maxlen
);
3213 if (!s
) return(NULL
);
3221 /****************************************************************************
3222 set the length of a file from a filedescriptor.
3223 Returns 0 on success, -1 on failure.
3224 ****************************************************************************/
3225 int set_filelen(int fd
, long len
)
3227 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3228 extend a file with ftruncate. Provide alternate implementation
3231 #if FTRUNCATE_CAN_EXTEND
3232 return ftruncate(fd
, len
);
3236 long currpos
= lseek(fd
, 0L, SEEK_CUR
);
3240 /* Do an fstat to see if the file is longer than
3241 the requested size (call ftruncate),
3242 or shorter, in which case seek to len - 1 and write 1
3244 if(fstat(fd
, &st
)<0)
3248 if (S_ISFIFO(st
.st_mode
)) return 0;
3251 if(st
.st_size
== len
)
3253 if(st
.st_size
> len
)
3254 return ftruncate(fd
, len
);
3256 if(lseek(fd
, len
-1, SEEK_SET
) != len
-1)
3258 if(write(fd
, &c
, 1)!=1)
3260 /* Seek to where we were */
3261 lseek(fd
, currpos
, SEEK_SET
);
3267 /****************************************************************************
3268 return the byte checksum of some data
3269 ****************************************************************************/
3270 int byte_checksum(char *buf
,int len
)
3272 unsigned char *p
= (unsigned char *)buf
;
3282 /****************************************************************************
3283 this is a version of setbuffer() for those machines that only have setvbuf
3284 ****************************************************************************/
3285 void setbuffer(FILE *f
,char *buf
,int bufsize
)
3287 setvbuf(f
,buf
,_IOFBF
,bufsize
);
3292 /****************************************************************************
3293 parse out a directory name from a path name. Assumes dos style filenames.
3294 ****************************************************************************/
3295 char *dirname_dos(char *path
,char *buf
)
3297 char *p
= strrchr(path
,'\\');
3312 /****************************************************************************
3313 parse out a filename from a path name. Assumes dos style filenames.
3314 ****************************************************************************/
3315 static char *filename_dos(char *path
,char *buf
)
3317 char *p
= strrchr(path
,'\\');
3329 /****************************************************************************
3330 expand a pointer to be a particular size
3331 ****************************************************************************/
3332 void *Realloc(void *p
,int size
)
3338 DEBUG(5,("Realloc asked for 0 bytes\n"));
3343 ret
= (void *)malloc(size
);
3345 ret
= (void *)realloc(p
,size
);
3348 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size
));
3354 /****************************************************************************
3356 ****************************************************************************/
3357 char *strdup(char *s
)
3360 if (!s
) return(NULL
);
3361 ret
= (char *)malloc(strlen(s
)+1);
3362 if (!ret
) return(NULL
);
3369 /****************************************************************************
3370 Signal handler for SIGPIPE (write on a disconnected socket)
3371 ****************************************************************************/
3374 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3378 /****************************************************************************
3379 get my own name and IP
3380 ****************************************************************************/
3381 BOOL
get_myname(char *my_name
,struct in_addr
*ip
)
3388 /* get my host name */
3389 if (gethostname(hostname
, MAXHOSTNAMELEN
) == -1)
3391 DEBUG(0,("gethostname failed\n"));
3396 if ((hp
= Get_Hostbyname(hostname
)) == 0)
3398 DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname
));
3404 /* split off any parts after an initial . */
3405 char *p
= strchr(hostname
,'.');
3408 fstrcpy(my_name
,hostname
);
3412 putip((char *)ip
,(char *)hp
->h_addr
);
3418 /****************************************************************************
3419 true if two IP addresses are equal
3420 ****************************************************************************/
3421 BOOL
ip_equal(struct in_addr ip1
,struct in_addr ip2
)
3424 a1
= ntohl(ip1
.s_addr
);
3425 a2
= ntohl(ip2
.s_addr
);
3430 /****************************************************************************
3431 open a socket of the specified type, port and address for incoming data
3432 ****************************************************************************/
3433 int open_socket_in(int type
, int port
, int dlevel
,uint32 socket_addr
)
3436 struct sockaddr_in sock
;
3440 /* get my host name */
3441 if (gethostname(host_name
, MAXHOSTNAMELEN
) == -1)
3442 { DEBUG(0,("gethostname failed\n")); return -1; }
3445 if ((hp
= Get_Hostbyname(host_name
)) == 0)
3447 DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name
));
3451 bzero((char *)&sock
,sizeof(sock
));
3452 memcpy((char *)&sock
.sin_addr
,(char *)hp
->h_addr
, hp
->h_length
);
3453 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3454 sock
.sin_len
= sizeof(sock
);
3456 sock
.sin_port
= htons( port
);
3457 sock
.sin_family
= hp
->h_addrtype
;
3458 sock
.sin_addr
.s_addr
= socket_addr
;
3459 res
= socket(hp
->h_addrtype
, type
, 0);
3461 { DEBUG(0,("socket failed\n")); return -1; }
3465 setsockopt(res
,SOL_SOCKET
,SO_REUSEADDR
,(char *)&one
,sizeof(one
));
3468 /* now we've got a socket - we need to bind it */
3469 if (bind(res
, (struct sockaddr
* ) &sock
,sizeof(sock
)) < 0)
3472 if (port
== SMB_PORT
|| port
== NMB_PORT
)
3473 DEBUG(dlevel
,("bind failed on port %d socket_addr=%s (%s)\n",
3474 port
,inet_ntoa(sock
.sin_addr
),strerror(errno
)));
3477 if (dlevel
> 0 && port
< 1000)
3480 if (port
>= 1000 && port
< 9000)
3481 return(open_socket_in(type
,port
+1,dlevel
,socket_addr
));
3486 DEBUG(3,("bind succeeded on port %d\n",port
));
3492 /****************************************************************************
3493 create an outgoing socket
3494 **************************************************************************/
3495 int open_socket_out(int type
, struct in_addr
*addr
, int port
,int timeout
)
3497 struct sockaddr_in sock_out
;
3499 int connect_loop
= 250; /* 250 milliseconds */
3500 int loops
= (timeout
* 1000) / connect_loop
;
3502 /* create a socket to write to */
3503 res
= socket(PF_INET
, type
, 0);
3505 { DEBUG(0,("socket error\n")); return -1; }
3507 if (type
!= SOCK_STREAM
) return(res
);
3509 bzero((char *)&sock_out
,sizeof(sock_out
));
3510 putip((char *)&sock_out
.sin_addr
,(char *)addr
);
3512 sock_out
.sin_port
= htons( port
);
3513 sock_out
.sin_family
= PF_INET
;
3515 /* set it non-blocking */
3516 set_blocking(res
,False
);
3518 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr
),port
));
3520 /* and connect it to the destination */
3522 ret
= connect(res
,(struct sockaddr
*)&sock_out
,sizeof(sock_out
));
3524 /* Some systems return EAGAIN when they mean EINPROGRESS */
3525 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
3526 errno
== EAGAIN
) && loops
--) {
3527 msleep(connect_loop
);
3531 if (ret
< 0 && (errno
== EINPROGRESS
|| errno
== EALREADY
||
3533 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr
),port
));
3539 if (ret
< 0 && errno
== EISCONN
) {
3546 DEBUG(1,("error connecting to %s:%d (%s)\n",
3547 inet_ntoa(*addr
),port
,strerror(errno
)));
3551 /* set it blocking again */
3552 set_blocking(res
,True
);
3558 /****************************************************************************
3559 interpret a protocol description string, with a default
3560 ****************************************************************************/
3561 int interpret_protocol(char *str
,int def
)
3563 if (strequal(str
,"NT1"))
3564 return(PROTOCOL_NT1
);
3565 if (strequal(str
,"LANMAN2"))
3566 return(PROTOCOL_LANMAN2
);
3567 if (strequal(str
,"LANMAN1"))
3568 return(PROTOCOL_LANMAN1
);
3569 if (strequal(str
,"CORE"))
3570 return(PROTOCOL_CORE
);
3571 if (strequal(str
,"COREPLUS"))
3572 return(PROTOCOL_COREPLUS
);
3573 if (strequal(str
,"CORE+"))
3574 return(PROTOCOL_COREPLUS
);
3576 DEBUG(0,("Unrecognised protocol level %s\n",str
));
3581 /****************************************************************************
3582 interpret a security level
3583 ****************************************************************************/
3584 int interpret_security(char *str
,int def
)
3586 if (strequal(str
,"SERVER"))
3588 if (strequal(str
,"USER"))
3590 if (strequal(str
,"SHARE"))
3593 DEBUG(0,("Unrecognised security level %s\n",str
));
3599 /****************************************************************************
3600 interpret an internet address or name into an IP address in 4 byte form
3601 ****************************************************************************/
3602 uint32
interpret_addr(char *str
)
3607 BOOL pure_address
= True
;
3609 if (strcmp(str
,"0.0.0.0") == 0) return(0);
3610 if (strcmp(str
,"255.255.255.255") == 0) return(0xFFFFFFFF);
3612 for (i
=0; pure_address
&& str
[i
]; i
++)
3613 if (!(isdigit(str
[i
]) || str
[i
] == '.'))
3614 pure_address
= False
;
3616 /* if it's in the form of an IP address then get the lib to interpret it */
3618 res
= inet_addr(str
);
3620 /* otherwise assume it's a network name of some sort and use
3622 if ((hp
= Get_Hostbyname(str
)) == 0) {
3623 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str
));
3626 if(hp
->h_addr
== NULL
) {
3627 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str
));
3630 putip((char *)&res
,(char *)hp
->h_addr
);
3633 if (res
== (uint32
)-1) return(0);
3638 /*******************************************************************
3639 a convenient addition to interpret_addr()
3640 ******************************************************************/
3641 struct in_addr
*interpret_addr2(char *str
)
3643 static struct in_addr ret
;
3644 uint32 a
= interpret_addr(str
);
3649 /*******************************************************************
3650 check if an IP is the 0.0.0.0
3651 ******************************************************************/
3652 BOOL
zero_ip(struct in_addr ip
)
3655 putip((char *)&a
,(char *)&ip
);
3660 /*******************************************************************
3661 matchname - determine if host name matches IP address
3662 ******************************************************************/
3663 static BOOL
matchname(char *remotehost
,struct in_addr addr
)
3668 if ((hp
= Get_Hostbyname(remotehost
)) == 0) {
3669 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost
));
3674 * Make sure that gethostbyname() returns the "correct" host name.
3675 * Unfortunately, gethostbyname("localhost") sometimes yields
3676 * "localhost.domain". Since the latter host name comes from the
3677 * local DNS, we just have to trust it (all bets are off if the local
3678 * DNS is perverted). We always check the address list, though.
3681 if (strcasecmp(remotehost
, hp
->h_name
)
3682 && strcasecmp(remotehost
, "localhost")) {
3683 DEBUG(0,("host name/name mismatch: %s != %s",
3684 remotehost
, hp
->h_name
));
3688 /* Look up the host address in the address list we just got. */
3689 for (i
= 0; hp
->h_addr_list
[i
]; i
++) {
3690 if (memcmp(hp
->h_addr_list
[i
], (caddr_t
) & addr
, sizeof(addr
)) == 0)
3695 * The host name does not map to the original host address. Perhaps
3696 * someone has compromised a name server. More likely someone botched
3697 * it, but that could be dangerous, too.
3700 DEBUG(0,("host name/address mismatch: %s != %s",
3701 inet_ntoa(addr
), hp
->h_name
));
3705 /*******************************************************************
3706 Reset the 'done' variables so after a client process is created
3707 from a fork call these calls will be re-done. This should be
3708 expanded if more variables need reseting.
3709 ******************************************************************/
3711 static BOOL global_client_name_done
= False
;
3712 static BOOL global_client_addr_done
= False
;
3714 void reset_globals_after_fork()
3716 global_client_name_done
= False
;
3717 global_client_addr_done
= False
;
3720 /*******************************************************************
3721 return the DNS name of the client
3722 ******************************************************************/
3723 char *client_name(int fd
)
3726 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3727 int length
= sizeof(sa
);
3728 static pstring name_buf
;
3730 static int last_fd
=-1;
3732 if (global_client_name_done
&& last_fd
== fd
)
3736 global_client_name_done
= False
;
3738 strcpy(name_buf
,"UNKNOWN");
3744 if (getpeername(fd
, &sa
, &length
) < 0) {
3745 DEBUG(0,("getpeername failed\n"));
3749 /* Look up the remote host name. */
3750 if ((hp
= gethostbyaddr((char *) &sockin
->sin_addr
,
3751 sizeof(sockin
->sin_addr
),
3753 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd
)));
3754 StrnCpy(name_buf
,client_addr(fd
),sizeof(name_buf
) - 1);
3756 StrnCpy(name_buf
,(char *)hp
->h_name
,sizeof(name_buf
) - 1);
3757 if (!matchname(name_buf
, sockin
->sin_addr
)) {
3758 DEBUG(0,("Matchname failed on %s %s\n",name_buf
,client_addr(fd
)));
3759 strcpy(name_buf
,"UNKNOWN");
3762 global_client_name_done
= True
;
3766 /*******************************************************************
3767 return the IP addr of the client as a string
3768 ******************************************************************/
3769 char *client_addr(int fd
)
3772 struct sockaddr_in
*sockin
= (struct sockaddr_in
*) (&sa
);
3773 int length
= sizeof(sa
);
3774 static fstring addr_buf
;
3775 static int last_fd
= -1;
3777 if (global_client_addr_done
&& fd
== last_fd
)
3781 global_client_addr_done
= False
;
3783 strcpy(addr_buf
,"0.0.0.0");
3789 if (getpeername(fd
, &sa
, &length
) < 0) {
3790 DEBUG(0,("getpeername failed\n"));
3794 fstrcpy(addr_buf
,(char *)inet_ntoa(sockin
->sin_addr
));
3796 global_client_addr_done
= True
;
3800 /*******************************************************************
3801 Patch from jkf@soton.ac.uk
3802 Split Luke's automount_server into YP lookup and string splitter
3803 so can easily implement automount_path().
3804 As we may end up doing both, cache the last YP result.
3805 *******************************************************************/
3807 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3808 static char *automount_lookup(char *user_name
)
3810 static fstring last_key
= "";
3811 static pstring last_value
= "";
3813 int nis_error
; /* returned by yp all functions */
3814 char *nis_result
; /* yp_match inits this */
3815 int nis_result_len
; /* and set this */
3816 char *nis_domain
; /* yp_get_default_domain inits this */
3817 char *nis_map
= (char *)lp_nis_home_map_name();
3819 if ((nis_error
= yp_get_default_domain(&nis_domain
)) != 0)
3821 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error
)));
3825 DEBUG(5, ("NIS Domain: %s\n", nis_domain
));
3827 if (!strcmp(user_name
, last_key
))
3829 nis_result
= last_value
;
3830 nis_result_len
= strlen(last_value
);
3835 if ((nis_error
= yp_match(nis_domain
, nis_map
,
3836 user_name
, strlen(user_name
),
3837 &nis_result
, &nis_result_len
)) != 0)
3839 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3840 yperr_string(nis_error
), user_name
, nis_map
));
3842 if (!nis_error
&& nis_result_len
>= sizeof(pstring
))
3844 nis_result_len
= sizeof(pstring
)-1;
3846 fstrcpy(last_key
, user_name
);
3847 strncpy(last_value
, nis_result
, nis_result_len
);
3848 last_value
[nis_result_len
] = '\0';
3851 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name
, last_value
));
3856 /*******************************************************************
3857 Patch from jkf@soton.ac.uk
3858 This is Luke's original function with the NIS lookup code
3859 moved out to a separate function.
3860 *******************************************************************/
3862 char *automount_server(char *user_name
)
3864 static pstring server_name
;
3865 int home_server_len
;
3867 /* use the local machine name as the default */
3868 /* this will be the default if AUTOMOUNT is not used or fails */
3869 pstrcpy(server_name
, local_machine
);
3871 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3873 if (lp_nis_home_map())
3875 char *automount_value
= automount_lookup(user_name
);
3876 home_server_len
= strcspn(automount_value
,":");
3877 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len
));
3878 if (home_server_len
> sizeof(pstring
))
3880 home_server_len
= sizeof(pstring
);
3882 strncpy(server_name
, automount_value
, home_server_len
);
3883 server_name
[home_server_len
] = '\0';
3887 DEBUG(4,("Home server: %s\n", server_name
));
3892 /*******************************************************************
3893 Patch from jkf@soton.ac.uk
3894 Added this to implement %p (NIS auto-map version of %H)
3895 *******************************************************************/
3897 char *automount_path(char *user_name
)
3899 static pstring server_path
;
3900 char *home_path_start
;
3902 /* use the passwd entry as the default */
3903 /* this will be the default if AUTOMOUNT is not used or fails */
3904 /* pstrcpy() copes with get_home_dir() returning NULL */
3905 pstrcpy(server_path
, get_home_dir(user_name
));
3907 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3909 if (lp_nis_home_map())
3911 char *automount_value
= automount_lookup(user_name
);
3912 home_path_start
= strchr(automount_value
,':');
3913 if (home_path_start
!= NULL
)
3915 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3916 home_path_start
?(home_path_start
+1):""));
3917 strcpy(server_path
, home_path_start
+1);
3922 DEBUG(4,("Home server path: %s\n", server_path
));
3928 /*******************************************************************
3929 sub strings with useful parameters
3930 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3931 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3932 ********************************************************************/
3933 void standard_sub_basic(char *str
)
3937 struct passwd
*pass
;
3938 char *username
= sam_logon_in_ssb
? samlogon_user
: sesssetup_user
;
3940 for (s
= str
; s
&& *s
&& (p
= strchr(s
,'%')); s
= p
)
3946 if ((pass
= Get_Pwnam(sesssetup_user
,False
))!=NULL
)
3948 string_sub(p
,"%G",gidtoname(pass
->pw_gid
));
3956 case 'N' : string_sub(p
,"%N", automount_server(username
)); break;
3957 case 'I' : string_sub(p
,"%I", client_addr(Client
)); break;
3958 case 'L' : string_sub(p
,"%L", local_machine
); break;
3959 case 'M' : string_sub(p
,"%M", client_name(Client
)); break;
3960 case 'R' : string_sub(p
,"%R", remote_proto
); break;
3961 case 'T' : string_sub(p
,"%T", timestring()); break;
3962 case 'U' : string_sub(p
,"%U", username
); break;
3963 case 'a' : string_sub(p
,"%a", remote_arch
); break;
3966 sprintf(pidstr
,"%d",(int)getpid());
3967 string_sub(p
,"%d", pidstr
);
3970 case 'h' : string_sub(p
,"%h", myhostname
); break;
3971 case 'm' : string_sub(p
,"%m", remote_machine
); break;
3972 case 'v' : string_sub(p
,"%v", VERSION
); break;
3973 case '$' : /* Expand environment variables */
3975 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3981 if (*(p
+2) != '(') { p
+=2; break; }
3982 if ((q
= strchr(p
,')')) == NULL
)
3984 DEBUG(0,("standard_sub_basic: Unterminated environment \
3985 variable [%s]\n", p
));
3990 copylen
= MIN((q
-r
),(sizeof(envname
)-1));
3991 strncpy(envname
,r
,copylen
);
3992 envname
[copylen
] = '\0';
3993 if ((envval
= getenv(envname
)) == NULL
)
3995 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3999 copylen
= MIN((q
+1-p
),(sizeof(envname
)-1));
4000 strncpy(envname
,p
,copylen
);
4001 envname
[copylen
] = '\0';
4002 string_sub(p
,envname
,envval
);
4005 case '\0': p
++; break; /* don't run off end if last character is % */
4006 default : p
+=2; break;
4012 /*******************************************************************
4013 are two IPs on the same subnet?
4014 ********************************************************************/
4015 BOOL
same_net(struct in_addr ip1
,struct in_addr ip2
,struct in_addr mask
)
4017 uint32 net1
,net2
,nmask
;
4019 nmask
= ntohl(mask
.s_addr
);
4020 net1
= ntohl(ip1
.s_addr
);
4021 net2
= ntohl(ip2
.s_addr
);
4023 return((net1
& nmask
) == (net2
& nmask
));
4027 /*******************************************************************
4028 write a string in unicoode format
4029 ********************************************************************/
4030 int PutUniCode(char *dst
,char *src
)
4034 dst
[ret
++] = src
[0];
4043 /****************************************************************************
4044 a wrapper for gethostbyname() that tries with all lower and all upper case
4045 if the initial name fails
4046 ****************************************************************************/
4047 struct hostent
*Get_Hostbyname(char *name
)
4049 char *name2
= strdup(name
);
4050 struct hostent
*ret
;
4054 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4060 * This next test is redundent and causes some systems (with
4061 * broken isalnum() calls) problems.
4066 if (!isalnum(*name2
))
4073 ret
= sys_gethostbyname(name2
);
4080 /* try with all lowercase */
4082 ret
= sys_gethostbyname(name2
);
4089 /* try with all uppercase */
4091 ret
= sys_gethostbyname(name2
);
4098 /* nothing works :-( */
4104 /****************************************************************************
4105 check if a process exists. Does this work on all unixes?
4106 ****************************************************************************/
4107 BOOL
process_exists(int pid
)
4109 return(kill(pid
,0) == 0 || errno
!= ESRCH
);
4113 /*******************************************************************
4114 turn a uid into a user name
4115 ********************************************************************/
4116 char *uidtoname(int uid
)
4118 static char name
[40];
4119 struct passwd
*pass
= getpwuid(uid
);
4120 if (pass
) return(pass
->pw_name
);
4121 sprintf(name
,"%d",uid
);
4125 /*******************************************************************
4126 turn a gid into a group name
4127 ********************************************************************/
4128 char *gidtoname(int gid
)
4130 static char name
[40];
4131 struct group
*grp
= getgrgid(gid
);
4132 if (grp
) return(grp
->gr_name
);
4133 sprintf(name
,"%d",gid
);
4137 /*******************************************************************
4139 ********************************************************************/
4140 void BlockSignals(BOOL block
,int signum
)
4143 int block_mask
= sigmask(signum
);
4144 static int oldmask
= 0;
4146 oldmask
= sigblock(block_mask
);
4148 sigsetmask(oldmask
);
4149 #elif defined(USE_SIGPROCMASK)
4152 sigaddset(&set
,signum
);
4153 sigprocmask(block
?SIG_BLOCK
:SIG_UNBLOCK
,&set
,NULL
);
4158 /*******************************************************************
4159 my own panic function - not suitable for general use
4160 ********************************************************************/
4161 void ajt_panic(void)
4163 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4168 #define DIRECT direct
4170 #define DIRECT dirent
4173 /*******************************************************************
4174 a readdir wrapper which just returns the file name
4175 also return the inode number if requested
4176 ********************************************************************/
4177 char *readdirname(void *p
)
4182 if (!p
) return(NULL
);
4184 ptr
= (struct DIRECT
*)readdir(p
);
4185 if (!ptr
) return(NULL
);
4187 dname
= ptr
->d_name
;
4190 if (telldir(p
) < 0) return(NULL
);
4194 /* this handles a broken compiler setup, causing a mixture
4195 of BSD and SYSV headers and libraries */
4197 static BOOL broken_readdir
= False
;
4198 if (!broken_readdir
&& !(*(dname
)) && strequal("..",dname
-2))
4200 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4201 broken_readdir
= True
;
4210 pstrcpy(buf
, dname
);
4211 unix_to_dos(buf
, True
);
4218 /*******************************************************************
4219 Utility function used to decide if the last component
4220 of a path matches a (possibly wildcarded) entry in a namelist.
4221 ********************************************************************/
4223 BOOL
is_in_path(char *name
, name_compare_entry
*namelist
)
4225 pstring last_component
;
4228 DEBUG(8, ("is_in_path: %s\n", name
));
4230 /* if we have no list it's obviously not in the path */
4231 if((namelist
== NULL
) || ((namelist
!= NULL
) && (namelist
[0].name
== NULL
)))
4233 DEBUG(8,("is_in_path: no name list.\n"));
4237 /* Get the last component of the unix name. */
4238 p
= strrchr(name
, '/');
4239 strncpy(last_component
, p
? p
: name
, sizeof(last_component
)-1);
4240 last_component
[sizeof(last_component
)-1] = '\0';
4242 for(; namelist
->name
!= NULL
; namelist
++)
4244 if(namelist
->is_wild
)
4246 /* look for a wildcard match. */
4247 if (mask_match(last_component
, namelist
->name
, case_sensitive
, False
))
4249 DEBUG(8,("is_in_path: mask match succeeded\n"));
4255 if((case_sensitive
&& (strcmp(last_component
, namelist
->name
) == 0))||
4256 (!case_sensitive
&& (StrCaseCmp(last_component
, namelist
->name
) == 0)))
4258 DEBUG(8,("is_in_path: match succeeded\n"));
4263 DEBUG(8,("is_in_path: match not found\n"));
4268 /*******************************************************************
4269 Strip a '/' separated list into an array of
4270 name_compare_enties structures suitable for
4271 passing to is_in_path(). We do this for
4272 speed so we can pre-parse all the names in the list
4273 and don't do it for each call to is_in_path().
4274 namelist is modified here and is assumed to be
4275 a copy owned by the caller.
4276 We also check if the entry contains a wildcard to
4277 remove a potentially expensive call to mask_match
4279 ********************************************************************/
4281 void set_namearray(name_compare_entry
**ppname_array
, char *namelist
)
4284 char *nameptr
= namelist
;
4285 int num_entries
= 0;
4288 (*ppname_array
) = NULL
;
4290 if((nameptr
== NULL
) || ((nameptr
!= NULL
) && (*nameptr
== '\0')))
4293 /* We need to make two passes over the string. The
4294 first to count the number of elements, the second
4299 if ( *nameptr
== '/' )
4301 /* cope with multiple (useless) /s) */
4305 /* find the next / */
4306 name_end
= strchr(nameptr
, '/');
4308 /* oops - the last check for a / didn't find one. */
4309 if (name_end
== NULL
)
4312 /* next segment please */
4313 nameptr
= name_end
+ 1;
4317 if(num_entries
== 0)
4320 if(( (*ppname_array
) = (name_compare_entry
*)malloc(
4321 (num_entries
+ 1) * sizeof(name_compare_entry
))) == NULL
)
4323 DEBUG(0,("set_namearray: malloc fail\n"));
4327 /* Now copy out the names */
4332 if ( *nameptr
== '/' )
4334 /* cope with multiple (useless) /s) */
4338 /* find the next / */
4339 if ((name_end
= strchr(nameptr
, '/')) != NULL
)
4344 /* oops - the last check for a / didn't find one. */
4345 if(name_end
== NULL
)
4348 (*ppname_array
)[i
].is_wild
= ((strchr( nameptr
, '?')!=NULL
) ||
4349 (strchr( nameptr
, '*')!=NULL
));
4350 if(((*ppname_array
)[i
].name
= strdup(nameptr
)) == NULL
)
4352 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4356 /* next segment please */
4357 nameptr
= name_end
+ 1;
4361 (*ppname_array
)[i
].name
= NULL
;
4366 /****************************************************************************
4367 routine to free a namearray.
4368 ****************************************************************************/
4370 void free_namearray(name_compare_entry
*name_array
)
4375 if(name_array
->name
!= NULL
)
4376 free(name_array
->name
);
4378 free((char *)name_array
);
4381 /****************************************************************************
4382 routine to do file locking
4383 ****************************************************************************/
4384 BOOL
fcntl_lock(int fd
,int op
,uint32 offset
,uint32 count
,int type
)
4391 uint32 mask
= 0xC0000000;
4393 /* make sure the count is reasonable, we might kill the lockd otherwise */
4396 /* the offset is often strange - remove 2 of its bits if either of
4397 the top two bits are set. Shift the top ones by two bits. This
4398 still allows OLE2 apps to operate, but should stop lockd from
4400 if ((offset
& mask
) != 0)
4401 offset
= (offset
& ~mask
) | ((offset
& mask
) >> 2);
4403 uint32 mask
= ((unsigned)1<<31);
4405 /* interpret negative counts as large numbers */
4409 /* no negative offsets */
4412 /* count + offset must be in range */
4413 while ((offset
< 0 || (offset
+ count
< 0)) && mask
)
4421 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd
,op
,(int)offset
,(int)count
,type
));
4424 lock
.l_whence
= SEEK_SET
;
4425 lock
.l_start
= (int)offset
;
4426 lock
.l_len
= (int)count
;
4431 ret
= fcntl(fd
,op
,&lock
);
4434 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno
,strerror(errno
)));
4440 (lock
.l_type
!= F_UNLCK
) &&
4441 (lock
.l_pid
!= 0) &&
4442 (lock
.l_pid
!= getpid()))
4444 DEBUG(3,("fd %d is locked by pid %d\n",fd
,lock
.l_pid
));
4448 /* it must be not locked or locked by me */
4452 /* a lock set or unset */
4455 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4456 offset
,count
,op
,type
,strerror(errno
)));
4458 /* perhaps it doesn't support this sort of locking?? */
4459 if (errno
== EINVAL
)
4461 DEBUG(3,("locking not supported? returning True\n"));
4468 /* everything went OK */
4469 DEBUG(8,("Lock call successful\n"));
4477 /*******************************************************************
4478 lock a file - returning a open file descriptor or -1 on failure
4479 The timeout is in seconds. 0 means no timeout
4480 ********************************************************************/
4481 int file_lock(char *name
,int timeout
)
4483 int fd
= open(name
,O_RDWR
|O_CREAT
,0666);
4485 if (fd
< 0) return(-1);
4488 if (timeout
) t
= time(NULL
);
4489 while (!timeout
|| (time(NULL
)-t
< timeout
)) {
4490 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)) return(fd
);
4491 msleep(LOCK_RETRY_TIMEOUT
);
4499 /*******************************************************************
4500 unlock a file locked by file_lock
4501 ********************************************************************/
4502 void file_unlock(int fd
)
4506 fcntl_lock(fd
,F_SETLK
,0,1,F_UNLCK
);
4511 /*******************************************************************
4512 is the name specified one of my netbios names
4513 returns true is it is equal, false otherwise
4514 ********************************************************************/
4515 BOOL
is_myname(char *s
)
4520 for (n
=0; my_netbios_names
[n
]; n
++) {
4521 if (strequal(my_netbios_names
[n
], s
))
4524 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s
, ret
));
4528 /*******************************************************************
4529 set the horrid remote_arch string based on an enum.
4530 ********************************************************************/
4531 void set_remote_arch(enum remote_arch_types type
)
4537 strcpy(remote_arch
, "WfWg");
4540 strcpy(remote_arch
, "OS2");
4543 strcpy(remote_arch
, "Win95");
4546 strcpy(remote_arch
, "WinNT");
4549 strcpy(remote_arch
,"Samba");
4552 ra_type
= RA_UNKNOWN
;
4553 strcpy(remote_arch
, "UNKNOWN");
4558 /*******************************************************************
4559 Get the remote_arch type.
4560 ********************************************************************/
4561 enum remote_arch_types
get_remote_arch()
4567 /*******************************************************************
4568 skip past some unicode strings in a buffer
4569 ********************************************************************/
4570 char *skip_unicode_string(char *buf
,int n
)
4581 /*******************************************************************
4582 Return a ascii version of a unicode string
4583 Hack alert: uses fixed buffer(s) and only handles ascii strings
4584 ********************************************************************/
4586 char *unistrn2(uint16
*buf
, int len
)
4588 static char lbufs
[8][MAXUNI
];
4590 char *lbuf
= lbufs
[nexti
];
4593 nexti
= (nexti
+1)%8;
4595 DEBUG(10, ("unistrn2: "));
4597 for (p
= lbuf
; *buf
&& p
-lbuf
< MAXUNI
-2 && len
> 0; len
--, p
++, buf
++)
4599 DEBUG(10, ("%4x ", *buf
));
4609 /*******************************************************************
4610 Return a ascii version of a unicode string
4611 Hack alert: uses fixed buffer(s) and only handles ascii strings
4612 ********************************************************************/
4614 char *unistr2(uint16
*buf
)
4616 static char lbufs
[8][MAXUNI
];
4618 char *lbuf
= lbufs
[nexti
];
4621 nexti
= (nexti
+1)%8;
4623 DEBUG(10, ("unistr2: "));
4625 for (p
= lbuf
; *buf
&& p
-lbuf
< MAXUNI
-2; p
++, buf
++)
4627 DEBUG(10, ("%4x ", *buf
));
4637 /*******************************************************************
4638 create a null-terminated unicode string from a null-terminated ascii string.
4639 return number of unicode chars copied, excluding the null character.
4641 only handles ascii strings
4642 ********************************************************************/
4644 int struni2(uint16
*p
, char *buf
)
4648 if (p
== NULL
) return 0;
4650 DEBUG(10, ("struni2: "));
4654 for (; *buf
&& len
< MAXUNI
-2; len
++, p
++, buf
++)
4656 DEBUG(10, ("%2x ", *buf
));
4668 /*******************************************************************
4669 Return a ascii version of a unicode string
4670 Hack alert: uses fixed buffer(s) and only handles ascii strings
4671 ********************************************************************/
4673 char *unistr(char *buf
)
4675 static char lbufs
[8][MAXUNI
];
4677 char *lbuf
= lbufs
[nexti
];
4680 nexti
= (nexti
+1)%8;
4682 for (p
= lbuf
; *buf
&& p
-lbuf
< MAXUNI
-2; p
++, buf
+= 2)
4690 /*******************************************************************
4691 strncpy for unicode strings
4692 ********************************************************************/
4693 int unistrncpy(char *dst
, char *src
, int len
)
4697 while (*src
&& len
> 0)
4711 /*******************************************************************
4712 strcpy for unicode strings. returns length (in num of wide chars)
4713 ********************************************************************/
4714 int unistrcpy(char *dst
, char *src
)
4731 /*******************************************************************
4732 safe string copy into a fstring
4733 ********************************************************************/
4734 void fstrcpy(char *dest
, char *src
)
4736 int maxlength
= sizeof(fstring
) - 1;
4738 DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
4747 while (maxlength
-- && *src
)
4751 DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
4756 /*******************************************************************
4757 safe string copy into a pstring
4758 ********************************************************************/
4759 void pstrcpy(char *dest
, char *src
)
4761 int maxlength
= sizeof(pstring
) - 1;
4763 DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
4772 while (maxlength
-- && *src
)
4776 DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
4782 /*******************************************************************
4783 align a pointer to a multiple of 4 bytes
4784 ********************************************************************/
4785 char *align4(char *q
, char *base
)
4789 q
+= 4 - ((q
- base
) & 3);
4794 /*******************************************************************
4795 align a pointer to a multiple of 2 bytes
4796 ********************************************************************/
4797 char *align2(char *q
, char *base
)
4806 /*******************************************************************
4807 align a pointer to a multiple of align_offset bytes. looks like it
4808 will work for offsets of 0, 2 and 4...
4809 ********************************************************************/
4810 char *align_offset(char *q
, char *base
, int align_offset_len
)
4812 int mod
= ((q
- base
) & (align_offset_len
-1));
4813 if (align_offset_len
!= 0 && mod
!= 0)
4815 q
+= align_offset_len
- mod
;
4820 void print_asc(int level
, unsigned char *buf
,int len
)
4824 DEBUG(level
,("%c", isprint(buf
[i
])?buf
[i
]:'.'));
4827 void dump_data(int level
,char *buf1
,int len
)
4829 unsigned char *buf
= (unsigned char *)buf1
;
4833 DEBUG(level
,("[%03X] ",i
));
4835 DEBUG(level
,("%02X ",(int)buf
[i
]));
4837 if (i
%8 == 0) DEBUG(level
,(" "));
4839 print_asc(level
,&buf
[i
-16],8); DEBUG(level
,(" "));
4840 print_asc(level
,&buf
[i
-8],8); DEBUG(level
,("\n"));
4841 if (i
<len
) DEBUG(level
,("[%03X] ",i
));
4849 if (n
>8) DEBUG(level
,(" "));
4850 while (n
--) DEBUG(level
,(" "));
4853 print_asc(level
,&buf
[i
-(i
%16)],n
); DEBUG(level
,(" "));
4855 if (n
>0) print_asc(level
,&buf
[i
-n
],n
);
4856 DEBUG(level
,("\n"));
4860 char *tab_depth(int depth
)
4862 static pstring spaces
;
4863 memset(spaces
, ' ', depth
* 4);
4864 spaces
[depth
* 4] = 0;
4868 /*****************************************************************
4869 Convert a domain SID to an ascii string. (non-reentrant).
4870 *****************************************************************/
4872 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4873 char *dom_sid_to_string(DOM_SID
*sid
)
4875 static pstring sidstr
;
4878 uint32 ia
= (sid
->id_auth
[5]) +
4879 (sid
->id_auth
[4] << 8 ) +
4880 (sid
->id_auth
[3] << 16) +
4881 (sid
->id_auth
[2] << 24);
4883 sprintf(sidstr
, "S-%d-%d", sid
->sid_rev_num
, ia
);
4885 for (i
= 0; i
< sid
->num_auths
; i
++)
4887 sprintf(subauth
, "-%d", sid
->sub_auths
[i
]);
4888 strcat(sidstr
, subauth
);
4891 DEBUG(7,("dom_sid_to_string returning %s\n", sidstr
));