1 /*
2
3 $Id$
4
5 G N O K I I
6
7 A Linux/Unix toolset and driver for the mobile phones.
8
9 This file is part of gnokii.
10
11 Gnokii is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 Gnokii is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with gnokii; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25 Copyright (C) 1999-2000 Hugh Blemings & Pavel Janik ml.
26 Copyright (C) 1999-2000 Gary Reuter, Reinhold Jordan
27 Copyright (C) 1999-2006 Pawel Kot
28 Copyright (C) 2000-2002 Marcin Wiacek, Chris Kemp, Manfred Jonsson
29 Copyright (C) 2001 Marian Jancar, Bartek Klepacz
30 Copyright (C) 2001-2002 Pavel Machek, Markus Plail
31 Copyright (C) 2002 Ladis Michl, Simon Huggins
32 Copyright (C) 2002-2004 BORBELY Zoltan
33 Copyright (C) 2003 Bertrik Sikken
34 Copyright (C) 2004 Martin Goldhahn
35
36 Mainline code for gnokii utility. Calendar functions.
37
38 */
39
40 #include "config.h"
41 #include "misc.h"
42 #include "compat.h"
43
44 #include <stdio.h>
45 #ifndef _GNU_SOURCE
46 # define _GNU_SOURCE 1
47 #endif
48 #include <getopt.h>
49
50 #include "gnokii-app.h"
51 #include "gnokii.h"
52
calendar_usage(FILE * f)53 void calendar_usage(FILE *f)
54 {
55 fprintf(f, _(
56 "Calendar options:\n"
57 " --getcalendarnote start_number [end_number|end] [-v|--vCal]\n"
58 " --writecalendarnote vcalendarfile start_number [end_number|end]\n"
59 " --deletecalendarnote start [end_number|end]\n"
60 ));
61 }
62
getcalendarnote_usage(FILE * f,int exitval)63 int getcalendarnote_usage(FILE *f, int exitval)
64 {
65 fprintf(f, _("usage: --getcalendarnote start_number [end_number | end] [-v|--vCal]\n"
66 " start_number - entry number in the phone calendar (numeric)\n"
67 " end_number - read to this entry in the phone calendar (numeric, optional)\n"
68 " end - the string \"end\" indicates all entries from start to end\n"
69 " -v - output in iCalendar format\n"
70 " NOTE: if no end is given, only the start entry is read\n"
71 ));
72 return exitval;
73 }
74
75 /* Calendar notes receiving. */
getcalendarnote(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)76 gn_error getcalendarnote(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
77 {
78 gn_calnote_list calnotelist;
79 gn_calnote calnote;
80 gn_error error = GN_ERR_NONE;
81 int i, first_location, last_location;
82 bool vcal = false;
83
84 struct option options[] = {
85 { "vCal", optional_argument, NULL, 'v'},
86 { NULL, 0, NULL, 0}
87 };
88
89 first_location = gnokii_atoi(optarg);
90 if (errno || first_location < 0)
91 return getcalendarnote_usage(stderr, -1);
92 last_location = parse_end_value_option(argc, argv, optind, first_location);
93 if (errno || last_location < 0)
94 return getcalendarnote_usage(stderr, -1);
95
96 while ((i = getopt_long(argc, argv, "v", options, NULL)) != -1) {
97 switch (i) {
98 case 'v':
99 vcal = true;
100 break;
101 default:
102 return getcalendarnote_usage(stderr, -1);
103 }
104 }
105 if (argc > optind + 1) {
106 /* There are too many arguments that don't start with '-' */
107 return getcalendarnote_usage(stderr, -1);
108 }
109
110 for (i = first_location; i <= last_location; i++) {
111 memset(&calnote, 0, sizeof(calnote));
112 memset(&calnotelist, 0, sizeof(calnotelist));
113 calnote.location = i;
114
115 gn_data_clear(data);
116 data->calnote = &calnote;
117 data->calnote_list = &calnotelist;
118
119 error = gn_sm_functions(GN_OP_GetCalendarNote, data, state);
120
121 if (error == GN_ERR_NONE) {
122 if (vcal) {
123 char *ical;
124
125 ical = gn_calnote2icalstr(&calnote);
126 fprintf(stdout, "%s\n", ical);
127 free (ical);
128 } else { /* Plain text output */
129 /* Translators: this is the header of a calendar note. Example: 1 (1). Type: Meeting */
130 fprintf(stdout, _("%d (%d). %s: %s\n"), i, calnote.location, _("Type"), gn_calnote_type2str(calnote.type));
131
132 fprintf(stdout, _(" Start date: %d-%02d-%02d\n"), calnote.time.year,
133 calnote.time.month,
134 calnote.time.day);
135
136 if (calnote.type != GN_CALNOTE_BIRTHDAY) {
137 fprintf(stdout, _(" Start time: %02d:%02d:%02d\n"), calnote.time.hour,
138 calnote.time.minute,
139 calnote.time.second);
140
141 if (calnote.end_time.year) {
142 fprintf(stdout, _(" End date: %d-%02d-%02d\n"), calnote.end_time.year,
143 calnote.end_time.month,
144 calnote.end_time.day);
145
146 fprintf(stdout, _(" End time: %02d:%02d:%02d\n"), calnote.end_time.hour,
147 calnote.end_time.minute,
148 calnote.end_time.second);
149 }
150 }
151
152 if (calnote.alarm.enabled) {
153 if (calnote.type == GN_CALNOTE_BIRTHDAY) {
154 fprintf(stdout, _(" Alarm date: %02d-%02d\n"),
155 calnote.alarm.timestamp.month,
156 calnote.alarm.timestamp.day);
157 } else {
158 fprintf(stdout, _(" Alarm date: %d-%02d-%02d\n"),
159 calnote.alarm.timestamp.year,
160 calnote.alarm.timestamp.month,
161 calnote.alarm.timestamp.day);
162 }
163 fprintf(stdout, _(" Alarm time: %02d:%02d:%02d\n"),
164 calnote.alarm.timestamp.hour,
165 calnote.alarm.timestamp.minute,
166 calnote.alarm.timestamp.second);
167 fprintf(stdout, _(" Alarm tone %s\n"),
168 calnote.alarm.tone ? _("enabled") : _("disabled"));
169 }
170
171 fprintf(stdout, _(" %s: "), _("Repeat"));
172 switch (calnote.recurrence) {
173 case GN_CALNOTE_NEVER:
174 case GN_CALNOTE_DAILY:
175 case GN_CALNOTE_WEEKLY:
176 case GN_CALNOTE_2WEEKLY:
177 case GN_CALNOTE_MONTHLY:
178 case GN_CALNOTE_YEARLY:
179 fprintf(stdout,"%s\n", gn_calnote_recurrence2str(calnote.recurrence));
180 break;
181 default:
182 fprintf(stdout, _("Every %d hours"), calnote.recurrence);
183 break;
184 }
185
186 if (calnote.recurrence != GN_CALNOTE_NEVER) {
187 fprintf(stdout, _(" The event will be repeated "));
188 switch (calnote.occurrences) {
189 case 0:
190 fprintf(stdout, _("forever."));
191 break;
192 default:
193 fprintf(stdout, _("%d times."), calnote.occurrences);
194 break;
195 }
196 fprintf(stdout, "\n");
197 }
198
199 fprintf(stdout, _(" Text: %s\n"), calnote.text);
200
201 switch (calnote.type) {
202 case GN_CALNOTE_CALL:
203 fprintf(stdout, _(" %s: %s\n"), _("Phone"), calnote.phone_number);
204 break;
205 case GN_CALNOTE_MEETING:
206 fprintf(stdout, _(" %s: %s\n"), _("Location"), calnote.mlocation);
207 break;
208 case GN_CALNOTE_BIRTHDAY:
209 case GN_CALNOTE_REMINDER:
210 case GN_CALNOTE_MEMO:
211 /* was already printed as calnote.text above */
212 break;
213 }
214 }
215
216 } else { /* error != GN_ERR_NONE */
217 /* stop processing if the last note was specified as "end" */
218 if (last_location == INT_MAX) {
219 /* it's not an error if we read at least a note and the rest is empty */
220 if ((i > first_location) && ((error == GN_ERR_EMPTYLOCATION) || (error == GN_ERR_INVALIDLOCATION))) {
221 error = GN_ERR_NONE;
222 }
223 last_location = 0;
224 }
225 if (error != GN_ERR_NONE) {
226 fprintf(stderr, _("The calendar note can not be read: %s\n"), gn_error_print(error));
227 }
228 }
229 }
230
231 return error;
232 }
233
writecalendarnote_usage(FILE * f,int exitval)234 int writecalendarnote_usage(FILE *f, int exitval)
235 {
236 fprintf(f, _("usage: --writecalendarnote vcalendarfile start_number [end_number|end]\n"
237 " vcalendarfile - file containing calendar notes in vCal format\n"
238 " start_number - first calendar note from vcalendarfile to read\n"
239 " end_number - last calendar note from vcalendarfile to read\n"
240 " end - read all notes from vcalendarfile from start_number\n"
241 " NOTE: it stores the note at the first empty location.\n"
242 ));
243 return exitval;
244 }
245
246 /* Writing calendar notes. */
writecalendarnote(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)247 gn_error writecalendarnote(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
248 {
249 gn_calnote calnote;
250 gn_error error = GN_ERR_NONE;
251 int first_location, last_location, i;
252 FILE *f;
253
254 f = fopen(optarg, "r");
255 if (f == NULL) {
256 fprintf(stderr, _("Can't open file %s for reading!\n"), optarg);
257 return GN_ERR_FAILED;
258 }
259
260 first_location = gnokii_atoi(argv[optind]);
261 if (errno || first_location < 0) {
262 fclose(f);
263 return writecalendarnote_usage(stderr, -1);
264 }
265 last_location = parse_end_value_option(argc, argv, optind + 1, first_location);
266 if (errno || last_location < 0) {
267 fclose(f);
268 return writecalendarnote_usage(stderr, -1);
269 }
270
271 for (i = first_location; i <= last_location; i++) {
272
273 memset(&calnote, 0, sizeof(calnote));
274 gn_data_clear(data);
275 data->calnote = &calnote;
276
277 /* TODO: gn_ical2note expects the pointer to begin file to
278 * iterate. Fix it to not rewind the file each time
279 */
280 rewind(f);
281 error = gn_ical2calnote(f, &calnote, i);
282
283 #ifndef WIN32
284 if (error == GN_ERR_NOTIMPLEMENTED) {
285 switch (gn_vcal_file_event_read(optarg, &calnote, i)) {
286 case 0:
287 error = GN_ERR_NONE;
288 break;
289 default:
290 error = GN_ERR_FAILED;
291 break;
292 }
293 }
294 #endif
295 if (error != GN_ERR_NONE) {
296 /* when reading until 'end' it's not an error if it tried to read a non existant note */
297 if ((last_location == INT_MAX) && (error == GN_ERR_EMPTYLOCATION)) {
298 error = GN_ERR_NONE;
299 } else {
300 fprintf(stderr, _("Failed to load vCalendar file: %s\n"), gn_error_print(error));
301 }
302 fclose(f);
303 return error;
304 }
305
306 error = gn_sm_functions(GN_OP_WriteCalendarNote, data, state);
307
308 if (error == GN_ERR_NONE)
309 fprintf(stderr, _("Successfully written!\n"));
310 else
311 fprintf(stderr, _("Failed to write calendar note: %s\n"), gn_error_print(error));
312 }
313 fclose(f);
314
315 return error;
316 }
317
deletecalendarnote_usage(FILE * f,int exitval)318 int deletecalendarnote_usage(FILE *f, int exitval)
319 {
320 fprintf(f, _("usage: --deletecalendarnote start_number [end_number | end]\n"
321 " start_number - first number in the phone calendar (numeric)\n"
322 " end_number - until this entry in the phone calendar (numeric, optional)\n"
323 " end - the string \"end\" indicates all entries from start to end\n"
324 " NOTE: if no end is given, only the start entry is deleted\n"
325 ));
326 return exitval;
327 }
328
329 /* Calendar note deleting. */
deletecalendarnote(int argc,char * argv[],gn_data * data,struct gn_statemachine * state)330 gn_error deletecalendarnote(int argc, char *argv[], gn_data *data, struct gn_statemachine *state)
331 {
332 gn_calnote calnote;
333 gn_calnote_list clist;
334 int i, first_location, last_location;
335 gn_error error = GN_ERR_NONE;
336
337 gn_data_clear(data);
338 memset(&calnote, 0, sizeof(gn_calnote));
339 data->calnote = &calnote;
340 memset(&clist, 0, sizeof(gn_calnote_list));
341 data->calnote_list = &clist;
342
343 first_location = gnokii_atoi(optarg);
344 if (errno || first_location < 0)
345 return deletecalendarnote_usage(stderr, -1);
346 last_location = parse_end_value_option(argc, argv, optind, first_location);
347 if (errno || last_location < 0)
348 return deletecalendarnote_usage(stderr, -1);
349
350 for (i = first_location; i <= last_location; i++) {
351 calnote.location = i;
352
353 error = gn_sm_functions(GN_OP_DeleteCalendarNote, data, state);
354 if (error == GN_ERR_NONE)
355 fprintf(stderr, _("Calendar note deleted.\n"));
356 else {
357 fprintf(stderr, _("The calendar note cannot be deleted: %s\n"), gn_error_print(error));
358 if (last_location == INT_MAX)
359 last_location = 0;
360 }
361 }
362
363 return error;
364 }
365