Example #1
0
/*
 * This implements the 'x' option.
 * Request that new entries be extracted.
 */
long
addfile(char *name, ino_t ino, int type)
{
	struct entry *ep;
	long descend = hflag ? GOOD : FAIL;
	char buf[100];

	if (TSTINO(ino, dumpmap) == 0) {
		dprintf(stdout, "%s: not on the tape\n", name);
		return (descend);
	}
	if (ino == WINO && command == 'i' && !vflag)
		return (descend);
	if (!mflag) {
		(void) sprintf(buf, "./%ju", (uintmax_t)ino);
		name = buf;
		if (type == NODE) {
			(void) genliteraldir(name, ino);
			return (descend);
		}
	}
	ep = lookupino(ino);
	if (ep != NULL) {
		if (strcmp(name, myname(ep)) == 0) {
			ep->e_flags |= NEW;
			return (descend);
		}
		type |= LINK;
	}
	ep = addentry(name, ino, type);
	if (type == NODE)
		newnode(ep);
	ep->e_flags |= NEW;
	return (descend);
}
void sendcoinsdialog::clear()
{
    // remove entries until only one left
    while(ui->entries->count())
    {
        ui->entries->takeat(0)->widget()->deletelater();
    }
    addentry();

    updatetabsandlabels();
}
void sendcoinsdialog::removeentry(sendcoinsentry* entry)
{
    entry->hide();

    // if the last entry is about to be removed add an empty one
    if (ui->entries->count() == 1)
        addentry();

    entry->deletelater();

    updatetabsandlabels();
}
Example #4
0
void scandirfunc(char *file)
{
   char *extptr;
   uint32_t hex;

   if(strlen(file) != 12)
      return;

   extptr=&file[strlen(file)-4];

   if(stricmp(extptr,".PNT")==0 && !scandir_boss)
   {
      char buf[200];
      struct Node4D n4d;

      hex=hextodec(file);

      n4d.Zone = cfg_Zone;
      n4d.Net = NET(hex);
      n4d.Node = NODE(hex);
      n4d.Point = 0;

      scandir_dir = file;
      scandir_boss = &n4d;

      MakeFullPath(cfg_Dir,file,buf,200);
      osScanDir(buf,scandirfunc);

      scandir_dir = NULL;
      scandir_boss = NULL;
   }

   if(!stricmp(extptr,".REQ")) addentry(scandir_dir,file,TYPE_REQUEST,scandir_boss,TRUE);

   if(!stricmp(extptr,".CLO")) addentry(scandir_dir,file,TYPE_CRASH,scandir_boss,TRUE);
   if(!stricmp(extptr,".DLO")) addentry(scandir_dir,file,TYPE_DIRECT,scandir_boss,TRUE);
   if(!stricmp(extptr,".FLO")) addentry(scandir_dir,file,TYPE_NORMAL,scandir_boss,TRUE);
   if(!stricmp(extptr,".HLO")) addentry(scandir_dir,file,TYPE_HOLD,scandir_boss,TRUE);

   if(!stricmp(extptr,".CUT")) addentry(scandir_dir,file,TYPE_CRASH,scandir_boss,FALSE);
   if(!stricmp(extptr,".DUT")) addentry(scandir_dir,file,TYPE_DIRECT,scandir_boss,FALSE);
   if(!stricmp(extptr,".OUT")) addentry(scandir_dir,file,TYPE_NORMAL,scandir_boss,FALSE);
   if(!stricmp(extptr,".HUT")) addentry(scandir_dir,file,TYPE_HOLD,scandir_boss,FALSE);
}
Example #5
0
static void
addoption(char *optstr)
{
	char *newoptions;
	struct entry *e;

	if ((newoptions = strchr(optstr, ':')) == NULL)
		errx(1, "Invalid option string");

	*newoptions++ = '\0';

	TAILQ_FOREACH(e, &opthead, entries)
		if (!strncmp(e->type, optstr, MFSNAMELEN)) {
			catopt(&e->options, newoptions);
			return;
		}
	addentry(&opthead, optstr, newoptions);
}
Example #6
0
static void
maketypelist(char *fslist)
{
	char *ptr;

	if ((fslist == NULL) || (fslist[0] == '\0'))
		errx(1, "empty type list");

	if (fslist[0] == 'n' && fslist[1] == 'o') {
		fslist += 2;
		which = NOT_IN_LIST;
	}
	else
		which = IN_LIST;

	while ((ptr = strsep(&fslist, ",")) != NULL)
		addentry(&selhead, ptr, "");

}
void sendcoinsdialog::setaddress(const qstring &address)
{
    sendcoinsentry *entry = 0;
    // replace the first entry if it is still unused
    if(ui->entries->count() == 1)
    {
        sendcoinsentry *first = qobject_cast<sendcoinsentry*>(ui->entries->itemat(0)->widget());
        if(first->isclear())
        {
            entry = first;
        }
    }
    if(!entry)
    {
        entry = addentry();
    }

    entry->setaddress(address);
}
void sendcoinsdialog::pasteentry(const sendcoinsrecipient &rv)
{
    if(!fnewrecipientallowed)
        return;

    sendcoinsentry *entry = 0;
    // replace the first entry if it is still unused
    if(ui->entries->count() == 1)
    {
        sendcoinsentry *first = qobject_cast<sendcoinsentry*>(ui->entries->itemat(0)->widget());
        if(first->isclear())
        {
            entry = first;
        }
    }
    if(!entry)
    {
        entry = addentry();
    }

    entry->setvalue(rv);
    updatetabsandlabels();
}
Example #9
0
/*
 * Insure that all the components of a pathname exist.
 */
void
pathcheck(char *name)
{
	char *cp;
	struct entry *ep;
	char *start;

	start = strchr(name, '/');
	if (start == 0)
		return;
	for (cp = start; *cp != '\0'; cp++) {
		if (*cp != '/')
			continue;
		*cp = '\0';
		ep = lookupname(name);
		if (ep == NULL) {
			/* Safe; we know the pathname exists in the dump. */
			ep = addentry(name, pathsearch(name)->d_ino, NODE);
			newnode(ep);
		}
		ep->e_flags |= NEW|KEEP;
		*cp = '/';
	}
}
Example #10
0
int
main(int argc, char *argv[])
{
	struct fstab *fs;
	int i, rval;
	const char *vfstype = NULL;
	char globopt[3];
	int ret = FSCK_EXIT_OK;
	char buf[MAXPATHLEN];

	globopt[0] = '-';
	globopt[2] = '\0';

	TAILQ_INIT(&selhead);
	TAILQ_INIT(&opthead);
	TAILQ_INIT(&omhead);

	while ((i = getopt(argc, argv, "dfl:nPpqT:t:vx:y")) != -1) {
		switch (i) {
		case 'd':
			flags |= CHECK_DEBUG;
			continue;

		case 'f':
			flags |= CHECK_FORCE;
			break;

		case 'n':
			flags |= CHECK_NOFIX;
			break;

		case 'p':
			flags |= CHECK_PREEN;
			break;

		case 'P':
			flags |= CHECK_PROGRESS;
			break;

		case 'q':
			break;

		case 'l':
			maxrun = atoi(optarg);
			continue;

		case 'T':
			if (*optarg)
				addoption(optarg);
			continue;

		case 't':
			if (TAILQ_FIRST(&selhead) != NULL)
				errx(1, "only one -t option may be specified.");

			maketypelist(optarg);
			vfstype = optarg;
			continue;

		case 'v':
			flags |= CHECK_VERBOSE;
			continue;

		case 'x':
			addentry(&omhead, optarg, "");
			continue;

		case 'y':
			break;

		case '?':
		default:
			usage();
			/* NOTREACHED */
		}

		/* Pass option to fsck_xxxfs */
		globopt[1] = i;
		catopt(&options, globopt);
	}

	/* Don't do progress meters if we're debugging. */
	if (flags & CHECK_DEBUG)
		flags &= ~CHECK_PROGRESS;

	/*
	 * If progress meters are being used, force max parallel to 1
	 * so the progress meter outputs don't interfere with one another.
	 */
	if (flags & CHECK_PROGRESS)
		maxrun = 1;

	argc -= optind;
	argv += optind;

	if (argc == 0)
		return checkfstab(flags, maxrun, isok, checkfs);

#define	BADTYPE(type)							\
	(strcmp(type, FSTAB_RO) &&					\
	    strcmp(type, FSTAB_RW) && strcmp(type, FSTAB_RQ))


	for (; argc--; argv++) {
		const char *spec, *spec2, *mntpt, *type, *cp;
		char	device[MAXPATHLEN];

		spec = mntpt = *argv;
		spec2 = getfsspecname(buf, sizeof(buf), spec);
		if (spec2 == NULL)
			spec2 = spec;

		cp = strrchr(spec2, '/');
		if (cp == 0) {
			(void)snprintf(device, sizeof(device), "%s%s",
				_PATH_DEV, spec2);
			spec2 = device;
		}

		fs = getfsfile(spec);
		if (fs == NULL)
		    fs = getfsspec(spec);
		if (fs == NULL && spec != spec2) {
		    fs = getfsspec(spec2);
		    spec = spec2;
		}

		if (fs) {
			spec = getfsspecname(buf, sizeof(buf), fs->fs_spec);
			if (spec == NULL)
				err(FSCK_EXIT_CHECK_FAILED, "%s", buf);
			type = fs->fs_vfstype;
			if (BADTYPE(fs->fs_type))
				errx(FSCK_EXIT_CHECK_FAILED,
				    "%s has unknown file system type.",
				    spec);
		} else {
			if (vfstype == NULL)
				vfstype = getfslab(spec);
			type = vfstype;
		}

		rval = checkfs(type, blockcheck(spec), *argv, NULL, NULL);
		if (rval > ret) 
			ret = rval;
	}

	return ret;
}
Example #11
0
// creates all menus
void WMain::createMenus() {
	fileMenu=new QMenu(this);
	wordMenu=new QMenu(this);
	testMenu=new QMenu(this);
	helpMenu=new QMenu(this);

	newAction=new QAction(tr("&New"), this);
	newAction->setShortcuts(QKeySequence::New);
	newAction->setStatusTip(tr("Create new dictionary"));

	openAction=new QAction(tr("&Open..."), this);
	openAction->setShortcuts(QKeySequence::Open);
	openAction->setStatusTip(tr("Open dictionary"));

	saveAction=new QAction(tr("&Save"), this);
	saveAction->setShortcuts(QKeySequence::Save);
	saveAction->setStatusTip(tr("Save dictionary"));

	saveasAction=new QAction(tr("&Save as..."), this);
	saveasAction->setShortcuts(QKeySequence::SaveAs);
	saveasAction->setStatusTip(tr("Save dictionary as"));

	printAction=new QAction(tr("&Print"), this);
	printAction->setShortcuts(QKeySequence::Print);
	printAction->setStatusTip(tr("Print dictionary"));
	
	settingsAction=new QAction(tr("&Settings"), this);
	settingsAction->setShortcut(QKeySequence("Ctrl+B"));
	settingsAction->setStatusTip(tr("Settings"));

	quitAction=new QAction(tr("&Quit"), this);
	quitAction->setShortcut(QKeySequence("Ctrl+Q"));
	quitAction->setStatusTip(tr("Quit dicto"));

	addAction=new QAction(tr("&Add..."), this);
	addAction->setShortcut(Qt::Key_Insert);
	addAction->setStatusTip(tr("Add new word"));

	editAction=new QAction(tr("&Edit..."), this);
	editAction->setStatusTip(tr("Edit current word"));

	deleteAction=new QAction(tr("&Delete"), this);
	deleteAction->setShortcut(Qt::Key_Delete);
	deleteAction->setStatusTip(tr("Delete current word"));

	sortAction=new QAction(tr("&Sort"), this);
	sortAction->setShortcut(QKeySequence("Ctrl+A"));
	sortAction->setStatusTip(tr("Sort dictionary"));

	testAction=new QAction(tr("&Test..."), this);
	testAction->setShortcut(QKeySequence("Ctrl+T"));
	testAction->setStatusTip(tr("Prepare test"));

	examAction=new QAction(tr("&Exam..."), this);
	examAction->setShortcut(QKeySequence("Ctrl+E"));
	examAction->setStatusTip(tr("Prepare exam"));

	statsAction=new QAction(tr("&Statistics..."), this);
	statsAction->setShortcut(QKeySequence("Ctrl+W"));
	statsAction->setStatusTip(tr("Show statistics"));

	aboutAction=new QAction(tr("&About"), this);
	aboutAction->setStatusTip(tr("About dicto"));

	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(newAction);
	fileMenu->addAction(openAction);
	fileMenu->addAction(saveAction);
	fileMenu->addAction(saveasAction);
	fileMenu->addAction(printAction);
	fileMenu->addSeparator();
	

	for (int i = 0; i < 10/*maxRecentFiles*/; ++i) {
		recentFilesActions[i] = new QAction(this);
		recentFilesActions[i]->setVisible(false);
		fileMenu->addAction(recentFilesActions[i]);
		connect(recentFilesActions[i], SIGNAL(triggered()),this, SLOT(openRecentFile()));
	}
	updateRecentFileActions();

	
	fileMenu->addSeparator();
	fileMenu->addAction(settingsAction);
	fileMenu->addSeparator();
	fileMenu->addAction(quitAction);

	wordMenu = menuBar()->addMenu(tr("&Words"));
	wordMenu->addAction(addAction);
	wordMenu->addAction(editAction);
	wordMenu->addAction(deleteAction);
	wordMenu->addSeparator();
	wordMenu->addAction(sortAction);

	testMenu = menuBar()->addMenu(tr("&Test"));
	testMenu->addAction(testAction);
	testMenu->addAction(examAction);
	testMenu->addSeparator();
	testMenu->addAction(statsAction);

	helpMenu = menuBar()->addMenu(tr("&Help"));
	helpMenu->addAction(aboutAction);

	connect(newAction, SIGNAL(triggered()), this, SLOT(newfile()));
	connect(openAction, SIGNAL(triggered()), this, SLOT(openfile()));
	connect(saveAction, SIGNAL(triggered()), this, SLOT(savefile()));
	connect(saveasAction, SIGNAL(triggered()), this, SLOT(saveas()));
	connect(printAction, SIGNAL(triggered()), this, SLOT(print()));
	connect(settingsAction, SIGNAL(triggered()), this, SLOT(show_settings()));
	connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));

	connect(addAction, SIGNAL(triggered()), this, SLOT(addentry()));
	connect(editAction, SIGNAL(triggered()), this, SLOT(editentry()));
	connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteentry()));
	connect(sortAction, SIGNAL(triggered()), this, SLOT(sortall()));

	connect(testAction, SIGNAL(triggered()), this, SLOT(preparetest()));
	connect(examAction, SIGNAL(triggered()), this, SLOT(prepareexam()));
	connect(statsAction, SIGNAL(triggered()), this, SLOT(stats()));

	connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
}
Example #12
0
struct smackentry* opensmackentry(const char *username)
{
	FILE *fp;
	char   *line;
	size_t linelen;
	struct smackentry *entry = NULL;

	fp = fopen(SMACK_USERS, "r");
	if (!fp) {
		perror("opening " SMACK_USERS);
		errno = ENOSYS;
		return NULL;
	}

	line = malloc(32); // because it should suffice in theory
	linelen = 32;
	errno = ENOENT;
	while (getline(&line, &linelen, fp) != -1)
	{
		const char *userstart = NULL;
		const char *labelstart = NULL;

		char *inl = line;

		// skip initial whitespace
		while (isspace(*inl))
			++inl;

		if (!*inl)
			continue;

		// extract username:
		userstart = inl;
		// it may not be "standard" but nothing keeps me from using
		// _ or - in /etc/passwd
		while (isalpha(*inl) || *inl == '_' || *inl == '-')
			++inl;
		// insert a nulbyte to end the username
		*inl = '\0';
		++inl;

		// Check the username now
		if (strcmp(username, userstart))
			continue;

		while (isspace(*inl))
			++inl;

		if (!*inl)
			continue;

		// extract all labels:

		entry = newentry(username);
		do
		{
			labelstart = inl;
			while (*inl && !isspace(*inl))
				++inl;
			if (!*inl) {
				// end of line
				addentry(entry, labelstart);
				break;
			}
			// more following:
			*inl = '\0';
			addentry(entry, labelstart);
			++inl;
			while (isspace(*inl))
				++inl;
		} while(*inl);
		break;
	}

	free(line);
	fclose(fp);
	return entry;
}
sendcoinsdialog::sendcoinsdialog(qwidget *parent) :
    qdialog(parent),
    ui(new ui::sendcoinsdialog),
    clientmodel(0),
    model(0),
    fnewrecipientallowed(true),
    ffeeminimized(true)
{
    ui->setupui(this);

#ifdef q_os_mac // icons on push buttons are very uncommon on mac
    ui->addbutton->seticon(qicon());
    ui->clearbutton->seticon(qicon());
    ui->sendbutton->seticon(qicon());
#else
    ui->addbutton->seticon(singlecoloricon(":/icons/add"));
    ui->clearbutton->seticon(singlecoloricon(":/icons/remove"));
    ui->sendbutton->seticon(singlecoloricon(":/icons/send"));
#endif

    guiutil::setupaddresswidget(ui->lineeditcoincontrolchange, this);

    addentry();

    connect(ui->addbutton, signal(clicked()), this, slot(addentry()));
    connect(ui->clearbutton, signal(clicked()), this, slot(clear()));

    // coin control
    connect(ui->pushbuttoncoincontrol, signal(clicked()), this, slot(coincontrolbuttonclicked()));
    connect(ui->checkbomoorecoincontrolchange, signal(statechanged(int)), this, slot(coincontrolchangechecked(int)));
    connect(ui->lineeditcoincontrolchange, signal(textedited(const qstring &)), this, slot(coincontrolchangeedited(const qstring &)));

    // coin control: clipboard actions
    qaction *clipboardquantityaction = new qaction(tr("copy quantity"), this);
    qaction *clipboardamountaction = new qaction(tr("copy amount"), this);
    qaction *clipboardfeeaction = new qaction(tr("copy fee"), this);
    qaction *clipboardafterfeeaction = new qaction(tr("copy after fee"), this);
    qaction *clipboardbytesaction = new qaction(tr("copy bytes"), this);
    qaction *clipboardpriorityaction = new qaction(tr("copy priority"), this);
    qaction *clipboardlowoutputaction = new qaction(tr("copy dust"), this);
    qaction *clipboardchangeaction = new qaction(tr("copy change"), this);
    connect(clipboardquantityaction, signal(triggered()), this, slot(coincontrolclipboardquantity()));
    connect(clipboardamountaction, signal(triggered()), this, slot(coincontrolclipboardamount()));
    connect(clipboardfeeaction, signal(triggered()), this, slot(coincontrolclipboardfee()));
    connect(clipboardafterfeeaction, signal(triggered()), this, slot(coincontrolclipboardafterfee()));
    connect(clipboardbytesaction, signal(triggered()), this, slot(coincontrolclipboardbytes()));
    connect(clipboardpriorityaction, signal(triggered()), this, slot(coincontrolclipboardpriority()));
    connect(clipboardlowoutputaction, signal(triggered()), this, slot(coincontrolclipboardlowoutput()));
    connect(clipboardchangeaction, signal(triggered()), this, slot(coincontrolclipboardchange()));
    ui->labelcoincontrolquantity->addaction(clipboardquantityaction);
    ui->labelcoincontrolamount->addaction(clipboardamountaction);
    ui->labelcoincontrolfee->addaction(clipboardfeeaction);
    ui->labelcoincontrolafterfee->addaction(clipboardafterfeeaction);
    ui->labelcoincontrolbytes->addaction(clipboardbytesaction);
    ui->labelcoincontrolpriority->addaction(clipboardpriorityaction);
    ui->labelcoincontrollowoutput->addaction(clipboardlowoutputaction);
    ui->labelcoincontrolchange->addaction(clipboardchangeaction);

    // init transaction fee section
    qsettings settings;
    if (!settings.contains("ffeesectionminimized"))
        settings.setvalue("ffeesectionminimized", true);
    if (!settings.contains("nfeeradio") && settings.contains("ntransactionfee") && settings.value("ntransactionfee").tolonglong() > 0) // compatibility
        settings.setvalue("nfeeradio", 1); // custom
    if (!settings.contains("nfeeradio"))
        settings.setvalue("nfeeradio", 0); // recommended
    if (!settings.contains("ncustomfeeradio") && settings.contains("ntransactionfee") && settings.value("ntransactionfee").tolonglong() > 0) // compatibility
        settings.setvalue("ncustomfeeradio", 1); // total at least
    if (!settings.contains("ncustomfeeradio"))
        settings.setvalue("ncustomfeeradio", 0); // per kilobyte
    if (!settings.contains("nsmartfeesliderposition"))
        settings.setvalue("nsmartfeesliderposition", 0);
    if (!settings.contains("ntransactionfee"))
        settings.setvalue("ntransactionfee", (qint64)default_transaction_fee);
    if (!settings.contains("fpayonlyminfee"))
        settings.setvalue("fpayonlyminfee", false);
    if (!settings.contains("fsendfreetransactions"))
        settings.setvalue("fsendfreetransactions", false);
    ui->groupfee->setid(ui->radiosmartfee, 0);
    ui->groupfee->setid(ui->radiocustomfee, 1);
    ui->groupfee->button((int)std::max(0, std::min(1, settings.value("nfeeradio").toint())))->setchecked(true);
    ui->groupcustomfee->setid(ui->radiocustomperkilobyte, 0);
    ui->groupcustomfee->setid(ui->radiocustomatleast, 1);
    ui->groupcustomfee->button((int)std::max(0, std::min(1, settings.value("ncustomfeeradio").toint())))->setchecked(true);
    ui->slidersmartfee->setvalue(settings.value("nsmartfeesliderposition").toint());
    ui->customfee->setvalue(settings.value("ntransactionfee").tolonglong());
    ui->checkboxminimumfee->setchecked(settings.value("fpayonlyminfee").tobool());
    ui->checkboxfreetx->setchecked(settings.value("fsendfreetransactions").tobool());
    minimizefeesection(settings.value("ffeesectionminimized").tobool());
}
Example #14
0
int 
handleclient(int conn) 
{
	char *basedir;
	char *clientdir;
	mp3entry *mp3buf;
	FILE *stream;

	if ((stream = fdopen(conn, "r+")) == NULL || !readrequest(stream)) {
		debug(1, "error while reading client request");
		fclose(stream);
		return(EXIT_FAILURE);
	}
	
	debug(1, "requested path %s", conf.path);

	GETCWD(basedir);
	if(chdir(conf.path))
		die("incorrect dir");
	GETCWD(clientdir);
	
	debug(1, "doing security checks");
	if(strncmp(basedir, clientdir, strlen(basedir) - 1)) {
		fclose(stream);
		debug(1, "basedir %s, clientdir %s", basedir, clientdir);
		die("client tried to break out of base directory");
	}
	
	debug(1, "looking for mp3 files in subdirectory %s", conf.path);
	if(!MODE_ISSET(MODE_SINGLE)) {
		getfiles(".");
	} else if(validfile(conf.filename, clientdir, &mp3buf)) { 
		addentry(&root, mp3buf);
	}
	
	if(!root)
		die("no files");
	else
		debug(1, "%d MP3 file(s) found", countentries(root));

	if(!MODE_ISSET(MODE_INDEX) && !conf.order) {
		debug(1, "shuffling mp3 files");
		shuffleentries();
	}

	if(conf.debuglevel > 2) {
		debug(1, "listing mp3 files");
		dumpentries();
	}
	
	if(MODE_ISSET(MODE_INDEX)) {
		debug(1, "entering HTTP mode");
		fprintf(stream, HTTPSERVMSG, AMPLE_VERSION);
		fflush(stream);
		createhtml(stream,(clientdir + strlen(basedir)),(strlen(clientdir) + 1));
	} else if(MODE_ISSET(MODE_SINGLE)) {
		debug(1, "entering MP3-Single mode");
		fprintf(stream, SINGLESERVMSG, AMPLE_VERSION, root->filesize);
		fflush(stream);
		playfile(stream, root);
	} else if (MODE_ISSET(MODE_METADATA)) {
		debug(1, "entering MP3-Metadata mode");
		fprintf(stream, SHOUTSERVMSG, AMPLE_VERSION, conf.servername, BYTESBETWEENMETA);
		fflush(stream);
		playlist(stream);
	} else {
		debug(1, "entering MP3-Basic mode");
		fprintf(stream, BASICSERVMSG, AMPLE_VERSION);
		fflush(stream);
		playlist(stream);
	}

	fclose(stream);
	clearlist(root);
	return(EXIT_SUCCESS);
}
Example #15
0
/*
 *	For each directory entry on the incremental tape, determine which
 *	category it falls into as follows:
 *	KEEP - entries that are to be left alone.
 *	NEW - new entries to be added.
 *	EXTRACT - files that must be updated with new contents.
 *	LINK - new links to be added.
 *	Renames are done at the same time.
 */
long
nodeupdates(char *name, ino_t ino, int type)
{
	struct entry *ep, *np, *ip;
	long descend = GOOD;
	int lookuptype = 0;
	int key = 0;
		/* key values */
#		define ONTAPE	0x1	/* inode is on the tape */
#		define INOFND	0x2	/* inode already exists */
#		define NAMEFND	0x4	/* name already exists */
#		define MODECHG	0x8	/* mode of inode changed */

	/*
	 * This routine is called once for each element in the
	 * directory hierarchy, with a full path name.
	 * The "type" value is incorrectly specified as LEAF for
	 * directories that are not on the dump tape.
	 *
	 * Check to see if the file is on the tape.
	 */
	if (TSTINO(ino, dumpmap))
		key |= ONTAPE;
	/*
	 * Check to see if the name exists, and if the name is a link.
	 */
	np = lookupname(name);
	if (np != NULL) {
		key |= NAMEFND;
		ip = lookupino(np->e_ino);
		if (ip == NULL)
			panic("corrupted symbol table\n");
		if (ip != np)
			lookuptype = LINK;
	}
	/*
	 * Check to see if the inode exists, and if one of its links
	 * corresponds to the name (if one was found).
	 */
	ip = lookupino(ino);
	if (ip != NULL) {
		key |= INOFND;
		for (ep = ip->e_links; ep != NULL; ep = ep->e_links) {
			if (ep == np) {
				ip = ep;
				break;
			}
		}
	}
	/*
	 * If both a name and an inode are found, but they do not
	 * correspond to the same file, then both the inode that has
	 * been found and the inode corresponding to the name that
	 * has been found need to be renamed. The current pathname
	 * is the new name for the inode that has been found. Since
	 * all files to be deleted have already been removed, the
	 * named file is either a now unneeded link, or it must live
	 * under a new name in this dump level. If it is a link, it
	 * can be removed. If it is not a link, it is given a
	 * temporary name in anticipation that it will be renamed
	 * when it is later found by inode number.
	 */
	if (((key & (INOFND|NAMEFND)) == (INOFND|NAMEFND)) && ip != np) {
		if (lookuptype == LINK) {
			removeleaf(np);
			freeentry(np);
		} else {
			dprintf(stdout, "name/inode conflict, mktempname %s\n",
				myname(np));
			mktempname(np);
		}
		np = NULL;
		key &= ~NAMEFND;
	}
	if ((key & ONTAPE) &&
	  (((key & INOFND) && ip->e_type != type) ||
	   ((key & NAMEFND) && np->e_type != type)))
		key |= MODECHG;

	/*
	 * Decide on the disposition of the file based on its flags.
	 * Note that we have already handled the case in which
	 * a name and inode are found that correspond to different files.
	 * Thus if both NAMEFND and INOFND are set then ip == np.
	 */
	switch (key) {

	/*
	 * A previously existing file has been found.
	 * Mark it as KEEP so that other links to the inode can be
	 * detected, and so that it will not be reclaimed by the search
	 * for unreferenced names.
	 */
	case INOFND|NAMEFND:
		ip->e_flags |= KEEP;
		dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
			flagvalues(ip));
		break;

	/*
	 * A file on the tape has a name which is the same as a name
	 * corresponding to a different file in the previous dump.
	 * Since all files to be deleted have already been removed,
	 * this file is either a now unneeded link, or it must live
	 * under a new name in this dump level. If it is a link, it
	 * can simply be removed. If it is not a link, it is given a
	 * temporary name in anticipation that it will be renamed
	 * when it is later found by inode number (see INOFND case
	 * below). The entry is then treated as a new file.
	 */
	case ONTAPE|NAMEFND:
	case ONTAPE|NAMEFND|MODECHG:
		if (lookuptype == LINK) {
			removeleaf(np);
			freeentry(np);
		} else {
			mktempname(np);
		}
		/* FALLTHROUGH */

	/*
	 * A previously non-existent file.
	 * Add it to the file system, and request its extraction.
	 * If it is a directory, create it immediately.
	 * (Since the name is unused there can be no conflict)
	 */
	case ONTAPE:
		ep = addentry(name, ino, type);
		if (type == NODE)
			newnode(ep);
		ep->e_flags |= NEW|KEEP;
		dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
			flagvalues(ep));
		break;

	/*
	 * A file with the same inode number, but a different
	 * name has been found. If the other name has not already
	 * been found (indicated by the KEEP flag, see above) then
	 * this must be a new name for the file, and it is renamed.
	 * If the other name has been found then this must be a
	 * link to the file. Hard links to directories are not
	 * permitted, and are either deleted or converted to
	 * symbolic links. Finally, if the file is on the tape,
	 * a request is made to extract it.
	 */
	case ONTAPE|INOFND:
		if (type == LEAF && (ip->e_flags & KEEP) == 0)
			ip->e_flags |= EXTRACT;
		/* FALLTHROUGH */
	case INOFND:
		if ((ip->e_flags & KEEP) == 0) {
			renameit(myname(ip), name);
			moveentry(ip, name);
			ip->e_flags |= KEEP;
			dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
				flagvalues(ip));
			break;
		}
		if (ip->e_type == NODE) {
			descend = FAIL;
			fprintf(stderr,
				"deleted hard link %s to directory %s\n",
				name, myname(ip));
			break;
		}
		ep = addentry(name, ino, type|LINK);
		ep->e_flags |= NEW;
		dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name,
			flagvalues(ep));
		break;

	/*
	 * A previously known file which is to be updated. If it is a link,
	 * then all names referring to the previous file must be removed
	 * so that the subset of them that remain can be recreated.
	 */
	case ONTAPE|INOFND|NAMEFND:
		if (lookuptype == LINK) {
			removeleaf(np);
			freeentry(np);
			ep = addentry(name, ino, type|LINK);
			if (type == NODE)
			        newnode(ep);
			ep->e_flags |= NEW|KEEP;
			dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name,
				flagvalues(ep));
			break;
		}
		if (type == LEAF && lookuptype != LINK)
			np->e_flags |= EXTRACT;
		np->e_flags |= KEEP;
		dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
			flagvalues(np));
		break;

	/*
	 * An inode is being reused in a completely different way.
	 * Normally an extract can simply do an "unlink" followed
	 * by a "creat". Here we must do effectively the same
	 * thing. The complications arise because we cannot really
	 * delete a directory since it may still contain files
	 * that we need to rename, so we delete it from the symbol
	 * table, and put it on the list to be deleted eventually.
	 * Conversely if a directory is to be created, it must be
	 * done immediately, rather than waiting until the
	 * extraction phase.
	 */
	case ONTAPE|INOFND|MODECHG:
	case ONTAPE|INOFND|NAMEFND|MODECHG:
		if (ip->e_flags & KEEP) {
			badentry(ip, "cannot KEEP and change modes");
			break;
		}
		if (ip->e_type == LEAF) {
			/* changing from leaf to node */
			for (ip = lookupino(ino); ip != NULL; ip = ip->e_links) {
				if (ip->e_type != LEAF)
					badentry(ip, "NODE and LEAF links to same inode");
				removeleaf(ip);
				freeentry(ip);
			}
			ip = addentry(name, ino, type);
			newnode(ip);
		} else {
			/* changing from node to leaf */
			if ((ip->e_flags & TMPNAME) == 0)
				mktempname(ip);
			deleteino(ip->e_ino);
			ip->e_next = removelist;
			removelist = ip;
			ip = addentry(name, ino, type);
		}
		ip->e_flags |= NEW|KEEP;
		dprintf(stdout, "[%s] %s: %s\n", keyval(key), name,
			flagvalues(ip));
		break;

	/*
	 * A hard link to a directory that has been removed.
	 * Ignore it.
	 */
	case NAMEFND:
		dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key),
			name);
		descend = FAIL;
		break;

	/*
	 * If we find a directory entry for a file that is not on
	 * the tape, then we must have found a file that was created
	 * while the dump was in progress. Since we have no contents
	 * for it, we discard the name knowing that it will be on the
	 * next incremental tape.
	 */
	case 0:
		fprintf(stderr, "%s: (inode %ju) not found on tape\n",
		    name, (uintmax_t)ino);
		break;

	/*
	 * If any of these arise, something is grievously wrong with
	 * the current state of the symbol table.
	 */
	case INOFND|NAMEFND|MODECHG:
	case NAMEFND|MODECHG:
	case INOFND|MODECHG:
		fprintf(stderr, "[%s] %s: inconsistent state\n", keyval(key),
			name);
		break;

	/*
	 * These states "cannot" arise for any state of the symbol table.
	 */
	case ONTAPE|MODECHG:
	case MODECHG:
	default:
		panic("[%s] %s: impossible state\n", keyval(key), name);
		break;
	}
	return (descend);
}
Example #16
0
/*
 * readconf - read the configuration information out of the file we
 *	      were passed.  Note that since the file is supposed to be
 *	      machine generated, we bail out at the first sign of trouble.
 */
static void
readconf(
	FILE *fp,
	char *name
	)
{
	register int i;
	char *token[NUMTOK];
	u_long intval[NUMTOK];
	u_int flags;
	char buf[MAXLINESIZE];
	char *bp;

	while (fgets(buf, MAXLINESIZE, fp) != NULL) {

		bp = buf;
		for (i = 0; i < NUMTOK; i++) {
			if ((token[i] = nexttoken(&bp)) == NULL) {
				msyslog(LOG_ERR,
					"tokenizing error in file `%s', quitting",
					name);
				resolver_exit(1);
			}
		}

		for (i = 1; i < NUMTOK - 1; i++) {
			if (!atouint(token[i], &intval[i])) {
				msyslog(LOG_ERR,
					"format error for integer token `%s', file `%s', quitting",
					token[i], name);
				resolver_exit(1);
			}
		}

#if 0 /* paranoid checking - these are done in newpeer() */
		if (intval[TOK_HMODE] != MODE_ACTIVE &&
		    intval[TOK_HMODE] != MODE_CLIENT &&
		    intval[TOK_HMODE] != MODE_BROADCAST) {
			msyslog(LOG_ERR, "invalid mode (%ld) in file %s",
				intval[TOK_HMODE], name);
			resolver_exit(1);
		}

		if (intval[TOK_VERSION] > NTP_VERSION ||
		    intval[TOK_VERSION] < NTP_OLDVERSION) {
			msyslog(LOG_ERR, "invalid version (%ld) in file %s",
				intval[TOK_VERSION], name);
			resolver_exit(1);
		}
		if (intval[TOK_MINPOLL] < ntp_minpoll ||
		    intval[TOK_MINPOLL] > NTP_MAXPOLL) {

			msyslog(LOG_ERR, "invalid MINPOLL value (%ld) in file %s",
				intval[TOK_MINPOLL], name);
			resolver_exit(1);
		}

		if (intval[TOK_MAXPOLL] < ntp_minpoll ||
		    intval[TOK_MAXPOLL] > NTP_MAXPOLL) {
			msyslog(LOG_ERR, "invalid MAXPOLL value (%ld) in file %s",
				intval[TOK_MAXPOLL], name);
			resolver_exit(1);
		}

		if ((intval[TOK_FLAGS] & ~(FLAG_PREFER | FLAG_NOSELECT |
		    FLAG_BURST | FLAG_IBURST | FLAG_SKEY)) != 0) {
			msyslog(LOG_ERR, "invalid flags (%ld) in file %s",
				intval[TOK_FLAGS], name);
			resolver_exit(1);
		}
#endif /* end paranoid checking */

		flags = 0;
		if (intval[TOK_FLAGS] & FLAG_PREFER)
		    flags |= CONF_FLAG_PREFER;
		if (intval[TOK_FLAGS] & FLAG_NOSELECT)
		    flags |= CONF_FLAG_NOSELECT;
		if (intval[TOK_FLAGS] & FLAG_BURST)
		    flags |= CONF_FLAG_BURST;
		if (intval[TOK_FLAGS] & FLAG_IBURST)
		    flags |= CONF_FLAG_IBURST;

#ifdef OPENSSL
		if (intval[TOK_FLAGS] & FLAG_SKEY)
		    flags |= CONF_FLAG_SKEY;
#endif /* OPENSSL */

		/*
		 * This is as good as we can check it.  Add it in.
		 */
		addentry(token[TOK_HOSTNAME],
			 (int)intval[TOK_NEEDED], (int)intval[TOK_TYPE],
			 (int)intval[TOK_HMODE], (int)intval[TOK_VERSION],
			 (int)intval[TOK_MINPOLL], (int)intval[TOK_MAXPOLL],
			 flags, (int)intval[TOK_TTL],
			 intval[TOK_KEYID], token[TOK_KEYSTR]);
	}
}
Example #17
0
void addentry(){
    	int i, s;
	/*Setting border color */
    	init_pair(2,COLOR_MAGENTA,COLOR_BLACK);
	attron(COLOR_PAIR(2));
	border(0,0,0,0, 0,0,0,0);
	refresh();
	attroff(COLOR_PAIR(2));
	refresh();
   	int fict, sh, ref, nonfict;
	FILE *fp;
	Book book;
    	char option = 'y';
   	clear();
	    	refresh();
    	while(option == 'y' || option == 'Y') {
    		printgen();
    		scanw("%d",&s);
			switch(s) {
				case FICTION :
						printfiction();
						scanw("%d",&fict);
				       		fp=fopen("Fiction.dat","ab+");
						if(getinfo(&book)){
							book.cat = categories[s - 1];
							book.subcat = fiction[fict - 1];
   						 	fseek(fp,0,SEEK_END);
   							fwrite(&book,sizeof(book),1,fp);
						        fclose(fp);
						}	
						break;
				case NONFICTION :
						fp=fopen("Nonfiction.dat","ab+");
                	        	        if(getinfo(&book) == 1){
                        	        	         book.cat = categories[s-1];
                                	        	 book.subcat = categories[s-1];
                     		                   	 fseek(fp,0,SEEK_END);
	                        	                 fwrite(&book,sizeof(book),1,fp);
	                                	         fclose(fp);
      		  	                        }
                	         	       break;
				case REFERENCE :
						printref();
						scanw("%d",&ref);
						fp=fopen("Reference.dat","ab+");
                     	          	        if(getinfo(&book) == 1){
                                        		 book.cat = categories[s-1];
                                        		 book.subcat = refer[ref - 1]; 
                                        		 fseek(fp,0,SEEK_END);
                            	            		 fwrite(&book,sizeof(book),1,fp);
                                	        	 fclose(fp);
                               			 }
                              			 break;
				case SELFHELP :
						printselfhelp();
						scanw("%d",&sh);
					 	fp=fopen("Selfhelp.dat","ab+");
                	                	if(getinfo(&book) == 1){
                        	                	 book.cat,categories[s-1];
                                	        	 book.subcat = selfhelp[sh - 1];
                                        		 fseek(fp,0,SEEK_END);
                                        		 fwrite(&book,sizeof(book),1,fp);
	                                       		 fclose(fp);
        	                	        }
                	               	        break;
				case MENU :
						mainmenu();
						return;
						break;
				default :
						printw("\n ----- Wrong option. Please select again -----\n");
						addentry();
						return;
			}
    		mvaddstr(10,16,"The record is sucessfully saved");
    		mvaddstr(11,16,"Add more ? (y/n) ");
		option = getch();
	}
	mvaddstr(12,16,"Press Enter to go to main menu");
	getch();
	mainmenu();
	refresh();
	return;
}
Example #18
0
/*
 * Initialize a symbol table from a file
 */
void
initsymtable(char *filename)
{
	char *base;
	long tblsize;
	struct entry *ep;
	struct entry *baseep, *lep;
	struct symtableheader hdr;
	struct stat stbuf;
	long i;
	int fd;

	Vprintf(stdout, "Initialize symbol table.\n");
	if (filename == NULL) {
		entrytblsize = maxino / HASHFACTOR;
		entry = calloc(entrytblsize, sizeof(struct entry *));
		if (entry == NULL)
			panic("no memory for entry table\n");
		ep = addentry(".", ROOTINO, NODE);
		ep->e_flags |= NEW;
		return;
	}
	if ((fd = open(filename, O_RDONLY, 0)) < 0) {
		warn("open");
		panic("cannot open symbol table file %s\n", filename);
	}
	if (fstat(fd, &stbuf) < 0) {
		warn("stat");
		panic("cannot stat symbol table file %s\n", filename);
	}
	tblsize = stbuf.st_size - sizeof(struct symtableheader);
	base = calloc(tblsize, sizeof(char));
	if (base == NULL)
		panic("cannot allocate space for symbol table\n");
	if (read(fd, base, tblsize) < 0 ||
	    read(fd, &hdr, sizeof(struct symtableheader)) < 0) {
		warn("read");
		panic("cannot read symbol table file %s\n", filename);
	}
	switch (command) {
	case 'r':
		/*
		 * For normal continuation, insure that we are using
		 * the next incremental tape
		 */
		if (hdr.dumpdate != dumptime)
			errx(1, "Incremental tape too %s",
			    (hdr.dumpdate < dumptime) ? "low" : "high");
		break;
	case 'R':
		/*
		 * For restart, insure that we are using the same tape
		 */
		curfile.action = SKIP;
		dumptime = hdr.dumptime;
		dumpdate = hdr.dumpdate;
		if (!bflag)
			newtapebuf(hdr.ntrec);
		getvol(hdr.volno);
		break;
	default:
		panic("initsymtable called from command %c\n", command);
		break;
	}
	maxino = hdr.maxino;
	entrytblsize = hdr.entrytblsize;
	entry = (struct entry **)
		(base + tblsize - (entrytblsize * sizeof(struct entry *)));
	baseep = (struct entry *)(base + hdr.stringsize - sizeof(struct entry));
	lep = (struct entry *)entry;
	for (i = 0; i < entrytblsize; i++) {
		if (entry[i] == NULL)
			continue;
		entry[i] = &baseep[(long)entry[i]];
	}
	for (ep = &baseep[1]; ep < lep; ep++) {
		ep->e_name = base + (long)ep->e_name;
		ep->e_parent = &baseep[(long)ep->e_parent];
		if (ep->e_sibling != NULL)
			ep->e_sibling = &baseep[(long)ep->e_sibling];
		if (ep->e_links != NULL)
			ep->e_links = &baseep[(long)ep->e_links];
		if (ep->e_entries != NULL)
			ep->e_entries = &baseep[(long)ep->e_entries];
		if (ep->e_next != NULL)
			ep->e_next = &baseep[(long)ep->e_next];
	}
}
Example #19
0
int main(int argc, char *argv[]) {
  FILE      *infile, *wadfile;
  char      keyword[20];
  char      vertexname[20], sectorname[20];
  char      fromvertexname[20], tovertexname[20];
  int      ox, oy, x, y, z, xf, yf;
  int      numentries, reslength;
  int      i;
  int      episode, level, maptype = 0;
  char      gametype[20];
  int      lastitem;
  int      floorh, ceilingh, brightness, special, tag, type, attrs, angle, flags;
  int      arg1, arg2, arg3, arg4, arg5;
  int       floort, ceilingt;
  int      uppert, lowert, normalt;
  char      thingname[20];
  int      tid;
  int      fromvertexindex, tovertexindex;
  int      rightsidedefindex, leftsidedefindex;
  int      sectorindex;
  char      behavior[16] = { 'A', 'C', 'S', '\0', 0x08, '\0', '\0', '\0',
             '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
                };

  w_vertex64_t   vertices[32768];
  w_sector64_t   sectors[32768];
  sidedef64_t  sidedefs[32768];
  linedef64_t  linedefs[32768];
  things64_t   things[32768];
  char lights[100000], macros[100000];
  int lightbytes = 0, macrobytes = 0;
  int      numvertices = 0, numsectors = 0, numsidedefs = 0,
			  numlinedefs = 0, numthings = 0;
  int      vertexshortcut = 1;
  int      sectorshortcut = 1;

  char      entryname[9];
  int      entrypos;

  if (argc != 3) {
    fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
    exit(-1);
  }
  if (!strcmp(argv[1], "-"))
    infile = stdin;
  else
    infile = fopen(argv[1], "r");
  if (infile == NULL) {
    fprintf(stderr,"Unable to open input file %s\n", argv[1]);
    exit(-1);
  }
  if (!strcmp(argv[2], "-"))
    wadfile = stdout;
  else
    wadfile = fopen(argv[2], "wb");
  if (wadfile == NULL) {
    fprintf(stderr,"Unable to create output file %s\n", argv[2]);
    exit(-1);
  }
  if (wadfile == stdout)
    quiet = 1;
  allowcomment(infile);
  fscanf(infile, " %s ", keyword);

  if (!strcmp(keyword, "LEVEL_START")) {
    fscanf(infile, " %d %d %d %s ", &episode, &level, &maptype, &gametype[0]);
    if(maptype != 64) {
       fprintf(stderr, "map file is not for Doom64EX\n");
       exit(-1);
    }
    allowcomment(infile);
    fscanf(infile, " %s ", keyword);
  } else {
    fprintf(stderr,"LEVEL_START marker missing!\n");
    exit(-1);
  }

  if (!strcmp(keyword, "VERTEXES_START") |
		  !strcmp(keyword, "VERTICES_START"))
  {
	  /* Process vertices until VERTEXES_END is found */
	  lastitem = 0;
	  numvertices = 0;
	  while (!lastitem) {
		  allowcomment(infile);
		  fscanf(infile, " %s ", vertexname);
		  if (!strcmp(vertexname, "VERTEXES_END") |
				  !strcmp(vertexname, "VERTICES_END"))
			  lastitem = 1;
		  else {
			  /* KLUDGE to speed things up, notice when vertex names contain
				* the vertex number and avoid the long scan of vertices[].
				*/
			  {
				  const char *p;
				  long num = 0;
				  int digits = 0;

				  /* Skip over the non-numeric prefix */
				  for (p = vertexname; *p != '\0' && (*p < '0' || *p > '9'); p++)
					  ;
				  for (; *p >= '0' && *p <= '9'; p++) {
					  num = 10 * num + *p - '0';
					  digits++;
				  }
				  if (digits == 0 || num != numvertices)
					  vertexshortcut = 0;
			  }
			  fscanf(infile, " : %d %d %d %d ", &x, &xf, &y, &yf);
			  allowcomment(infile);
			  vertices[numvertices].x = x;
			  vertices[numvertices].y = y;
			  vertices[numvertices].x_frac = xf;
			  vertices[numvertices].y_frac = yf;
			  strncpy(vertices[numvertices].name, vertexname, 8);
			  numvertices++;
		  }
	  }
	  fscanf(infile, " %s ", keyword);
  } else {
	  fprintf(stderr,"VERTEXES_START marker missing!\n");
	  exit(-1);
  }

  if (!strcmp(keyword, "SECTORS_START")) {
	  int i;
	  uint32_t flags;
	  uint16_t sflags;
	  /* Process sectors until SECTORS_END is found */
	  lastitem = 0;
	  numsectors = 0;
	  while (!lastitem) {
		  allowcomment(infile);
		  fscanf(infile, " %s ", sectorname);
		  if (!strcmp(sectorname, "SECTORS_END"))
			  lastitem = 1;
		  else {
			  fscanf(infile, " : %d %d %d %d %d %d %d ", &floorh, &ceilingh,
					  &floort, &ceilingt, &type, &tag, &flags);
			  /* KLUDGE to speed things up, notice when sector names contain
				* the sector number and avoid the long scan of sectors[].
				*/
			  {
				  const char *p;
				  long num = 0;
				  int digits = 0;

				  /* Skip over the non-numeric prefix */
				  for (p = sectorname; *p != '\0' && (*p < '0' || *p > '9'); p++)
					  ;
				  for (; *p >= '0' && *p <= '9'; p++)
				  {
					  num = 10 * num + *p - '0';
					  digits++;
				  }
				  if (digits == 0 || num != numsectors)
					  sectorshortcut = 0;
			  }
			  allowcomment(infile);
			  sectors[numsectors].s.f_height = floorh;
			  sectors[numsectors].s.c_height = ceilingh;
			  sectors[numsectors].s.type = type;
			  sectors[numsectors].s.flags = flags;
			  sectors[numsectors].s.tag = tag;
			  strncpy(sectors[numsectors].name, sectorname, 8);
			  sectors[numsectors].s.f_index = floort;
			  sectors[numsectors].s.c_index = ceilingt;

			  for(i=0; i<10; i++) {
				  int got;
				  fscanf(infile, " %x ", &got);
				  sectors[numsectors].s.color_index[i] = got & 0xff;
			  }

			  numsectors++;
		  }
	  }
	  fscanf(infile, " %s ", keyword);
  } else {
	  fprintf(stderr,"SECTORS_START marker missing!\n");
	  exit(-1);
  }

  if (!strcmp(keyword, "LINEDEFS_START")) {
	  uint32_t flags;
	  uint16_t sflags;

	  /* Process lines until LINEDEFS_END is found */
	  lastitem = 0;
	  numlinedefs = 0;
	  while (!lastitem) {
		  allowcomment(infile);
		  fscanf(infile, " %s ", fromvertexname);
		  if (!strcmp(fromvertexname, "LINEDEFS_END"))
			  lastitem = 1;
		  else {
			  fscanf(infile, " %s : %u %hu %d ", tovertexname, &flags, &type, &tag);
			  allowcomment(infile);
			  fromvertexindex = findmatch(fromvertexname, (char*)vertices,
					  vertexshortcut, numvertices,
					  sizeof(w_vertex64_t));
			  tovertexindex = findmatch(tovertexname, (char*)vertices,
					  vertexshortcut, numvertices,
					  sizeof(w_vertex64_t));

			  /* Read one or two SIDEDEFS */
			  fscanf(infile, " %s %d %d %d %d %d ", sectorname, &ox, &oy,
					  &uppert, &lowert, &normalt);
			  allowcomment(infile);
			  sectorindex = findmatch(sectorname, (char*)sectors, sectorshortcut,
					  numsectors, sizeof(w_sector64_t));
			  sidedefs[numsidedefs].sector = sectorindex;
			  sidedefs[numsidedefs].x = ox;
			  sidedefs[numsidedefs].y = oy;
			  sidedefs[numsidedefs].u_texture = uppert;
			  sidedefs[numsidedefs].l_texture = lowert;
			  sidedefs[numsidedefs].m_texture = normalt;
			  rightsidedefindex = numsidedefs;
			  numsidedefs++;
			  fscanf(infile, "%s", sectorname);
			  if (!strcmp(sectorname, "-")) {
				  allowcomment(infile);
				  leftsidedefindex = -1;
			  } else {
				  fscanf(infile, " %d %d %u %u %u ", &ox, &oy, &uppert, &lowert, &normalt);
				  allowcomment(infile);
				  sectorindex = findmatch(sectorname, (char*)sectors, sectorshortcut,
						  numsectors, sizeof(w_sector64_t));
				  sidedefs[numsidedefs].sector = sectorindex;
				  sidedefs[numsidedefs].x = ox;
				  sidedefs[numsidedefs].y = oy;
				  sidedefs[numsidedefs].u_texture = uppert;
				  sidedefs[numsidedefs].l_texture = lowert;
				  sidedefs[numsidedefs].m_texture = normalt;
				  leftsidedefindex = numsidedefs;
				  numsidedefs++;
			  }
			  linedefs[numlinedefs].v_from = fromvertexindex;
			  linedefs[numlinedefs].v_to = tovertexindex;
			  linedefs[numlinedefs].flags = flags;
			  linedefs[numlinedefs].type = sflags;
			  linedefs[numlinedefs].tag = tag;
			  linedefs[numlinedefs].r_side = rightsidedefindex;
			  linedefs[numlinedefs].l_side = leftsidedefindex;
			  numlinedefs++;
		  }
	  }
	  fscanf(infile, " %s ", keyword);
  } else {
    fprintf(stderr,"LINEDEFS_START marker missing!\n");
    exit(-1);
  }

  if (!strcmp(keyword, "THINGS_START")) {
	  /* Process things until THINGS_END is found */
	  lastitem = 0;
	  numthings = 0;
	  while (!lastitem) {
		  allowcomment(infile);
		  fscanf(infile, " %s ", thingname);
		  if (!strcmp(thingname, "THINGS_END"))
			  lastitem = 1;
		  else {
			  sscanf(thingname, "%hd", &(things[numthings].type));
			  fscanf(infile, " : %hd %hd %hd %hd %hd %hd",
					  &(things[numthings].x),
					  &(things[numthings].y),
					  &(things[numthings].z),
					  &(things[numthings].angle),
					  &(things[numthings].flags),
					  &(things[numthings].tid));
			  allowcomment(infile);
			  numthings++;
		  }
	  }
	  fscanf(infile, " %s ", keyword);
  } else {
	  fprintf(stderr,"THINGS_START marker missing!\n");
	  exit(-1);
  }

  if (!strcmp(keyword, "LIGHTS_START")) {
	  lightbytes = 0;
	  fscanf(infile, " %s ", keyword);
	  while(strcmp(keyword, "LIGHTS_END")) {
		  unsigned int got;
		  sscanf(keyword, " %d ", &got);
		  lights[lightbytes++] = (unsigned char)(got & 0xff);
		  fscanf(infile, " %s ", keyword);
	  }
  } else {
	  fprintf(stderr,"LIGHTS_START marker missing!\n");
	  exit(-1);
  }

  fscanf(infile, " %s ", keyword);
  if (!strcmp(keyword, "MACROS_START")) {
	  macrobytes = 0;
	  fscanf(infile, " %s ", keyword);
	  while(strcmp(keyword, "MACROS_END")) {
		  unsigned int got;
		  sscanf(keyword, " %d ", &got);
		  macros[macrobytes++] = (unsigned char)(got & 0xff);
		  fscanf(infile, " %s ", keyword);
	  }
  } else {
	  fprintf(stderr,"MACROS_START marker missing!\n");
	  exit(-1);
  }


  if (infile != stdin)
	  fclose(infile);

  /* Concatenate all the data into the final PWAD file */

  /* Header */
  fprintf(wadfile,"PWAD");

  /* Doom64 map type */
  numentries = 14;
  putlong(numentries, wadfile);
  reslength = numthings * sizeof(things64_t) +
	  numlinedefs * sizeof(linedef64_t) +
	  numsidedefs * sizeof(sidedef64_t) +
	  numvertices * sizeof(vertex64_t) +
	  numsectors * sizeof(sector64_t) +
	  lightbytes +
	  macrobytes +
	  sizeof(wadinfo_t);
  putlong(reslength, wadfile);

  /* ExMy - start at position 12 (zero length entry) */

  /* THINGS - start at position 12 */
  for (i = 0; i < numthings; i++) {
      /* Doom map type */
      putshort(things[i].x, wadfile);
      putshort(things[i].y, wadfile);
      putshort(things[i].z, wadfile);
      putshort(things[i].angle, wadfile);
      putshort(things[i].type, wadfile);
      putshort(things[i].flags, wadfile);
      putshort(things[i].tid, wadfile);
  }

  /* LINEDEFS - start at position 12 + numthings * sizeof(things_t) */
  for (i = 0; i < numlinedefs; i++) {
	  /* Doom map type */
	  putshort(linedefs[i].v_from, wadfile);
	  putshort(linedefs[i].v_to, wadfile);
	  putlong(linedefs[i].flags, wadfile);
	  putshort(linedefs[i].type, wadfile);
	  putshort(linedefs[i].tag, wadfile);
	  putshort(linedefs[i].r_side, wadfile);
	  putshort(linedefs[i].l_side, wadfile);
  }

  /* SIDEDEFS - start at position 12 + numthings * sizeof(things_t) +
   * numlinedefs * sizeof(linedef_t)
   */
  for (i = 0; i < numsidedefs; i++) {
    putshort(sidedefs[i].x, wadfile);
    putshort(sidedefs[i].y, wadfile);
    putshort(sidedefs[i].u_texture, wadfile);
    putshort(sidedefs[i].l_texture, wadfile);
    putshort(sidedefs[i].m_texture, wadfile);
    putshort(sidedefs[i].sector, wadfile);
  }

  /* VERTEXES - start at position 12 + numthings * sizeof(things_t) +
   * numlinedefs * sizeof(linedef_t) + numsidedefs * sizeof(sidedef_t)
   */
  for (i = 0; i < numvertices; i++) {
    putshort(vertices[i].x_frac, wadfile);
    putshort(vertices[i].x, wadfile);
    putshort(vertices[i].y_frac, wadfile);
    putshort(vertices[i].y, wadfile);
  }

  /* SECTORS - start at position 12 + numthings * sizeof(things_t) +
   * numlinedefs * sizeof(linedef_t) + numsidedefs * sizeof(sidedef_t) +
   * numvertices * sizeof(vertex_t)
   */
  for (i = 0; i < numsectors; i++) {
    putshort(sectors[i].s.f_height, wadfile);
    putshort(sectors[i].s.c_height, wadfile);
    putshort(sectors[i].s.f_index, wadfile);
    putshort(sectors[i].s.c_index, wadfile);
	 fwrite(sectors[i].s.color_index, 10, 1, wadfile);
    putshort(sectors[i].s.type, wadfile);
    putshort(sectors[i].s.tag, wadfile);
    putshort(sectors[i].s.flags, wadfile);
  }

  fwrite(lights, lightbytes, 1, wadfile);
  fwrite(macros, macrobytes, 1, wadfile);

  /* Now, write the main directory */
  entrypos = 12;
  if (episode > 0)
      sprintf(entryname, "E%1dM%1d", episode, level);
  else
      sprintf(entryname, "MAP%02d", level);
  addentry(&entrypos, 0,            entryname,  wadfile);
    addentry(&entrypos, numthings*sizeof(things64_t),   "THINGS",   wadfile);
    addentry(&entrypos, numlinedefs*sizeof(linedef64_t),   "LINEDEFS", wadfile);
  addentry(&entrypos, numsidedefs*sizeof(sidedef64_t),   "SIDEDEFS", wadfile);
  addentry(&entrypos, numvertices*sizeof(vertex64_t),   "VERTEXES", wadfile);
  addentry(&entrypos, 0,                       "SEGS",     wadfile);
  addentry(&entrypos, 0,                       "SSECTORS", wadfile);
  addentry(&entrypos, 0,                       "NODES",    wadfile);
  addentry(&entrypos, numsectors*sizeof(sector64_t),   "SECTORS",  wadfile);
  addentry(&entrypos, 0,                       "REJECT",   wadfile);
  addentry(&entrypos, 0,                       "BLOCKMAP", wadfile);
  addentry(&entrypos, 0,                       "LEAFS", wadfile);
  addentry(&entrypos, lightbytes,                       "LIGHTS", wadfile);
  addentry(&entrypos, macrobytes,                       "MACROS", wadfile);

  /* DONE! */
  if (wadfile != stdout)
    fclose(wadfile);
  return 0;
}