2
* This file has been modified from the original Samba package
3
* by Secure Networks Inc., January and February, 1997. This package and
4
* all code which it is based on falls under the GNU Public License
9
Unix SMB/Netbios implementation.
11
Samba utility functions
12
Copyright (C) Andrew Tridgell 1992-1995
14
This program is free software; you can redistribute it and/or modify
15
it under the terms of the GNU General Public License as published by
16
the Free Software Foundation; either version 2 of the License, or
17
(at your option) any later version.
19
This program is distributed in the hope that it will be useful,
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
GNU General Public License for more details.
24
You should have received a copy of the GNU General Public License
25
along with this program; if not, write to the Free Software
26
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33
#include <sys/socket.h>
42
int Protocol = PROTOCOL_COREPLUS;
46
/* a default finfo structure to ensure all fields are sensible */
47
file_info def_finfo = {-1,0,0,0,0,0,0,""};
49
/* these are some file handles where debug info will be stored */
52
/* the client file descriptor */
55
/* info on the client */
56
struct from_host Client_info=
57
{"UNKNOWN","0.0.0.0",NULL};
59
/* the last IP received from */
60
struct in_addr lastip;
62
/* the last port received from */
65
/* my IP, the broadcast IP and the Netmask */
67
struct in_addr bcast_ip;
68
struct in_addr Netmask;
73
case handling on filenames
75
int case_default = CASE_LOWER;
78
/* size of reads during a direct file to file transfer */
79
int ReadSize = 16*1024;
81
pstring debugf = "/tmp/log.samba";
84
/* the following control case operations - they are put here so the
85
client can link easily */
88
BOOL use_mangled_map = False;
89
BOOL short_case_preserve;
92
fstring remote_machine="";
93
fstring local_machine="";
94
fstring remote_arch="UNKNOWN";
95
fstring remote_proto="UNKNOWN";
96
pstring myhostname="";
97
pstring user_socket_options="";
98
pstring sesssetup_user="";
101
static char *filename_dos(char *path,char *buf);
103
static BOOL stdout_logging = False;
107
#define exit(x) return(0)
110
/*******************************************************************
111
get ready for syslog stuff
112
******************************************************************/
113
void setup_logging(char *pname,BOOL interactive)
117
char *p = strrchr(pname,'/');
119
openlog(pname, LOG_PID, LOG_DAEMON);
123
stdout_logging = True;
129
BOOL append_log=False;
131
/*******************************************************************
132
write an debug message on the debugfile. This is called by the DEBUG
134
********************************************************************/
136
int Debug1(char *format_str, ...)
147
va_start(ap, format_str);
150
format_str = va_arg(ap,char *);
153
if (stdout_logging) {
154
vfprintf(dbf,format_str,ap);
161
static int debug_count=0;
164
if (debug_count == 100) {
165
int maxlog = lp_max_log_size() * 1024;
166
if (dbf && maxlog > 0)
170
if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
171
fclose(dbf); dbf = NULL;
173
if (dbf && file_size(debugf) > maxlog) {
175
fclose(dbf); dbf = NULL;
176
sprintf(name,"%s.old",debugf);
177
sys_rename(debugf,name);
187
if (!lp_syslog_only())
192
dbf = fopen(debugf,"w");
201
if (syslog_level < lp_syslog())
204
* map debug levels to syslog() priorities
205
* note that not all DEBUG(0, ...) calls are
208
static int priority_map[] = {
217
if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
219
priority = LOG_DEBUG;
221
priority = priority_map[syslog_level];
223
vsprintf(msgbuf, format_str, ap);
226
syslog(priority, "%s", msgbuf);
231
if (!lp_syslog_only())
234
vfprintf(dbf,format_str,ap);
243
/****************************************************************************
244
routine to do file locking
245
****************************************************************************/
246
BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
253
uint32 mask = 0xC0000000;
255
/* make sure the count is reasonable, we might kill the lockd otherwise */
258
/* the offset is often strange - remove 2 of its bits if either of
259
the top two bits are set. Shift the top ones by two bits. This
260
still allows OLE2 apps to operate, but should stop lockd from
262
if ((offset & mask) != 0)
263
offset = (offset & ~mask) | ((offset & mask) >> 2);
265
unsigned long mask = ((unsigned)1<<31);
267
/* interpret negative counts as large numbers */
271
/* no negative offsets */
274
/* count + offset must be in range */
275
while ((offset < 0 || (offset + count < 0)) && mask)
283
DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
286
lock.l_whence = SEEK_SET;
287
lock.l_start = (int)offset;
288
lock.l_len = (int)count;
293
ret = fcntl(fd,op,&lock);
296
DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
302
(lock.l_type != F_UNLCK) &&
304
(lock.l_pid != getpid()))
306
DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
310
/* it must be not locked or locked by me */
314
/* a lock set or unset */
317
DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
318
offset,count,op,type,strerror(errno)));
320
/* perhaps it doesn't support this sort of locking?? */
323
DEBUG(3,("locking not supported? returning True\n"));
330
/* everything went OK */
331
DEBUG(5,("Lock call successful\n"));
339
/*******************************************************************
340
lock a file - returning a open file descriptor or -1 on failure
341
The timeout is in seconds. 0 means no timeout
342
********************************************************************/
343
int file_lock(char *name,int timeout)
345
int fd = open(name,O_RDWR|O_CREAT,0666);
347
if (fd < 0) return(-1);
350
if (timeout) t = time(NULL);
351
while (!timeout || (time(NULL)-t < timeout)) {
352
if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
353
msleep(LOCK_RETRY_TIMEOUT);
361
/*******************************************************************
362
unlock a file locked by file_lock
363
********************************************************************/
364
void file_unlock(int fd)
368
fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
373
/*******************************************************************
374
a gettimeofday wrapper
375
********************************************************************/
376
void GetTimeOfDay(struct timeval *tval)
381
gettimeofday(tval,NULL);
385
int extra_time_offset = 0;
387
static int timediff = 0;
389
/*******************************************************************
390
init the time differences
391
********************************************************************/
394
struct tm tm_utc,tm_local;
399
tm_utc = *(gmtime(&t));
400
tm_local = *(localtime(&t));
403
timediff = -tm_local.tm_gmtoff;
405
timediff = mktime(&tm_utc) - mktime(&tm_local);
408
if (serverzone == 0) {
409
serverzone = timediff - DSTDiff(t);
410
DEBUG(4,("Serverzone is %d\n",serverzone));
415
/*******************************************************************
416
return the DST offset for a particular time
417
We keep a table of DST offsets to prevent calling localtime() on each
418
call of this function. This saves a LOT of time on many unixes.
419
********************************************************************/
420
int DSTDiff(time_t t)
422
static struct dst_table {time_t start,end; BOOL is_dst;} *dst_table = NULL;
423
static int table_size = 0;
427
if (t == 0) t = time(NULL);
430
for (i=0;i<table_size;i++)
431
if (t >= dst_table[i].start && t <= dst_table[i].end) break;
434
is_dst = dst_table[i].is_dst;
438
dst_table = (struct dst_table *)Realloc(dst_table,
439
sizeof(dst_table[0])*(i+1));
447
dst_table[i].is_dst = is_dst = (localtime(&t)->tm_isdst?True:False);;
448
dst_table[i].start = dst_table[i].end = t;
450
/* no entry will cover more than 6 months */
451
low = t - 3*30*24*60*60;
452
high = t + 3*30*24*60*60;
454
/* widen the new entry using two bisection searches */
455
while (low+60*60 < dst_table[i].start) {
456
t = low + (dst_table[i].start-low)/2;
457
if ((localtime(&t)->tm_isdst?True:False) == is_dst)
458
dst_table[i].start = t;
463
while (high-60*60 > dst_table[i].end) {
464
t = high + (high-dst_table[i].end)/2;
465
if ((localtime(&t)->tm_isdst?True:False) == is_dst)
466
dst_table[i].end = t;
472
DEBUG(1,("Added DST entry from %s ",
473
asctime(localtime(&dst_table[i].start))));
474
DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)),
475
dst_table[i].is_dst));
480
return((is_dst?60*60:0) - (extra_time_offset*60));
483
/****************************************************************************
484
return the difference between local and GMT time
485
****************************************************************************/
486
int TimeDiff(time_t t)
488
static BOOL initialised = False;
489
if (!initialised) {initialised=True; TimeInit();}
490
return(timediff - DSTDiff(t));
493
/****************************************************************************
494
try to optimise the localtime call, it can be quite expenive on some machines
495
timemul is normally LOCAL_TO_GMT, GMT_TO_LOCAL or 0
496
****************************************************************************/
497
struct tm *LocalTime(time_t *t,int timemul)
502
t2 += timemul * TimeDiff(t2);
508
/****************************************************************************
509
determine if a file descriptor is in fact a socket
510
****************************************************************************/
511
BOOL is_a_socket(int fd)
516
/* evil, but it works */
519
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
524
/****************************************************************************
525
Get the next token from a string, return False if none found
526
handles double-quotes.
527
Based on a routine by GJC@VILLAGE.COM.
528
Extensively modified by Andrew.Tridgell@anu.edu.au
529
****************************************************************************/
530
BOOL next_token(char **ptr,char *buff,char *sep)
532
static char *last_ptr=NULL;
536
if (!ptr) ptr = &last_ptr;
537
if (!ptr) return(False);
541
/* default to simple separators */
542
if (!sep) sep = " \t\n\r";
544
/* find the first non sep char */
545
while(*s && strchr(sep,*s)) s++;
548
if (! *s) return(False);
550
/* copy over the token */
551
for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
559
*ptr = (*s) ? s+1 : s;
566
/*******************************************************************
567
safely copies memory, ensuring no overlap problems.
568
this is only used if the machine does not have it's own memmove().
569
this is not the fastest algorithm in town, but it will do for our
571
********************************************************************/
572
void *MemMove(void *dest,void *src,int size)
576
if (dest==src || !size) return(dest);
578
d = (unsigned long)dest;
579
s = (unsigned long)src;
581
if ((d >= (s+size)) || (s >= (d+size))) {
583
memcpy(dest,src,size);
589
/* we can forward copy */
590
if (s-d >= sizeof(int) &&
591
!(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
592
/* do it all as words */
593
int *idest = (int *)dest;
594
int *isrc = (int *)src;
596
for (i=0;i<size;i++) idest[i] = isrc[i];
599
char *cdest = (char *)dest;
600
char *csrc = (char *)src;
601
for (i=0;i<size;i++) cdest[i] = csrc[i];
606
/* must backward copy */
607
if (d-s >= sizeof(int) &&
608
!(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
609
/* do it all as words */
610
int *idest = (int *)dest;
611
int *isrc = (int *)src;
613
for (i=size-1;i>=0;i--) idest[i] = isrc[i];
616
char *cdest = (char *)dest;
617
char *csrc = (char *)src;
618
for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
625
/****************************************************************************
626
prompte a dptr (to make it recently used)
627
****************************************************************************/
628
void array_promote(char *array,int elsize,int element)
634
p = (char *)malloc(elsize);
638
DEBUG(5,("Ahh! Can't malloc\n"));
641
memcpy(p,array + element * elsize, elsize);
642
memmove(array + elsize,array,elsize*element);
643
memcpy(array,p,elsize);
647
enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
656
} socket_options[] = {
657
{"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
658
{"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
659
{"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
661
{"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
663
#ifdef IPTOS_LOWDELAY
664
{"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
666
#ifdef IPTOS_THROUGHPUT
667
{"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
670
{"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
673
{"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
676
{"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
679
{"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
685
/****************************************************************************
686
set user socket options
687
****************************************************************************/
688
void set_socket_options(int fd, char *options)
692
while (next_token(&options,tok," \t,"))
697
BOOL got_value = False;
699
if ((p = strchr(tok,'=')))
706
for (i=0;socket_options[i].name;i++)
707
if (strequal(socket_options[i].name,tok))
710
if (!socket_options[i].name)
712
DEBUG(0,("Unknown socket option %s\n",tok));
716
switch (socket_options[i].opttype)
720
ret = setsockopt(fd,socket_options[i].level,
721
socket_options[i].option,(char *)&value,sizeof(int));
726
DEBUG(0,("syntax error - %s does not take a value\n",tok));
729
int on = socket_options[i].value;
730
ret = setsockopt(fd,socket_options[i].level,
731
socket_options[i].option,(char *)&on,sizeof(int));
737
DEBUG(0,("Failed to set socket option %s\n",tok));
743
/****************************************************************************
744
close the socket communication
745
****************************************************************************/
746
void close_sockets(void )
756
/****************************************************************************
757
return the date and time as a string
758
****************************************************************************/
759
char *timestring(void )
761
static char TimeBuf[100];
765
strcpy(TimeBuf, asctime(LocalTime(&t,GMT_TO_LOCAL)));
766
#elif defined(CLIX) || defined(CONVEX)
767
strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",LocalTime(&t,GMT_TO_LOCAL));
769
strftime(TimeBuf,100,"%D %r",LocalTime(&t,GMT_TO_LOCAL));
770
#elif defined(TZ_TIME)
772
strftime(TimeBuf,100,"%D:%T",LocalTime(&t,0));
773
sprintf(TimeBuf+strlen(TimeBuf)," %+03d%02d",
774
-TimeDiff(t)/(60*60),-(TimeDiff(t)/60)%60);
777
strftime(TimeBuf,100,"%D %T",LocalTime(&t,GMT_TO_LOCAL));
782
/****************************************************************************
783
determine whether we are in the specified group
784
****************************************************************************/
785
BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
789
if (group == current_gid) return(True);
791
for (i=0;i<ngroups;i++)
792
if (group == groups[i])
798
/****************************************************************************
799
this is a safer strcpy(), meant to prevent core dumps when nasty things happen
800
****************************************************************************/
801
char *StrCpy(char *dest,char *src)
806
/* I don't want to get lazy with these ... */
808
DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
813
if (!dest) return(NULL);
818
while ((*d++ = *src++)) ;
822
/****************************************************************************
823
line strncpy but always null terminates. Make sure there is room!
824
****************************************************************************/
825
char *StrnCpy(char *dest,const char *src,int n)
828
if (!dest) return(NULL);
833
while (n-- && (*d++ = *src++)) ;
839
/*******************************************************************
840
copy an IP address from one buffer to another
841
********************************************************************/
842
void putip(void *dest,void *src)
848
/****************************************************************************
849
interpret the weird netbios "name". Return the name type
850
****************************************************************************/
851
static int name_interpret(char *in,char *out)
854
int len = (*in++) / 2;
858
if (len > 30 || len<1) return(0);
862
if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
866
*out = ((in[0]-'A')<<4) + (in[1]-'A');
874
/* Handle any scope names */
877
*out++ = '.'; /* Scope names are separated by periods */
878
len = *(unsigned char *)in++;
879
StrnCpy(out, in, len);
888
/****************************************************************************
889
mangle a name into netbios format
890
****************************************************************************/
891
int name_mangle(char *In,char *Out,char name_type)
895
char *in = (char *)&buf[0];
896
char *out = (char *)Out;
901
if ((In[0] == '*') && (In[1] == '\0')) {
903
memset(&buf[1],0,16);
905
StrnCpy(name,In,sizeof(name)-1);
906
sprintf(buf,"%-15.15s%c",name,name_type);
910
StrnCpy(name,In,sizeof(name)-1);
911
sprintf(buf,"%-15.15s%c",name,name_type);
914
memset(&buf[1],0,16);
920
char c = toupper(in[i]);
921
out[i*2] = (c>>4) + 'A';
922
out[i*2+1] = (c & 0xF) + 'A';
930
p = strchr(label, '.');
932
p = label + strlen(label);
934
memcpy(out, label, p - label);
936
label += p - label + (*p == '.');
939
return(name_len(Out));
943
/*******************************************************************
944
check if a file exists
945
********************************************************************/
946
BOOL file_exist(char *fname,struct stat *sbuf)
949
if (!sbuf) sbuf = &st;
951
if (sys_stat(fname,sbuf) != 0)
954
return(S_ISREG(sbuf->st_mode));
957
/*******************************************************************
958
check a files mod time
959
********************************************************************/
960
time_t file_modtime(char *fname)
964
if (sys_stat(fname,&st) != 0)
970
/*******************************************************************
971
check if a directory exists
972
********************************************************************/
973
BOOL directory_exist(char *dname,struct stat *st)
978
if (sys_stat(dname,st) != 0)
981
return(S_ISDIR(st->st_mode));
984
/*******************************************************************
985
returns the size in bytes of the named file
986
********************************************************************/
987
uint32 file_size(char *file_name)
991
sys_stat(file_name,&buf);
995
/****************************************************************************
996
check if it's a null mtime
997
****************************************************************************/
998
static BOOL null_mtime(time_t mtime)
1000
if (mtime == 0 || mtime == 0xFFFFFFFF)
1005
/*******************************************************************
1006
create a 16 bit dos packed date
1007
********************************************************************/
1008
static uint16 make_dos_date1(time_t unixdate,struct tm *t)
1011
ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
1012
ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
1016
/*******************************************************************
1017
create a 16 bit dos packed time
1018
********************************************************************/
1019
static uint16 make_dos_time1(time_t unixdate,struct tm *t)
1022
ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3));
1023
ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
1027
/*******************************************************************
1028
create a 32 bit dos packed date/time from some parameters
1029
This takes a GMT time and returns a packed localtime structure
1030
********************************************************************/
1031
static uint32 make_dos_date(time_t unixdate)
1036
t = LocalTime(&unixdate,GMT_TO_LOCAL);
1038
ret = make_dos_date1(unixdate,t);
1039
ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t);
1044
/*******************************************************************
1045
put a dos date into a buffer (time/date format)
1046
This takes GMT time and puts local time in the buffer
1047
********************************************************************/
1048
void put_dos_date(char *buf,int offset,time_t unixdate)
1050
uint32 x = make_dos_date(unixdate);
1051
SIVAL(buf,offset,x);
1054
/*******************************************************************
1055
put a dos date into a buffer (date/time format)
1056
This takes GMT time and puts local time in the buffer
1057
********************************************************************/
1058
void put_dos_date2(char *buf,int offset,time_t unixdate)
1060
uint32 x = make_dos_date(unixdate);
1061
x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
1062
SIVAL(buf,offset,x);
1065
/*******************************************************************
1066
put a dos 32 bit "unix like" date into a buffer. This routine takes
1067
GMT and converts it to LOCAL time before putting it (most SMBs assume
1068
localtime for this sort of date)
1069
********************************************************************/
1070
void put_dos_date3(char *buf,int offset,time_t unixdate)
1072
if (!null_mtime(unixdate))
1073
unixdate += GMT_TO_LOCAL*TimeDiff(unixdate);
1074
SIVAL(buf,offset,unixdate);
1077
/*******************************************************************
1078
interpret a 32 bit dos packed date/time to some parameters
1079
********************************************************************/
1080
static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second)
1084
p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF;
1085
p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
1087
*second = 2*(p0 & 0x1F);
1088
*minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
1089
*hour = (p1>>3)&0xFF;
1091
*month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
1092
*year = ((p3>>1)&0xFF) + 80;
1095
/*******************************************************************
1096
create a unix date (int GMT) from a dos date (which is actually in
1098
********************************************************************/
1099
time_t make_unix_date(void *date_ptr)
1105
dos_date = IVAL(date_ptr,0);
1107
if (dos_date == 0) return(0);
1109
interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
1110
&t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
1115
/* mktime() also does the local to GMT time conversion for us. XXXXX
1116
Do all unixes do this the same?? */
1122
/*******************************************************************
1123
like make_unix_date() but the words are reversed
1124
********************************************************************/
1125
time_t make_unix_date2(void *date_ptr)
1129
x = IVAL(date_ptr,0);
1130
x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
1133
return(make_unix_date((void *)&x));
1136
/*******************************************************************
1137
create a unix GMT date from a dos date in 32 bit "unix like" format
1138
these generally arrive as localtimes, with corresponding DST
1139
********************************************************************/
1140
time_t make_unix_date3(void *date_ptr)
1142
time_t t = IVAL(date_ptr,0);
1144
t += LOCAL_TO_GMT*TimeDiff(t);
1148
/*******************************************************************
1149
return a string representing an attribute for a file
1150
********************************************************************/
1151
char *attrib_string(int mode)
1153
static char attrstr[10];
1157
if (mode & aVOLID) strcat(attrstr,"V");
1158
if (mode & aDIR) strcat(attrstr,"D");
1159
if (mode & aARCH) strcat(attrstr,"A");
1160
if (mode & aHIDDEN) strcat(attrstr,"H");
1161
if (mode & aSYSTEM) strcat(attrstr,"S");
1162
if (mode & aRONLY) strcat(attrstr,"R");
1168
/*******************************************************************
1169
case insensitive string compararison
1170
********************************************************************/
1171
int StrCaseCmp(char *s, char *t)
1173
for (; tolower(*s) == tolower(*t); ++s, ++t)
1176
return tolower(*s) - tolower(*t);
1179
/*******************************************************************
1180
case insensitive string compararison, length limited
1181
********************************************************************/
1182
int StrnCaseCmp(char *s, char *t, int n)
1184
while (n-- && *s && *t) {
1185
if (tolower(*s) != tolower(*t)) return(tolower(*s) - tolower(*t));
1188
if (n) return(tolower(*s) - tolower(*t));
1193
/*******************************************************************
1195
********************************************************************/
1196
BOOL strequal(char *s1,char *s2)
1198
if (!s1 || !s2) return(False);
1200
return(StrCaseCmp(s1,s2)==0);
1203
/*******************************************************************
1204
compare 2 strings up to and including the nth char.
1205
******************************************************************/
1206
BOOL strnequal(char *s1,char *s2,int n)
1208
if (!s1 || !s2 || !n) return(False);
1210
return(StrnCaseCmp(s1,s2,n)==0);
1213
/*******************************************************************
1214
compare 2 strings (case sensitive)
1215
********************************************************************/
1216
BOOL strcsequal(char *s1,char *s2)
1218
if (!s1 || !s2) return(False);
1220
return(strcmp(s1,s2)==0);
1224
/* work around fucking BROKEN bfd libraries */
1225
/* XXX: it was later found that calling charset_initialise fixed it */
1226
void strlower (char * s)
1228
register unsigned int c;
1231
c = (unsigned int) *s;
1237
void strupper (char * s)
1239
register unsigned int c;
1242
c = (unsigned int) *s;
1250
/*******************************************************************
1251
convert a string to lower case
1252
********************************************************************/
1253
void strlower(char *s)
1258
if (is_shift_jis (*s)) {
1260
} else if (is_kana (*s)) {
1275
/*******************************************************************
1276
convert a string to upper case
1277
********************************************************************/
1278
void strupper(char *s)
1283
if (is_shift_jis (*s)) {
1285
} else if (is_kana (*s)) {
1299
#endif /* SCANNER */
1301
/*******************************************************************
1302
convert a string to "normal" form
1303
********************************************************************/
1304
void strnorm(char *s)
1306
if (case_default == CASE_UPPER)
1312
/*******************************************************************
1313
check if a string is in "normal" case
1314
********************************************************************/
1315
BOOL strisnormal(char *s)
1317
if (case_default == CASE_UPPER)
1318
return(!strhaslower(s));
1320
return(!strhasupper(s));
1324
/****************************************************************************
1326
****************************************************************************/
1327
void string_replace(char *s,char oldc,char newc)
1332
if (is_shift_jis (*s)) {
1334
} else if (is_kana (*s)) {
1350
/****************************************************************************
1351
make a file into unix format
1352
****************************************************************************/
1353
void unix_format(char *fname)
1356
string_replace(fname,'\\','/');
1358
dos2unix_format(fname, True);
1363
strcpy(namecopy,fname);
1365
strcat(fname,namecopy);
1369
/****************************************************************************
1370
make a file into dos format
1371
****************************************************************************/
1372
void dos_format(char *fname)
1375
unix2dos_format(fname, True);
1377
string_replace(fname,'/','\\');
1379
#endif /* SCANNER */
1381
/*******************************************************************
1382
show a smb message structure
1383
********************************************************************/
1384
void show_msg(char *buf)
1391
DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1393
(int)CVAL(buf,smb_com),
1394
(int)CVAL(buf,smb_rcls),
1395
(int)CVAL(buf,smb_reh),
1396
(int)SVAL(buf,smb_err),
1397
(int)CVAL(buf,smb_flg),
1398
(int)SVAL(buf,smb_flg2)));
1399
DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1400
(int)SVAL(buf,smb_tid),
1401
(int)SVAL(buf,smb_pid),
1402
(int)SVAL(buf,smb_uid),
1403
(int)SVAL(buf,smb_mid),
1404
(int)CVAL(buf,smb_wct)));
1405
for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1406
DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1407
SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1408
bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1409
DEBUG(5,("smb_bcc=%d\n",bcc));
1410
if (DEBUGLEVEL < 10)
1412
for (i=0;i<MIN(bcc,128);i++)
1413
DEBUG(10,("%X ",CVAL(smb_buf(buf),i)));
1417
/*******************************************************************
1418
return the length of an smb packet
1419
********************************************************************/
1420
int smb_len(char *buf)
1422
return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1425
/*******************************************************************
1426
set the length of an smb packet
1427
********************************************************************/
1428
void _smb_setlen(char *buf,int len)
1431
buf[1] = (len&0x10000)>>16;
1432
buf[2] = (len&0xFF00)>>8;
1436
/*******************************************************************
1437
set the length and marker of an smb packet
1438
********************************************************************/
1439
void smb_setlen(char *buf,int len)
1441
_smb_setlen(buf,len);
1449
/*******************************************************************
1450
setup the word count and byte count for a smb message
1451
********************************************************************/
1452
int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1455
bzero(buf + smb_size,num_words*2 + num_bytes);
1456
CVAL(buf,smb_wct) = num_words;
1457
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1458
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1459
return (smb_size + num_words*2 + num_bytes);
1462
/*******************************************************************
1463
return the number of smb words
1464
********************************************************************/
1465
int smb_numwords(char *buf)
1467
return (CVAL(buf,smb_wct));
1470
/*******************************************************************
1471
return the size of the smb_buf region of a message
1472
********************************************************************/
1473
int smb_buflen(char *buf)
1475
return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1478
/*******************************************************************
1479
return a pointer to the smb_buf data area
1480
********************************************************************/
1481
int smb_buf_ofs(char *buf)
1483
return (smb_size + CVAL(buf,smb_wct)*2);
1486
/*******************************************************************
1487
return a pointer to the smb_buf data area
1488
********************************************************************/
1489
char *smb_buf(char *buf)
1491
return (buf + smb_buf_ofs(buf));
1494
/*******************************************************************
1495
return the SMB offset into an SMB buffer
1496
********************************************************************/
1497
int smb_offset(char *p,char *buf)
1499
return(PTR_DIFF(p,buf+4));
1503
/*******************************************************************
1504
skip past some strings in a buffer
1505
********************************************************************/
1506
char *skip_string(char *buf,int n)
1509
buf += strlen(buf) + 1;
1513
/*******************************************************************
1514
trim the specified elements off the front and back of a string
1515
********************************************************************/
1516
BOOL trim_string(char *s,char *front,char *back)
1519
while (front && *front && strncmp(s,front,strlen(front)) == 0)
1525
if (!(*p = p[strlen(front)]))
1530
while (back && *back && strlen(s) >= strlen(back) &&
1531
(strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1534
s[strlen(s)-strlen(back)] = 0;
1540
/*******************************************************************
1541
reduce a file name, removing .. elements.
1542
********************************************************************/
1543
void dos_clean_name(char *s)
1547
DEBUG(3,("dos_clean_name [%s]\n",s));
1549
/* remove any double slashes */
1550
string_sub(s, "\\\\", "\\");
1552
while ((p = strstr(s,"\\..\\")) != NULL)
1559
if ((p=strrchr(s,'\\')) != NULL)
1566
trim_string(s,NULL,"\\..");
1568
string_sub(s, "\\.\\", "\\");
1571
/*******************************************************************
1572
reduce a file name, removing .. elements.
1573
********************************************************************/
1574
void unix_clean_name(char *s)
1578
DEBUG(3,("unix_clean_name [%s]\n",s));
1580
/* remove any double slashes */
1581
string_sub(s, "//","/");
1583
while ((p = strstr(s,"/../")) != NULL)
1590
if ((p=strrchr(s,'/')) != NULL)
1597
trim_string(s,NULL,"/..");
1601
/*******************************************************************
1602
a wrapper for the normal chdir() function
1603
********************************************************************/
1604
int ChDir(char *path)
1607
static pstring LastDir="";
1609
if (strcsequal(path,".")) return(0);
1611
if (*path == '/' && strcsequal(LastDir,path)) return(0);
1612
DEBUG(3,("chdir to %s\n",path));
1613
res = sys_chdir(path);
1615
strcpy(LastDir,path);
1620
/*******************************************************************
1621
return the absolute current directory path. A dumb version.
1622
********************************************************************/
1623
static char *Dumb_GetWd(char *s)
1626
return ((char *)getcwd(s,sizeof(pstring)));
1628
return ((char *)getwd(s));
1633
/* number of list structures for a caching GetWd function. */
1634
#define MAX_GETWDCACHE (50)
1642
} ino_list[MAX_GETWDCACHE];
1644
BOOL use_getwd_cache=True;
1646
/*******************************************************************
1647
return the absolute current directory path
1648
********************************************************************/
1649
char *GetWd(char *str)
1652
static BOOL getwd_cache_init = False;
1653
struct stat st, st2;
1658
if (!use_getwd_cache)
1659
return(Dumb_GetWd(str));
1661
/* init the cache */
1662
if (!getwd_cache_init)
1664
getwd_cache_init = True;
1665
for (i=0;i<MAX_GETWDCACHE;i++)
1667
string_init(&ino_list[i].text,"");
1668
ino_list[i].valid = False;
1672
/* Get the inode of the current directory, if this doesn't work we're
1675
if (stat(".",&st) == -1)
1677
DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1678
return(Dumb_GetWd(str));
1682
for (i=0; i<MAX_GETWDCACHE; i++)
1683
if (ino_list[i].valid)
1686
/* If we have found an entry with a matching inode and dev number
1687
then find the inode number for the directory in the cached string.
1688
If this agrees with that returned by the stat for the current
1689
directory then all is o.k. (but make sure it is a directory all
1692
if (st.st_ino == ino_list[i].inode &&
1693
st.st_dev == ino_list[i].dev)
1695
if (stat(ino_list[i].text,&st2) == 0)
1697
if (st.st_ino == st2.st_ino &&
1698
st.st_dev == st2.st_dev &&
1699
(st2.st_mode & S_IFMT) == S_IFDIR)
1701
strcpy (str, ino_list[i].text);
1703
/* promote it for future use */
1704
array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1709
/* If the inode is different then something's changed,
1710
scrub the entry and start from scratch. */
1711
ino_list[i].valid = False;
1718
/* We don't have the information to hand so rely on traditional methods.
1719
The very slow getcwd, which spawns a process on some systems, or the
1720
not quite so bad getwd. */
1724
DEBUG(0,("Getwd failed, errno %d\n",errno));
1730
DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1732
/* add it to the cache */
1733
i = MAX_GETWDCACHE - 1;
1734
string_set(&ino_list[i].text,s);
1735
ino_list[i].dev = st.st_dev;
1736
ino_list[i].inode = st.st_ino;
1737
ino_list[i].valid = True;
1739
/* put it at the top of the list */
1740
array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1747
/*******************************************************************
1748
reduce a file name, removing .. elements and checking that
1749
it is below dir in the heirachy. This uses GetWd() and so must be run
1750
on the system that has the referenced file system.
1752
widelinks are allowed if widelinks is true
1753
********************************************************************/
1754
BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1756
#ifndef REDUCE_PATHS
1764
BOOL relative = (*s != '/');
1766
*dir2 = *wd = *basename = *newname = 0;
1771
/* can't have a leading .. */
1772
if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1774
DEBUG(3,("Illegal file name? (%s)\n",s));
1780
DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1782
/* remove any double slashes */
1783
string_sub(s,"//","/");
1786
p = strrchr(basename,'/');
1793
DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1797
if (ChDir(dir) != 0)
1799
DEBUG(0,("couldn't chdir to %s\n",dir));
1805
DEBUG(0,("couldn't getwd for %s\n",dir));
1811
if (p && (p != basename))
1814
if (strcmp(p+1,".")==0)
1816
if (strcmp(p+1,"..")==0)
1820
if (ChDir(basename) != 0)
1823
DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
1827
if (!GetWd(newname))
1830
DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1834
if (p && (p != basename))
1836
strcat(newname,"/");
1837
strcat(newname,p+1);
1841
int l = strlen(dir2);
1842
if (dir2[l-1] == '/')
1845
if (strncmp(newname,dir2,l) != 0)
1848
DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1854
if (newname[l] == '/')
1855
strcpy(s,newname + l + 1);
1857
strcpy(s,newname+l);
1868
DEBUG(3,("reduced to %s\n",s));
1873
/****************************************************************************
1875
****************************************************************************/
1876
static void expand_one(char *Mask,int len)
1879
while ((p1 = strchr(Mask,'*')) != NULL)
1881
int lfill = (len+1) - strlen(Mask);
1882
int l1= (p1 - Mask);
1885
memset(tmp+l1,'?',lfill);
1886
strcpy(tmp + l1 + lfill,Mask + l1 + 1);
1891
/****************************************************************************
1892
expand a wildcard expression, replacing *s with ?s
1893
****************************************************************************/
1894
void expand_mask(char *Mask,BOOL doext)
1899
BOOL hasdot = False;
1901
BOOL absolute = (*Mask == '\\');
1903
*mbeg = *mext = *dirpart = *filepart = 0;
1905
/* parse the directory and filename */
1906
if (strchr(Mask,'\\'))
1907
dirname_dos(Mask,dirpart);
1909
filename_dos(Mask,filepart);
1911
strcpy(mbeg,filepart);
1912
if ((p1 = strchr(mbeg,'.')) != NULL)
1922
if (strlen(mbeg) > 8)
1924
strcpy(mext,mbeg + 8);
1930
strcpy(mbeg,"????????");
1931
if ((*mext == 0) && doext && !hasdot)
1939
strcpy(Mask,dirpart);
1940
if (*dirpart || absolute) strcat(Mask,"\\");
1945
DEBUG(6,("Mask expanded to [%s]\n",Mask));
1949
/****************************************************************************
1950
does a string have any uppercase chars in it?
1951
****************************************************************************/
1952
BOOL strhasupper(char *s)
1957
if (is_shift_jis (*s)) {
1959
} else if (is_kana (*s)) {
1962
if (isupper(*s)) return(True);
1966
if (isupper(*s)) return(True);
1973
/****************************************************************************
1974
does a string have any lowercase chars in it?
1975
****************************************************************************/
1976
BOOL strhaslower(char *s)
1981
if (is_shift_jis (*s)) {
1983
} else if (is_kana (*s)) {
1986
if (islower(*s)) return(True);
1990
if (islower(*s)) return(True);
1997
/****************************************************************************
1998
find the number of chars in a string
1999
****************************************************************************/
2000
int count_chars(char *s,char c)
2013
/****************************************************************************
2015
****************************************************************************/
2016
void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
2023
if ((mode & aDIR) != 0)
2026
memset(buf+1,' ',11);
2027
if ((p = strchr(mask2,'.')) != NULL)
2030
memcpy(buf+1,mask2,MIN(strlen(mask2),8));
2031
memcpy(buf+9,p+1,MIN(strlen(p+1),3));
2035
memcpy(buf+1,mask2,MIN(strlen(mask2),11));
2037
bzero(buf+21,DIR_STRUCT_SIZE-21);
2038
CVAL(buf,21) = mode;
2039
put_dos_date(buf,22,date);
2040
SSVAL(buf,26,size & 0xFFFF);
2041
SSVAL(buf,28,size >> 16);
2042
StrnCpy(buf+30,fname,12);
2043
if (!case_sensitive)
2045
DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2049
/*******************************************************************
2050
close the low 3 fd's and open dev/null in their place
2051
********************************************************************/
2052
void close_low_fds(void)
2056
close(0); close(1); close(2);
2057
/* try and use up these file descriptors, so silly
2058
library routines writing to stdout etc won't cause havoc */
2060
fd = open("/dev/null",O_RDWR,0);
2061
if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2063
DEBUG(0,("Can't open /dev/null\n"));
2067
DEBUG(0,("Didn't get file descriptor %d\n",i));
2074
/****************************************************************************
2076
****************************************************************************/
2077
int write_socket(int fd,char *buf,int len)
2083
DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2084
ret = write_data(fd,buf,len);
2086
DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2090
/****************************************************************************
2092
****************************************************************************/
2093
int read_udp_socket(int fd,char *buf,int len)
2096
struct sockaddr sock;
2099
socklen = sizeof(sock);
2100
bzero((char *)&sock,socklen);
2101
bzero((char *)&lastip,sizeof(lastip));
2102
ret = recvfrom(fd,buf,len,0,&sock,&socklen);
2105
DEBUG(2,("read socket failed. ERRNO=%d\n",errno));
2109
lastip = *(struct in_addr *) &sock.sa_data[2];
2110
lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
2115
/****************************************************************************
2116
Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2118
if SYSV use O_NDELAY
2120
****************************************************************************/
2121
int set_blocking(int fd, BOOL set)
2125
#define FLAG_TO_SET O_NONBLOCK
2128
#define FLAG_TO_SET O_NDELAY
2130
#define FLAG_TO_SET FNDELAY
2134
if((val = fcntl(fd, F_GETFL, 0))==-1)
2136
if(set) /* Turn blocking on - ie. clear nonblock flag */
2137
val &= ~FLAG_TO_SET;
2140
return fcntl( fd, F_SETFL, val);
2145
/****************************************************************************
2146
Calculate the difference in timeout values. Return 1 if val1 > val2,
2147
0 if val1 == val2, -1 if val1 < val2. Stores result in retval. retval
2148
may be == val1 or val2
2149
****************************************************************************/
2150
static int tval_sub( struct timeval *retval, struct timeval *val1, struct timeval *val2)
2152
int usecdiff = val1->tv_usec - val2->tv_usec;
2153
int secdiff = val1->tv_sec - val2->tv_sec;
2155
usecdiff = 1000000 + usecdiff;
2158
retval->tv_sec = secdiff;
2159
retval->tv_usec = usecdiff;
2164
return (usecdiff < 0 ) ? -1 : ((usecdiff > 0 ) ? 1 : 0);
2167
/****************************************************************************
2168
read data from a device with a timout in msec.
2169
mincount = if timeout, minimum to read before returning
2170
maxcount = number to be read.
2171
****************************************************************************/
2172
int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out,BOOL exact)
2178
struct timeval timeout, tval1, tval2, tvaldiff;
2180
/* just checking .... */
2181
if (maxcnt <= 0) return(0);
2184
time_out = DEFAULT_PIPE_TIMEOUT;
2188
if (mincnt == 0) mincnt = maxcnt;
2190
while (nread < mincnt)
2192
readret = read(fd, buf + nread, maxcnt - nread);
2193
if (readret <= 0) return(nread);
2199
/* Non blocking read */
2201
set_blocking(fd, False);
2202
nread = read_data(fd, buf, mincnt);
2204
nread += read(fd,buf+nread,maxcnt-nread);
2205
if(nread == -1 && errno == EWOULDBLOCK)
2207
set_blocking(fd,True);
2211
/* Most difficult - timeout read */
2212
/* If this is ever called on a disk file and
2213
mincnt is greater then the filesize then
2214
system performance will suffer severely as
2215
select always return true on disk files */
2217
/* Set initial timeout */
2218
timeout.tv_sec = time_out / 1000;
2219
timeout.tv_usec = 1000 * (time_out % 1000);
2221
/* As most UNIXes don't modify the value of timeout
2222
when they return from select we need to get the timeofday (in usec)
2223
now, and also after the select returns so we know
2224
how much time has elapsed */
2227
GetTimeOfDay( &tval1);
2228
nread = 0; /* Number of bytes we have read */
2236
selrtn = sys_select(&fds,&timeout);
2238
/* Check if error */
2245
/* Did we timeout ? */
2247
if (nread < mincnt) return -1;
2251
readret = read( fd, buf+nread, maxcnt-nread);
2254
/* force a particular error number for
2265
/* If we have read more than mincnt then return */
2266
if( nread >= mincnt )
2269
/* We need to do another select - but first reduce the
2270
time_out by the amount of time already elapsed - if
2271
this is less than zero then return */
2274
GetTimeOfDay( &tval2);
2275
(void)tval_sub( &tvaldiff, &tval2, &tval1);
2277
if( tval_sub( &timeout, &timeout, &tvaldiff) <= 0)
2284
/* Save the time of day as we need to do the select
2285
again (saves a system call)*/
2289
/* Return the number we got */
2293
/****************************************************************************
2294
read data from the client. Maxtime is in milliseconds
2295
****************************************************************************/
2296
int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2301
struct timeval timeout;
2306
timeout.tv_sec = maxtime / 1000;
2307
timeout.tv_usec = (maxtime % 1000) * 1000;
2309
selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2311
if (!FD_ISSET(fd,&fds))
2314
nread = read_udp_socket(fd, buffer, bufsize);
2316
/* return the number got */
2320
/*******************************************************************
2321
find the difference in milliseconds between two struct timeval
2323
********************************************************************/
2324
int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2326
return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2327
((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2330
/****************************************************************************
2331
send a keepalive packet (rfc1002)
2332
****************************************************************************/
2333
BOOL send_keepalive(int client)
2335
unsigned char buf[4];
2338
buf[1] = buf[2] = buf[3] = 0;
2340
return(write_data(client,(char *)buf,4) == 4);
2345
/****************************************************************************
2346
read data from the client, reading exactly N bytes.
2347
****************************************************************************/
2348
int read_data(int fd,char *buffer,int N)
2355
ret = read(fd,buffer + total,N - total);
2357
/* this is for portability */
2369
/****************************************************************************
2371
****************************************************************************/
2372
int write_data(int fd,char *buffer,int N)
2379
ret = write(fd,buffer + total,N - total);
2390
/* variables used by the read prediction module */
2395
int rp_predict_fd = -1;
2396
int rp_predict_offset = 0;
2397
int rp_predict_length = 0;
2400
char *rp_buffer = NULL;
2401
BOOL predict_skip=False;
2402
time_t smb_last_time=(time_t)0;
2404
/****************************************************************************
2405
handle read prediction on a file
2406
****************************************************************************/
2407
int read_predict(int fd,int offset,char *buf,char **ptr,int num)
2410
int possible = rp_length - (offset - rp_offset);
2412
possible = MIN(possible,num);
2414
/* give data if possible */
2416
offset >= rp_offset &&
2418
smb_last_time-rp_time < rp_timeout)
2422
memcpy(buf,rp_buffer + (offset-rp_offset),possible);
2424
*ptr = rp_buffer + (offset-rp_offset);
2425
DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
2429
predict_skip = True;
2431
predict_skip = False;
2433
/* prepare the next prediction */
2435
rp_predict_offset = offset + num;
2436
rp_predict_length = num;
2439
if (ret < 0) ret = 0;
2444
/****************************************************************************
2446
****************************************************************************/
2447
void do_read_prediction()
2449
if (predict_skip) return;
2451
if (rp_predict_fd == -1)
2454
rp_fd = rp_predict_fd;
2455
rp_offset = rp_predict_offset;
2460
rp_predict_length = MIN(rp_predict_length,2*ReadSize);
2461
rp_predict_length = MAX(rp_predict_length,1024);
2462
rp_offset = (rp_offset/1024)*1024;
2463
rp_predict_length = (rp_predict_length/1024)*1024;
2465
if (rp_predict_length > rp_alloced)
2467
rp_buffer = Realloc(rp_buffer,rp_predict_length);
2468
rp_alloced = rp_predict_length;
2471
DEBUG(0,("can't allocate read-prediction buffer\n"));
2479
if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
2485
rp_length = read(rp_fd,rp_buffer,rp_predict_length);
2486
rp_time = time(NULL);
2491
/****************************************************************************
2492
invalidate read-prediction on a fd
2493
****************************************************************************/
2494
void invalidate_read_prediction(int fd)
2498
if (rp_predict_fd == fd)
2503
/****************************************************************************
2504
transfer some data between two fd's
2505
****************************************************************************/
2506
int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2508
static char *buf=NULL;
2510
static int size = 0;
2513
DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2515
if ((size < ReadSize) && buf) {
2520
size = MAX(ReadSize,1024);
2522
while (!buf && size>0) {
2523
buf = (char *)Realloc(buf,size+8);
2524
if (!buf) size /= 2;
2527
DEBUG(0,("Can't allocate transfer buffer!\n"));
2531
abuf = buf + (align%8);
2538
int s = MIN(n,size);
2543
if (header && (headlen >= MIN(s,1024))) {
2553
if (header && headlen > 0)
2555
ret = MIN(headlen,size);
2556
memcpy(buf1,header,ret);
2559
if (headlen <= 0) header = NULL;
2563
ret += read(infd,buf1+ret,s-ret);
2567
ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2568
if (ret2 > 0) total += ret2;
2569
/* if we can't write then dump excess data */
2571
transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2573
if (ret <= 0 || ret2 != ret)
2581
/****************************************************************************
2582
read 4 bytes of a smb packet and return the smb length of the packet
2583
possibly store the result in the buffer
2584
****************************************************************************/
2585
int read_smb_length(int fd,char *inbuf,int timeout)
2589
int len=0, msg_type;
2600
ok = (read_with_timeout(fd,buffer,4,4,timeout,False) == 4);
2602
ok = (read_data(fd,buffer,4) == 4);
2608
DEBUG(10,("select timeout (%d)\n", timeout));
2613
DEBUG(6,("couldn't read from client\n"));
2618
len = smb_len(buffer);
2619
msg_type = CVAL(buffer,0);
2621
if (msg_type == 0x85)
2623
DEBUG(5,( "Got keepalive packet\n"));
2628
DEBUG(10,("got smb length of %d\n",len));
2635
/****************************************************************************
2636
read an smb from a fd and return it's length
2637
The timeout is in milli seconds
2638
****************************************************************************/
2639
BOOL receive_smb(int fd,char *buffer,int timeout)
2644
bzero(buffer,smb_size + 100);
2646
len = read_smb_length(fd,buffer,timeout);
2650
if (len > BUFFER_SIZE)
2652
DEBUG(0,("Invalid packet length! (%d bytes)\n",len));
2653
if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2657
ok = (read_data(fd,buffer+4,len) == len);
2669
/****************************************************************************
2671
****************************************************************************/
2672
BOOL send_smb(int fd,char *buffer)
2676
len = smb_len(buffer) + 4;
2678
while (nwritten < len)
2680
ret = write_socket(fd,buffer+nwritten,len - nwritten);
2683
DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2695
/****************************************************************************
2696
find a pointer to a netbios name
2697
****************************************************************************/
2698
char *name_ptr(char *buf,int ofs)
2700
unsigned char c = *(unsigned char *)(buf+ofs);
2702
if ((c & 0xC0) == 0xC0)
2706
memcpy(p,buf+ofs,2);
2709
DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2716
/****************************************************************************
2717
extract a netbios name from a buf
2718
****************************************************************************/
2719
int name_extract(char *buf,int ofs,char *name)
2721
char *p = name_ptr(buf,ofs);
2722
int d = PTR_DIFF(p,buf+ofs);
2724
if (d < -50 || d > 50) return(0);
2725
return(name_interpret(p,name));
2729
/****************************************************************************
2730
return the total storage length of a mangled name
2731
****************************************************************************/
2732
int name_len(char *s)
2735
unsigned char c = *(unsigned char *)s;
2736
if ((c & 0xC0) == 0xC0)
2738
while (*s) s += (*s)+1;
2739
return(PTR_DIFF(s,s0)+1);
2742
/****************************************************************************
2743
send a single packet to a port on another machine
2744
****************************************************************************/
2745
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2749
struct sockaddr_in sock_out;
2754
/* create a socket to write to */
2755
out_fd = socket(AF_INET, type, 0);
2758
DEBUG(0,("socket failed"));
2762
/* set the address and port */
2763
bzero((char *)&sock_out,sizeof(sock_out));
2764
putip((char *)&sock_out.sin_addr,(char *)&ip);
2765
sock_out.sin_port = htons( port );
2766
sock_out.sin_family = AF_INET;
2769
DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2770
len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2773
ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2776
DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n",
2777
inet_ntoa(ip),port,errno));
2783
/*******************************************************************
2784
sleep for a specified number of milliseconds
2785
********************************************************************/
2789
struct timeval tval,t1,t2;
2796
tval.tv_sec = (t-tdiff)/1000;
2797
tval.tv_usec = 1000*((t-tdiff)%1000);
2801
sys_select(&fds,&tval);
2804
tdiff = TvalDiff(&t1,&t2);
2808
/****************************************************************************
2809
check if a string is part of a list
2810
****************************************************************************/
2811
BOOL in_list(char *s,char *list,BOOL casesensitive)
2816
if (!list) return(False);
2818
while (next_token(&p,tok,LIST_SEP))
2820
if (casesensitive) {
2821
if (strcmp(tok,s) == 0)
2824
if (StrCaseCmp(tok,s) == 0)
2831
/* this is used to prevent lots of mallocs of size 1 */
2832
static char *null_string = NULL;
2834
/****************************************************************************
2835
set a string value, allocing the space for the string
2836
****************************************************************************/
2837
BOOL string_init(char **dest,char *src)
2848
null_string = (char *)malloc(1);
2851
*dest = null_string;
2855
*dest = (char *)malloc(l+1);
2861
/****************************************************************************
2863
****************************************************************************/
2864
void string_free(char **s)
2866
if (!s || !(*s)) return;
2867
if (*s == null_string)
2873
/****************************************************************************
2874
set a string value, allocing the space for the string, and deallocating any
2876
****************************************************************************/
2877
BOOL string_set(char **dest,char *src)
2881
return(string_init(dest,src));
2884
/****************************************************************************
2885
substitute a string for a pattern in another string. Make sure there is
2888
This routine looks for pattern in s and replaces it with
2889
insert. It may do multiple replacements.
2891
return True if a substitution was done.
2892
****************************************************************************/
2893
BOOL string_sub(char *s,char *pattern,char *insert)
2899
if (!insert || !pattern || !s) return(False);
2902
lp = strlen(pattern);
2903
li = strlen(insert);
2905
if (!*pattern) return(False);
2907
while (lp <= ls && (p = strstr(s,pattern)))
2910
memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2911
memcpy(p,insert,li);
2920
/*********************************************************
2921
* Recursive routine that is called by mask_match.
2922
* Does the actual matching.
2923
*********************************************************/
2924
BOOL do_match(char *str, char *regexp, int case_sig)
2928
for( p = regexp; *p && *str; ) {
2935
/* Look for a character matching
2936
the one after the '*' */
2939
return True; /* Automatic match */
2941
while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2943
if(do_match(str,p,case_sig))
2957
if(toupper(*str) != toupper(*p))
2967
if (!*p && str[0] == '.' && str[1] == 0)
2970
if (!*str && *p == '?')
2972
while (*p == '?') p++;
2976
if(!*str && (*p == '*' && p[1] == '\0'))
2982
/*********************************************************
2983
* Routine to match a given string with a regexp - uses
2984
* simplified regexp that takes * and ? only. Case can be
2985
* significant or not.
2986
*********************************************************/
2987
BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2991
fstring ebase,eext,sbase,sext;
2995
/* Make local copies of str and regexp */
2996
StrnCpy(p1,regexp,sizeof(pstring)-1);
2997
StrnCpy(p2,str,sizeof(pstring)-1);
2999
if (!strchr(p2,'.')) {
3004
if (!strchr(p1,'.')) {
3012
string_sub(p1,"*.*","*");
3013
string_sub(p1,".*","*");
3017
/* Remove any *? and ** as they are meaningless */
3018
for(p = p1; *p; p++)
3019
while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3020
(void)strcpy( &p[1], &p[2]);
3022
if (strequal(p1,"*")) return(True);
3024
DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3030
if ((p=strrchr(p1,'.'))) {
3039
if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3049
matched = do_match(sbase,ebase,case_sig) &&
3050
(trans2 || do_match(sext,eext,case_sig));
3052
DEBUG(5,("mask_match returning %d\n", matched));
3058
/****************************************************************************
3059
become a daemon, discarding the controlling terminal
3060
****************************************************************************/
3061
void become_daemon(void)
3063
#ifndef NO_FORK_DEBUG
3067
/* detach from the terminal */
3073
int i = open("/dev/tty", O_RDWR);
3076
ioctl(i, (int) TIOCNOTTY, (char *)0);
3084
#endif /* SCANNER */
3086
/****************************************************************************
3087
calculate the default netmask for an address
3088
****************************************************************************/
3089
static void default_netmask(struct in_addr *inm, struct in_addr *iad)
3091
unsigned long ad = ntohl(iad->s_addr);
3094
** Guess a netmask based on the class of the IP address given.
3096
if ( (ad & 0x80000000) == 0 ) {
3097
/* class A address */
3099
} else if ( (ad & 0xC0000000) == 0x80000000 ) {
3100
/* class B address */
3102
} else if ( (ad & 0xE0000000) == 0xC0000000 ) {
3103
/* class C address */
3106
/* class D or E; netmask doesn't make much sense - guess 4 bits */
3109
inm->s_addr = htonl(nm);
3112
/****************************************************************************
3113
get the broadcast address for our address
3114
(troyer@saifr00.ateng.az.honeywell.com)
3115
****************************************************************************/
3116
void get_broadcast(struct in_addr *if_ipaddr,
3117
struct in_addr *if_bcast,
3118
struct in_addr *if_nmask)
3121
#ifndef NO_GET_BROADCAST
3122
int sock = -1; /* AF_INET raw socket desc */
3124
struct ifreq *ifr=NULL;
3127
#if defined(EVEREST)
3130
struct ifreq *ifreqs;
3131
#elif defined(USE_IFREQ)
3133
struct strioctl strioctl;
3140
/* get a default netmask and broadcast */
3141
default_netmask(if_nmask, if_ipaddr);
3143
#ifndef NO_GET_BROADCAST
3144
/* Create a socket to the INET kernel. */
3146
if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
3148
if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
3151
DEBUG(0,( "Unable to open socket to get broadcast address\n"));
3155
/* Get a list of the configured interfaces */
3157
/* This is part of SCO Openserver 5: The ioctls are no longer part
3158
if the lower level STREAMS interface glue. They are now real
3161
if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
3162
DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
3164
DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
3166
ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
3167
ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
3169
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
3170
DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
3174
for (i = 0; i < n_interfaces; ++i) {
3175
if (if_ipaddr->s_addr ==
3176
((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
3183
#elif defined(USE_IFREQ)
3184
ifc = (struct ifconf *)buff;
3185
ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
3186
strioctl.ic_cmd = SIOCGIFCONF;
3187
strioctl.ic_dp = (char *)ifc;
3188
strioctl.ic_len = sizeof(buff);
3189
if (ioctl(sock, I_STR, &strioctl) < 0) {
3190
DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
3192
ifr = (struct ifreq *)ifc->ifc_req;
3194
/* Loop through interfaces, looking for given IP address */
3195
for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
3196
if (if_ipaddr->s_addr ==
3197
(*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3203
#elif defined(__FreeBSD__) || defined(NETBSD) || defined(OPENBSD)
3204
ifc.ifc_len = sizeof(buff);
3206
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
3207
DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
3210
/* Loop through interfaces, looking for given IP address */
3213
if (if_ipaddr->s_addr ==
3214
(*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3218
i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
3219
ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
3223
ifc.ifc_len = sizeof(buff);
3225
if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
3226
DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
3230
/* Loop through interfaces, looking for given IP address */
3231
for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
3233
if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
3235
if (if_ipaddr->s_addr ==
3236
(*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
3245
DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
3247
/* Get the netmask address from the kernel */
3251
strioctl.ic_cmd = SIOCGIFNETMASK;
3252
strioctl.ic_dp = (char *)&ifreq;
3253
strioctl.ic_len = sizeof(struct ifreq);
3254
if (ioctl(sock, I_STR, &strioctl) < 0)
3255
DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
3257
*if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
3259
if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
3260
DEBUG(0,("SIOCGIFNETMASK failed\n"));
3262
*if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
3265
DEBUG(2,("Netmask for %s = %s\n", ifr->ifr_name,
3266
inet_ntoa(*if_nmask)));
3274
/* sanity check on the netmask */
3276
unsigned long nm = ntohl(if_nmask->s_addr);
3277
if ((nm >> 24) != 0xFF) {
3278
DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
3279
default_netmask(if_nmask, if_ipaddr);
3283
/* derive the broadcast assuming a 1's broadcast, as this is what
3284
all MS operating systems do, we have to comply even if the unix
3285
box is setup differently */
3287
unsigned long ad = ntohl(if_ipaddr->s_addr);
3288
unsigned long nm = ntohl(if_nmask->s_addr);
3289
unsigned long bc = (ad & nm) | (0xffffffff & ~nm);
3290
if_bcast->s_addr = htonl(bc);
3293
DEBUG(2,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
3294
} /* get_broadcast */
3297
/****************************************************************************
3298
put up a yes/no prompt
3299
****************************************************************************/
3305
if (!fgets(ans,sizeof(ans)-1,stdin))
3308
if (*ans == 'y' || *ans == 'Y')
3314
/****************************************************************************
3315
read a line from a file with possible \ continuation chars.
3316
Blanks at the start or end of a line are stripped.
3317
The string will be allocated if s2 is NULL
3318
****************************************************************************/
3319
char *fgets_slash(char *s2,int maxlen,FILE *f)
3324
BOOL start_of_line = True;
3331
maxlen = MIN(maxlen,8);
3332
s = (char *)Realloc(s,maxlen);
3335
if (!s || maxlen < 2) return(NULL);
3339
while (len < maxlen-1)
3347
while (len > 0 && s[len-1] == ' ')
3351
if (len > 0 && s[len-1] == '\\')
3354
start_of_line = True;
3359
if (len <= 0 && !s2)
3361
return(len>0?s:NULL);
3366
start_of_line = False;
3370
if (!s2 && len > maxlen-3)
3373
s = (char *)Realloc(s,maxlen);
3374
if (!s) return(NULL);
3382
/****************************************************************************
3383
set the length of a file from a filedescriptor.
3384
Returns 0 on success, -1 on failure.
3385
****************************************************************************/
3386
int set_filelen(int fd, long len)
3388
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3389
extend a file with ftruncate. Provide alternate implementation
3392
#if FTRUNCATE_CAN_EXTEND
3393
return ftruncate(fd, len);
3397
long currpos = lseek(fd, 0L, SEEK_CUR);
3401
/* Do an fstat to see if the file is longer than
3402
the requested size (call ftruncate),
3403
or shorter, in which case seek to len - 1 and write 1
3405
if(fstat(fd, &st)<0)
3409
if (S_ISFIFO(st.st_mode)) return 0;
3412
if(st.st_size == len)
3414
if(st.st_size > len)
3415
return ftruncate(fd, len);
3417
if(lseek(fd, len-1, SEEK_SET) != len -1)
3419
if(write(fd, &c, 1)!=1)
3421
/* Seek to where we were */
3422
lseek(fd, currpos, SEEK_SET);
3428
/****************************************************************************
3429
return the byte checksum of some data
3430
****************************************************************************/
3431
int byte_checksum(char *buf,int len)
3433
unsigned char *p = (unsigned char *)buf;
3443
/****************************************************************************
3444
this is a version of setbuffer() for those machines that only have setvbuf
3445
****************************************************************************/
3446
void setbuffer(FILE *f,char *buf,int bufsize)
3448
setvbuf(f,buf,_IOFBF,bufsize);
3453
/****************************************************************************
3454
parse out a directory name from a path name. Assumes dos style filenames.
3455
****************************************************************************/
3456
char *dirname_dos(char *path,char *buf)
3458
char *p = strrchr(path,'\\');
3473
/****************************************************************************
3474
parse out a filename from a path name. Assumes dos style filenames.
3475
****************************************************************************/
3476
static char *filename_dos(char *path,char *buf)
3478
char *p = strrchr(path,'\\');
3490
/****************************************************************************
3491
expand a pointer to be a particular size
3492
****************************************************************************/
3493
void *Realloc(void *p,int size)
3497
ret = (void *)malloc(size);
3499
ret = (void *)realloc(p,size);
3502
DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3507
/****************************************************************************
3508
set the time on a file
3509
****************************************************************************/
3510
BOOL set_filetime(char *fname,time_t mtime)
3512
struct utimbuf times;
3514
if (null_mtime(mtime)) return(True);
3516
times.modtime = times.actime = mtime;
3518
if (sys_utime(fname,×)) {
3519
DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
3527
/****************************************************************************
3529
****************************************************************************/
3530
char *strdup(char *s)
3533
if (!s) return(NULL);
3534
ret = (char *)malloc(strlen(s)+1);
3535
if (!ret) return(NULL);
3543
/****************************************************************************
3544
Signal handler for SIGPIPE (write on a disconnected socket)
3545
****************************************************************************/
3548
DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3551
#endif /* SCANNER */
3553
#ifdef REPLACE_STRLEN
3554
/****************************************************************************
3555
a replacement strlen() that returns int for solaris
3556
****************************************************************************/
3567
/****************************************************************************
3568
return a time at the start of the current month
3569
****************************************************************************/
3570
time_t start_of_month(void)
3572
time_t t = time(NULL);
3586
/*******************************************************************
3587
check for a sane unix date
3588
********************************************************************/
3589
BOOL sane_unix_date(time_t unixdate)
3592
time_t t_today = time(NULL);
3594
t = *(LocalTime(&unixdate,LOCAL_TO_GMT));
3595
today = *(LocalTime(&t_today,LOCAL_TO_GMT));
3600
if (t.tm_year > today.tm_year)
3603
if (t.tm_year == today.tm_year &&
3604
t.tm_mon > today.tm_mon)
3608
if (t.tm_year == today.tm_year &&
3609
t.tm_mon == today.tm_mon &&
3610
t.tm_mday > (today.tm_mday+1))
3619
/*******************************************************************
3620
ftruncate for operating systems that don't have it
3621
********************************************************************/
3622
int ftruncate(int f,long l)
3629
fl.l_type = F_WRLCK;
3630
return fcntl(f, F_FREESP, &fl);
3636
/****************************************************************************
3637
get my own name and IP
3638
****************************************************************************/
3639
BOOL get_myname(char *myname,struct in_addr *ip)
3646
/* get my host name */
3647
if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3649
DEBUG(0,("gethostname failed\n"));
3654
if ((hp = Get_Hostbyname(hostname)) == 0)
3656
DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
3662
/* split off any parts after an initial . */
3663
char *p = strchr(hostname,'.');
3666
strcpy(myname,hostname);
3670
putip((char *)ip,(char *)hp->h_addr);
3676
/****************************************************************************
3677
true if two IP addresses are equal
3678
****************************************************************************/
3679
BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3681
unsigned long a1,a2;
3682
a1 = ntohl(ip1.s_addr);
3683
a2 = ntohl(ip2.s_addr);
3688
/****************************************************************************
3689
open a socket of the specified type, port and address for incoming data
3690
****************************************************************************/
3691
int open_socket_in(int type, int port, int dlevel)
3694
struct sockaddr_in sock;
3699
/* skip all this lookup nonsense and just plug the stuff in like our
3700
IQ was normal, eh? */
3701
bzero ((char *)&sock, sizeof (sock));
3702
sock.sin_port = htons (port);
3703
sock.sin_family = AF_INET;
3704
sock.sin_addr.s_addr = INADDR_ANY;
3705
res = socket (AF_INET, type, 0);
3707
/* get my host name */
3708
#ifdef MAXHOSTNAMELEN
3709
if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3711
if (gethostname(host_name, sizeof(host_name)) == -1)
3713
{ DEBUG(0,("gethostname failed\n")); return -1; }
3716
if ((hp = Get_Hostbyname(host_name)) == 0)
3718
DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
3722
bzero((char *)&sock,sizeof(sock));
3723
memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3724
#if defined(__FreeBSD__) || defined(NETBSD) || defined(OPENBSD)
3725
sock.sin_len = sizeof(sock);
3727
sock.sin_port = htons( port );
3728
sock.sin_family = hp->h_addrtype;
3729
sock.sin_addr.s_addr = INADDR_ANY;
3730
res = socket(hp->h_addrtype, type, 0);
3731
#endif /* SCANNER */
3733
{ DEBUG(0,("socket failed\n")); return -1; }
3737
setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3740
/* now we've got a socket - we need to bind it */
3741
if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3744
if (port == 139 || port == 137)
3745
DEBUG(dlevel,("bind failed on port %d (%s)\n",
3746
port,strerror(errno)));
3749
if (dlevel > 0 && port < 1000)
3752
if (port >= 1000 && port < 9000)
3753
return(open_socket_in(type,port+1,dlevel));
3758
DEBUG(3,("bind succeeded on port %d\n",port));
3764
/****************************************************************************
3765
create an outgoing socket
3766
**************************************************************************/
3767
int open_socket_out(int type, struct in_addr *addr, int port )
3769
struct sockaddr_in sock_out;
3772
/* create a socket to write to */
3773
res = socket(PF_INET, type, 0);
3775
{ DEBUG(0,("socket error\n")); return -1; }
3777
if (type != SOCK_STREAM) return(res);
3779
bzero((char *)&sock_out,sizeof(sock_out));
3780
putip((char *)&sock_out.sin_addr,(char *)addr);
3782
sock_out.sin_port = htons( port );
3783
sock_out.sin_family = PF_INET;
3785
DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3787
/* and connect it to the destination */
3788
if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))<0) {
3789
DEBUG(0,("connect error: %s\n",strerror(errno)));
3798
/****************************************************************************
3799
interpret a protocol description string, with a default
3800
****************************************************************************/
3801
int interpret_protocol(char *str,int def)
3803
if (strequal(str,"NT1"))
3804
return(PROTOCOL_NT1);
3805
if (strequal(str,"LANMAN2"))
3806
return(PROTOCOL_LANMAN2);
3807
if (strequal(str,"LANMAN1"))
3808
return(PROTOCOL_LANMAN1);
3809
if (strequal(str,"CORE"))
3810
return(PROTOCOL_CORE);
3811
if (strequal(str,"COREPLUS"))
3812
return(PROTOCOL_COREPLUS);
3813
if (strequal(str,"CORE+"))
3814
return(PROTOCOL_COREPLUS);
3816
DEBUG(0,("Unrecognised protocol level %s\n",str));
3821
/****************************************************************************
3822
interpret a security level
3823
****************************************************************************/
3824
int interpret_security(char *str,int def)
3826
if (strequal(str,"SERVER"))
3828
if (strequal(str,"USER"))
3830
if (strequal(str,"SHARE"))
3833
DEBUG(0,("Unrecognised security level %s\n",str));
3839
/****************************************************************************
3840
interpret an internet address or name into an IP address in 4 byte form
3841
****************************************************************************/
3842
unsigned long interpret_addr(char *str)
3847
if (strcmp(str,"0.0.0.0") == 0) return(0);
3848
if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3850
/* SCANNER: XXX: wrong assumption! what about 3com.com... */
3851
/* should return struct in_addr, too, even if it *is* ulong */
3853
/* if it's in the form of an IP address then get the lib to interpret it */
3854
if (isdigit(str[0])) {
3855
res = inet_addr(str);
3857
/* otherwise assume it's a network name of some sort and use Get_Hostbyname */
3858
if ((hp = Get_Hostbyname(str)) == 0) {
3859
DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3862
putip((char *)&res,(char *)hp->h_addr);
3865
if (res == (unsigned long)-1) return(0);
3878
longjmp (gh_buf, 1);
3880
#endif /* GH_SLEAZE */
3882
char * Get_Hostbyaddr (struct in_addr ip)
3884
static char outbuf [MAXHOSTNAMELEN + 4]; /* reused on every call */
3885
struct hostent * hp;
3890
signal (SIGALRM, tmx);
3892
if (setjmp (gh_buf) > 0)
3895
hp = gethostbyaddr ((char *) &ip, sizeof (struct in_addr), AF_INET);
3897
signal (SIGALRM, SIG_DFL);
3900
if (hp && (hp->h_name)) {
3901
strncpy (outbuf, hp->h_name, MAXHOSTNAMELEN);
3902
outbuf[MAXHOSTNAMELEN] = '\0';
3907
} /* Get_Hostbyaddr */
3909
#endif /* SCANNER */
3911
/*******************************************************************
3912
a convenient addition to interpret_addr()
3913
******************************************************************/
3914
struct in_addr *interpret_addr2(char *str)
3916
static struct in_addr ret;
3917
unsigned long a = interpret_addr(str);
3918
putip((char *)&ret,(char *)&a);
3922
/*******************************************************************
3923
check if an IP is the 0.0.0.0
3924
******************************************************************/
3925
BOOL zero_ip(struct in_addr ip)
3928
putip((char *)&a,(char *)&ip);
3932
#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
3934
/****************************************************************************
3935
interpret an 8 byte "filetime" structure to a time_t
3936
It's originally in "100ns units since jan 1st 1601"
3938
It appears to be kludge-GMT (at least for file listings). This means
3939
its the GMT you get by taking a localtime and adding the
3940
serverzone. This is NOT the same as GMT in some cases. This routine
3941
converts this to real GMT.
3942
****************************************************************************/
3943
time_t interpret_long_date(char *p)
3951
if (thigh == 0) return(0);
3953
d = ((double)thigh)*4.0*(double)(1<<30);
3954
d += (tlow&0xFFF00000);
3957
/* now adjust by 369 years to make the secs since 1970 */
3958
d -= TIME_FIXUP_CONSTANT;
3963
ret = (time_t)(d+0.5);
3965
/* this takes us from kludge-GMT to real GMT */
3966
ret += TimeDiff(ret) - serverzone;
3972
/****************************************************************************
3973
put a 8 byte filetime from a time_t
3974
This takes real GMT as input and converts to kludge-GMT
3975
****************************************************************************/
3976
void put_long_date(char *p,time_t t)
3982
SIVAL(p,0,0); SIVAL(p,4,0);
3986
/* this converts GMT to kludge-GMT */
3987
t -= TimeDiff(t) - serverzone;
3991
d += TIME_FIXUP_CONSTANT;
3995
thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
3996
tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
4002
/*******************************************************************
4003
sub strings with useful parameters
4004
********************************************************************/
4005
void standard_sub_basic(char *s)
4007
if (!strchr(s,'%')) return;
4009
string_sub(s,"%R",remote_proto);
4010
string_sub(s,"%a",remote_arch);
4011
string_sub(s,"%m",remote_machine);
4012
string_sub(s,"%L",local_machine);
4014
if (!strchr(s,'%')) return;
4016
string_sub(s,"%v",VERSION);
4017
string_sub(s,"%h",myhostname);
4018
string_sub(s,"%U",sesssetup_user);
4020
if (!strchr(s,'%')) return;
4022
string_sub(s,"%I",Client_info.addr);
4023
string_sub(s,"%M",Client_info.name);
4024
string_sub(s,"%T",timestring());
4026
if (!strchr(s,'%')) return;
4030
sprintf(pidstr,"%d",(int)getpid());
4031
string_sub(s,"%d",pidstr);
4036
/*******************************************************************
4037
write a string in unicoode format
4038
********************************************************************/
4039
void PutUniCode(char *dst,char *src)
4047
dst[0] = dst[1] = 0;
4051
/****************************************************************************
4052
a wrapper for gethostbyname() that tries with all lower and all upper case
4053
if the initial name fails
4054
****************************************************************************/
4055
struct hostent *Get_Hostbyname(char *name)
4057
char *name2 = strdup(name);
4058
struct hostent *ret;
4062
DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4066
if (!isalnum(*name2))
4073
signal (SIGALRM, tmx);
4075
if (setjmp (gh_buf) > 0)
4078
ret = gethostbyname(name2);
4080
signal (SIGALRM, SIG_DFL);
4089
/* try with all lowercase */
4091
ret = gethostbyname(name2);
4098
/* try with all uppercase */
4100
ret = gethostbyname(name2);
4107
/* nothing works :-( */
4113
/****************************************************************************
4114
check if a process exists. Does this work on all unixes?
4115
****************************************************************************/
4116
BOOL process_exists(int pid)
4120
sprintf(s,"/proc/%d",pid);
4121
return(directory_exist(s,NULL));
4124
static BOOL tested=False;
4125
static BOOL ok=False;
4129
sprintf(s,"/proc/%05d",getpid());
4130
ok = file_exist(s,NULL);
4133
sprintf(s,"/proc/%05d",pid);
4134
return(file_exist(s,NULL));
4138
/* a best guess for non root access */
4139
if (geteuid() != 0) return(True);
4141
/* otherwise use kill */
4142
return(pid == getpid() || kill(pid,0) == 0);
4147
/*******************************************************************
4148
turn a uid into a user name
4149
********************************************************************/
4150
char *uidtoname(int uid)
4152
static char name[20];
4153
struct passwd *pass = getpwuid(uid);
4154
if (pass) return(pass->pw_name);
4155
sprintf(name,"%d",uid);
4159
/*******************************************************************
4160
turn a gid into a group name
4161
********************************************************************/
4162
char *gidtoname(int gid)
4164
static char name[20];
4165
struct group *grp = getgrgid(gid);
4166
if (grp) return(grp->gr_name);
4167
sprintf(name,"%d",gid);
4171
/*******************************************************************
4173
********************************************************************/
4174
void BlockSignals(BOOL block)
4177
int block_mask = (sigmask(SIGTERM)|sigmask(SIGQUIT)|sigmask(SIGSEGV)
4178
|sigmask(SIGCHLD)|sigmask(SIGQUIT)|sigmask(SIGBUS)|
4181
sigblock(block_mask);
4183
sigunblock(block_mask);
4188
#define DIRECT direct
4190
#define DIRECT dirent
4193
/*******************************************************************
4194
a readdir wrapper which just returns the file name
4195
also return the inode number if requested
4196
********************************************************************/
4197
char *readdirname(void *p)
4202
if (!p) return(NULL);
4204
ptr = (struct DIRECT *)readdir(p);
4205
if (!ptr) return(NULL);
4207
dname = ptr->d_name;
4213
unix_to_dos(buf, True);
4219
if (telldir(p) < 0) return(NULL);
4223
/* this handles a broken compiler setup, causing a mixture
4224
of BSD and SYSV headers and libraries */
4226
static BOOL broken_readdir = False;
4227
if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4229
DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4230
broken_readdir = True;
4242
#if (defined(SecureWare) && defined(SCO))
4243
/* This is needed due to needing the nap() function but we don't want
4244
to include the Xenix libraries since that will break other things...
4245
BTW: system call # 0x0c28 is the same as calling nap() */
4246
long nap(long milliseconds) {
4247
return syscall(0x0c28, milliseconds);
4251
#ifdef NO_INITGROUPS
4252
#include <sys/types.h>
4257
#define NULL (void *)0
4260
/****************************************************************************
4261
some systems don't have an initgroups call
4262
****************************************************************************/
4263
int initgroups(char *name,gid_t id)
4266
/* yikes! no SETGROUPS or INITGROUPS? how can this work? */
4269
gid_t grouplst[NGROUPS_MAX];
4276
while (i < NGROUPS_MAX &&
4277
((g = (struct group *)getgrent()) != (struct group *)NULL))
4279
if (g->gr_gid == id)
4283
while (gr && (*gr != (char)NULL)) {
4284
if (strcmp(name,gr) == 0) {
4285
grouplst[i] = g->gr_gid;
4290
gr = g->gr_mem[++j];
4294
return(setgroups(i,grouplst));
4302
/* undo the wrapping temporarily */
4307
/****************************************************************************
4308
wrapper for malloc() to catch memory errors
4309
****************************************************************************/
4310
void *malloc_wrapped(int size,char *file,int line)
4312
#ifdef xx_old_malloc
4313
void *res = xx_old_malloc(size);
4315
void *res = malloc(size);
4317
DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
4319
size,(unsigned int)res));
4323
/****************************************************************************
4324
wrapper for realloc() to catch memory errors
4325
****************************************************************************/
4326
void *realloc_wrapped(void *ptr,int size,char *file,int line)
4328
#ifdef xx_old_realloc
4329
void *res = xx_old_realloc(ptr,size);
4331
void *res = realloc(ptr,size);
4333
DEBUG(3,("Realloc\n"));
4334
DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
4336
(unsigned int)ptr));
4337
DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
4339
size,(unsigned int)res));
4343
/****************************************************************************
4344
wrapper for free() to catch memory errors
4345
****************************************************************************/
4346
void free_wrapped(void *ptr,char *file,int line)
4353
DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
4354
file,line,(unsigned int)ptr));
4358
/* and re-do the define for spots lower in this file */
4359
#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
4360
#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
4361
#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
4365
#ifdef REPLACE_STRSTR
4366
/****************************************************************************
4367
Mips version of strstr doesn't seem to work correctly.
4368
There is a #define in includes.h to redirect calls to this function.
4369
****************************************************************************/
4370
char *Strstr(char *s, char *p)
4372
int len = strlen(p);
4374
while ( *s != '\0' ) {
4375
if ( strncmp(s, p, len) == 0 )
4382
#endif /* REPLACE_STRSTR */
4385
#ifdef REPLACE_MKTIME
4386
/*******************************************************************
4387
a mktime() replacement for those who don't have it - contributed by
4388
C.A. Lademann <cal@zls.com>
4389
********************************************************************/
4391
#define HOUR 60*MINUTE
4393
#define YEAR 365*DAY
4394
time_t Mktime(struct tm *t)
4398
int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
4404
epoch = (t->tm_year - 70) * YEAR +
4405
(t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
4410
for(i = 0; i < t->tm_mon; i++) {
4411
epoch += mon [m] * DAY;
4412
if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
4421
epoch += (t->tm_mday - 1) * DAY;
4422
epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
4424
if((u = localtime(&epoch)) != NULL) {
4425
t->tm_sec = u->tm_sec;
4426
t->tm_min = u->tm_min;
4427
t->tm_hour = u->tm_hour;
4428
t->tm_mday = u->tm_mday;
4429
t->tm_mon = u->tm_mon;
4430
t->tm_year = u->tm_year;
4431
t->tm_wday = u->tm_wday;
4432
t->tm_yday = u->tm_yday;
4433
t->tm_isdst = u->tm_isdst;
4435
memcpy(t->tm_name, u->tm_name, LTZNMAX);
4441
#endif /* REPLACE_MKTIME */
4445
#ifdef REPLACE_RENAME
4446
/* Rename a file. (from libiberty in GNU binutils) */
4452
if (link (zfrom, zto) < 0)
4454
if (errno != EEXIST)
4456
if (unlink (zto) < 0
4457
|| link (zfrom, zto) < 0)
4460
return unlink (zfrom);
4465
#ifdef REPLACE_INNETGR
4467
* Search for a match in a netgroup. This replaces it on broken systems.
4469
int InNetGr(group, host, user, dom)
4470
char *group, *host, *user, *dom;
4472
char *hst, *usr, *dm;
4475
while (getnetgrent(&hst, &usr, &dm))
4476
if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
4477
((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
4478
((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
4490
/*******************************************************************
4491
a wrapper around memcpy for diagnostic purposes
4492
********************************************************************/
4493
void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
4495
if (l>64 && (((int)d)%4) != (((int)s)%4))
4496
DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
4497
#ifdef xx_old_memcpy
4498
return(xx_old_memcpy(d,s,l));
4500
return(memcpy(d,s,l));
4503
#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)