1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-27 04:40:59 +01:00

zsh-3.1.5-pws-5

This commit is contained in:
Tanaka Akira 1999-04-15 18:11:42 +00:00
parent 2a5a899a55
commit 20d67907c9
47 changed files with 2212 additions and 425 deletions

View file

@ -5,4 +5,5 @@ DISTFILES_SRC='
example.mdd example.c
files.mdd files.c
stat.mdd stat.c
zftp.mdd zftp.c
'

View file

@ -1,3 +1,6 @@
autobins="example"
autoinfixconds="ex"
autoprefixconds="len"
objects="example.o"

View file

@ -195,18 +195,18 @@ bin_ln(char *nam, char **args, char *ops, int func)
if(func == BIN_MV) {
move = rename;
move = (MoveFunc) rename;
flags = ops['f'] ? 0 : MV_ASKNW;
flags |= MV_ATOMIC;
} else {
flags = ops['f'] ? MV_FORCE : 0;
#ifdef HAVE_LSTAT
if(ops['s'])
move = symlink;
move = (MoveFunc) symlink;
else
#endif
{
move = link;
move = (MoveFunc) link;
if(!ops['d'])
flags |= MV_NODIRS;
}

View file

@ -346,7 +346,7 @@ bin_stat(char *name, char **args, char *ops, int func)
} else {
for (; *arg; arg++) {
if (strchr("glLnNrstT", *arg))
ops[*arg] = 1;
ops[STOUC(*arg)] = 1;
else if (*arg == 'A') {
if (arg[1]) {
arrnam = arg+1;
@ -505,7 +505,7 @@ bin_stat(char *name, char **args, char *ops, int func)
continue;
}
if (flags & STF_FILE)
if (flags & STF_FILE) {
if (arrnam)
*arrptr++ = ztrdup(*args);
else if (hashnam) {
@ -513,6 +513,7 @@ bin_stat(char *name, char **args, char *ops, int func)
*hashptr++ = ztrdup(*args);
} else
printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n");
}
if (iwhich > -1) {
statprint(&statbuf, outbuf, *args, iwhich, flags);
if (arrnam)
@ -544,7 +545,7 @@ bin_stat(char *name, char **args, char *ops, int func)
putchar('\n');
}
if (arrnam)
if (arrnam) {
if (ret)
freearray(array);
else {
@ -552,8 +553,9 @@ bin_stat(char *name, char **args, char *ops, int func)
if (errflag)
return 1;
}
}
if (hashnam)
if (hashnam) {
if (ret)
freearray(hash);
else {
@ -561,6 +563,7 @@ bin_stat(char *name, char **args, char *ops, int func)
if (errflag)
return 1;
}
}
return ret;
}

View file

@ -62,9 +62,19 @@
/* it's a TELNET based protocol, but don't think I like doing this */
#include <arpa/telnet.h>
/*
* We use poll() in preference to select because some subset of manuals says
* that's the thing to do, plus it's a bit less fiddly. I don't actually
* have access to a system with poll but not select, however, though
* both bits of the code have been tested on a machine with both.
*/
#ifdef HAVE_POLL_H
# include <poll.h>
#endif
/* pinch the definition from <netinet/in.h> for deficient headers */
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
# define INADDR_NONE 0xffffffff
#endif
/*
@ -124,7 +134,8 @@ enum {
ZFTP_HERE = 0x0100, /* here rather than over there */
ZFTP_CDUP = 0x0200, /* CDUP rather than CWD */
ZFTP_REST = 0x0400, /* restart: set point in remote file */
ZFTP_RECV = 0x0800 /* receive rather than send */
ZFTP_RECV = 0x0800, /* receive rather than send */
ZFTP_TEST = 0x1000 /* test command, don't test */
};
typedef struct zftpcmd *Zftpcmd;
@ -134,6 +145,7 @@ static struct zftpcmd zftpcmdtab[] = {
{ "params", zftp_params, 0, 4, 0 },
{ "login", zftp_login, 0, 3, ZFTP_CONN },
{ "user", zftp_login, 0, 3, ZFTP_CONN },
{ "test", zftp_test, 0, 0, ZFTP_TEST },
{ "cd", zftp_cd, 1, 1, ZFTP_CONN|ZFTP_LOGI },
{ "cdup", zftp_cd, 0, 0, ZFTP_CONN|ZFTP_LOGI|ZFTP_CDUP },
{ "dir", zftp_dir, 0, -1, ZFTP_CONN|ZFTP_LOGI },
@ -674,8 +686,8 @@ zfgetmsg()
zfgetline(line, 256, tmout);
ptr = line;
if (zfdrrrring || !isdigit((int)*ptr) || !isdigit((int)ptr[1]) ||
!isdigit((int)ptr[2])) {
if (zfdrrrring || !isdigit(STOUC(*ptr)) || !isdigit(STOUC(ptr[1])) ||
!isdigit(STOUC(ptr[2]))) {
/* timeout, or not talking FTP. not really interested. */
zcfinish = 2;
if (!zfclosing)
@ -820,7 +832,7 @@ zfopendata(char *name)
zwarnnam(name, "Must set preference S or P to transfer data", NULL, 0);
return 1;
}
zdfd = zfmovefd(socket(AF_INET, SOCK_STREAM, 0));
zdfd = socket(AF_INET, SOCK_STREAM, 0);
if (zdfd < 0) {
zwarnnam(name, "can't get data socket: %e", NULL, errno);
return 1;
@ -851,7 +863,7 @@ zfopendata(char *name)
* lastmsg already has the reply code expunged.
*/
for (ptr = lastmsg; *ptr; ptr++)
if (isdigit(*ptr))
if (isdigit(STOUC(*ptr)))
break;
if (sscanf(ptr, "%d,%d,%d,%d,%d,%d",
nums, nums+1, nums+2, nums+3, nums+4, nums+5) != 6) {
@ -986,11 +998,11 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
char *ptr = strstr(lastmsg, "bytes");
zfstatus |= ZFST_NOSZ|ZFST_TRSZ;
if (ptr) {
while (ptr > lastmsg && !isdigit(*ptr))
while (ptr > lastmsg && !isdigit(STOUC(*ptr)))
ptr--;
while (ptr > lastmsg && isdigit(ptr[-1]))
while (ptr > lastmsg && isdigit(STOUC(ptr[-1])))
ptr--;
if (isdigit(*ptr)) {
if (isdigit(STOUC(*ptr))) {
zfstatus &= ~ZFST_NOSZ;
if (getsize) {
long sz = zstrtol(ptr, NULL, 10);
@ -1017,6 +1029,13 @@ zfgetdata(char *name, char *rest, char *cmd, int getsize)
return 1;
}
zdfd = newfd; /* this is now the actual data fd */
} else {
/*
* We avoided dup'ing zdfd up to this point, to try to keep
* things simple, so we now need to move it out of the way
* of the user-visible fd's.
*/
zdfd = zfmovefd(zdfd);
}
@ -1659,7 +1678,7 @@ zftp_open(char *name, char **args, int flags)
}
zsock.sin_port = zservp->s_port;
zcfd = zfmovefd(socket(zsock.sin_family, SOCK_STREAM, 0));
zcfd = socket(zsock.sin_family, SOCK_STREAM, 0);
if (zcfd < 0) {
zwarnnam(name, "socket failed: %e", NULL, errno);
zfunsetparam("ZFTP_HOST");
@ -1667,12 +1686,6 @@ zftp_open(char *name, char **args, int flags)
return 1;
}
#if defined(F_SETFD) && defined(FD_CLOEXEC)
/* If the shell execs a program, we don't want this fd left open. */
len = FD_CLOEXEC;
fcntl(zcfd, F_SETFD, &len);
#endif
/*
* now connect the socket. manual pages all say things like `this is all
* explained oh-so-wonderfully in some other manual page'. not.
@ -1708,6 +1721,19 @@ zftp_open(char *name, char **args, int flags)
/* now we can talk to the control connection */
zcfinish = 0;
/*
* Move the fd out of the user-visible range. We need to do
* this after the connect() on some systems.
*/
zcfd = zfmovefd(zcfd);
#if defined(F_SETFD) && defined(FD_CLOEXEC)
/* If the shell execs a program, we don't want this fd left open. */
len = FD_CLOEXEC;
fcntl(zcfd, F_SETFD, &len);
#endif
len = sizeof(zsock);
if (getsockname(zcfd, (struct sockaddr *)&zsock, &len) < 0) {
zwarnnam(name, "getsockname failed: %e", NULL, errno);
@ -2022,6 +2048,69 @@ zftp_login(char *name, char **args, int flags)
return zfgetcwd();
}
/*
* See if the server wants to tell us something. On a timeout, we usually
* have a `421 Timeout' or something such waiting for us, so we read
* it here. As well as being called explicitly by the user
* (precmd is a very good place for this, it's cheap since it has
* no network overhead), we call it in the bin_zftp front end if we
* have a connection and weren't going to call it anyway.
*
* Poll-free and select-free systems are few and far between these days,
* but I'm willing to consider suggestions.
*/
/**/
static int
zftp_test(char *name, char **args, int flags)
{
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
int ret;
# ifdef HAVE_POLL
struct pollfd pfd;
# else
fd_set f;
struct timeval tv;
# endif /* HAVE_POLL */
if (zcfd == -1)
return 1;
# ifdef HAVE_POLL
# ifndef POLLIN
/* safety first, though I think POLLIN is more common */
# define POLLIN POLLNORM
# endif /* HAVE_POLL */
pfd.fd = zcfd;
pfd.events = POLLIN;
if ((ret = poll(&pfd, 1, 0)) < 0 && errno != EINTR && errno != EAGAIN)
zfclose();
else if (ret > 0 && pfd.revents) {
/* handles 421 (maybe a bit noisily?) */
zfgetmsg();
}
# else
FD_ZERO(&f);
FD_SET(zcfd, &f);
tv.tv_sec = 0;
tv.tv_usec = 0;
if ((ret = select(zcfd +1, (SELECT_ARG_2_T) &f, NULL, NULL, &tv)) < 0
&& errno != EINTR)
zfclose();
else if (ret > 0) {
/* handles 421 */
zfgetmsg();
}
# endif /* HAVE_POLL */
/* if we now have zcfd == -1, then we've just been dumped out. */
return (zcfd == -1) ? 2 : 0;
#else
zfwarnnam(name, "not supported on this system.", NULL, 0);
return 3;
#endif /* defined(HAVE_POLL) || defined(HAVE_SELECT) */
}
/* do ls or dir on the remote directory */
/**/
@ -2476,7 +2565,7 @@ bin_zftp(char *name, char **args, char *ops, int func)
char fullname[11] = "zftp ";
char *cnam = *args++, *prefs, *ptr;
Zftpcmd zptr;
int n, ret;
int n, ret = 0;
for (zptr = zftpcmdtab; zptr->nam; zptr++)
if (!strcmp(zptr->nam, cnam))
@ -2521,8 +2610,25 @@ bin_zftp(char *name, char **args, char *ops, int func)
"B" : "S"), ZFPM_READONLY);
}
}
#if defined(HAVE_SELECT) || defined (HAVE_POLL)
if (zcfd != -1 && !(zptr->flags & ZFTP_TEST)) {
/*
* Test the connection for a bad fd or incoming message, but
* only if the connection was last heard of open, and
* if we are not about to call the test command anyway.
* Not worth it unless we have select() or poll().
*/
ret = zftp_test("zftp test", NULL, 0);
}
#endif
if ((zptr->flags & ZFTP_CONN) && zcfd == -1) {
zwarnnam(fullname, "not connected.", NULL, 0);
if (ret != 2) {
/*
* with ret == 2, we just got dumped out in the test,
* so enough messages already.
*/
zwarnnam(fullname, "not connected.", NULL, 0);
}
return 1;
}