~ubuntu-branches/ubuntu/karmic/pilot-link/karmic

« back to all changes in this revision

Viewing changes to src/memos.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Rousseau
  • Date: 2006-09-22 11:51:36 UTC
  • mfrom: (3.1.8 edgy)
  • Revision ID: james.westby@ubuntu.com-20060922115136-qqmy17bx8j5x0y72
Tags: 0.12.1-5
* urgency medium since libpisock-dev was not usable to build any package
* libpisock-dev now depends on libusb-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * memos.c:  Translate Palm Memos into e-mail format
3
 
 *
4
 
 * Copyright (c) 1996, Kenneth Albanowski
5
 
 * 
6
 
 * This program is free software; you can redistribute it and/or modify it
7
 
 * under the terms of the GNU General Public License as published by the
8
 
 * Free Software Foundation; either version 2 of the License, or (at your
9
 
 * option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful, but
12
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
14
 
 * Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License along
17
 
 * with this program; if not, write to the Free Software Foundation, Inc.,
18
 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
 
 *
20
 
 */
21
 
 
22
 
#include "getopt.h"
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <string.h>
26
 
#include <time.h>
27
 
#include <sys/stat.h>
28
 
#include <regex.h>
29
 
 
30
 
#include "pi-source.h"
31
 
#include "pi-socket.h"
32
 
#include "pi-memo.h"
33
 
#include "pi-dlp.h"
34
 
#include "pi-file.h"
35
 
#include "pi-header.h"
36
 
 
37
 
/* constants to determine how to produce memos */
38
 
#define MEMO_MBOX_STDOUT 0
39
 
#define MEMO_DIRECTORY 1
40
 
#define MAXDIRNAMELEN 1024
41
 
 
42
 
int verbose = 0;
43
 
char *progname;
44
 
 
45
 
/* Declare prototypes */
46
 
static void display_help(char *progname);
47
 
void print_splash(char *progname);
48
 
int pilot_connect(char *port);
49
 
 
50
 
struct option options[] = {
51
 
        {"help",        no_argument,       NULL, 'h'},
52
 
        {"version",     no_argument,       NULL, 'v'},
53
 
        {"port",        required_argument, NULL, 'p'},
54
 
        {"verbose",     no_argument,       NULL, 'V'},
55
 
        {"delete",      required_argument, NULL, 'd'},
56
 
        {"file",        required_argument, NULL, 'f'},
57
 
        {"save",        required_argument, NULL, 's'},
58
 
        {"category",    required_argument, NULL, 'c'},
59
 
        {"regex",       required_argument, NULL, 'r'},
60
 
        {NULL,          0,                 NULL, 0}
61
 
};
62
 
 
63
 
static const char *optstring = "p:hvVd:f:s:c:r:";
64
 
 
65
 
void write_memo_mbox(struct Memo m, struct MemoAppInfo mai, int category);
66
 
void write_memo_in_directory(char *dirname, struct Memo m,
67
 
                             struct MemoAppInfo mai, int category,
68
 
                             int verbose);
69
 
 
70
 
/***********************************************************************
71
 
 *
72
 
 * Function:    write_memo_mbox
73
 
 *
74
 
 * Summary:     Write a memo entry to MailDB database
75
 
 *
76
 
 * Parameters:  None
77
 
 *
78
 
 * Returns:     Nothing
79
 
 *
80
 
 ***********************************************************************/
81
 
void write_memo_mbox(struct Memo m, struct MemoAppInfo mai, int category)
82
 
{
83
 
        int     j;
84
 
        time_t  now;
85
 
        char    *time_str;
86
 
        
87
 
        now = time( NULL );
88
 
 
89
 
        /* FIXME: might be good to get the time stamp of the memo file for
90
 
         * the "Received" line */
91
 
 
92
 
        time_str = ctime(&now); 
93
 
 
94
 
        printf("From: MemoDB@Palm.Handheld via pilot-link/memos\n"
95
 
               "Received: %s" 
96
 
               "To: Your Machine\n"
97
 
               "Date: %s"
98
 
               "Subject: ", time_str, time_str ); 
99
 
 
100
 
        /* print category name in brackets in subject field */
101
 
        printf("[%s] ", mai.category.name[category]);
102
 
 
103
 
        /* print (at least part of) first line as part of subject: */
104
 
        for (j = 0; j < 40; j++) {
105
 
                if ((!m.text[j]) || (m.text[j] == '\n'))
106
 
                        break;
107
 
                printf("%c", m.text[j]);
108
 
        }
109
 
        if (j == 40)
110
 
                printf("...\n");
111
 
        else
112
 
                printf("\n");
113
 
        printf("\n");
114
 
        puts(m.text);
115
 
}
116
 
 
117
 
/***********************************************************************
118
 
 *
119
 
 * Function:    write_memo_in_directory
120
 
 *
121
 
 * Summary:     Writes each memo into /$DIR/$CATEGORY/$FILENAME form
122
 
 *              after the user specifies the -d /dir/name argument  
123
 
 *
124
 
 * Parameters:  None
125
 
 *
126
 
 * Returns:     Nothing
127
 
 *
128
 
 ***********************************************************************/
129
 
void
130
 
write_memo_in_directory(char *dirname, struct Memo m,
131
 
                        struct MemoAppInfo mai, int category, int verbose)
132
 
{
133
 
        int     j;
134
 
        char    pathbuffer[MAXDIRNAMELEN + (128 * 3)] = "",
135
 
                tmp[5] = "";
136
 
        FILE *fd;
137
 
 
138
 
        /* Should check if dirname exists and is a directory */
139
 
        mkdir(dirname, 0700);
140
 
 
141
 
        /* Create a directory for the category */
142
 
        strncat(pathbuffer, dirname, MAXDIRNAMELEN);
143
 
        strncat(pathbuffer, "/", 1);
144
 
 
145
 
        /* Should make sure category doesn't have slashes in it */
146
 
        strncat(pathbuffer, mai.category.name[category], 60);
147
 
 
148
 
        /* Should check if there were problems creating directory */
149
 
        /* open the actual file to write */
150
 
        strncat(pathbuffer, "/", 1);
151
 
        for (j = 0; j < 40; j++) {
152
 
                if ((!m.text[j]) || (m.text[j] == '\n'))
153
 
                        break;
154
 
                if (m.text[j] == '/') {
155
 
                        strncat(pathbuffer, "=2F", 3);
156
 
                        continue;
157
 
                }
158
 
                if (m.text[j] == '=') {
159
 
                        strncat(pathbuffer, "=3D", 3);
160
 
                        continue;
161
 
                }
162
 
#ifdef OS2
163
 
                if (m.text[j] == ':') {
164
 
                        strncat(pathbuffer, "=3A", 3);
165
 
                        continue;
166
 
                }
167
 
#endif
168
 
                /* escape if it's an ISO8859 control chcter (note: some
169
 
                   are printable on the Palm) */
170
 
                if ((m.text[j] | 0x7f) < ' ') {
171
 
                        tmp[0] = '\0';
172
 
                        sprintf(tmp, "=%2X", (unsigned char) m.text[j]);
173
 
                } else {
174
 
                        tmp[0] = m.text[j];
175
 
                        tmp[1] = '\0';
176
 
                }
177
 
                strcat(pathbuffer, tmp);
178
 
        }
179
 
 
180
 
        if (verbose) {
181
 
                printf("Writing %s\n", pathbuffer);
182
 
        }
183
 
 
184
 
        if (!(fd = fopen(pathbuffer, "w"))) {
185
 
                printf("%s: can't open file \"%s\" for writing\n",
186
 
                        progname, pathbuffer);
187
 
                exit(1);
188
 
        }
189
 
        fputs(m.text, fd);
190
 
        fclose(fd);
191
 
}
192
 
 
193
 
/***********************************************************************
194
 
 *
195
 
 * Function:    display_help
196
 
 *
197
 
 * Summary:     Outputs the program arguments and params
198
 
 *
199
 
 * Parameters:  None
200
 
 *
201
 
 * Returns:     Nothing
202
 
 *
203
 
 ***********************************************************************/
204
 
static void display_help(char *progname)
205
 
{
206
 
        printf("   Manipulate MemoDB.pdb entries from a file or your Palm device\n\n");
207
 
        printf("   Usage: memos -p <port> [-V] [options]\n\n");
208
 
        printf("   Options:\n");
209
 
        printf("     -p, --port <port>       Use device file <port> to communicate with Palm\n");
210
 
        printf("     -h, --help              Display help information for %s\n", progname);
211
 
        printf("     -v, --version           Display %s version information\n", progname);
212
 
        printf("     -V, --verbose           Verbose, with -d, print each filename when\n");
213
 
        printf("                             written\n");
214
 
        printf("     -d, --delete            Delete memo named by number <num>\n");
215
 
        printf("     -f, --file [file] ..    Use <file> as input file (instead of MemoDB.pdb)\n");
216
 
        printf("     -s, --save <dir>        Save memos in <dir> instead of writing to\n");
217
 
        printf("                             STDOUT\n");
218
 
        printf("     -c, --category <cat>    Only upload memos in this category\n");
219
 
        printf("     -r, --regex [regexp]    Select memos saved by regular expression on\n");
220
 
        printf("                             title\n\n");
221
 
 
222
 
        printf("   By default, the contents of your Palm's memo database will be written to\n");
223
 
        printf("   standard output as a standard Unix mailbox (mbox-format) file, with each\n");
224
 
        printf("   memo as a separate message.  The subject of each message will be the\n");
225
 
        printf("   category.\n\n");
226
 
 
227
 
        printf("   If '-s' is specified, than instead of being written to standard output,\n");
228
 
        printf("   will be saved in subdirectories of <dir>. Each subdirectory will be the\n");
229
 
        printf("   name of a category on the Palm, and will contain the memos in that\n");
230
 
        printf("   category. Each memo's filename will be the first line (up to the first 40\n");
231
 
        printf("   chcters) of the memo. Control chcters, slashes, and equal signs that\n");
232
 
        printf("   would otherwise appear in filenames are converted after the fashion of\n");
233
 
        printf("   MIME's quoted-printable encoding. Note that if you have two memos in the\n");
234
 
        printf("   same category whose first lines are identical, one of them will be\n");
235
 
        printf("   overwritten.\n\n");
236
 
 
237
 
        printf("   If '-f' is specified, the specified file will be treated as a memo\n");
238
 
        printf("   database from which to read memos, rather than HotSyncing from the Palm.\n\n");
239
 
 
240
 
        return;
241
 
}
242
 
 
243
 
int main(int argc, char *argv[])
244
 
{
245
 
        int     attr, 
246
 
                c,              /* switch */
247
 
                category,
248
 
                db,
249
 
                index,
250
 
                len,
251
 
                ret,
252
 
                sd              = -1,
253
 
                verbose         = 0,
254
 
                delete          = 0,
255
 
                mode            = MEMO_MBOX_STDOUT,
256
 
                bufsize         = 1024,
257
 
                match_category  = -1,
258
 
                title_matching  = 0;
259
 
 
260
 
        unsigned char   buffer[0xffff];
261
 
        
262
 
        char    appblock[0xffff],
263
 
                dirname[MAXDIRNAMELEN] = "",
264
 
                *buf            = NULL,
265
 
                *progname       = argv[0],
266
 
                *port           = NULL,
267
 
                category_name[MAXDIRNAMELEN + 1] = "",
268
 
                filename[MAXDIRNAMELEN + 1], *ptr;
269
 
        
270
 
        struct  MemoAppInfo mai;
271
 
        struct  pi_file *pif = NULL;
272
 
        struct  Memo m;
273
 
 
274
 
        regex_t title_pattern;
275
 
        recordid_t id;
276
 
 
277
 
        while ((c = getopt_long(argc, argv, optstring, options, NULL)) != -1) {
278
 
                switch (c) {
279
 
 
280
 
                case 'h':
281
 
                        display_help(progname);
282
 
                        return 0;
283
 
                case 'v':
284
 
                        print_splash(progname);
285
 
                        return 0;
286
 
                case 'd':
287
 
                        delete = 1;
288
 
                        break;
289
 
                case 'p':
290
 
                        port = optarg;
291
 
                        break;
292
 
                case 'f':
293
 
                        strncpy(filename, optarg, MAXDIRNAMELEN);
294
 
                        filename[MAXDIRNAMELEN] = '\0';
295
 
                        break;
296
 
                case 's':
297
 
                        strncpy(dirname, optarg, sizeof(dirname));
298
 
                        mode = MEMO_DIRECTORY;
299
 
                        break;
300
 
                case 'c':
301
 
                        strncpy(category_name, optarg, MAXDIRNAMELEN);
302
 
                        category_name[strlen( category_name )] = '\0';
303
 
                        break;
304
 
                case 'r':
305
 
                        ret = regcomp(&title_pattern, optarg, REG_NOSUB);
306
 
                        buf = (char *) malloc(bufsize);
307
 
                        if (ret) {
308
 
                                regerror(ret, &title_pattern, buf,
309
 
                                        bufsize);
310
 
                                printf("%s\n", buf);
311
 
                                exit(1);
312
 
                        }
313
 
                        title_matching = 1;
314
 
                        break;
315
 
                default:
316
 
                        display_help(progname);
317
 
                        return 0;
318
 
                }
319
 
        }
320
 
 
321
 
        /* FIXME - Need to add tests here for port/filename, clean this. -DD */
322
 
        if (filename[0] == '\0') {
323
 
        
324
 
                sd = pilot_connect(port);
325
 
 
326
 
                if (sd < 0)
327
 
                        goto error;
328
 
 
329
 
                if (dlp_OpenConduit(sd) < 0)
330
 
                        goto error_close;
331
 
 
332
 
                /* Open the Memo Pad's database, store access handle in db */
333
 
                if (dlp_OpenDB(sd, 0, 0x80 | 0x40, "MemoDB", &db) < 0) {
334
 
                        printf("Unable to open MemoDB.\n");
335
 
                        dlp_AddSyncLogEntry(sd,
336
 
                                            "Unable to open MemoDB.\n");
337
 
                        exit(1);
338
 
                }
339
 
        
340
 
                dlp_ReadAppBlock(sd, db, 0, (unsigned char *) appblock,
341
 
                                 0xffff);
342
 
        } else {
343
 
                int len;
344
 
 
345
 
                pif = pi_file_open(filename);
346
 
                if (!pif) {
347
 
                        perror("pi_file_open");
348
 
                        exit(1);
349
 
                }
350
 
 
351
 
                ret = pi_file_get_app_info(pif, (void *) &ptr, &len);
352
 
                if (ret == -1) {
353
 
                        perror("pi_file_get_app_info");
354
 
                        exit(1);
355
 
                }
356
 
 
357
 
                memcpy(appblock, ptr, len);
358
 
        }
359
 
 
360
 
        unpack_MemoAppInfo(&mai, (unsigned char *) appblock, 0xffff);
361
 
 
362
 
        if (category_name[0] != '\0') {
363
 
                for (index = 0, match_category = -1; index < 16; index += 1) {
364
 
                        if ((strlen(mai.category.name[index]) > 0)
365
 
                            && (strcmp(mai.category.name[index], category_name)
366
 
                                == 0))
367
 
                                match_category = index;
368
 
                }
369
 
                if (match_category < 0) {
370
 
                        printf("Can't find specified Memo category \"%s\".\n",
371
 
                                category_name);
372
 
                        dlp_AddSyncLogEntry(sd,
373
 
                                "Can't find specified memo category.\n");
374
 
                        exit(1);
375
 
                };
376
 
        }
377
 
 
378
 
        for (index = 0;; index++) {
379
 
 
380
 
                if (filename[0] == '\0') {
381
 
                        if (match_category >= 0) {
382
 
                                len = dlp_ReadNextRecInCategory(sd, db,
383
 
                                                                match_category,
384
 
                                                                buffer, &id,
385
 
                                                                0, 0,
386
 
                                                                &attr);
387
 
                                category = match_category;
388
 
                        } else {
389
 
                                len = dlp_ReadRecordByIndex(sd, db, index,
390
 
                                                            buffer, &id, 0,
391
 
                                                            &attr,
392
 
                                                            &category);
393
 
                        }
394
 
                        if (len < 0)
395
 
                                break;
396
 
                } else {
397
 
                        if (pi_file_read_record
398
 
                            (pif, index, (void *) &ptr, &len, &attr, &category,
399
 
                             0))
400
 
                                break;
401
 
                        memcpy(buffer, ptr, len);
402
 
                }
403
 
 
404
 
                /* Skip deleted records */
405
 
                if ((attr & dlpRecAttrDeleted)
406
 
                    || (attr & dlpRecAttrArchived))
407
 
                        continue;
408
 
 
409
 
                /* Skip memos whose category doesn't match */
410
 
                if( match_category >= 0 ) {
411
 
                        if( match_category != category )
412
 
                                continue;
413
 
                } 
414
 
 
415
 
                unpack_Memo(&m, buffer, len);
416
 
 
417
 
                /* Skip memos whose title does not match with the query */
418
 
                if (title_matching) {
419
 
                        for (len = 0; m.text[len] && m.text[len] != '\n';
420
 
                             len++);
421
 
                        if (bufsize < len + 1)
422
 
                                buf = (char *) realloc(buf, len + 1);
423
 
                        strncpy(buf, m.text, len);
424
 
                        buf[len] = '\0';
425
 
                        if (regexec(&title_pattern, buf, 0, NULL, 0) ==
426
 
                            REG_NOMATCH)
427
 
                                continue;
428
 
                }
429
 
 
430
 
                switch (mode) {
431
 
                  case MEMO_MBOX_STDOUT:
432
 
                          write_memo_mbox(m, mai, category);
433
 
                          break;
434
 
                  case MEMO_DIRECTORY:
435
 
                          write_memo_in_directory(dirname, m, mai,
436
 
                                                  category, verbose);
437
 
                          break;
438
 
                }
439
 
        }
440
 
 
441
 
        if (delete && (filename[0] == '\0')) {
442
 
                if (verbose)
443
 
                        printf("Deleting record %d.\n", (int) id);
444
 
                dlp_DeleteRecord(sd, db, 0, id);
445
 
        }
446
 
 
447
 
        if (title_matching) {
448
 
                regfree(&title_pattern);
449
 
                free(buf);
450
 
        }
451
 
 
452
 
        if (filename[0] == '\0') {
453
 
                /* Close the database */
454
 
                dlp_CloseDB(sd, db);
455
 
                dlp_AddSyncLogEntry(sd, "Successfully read memos from Palm.\n"
456
 
                                        "Thank you for using pilot-link.\n");
457
 
                pi_close(sd);
458
 
        } else {
459
 
                pi_file_close(pif);
460
 
        }
461
 
        return 0;
462
 
 
463
 
error_close:
464
 
        pi_close(sd);
465
 
 
466
 
error:
467
 
        fprintf(stderr, "Please use -h for more detailed options.\n");
468
 
 
469
 
        return -1;
470
 
}