ref: 1633e20b32f9311c8ac7cf43aca194c355aff985
parent: cbf003434b08faa8836046c8d04dc3d0d8fafac4
author: Jacob Moody <moody@posixcafe.org>
date: Sun Nov 26 15:23:45 EST 2023
ip/torrent: allow seeding files from read-only contexts. Makes 'auth/none ip/torrent -s ...' work without making the files world writable iff we already have all pieces of the torrent.
--- a/sys/src/cmd/ip/torrent.c
+++ b/sys/src/cmd/ip/torrent.c
@@ -29,7 +29,8 @@
{
File *next;
char *name;
- int fd;
+ int rfd;
+ int wfd;
vlong off;
vlong len;
};
@@ -204,7 +205,7 @@
break;
off -= f->off;
n = ((off + len) > f->len) ? f->len - off : len;
- if((n = (wr ? pwrite(f->fd, data, n, off) : pread(f->fd, data, n, off))) <= 0)
+ if((n = (wr ? pwrite(f->wfd, data, n, off) : pread(f->rfd, data, n, off))) <= 0)
return -1;
if((m = rwpiece(wr, index, data + n, len - n, poff + n)) < 0)
return -1;
@@ -1292,6 +1293,7 @@
f = mallocz(sizeof(*f), 1);
f->len = atoll(s);
f->name = dstr(dlook(info, "name"));
+ f->rfd = f->wfd = -1;
for(di = dlook(d->val, "path"); di && di->typ == 'l'; di = di->next)
if(s = dstr(di->val))
f->name = f->name ? smprint("%s/%s", f->name, s) : s;
@@ -1302,6 +1304,7 @@
f = mallocz(sizeof(*f), 1);
f->len = atoll(s);
f->name = dstr(dlook(info, "name"));
+ f->rfd = f->wfd = -1;
*fp = f;
}
len = 0;
@@ -1310,10 +1313,10 @@
sysfatal("bogus file entry in meta info");
s = fixnamedup(f->name);
if(vflag) fprint(pflag ? 2 : 1, "%s\n", s);
- if((f->fd = open(s, ORDWR)) < 0){
+ if((f->rfd = open(s, OREAD)) < 0){
if(mkdirs(s) < 0)
sysfatal("mkdirs: %r");
- if((f->fd = create(s, ORDWR, 0666)) < 0)
+ if((f->wfd = f->rfd = create(s, ORDWR, 0666)) < 0)
sysfatal("create: %r");
}
f->off = len;
@@ -1358,8 +1361,12 @@
while(waitpid() >= 0)
;
- if(finished() && !sflag)
- exits(0);
+ if(finished()){
+ if(!sflag)
+ exits(nil);
+ } else for(f = files; f; f = f->next)
+ if(f->wfd < 0 && (open(fixnamedup(f->name), OWRITE) < 0))
+ sysfatal("create: %r");
srand(truerand());
atnotify(catch, 1);