Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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 (&current_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;
}
Пример #5
0
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, &note);

      fstat (io.fidtxt, &statbuf);

      time (&timet);
      if (note.n_addr.textlen > HARDMAX ||
          note.n_nresp < 0 || convert_time (&note.n_lmod) > timet ||
          convert_time (&note.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 (&note.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, &note);

      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, &note);

      fstat (io.fidtxt, &statbuf);

      time (&timet);
      if (note.n_addr.textlen > HARDMAX ||
          note.n_nresp < 0 || convert_time (&note.n_lmod) > timet ||
          convert_time (&note.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 (&note.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, &note);

      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;
    }
}
Пример #6
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, &note);

  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 (&note.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, &note);
  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;
}
Пример #7
0
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 (&note.n_date, newt->created);
  get_uiuc_time (&note.n_rcvd, newt->created);
  get_uiuc_time (&note.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, &note);

  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;
}