void winread(Window *w, uint q0, uint q1, char *data) { int m, n, nr; char buf[256]; if(w->addr < 0) w->addr = winopenfile(w, "addr"); if(w->data < 0) w->data = winopenfile(w, "data"); m = q0; while(m < q1){ n = sprint(buf, "#%d", m); if(write(w->addr, buf, n) != n) error("error writing addr: %r"); n = read(w->data, buf, sizeof buf); if(n <= 0) error("reading data: %r"); nr = utfnlen(buf, n); while(m+nr >q1){ do; while(n>0 && (buf[--n]&0xC0)==0x80); --nr; } if(n == 0) break; memmove(data, buf, n); data += n; *data = 0; m += nr; } }
/* * Depends on d.qid.vers being highest numbered message in dir. */ void acmetimer(Article *m, Window *w) { Biobuf *b; Dir *d; assert(m==nil && w==root); if((d = dirstat(dir))==nil | hi==d->qid.vers){ free(d); return; } if(w->data < 0) w->data = winopenfile(w, "data"); if(winsetaddr(w, "0", 0)) write(w->data, "", 0); b = emalloc(sizeof(*b)); Binit(b, w->data, OWRITE); adddir(b, d->qid.vers, hi+1, d->qid.vers); hi = d->qid.vers; Bterm(b); free(b); free(d); winselect(w, "0,.", 0); }
void wintagwrite(Window *w, char *s, int n) { int fd; fd = winopenfile(w, "tag"); if(write(fd, s, n) != n) error("tag write: %r"); close(fd); }
int winsetaddr(Window *w, char *addr, int errok) { if(w->addr < 0) w->addr = winopenfile(w, "addr"); if(write(w->addr, addr, strlen(addr)) < 0){ if(!errok) error("error writing addr(%s): %r", addr); return 0; } return 1; }
frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock) { fileref_t *fref; char buf[256]; int val, filter; char *prompt; strcpy(buf, ""); switch (usage & fileusage_TypeMask) { case fileusage_SavedGame: prompt = "Saved game"; filter = FILTER_SAVE; break; case fileusage_Transcript: prompt = "Transcript file"; filter = FILTER_TEXT; break; case fileusage_InputRecord: prompt = "Command record file"; filter = FILTER_TEXT; break; case fileusage_Data: default: prompt = "Data file"; filter = FILTER_ALL; break; } if (fmode == filemode_Read) winopenfile(prompt, buf, sizeof buf, filter); else winsavefile(prompt, buf, sizeof buf, filter); val = strlen(buf); if (!val) { /* The player just hit return. It would be nice to provide a default value, but this implementation is too cheap. */ return NULL; } fref = gli_new_fileref(buf, usage, rock); if (!fref) { gli_strict_warning("fileref_create_by_prompt: unable to create fileref."); return NULL; } return fref; }
/* * Show the first nshow messages in the window. * This depends on nntpfs presenting contiguously * numbered directories, and on the qid version being * the topmost numbered directory. */ void dirwindow(Window *w) { if((hi=gethi()) < 0) return; if(w->data < 0) w->data = winopenfile(w, "data"); fprint(w->ctl, "dirty\n"); winopenbody(w, OWRITE); lo = adddir(w->body, hi, 0, nshow); winclean(w); }
void mesgmenudel(Window *w, Message *mbox, Message *m) { char *buf; if(w->data < 0) w->data = winopenfile(w, "data"); buf = name2regexp(deletedrx, m->name); if(winsetaddr(w, buf, 1) && winsetaddr(w, ".,./.*\\n(\t.*\\n)*/", 1)) write(w->data, "", 0); free(buf); close(w->data); close(w->addr); w->addr = w->data = -1; mbox->dirty = 1; m->deleted = 1; }
void mesgmenumark(Window *w, char *which, char *mark) { char *buf; if(w->data < 0) w->data = winopenfile(w, "data"); buf = name2regexp(deletedrx01, which); if(winsetaddr(w, buf, 1) && winsetaddr(w, "+0-#1", 1)) /* go to end of line */ write(w->data, mark, strlen(mark)); free(buf); close(w->data); close(w->addr); w->addr = w->data = -1; if(!mbox.dirty) winclean(w); }
void mesgmenumarkundel(Window *w, Message* _, Message *m) { char *buf; if(m->deleted == 0) return; if(w->data < 0) w->data = winopenfile(w, "data"); buf = name2regexp(deletedrx, m->name); if(winselect(w, buf, 1)) if(winsetaddr(w, deletedaddr, 1)) write(w->data, "", 0); free(buf); close(w->data); close(w->addr); w->addr = w->data = -1; m->deleted = 0; }
Window* newwindow(void) { char buf[12]; Window *w; w = emalloc(sizeof(Window)); w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC); if(w->ctl<0 || read(w->ctl, buf, 12)!=12) error("can't open window ctl file: %r"); ctlprint(w->ctl, "noscroll\n"); w->id = atoi(buf); w->event = winopenfile(w, "event"); w->addr = -1; /* will be opened when needed */ w->body = nil; w->data = -1; w->cevent = chancreate(sizeof(Event*), 0); return w; }
/* one new message has arrived, as mbox->tail */ void mesgmenunew(Window *w, Message *mbox) { Biobuf *b; winselect(w, "0", 0); w->data = winopenfile(w, "data"); b = emalloc(sizeof(Biobuf)); Binit(b, w->data, OWRITE); mesgmenu0(w, mbox, mbox->name, "", 0, b, 1, !shortmenu); Bterm(b); free(b); if(!mbox->dirty) winclean(w); /* select tag line plus following indented lines, but not final newline (it's distinctive) */ winselect(w, "0/.*\\n((\t.*\\n)*\t.*)?/", 1); close(w->addr); close(w->data); w->addr = -1; w->data = -1; }
/* * find the playing string, leave in addr * if q0, q1 are non-nil, set them to the addr of the string. */ int findplay(Window *w, char *s, uint32_t *q0, uint32_t *q1) { char xbuf[25]; if(w->data < 0) w->data = winopenfile(w, "data"); if(!winsetaddr(w, "#0", 1) || !winsetaddr(w, s, 1)) return 0; seek(w->addr, 0, 0); if(read(w->addr, xbuf, 24) != 24) return 0; xbuf[24] = 0; if(q0) *q0 = atoi(xbuf); if(q1) *q1 = atoi(xbuf+12); return 1; }
void mesgmenumarkdel(Window *w, Message *mbox, Message *m, int writeback) { char *buf; if(m->deleted) return; m->writebackdel = writeback; if(w->data < 0) w->data = winopenfile(w, "data"); buf = name2regexp("", m->name); strcat(buf, "-#0"); if(winselect(w, buf, 1)) write(w->data, deleted, 10); free(buf); close(w->data); close(w->addr); w->addr = w->data = -1; mbox->dirty = 1; m->deleted = 1; }
void wikiget(Wiki *w) { char *p; int fd, normal; Biobuf *bin; fprint(w->win->ctl, "dirty\n"); p = emalloc(strlen(w->arg)+8+1); strcpy(p, w->arg); normal = 1; if(p[strlen(p)-1] == '/'){ normal = 0; strcat(p, "current"); }else if(strlen(p)>8 && strcmp(p+strlen(p)-8, "/current")==0){ normal = 0; w->arg[strlen(w->arg)-7] = '\0'; } if((fd = open(p, OREAD)) < 0){ fprint(2, "Wiki: cannot read %s: %r\n", p); winclean(w->win); return; } free(p); winopenbody(w->win, OWRITE); bin = emalloc(sizeof(*bin)); Binit(bin, fd, OREAD); p = nil; if(!normal){ if((p = Brdline(bin, '\n')) == nil){ fprint(2, "Wiki: cannot read title: %r\n"); winclean(w->win); close(fd); free(bin); return; } p[Blinelen(bin)-1] = '\0'; } /* clear window */ if(w->win->data < 0) w->win->data = winopenfile(w->win, "data"); if(winsetaddr(w->win, ",", 0)) write(w->win->data, "", 0); if(!normal) Bprint(w->win->body, "%s\n\n", p); while(p = Brdline(bin, '\n')){ p[Blinelen(bin)-1] = '\0'; if(normal) Bprint(w->win->body, "%s\n", p); else{ if(p[0]=='D') w->time = strtoul(p+1, 0, 10); else if(p[0]=='#') Bprint(w->win->body, "%s\n", p+1); } } winclean(w->win); free(bin); close(fd); }
int acmecmd(Article *m, Window *w, char *s) { int n; Biobuf *b; //fprint(2, "cmd %s\n", s); s = skip(s, ""); if(iscmd(s, "Del")){ if(m == nil){ /* don't close dir until messages close */ if(mlist != nil){ ctlprint(mlist->w->ctl, "show\n"); return 1; } if(windel(w, 0)) threadexitsall(nil); return 1; }else{ if(windel(w, 0)) m->dead = 1; return 1; } } if(m==nil && iscmd(s, "More")){ s = skip(s, "More"); if(n = atoi(s)) nshow = n; if(w->data < 0) w->data = winopenfile(w, "data"); winsetaddr(w, "$", 1); fprint(w->ctl, "dirty\n"); b = emalloc(sizeof(*b)); Binit(b, w->data, OWRITE); lo = adddir(b, lo, 0, nshow); Bterm(b); free(b); winclean(w); winsetaddr(w, ".,", 0); } if(m!=nil && !m->ispost && iscmd(s, "Headers")){ m->headers = !m->headers; fillmesgwindow(-1, m); return 1; } if(iscmd(s, "Newpost")){ m = newpost(); winopenbody(m->w, OWRITE); Bprint(m->w->body, "%s\nsubject: \n\n", group); winclean(m->w); winselect(m->w, "$", 0); return 1; } if(m!=nil && !m->ispost && iscmd(s, "Reply")){ replywindow(m); return 1; } // if(m!=nil && iscmd(s, "Replymail")){ // fprint(2, "no replymail yet\n"); // return 1; // } if(iscmd(s, "Post")){ mesgpost(m); return 1; } return 0; }
int fillmesgwindow(int fd, Article *m) { Biobuf *b; char *p, tmp[40]; int i, inhdr, copy, xfd; Window *w; xfd = -1; if(fd == -1){ sprint(tmp, "%d/article", m->n); p = estrstrdup(dir, tmp); if((xfd = open(p, OREAD)) < 0){ free(p); return 0; } free(p); fd = xfd; } w = m->w; if(w->data < 0) w->data = winopenfile(w, "data"); if(winsetaddr(w, ",", 0)) write(w->data, "", 0); winopenbody(m->w, OWRITE); b = emalloc(sizeof(*b)); Binit(b, fd, OREAD); inhdr = 1; copy = 1; while(p = Brdline(b, '\n')){ if(Blinelen(b)==1) inhdr = 0, copy=1; if(inhdr && !isspace(p[0])){ copy = 1; if(!m->headers){ if(cistrncmp(p, "from:", 5)==0){ p[Blinelen(b)-1] = '\0'; p = fixfrom(skip(p, "from:")); Bprint(m->w->body, "From: %s\n", p); free(p); copy = 0; continue; } for(i=0; i<nelem(skipheader); i++) if(cistrncmp(p, skipheader[i], strlen(skipheader[i]))==0) copy=0; } } if(copy) Bwrite(m->w->body, p, Blinelen(b)); } Bterm(b); free(b); winclean(m->w); if(xfd != -1) close(xfd); return 1; }
int pipecommand(Window *w, char *s) { ulong q0, q1; char tmp[32], *t; int n, k; while(*s==' ' || *s=='\t' || *s=='\n') s++; if(strcmp(s, "Delete")==0){ windel(w, 1); threadexits(nil); return 1; } if(strcmp(s, "Del")==0){ if(windel(w, 0)) threadexits(nil); return 1; } if(strcmp(s, "Send") == 0){ if(w->addr < 0) w->addr = winopenfile(w, "addr"); ctlprint(w->ctl, "addr=dot\n"); seek(w->addr, 0UL, 0); if(read(w->addr, tmp, 2*12) == 2*12){ q0 = atol(tmp+0*12); q1 = atol(tmp+1*12); if(q0 == q1){ t = nil; k = 0; if(snarffd > 0){ seek(0, snarffd, 0); for(;;){ t = realloc(t, k+8192+2); if(t == nil) error("alloc failed: %r\n"); n = read(snarffd, t+k, 8192); if(n <= 0) break; k += n; } t[k] = 0; } }else{ t = emalloc((q1-q0)*UTFmax+2); winread(w, q0, q1, t); k = strlen(t); } if(t!=nil && t[0]!='\0'){ if(t[k-1]!='\n' && t[k-1]!='\004'){ t[k++] = '\n'; t[k] = '\0'; } sendit(t); } free(t); } return 1; } return 0; }
int mesgopen(Message *mbox, char *dir, char *s, Message *mesg, int plumbed, char *digest) { char *t, *u, *v; Message *m; char *direlem[10]; int i, ndirelem, reuse; /* find white-space-delimited first word */ for(t=s; *t!='\0' && !isspace(*t); t++) ; u = emalloc(t-s+1); memmove(u, s, t-s); /* separate it on slashes */ ndirelem = tokenizec(u, direlem, nelem(direlem), "/"); if(ndirelem <= 0){ Error: free(u); return 0; } if(plumbed){ write(wctlfd, "top", 3); write(wctlfd, "current", 7); } /* open window for message */ m = mesglookup(mbox, direlem[0], digest); if(m == nil) goto Error; if(mesg!=nil && m!=mesg) /* string looked like subpart but isn't part of this message */ goto Error; if(m->opened == 0){ if(m->w == nil){ reuse = 0; m->w = newwindow(); }else{ reuse = 1; /* re-use existing window */ if(winsetaddr(m->w, "0,$", 1)){ if(m->w->data < 0) m->w->data = winopenfile(m->w, "data"); write(m->w->data, "", 0); } } v = estrstrdup(mbox->name, m->name); winname(m->w, v); free(v); if(!reuse){ if(m->deleted) wintagwrite(m->w, "Q Reply all UnDelmesg Save ", 2+6+4+10+5); else wintagwrite(m->w, "Q Reply all Delmesg Save ", 2+6+4+8+5); } threadcreate(mesgctl, m, STACK); winopenbody(m->w, OWRITE); mesgload(m, dir, m->name, m->w); winclosebody(m->w); winclean(m->w); m->opened = 1; if(ndirelem == 1){ free(u); return 1; } } if(ndirelem == 1 && plumbport(m->type, m->filename) <= 0){ /* make sure dot is visible */ ctlprint(m->w->ctl, "show\n"); return 0; } /* walk to subpart */ dir = estrstrdup(dir, m->name); for(i=1; i<ndirelem; i++){ m = mesglookup(m, direlem[i], digest); if(m == nil) break; dir = egrow(dir, m->name, nil); } if(m != nil && plumbport(m->type, m->filename) > 0) plumb(m, dir); free(dir); free(u); return 1; }