1 /*
2 
3   G N O K I I
4 
5   A Linux/Unix toolset and driver for the mobile phones.
6 
7   This file is part of gnokii.
8 
9   Gnokii 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   Gnokii 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 gnokii; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 
23   Copyright (C) 1999-2000  Hugh Blemings & Pavel Janik ml.
24   Copyright (C) 1999-2000  Gary Reuter, Reinhold Jordan
25   Copyright (C) 1999-2011  Pawel Kot
26   Copyright (C) 2000-2002  Marcin Wiacek, Chris Kemp, Manfred Jonsson
27   Copyright (C) 2001       Marian Jancar, Bartek Klepacz
28   Copyright (C) 2001-2002  Pavel Machek, Markus Plail
29   Copyright (C) 2002       Ladis Michl, Simon Huggins
30   Copyright (C) 2002-2004  BORBELY Zoltan
31   Copyright (C) 2003       Bertrik Sikken
32   Copyright (C) 2004       Martin Goldhahn
33 
34   Mainline code for gnokii utility. File handling functions.
35 
36 */
37 
38 #include "config.h"
39 #include "misc.h"
40 #include "compat.h"
41 
42 #include <stdio.h>
43 #ifndef _GNU_SOURCE
44 #  define _GNU_SOURCE 1
45 #endif
46 #include <getopt.h>
47 
48 #include "gnokii-app.h"
49 #include "gnokii.h"
50 
file_usage(FILE * f)51 void file_usage(FILE *f)
52 {
53 	fprintf(f, _("File options:\n"
54 		     "          --getfilelist remote_path\n"
55 		     "          --getfiledetailsbyid [id]\n"
56 		     "          --getfileid remote_filename\n"
57 		     "          --getfile remote_filename [local_filename]\n"
58 		     "          --getfilebyid id [local_filename]\n"
59 		     "          --getallfiles remote_path\n"
60 		     "          --putfile local_filename remote_filename\n"
61 		     "          --deletefile remote_filename\n"
62 		     "          --deletefilebyid id\n"
63 		));
64 }
65 
set_fileid(gn_file * fi,char * arg)66 static void set_fileid(gn_file *fi, char *arg)
67 {
68 	unsigned long j, index, len = 1;
69 	index = j = atol(arg);
70 	while (j > 255) {
71 		len++;
72 		j /= 256;
73 	}
74 	if (len % 2)
75 		len++;
76 	fi->id = calloc(len + 1, sizeof(char));
77 	fi->id[0] = len;
78 	for (j = len; j > 0; j--) {
79 		fi->id[j] = index % 256;
80 		index = (index >> 8);
81 	}
82 }
83 
84 /* Get file list. */
getfilelist(char * path,gn_data * data,struct gn_statemachine * state)85 gn_error getfilelist(char *path, gn_data *data, struct gn_statemachine *state)
86 {
87     	gn_file_list fi;
88 	gn_error error;
89 	int i;
90 
91 	memset(&fi, 0, sizeof(fi));
92 	snprintf(fi.path, sizeof(fi.path), "%s", path);
93 
94 	gn_data_clear(data);
95 	data->file_list = &fi;
96 
97 	if ((error = gn_sm_functions(GN_OP_GetFileList, data, state)) != GN_ERR_NONE)
98 		fprintf(stderr, _("Failed to get info for %s: %s\n"), path, gn_error_print(error));
99 	else {
100 		fprintf(stdout, _("Filelist for path %s:\n"), path);
101 		for (i = 0; i < fi.file_count; i++) {
102 			fprintf(stdout, _("  %s\n"), fi.files[i]->name);
103 			free(fi.files[i]);
104 		}
105 	}
106 	return error;
107 }
108 
getfiledetailsbyid(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)109 gn_error getfiledetailsbyid(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
110 {
111     	gn_file fi;
112     	gn_file_list fil;
113 	gn_error error;
114 	int i;
115 
116 	memset(&fi, 0, sizeof(fi));
117 	memset(&fil, 0, sizeof(fil));
118 
119 	gn_data_clear(data);
120 	data->file = &fi;
121 	data->file_list = &fil;
122 	/* default parameter is root == 0x01 */
123 	if (argc == optind) {
124 		fi.id = calloc(3, sizeof(char));
125 		if (!fi.id)
126 			return GN_ERR_INTERNALERROR;
127 		fi.id[0] = 2;
128 		fi.id[1] = 0x00;
129 		fi.id[2] = 0x01;
130 	} else {
131 		set_fileid(&fi, argv[optind]);
132 	}
133 
134 	if ((error = gn_sm_functions(GN_OP_GetFileDetailsById, data, state)) != GN_ERR_NONE)
135 		fprintf(stderr, _("Failed to get filename: %s\n"), gn_error_print(error));
136 	else {
137 		int fileid = 0, counter = 16;
138 		for (i = fi.id[0]; i > 0; i--) {
139 			fileid += fi.id[i] * (counter / 16);
140 			counter *= 16;
141 		}
142 		fprintf(stdout, _("| %s (%d)\n"), fi.name, fileid);
143 		for (i = 0; i < fil.file_count; i++) {
144 			int j;
145 		    	gn_file fi2;
146 		    	gn_file_list fil2;
147 			gn_error error2;
148 
149 			dprintf("getting %s\n", fil.files[i]->id);
150 			memset(&fi2, 0, sizeof(fi2));
151 			memset(&fil2, 0, sizeof(fil2));
152 
153 			gn_data_clear(data);
154 			data->file = &fi2;
155 			data->file_list = &fil2;
156 			fi2.id = fil.files[i]->id;
157 
158 			error2 = gn_sm_functions(GN_OP_GetFileDetailsById, data, state);
159 			switch (error2) {
160 			case GN_ERR_NONE:
161 				fileid = 0;
162 				counter = 16;
163 				for (j = fi2.id[0]; j > 0; j--) {
164 					fileid += fi2.id[j] * (counter / 16);
165 					counter *= 16;
166 				}
167 				fprintf(stdout, _(" - %s (%d)\n"), fi2.name, fileid);
168 				break;
169 			default:
170 				fprintf(stderr, _("Failed to get filename: %s\n"), gn_error_print(error));
171 				break;
172 			}
173 		}
174 	}
175 	free(fi.id);
176 	return error;
177 }
178 
179 /* Get file id */
getfileid(char * filename,gn_data * data,struct gn_statemachine * state)180 gn_error getfileid(char *filename, gn_data *data, struct gn_statemachine *state)
181 {
182     	gn_file fi;
183 	gn_error error;
184 
185 	memset(&fi, 0, sizeof(fi));
186 	snprintf(fi.name, 512, "%s", filename);
187 
188 	gn_data_clear(data);
189 	data->file = &fi;
190 
191 	if ((error = gn_sm_functions(GN_OP_GetFileId, data, state)) != GN_ERR_NONE)
192 		fprintf(stderr, _("Failed to get info for %s: %s\n"),filename, gn_error_print(error));
193 	else {
194 		fprintf(stdout, _("Fileid for file %s is %02x %02x %02x %02x %02x %02x\n"), filename, fi.id[0], fi.id[1], fi.id[2], fi.id[3], fi.id[4], fi.id[5]);
195 	}
196 	return error;
197 }
198 
199 /* Delete file */
deletefile(char * filename,gn_data * data,struct gn_statemachine * state)200 gn_error deletefile(char *filename, gn_data *data, struct gn_statemachine *state)
201 {
202     	gn_file fi;
203 	gn_error error;
204 
205 	memset(&fi, 0, sizeof(fi));
206 	snprintf(fi.name, 512, "%s", filename);
207 
208 	gn_data_clear(data);
209 	data->file = &fi;
210 
211 	if ((error = gn_sm_functions(GN_OP_DeleteFile, data, state)) != GN_ERR_NONE)
212 		fprintf(stderr, _("Failed to delete %s: %s\n"), filename, gn_error_print(error));
213 	else {
214 		fprintf(stderr, _("Deleted: %s\n"), filename);
215 	}
216 	return error;
217 }
218 
219 /* Delete file */
deletefilebyid(char * id,gn_data * data,struct gn_statemachine * state)220 gn_error deletefilebyid(char *id, gn_data *data, struct gn_statemachine *state)
221 {
222     	gn_file fi;
223 	gn_error error;
224 
225 	memset(&fi, 0, sizeof(fi));
226 	set_fileid(&fi, id);
227 
228 	gn_data_clear(data);
229 	data->file = &fi;
230 
231 	if ((error = gn_sm_functions(GN_OP_DeleteFileById, data, state)) != GN_ERR_NONE)
232 		fprintf(stderr, _("Failed to delete %s: %s\n"), id, gn_error_print(error));
233 	else {
234 		fprintf(stderr, _("Deleted: %s\n"), id);
235 	}
236 	return error;
237 }
238 
getfile_usage(FILE * f,int exitval)239 int getfile_usage(FILE *f, int exitval)
240 {
241 	fprintf(f, _(" usage: --getfile remote_filename [localfilename]\n"));
242 	return exitval;
243 }
244 
245 /* Get file */
getfile(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)246 gn_error getfile(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
247 {
248     	gn_file fi;
249 	gn_error error;
250 	FILE *f;
251 	char filename2[512];
252 
253 	if (argc < optind)
254 		return getfile_usage(stderr, -1);
255 
256 	memset(filename2, 0, 512);
257 	memset(&fi, 0, sizeof(fi));
258 	snprintf(fi.name, 512, "%s", optarg);
259 
260 	gn_data_clear(data);
261 	data->file = &fi;
262 
263 	data->progress_indication = NULL;
264 
265 	if ((error = gn_sm_functions(GN_OP_GetFile, data, state)) != GN_ERR_NONE)
266 		fprintf(stderr, _("Failed to get file %s: %s\n"), optarg, gn_error_print(error));
267 	else {
268 		if (argc == optind) {
269 			if (strrchr(optarg, '/'))
270 				snprintf(filename2, sizeof(filename2), "%s", strrchr(optarg, '/') + 1);
271 			else if (strrchr(optarg, '\\'))
272 				snprintf(filename2, sizeof(filename2), "%s", strrchr(optarg, '\\') + 1);
273 			else
274 				snprintf(filename2, sizeof(filename2), "default.dat");
275 			fprintf(stdout, _("Got file %s.  Save to [%s]: "), optarg, filename2);
276 			gn_line_get(stdin, filename2, 512);
277 			if (filename2[0] == 0) {
278 				if (strrchr(optarg, '/'))
279 					snprintf(filename2, sizeof(filename2), "%s", strrchr(optarg, '/') + 1);
280 				else if (strrchr(optarg, '\\'))
281 					snprintf(filename2, sizeof(filename2), "%s", strrchr(optarg, '\\') + 1);
282 				else
283 					snprintf(filename2, sizeof(filename2), "default.dat");
284 			}
285 		} else {
286 			snprintf(filename2, sizeof(filename2), "%s", argv[optind]);
287 		}
288 		f = fopen(filename2, "w");
289 		if (!f) {
290 			fprintf(stderr, _("Can't open file %s for writing!\n"), filename2);
291 			return GN_ERR_FAILED;
292 		}
293 		if (fwrite(fi.file, fi.file_length, 1, f) < 0) {
294 			fprintf(stderr, _("Failed to write to file %s.\n"), filename2);
295 			error = GN_ERR_FAILED;
296 		}
297 		fclose(f);
298 		free(fi.file);
299 	}
300 	return error;
301 }
302 
getfilebyid_usage(FILE * f,int exitval)303 int getfilebyid_usage(FILE *f, int exitval)
304 {
305 	fprintf(f, _(" usage: --getfilebyid id [localfilename]\n"));
306 	return exitval;
307 }
308 
309 /* Get file */
getfilebyid(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)310 gn_error getfilebyid(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
311 {
312     	gn_file fi;
313     	gn_file_list fil;
314 	gn_error error;
315 	FILE *f;
316 	char filename2[512];
317 
318 	if (argc < optind)
319 		return getfilebyid_usage(stderr, -1);
320 
321 	memset(filename2, 0, 512);
322 	memset(&fi, 0, sizeof(fi));
323 	set_fileid(&fi, optarg);
324 
325 	gn_data_clear(data);
326 	data->file = &fi;
327 	data->file_list = &fil;
328 
329 	data->progress_indication = NULL;
330 
331 	if ((error = gn_sm_functions(GN_OP_GetFileDetailsById, data, state)) != GN_ERR_NONE)
332 		fprintf(stderr, _("Failed to get file: %s\n"), gn_error_print(error));
333 	else {
334 		dprintf("File is %s\n", fi.name);
335 		fi.file = malloc(fi.file_length);
336 		error = gn_sm_functions(GN_OP_GetFileById, data, state);
337 		if (error == GN_ERR_NONE) {
338 			if (argc == optind) {
339 				snprintf(filename2, sizeof(filename2), "%s", fi.name);
340 			} else {
341 				snprintf(filename2, sizeof(filename2), "%s", argv[optind]);
342 			}
343 			f = fopen(filename2, "w");
344 			if (!f) {
345 				fprintf(stderr, _("Can't open file %s for writing!\n"), filename2);
346 				return GN_ERR_FAILED;
347 			}
348 			if (fwrite(fi.file, fi.file_length, 1, f) < 0) {
349 				fprintf(stderr, _("Failed to write to file %s.\n"), filename2);
350 				error = GN_ERR_FAILED;
351 			}
352 			fclose(f);
353 			free(fi.file);
354 		} else {
355 			fprintf(stderr, "%s\n", gn_error_print(error));
356 		}
357 	}
358 	return error;
359 }
360 
361 /* Get all files */
getallfiles(char * path,gn_data * data,struct gn_statemachine * state)362 gn_error getallfiles(char *path, gn_data *data, struct gn_statemachine *state)
363 {
364     	gn_file_list fi;
365 	gn_error error;
366 	int i;
367 	FILE *f;
368 	char filename2[512];
369 
370 	memset(&fi, 0, sizeof(fi));
371 	snprintf(fi.path, sizeof(fi.path), "%s", path);
372 
373 	gn_data_clear(data);
374 	data->file_list = &fi;
375 
376 	if ((error = gn_sm_functions(GN_OP_GetFileList, data, state)) != GN_ERR_NONE)
377 		fprintf(stderr, _("Failed to get info for %s: %s\n"), path, gn_error_print(error));
378 	else {
379 		char *pos = strrchr(path, '/');
380 		if (!pos)
381 			pos = strrchr(path, '\\');
382 
383 		if (pos)
384 			*(pos+1) = 0;
385 
386 		for (i = 0; i < fi.file_count; i++) {
387 			data->file = fi.files[i];
388 			snprintf(filename2, sizeof(filename2), "%s", fi.files[i]->name);
389 			snprintf(fi.files[i]->name, sizeof(fi.files[i]->name), "%s%s", path, filename2);
390 			if ((error = gn_sm_functions(GN_OP_GetFile, data, state)) != GN_ERR_NONE)
391 				fprintf(stderr, _("Failed to get file %s: %s\n"), data->file->name, gn_error_print(error));
392 			else {
393 				fprintf(stderr, _("Got file %s.\n"), filename2);
394 				f = fopen(filename2, "w");
395 				if (!f) {
396 					fprintf(stderr, _("Can't open file %s for writing!\n"), filename2);
397 					return GN_ERR_FAILED;
398 				}
399 				if (fwrite(data->file->file, data->file->file_length, 1, f) < 0) {
400 					fprintf(stderr, _("Failed to write to file %s.\n"), filename2);
401 					fclose(f);
402 					return GN_ERR_FAILED;
403 				}
404 				fclose(f);
405 				free(data->file->file);
406 			}
407 			free(fi.files[i]);
408 		}
409 	}
410 	return error;
411 }
412 
putfile_usage(FILE * f,int exitval)413 int putfile_usage(FILE *f, int exitval)
414 {
415 	fprintf(f, _(" usage: --putfile local_filename remote_filename\n"));
416 	return exitval;
417 }
418 
419 /* Put file */
putfile(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)420 gn_error putfile(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
421 {
422 	gn_file fi;
423 	gn_error error = GN_ERR_FAILED;
424 	FILE *f;
425 
426 	if (argc != optind + 1)
427 		return putfile_usage(stderr, -1);
428 
429 	memset(&fi, 0, sizeof(fi));
430 	snprintf(fi.name, 512, "%s", argv[optind]);
431 
432 	gn_data_clear(data);
433 	data->file = &fi;
434 
435 	f = fopen(optarg, "rb");
436 	if (!f || fseek(f, 0, SEEK_END)) {
437 		fprintf(stderr, _("Can't open file %s for reading!\n"), optarg);
438  		goto err;
439 	}
440 	fi.file_length = ftell(f);
441 	rewind(f);
442 	fi.file = malloc(fi.file_length);
443 	if (fread(fi.file, 1, fi.file_length, f) != fi.file_length) {
444 		fprintf(stderr, _("File %s corrupted!\n"), optarg);
445 		goto out;
446 	}
447 
448 	if ((error = gn_sm_functions(GN_OP_PutFile, data, state)) != GN_ERR_NONE)
449 		fprintf(stderr, _("Failed to put file to %s: %s\n"), argv[optind], gn_error_print(error));
450 
451 out:
452 	free(fi.file);
453 	fclose(f);
454 
455 err:
456 	return error;
457 }
458