forked from mirrors/tftp-hpa-google
-> Clean up the use of autoconf macros a bit.
-> Always pass O_TEXT/O_BINARY and "t"/"b" respectively, as appropriate.
This commit is contained in:
parent
5c5b5e8a0b
commit
64ae5fda79
7 changed files with 91 additions and 87 deletions
52
aclocal.m4
vendored
52
aclocal.m4
vendored
|
@ -42,59 +42,38 @@ AH_TEMPLATE([HAVE_MSGHDR_MSG_CONTROL],
|
|||
[Define if struct msghdr has the msg_control field.])
|
||||
|
||||
AC_DEFUN(PA_MSGHDR_MSG_CONTROL,
|
||||
[AC_MSG_CHECKING([for msg_control in struct msghdr])
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#define _XPG4_2 /* Needed on Solaris */
|
||||
[AC_CHECK_MEMBER(struct msghdr.msg_control,
|
||||
[AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL)],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
],
|
||||
[
|
||||
struct msghdr msg;
|
||||
void *p = (void *) &msg.msg_control;
|
||||
],
|
||||
[
|
||||
AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL)
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
])])
|
||||
])])
|
||||
|
||||
dnl ------------------------------------------------------------------------
|
||||
dnl PA_STRUCT_IN_PKTINFO
|
||||
dnl
|
||||
dnl Look for definition of struct in_pktinfo. Some versions of glibc
|
||||
dnl lack struct in_pktinfo; if so we need to include the definition
|
||||
dnl ourselves -- but we only want to do that if absolutely necessary!
|
||||
dnl
|
||||
dnl Look for definition of struct in_pktinfo, which at least has an
|
||||
dnl ipi_addr member. Some versions of glibc lack struct in_pktinfo;
|
||||
dnl if so we need to include the definition ourselves -- but we only
|
||||
dnl want to do that if absolutely necessary!
|
||||
dnl ------------------------------------------------------------------------
|
||||
AH_TEMPLATE([HAVE_STRUCT_IN_PKTINFO],
|
||||
[Define if struct in_pktinfo is defined.])
|
||||
|
||||
AC_DEFUN(PA_STRUCT_IN_PKTINFO,
|
||||
[AC_MSG_CHECKING([for definition of struct in_pktinfo])
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
[AC_CHECK_MEMBER(struct in_pktinfo.ipi_addr,
|
||||
[AC_DEFINE(HAVE_STRUCT_IN_PKTINFO)],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/uio.h>
|
||||
],
|
||||
[
|
||||
struct in_pktinfo pktinfo;
|
||||
int foo = sizeof(struct in_pktinfo);
|
||||
void *quux = (void *)(&pktinfo.ipi_addr);
|
||||
],
|
||||
[
|
||||
AC_DEFINE(HAVE_STRUCT_IN_PKTINFO)
|
||||
AC_MSG_RESULT([yes])
|
||||
],
|
||||
[
|
||||
AC_MSG_RESULT([no])
|
||||
])])
|
||||
])])
|
||||
|
||||
dnl --------------------------------------------------------------------------
|
||||
dnl PA_HAVE_TCPWRAPPERS
|
||||
|
@ -179,6 +158,7 @@ dnl PA_HEADER_DEFINES(header, type, value)
|
|||
dnl --------------------------------------------------------------------------
|
||||
AC_DEFUN(PA_HEADER_DEFINES,
|
||||
[AC_MSG_CHECKING([if $1 defines $3])
|
||||
AH_TEMPLATE([HAVE_$3_DEFINITION], [Define if $1 defines $3])
|
||||
AC_TRY_COMPILE([
|
||||
#include <$1>
|
||||
],
|
||||
|
|
9
config.h
9
config.h
|
@ -109,6 +109,15 @@
|
|||
#define E_WOULD_BLOCK(x) ((x) == EWOULDBLOCK)
|
||||
#endif
|
||||
|
||||
/* Some broken systems care about text versus binary, but
|
||||
real Unix systems don't... */
|
||||
#ifndef HAVE_O_TEXT_DEFINITION
|
||||
#define O_TEXT 0
|
||||
#endif
|
||||
#ifndef HAVE_O_BINARY_DEFINITION
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/* If we don't have intmax_t, try creating it */
|
||||
|
||||
#ifndef HAVE_INTMAX_T
|
||||
|
|
|
@ -110,6 +110,10 @@ AC_CHECK_FUNCS(strtoull)
|
|||
PA_MSGHDR_MSG_CONTROL
|
||||
PA_STRUCT_IN_PKTINFO
|
||||
|
||||
PA_HEADER_DEFINES(fcntl.h, int, O_NONBLOCK)
|
||||
PA_HEADER_DEFINES(fcntl.h, int, O_BINARY)
|
||||
PA_HEADER_DEFINES(fcntl.h, int, O_TEXT)
|
||||
|
||||
AH_TEMPLATE([HAVE_SIGSETJMP],
|
||||
[Define if we have sigsetjmp, siglongjmp and sigjmp_buf.])
|
||||
PA_SIGSETJMP([AC_DEFINE(HAVE_SIGSETJMP)])
|
||||
|
@ -128,8 +132,6 @@ dnl
|
|||
|
||||
common_libs="$LIBS"
|
||||
|
||||
AH_TEMPLATE([HAVE_IPPORT_TFTP_DEFINITION],
|
||||
[Define if netinet/in.h defines IPPORT_TFTP.])
|
||||
PA_HEADER_DEFINES(netinet/in.h, int, IPPORT_TFTP)
|
||||
|
||||
PA_WITH_BOOL(tcpwrappers, 1,
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#ifndef RECVFILE_H
|
||||
#define RECVFILE_H
|
||||
|
||||
void tftp_recvfile (int, char *, char *);
|
||||
void tftp_sendfile (int, char *, char *);
|
||||
void tftp_recvfile (int, const char *, const char *);
|
||||
void tftp_sendfile (int, const char *, const char *);
|
||||
|
||||
#endif
|
||||
|
|
79
tftp/main.c
79
tftp/main.c
|
@ -66,13 +66,31 @@ static const char *rcsid UNUSED =
|
|||
#define TIMEOUT 5 /* secs between rexmt's */
|
||||
#define LBUFLEN 200 /* size of input buffer */
|
||||
|
||||
struct modes {
|
||||
const char *m_name;
|
||||
const char *m_mode;
|
||||
int m_openflags;
|
||||
};
|
||||
|
||||
static const struct modes modes[] = {
|
||||
{ "netascii", "netascii", O_TEXT },
|
||||
{ "ascii", "netascii", O_TEXT },
|
||||
{ "octet", "octet", O_BINARY },
|
||||
{ "binary", "octet", O_BINARY },
|
||||
{ "image", "octet", O_BINARY },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
#define MODE_OCTET (&modes[2])
|
||||
#define MODE_NETASCII (&modes[0])
|
||||
#define MODE_DEFAULT MODE_NETASCII
|
||||
|
||||
struct sockaddr_in peeraddr;
|
||||
int f;
|
||||
u_short port;
|
||||
int trace;
|
||||
int verbose;
|
||||
int connected;
|
||||
char mode[32];
|
||||
const struct modes *mode;
|
||||
#ifdef WITH_READLINE
|
||||
char *line = NULL;
|
||||
#else
|
||||
|
@ -104,7 +122,7 @@ static void command (void);
|
|||
static void getusage (char *);
|
||||
static void makeargv (void);
|
||||
static void putusage (char *);
|
||||
static void settftpmode (const char *);
|
||||
static void settftpmode (const struct modes *);
|
||||
|
||||
#define HELPINDENT (sizeof("connect"))
|
||||
|
||||
|
@ -213,7 +231,7 @@ main(int argc, char *argv[])
|
|||
perror("tftp: bind");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(mode, "netascii");
|
||||
mode = MODE_DEFAULT;
|
||||
bsd_signal(SIGINT, intr);
|
||||
if (pargc > 1) {
|
||||
if (sigsetjmp(toplevel,1) != 0)
|
||||
|
@ -326,27 +344,14 @@ setpeer(int argc, char *argv[])
|
|||
connected = 1;
|
||||
}
|
||||
|
||||
struct modes {
|
||||
const char *m_name;
|
||||
const char *m_mode;
|
||||
} modes[] = {
|
||||
{ "ascii", "netascii" },
|
||||
{ "netascii", "netascii" },
|
||||
{ "binary", "octet" },
|
||||
{ "image", "octet" },
|
||||
{ "octet", "octet" },
|
||||
/* { "mail", "mail" }, */
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
void
|
||||
modecmd(int argc, char *argv[])
|
||||
{
|
||||
struct modes *p;
|
||||
const struct modes *p;
|
||||
const char *sep;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Using %s mode to transfer files.\n", mode);
|
||||
printf("Using %s mode to transfer files.\n", mode->m_mode);
|
||||
return;
|
||||
}
|
||||
if (argc == 2) {
|
||||
|
@ -354,7 +359,7 @@ modecmd(int argc, char *argv[])
|
|||
if (strcmp(argv[1], p->m_name) == 0)
|
||||
break;
|
||||
if (p->m_name) {
|
||||
settftpmode(p->m_mode);
|
||||
settftpmode(p);
|
||||
return;
|
||||
}
|
||||
printf("%s: unknown mode\n", argv[1]);
|
||||
|
@ -376,22 +381,22 @@ void
|
|||
setbinary(int argc, char *argv[])
|
||||
{
|
||||
(void)argc; (void)argv; /* Quiet unused warning */
|
||||
settftpmode("octet");
|
||||
settftpmode(MODE_OCTET);
|
||||
}
|
||||
|
||||
void
|
||||
setascii(int argc, char *argv[])
|
||||
{
|
||||
(void)argc; (void)argv; /* Quiet unused warning */
|
||||
settftpmode("netascii");
|
||||
settftpmode(MODE_NETASCII);
|
||||
}
|
||||
|
||||
static void
|
||||
settftpmode(const char *newmode)
|
||||
settftpmode(const struct modes *newmode)
|
||||
{
|
||||
strcpy(mode, newmode);
|
||||
mode = newmode;
|
||||
if (verbose)
|
||||
printf("mode set to %s\n", mode);
|
||||
printf("mode set to %s\n", mode->m_mode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -444,16 +449,16 @@ put(int argc, char *argv[])
|
|||
}
|
||||
if (argc < 4) {
|
||||
cp = argc == 2 ? tail(targ) : argv[1];
|
||||
fd = open(cp, O_RDONLY);
|
||||
fd = open(cp, O_RDONLY|mode->m_openflags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "tftp: "); perror(cp);
|
||||
return;
|
||||
}
|
||||
if (verbose)
|
||||
printf("putting %s to %s:%s [%s]\n",
|
||||
cp, hostname, targ, mode);
|
||||
cp, hostname, targ, mode->m_mode);
|
||||
peeraddr.sin_port = port;
|
||||
tftp_sendfile(fd, targ, mode);
|
||||
tftp_sendfile(fd, targ, mode->m_mode);
|
||||
return;
|
||||
}
|
||||
/* this assumes the target is a directory */
|
||||
|
@ -462,16 +467,16 @@ put(int argc, char *argv[])
|
|||
*cp++ = '/';
|
||||
for (n = 1; n < argc - 1; n++) {
|
||||
strcpy(cp, tail(argv[n]));
|
||||
fd = open(argv[n], O_RDONLY);
|
||||
fd = open(argv[n], O_RDONLY|mode->m_openflags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "tftp: "); perror(argv[n]);
|
||||
continue;
|
||||
}
|
||||
if (verbose)
|
||||
printf("putting %s to %s:%s [%s]\n",
|
||||
argv[n], hostname, targ, mode);
|
||||
argv[n], hostname, targ, mode->m_mode);
|
||||
peeraddr.sin_port = port;
|
||||
tftp_sendfile(fd, targ, mode);
|
||||
tftp_sendfile(fd, targ, mode->m_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,29 +537,29 @@ get(int argc, char *argv[])
|
|||
}
|
||||
if (argc < 4) {
|
||||
cp = argc == 3 ? argv[2] : tail(src);
|
||||
fd = creat(cp, 0644);
|
||||
fd = open(cp, O_WRONLY|O_CREAT|O_TRUNC|mode->m_openflags, 0666);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "tftp: "); perror(cp);
|
||||
return;
|
||||
}
|
||||
if (verbose)
|
||||
printf("getting from %s:%s to %s [%s]\n",
|
||||
hostname, src, cp, mode);
|
||||
hostname, src, cp, mode->m_mode);
|
||||
peeraddr.sin_port = port;
|
||||
tftp_recvfile(fd, src, mode);
|
||||
tftp_recvfile(fd, src, mode->m_mode);
|
||||
break;
|
||||
}
|
||||
cp = tail(src); /* new .. jdg */
|
||||
fd = creat(cp, 0644);
|
||||
fd = open(cp, O_WRONLY|O_CREAT|O_TRUNC|mode->m_openflags, 0666);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "tftp: "); perror(cp);
|
||||
continue;
|
||||
}
|
||||
if (verbose)
|
||||
printf("getting from %s:%s to %s [%s]\n",
|
||||
hostname, src, cp, mode);
|
||||
hostname, src, cp, mode->m_mode);
|
||||
peeraddr.sin_port = port;
|
||||
tftp_recvfile(fd, src, mode);
|
||||
tftp_recvfile(fd, src, mode->m_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,7 +626,7 @@ status(int argc, char *argv[])
|
|||
printf("Connected to %s.\n", hostname);
|
||||
else
|
||||
printf("Not connected.\n");
|
||||
printf("Mode: %s Verbose: %s Tracing: %s\n", mode,
|
||||
printf("Mode: %s Verbose: %s Tracing: %s\n", mode->m_mode,
|
||||
verbose ? "on" : "off", trace ? "on" : "off");
|
||||
printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
|
||||
rexmtval, maxtimeout);
|
||||
|
|
|
@ -77,7 +77,7 @@ static void tpacket(const char *, struct tftphdr *, int);
|
|||
* Send the requested file.
|
||||
*/
|
||||
void
|
||||
tftp_sendfile(int fd, char *name, char *mode)
|
||||
tftp_sendfile(int fd, const char *name, const char *mode)
|
||||
{
|
||||
struct tftphdr *ap; /* data and ack packets */
|
||||
struct tftphdr *dp;
|
||||
|
@ -93,8 +93,8 @@ tftp_sendfile(int fd, char *name, char *mode)
|
|||
startclock(); /* start stat's clock */
|
||||
dp = r_init(); /* reset fillbuf/read-ahead code */
|
||||
ap = (struct tftphdr *)ackbuf;
|
||||
file = fdopen(fd, "r");
|
||||
convert = !strcmp(mode, "netascii");
|
||||
file = fdopen(fd, convert ? "rt" : "rb");
|
||||
block = 0;
|
||||
is_request = 1; /* First packet is the actual WRQ */
|
||||
amount = 0;
|
||||
|
@ -185,7 +185,7 @@ abort:
|
|||
* Receive a file.
|
||||
*/
|
||||
void
|
||||
tftp_recvfile(int fd, char *name, char *mode)
|
||||
tftp_recvfile(int fd, const char *name, const char *mode)
|
||||
{
|
||||
struct tftphdr *ap;
|
||||
struct tftphdr *dp;
|
||||
|
@ -201,8 +201,8 @@ tftp_recvfile(int fd, char *name, char *mode)
|
|||
startclock();
|
||||
dp = w_init();
|
||||
ap = (struct tftphdr *)ackbuf;
|
||||
file = fdopen(fd, "w");
|
||||
convert = !strcmp(mode, "netascii");
|
||||
file = fdopen(fd, convert ?"wt":"wb");
|
||||
block = 1;
|
||||
firsttrip = 1;
|
||||
amount = 0;
|
||||
|
|
|
@ -175,7 +175,7 @@ set_socket_nonblock(int fd, int flag)
|
|||
{
|
||||
int err;
|
||||
int flags;
|
||||
#if defined(HAVE_FCNTL) && defined(O_NONBLOCK)
|
||||
#if defined(HAVE_FCNTL) && defined(HAVE_O_NONBLOCK_DEFINITION)
|
||||
/* Posixly correct */
|
||||
err = ((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
|
||||
(fcntl(fd, F_SETFL, flag ? flags|O_NONBLOCK : flags&~O_NONBLOCK) < 0);
|
||||
|
@ -929,7 +929,7 @@ FILE *file;
|
|||
* Validate file access. Since we
|
||||
* have no uid or gid, for now require
|
||||
* file to exist and be publicly
|
||||
* readable/writable.
|
||||
* readable/writable, unless -p specified.
|
||||
* If we were invoked with arguments
|
||||
* from inetd then the file must also be
|
||||
* in one of the given directory prefixes.
|
||||
|
@ -941,9 +941,10 @@ validate_access(char *filename, int mode, struct formats *pf)
|
|||
{
|
||||
struct stat stbuf;
|
||||
int i, len;
|
||||
int fd, wmode;
|
||||
int fd, wmode, rmode;
|
||||
char *cp;
|
||||
const char **dirp;
|
||||
char stdio_mode[3];
|
||||
|
||||
tsize_ok = 0;
|
||||
|
||||
|
@ -974,9 +975,12 @@ validate_access(char *filename, int mode, struct formats *pf)
|
|||
*/
|
||||
wmode = O_WRONLY |
|
||||
(cancreate ? O_CREAT : 0) |
|
||||
(unixperms ? O_TRUNC : 0);
|
||||
(unixperms ? O_TRUNC : 0) |
|
||||
(pf->f_convert ? O_TEXT : O_BINARY);
|
||||
rmode = O_RDONLY |
|
||||
(pf->f_convert ? O_TEXT : O_BINARY);
|
||||
|
||||
fd = open(filename, mode == RRQ ? O_RDONLY : wmode, 0666);
|
||||
fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
|
||||
if (fd < 0) {
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
|
@ -1015,7 +1019,11 @@ validate_access(char *filename, int mode, struct formats *pf)
|
|||
tsize_ok = 1;
|
||||
}
|
||||
|
||||
file = fdopen(fd, (mode == RRQ)? "r":"w");
|
||||
stdio_mode[0] = (mode == RRQ) ? 'r':'w';
|
||||
stdio_mode[1] = (pf->f_convert) ? 't':'b';
|
||||
stdio_mode[2] = '\0';
|
||||
|
||||
file = fdopen(fd, stdio_mode);
|
||||
if (file == NULL)
|
||||
exit(EX_OSERR); /* Internal error */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue