mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-12-23 11:10:56 +00:00
786 lines
30 KiB
C
786 lines
30 KiB
C
|
/*
|
||
|
LumpMod v0.2.1, a command-line utility for working with lumps in wad
|
||
|
files.
|
||
|
Copyright (C) 2003 Thunder Palace Entertainment.
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||
|
|
||
|
lumpmod.c: Provides program functionality; depends on lump.c and lump.h
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include "lump.h"
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
enum commands { C_ADD, C_ADDSECT, C_DELETE, C_DELSECT, C_EXTRACT, C_LIST,
|
||
|
C_RENAME, C_UPDATE } cmd;
|
||
|
struct wadfile *wfptr;
|
||
|
struct lumplist *startitem, *enditem = NULL;
|
||
|
FILE *fpoint;
|
||
|
char *progname, **params;
|
||
|
char *startname = NULL, *endname = NULL;
|
||
|
int numargs, numparams, insection = 0;
|
||
|
|
||
|
progname = argv[0];
|
||
|
numargs = argc - 1;
|
||
|
|
||
|
/* Verify that there are enough arguments */
|
||
|
if(numargs < 2) {
|
||
|
fprintf(stderr, "%s: not enough arguments\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Identify the command used */
|
||
|
if(strcmp(argv[2], "add" ) == 0) cmd = C_ADD;
|
||
|
else if(strcmp(argv[2], "addsect") == 0) cmd = C_ADDSECT;
|
||
|
else if(strcmp(argv[2], "delete" ) == 0) cmd = C_DELETE;
|
||
|
else if(strcmp(argv[2], "delsect") == 0) cmd = C_DELSECT;
|
||
|
else if(strcmp(argv[2], "extract") == 0) cmd = C_EXTRACT;
|
||
|
else if(strcmp(argv[2], "list" ) == 0) cmd = C_LIST;
|
||
|
else if(strcmp(argv[2], "rename" ) == 0) cmd = C_RENAME;
|
||
|
else if(strcmp(argv[2], "update" ) == 0) cmd = C_UPDATE;
|
||
|
else {
|
||
|
fprintf(stderr, "%s: invalid command %s\n", progname, argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Check for -s option */
|
||
|
if(numargs >= 4 && strcmp(argv[3], "-s") == 0) {
|
||
|
if(cmd == C_ADDSECT || cmd == C_DELSECT) {
|
||
|
fprintf(stderr, "%s: no option -s for command %s\n", progname, argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
insection = 1;
|
||
|
params = &argv[5];
|
||
|
numparams = numargs - 4;
|
||
|
|
||
|
/* Assume a map name if length > 2 */
|
||
|
if(strlen(argv[4]) > 2) startname = argv[4];
|
||
|
else {
|
||
|
startname = malloc(strlen(argv[4]) + 7);
|
||
|
endname = malloc(strlen(argv[4]) + 5);
|
||
|
if(startname == NULL || endname == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
sprintf(startname, "%s_START", argv[4]);
|
||
|
sprintf(endname, "%s_END", argv[4]);
|
||
|
}
|
||
|
} else {
|
||
|
params = &argv[3];
|
||
|
numparams = numargs - 2;
|
||
|
} /* end of check for -s option */
|
||
|
|
||
|
/* Load the wadfile into memory, since all commands require this */
|
||
|
fpoint = fopen(argv[1], "rb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s\n", progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
wfptr = read_wadfile(fpoint);
|
||
|
fclose(fpoint);
|
||
|
if(wfptr == NULL) {
|
||
|
fprintf(stderr, "%s: %s is not a valid wadfile\n", progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Find startitem and enditem, using startname and endname */
|
||
|
if(startname == NULL) startitem = wfptr->head;
|
||
|
else {
|
||
|
startitem = find_previous_lump(wfptr->head, NULL, startname);
|
||
|
if(startitem == NULL) {
|
||
|
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
||
|
startname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
startitem = startitem->next;
|
||
|
if(endname == NULL) {
|
||
|
if(startitem->next != NULL) {
|
||
|
char *itemname;
|
||
|
|
||
|
enditem = startitem->next;
|
||
|
itemname = get_lump_name(enditem->cl);
|
||
|
while( strcmp(itemname, "THINGS" ) == 0 ||
|
||
|
strcmp(itemname, "LINEDEFS") == 0 ||
|
||
|
strcmp(itemname, "SIDEDEFS") == 0 ||
|
||
|
strcmp(itemname, "VERTEXES") == 0 ||
|
||
|
strcmp(itemname, "SEGS" ) == 0 ||
|
||
|
strcmp(itemname, "SSECTORS") == 0 ||
|
||
|
strcmp(itemname, "NODES" ) == 0 ||
|
||
|
strcmp(itemname, "SECTORS" ) == 0 ||
|
||
|
strcmp(itemname, "REJECT" ) == 0 ||
|
||
|
strcmp(itemname, "BLOCKMAP") == 0) {
|
||
|
enditem = enditem->next;
|
||
|
if(enditem == NULL) break;
|
||
|
free(itemname);
|
||
|
itemname = get_lump_name(enditem->cl);
|
||
|
}
|
||
|
free(itemname);
|
||
|
if(enditem != NULL) enditem = enditem->next;
|
||
|
} else enditem = NULL;
|
||
|
} else {
|
||
|
enditem = find_previous_lump(startitem, NULL, endname);
|
||
|
if(enditem == NULL) {
|
||
|
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
||
|
endname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
enditem = enditem->next;
|
||
|
}
|
||
|
} /* end of finding startitem and enditem */
|
||
|
|
||
|
/* Do stuff specific to each command */
|
||
|
switch(cmd) {
|
||
|
case C_ADD: {
|
||
|
struct lumplist *startitem2, *before, *existing;
|
||
|
int overwrite = 1, firstentry = 0, canduplicate = 0;
|
||
|
char *startname2 = NULL;
|
||
|
|
||
|
/* Parse options: -a, -b, -d, -n */
|
||
|
while(numparams > 2) {
|
||
|
if(params[0][0] != '-') break;
|
||
|
if(strcmp(params[0], "-n") == 0) overwrite = 0;
|
||
|
else if(strcmp(params[0], "-d") == 0) canduplicate = 1;
|
||
|
else if(strcmp(params[0], "-b") == 0) firstentry = 1;
|
||
|
else if(strcmp(params[0], "-a") == 0) {
|
||
|
params = ¶ms[1];
|
||
|
numparams--;
|
||
|
startname2 = params[0];
|
||
|
} else {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
params = ¶ms[1];
|
||
|
numparams--;
|
||
|
}
|
||
|
|
||
|
if(numparams < 2) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Find the lump after which to add */
|
||
|
if(firstentry) before = startitem;
|
||
|
else if(startname2 != NULL) {
|
||
|
before = find_previous_lump(startitem, enditem, startname2);
|
||
|
if(before == NULL) {
|
||
|
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
||
|
startname2, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
before = before->next;
|
||
|
} else {
|
||
|
if(insection) {
|
||
|
before = find_last_lump_between(startitem, enditem);
|
||
|
if(before == NULL) before = startitem;
|
||
|
} else before = find_last_lump(wfptr);
|
||
|
}
|
||
|
startitem2 = before;
|
||
|
|
||
|
/* Add LUMPNAME FILENAME pairs */
|
||
|
printf("Adding lumps in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
long newlumpsize;
|
||
|
unsigned char *newlumpdata;
|
||
|
|
||
|
/* Check whether the lump already exists, unless -d is used */
|
||
|
if(canduplicate) existing = NULL;
|
||
|
else existing = find_previous_lump(startitem, enditem, params[0]);
|
||
|
if(existing != NULL) existing = existing->next;
|
||
|
if(existing != NULL && overwrite == 0) {
|
||
|
printf("Lump %s already exists. Taking no action.\n", params[0]);
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Read the file with new lump data */
|
||
|
fpoint = fopen(params[1], "rb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: can't open file %s\n", progname,
|
||
|
params[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Find size of lump data */
|
||
|
fseek(fpoint, 0, SEEK_END);
|
||
|
newlumpsize = ftell(fpoint);
|
||
|
fseek(fpoint, 0, SEEK_SET);
|
||
|
|
||
|
/* Copy lump data to memory */
|
||
|
if(newlumpsize == 0) newlumpdata = NULL;
|
||
|
else {
|
||
|
newlumpdata = malloc(newlumpsize);
|
||
|
if(newlumpdata == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(fread(newlumpdata, newlumpsize, 1, fpoint) < 1) {
|
||
|
fprintf(stderr, "%s: unable to read file %s\n",
|
||
|
progname, params[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Close the file */
|
||
|
fclose(fpoint);
|
||
|
|
||
|
/* Add or update lump */
|
||
|
if(existing == NULL) {
|
||
|
if(add_lump(wfptr, before, params[0], newlumpsize,
|
||
|
newlumpdata) != 0) {
|
||
|
fprintf(stderr, "%s: unable to add lump %s\n",
|
||
|
progname, params[0]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
printf("Lump %s added.\n", params[0]);
|
||
|
|
||
|
/* Other lumps will be added after the new one */
|
||
|
before = before->next;
|
||
|
} else {
|
||
|
existing->cl->len = newlumpsize;
|
||
|
free(existing->cl->data);
|
||
|
existing->cl->data = malloc(newlumpsize);
|
||
|
if(existing->cl->data == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
memcpy(existing->cl->data, newlumpdata, newlumpsize);
|
||
|
printf("Lump %s updated.\n", params[0]);
|
||
|
}
|
||
|
|
||
|
/* Advance to the next pair, if there is a next pair */
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
} /* end of adding LUMPNAME FILENAME pairs */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_ADD */
|
||
|
break;
|
||
|
|
||
|
case C_UPDATE: {
|
||
|
struct lumplist *existing;
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 2 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 2) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Update LUMPNAME FILENAME pairs */
|
||
|
printf("Updating lumps in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
long newlumpsize;
|
||
|
unsigned char *newlumpdata;
|
||
|
|
||
|
/* Check whether the lump already exists */
|
||
|
existing = find_previous_lump(startitem, enditem, params[0]);
|
||
|
if(existing == NULL) {
|
||
|
printf("Lump %s does not exist. Taking no action.\n",
|
||
|
params[0]);
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
continue;
|
||
|
}
|
||
|
existing = existing->next;
|
||
|
|
||
|
/* Read the file with new lump data */
|
||
|
fpoint = fopen(params[1], "rb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: can't open file %s\n", progname,
|
||
|
params[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Find size of lump data */
|
||
|
fseek(fpoint, 0, SEEK_END);
|
||
|
newlumpsize = ftell(fpoint);
|
||
|
fseek(fpoint, 0, SEEK_SET);
|
||
|
|
||
|
/* Copy lump data to memory */
|
||
|
if(newlumpsize == 0) newlumpdata = NULL;
|
||
|
else {
|
||
|
newlumpdata = malloc(newlumpsize);
|
||
|
if(newlumpdata == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(fread(newlumpdata, newlumpsize, 1, fpoint) < 1) {
|
||
|
fprintf(stderr, "%s: unable to read file %s\n",
|
||
|
progname, params[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Close the file */
|
||
|
fclose(fpoint);
|
||
|
|
||
|
/* Update lump */
|
||
|
existing->cl->len = newlumpsize;
|
||
|
free(existing->cl->data);
|
||
|
existing->cl->data = malloc(newlumpsize);
|
||
|
if(existing->cl->data == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
memcpy(existing->cl->data, newlumpdata, newlumpsize);
|
||
|
printf("Lump %s updated.\n", params[0]);
|
||
|
|
||
|
/* Advance to the next pair, if there is a next pair */
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
} /* end of updating LUMPNAME FILENAME pairs */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_UPDATE */
|
||
|
break;
|
||
|
|
||
|
case C_DELETE: {
|
||
|
struct lumplist *before;
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 1 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 1) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Delete LUMPNAME lumps */
|
||
|
printf("Deleting lumps in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
|
||
|
/* Find the lump to delete */
|
||
|
before = find_previous_lump(startitem, enditem, params[0]);
|
||
|
if(before == NULL) {
|
||
|
printf("Lump %s does not exist. Taking no action.\n",
|
||
|
params[0]);
|
||
|
numparams--;
|
||
|
if(numparams < 1) break;
|
||
|
params = ¶ms[1];
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* Delete it */
|
||
|
remove_next_lump(wfptr, before);
|
||
|
printf("Lump %s deleted.\n", params[0]);
|
||
|
|
||
|
/* Advance to the next item to delete, if there is one */
|
||
|
numparams--;
|
||
|
if(numparams < 1) break;
|
||
|
params = ¶ms[1];
|
||
|
} /* end of deleting LUMPNAME lumps */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_DELETE */
|
||
|
break;
|
||
|
|
||
|
case C_RENAME: {
|
||
|
struct lumplist *renamed;
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 2 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 2) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Rename OLDNAME NEWNAME pairs */
|
||
|
printf("Renaming lumps in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
|
||
|
/* Find the lump to rename */
|
||
|
renamed = find_previous_lump(startitem, enditem, params[0]);
|
||
|
if(renamed == NULL) {
|
||
|
printf("Lump %s does not exist. Taking no action.\n",
|
||
|
params[0]);
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
continue;
|
||
|
}
|
||
|
renamed = renamed->next;
|
||
|
|
||
|
/* Rename lump */
|
||
|
memset(renamed->cl->name, '\0', 8);
|
||
|
if(strlen(params[1]) >= 8) memcpy(renamed->cl->name,
|
||
|
params[1], 8);
|
||
|
else strcpy(renamed->cl->name, params[1]);
|
||
|
|
||
|
printf("Lump %s renamed to %s.\n", params[0], params[1]);
|
||
|
|
||
|
/* Advance to the next pair, if there is a next pair */
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
} /* end of renaming OLDNAME NEWNAME pairs */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_RENAME */
|
||
|
break;
|
||
|
|
||
|
case C_EXTRACT: {
|
||
|
struct lumplist *extracted;
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 2 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 2) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Extract LUMPNAME FILENAME pairs */
|
||
|
printf("Extracting lumps from %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
|
||
|
/* Find the lump to extract */
|
||
|
extracted = find_previous_lump(startitem, enditem, params[0]);
|
||
|
if(extracted == NULL) {
|
||
|
printf("Lump %s does not exist. Taking no action.\n",
|
||
|
params[0]);
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
continue;
|
||
|
}
|
||
|
extracted = extracted->next;
|
||
|
|
||
|
/* Open the file to extract to */
|
||
|
fpoint = fopen(params[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: can't open file %s for writing\n",
|
||
|
progname, params[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Extract lump */
|
||
|
if(fwrite(extracted->cl->data, extracted->cl->len, 1, fpoint)
|
||
|
< 1) {
|
||
|
fprintf(stderr, "%s: unable to write lump %s to disk\n",
|
||
|
progname, params[0]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Close the file */
|
||
|
fclose(fpoint);
|
||
|
printf("Lump %s saved as %s.\n", params[0], params[1]);
|
||
|
|
||
|
/* Advance to the next pair, if there is a next pair */
|
||
|
numparams -= 2;
|
||
|
if(numparams < 2) break;
|
||
|
params = ¶ms[2];
|
||
|
} /* end of extracting LUMPNAME FILENAME pairs */
|
||
|
|
||
|
printf("Finished extracting lumps from file %s.\n", argv[1]);
|
||
|
} /* end of C_EXTRACT */
|
||
|
break;
|
||
|
|
||
|
case C_LIST: {
|
||
|
struct lumplist *curlump;
|
||
|
int verbose = 0, i = 0;
|
||
|
|
||
|
/* Parse options: -v */
|
||
|
while(numparams > 0) {
|
||
|
if(params[0][0] != '-') break;
|
||
|
if(strcmp(params[0], "-v") == 0) verbose = 1;
|
||
|
else {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
params = ¶ms[1];
|
||
|
numparams--;
|
||
|
}
|
||
|
|
||
|
/* Loop through the lump list, printing lump info */
|
||
|
for(curlump = startitem->next; curlump != enditem; curlump =
|
||
|
curlump->next) {
|
||
|
i++;
|
||
|
if(verbose) printf("%5i %-8s %7li\n", i,
|
||
|
get_lump_name(curlump->cl), curlump->cl->len);
|
||
|
else printf("%s\n", get_lump_name(curlump->cl));
|
||
|
}
|
||
|
} /* end of C_LIST */
|
||
|
break;
|
||
|
|
||
|
case C_DELSECT: {
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 1 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 1) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Delete sections */
|
||
|
printf("Deleting sections in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
struct lumplist *curlump;
|
||
|
|
||
|
/* Assume a map name if length > 2 */
|
||
|
if(strlen(params[0]) > 2) startname = params[0];
|
||
|
else {
|
||
|
startname = malloc(strlen(params[0]) + 7);
|
||
|
endname = malloc(strlen(params[0]) + 5);
|
||
|
if(startname == NULL || endname == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
sprintf(startname, "%s_START", params[0]);
|
||
|
sprintf(endname, "%s_END", params[0]);
|
||
|
}
|
||
|
|
||
|
/* Find startitem and enditem, using startname and endname */
|
||
|
startitem = find_previous_lump(wfptr->head, NULL, startname);
|
||
|
if(startitem == NULL) {
|
||
|
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
||
|
startname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(endname == NULL && startitem->next != NULL) {
|
||
|
char *itemname;
|
||
|
|
||
|
enditem = startitem->next;
|
||
|
itemname = get_lump_name(enditem->cl);
|
||
|
do {
|
||
|
enditem = enditem->next;
|
||
|
if(enditem == NULL) break;
|
||
|
free(itemname);
|
||
|
itemname = get_lump_name(enditem->cl);
|
||
|
} while(strcmp(itemname, "THINGS" ) == 0 ||
|
||
|
strcmp(itemname, "LINEDEFS") == 0 ||
|
||
|
strcmp(itemname, "SIDEDEFS") == 0 ||
|
||
|
strcmp(itemname, "VERTEXES") == 0 ||
|
||
|
strcmp(itemname, "SEGS" ) == 0 ||
|
||
|
strcmp(itemname, "SSECTORS") == 0 ||
|
||
|
strcmp(itemname, "NODES" ) == 0 ||
|
||
|
strcmp(itemname, "SECTORS" ) == 0 ||
|
||
|
strcmp(itemname, "REJECT" ) == 0 ||
|
||
|
strcmp(itemname, "BLOCKMAP") == 0);
|
||
|
free(itemname);
|
||
|
}
|
||
|
else {
|
||
|
enditem = find_previous_lump(startitem, NULL, endname);
|
||
|
if(enditem == NULL) {
|
||
|
fprintf(stderr, "%s: can't find lump %s in %s",
|
||
|
progname, endname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
enditem = enditem->next->next;
|
||
|
} /* end of finding startitem and enditem */
|
||
|
|
||
|
/* Loop through the section lumps, deleting them */
|
||
|
curlump = startitem;
|
||
|
while(curlump->next != enditem)
|
||
|
remove_next_lump(wfptr, curlump);
|
||
|
printf("Deleted section %s.\n", params[0]);
|
||
|
|
||
|
/* Move to next parameter, if it exists */
|
||
|
numparams--;
|
||
|
if(numparams < 1) break;
|
||
|
params = ¶ms[1];
|
||
|
} /* end of deleting sections */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_DELSECT */
|
||
|
break;
|
||
|
|
||
|
case C_ADDSECT: {
|
||
|
|
||
|
/* Parse options (none) */
|
||
|
if(numparams > 1 && params[0][0] == '-') {
|
||
|
fprintf(stderr, "%s: no option %s for command %s",
|
||
|
progname, params[0], argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(numparams < 1) {
|
||
|
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
||
|
argv[2]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
/* Add sections */
|
||
|
printf("Adding sections in %s...\n", argv[1]);
|
||
|
for(;;) {
|
||
|
struct lumplist *curlump;
|
||
|
|
||
|
/* Assume a map name if length > 2 */
|
||
|
if(strlen(params[0]) > 2) startname = params[0];
|
||
|
else {
|
||
|
startname = malloc(strlen(params[0]) + 7);
|
||
|
endname = malloc(strlen(params[0]) + 5);
|
||
|
if(startname == NULL || endname == NULL) {
|
||
|
fprintf(stderr, "%s: out of memory\n", progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
sprintf(startname, "%s_START", params[0]);
|
||
|
sprintf(endname, "%s_END", params[0]);
|
||
|
}
|
||
|
|
||
|
/* Add section, unless it already exists */
|
||
|
if(find_previous_lump(wfptr->head, NULL, startname) == NULL) {
|
||
|
struct lumplist *last;
|
||
|
|
||
|
last = find_last_lump(wfptr);
|
||
|
if(add_lump(wfptr, last, startname, 0, NULL) != 0) {
|
||
|
fprintf(stderr, "%s: unable to add lump %s\n",
|
||
|
progname, startname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
|
||
|
if(endname != NULL) {
|
||
|
last = last->next;
|
||
|
if(add_lump(wfptr, last, endname, 0, NULL) != 0) {
|
||
|
fprintf(stderr, "%s: unable to add lump %s\n",
|
||
|
progname, endname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printf("Added section %s.\n", params[0]);
|
||
|
} else
|
||
|
printf("Section %s already exists. Taking no action.\n",
|
||
|
params[0]);
|
||
|
|
||
|
/* Move to next parameter, if it exists */
|
||
|
numparams--;
|
||
|
if(numparams < 1) break;
|
||
|
params = ¶ms[1];
|
||
|
} /* end of adding sections */
|
||
|
|
||
|
/* Save the modified wadfile */
|
||
|
fpoint = fopen(argv[1], "wb");
|
||
|
if(fpoint == NULL) {
|
||
|
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
||
|
progname, argv[1]);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
if(write_wadfile(fpoint, wfptr) != 0) {
|
||
|
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
||
|
progname);
|
||
|
return EXIT_FAILURE;
|
||
|
}
|
||
|
fclose(fpoint);
|
||
|
printf("File %s successfully updated.\n", argv[1]);
|
||
|
} /* end of C_ADDSECT */
|
||
|
} /* end of command-specific stuff */
|
||
|
|
||
|
return EXIT_SUCCESS;
|
||
|
}
|