#include #include #define NODEFINE #include "dat.h" static char* rdenv(char *name) { char *v; int fd, size; fd = open(name, OREAD); if(fd < 0) return 0; size = seek(fd, 0, 2); v = malloc(size+1); if(v == 0) return nil; seek(fd, 0, 0); read(fd, v, size); v[size] = 0; close(fd); return v; } static int newwin(void) { char *srv, *mntsrv; char spec[100]; int srvfd; srv = rdenv("/env/wsys"); if(srv == 0){ mntsrv = rdenv("/mnt/term/env/wsys"); if(mntsrv == 0){ fprint(2, "factotum: can't find $wsys\n"); return -1; } srv = malloc(strlen(mntsrv)+10); strcpy(srv, "/mnt/term"); strcat(srv, mntsrv); free(mntsrv); } srvfd = open(srv, ORDWR); free(srv); if(srvfd == -1){ fprint(2, "factotum: can't open %s: %r\n", srv); return -1; } sprint(spec, "new", getpid()); if(mount(srvfd, -1, "/mnt/temp", 0, spec) == -1){ close(srvfd); fprint(2, "factotum: can't mount /mnt/wsys: %r (spec=%s)\n", spec); return -1; } close(srvfd); return 0; } /* * prompt for a string with a possible default response */ String* readcons(char *prompt, char *def, int raw) { int fdin, fdout, ctl, n; char line[10]; String *s = s_new(); if(newwin() < 0) return nil; fdin = open("/mnt/temp/cons", OREAD); if(fdin < 0) fdin = 0; fdout = open("/mnt/temp/cons", OWRITE); if(fdout < 0) fdout = 1; if(def != nil) fprint(fdout, "%s[%s]: ", prompt, def); else fprint(fdout, "%s: ", prompt); if(raw){ ctl = open("/mnt/temp/consctl", OWRITE); if(ctl >= 0) write(ctl, "rawon", 5); } else ctl = -1; for(;;){ n = read(fdin, line, 1); if(n == 0){ Error: close(fdin); close(fdout); if(ctl >= 0) close(ctl); s_free(s); unmount(nil, "/mnt/temp"); return nil; } if(n < 0) goto Error; if(line[0] == 0x7f) goto Error; if(n == 0 || line[0] == '\n' || line[0] == '\r'){ if(raw){ write(ctl, "rawoff", 6); write(fdout, "\n", 1); } close(ctl); close(fdin); close(fdout); s_terminate(s); if(*s_to_c(s) == 0 && def != nil) s_append(s, def); unmount(nil, "/mnt/temp"); return s; } if(line[0] == '\b'){ if(s_len(s) > 0) s->ptr--; } else if(line[0] == 0x15) { /* ^U: line kill */ s_reset(s); } else { s_putc(s, line[0]); } } abort(); return nil; /* how does this happen */ }