static int rwcommon(Vqctl *d, void *va, int32_t n, int qidx) { uint16_t descr[1]; Virtq *vq = d->vqs[qidx]; if(vq == nil) { error("virtcon: no virtqueue"); } int nd = getdescr(vq, 1, descr); if(nd < 1) { error("virtcon: queue low"); return -1; } uint8_t *buf = malloc(n); if(buf==nil) { error("devvcon: no memory to allocate the exchange buffer"); return -1; } if(qidx) { memmove(buf, va, n); } q2descr(vq, descr[0])->addr = PADDR(buf); q2descr(vq, descr[0])->len = n; if(!qidx) { q2descr(vq, descr[0])->flags = VRING_DESC_F_WRITE; } int rc = queuedescr(vq, 1, descr); if(!qidx) { memmove(va, buf, n); } reldescr(vq, 1, descr); free(buf); return (rc >= 0)?n:rc; }
int main(int argc, char *argv[]) { /* setlocale(), so mbtowc() etc will work. We may want to encode/decode non-ascii stuff. Spies works with many scripts . . . */ if (setlocale(LC_ALL, "") == NULL) feil("Bad locale, please configure your computer correctly. Install the locale package, and/or set the LANG environment variable.\n"); if (argc < 2) feil("enigma machine-description\n"); machine *m=getdescr(argv[1]); if (!m) feil("Unuseable machine description\n"); interactive(m); }
void getlist_newsgroups(SERVER *server, int sock, char *glist) { char group[512], descr[512]; int num = 0, nd; struct DESCR *dsc; sprintf(buf, "LIST newsgroups %s\r\n", glist); if ( write_socket(sock, buf, strlen(buf), server->Timeout) == -1 ) die("Cant write to server"); if ( fgetsrn(buf, BUFSIZE, sock) == NULL ) die("Cant read list newsgroups response"); if ( atoi(buf) != 215 ) die("Invalid response from server: %s", buf); nd = numdescrs; while ( 1 ) { if ( fgetsrn(buf, BUFSIZE, sock) == NULL ) die("Cant read newsgroups file"); if ( buf[0] == '.' && buf[1] == '\r' ) break; if ( sscanf(buf, "%510s %510[^\r\n]", group, descr) == 2 ) { /* * check for garbage description like "???" or "No description" or such * this will also match correct descriptions which just happen to have the * word description in their name. */ if ( descr[0] != '?' && strstr(descr, "Description") == NULL && strstr(descr, "description") == NULL ) { if ( (dsc=getdescr(group, nd)) == NULL ) { (descriptions+numdescrs)->newsgroup = strdup(group); (descriptions+numdescrs)->description = strdup(descr); num++; numdescrs++; } } } } printf("Loaded newsgroups for %d groups\n", num); }
int uiuc_close_nf (struct notesfile *nf, short updatestats) { struct io_f io; struct flock dlock; int error; time_t current_time; error = init (&io, nf->ref); if (error != NEWTS_NO_ERROR) return error; if (updatestats) { dlock.l_type = F_WRLCK; dlock.l_whence = SEEK_SET; dlock.l_start = 0; dlock.l_len = (off_t) sizeof (struct daddr_f); TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &dlock)); getdescr (&io, &io.descr); time (¤t_time); io.descr.entries++; io.descr.walltime += difftime (current_time, nf->time_entered); putdescr (&io, &io.descr); fdatasync (io.fidndx); dlock.l_type = F_UNLCK; fcntl (io.fidndx, F_SETLK, &dlock); } closenf (&io); return NEWTS_NO_ERROR; }
int uiuc_modify_note_text (struct newt *newt) { static uid_t anon; static short anon_is_set = FALSE; struct io_f io; struct daddr_f daddr; struct note_f note; struct stat statbuf; struct flock dlock, nlock; time_t timet; if (!anon_is_set) { struct passwd *pw = getpwnam (ANON); anon = pw->pw_uid; anon_is_set = TRUE; endpwent (); } init (&io, &newt->nr.nfr); if (io.descr.d_stat & NFINVALID) { closenf (&io); return -1; } if (newt->nr.notenum < -1 || newt->nr.notenum > io.descr.d_nnote) { closenf (&io); return -1; } nlock.l_type = F_RDLCK; nlock.l_whence = SEEK_SET; nlock.l_start = (off_t) (sizeof (struct descr_f) + (newt->nr.notenum * sizeof (struct note_f))); nlock.l_len = (off_t) sizeof (struct note_f); if (newt->nr.respnum == 0) { TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &nlock)); getnoterec (&io, newt->nr.notenum, ¬e); fstat (io.fidtxt, &statbuf); time (&timet); if (note.n_addr.textlen > HARDMAX || note.n_nresp < 0 || convert_time (¬e.n_lmod) > timet || convert_time (¬e.n_date) > timet || (off_t) (note.n_addr.textlen + note.n_addr.addr) > statbuf.st_size) { closenf (&io); return -1; } /* We're allowed to change the director message here; saves time. */ if (newt->director_message) note.n_stat |= DIRMES; else note.n_stat &= ~DIRMES; if (!allow (&io, DRCTOK)) { if (io.descr.d_stat & ISMODERATED) note.n_stat |= ISUNAPPROVED; else note.n_stat &= ~ISUNAPPROVED; } else note.n_stat &= ~ISUNAPPROVED; /* Update the note's text record */ puttextrec (&io, newt->text, &daddr, -1); note.n_addr.addr = daddr.addr; note.n_addr.textlen = daddr.textlen; /* We could be dealing with a newly anonymous note. Stupid, huh? */ if (newt->options & NOTE_ANONYMOUS) { strncpy (note.n_auth.aname, "anonymous", NAMESZ); note.n_auth.aid = (int) anon; } /* Set the descriptor lock; we'll be updating modification time. */ dlock.l_type = F_RDLCK; dlock.l_whence = SEEK_SET; dlock.l_start = 0; dlock.l_len = (off_t) sizeof (struct descr_f); TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &dlock)); getdescr (&io, &io.descr); get_uiuc_time (&io.descr.d_lastm, newt->modified); get_uiuc_time (¬e.n_lmod, newt->modified); io.descr.d_delnote++; nlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &nlock)); dlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &dlock)); putnoterec (&io, newt->nr.notenum, ¬e); nlock.l_type = F_UNLCK; fcntl (io.fidndx, F_SETLK, &nlock); putdescr (&io, &io.descr); fdatasync (io.fidndx); dlock.l_type = F_UNLCK; fcntl (io.fidndx, F_SETLK, &dlock); closenf (&io); return 0; } else { struct resp_f resp, oldresp; struct flock rlock; int offset, record; TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &nlock)); getnoterec (&io, newt->nr.notenum, ¬e); fstat (io.fidtxt, &statbuf); time (&timet); if (note.n_addr.textlen > HARDMAX || note.n_nresp < 0 || convert_time (¬e.n_lmod) > timet || convert_time (¬e.n_date) > timet || (off_t) (note.n_addr.textlen + note.n_addr.addr) > statbuf.st_size) { closenf (&io); return -1; } if (logical_resp (&io, newt->nr.notenum, newt->nr.respnum, &oldresp, &offset, &record) == -1) return -1; rlock.l_type = F_RDLCK; rlock.l_whence = SEEK_SET; rlock.l_start = (off_t) (sizeof (int) + (record * sizeof (struct resp_f))); rlock.l_len = (off_t) sizeof (struct resp_f); TEMP_FAILURE_RETRY (fcntl (io.fidrdx, F_SETLKW, &rlock)); memcpy (&resp, &oldresp, sizeof (struct resp_f)); /* We're allowed to change the director message here; it'll save time. */ if (newt->director_message) resp.r_stat[offset] |= DIRMES; else resp.r_stat[offset] &= ~DIRMES; if (!allow (&io, DRCTOK)) { if (io.descr.d_stat & ISMODERATED) note.n_stat |= ISUNAPPROVED; else note.n_stat &= ~ISUNAPPROVED; } else note.n_stat &= ~ISUNAPPROVED; /* Update the response's text record */ puttextrec (&io, newt->text, &daddr, -1); resp.r_addr[offset].addr = daddr.addr; resp.r_addr[offset].textlen = daddr.textlen; /* We could be dealing with a newly anonymous note. Stupid, huh? */ if (newt->options & NOTE_ANONYMOUS) { strncpy (resp.r_auth[offset].aname, "anonymous", NAMESZ); note.n_auth.aid = (int) anon; } /* Set up the descriptor lock (we update the "updated time") */ dlock.l_type = F_RDLCK; dlock.l_whence = SEEK_SET; dlock.l_start = 0; dlock.l_len = (off_t) sizeof (struct descr_f); TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &dlock)); getdescr (&io, &io.descr); get_uiuc_time (&io.descr.d_lastm, newt->modified); get_uiuc_time (¬e.n_lmod, newt->modified); io.descr.d_delresp++; rlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io.fidrdx, F_SETLKW, &rlock)); nlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &nlock)); dlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io.fidndx, F_SETLKW, &dlock)); putresprec (&io, record, &resp); putnoterec (&io, newt->nr.notenum, ¬e); nlock.l_type = F_UNLCK; fcntl (io.fidndx, F_SETLK, &nlock); putdescr (&io, &io.descr); fdatasync (io.fidrdx); fdatasync (io.fidndx); dlock.l_type = F_UNLCK; fcntl (io.fidndx, F_SETLK, &dlock); rlock.l_type = F_UNLCK; fcntl (io.fidrdx, F_SETLK, &rlock); closenf (&io); return 0; } }
int put_resp (struct io_f *io, struct daddr_f *where, struct newt *newt, int flags) { struct note_f note; struct resp_f resp; struct flock dlock, nlock, rlock; int lastin, phys, i; rlock.l_whence = SEEK_SET; nlock.l_type = F_RDLCK; nlock.l_whence = SEEK_SET; nlock.l_start = (off_t) (sizeof (struct descr_f) + (newt->nr.notenum * sizeof (struct note_f))); nlock.l_len = (off_t) sizeof (struct note_f); TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &nlock)); getnoterec (io, newt->nr.notenum, ¬e); if (note.n_rindx < 0) { lastin = note.n_rindx = get_new_resp_block (io); resp.r_first = 1; resp.r_last = 0; resp.r_previous = -1; resp.r_next = -1; for (i=0; i<RESPSZ; i++) resp.r_stat[i] = 0; } else { rlock.l_type = F_RDLCK; rlock.l_start = (off_t) (sizeof (int) + (note.n_rindx * sizeof (struct resp_f))); rlock.l_len = (off_t) sizeof (struct resp_f); TEMP_FAILURE_RETRY (fcntl (io->fidrdx, F_SETLKW, &rlock)); getresprec (io, lastin = note.n_rindx, &resp); rlock.l_type = F_UNLCK; fcntl (io->fidrdx, F_SETLK, &rlock); } i = phys = 0; while (i < note.n_nresp) { if (phys >= RESPSZ) { rlock.l_type = F_RDLCK; rlock.l_start = (off_t) (sizeof (int) + (resp.r_next * sizeof (struct resp_f))); rlock.l_len = (off_t) sizeof (struct resp_f); TEMP_FAILURE_RETRY (fcntl (io->fidrdx, F_SETLKW, &rlock)); phys = 0; getresprec (io, lastin = resp.r_next, &resp); rlock.l_type = F_UNLCK; fcntl (io->fidrdx, F_SETLK, &rlock); } if ((resp.r_stat[phys] & NOTE_DELETED) == 0) i++; phys++; } if (phys >= RESPSZ) /* We are in a new block of responses. */ { phys = 0; resp.r_next = get_new_resp_block (io); rlock.l_type = F_WRLCK; rlock.l_start = (off_t) (sizeof (int) + (lastin * sizeof (struct resp_f))); rlock.l_len = (off_t) sizeof (struct resp_f); TEMP_FAILURE_RETRY (fcntl (io->fidrdx, F_SETLKW, &rlock)); putresprec (io, lastin, &resp); resp.r_previous = lastin; lastin = resp.r_next; resp.r_next = -1; resp.r_first = note.n_nresp + 1; resp.r_last = resp.r_first - 1; for (i=0; i<RESPSZ; i++) resp.r_stat[i] = 0; } fdatasync (io->fidrdx); rlock.l_type = F_RDLCK; rlock.l_start = (off_t) (sizeof (int) + (lastin * sizeof (struct resp_f))); rlock.l_len = (off_t) sizeof (struct resp_f); TEMP_FAILURE_RETRY (fcntl (io->fidrdx, F_SETLKW, &rlock)); note.n_nresp++; resp.r_addr[phys].addr = where->addr; resp.r_addr[phys].textlen = where->textlen; strncpy (resp.r_auth[phys].aname, newt->auth.name, NAMESZ); strncpy (resp.r_auth[phys].asystem, newt->auth.system, HOMESYSSZ); resp.r_auth[phys].aid = (int) newt->auth.uid; strncpy (resp.r_from[phys], newt->auth.system, SYSSZ); resp.r_stat[phys] = 0; if (newt->director_message && allow (io, DRCTOK)) resp.r_stat[phys] |= DIRMES; /* Adjust moderation flag appropriately. */ if (flags & SKIP_MODERATION) { if (newt->options & NOTE_UNAPPROVED) resp.r_stat[phys] |= ISUNAPPROVED; } else if (io->descr.d_stat & ISMODERATED && !allow (io, DRCTOK)) resp.r_stat[phys] |= ISUNAPPROVED; if (newt->options & NOTE_ANONYMOUS) strncpy (resp.r_auth[phys].aname, "anonymous", NAMESZ); /* Prepare to alter the descriptor. */ dlock.l_type = F_RDLCK; dlock.l_whence = SEEK_SET; dlock.l_start = 0; dlock.l_len = (off_t) sizeof (struct descr_f); TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &dlock)); getdescr (io, &io->descr); if (flags & ADD_ID) { strncpy (resp.r_id[phys].sys, newt->auth.system, SYSSZ); resp.r_id[phys].uniqid = ++io->descr.d_id.uniqid; resp.r_id[phys].uniqid += UNIQPLEX * io->descr.d_nfnum; } else { strncpy (resp.r_id[phys].sys, newt->id.system, SYSSZ); resp.r_id[phys].sys[SYSSZ - 1] = '\0'; resp.r_id[phys].uniqid = newt->id.number; } if (flags & UPDATE_TIMES) { get_uiuc_time (&io->descr.d_lastm, newt->created); get_uiuc_time (¬e.n_lmod, newt->modified); } get_uiuc_time (&resp.r_when[phys], newt->created); get_uiuc_time (&resp.r_rcvd[phys], newt->created); resp.r_last++; rlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io->fidrdx, F_SETLKW, &rlock)); nlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &nlock)); dlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &dlock)); putresprec (io, lastin, &resp); putnoterec (io, newt->nr.notenum, ¬e); io->descr.d_rspwrit++; nlock.l_type = F_UNLCK; fcntl (io->fidndx, F_SETLK, &nlock); putdescr (io, &io->descr); fdatasync (io->fidrdx); fdatasync (io->fidndx); dlock.l_type = F_UNLCK; fcntl (io->fidndx, F_SETLK, &dlock); rlock.l_type = F_UNLCK; fcntl (io->fidrdx, F_SETLK, &rlock); return note.n_nresp; }
int put_note (struct io_f *io, struct daddr_f *where, struct newt *newt, int flags) { static uid_t anon; static short anon_is_set = FALSE; struct note_f note; struct flock dlock, nlock; int notenum; if (!anon_is_set) { struct passwd *pw = getpwnam (ANON); anon = pw->pw_uid; anon_is_set = TRUE; endpwent (); } if (io == NULL || where == NULL || newt == NULL) return -1; /* Save the provided disk address information. */ note.n_addr.addr = where->addr; note.n_addr.textlen = where->textlen; /* Save the author information. */ strncpy (note.n_auth.aname, newt->auth.name, NAMESZ); strncpy (note.n_auth.asystem, newt->auth.system, HOMESYSSZ); note.n_auth.aid = (int) newt->auth.uid; strncpy (note.n_from, newt->auth.system, SYSSZ); note.n_from[SYSSZ - 1] = '\0'; /* Save the title. */ strncpy (note.ntitle, newt->title, TITLEN); note.ntitle[TITLEN - 1] = '\0'; /* Initialize response storage. */ note.n_nresp = 0; note.n_rindx = -1; /* Save note options - director message, write-only. */ note.n_stat = 0; if (newt->director_message && allow (io, DRCTOK)) note.n_stat |= DIRMES; if (newt->options & NOTE_WRITE_ONLY) note.n_stat |= WRITONLY; /* Adjust moderation flag appropriately. */ if (flags & SKIP_MODERATION) { if (newt->options & NOTE_UNAPPROVED) note.n_stat |= ISUNAPPROVED; } else if (io->descr.d_stat & ISMODERATED && !allow (io, DRCTOK)) note.n_stat |= ISUNAPPROVED; if (newt->options & NOTE_ANONYMOUS) { strncpy (note.n_auth.aname, "anonymous", NAMESZ); note.n_auth.aid = (int) anon; } /* Prepare to alter the descriptor. */ dlock.l_type = F_RDLCK; dlock.l_whence = SEEK_SET; dlock.l_start = 0; dlock.l_len = (off_t) sizeof (struct descr_f); TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &dlock)); getdescr (io, &io->descr); /* If specified, generate a new ID for the note. Otherwise, use the already * existing ID. */ if (flags & ADD_ID) { strncpy (note.n_id.sys, newt->auth.system, SYSSZ); note.n_id.sys[SYSSZ - 1] = '\0'; note.n_id.uniqid = ++io->descr.d_id.uniqid; note.n_id.uniqid += UNIQPLEX * io->descr.d_nfnum; } else { strncpy (note.n_id.sys, newt->id.system, SYSSZ); note.n_id.sys[SYSSZ - 1] = '\0'; note.n_id.uniqid = newt->id.number; } /* Set up flags for a policy note or a regular note, depending. */ if (flags & ADD_POLICY) { if (!allow (io, DRCTOK)) { closenf (io); return -2; } io->descr.d_plcy = 1; notenum = 0; } else { notenum = ++io->descr.d_nnote; } /* Save the current time into the note. */ if (flags & UPDATE_TIMES) get_uiuc_time (&io->descr.d_lastm, newt->created); get_uiuc_time (¬e.n_date, newt->created); get_uiuc_time (¬e.n_rcvd, newt->created); get_uiuc_time (¬e.n_lmod, newt->modified); /* Save to disk. */ nlock.l_type = F_WRLCK; nlock.l_whence = SEEK_SET; nlock.l_start = (off_t) (sizeof (struct descr_f) + (notenum * sizeof (struct note_f))); nlock.l_len = (off_t) sizeof (struct note_f); TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &nlock)); dlock.l_type = F_WRLCK; TEMP_FAILURE_RETRY (fcntl (io->fidndx, F_SETLKW, &dlock)); putnoterec (io, notenum, ¬e); nlock.l_type = F_UNLCK; fcntl (io->fidndx, F_SETLK, &nlock); io->descr.d_notwrit++; putdescr (io, &io->descr); fdatasync (io->fidndx); dlock.l_type = F_UNLCK; fcntl (io->fidndx, F_SETLK, &dlock); return notenum; }