]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/ip/tftpd.c
ip/tftpd: fix %.*s format for homedir path
[plan9front.git] / sys / src / cmd / ip / tftpd.c
index 9b543a29e51babdc9a74c4a3d3e5579bbccbce6a..ab6d91f70e871d98db853e886ed155a419ee58a5 100644 (file)
@@ -6,12 +6,10 @@
 #include <auth.h>
 #include <bio.h>
 #include <ip.h>
-#include <ndb.h>
 
 enum
 {
        Maxpath=        128,
-       Maxerr=         256,
 
        Debug=          0,
 
@@ -86,16 +84,15 @@ void        nak(int, int, char*);
 void   ack(int, ushort);
 void   clrcon(void);
 void   setuser(void);
-char*  sunkernel(char*);
 void   remoteaddr(char*, char*, int);
 void   doserve(int);
 
 char   bigbuf[32768];
 char   raddr[64];
 
-char   *dir = "/lib/tftpd";
 char   *dirsl;
 int    dirsllen;
+char   *homedir = "/";
 char   flog[] = "ipboot";
 char   net[Maxpath];
 
@@ -130,7 +127,7 @@ main(int argc, char **argv)
                dbg++;
                break;
        case 'h':
-               dir = EARGF(usage());
+               homedir = EARGF(usage());
                break;
        case 'r':
                restricted = 1;
@@ -145,9 +142,10 @@ main(int argc, char **argv)
                usage();
        }ARGEND
 
-       snprint(buf, sizeof buf, "%s/", dir);
-       dirsl = strdup(buf);
-       dirsllen = strlen(dirsl);
+       dirsllen = strlen(homedir);
+       while(dirsllen > 0 && homedir[dirsllen-1] == '/')
+               dirsllen--;
+       dirsl = smprint("%.*s/", utfnlen(homedir, dirsllen), homedir);
 
        fmtinstall('E', eipfmt);
        fmtinstall('I', eipfmt);
@@ -157,8 +155,8 @@ main(int argc, char **argv)
         * "cd /usr/$user", so call setuser before chdir.
         */
        setuser();
-       if(chdir(dir) < 0)
-               sysfatal("can't get to directory %s: %r", dir);
+       if(chdir(homedir) < 0)
+               sysfatal("can't get to directory %s: %r", homedir);
 
        if(!dbg)
                switch(rfork(RFNOTEG|RFPROC|RFFDG)) {
@@ -302,12 +300,13 @@ options(int fd, char *buf, int bufsz, char *file, ushort oper, char *p, int dlen
                        break;
                dlen -= vallen;
 
-               nopts++;
                olen = 0;
                op = handleopt(fd, p, val);
                if (op == nil)
                        continue;
 
+               nopts++;
+
                /* append OACK response to buf */
                nmlen = emits(p, bp, ep);       /* option name */
                if (nmlen < 0)
@@ -340,9 +339,6 @@ options(int fd, char *buf, int bufsz, char *file, ushort oper, char *p, int dlen
        if (nopts == 0)
                return 0;               /* no options actually seen */
 
-       if (bp + 3 >= ep)
-               return -1;
-
        if (write(fd, buf, bp - buf) < bp - buf) {
                syslog(dbg, flog, "tftpd network write error on oack to %s: %r",
                        raddr);
@@ -545,9 +541,9 @@ awaitack(int fd, int block)
                if (Debug)
                        syslog(dbg, flog, "tftpd %d read ack of %d bytes "
                                "for block %d", pid, al, ackblock);
-               if(ackblock == block)
+               if(ackblock == (block & 0xffff))
                        return Ackok;           /* for block just sent */
-               else if(ackblock == block + 1)  /* intel pxe eof bug */
+               else if(ackblock == (block + 1 & 0xffff))       /* intel pxe eof bug */
                        return Ackok;
                else if(ackblock == 0xffff)
                        return Ackrexmit;
@@ -564,16 +560,10 @@ sendfile(int fd, char *name, char *mode, int opts)
 {
        int file, block, ret, rexmit, n, txtry;
        uchar buf[Maxsegsize+Hdrsize];
-       char errbuf[Maxerr];
+       char errbuf[ERRMAX];
 
-       file = -1;
        syslog(dbg, flog, "tftpd %d send file '%s' %s to %s",
                pid, name, mode, raddr);
-       name = sunkernel(name);
-       if(name == 0){
-               nak(fd, 0, "not in our database");
-               goto error;
-       }
 
        notify(catcher);
 
@@ -645,7 +635,7 @@ recvfile(int fd, char *name, char *mode)
 {
        ushort op, block, inblock;
        uchar buf[Maxsegsize+8];
-       char errbuf[Maxerr];
+       char errbuf[ERRMAX];
        int n, ret, file;
 
        syslog(dbg, flog, "receive file '%s' %s from %s", name, mode, raddr);
@@ -654,7 +644,7 @@ recvfile(int fd, char *name, char *mode)
        if(file < 0) {
                errstr(errbuf, sizeof errbuf);
                nak(fd, 0, errbuf);
-               syslog(dbg, flog, "can't create %s: %r", name);
+               syslog(dbg, flog, "can't create %s: %s", name, errbuf);
                return;
        }
 
@@ -732,13 +722,16 @@ nak(int fd, int code, char *msg)
        char buf[128];
        int n;
 
+       n = 5 + strlen(msg);
+       if(n > sizeof(buf))
+               n = sizeof(buf);
        buf[0] = 0;
        buf[1] = Tftp_ERROR;
        buf[2] = 0;
        buf[3] = code;
-       strcpy(buf+4, msg);
-       n = strlen(msg) + 4 + 1;
-       if(write(fd, buf, n) < n)
+       memmove(buf+4, msg, n - 5);
+       buf[n-1] = 0;
+       if(write(fd, buf, n) != n)
                sysfatal("write nak: %r");
 }
 
@@ -755,59 +748,6 @@ setuser(void)
                sysfatal("can't build namespace: %r");
 }
 
-char*
-lookup(char *sattr, char *sval, char *tattr, char *tval, int len)
-{
-       static Ndb *db;
-       char *attrs[1];
-       Ndbtuple *t;
-
-       if(db == nil)
-               db = ndbopen(0);
-       if(db == nil)
-               return nil;
-
-       if(sattr == nil)
-               sattr = ipattr(sval);
-
-       attrs[0] = tattr;
-       t = ndbipinfo(db, sattr, sval, attrs, 1);
-       if(t == nil)
-               return nil;
-       strncpy(tval, t->val, len);
-       tval[len-1] = 0;
-       ndbfree(t);
-       return tval;
-}
-
-/*
- *  for sun kernel boots, replace the requested file name with
- *  a one from our database.  If the database doesn't specify a file,
- *  don't answer.
- */
-char*
-sunkernel(char *name)
-{
-       ulong addr;
-       uchar v4[IPv4addrlen];
-       uchar v6[IPaddrlen];
-       char buf[256];
-       char ipbuf[128];
-       char *suffix;
-
-       addr = strtoul(name, &suffix, 16);
-       if(suffix-name != 8 || (strcmp(suffix, "") != 0 && strcmp(suffix, ".SUN") != 0))
-               return name;
-
-       v4[0] = addr>>24;
-       v4[1] = addr>>16;
-       v4[2] = addr>>8;
-       v4[3] = addr;
-       v4tov6(v6, v4);
-       sprint(ipbuf, "%I", v6);
-       return lookup("ip", ipbuf, "bootf", buf, sizeof buf);
-}
-
 void
 remoteaddr(char *dir, char *raddr, int len)
 {