shithub: todofs

Download patch

ref: efe80883a260ebb4396edd73dd707a72a0ccc222
parent: a05459a8d6a5a190db2fe52a89ed22bf515834b4
author: sirjofri <sirjofri@sirjofri.de>
date: Thu Jun 27 13:05:08 EDT 2024

adds file extension rename support

--- a/README
+++ b/README
@@ -37,7 +37,9 @@
 
 To edit a task, just open/read/write the task/data file. This will be forwarded to files-on-disk automatically.
 
-The data file can have a file extension, depending on the file extension. This should be used for plumbing. Adding a file extension using the filesystem is a TODO.
+The data file can have a file extension, depending on the file extension. This should be used for plumbing. To change this file extension, just rename the data file:
+
+	; mv 2-Second_Task/data 2-Second_Task/data.txt
 
 To rename a task:
 
--- a/todofs.c
+++ b/todofs.c
@@ -166,6 +166,19 @@
 	return 0;
 }
 
+static char*
+taskfile(Task *t, char *ext)
+{
+	if (ext) {
+		return smprint("%s%s", ultostr(t->id), ext);
+	} else {
+		if (t->ext)
+			return smprint("%s%s", ultostr(t->id), t->ext);
+		else
+			return smprint("%s", ultostr(t->id));
+	}
+}
+
 Status*
 getstatus(char *name, int *id)
 {
@@ -433,6 +446,46 @@
 }
 
 static int
+settaskextension(Task *t, char *name)
+{
+	Dir null, *dir;
+	char *fromfile, *tofile;
+	char *ext;
+	
+	ext = strchr(name, '.');
+	fromfile = taskfile(t, nil);
+	tofile = taskfile(t, ext && ext[1] ? ext : "");
+	
+	dir = dirstat(tofile);
+	if (dir) {
+		fprint(2, "%s exists: remove\n", tofile);
+		if (remove(tofile) < 0) {
+			free(dir);
+			free(fromfile);
+			free(tofile);
+			return 0;
+		}
+		free(dir);
+	}
+	
+	nulldir(&null);
+	null.name = tofile;
+	if (!dirwstat(fromfile, &null) < 0)
+		goto Errout;
+	
+	free(fromfile);
+	free(tofile);
+	free(dir);
+	return 1;
+	
+Errout:
+	free(fromfile);
+	free(tofile);
+	free(dir);
+	return 0;
+}
+
+static int
 updatetask(Task *t, char *name, char *assignee, char *group, char *title)
 {
 	char buf[32];
@@ -1130,6 +1183,8 @@
 	r->ofcall.qid = (Qid){Qdir, 0, QTDIR};
 	r->fid->qid = r->ofcall.qid;
 	r->fid->aux = 0;
+	readstatuses();
+	readtasks();
 	respond(r, nil);
 }
 
@@ -1165,6 +1220,8 @@
 			*qid = (Qid){mkqid(Qdir, 0), 0, QTDIR};
 			return nil;
 		}
+		readstatuses();
+		readtasks();
 		if (t = getftask(name, &sid, &tid)) {
 			if (qnum != sid) {
 				return "task has a different status";
@@ -1174,6 +1231,8 @@
 		}
 		return "task not found";
 	case Qtask:
+		readstatuses();
+		readtasks();
 		t = getgtask(qnum, &s);
 		if (!t) {
 			return "task not found";
@@ -1199,10 +1258,6 @@
 			*qid = (Qid){mkqid(Qdata, qnum), 0, 0};
 			return nil;
 		}
-		if (strcmp(name, qnames[Qdata]) == 0) {
-			*qid = (Qid){mkqid(Qdata, qnum), 0, 0};
-			return nil;
-		}
 	}
 	return "error";
 }
@@ -1218,11 +1273,16 @@
 fswstat(Req *r)
 {
 	Task *t;
+	ulong qnum;
 	int save = 0;
 	
+	qnum = qidnum(r->fid->qid.path);
+	
 	switch (qidtype(r->fid->qid.path)) {
 	case Qtask:
-		t = getgtask(qidnum(r->fid->qid.path), nil);
+		readstatuses();
+		readtasks();
+		t = getgtask(qnum, nil);
 		if (!t) {
 			respond(r, "invalid task");
 			return;
@@ -1250,6 +1310,23 @@
 		if (save)
 			savedata();
 		
+		break;
+	case Qdata:
+		readstatuses();
+		readtasks();
+		t = getgtask(qnum, nil);
+		if (!t) {
+			responderror(r);
+			return;
+		}
+		if (!r->d.name || !r->d.name[0]) {
+			respond(r, "invalid operation");
+			return;
+		}
+		if (!settaskextension(t, r->d.name)) {
+			responderror(r);
+			return;
+		}
 		break;
 	default:
 		respond(r, "invalid operation");