commit - b2263c45b76e09cf07b7149fb84b85777c682047
commit + 8f9f99f7fc753a3bf04eff946db4332ebd75a811
blob - 39f6ae2ca4f588e5ce2850fb6cf4fdf72c05cf47
blob + a2b0e5c0e7c1396d99b63d21105dcba6e63fbe42
--- kamiftp/ftp.c
+++ kamiftp/ftp.c
errx(1, "expected tag 0x%x, got 0x%x", tag, t);
}
+static char *
+check(uint8_t type, uint16_t tag)
+{
+ uint16_t rtag;
+ uint8_t rtype;
+
+ rtype = np_read8(buf);
+ rtag = np_read16(buf);
+ if (rtype == type) {
+ if (rtag != tag)
+ errx(1, "expected tag 0x%x, got 0x%x", tag, rtag);
+ return NULL;
+ }
+
+ if (rtype == Rerror)
+ return np_readstr(buf);
+
+ errx(1, "expected %s, got msg type %s",
+ pp_msg_type(type), pp_msg_type(rtype));
+}
+
static void
do_version(void)
{
ASSERT_EMPTYBUF();
}
-static int
-walk_path(int fid, int newfid, const char *path, struct qid *qid)
+static char *
+walk_path(int fid, int newfid, const char *path, int *missing,
+ struct qid *qid)
{
- char *wnames[MAXWELEM], *p, *t;
+ char *wnames[MAXWELEM], *p, *t, *errstr;
size_t nwname, i;
uint16_t nwqid;
twalk(fid, newfid, (const char **)wnames, nwname);
do_send();
recv_msg();
- expect2(Rwalk, iota_tag);
+ *missing = nwname;
+ if ((errstr = check(Rwalk, iota_tag)) != NULL)
+ return errstr;
+
nwqid = np_read16(buf);
assert(nwqid <= nwname);
free(p);
- return nwqid == nwname;
+ *missing = nwname - nwqid;
+ return NULL;
}
static void
cmd_cd(int argc, const char **argv)
{
struct qid qid;
- int nfid;
+ int nfid, miss;
+ char *errstr;
if (argc != 1) {
printf("usage: cd remote-path\n");
}
nfid = pwdfid+1;
- if (walk_path(pwdfid, nfid, argv[0], &qid) == -1 ||
- !(qid.type & QTDIR)) {
- printf("can't cd %s\n", argv[0]);
+ errstr = walk_path(pwdfid, nfid, argv[0], &miss, &qid);
+ if (errstr != NULL) {
+ printf("%s: %s\n", argv[0], errstr);
+ free(errstr);
+ return;
+ }
+
+ if (miss != 0 || !(qid.type & QTDIR)) {
+ printf("%s: not a directory\n", argv[0]);
do_clunk(nfid);
- } else {
- do_clunk(pwdfid);
- pwdfid = nfid;
+ return;
}
+
+ do_clunk(pwdfid);
+ pwdfid = nfid;
}
static void
{
struct qid qid;
const char *l;
- int nfid;
- int fd;
+ char *errstr;
+ int nfid, fd, miss;
if (argc != 1 && argc != 2) {
printf("usage: get remote-file [local-file]\n");
l = argv[0];
nfid = pwdfid+1;
- if (walk_path(pwdfid, nfid, argv[0], &qid) == -1) {
- printf("can't fetch %s\n", argv[0]);
+ errstr = walk_path(pwdfid, nfid, argv[0], &miss, &qid);
+ if (errstr != NULL) {
+ printf("%s: %s\n", argv[0], errstr);
+ free(errstr);
return;
}
- if (qid.type != 0) {
- printf("can't fetch %s\n", argv[0]);
+ if (miss != 0 || qid.type != 0) {
+ printf("%s: not a file\n", argv[0]);
do_clunk(nfid);
return;
}
cmd_page(int argc, const char **argv)
{
struct qid qid;
- int nfid, tmpfd;
- char sfn[24], p[PATH_MAX], *name;
+ int nfid, tmpfd, miss;
+ char sfn[24], p[PATH_MAX], *name, *errstr;
if (argc != 1) {
puts("usage: page file");
}
nfid = pwdfid+1;
- if (walk_path(pwdfid, nfid, *argv, &qid) == -1) {
- printf("can't fetch %s\n", *argv);
+ errstr = walk_path(pwdfid, nfid, *argv, &miss, &qid);
+ if (errstr != NULL) {
+ printf("%s: %s\n", *argv, errstr);
+ free(errstr);
return;
}
- if (qid.type != 0) {
- printf("can't page file type %s\n", pp_qid_type(qid.type));
+ if (miss != 0 || qid.type != 0) {
+ printf("%s: not a file\n", *argv);
do_clunk(nfid);
return;
}