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