PageRenderTime 66ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/jpilot-1.8.1/jpilot-dump.c

#
C | 1297 lines | 1231 code | 26 blank | 40 comment | 14 complexity | 741b06c6dc10100d2625a4f2ab0d750b MD5 | raw file
Possible License(s): GPL-2.0
  1. /* $Id: jpilot-dump.c,v 1.44 2011-02-09 21:37:28 rousseau Exp $ */
  2. /*******************************************************************************
  3. * jpilot-dump.c
  4. *
  5. * Copyright (C) 2000 by hvrietsc
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. ******************************************************************************/
  21. /********************************* Includes ***********************************/
  22. #include "config.h"
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <time.h>
  27. #ifdef HAVE_LOCALE_H
  28. # include <locale.h>
  29. #endif
  30. /* Pilot-link header files */
  31. #include <pi-todo.h>
  32. #include <pi-memo.h>
  33. #include <pi-address.h>
  34. #include <pi-calendar.h>
  35. /* Jpilot header files */
  36. #include "datebook.h"
  37. #include "address.h"
  38. #include "todo.h"
  39. #include "memo.h"
  40. #include "utils.h"
  41. #include "i18n.h"
  42. #include "otherconv.h"
  43. #include "prefs.h"
  44. #include "sync.h"
  45. /********************************* Constants **********************************/
  46. /* RFCs use CRLF for Internet newline */
  47. #define CRLF "\x0D\x0A"
  48. #define LIMIT(a,b,c) if (a < b) {a=b;} if (a > c) {a=c;}
  49. /* Uncomment for more debug output */
  50. /* #define JDUMP_DEBUG 1 */
  51. /******************************* Global vars **********************************/
  52. /* dump switches */
  53. int dumpD;
  54. int dumpI;
  55. int dumpN;
  56. int Nyear;
  57. int Nmonth;
  58. int Nday;
  59. int dumpA;
  60. int dumpM;
  61. int dumpT;
  62. char *formatD;
  63. char *formatM;
  64. char *formatA;
  65. char *formatT;
  66. /* Start Hack */
  67. /* FIXME: The following is a hack.
  68. * The variables below are global variables in jpilot.c which are unused in
  69. * this code but must be instantiated for the code to compile.
  70. * The same is true of the functions which are only used in GUI mode. */
  71. pid_t jpilot_master_pid = -1;
  72. int pipe_to_parent;
  73. GtkWidget *glob_dialog;
  74. GtkWidget *glob_date_label;
  75. gint glob_date_timer_tag;
  76. void output_to_pane(const char *str) { return; }
  77. int sync_once(struct my_sync_info *sync_info) { return EXIT_SUCCESS; }
  78. /* End Hack */
  79. /****************************** Main Code *************************************/
  80. static void fprint_jpd_usage_string(FILE *out)
  81. {
  82. fprintf(out, "%s-dump [ +format [-v] || [-h] || [-f] || [-D] || [-i] || [-N] || [-A] || [-T] || [-M] ]\n", EPN);
  83. fprintf(out, _(" +D +A +T +M format like date +format.\n"));
  84. fprintf(out, _(" -v display version and exit\n"));
  85. fprintf(out, _(" -h display help text\n"));
  86. fprintf(out, _(" -f display help for format codes\n"));
  87. fprintf(out, _(" -D dump DateBook\n"));
  88. fprintf(out, _(" -i dump DateBook in iCalendar format\n"));
  89. fprintf(out, _(" -N dump appts for today in DateBook\n"));
  90. fprintf(out, _(" -NYYYY/MM/DD dump appts on YYYY/MM/DD in DateBook\n"));
  91. fprintf(out, _(" -A dump Address book\n"));
  92. fprintf(out, _(" -T dump ToDo list as CSV\n"));
  93. fprintf(out, _(" -M dump Memos\n"));
  94. }
  95. /* convert from UTF8 to local encoding */
  96. static void utf8_to_local(char *str)
  97. {
  98. char *local_buf;
  99. if (str == NULL)
  100. return;
  101. local_buf = g_locale_from_utf8(str, -1, NULL, NULL, NULL);
  102. if (local_buf)
  103. {
  104. g_strlcpy(str, local_buf, strlen(str)+1);
  105. free(local_buf);
  106. }
  107. }
  108. /* Parse the string and replace dangerous characters with spaces */
  109. static void takeoutfunnies(char *str)
  110. {
  111. int i;
  112. if (!str) {
  113. return;
  114. }
  115. for (i=0; str[i]; i++) {
  116. if ((str[i]=='\r') ||
  117. (str[i]=='\n') ||
  118. (str[i]=='\\') ||
  119. (str[i]=='\'') ||
  120. (str[i]=='"' ) ||
  121. (str[i]=='`' )
  122. ) {
  123. str[i]=' ';
  124. }
  125. }
  126. }
  127. static int dumpical(void)
  128. {
  129. MyAppointment *mappt;
  130. AppointmentList *al, *temp_list;
  131. int i;
  132. char text[1024];
  133. char csv_text[65550];
  134. char *p;
  135. gchar *end;
  136. time_t ltime;
  137. struct tm *now;
  138. struct tm ical_time;
  139. long char_set;
  140. char username[256];
  141. char hostname[256];
  142. const char *svalue;
  143. long userid;
  144. /* ICAL setup */
  145. get_pref(PREF_CHAR_SET, &char_set, NULL);
  146. if (char_set < CHAR_SET_UTF) {
  147. fprintf(stderr, _("Warning: "
  148. "Host character encoding is not UTF-8 based.\n"
  149. "Exported ical file may not be standards-compliant\n"));
  150. }
  151. get_pref(PREF_USER, NULL, &svalue);
  152. g_strlcpy(text, svalue, 128);
  153. text[127] = '\0';
  154. charset_p2j(text, 128, char_set);
  155. str_to_ical_str(username, sizeof(username), text);
  156. get_pref(PREF_USER_ID, &userid, NULL);
  157. gethostname(text, sizeof(hostname));
  158. text[sizeof(hostname)-1]='\0';
  159. str_to_ical_str(hostname, sizeof(hostname), text);
  160. time(&ltime);
  161. now = gmtime(&ltime);
  162. al=NULL;
  163. get_days_appointments2(&al, NULL, 2, 2, 2, NULL);
  164. mappt=NULL;
  165. for (i=0, temp_list=al; temp_list; temp_list = temp_list->next, i++) {
  166. mappt = &(temp_list->mappt);
  167. /* RFC 2445: Internet Calendaring and Scheduling Core
  168. * Object Specification */
  169. if (i == 0) {
  170. printf("BEGIN:VCALENDAR"CRLF);
  171. printf("VERSION:2.0"CRLF);
  172. printf("PRODID:%s"CRLF, FPI_STRING);
  173. }
  174. printf("BEGIN:VEVENT"CRLF);
  175. /* XXX maybe if it's secret export a VFREEBUSY busy instead? */
  176. if (mappt->attrib & dlpRecAttrSecret) {
  177. printf("CLASS:PRIVATE"CRLF);
  178. }
  179. printf("UID:palm-datebook-%08x-%08lx-%s@%s"CRLF,
  180. mappt->unique_id, userid, username, hostname);
  181. printf("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ"CRLF,
  182. now->tm_year+1900,
  183. now->tm_mon+1,
  184. now->tm_mday,
  185. now->tm_hour,
  186. now->tm_min,
  187. now->tm_sec);
  188. if (mappt->appt.description) {
  189. g_strlcpy(text, mappt->appt.description, 51);
  190. /* truncate the string on a UTF-8 character boundary */
  191. if (char_set > CHAR_SET_UTF) {
  192. if (!g_utf8_validate(text, -1, (const gchar **)&end))
  193. *end = 0;
  194. }
  195. } else {
  196. /* Handle pathological case with null description. */
  197. text[0] = '\0';
  198. }
  199. if ((p = strchr(text, '\n'))) {
  200. *p = '\0';
  201. }
  202. str_to_ical_str(csv_text, sizeof(csv_text), text);
  203. printf("SUMMARY:%s%s"CRLF, csv_text,
  204. strlen(text) > 49 ? "..." : "");
  205. str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.description);
  206. printf("DESCRIPTION:%s", csv_text);
  207. if (mappt->appt.note && mappt->appt.note[0]) {
  208. str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.note);
  209. printf("\\n"CRLF" %s"CRLF, csv_text);
  210. } else {
  211. printf(CRLF);
  212. }
  213. if (mappt->appt.event) {
  214. printf("DTSTART;VALUE=DATE:%04d%02d%02d"CRLF,
  215. mappt->appt.begin.tm_year+1900,
  216. mappt->appt.begin.tm_mon+1,
  217. mappt->appt.begin.tm_mday);
  218. /* XXX unclear: can "event" span multiple days? */
  219. /* since DTEND is "noninclusive", should this be the next day? */
  220. if (mappt->appt.end.tm_year != mappt->appt.begin.tm_year ||
  221. mappt->appt.end.tm_mon != mappt->appt.begin.tm_mon ||
  222. mappt->appt.end.tm_mday != mappt->appt.begin.tm_mday) {
  223. printf("DTEND;VALUE=DATE:%04d%02d%02d"CRLF,
  224. mappt->appt.end.tm_year+1900,
  225. mappt->appt.end.tm_mon+1,
  226. mappt->appt.end.tm_mday);
  227. }
  228. } else {
  229. /*
  230. * These are "local" times, so will be treated as being in
  231. * the other person's timezone when they are imported. This
  232. * may or may not be what is desired. (DateBk calls this
  233. * "all time zones").
  234. *
  235. * DateBk timezones could help us decide what to do here.
  236. *
  237. * When using DateBk timezones, we could write them out
  238. * as iCalendar timezones.
  239. *
  240. * Maybe the default should be to write an absolute (UTC) time,
  241. * and only write a "local" time when using DateBk and it says to.
  242. * It'd be interesting to see if repeated events get translated
  243. * properly when doing this, or if they become not eligible for
  244. * daylight savings. This probably depends on the importing
  245. * application.
  246. */
  247. printf("DTSTART:%04d%02d%02dT%02d%02d00"CRLF,
  248. mappt->appt.begin.tm_year+1900,
  249. mappt->appt.begin.tm_mon+1,
  250. mappt->appt.begin.tm_mday,
  251. mappt->appt.begin.tm_hour,
  252. mappt->appt.begin.tm_min);
  253. printf("DTEND:%04d%02d%02dT%02d%02d00"CRLF,
  254. mappt->appt.end.tm_year+1900,
  255. mappt->appt.end.tm_mon+1,
  256. mappt->appt.end.tm_mday,
  257. mappt->appt.end.tm_hour,
  258. mappt->appt.end.tm_min);
  259. }
  260. if (mappt->appt.repeatType != repeatNone) {
  261. int wcomma, rptday;
  262. char *wday[] = {"SU","MO","TU","WE","TH","FR","SA"};
  263. printf("RRULE:FREQ=");
  264. switch (mappt->appt.repeatType) {
  265. case repeatNone:
  266. /* can't happen, just here to silence compiler warning */
  267. break;
  268. case repeatDaily:
  269. printf("DAILY");
  270. break;
  271. case repeatWeekly:
  272. printf("WEEKLY;BYDAY=");
  273. wcomma=0;
  274. for (i=0; i<7; i++) {
  275. if (mappt->appt.repeatDays[i]) {
  276. if (wcomma) {
  277. printf(",");
  278. }
  279. wcomma = 1;
  280. printf("%s", wday[i]);
  281. }
  282. }
  283. break;
  284. case repeatMonthlyByDay:
  285. rptday = (mappt->appt.repeatDay / 7) + 1;
  286. printf("MONTHLY;BYDAY=%d%s", rptday == 5 ? -1 : rptday,
  287. wday[mappt->appt.repeatDay % 7]);
  288. break;
  289. case repeatMonthlyByDate:
  290. printf("MONTHLY;BYMONTHDAY=%d", mappt->appt.begin.tm_mday);
  291. break;
  292. case repeatYearly:
  293. printf("YEARLY");
  294. break;
  295. }
  296. if (mappt->appt.repeatFrequency != 1) {
  297. if (mappt->appt.repeatType == repeatWeekly &&
  298. mappt->appt.repeatWeekstart >= 0 && mappt->appt.repeatWeekstart < 7) {
  299. printf(CRLF" "); // Weekly repeats can exceed RFC line length
  300. printf(";WKST=%s", wday[mappt->appt.repeatWeekstart]);
  301. }
  302. printf(";INTERVAL=%d", mappt->appt.repeatFrequency);
  303. }
  304. if (!mappt->appt.repeatForever) {
  305. /* RFC 2445 is unclear on how to handle inclusivity for
  306. * dates, rather than datestamps. Because most other
  307. * ical parsers assume non-inclusivity Jpilot needs to
  308. * add one day to the end date of repeating events. */
  309. memset(&ical_time, 0, sizeof(ical_time));
  310. ical_time.tm_year = mappt->appt.repeatEnd.tm_year;
  311. ical_time.tm_mon = mappt->appt.repeatEnd.tm_mon;
  312. ical_time.tm_mday = mappt->appt.repeatEnd.tm_mday;
  313. ical_time.tm_isdst= -1;
  314. mktime(&ical_time);
  315. printf(";UNTIL=%04d%02d%02d",
  316. ical_time.tm_year+1900,
  317. ical_time.tm_mon+1,
  318. ical_time.tm_mday);
  319. }
  320. printf(CRLF);
  321. if (mappt->appt.exceptions > 0) {
  322. for (i=0; i<mappt->appt.exceptions; i++) {
  323. printf("EXDATE;VALUE=DATE:%04d%02d%02d"CRLF,
  324. mappt->appt.exception[i].tm_year+1900,
  325. mappt->appt.exception[i].tm_mon+1,
  326. mappt->appt.exception[i].tm_mday);
  327. }
  328. }
  329. }
  330. if (mappt->appt.alarm) {
  331. char *units;
  332. printf("BEGIN:VALARM"CRLF);
  333. printf("ACTION:DISPLAY"CRLF);
  334. str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.description);
  335. printf("DESCRIPTION:%s"CRLF, csv_text);
  336. switch (mappt->appt.advanceUnits) {
  337. case advMinutes:
  338. units = "M";
  339. break;
  340. case advHours:
  341. units = "H";
  342. break;
  343. case advDays:
  344. units = "D";
  345. break;
  346. default: /* XXX */
  347. units = "?";
  348. break;
  349. }
  350. printf("TRIGGER:-PT%d%s"CRLF, mappt->appt.advance, units);
  351. printf("END:VALARM"CRLF);
  352. }
  353. printf("END:VEVENT"CRLF);
  354. if (temp_list->next == NULL) {
  355. printf("END:VCALENDAR"CRLF);
  356. }
  357. }
  358. free_AppointmentList(&al);
  359. return EXIT_SUCCESS;
  360. }
  361. static int dumpbook(void)
  362. {
  363. AppointmentList *tal, *al;
  364. int num, i;
  365. int year, month, day, hour, minute;
  366. struct tm tm_dom;
  367. al = NULL;
  368. num = get_days_appointments(&al, NULL, NULL);
  369. if (num == 0)
  370. return (0);
  371. /* get date */
  372. LIMIT(Nday,1,31);
  373. LIMIT(Nyear,1900,3000);
  374. LIMIT(Nmonth,1,12);
  375. tm_dom.tm_sec = 0;
  376. tm_dom.tm_min = 0;
  377. tm_dom.tm_hour = 0;
  378. tm_dom.tm_mday = Nday;
  379. tm_dom.tm_year = Nyear-1900;
  380. tm_dom.tm_mon = Nmonth-1;
  381. tm_dom.tm_isdst = 0;
  382. mktime(&tm_dom);
  383. #ifdef JDUMP_DEBUG
  384. printf("Dumpbook:dump year=%d,month=%d,day=%d\n", Nyear, Nmonth, Nday);
  385. printf("Dumpbook:date is %s", asctime(&tm_dom));
  386. #endif
  387. for (tal=al; tal; tal = tal->next) {
  388. if (((dumpN == FALSE) || (isApptOnDate(&(tal->mappt.appt), &tm_dom) == TRUE))
  389. && (tal->mappt.rt != DELETED_PALM_REC)
  390. && (tal->mappt.rt != MODIFIED_PALM_REC)) {
  391. utf8_to_local(tal->mappt.appt.description);
  392. utf8_to_local(tal->mappt.appt.note);
  393. /* sort through format codes */
  394. for (i=2; formatD[i] != '\0'; i++) {
  395. if ( formatD[i] != '%') {
  396. printf("%c", formatD[i]);
  397. } else {
  398. switch (formatD[i+1]) {
  399. case '\0':
  400. break;
  401. case 'n' :
  402. printf("\n");
  403. i++;
  404. break;
  405. case 't' :
  406. printf("\t");
  407. i++;
  408. break;
  409. case 'q' :
  410. printf("'");
  411. i++;
  412. break;
  413. case 'Q' :
  414. printf("\"");
  415. i++;
  416. break;
  417. case 'w' :
  418. printf("%d", tal->mappt.appt.alarm);
  419. i++;
  420. break;
  421. case 'v' :
  422. printf("%d", tal->mappt.appt.advance);
  423. i++;
  424. break;
  425. case 'u' :
  426. switch (tal->mappt.appt.advanceUnits) {
  427. case advMinutes : printf("m"); break;
  428. case advHours : printf("h"); break;
  429. case advDays : printf("d"); break;
  430. default : printf("x"); break;
  431. }
  432. i++;
  433. break;
  434. case 'X' :
  435. takeoutfunnies(tal->mappt.appt.note);
  436. /* fall thru */
  437. case 'x' :
  438. if (tal->mappt.appt.note != NULL) {
  439. printf("%s", tal->mappt.appt.note);
  440. }
  441. i++;
  442. break;
  443. case 'A' :
  444. takeoutfunnies(tal->mappt.appt.description);
  445. /* fall thru */
  446. case 'a' :
  447. printf("%s", tal->mappt.appt.description);
  448. i++;
  449. break;
  450. case 'N' : /* normal output */
  451. /* start date+time, end date+time, "description" */
  452. takeoutfunnies(tal->mappt.appt.description);
  453. printf("%.4d/%.2d/%.2d,%.2d:%.2d,%.4d/%.2d/%.2d,%.2d:%.2d,\"%s\"",
  454. tal->mappt.appt.begin.tm_year+1900,
  455. tal->mappt.appt.begin.tm_mon+1,
  456. tal->mappt.appt.begin.tm_mday,
  457. tal->mappt.appt.begin.tm_hour,
  458. tal->mappt.appt.begin.tm_min,
  459. tal->mappt.appt.end.tm_year+1900,
  460. tal->mappt.appt.end.tm_mon+1,
  461. tal->mappt.appt.end.tm_mday,
  462. tal->mappt.appt.end.tm_hour,
  463. tal->mappt.appt.end.tm_min,
  464. tal->mappt.appt.description
  465. );
  466. i++;
  467. break;
  468. /* now process the double character format codes */
  469. case 'b' :
  470. case 'e' :
  471. if (formatD[i+1] == 'b') {
  472. year = tal->mappt.appt.begin.tm_year+1900;
  473. month = tal->mappt.appt.begin.tm_mon+1;
  474. day = tal->mappt.appt.begin.tm_mday;
  475. hour = tal->mappt.appt.begin.tm_hour;
  476. minute = tal->mappt.appt.begin.tm_min;
  477. } else {
  478. year = tal->mappt.appt.end.tm_year+1900;
  479. month = tal->mappt.appt.end.tm_mon+1;
  480. day = tal->mappt.appt.end.tm_mday;
  481. hour = tal->mappt.appt.end.tm_hour;
  482. minute = tal->mappt.appt.end.tm_min;
  483. }
  484. /* do %bx and %ex format codes */
  485. switch (formatD[i+2]) {
  486. case '\0':
  487. printf("%c", formatD[i+1]);
  488. break;
  489. case 'm' :
  490. printf("%.2d", month);
  491. i++;
  492. break;
  493. case 'd' :
  494. printf("%.2d", day);
  495. i++;
  496. break;
  497. case 'y' :
  498. printf("%.2d", year%100);
  499. i++;
  500. break;
  501. case 'Y' :
  502. printf("%.4d", year);
  503. i++;
  504. break;
  505. case 'X' :
  506. printf("%.2d/%.2d/%.2d", year-1900, month, day);
  507. i++;
  508. break;
  509. case 'D' :
  510. printf("%.2d/%.2d/%.2d", month, day, year%100);
  511. i++;
  512. break;
  513. case 'H' :
  514. printf("%.2d", hour);
  515. i++;
  516. break;
  517. case 'k' :
  518. printf("%d", hour);
  519. i++;
  520. break;
  521. case 'I' :
  522. if (hour < 13) {
  523. printf("%.2d", hour);
  524. } else {
  525. printf("%.2d", hour-12);
  526. }
  527. i++;
  528. break;
  529. case 'l' :
  530. if (hour < 13) {
  531. printf("%d", hour);
  532. } else {
  533. printf("%d", hour-12);
  534. }
  535. i++;
  536. break;
  537. case 'M' :
  538. printf("%.2d", minute);
  539. i++;
  540. break;
  541. case 'p' :
  542. if (hour < 13) {
  543. printf("AM");
  544. } else {
  545. printf("PM");
  546. }
  547. i++;
  548. break;
  549. case 'T' :
  550. printf("%.2d:%.2d", hour, minute);
  551. i++;
  552. break;
  553. case 'r' :
  554. if (hour < 13) {
  555. printf("%.2d:%.2d AM", hour, minute);
  556. } else {
  557. printf("%.2d:%.2d PM", hour-12, minute);
  558. }
  559. i++;
  560. break;
  561. case 'h' :
  562. case 'b' :
  563. switch (month-1) {
  564. case 0: printf("Jan"); break;
  565. case 1: printf("Feb"); break;
  566. case 2: printf("Mar"); break;
  567. case 3: printf("Apr"); break;
  568. case 4: printf("May"); break;
  569. case 5: printf("Jun"); break;
  570. case 6: printf("Jul"); break;
  571. case 7: printf("Aug"); break;
  572. case 8: printf("Sep"); break;
  573. case 9: printf("Oct"); break;
  574. case 10:printf("Nov"); break;
  575. case 11:printf("Dec"); break;
  576. default:printf("???"); break;
  577. }
  578. i++;
  579. break;
  580. case 'B' :
  581. switch (month-1) {
  582. case 0: printf("January"); break;
  583. case 1: printf("February"); break;
  584. case 2: printf("March"); break;
  585. case 3: printf("April"); break;
  586. case 4: printf("May"); break;
  587. case 5: printf("June"); break;
  588. case 6: printf("July"); break;
  589. case 7: printf("August"); break;
  590. case 8: printf("September"); break;
  591. case 9: printf("October"); break;
  592. case 10:printf("November"); break;
  593. case 11:printf("December"); break;
  594. default:printf("???"); break;
  595. }
  596. i++;
  597. break;
  598. default: /* 2 letter format codes */
  599. printf("%c%c", formatD[i+1], formatD[i+2]);
  600. i++;
  601. break;
  602. } /* end switch 2 letters format codes */
  603. i++;
  604. break;
  605. default: /* one letter format codes */
  606. printf("%c", formatD[i+1]);
  607. i++;
  608. break;
  609. } /* end switch one letter format codes */
  610. } /* end if % */
  611. } /* for loop over formatD */
  612. printf("\n");
  613. } /* end if excluding deleted records */
  614. } /* end for loop on tal= */
  615. free_AppointmentList(&al);
  616. return EXIT_SUCCESS;
  617. }
  618. static int dumpaddress(void)
  619. {
  620. AddressList *tal, *al;
  621. int num, i;
  622. struct AddressAppInfo ai;
  623. get_address_app_info(&ai);
  624. al = NULL;
  625. i = 0;
  626. num = get_addresses(&al, i);
  627. for (tal=al; tal; tal = tal->next) {
  628. if ((tal->maddr.rt != DELETED_PALM_REC) &&
  629. (tal->maddr.rt != MODIFIED_PALM_REC)) {
  630. for (num=0; num < 19; num++)
  631. utf8_to_local(tal->maddr.addr.entry[num]);
  632. for ( i=2 ; formatA[i] != '\0' ; i++) {
  633. if ( formatA[i] != '%') {
  634. printf("%c", formatA[i]);
  635. } else {
  636. switch (formatA[i+1]) {
  637. case '\0':
  638. break;
  639. case 'n' :
  640. printf("\n");
  641. i++;
  642. break;
  643. case 't' :
  644. printf("\t");
  645. i++;
  646. break;
  647. case 'q' :
  648. printf("'");
  649. i++;
  650. break;
  651. case 'Q' :
  652. printf("\"");
  653. i++;
  654. break;
  655. case 'C' :
  656. printf("%s", ai.category.name[tal->maddr.attrib & 0x0F]);
  657. i++;
  658. break;
  659. case 'N' : /* normal output */
  660. for (num=0; num < 19 ; num++) {
  661. if (tal->maddr.addr.entry[num] == NULL) {
  662. printf("\n");
  663. } else {
  664. printf("%s\n", tal->maddr.addr.entry[num]);
  665. }
  666. }
  667. i++;
  668. break;
  669. #define PRIT if (tal->maddr.addr.entry[num] != NULL) { printf("%s", tal->maddr.addr.entry[num]); }
  670. #define PRITE if (tal->maddr.addr.entry[num + 3] != NULL) { printf("%d", tal->maddr.addr.phoneLabel[num]); }
  671. case 'l' : num=0; PRIT; i++; break;
  672. case 'f' : num=1; PRIT; i++; break;
  673. case 'c' : num=2; PRIT; i++; break;
  674. case 'p' : num=3;
  675. switch (formatA[i+2]) {
  676. case '1' : num=3; PRIT; i++; break;
  677. case '2' : num=4; PRIT; i++; break;
  678. case '3' : num=5; PRIT; i++; break;
  679. case '4' : num=6; PRIT; i++; break;
  680. case '5' : num=7; PRIT; i++; break;
  681. }
  682. i++;
  683. break;
  684. case 'e' : num = 0;
  685. switch (formatA[i+2]) {
  686. case '1' : num=0; PRITE; i++; break;
  687. case '2' : num=1; PRITE; i++; break;
  688. case '3' : num=2; PRITE; i++; break;
  689. case '4' : num=3; PRITE; i++; break;
  690. case '5' : num=4; PRITE; i++; break;
  691. }
  692. i++;
  693. break;
  694. case 'a' : num=8; PRIT; i++; break;
  695. case 'T' : num=9; PRIT; i++; break;
  696. case 's' : num=10; PRIT; i++; break;
  697. case 'z' : num=11; PRIT; i++; break;
  698. case 'u' : num=12; PRIT; i++; break;
  699. case 'm' : num=13; PRIT; i++; break;
  700. case 'U' :
  701. switch (formatA[i+2]) {
  702. case '1' : num=14; PRIT; i++; break;
  703. case '2' : num=15; PRIT; i++; break;
  704. case '3' : num=16; PRIT; i++; break;
  705. case '4' : num=17; PRIT; i++; break;
  706. }
  707. i++;
  708. break;
  709. case 'X' :
  710. takeoutfunnies(tal->maddr.addr.entry[18]);
  711. /* fall thru */
  712. case 'x' :
  713. if (tal->maddr.addr.entry[18] != NULL) printf("%s", tal->maddr.addr.entry[18]);
  714. i++;
  715. break;
  716. default: /* one letter ones */
  717. printf("%c", formatA[i+1]);
  718. i++;
  719. break;
  720. } /* switch one letter ones */
  721. } /* fi */
  722. } /* for */
  723. printf("\n");
  724. }/* end if deleted*/
  725. }/* end for tal=*/
  726. free_AddressList(&al);
  727. return EXIT_SUCCESS;
  728. }
  729. static int dumptodo(void)
  730. {
  731. ToDoList *tal, *al;
  732. int num, i;
  733. int year, month, day, hour, minute;
  734. struct ToDoAppInfo ai;
  735. get_todo_app_info(&ai);
  736. al = NULL;
  737. num = get_todos(&al, SORT_ASCENDING);
  738. for (tal=al; tal; tal = tal->next) {
  739. if ((tal->mtodo.rt != DELETED_PALM_REC) &&
  740. (tal->mtodo.rt != MODIFIED_PALM_REC)) {
  741. utf8_to_local(tal->mtodo.todo.description);
  742. utf8_to_local(tal->mtodo.todo.note);
  743. for ( i=2; formatT[i] != '\0'; i++) {
  744. if ( formatT[i] != '%') {
  745. printf("%c", formatT[i]);
  746. } else {
  747. switch (formatT[i+1]) {
  748. case '\0':
  749. break;
  750. case 'n' :
  751. printf("\n");
  752. i++;
  753. break;
  754. case 't' :
  755. printf("\t");
  756. i++;
  757. break;
  758. case 'p' :
  759. printf("%d", tal->mtodo.todo.priority);
  760. i++;
  761. break;
  762. case 'q' :
  763. printf("'");
  764. i++;
  765. break;
  766. case 'Q' :
  767. printf("\"");
  768. i++;
  769. break;
  770. case 'X' :
  771. takeoutfunnies(tal->mtodo.todo.note);
  772. /* fall thru */
  773. case 'x' :
  774. if (tal->mtodo.todo.note != NULL)
  775. printf("%s", tal->mtodo.todo.note);
  776. i++;
  777. break;
  778. case 'C' :
  779. printf("%s", ai.category.name[tal->mtodo.attrib & 0x0F]);
  780. i++;
  781. break;
  782. case 'A' :
  783. takeoutfunnies(tal->mtodo.todo.description);
  784. /* fall thru */
  785. case 'a' :
  786. printf("%s", tal->mtodo.todo.description);
  787. i++;
  788. break;
  789. case 'c' :
  790. printf("%d", tal->mtodo.todo.complete);
  791. i++;
  792. break;
  793. case 'i' :
  794. printf("%d", tal->mtodo.todo.indefinite);
  795. i++;
  796. break;
  797. case 'N' : /* normal output */
  798. takeoutfunnies(tal->mtodo.todo.description);
  799. if(tal->mtodo.todo.indefinite &&
  800. !tal->mtodo.todo.complete) {
  801. year = 9999;
  802. month = 12;
  803. day = 31;
  804. hour = 23;
  805. minute = 59;
  806. } else {
  807. year = tal->mtodo.todo.due.tm_year+1900;
  808. month = tal->mtodo.todo.due.tm_mon+1;
  809. day = tal->mtodo.todo.due.tm_mday;
  810. hour = tal->mtodo.todo.due.tm_hour;
  811. minute = tal->mtodo.todo.due.tm_min;
  812. }
  813. /* check garbage */
  814. LIMIT(year,1900,9999);
  815. LIMIT(month,1,12);
  816. LIMIT(day,1,31);
  817. LIMIT(hour,0,23);
  818. LIMIT(minute,0,59);
  819. printf("%d,%d,%d,%.4d/%.2d/%.2d,\"%s\"",
  820. tal->mtodo.todo.complete,
  821. tal->mtodo.todo.priority,
  822. tal->mtodo.todo.indefinite,
  823. year, month, day,
  824. tal->mtodo.todo.description
  825. );
  826. i++;
  827. break;
  828. /* now the double letter format codes */
  829. case 'd' :
  830. if(tal->mtodo.todo.indefinite && !tal->mtodo.todo.complete) {
  831. year = 9999;
  832. month = 12;
  833. day = 31;
  834. hour = 23;
  835. minute = 59;
  836. } else {
  837. year = tal->mtodo.todo.due.tm_year+1900;
  838. month = tal->mtodo.todo.due.tm_mon+1;
  839. day = tal->mtodo.todo.due.tm_mday;
  840. hour = tal->mtodo.todo.due.tm_hour;
  841. minute = tal->mtodo.todo.due.tm_min;
  842. }
  843. /* check garbage */
  844. LIMIT(year,1900,9999);
  845. LIMIT(month,1,12);
  846. LIMIT(day,1,31);
  847. LIMIT(hour,0,23);
  848. LIMIT(minute,0,59);
  849. /* do %dx formats */
  850. switch (formatT[i+2]) {
  851. case '\0':
  852. printf("%c", formatT[i+1]);
  853. break;
  854. case 'm' :
  855. printf("%.2d", month);
  856. i++;
  857. break;
  858. case 'd' :
  859. printf("%.2d", day);
  860. i++;
  861. break;
  862. case 'y' :
  863. printf("%.2d", year%100);
  864. i++;
  865. break;
  866. case 'Y' :
  867. printf("%.4d", year);
  868. i++;
  869. break;
  870. case 'X' :
  871. printf("%.2d/%.2d/%.2d", year-1900, month, day);
  872. i++;
  873. break;
  874. case 'D' :
  875. printf("%.2d/%.2d/%.2d", month, day, year%100);
  876. i++;
  877. break;
  878. case 'H' :
  879. printf("%.2d", hour);
  880. i++;
  881. break;
  882. case 'k' :
  883. printf("%d", hour);
  884. i++;
  885. break;
  886. case 'I' :
  887. if (hour < 13) {
  888. printf("%.2d", hour);
  889. } else {
  890. printf("%.2d", hour-12);
  891. }
  892. i++;
  893. break;
  894. case 'l' :
  895. if (hour < 13) {
  896. printf("%d", hour);
  897. } else {
  898. printf("%d", hour-12);
  899. }
  900. i++;
  901. break;
  902. case 'M' :
  903. printf("%.2d", minute);
  904. i++;
  905. break;
  906. case 'p' :
  907. if (hour < 13) {
  908. printf("AM");
  909. } else {
  910. printf("PM");
  911. }
  912. i++;
  913. break;
  914. case 'T' :
  915. printf("%.2d:%.2d", hour, minute);
  916. i++;
  917. break;
  918. case 'r' :
  919. if (hour < 13) {
  920. printf("%.2d:%.2d AM", hour, minute);
  921. } else {
  922. printf("%.2d:%.2d PM", hour-12, minute);
  923. }
  924. i++;
  925. break;
  926. case 'h' :
  927. case 'b' :
  928. switch (month-1) {
  929. case 0: printf("Jan"); break;
  930. case 1: printf("Feb"); break;
  931. case 2: printf("Mar"); break;
  932. case 3: printf("Apr"); break;
  933. case 4: printf("May"); break;
  934. case 5: printf("Jun"); break;
  935. case 6: printf("Jul"); break;
  936. case 7: printf("Aug"); break;
  937. case 8: printf("Sep"); break;
  938. case 9: printf("Oct"); break;
  939. case 10:printf("Nov"); break;
  940. case 11:printf("Dec"); break;
  941. default:printf("???"); break;
  942. }
  943. i++;
  944. break;
  945. case 'B' :
  946. switch (month-1) {
  947. case 0: printf("January"); break;
  948. case 1: printf("February"); break;
  949. case 2: printf("March"); break;
  950. case 3: printf("April"); break;
  951. case 4: printf("May"); break;
  952. case 5: printf("June"); break;
  953. case 6: printf("July"); break;
  954. case 7: printf("August"); break;
  955. case 8: printf("September"); break;
  956. case 9: printf("October"); break;
  957. case 10:printf("November"); break;
  958. case 11:printf("December"); break;
  959. default:printf("???"); break;
  960. }
  961. i++;
  962. break;
  963. default: /* 2 letter format codes */
  964. printf("%c%c", formatT[i+1], formatT[i+2]);
  965. i++;
  966. break;
  967. } /* switch 2 letter format codes*/
  968. i++;
  969. break;
  970. default: /* one letter format codes */
  971. printf("%c", formatT[i+1]);
  972. i++;
  973. break;
  974. } /* switch one letter format codes */
  975. } /* fi */
  976. } /* for */
  977. printf("\n");
  978. } /* end if deleted*/
  979. } /* end for tal=*/
  980. free_ToDoList(&al);
  981. return EXIT_SUCCESS;
  982. }
  983. static int dumpmemo(void)
  984. {
  985. MemoList *tal, *al;
  986. int num,i;
  987. struct MemoAppInfo ai;
  988. get_memo_app_info(&ai);
  989. al = NULL;
  990. i = 0;
  991. num = get_memos(&al, i);
  992. for (tal=al; tal; tal = tal->next) {
  993. if ((tal->mmemo.rt != DELETED_PALM_REC) &&
  994. (tal->mmemo.rt != MODIFIED_PALM_REC)) {
  995. utf8_to_local(tal->mmemo.memo.text);
  996. for ( i=2 ; formatM[i] != '\0' ; i++) {
  997. if ( formatM[i] != '%') {
  998. printf("%c", formatM[i]);
  999. } else {
  1000. switch (formatM[i+1]) {
  1001. case '\0':
  1002. break;
  1003. case 'n' :
  1004. printf("\n");
  1005. i++;
  1006. break;
  1007. case 't' :
  1008. printf("\t");
  1009. i++;
  1010. break;
  1011. case 'q' :
  1012. printf("'");
  1013. i++;
  1014. break;
  1015. case 'Q' :
  1016. printf("\"");
  1017. i++;
  1018. break;
  1019. case 'X' :
  1020. takeoutfunnies(tal->mmemo.memo.text);
  1021. /* fall thru */
  1022. case 'x' :
  1023. if (tal->mmemo.memo.text != NULL)
  1024. printf("%s", tal->mmemo.memo.text);
  1025. i++;
  1026. break;
  1027. case 'C' :
  1028. printf("%s", ai.category.name[tal->mmemo.attrib & 0x0F]);
  1029. i++;
  1030. break;
  1031. case 'N' : /* normal output */
  1032. printf("%s\n", tal->mmemo.memo.text);
  1033. i++;
  1034. break;
  1035. default: /* one letter ones */
  1036. printf("%c", formatM[i+1]);
  1037. i++;
  1038. break;
  1039. } /* switch one letter ones */
  1040. } /* fi */
  1041. } /* for */
  1042. printf("\n");
  1043. } /* end if deleted */
  1044. } /* end for tal= */
  1045. free_MemoList(&al);
  1046. return EXIT_SUCCESS;
  1047. }
  1048. int main(int argc, char *argv[])
  1049. {
  1050. int i;
  1051. time_t ltime;
  1052. struct tm *now;
  1053. /* fill dump format with default */
  1054. formatD="+D%N";
  1055. formatM="+M%N";
  1056. formatA="+A%N";
  1057. formatT="+T%N";
  1058. dumpD = FALSE;
  1059. dumpI = FALSE;
  1060. dumpN = FALSE;
  1061. Nyear = 1997;
  1062. Nmonth = 12;
  1063. Nday = 31;
  1064. dumpA = FALSE;
  1065. dumpM = FALSE;
  1066. dumpT = FALSE;
  1067. /* enable internationalization(i18n) before printing any output */
  1068. #if defined(ENABLE_NLS)
  1069. # ifdef HAVE_LOCALE_H
  1070. setlocale(LC_ALL, "");
  1071. # endif
  1072. bindtextdomain(EPN, LOCALEDIR);
  1073. textdomain(EPN);
  1074. #endif
  1075. /* If called with no arguments then print usage information */
  1076. if (argc == 1)
  1077. {
  1078. fprint_jpd_usage_string(stderr);
  1079. exit(0);
  1080. }
  1081. /* process command line options */
  1082. for (i=1; i<argc; i++) {
  1083. if (!strncasecmp(argv[i], "+D", 2)) {
  1084. formatD=argv[i];
  1085. }
  1086. if (!strncasecmp(argv[i], "+M", 2)) {
  1087. formatM=argv[i];
  1088. }
  1089. if (!strncasecmp(argv[i], "+A", 2)) {
  1090. formatA=argv[i];
  1091. }
  1092. if (!strncasecmp(argv[i], "+T", 2)) {
  1093. formatT=argv[i];
  1094. }
  1095. if (!strncasecmp(argv[i], "-v", 2)) {
  1096. printf("jpilot-dump %s Copyright (C) hvrietsc@yahoo.com\n", VERSION);
  1097. exit(0);
  1098. }
  1099. if (!strncasecmp(argv[i], "-h", 2)) {
  1100. fprint_jpd_usage_string(stderr);
  1101. exit(0);
  1102. }
  1103. if (!strncasecmp(argv[i], "-D", 2)) {
  1104. dumpD = TRUE;
  1105. }
  1106. if (!strncasecmp(argv[i], "-I", 2)) {
  1107. dumpI = TRUE;
  1108. }
  1109. if (!strncasecmp(argv[i], "-N", 2)) {
  1110. dumpN = TRUE;
  1111. dumpD = TRUE;
  1112. if ( strlen(argv[i]) < 12) {
  1113. /* illegal format, use today's date */
  1114. time(&ltime);
  1115. now = localtime(&ltime);
  1116. Nyear = 1900+now->tm_year;
  1117. Nmonth= 1+now->tm_mon;
  1118. Nday = now->tm_mday;
  1119. } else {
  1120. Nyear = (argv[i][2]-'0')*1000+(argv[i][3]-'0')*100+(argv[i][4]-'0')*10 +argv[i][5]-'0';
  1121. Nmonth= (argv[i][7]-'0')*10+(argv[i][8]-'0');
  1122. Nday = (argv[i][10]-'0')*10+(argv[i][11]-'0');
  1123. }
  1124. #ifdef JDUMP_DEBUG
  1125. printf("-N option: year=%d,month=%d,day=%d\n", Nyear, Nmonth, Nday);
  1126. #endif
  1127. }
  1128. if (!strncasecmp(argv[i], "-A", 2)) {
  1129. dumpA = TRUE;
  1130. }
  1131. if (!strncasecmp(argv[i], "-T", 2)) {
  1132. dumpT = TRUE;
  1133. }
  1134. if (!strncasecmp(argv[i], "-M", 2)) {
  1135. dumpM = TRUE;
  1136. }
  1137. if (!strncasecmp(argv[i], "-f", 2)) {
  1138. puts("+format GENERAL string:");
  1139. puts("%% prints a %");
  1140. puts("%n prints a newline");
  1141. puts("%t prints a tab");
  1142. puts("%q prints a \'");
  1143. puts("%Q prints a \"");
  1144. puts("%a prints appointment/todo description");
  1145. puts("%A prints appointment/todo description CR,LF,\',\",//,` removed");
  1146. puts("%x prints attached note");
  1147. puts("%X prints attached note CR,LF,etc removed");
  1148. puts("GENERAL date&time fields for value of %b see below:");
  1149. puts("%bm prints month 00-12");
  1150. puts("%bd prints day 01-31");
  1151. puts("%by prints year 00-99");
  1152. puts("%bY prints year 1970-....");
  1153. puts("%bX prints years since 1900 00-999");
  1154. puts("%bD prints mm/dd/yy");
  1155. puts("%bH prints hour 00-23");
  1156. puts("%bk prints hour 0-23");
  1157. puts("%bI prints hour 01-12");
  1158. puts("%bl prints hour 1-12");
  1159. puts("%bM prints minute 00-59");
  1160. puts("%bp prints AM or PM");
  1161. puts("%bT prints HH:MM HH=00-23");
  1162. puts("%br prints hh:mm [A|P]M hh=01-12");
  1163. puts("%bh prints month Jan-Dec");
  1164. puts("%bb prints month Jan-Dec");
  1165. puts("%bB prints month January-December");
  1166. printf("+D Datebook SPECIFIC strings (Default is %s):\n", formatD);
  1167. puts("if %b=%b then begin date/time, if %b=%e then end date/time");
  1168. puts("%N prints start-date,start-time,end-date,end-time,\"description\"");
  1169. puts("%w prints 1 if alarm on else prints 0");
  1170. puts("%v prints nr of advance alarm units");
  1171. puts("%u prints unit of advance m(inute), h(our), d(ay)");
  1172. printf("+A Address SPECIFIC strings (Default is %s):\n", formatA);
  1173. puts("%N prints every field from last name to note on a separate line");
  1174. puts("%C prints category of address as text");
  1175. puts("%l last name");
  1176. puts("%f first name");
  1177. puts("%c company");
  1178. puts("%p phone1, %p1 phone1, %p2 phone2, %p3 phone3, %p4 phone4 %p5 phone5");
  1179. puts("%e phone label1, %e1 phone label1, %e2 phone label2, %e3 phone label3, %e4 phone label4 %e5 phone label5");
  1180. puts("%a address");
  1181. puts("%T town/city");
  1182. puts("%s state");
  1183. puts("%z zip");
  1184. puts("%u country");
  1185. puts("%m title");
  1186. puts("%U1 user defined 1, %U2-%U4");
  1187. puts("%x prints memo");
  1188. puts("%X prints memo CR,LF,etc removed");
  1189. printf("+T Todo SPECIFIC strings (Default is %s):\n", formatT);
  1190. puts("if %b=%d then due date/time");
  1191. puts("%N prints completed,priority,indefinite,due-date,\"description\"");
  1192. puts("%c prints 1 if completed else 0");
  1193. puts("%i prints 1 if indefinite else 0");
  1194. puts("%p prints priority of todo item");
  1195. printf("+M memo SPECIFIC strings (Default is %s):\n", formatM);
  1196. puts("%N prints each memo separated by a blank line");
  1197. puts("%x prints memo");
  1198. puts("%X prints memo CR,LF,etc removed");
  1199. puts("%C prints category of memo as text");
  1200. exit(0);
  1201. } /* end printing format usage */
  1202. } /* end for over argc */
  1203. pref_init();
  1204. pref_read_rc_file();
  1205. if (otherconv_init()) {
  1206. printf("Error: could not set encoding\n");
  1207. return EXIT_FAILURE;
  1208. }
  1209. /* dump selected database */
  1210. if (dumpD) {
  1211. dumpbook();
  1212. }
  1213. if (dumpI) {
  1214. dumpical();
  1215. }
  1216. if (dumpA) {
  1217. dumpaddress();
  1218. }
  1219. if (dumpT) {
  1220. dumptodo();
  1221. }
  1222. if (dumpM) {
  1223. dumpmemo();
  1224. }
  1225. /* clean up */
  1226. otherconv_free();
  1227. return EXIT_SUCCESS;
  1228. }