1 /*
2 * LDAT - Luola Datafile format archiver
3 * Copyright (C) 2002-2005 Calle Laakkonen
4 *
5 * File : ldatar.c
6 * Description : A program to manipulate LDAT archives
7 * Author(s) : Calle Laakkonen
8 *
9 * LDAT is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * Luola is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include <stdlib.h>
25 #include <getopt.h>
26 #include <stdio.h>
27
28 #include "ldat.h"
29 #include "archive.h"
30
31 typedef enum {MODE_UNSET,LIST,PACK,EXTRACT} Mode;
32 static Mode ldat_mode = MODE_UNSET;
33 static int verbose = 0, pack_index = 1;
34
35 /* Print out list of files in LDAT archive */
list_ldat(const char * filename)36 static int list_ldat(const char *filename) {
37 LDAT *ldat = ldat_open_file(filename);
38 if(!ldat) return 1;
39
40 print_ldat_catalog(ldat, verbose);
41
42 ldat_free(ldat);
43 return 0;
44 }
45
46 /* Make a new LDAT archive */
pack_ldat(const char * filename,int filec,char * filev[])47 static int pack_ldat(const char *filename,int filec, char *filev[]) {
48 const char *outputfile;
49 LDAT *ldat = ldat_create();
50
51 if(filec==0) {
52 /* No list of files specified, assume filename is a .pack file */
53 outputfile = pack_ldat_index(ldat,filename, pack_index,verbose);
54 if(outputfile==NULL)
55 return 1;
56 } else {
57 /* Pack listed files */
58 struct dllist *files=NULL;
59 int r;
60 for(r=0;r<filec;r++) {
61 struct Filename *newfile = make_file(filev[r],filev[r],0);
62 if(newfile == NULL)
63 return 1;
64 if (files)
65 dllist_append(files, newfile);
66 else
67 files = dllist_append(NULL, newfile);
68 }
69 pack_ldat_files(ldat,files,verbose);
70 outputfile = filename;
71 }
72 if(verbose)
73 printf("Saving \"%s\"...\n",outputfile);
74 if(ldat_save_file(ldat, outputfile)) {
75 fputs("Error occured while saving",stderr);
76 ldat_free(ldat);
77 return 1;
78 }
79 if(verbose)
80 printf("\tOk.\n");
81 ldat_free(ldat);
82 return 0;
83 }
84
85 /* Extract files from an LDAT archive */
extract_ldat(const char * filename,int filec,char * filev[])86 static int extract_ldat(const char *filename,int filec, char *filev[]) {
87 int rval=0;
88 if(filec==0) {
89 /* No list of files specified, assume filename is a .pack file */
90 if(unpack_ldat_index(filename, verbose))
91 rval=1;
92 } else {
93 /* Unpack listed files */
94 LDAT *ldat = ldat_open_file(filename);
95 if(ldat==NULL) {
96 rval=1;
97 } else {
98 struct dllist *files=NULL;
99 int r;
100 for(r=0;r<filec;r++) {
101 struct Filename file;
102 strcpy(file.filename,filev[r]);
103 strcpy(file.id,filev[r]);
104 file.index = 0;
105 if(r+1<filec) {
106 char *endptr=NULL;
107 int tmpi = strtol(filev[r+1],&endptr,10);
108 if(endptr==NULL) {
109 file.index=tmpi;
110 r++;
111 }
112 }
113 if(unpack_ldat_file(ldat,&file,verbose)) {
114 rval=1;
115 break;
116 }
117 }
118 ldat_free(ldat);
119 }
120 }
121
122 return rval;
123 }
124
set_mode(Mode mode)125 static void set_mode(Mode mode) {
126 if(ldat_mode!=MODE_UNSET) {
127 fputs("Use only one of -l, -p or -x\n",stderr);
128 exit(1);
129 }
130 ldat_mode = mode;
131 }
132
main(int argc,char * argv[])133 int main(int argc, char *argv[]) {
134 const char *ldatfile;
135 int c=0,rval;
136 if(argc==1) {
137 puts("Luola Datafile tool");
138 puts("Usage: ldat <options> [files...]\nOptions:");
139 puts("\t-h, --help Show this help");
140 puts("\t-l, --list <ldat> List the contents of an archive");
141 puts("\t-p, --pack <ldat/pack> Pack files into an archive");
142 puts("\t-x, --extract <ldat/pack> Extract files from an archive");
143 puts("\t-I, --noindex Do not automatically insert index file");
144 puts("\t-v, --verbose Print extra information");
145 exit(0);
146 }
147
148 while(c!=-1) {
149 static struct option options[] = {
150 {"list", required_argument, 0, 'l'},
151 {"pack", required_argument, 0, 'p'},
152 {"extract", required_argument, 0, 'x'},
153 {"index", no_argument, 0, 'i'},
154 {"noindex",no_argument, 0, 'I'},
155 {0,0,0,0}};
156 int option_index = 0;
157
158 c = getopt_long(argc,argv,"l:p:x:Iv", options, &option_index);
159 switch(c) {
160 case 'l': set_mode(LIST); ldatfile=optarg; break;
161 case 'p': set_mode(PACK); ldatfile=optarg; break;
162 case 'x': set_mode(EXTRACT); ldatfile=optarg; break;
163 case 'I': pack_index = 0; break;
164 case 'v': verbose = 1; break;
165 case '?': exit(1);
166 }
167 }
168
169 switch(ldat_mode) {
170 case MODE_UNSET:
171 fputs("No action selected\n",stderr);
172 rval=1;
173 break;
174 case LIST:
175 rval=list_ldat(ldatfile);
176 break;
177 case PACK:
178 rval=pack_ldat(ldatfile,argc-optind,argv+optind);
179 break;
180 case EXTRACT:
181 rval=extract_ldat(ldatfile,argc-optind,argv+optind);
182 break;
183 }
184
185 return rval;
186 }
187
188