"Fossies" - the Fresh Open Source Software Archive

Member "jpilot-2_0_1/jpilot-dump.c" (3 Apr 2021, 71705 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "jpilot-dump.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.2_vs_2_0_1.

    1 /*******************************************************************************
    2  * jpilot-dump.c
    3  *
    4  * Copyright (C) 2000 by hvrietsc
    5  *
    6  * This program is free software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License as published by
    8  * the Free Software Foundation; either version 2 of the License, or
    9  * (at your option) any later version.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  ******************************************************************************/
   20 
   21 /********************************* Includes ***********************************/
   22 #include "config.h"
   23 #include <stdlib.h>
   24 #include <stdio.h>
   25 #include <string.h>
   26 #include <time.h>
   27 #include <sys/stat.h>
   28 #ifdef HAVE_LOCALE_H
   29 #  include <locale.h>
   30 #endif
   31 
   32 /* Pilot-link header files */
   33 #include <pi-todo.h>
   34 #include <pi-memo.h>
   35 #include <pi-address.h>
   36 #include <pi-calendar.h>
   37 
   38 /* Jpilot header files */
   39 #include "datebook.h"
   40 #include "address.h"
   41 #include "todo.h"
   42 #include "memo.h"
   43 #include "utils.h"
   44 #include "i18n.h"
   45 #include "otherconv.h"
   46 #include "prefs.h"
   47 #include "sync.h"
   48 
   49 /********************************* Constants **********************************/
   50 /* RFCs use CRLF for Internet newline */
   51 #define CRLF "\x0D\x0A"
   52 
   53 #define LIMIT(a,b,c) if (a < b) {a=b;} if (a > c) {a=c;}
   54 
   55 /* Uncomment for more debug output */
   56 /* #define JDUMP_DEBUG 1 */
   57 
   58 /******************************* Global vars **********************************/
   59 /* dump switches */
   60 int  dumpD;
   61 int  dumpI;
   62 int  dumpN;
   63 int  Nyear;
   64 int  Nmonth;
   65 int  Nday;
   66 int  dumpA;
   67 int  dumpC;
   68 int  dumpC_type;
   69 int  dumpM;
   70 int  dumpT;
   71 const char *formatD;
   72 const char *formatM;
   73 const char *formatA;
   74 const char *formatT;
   75 
   76 /* Start Hack */
   77 /* FIXME: The following is a hack.
   78  * The variables below are global variables in jpilot.c which are unused in
   79  * this code but must be instantiated for the code to compile.  
   80  * The same is true of the functions which are only used in GUI mode. */
   81 pid_t jpilot_master_pid = -1;
   82 int pipe_to_parent;
   83 GtkWidget *glob_dialog;
   84 GtkWidget *glob_date_label;
   85 gint glob_date_timer_tag;
   86 
   87 void output_to_pane(const char *str) { return; }
   88 int sync_once(struct my_sync_info *sync_info) { return EXIT_SUCCESS; }
   89 /* End Hack */
   90 
   91 /* Structs needed for ContactsDB export */
   92 
   93 static address_schema_entry contact_schema[NUM_CONTACT_FIELDS]={
   94    {contLastname,  0, ADDRESS_GUI_LABEL_TEXT},
   95    {contFirstname, 0, ADDRESS_GUI_LABEL_TEXT},
   96    {contCompany,   0, ADDRESS_GUI_LABEL_TEXT},
   97    {contTitle,     0, ADDRESS_GUI_LABEL_TEXT},
   98    {contPhone1,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
   99    {contPhone2,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  100    {contPhone3,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  101    {contPhone4,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  102    {contPhone5,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  103    {contPhone6,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  104    {contPhone7,    0, ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT},
  105    {contIM1,       0, ADDRESS_GUI_IM_MENU_TEXT},
  106    {contIM2,       0, ADDRESS_GUI_IM_MENU_TEXT},
  107    {contWebsite,   0, ADDRESS_GUI_WEBSITE_TEXT},
  108    {contAddress1,  1, ADDRESS_GUI_ADDR_MENU_TEXT},
  109    {contCity1,     1, ADDRESS_GUI_LABEL_TEXT},
  110    {contState1,    1, ADDRESS_GUI_LABEL_TEXT},
  111    {contZip1,      1, ADDRESS_GUI_LABEL_TEXT},
  112    {contCountry1,  1, ADDRESS_GUI_LABEL_TEXT},
  113    {contAddress2,  2, ADDRESS_GUI_ADDR_MENU_TEXT},
  114    {contCity2,     2, ADDRESS_GUI_LABEL_TEXT},
  115    {contState2,    2, ADDRESS_GUI_LABEL_TEXT},
  116    {contZip2,      2, ADDRESS_GUI_LABEL_TEXT},
  117    {contCountry2,  2, ADDRESS_GUI_LABEL_TEXT},
  118    {contAddress3,  3, ADDRESS_GUI_ADDR_MENU_TEXT},
  119    {contCity3,     3, ADDRESS_GUI_LABEL_TEXT},
  120    {contState3,    3, ADDRESS_GUI_LABEL_TEXT},
  121    {contZip3,      3, ADDRESS_GUI_LABEL_TEXT},
  122    {contCountry3,  3, ADDRESS_GUI_LABEL_TEXT},
  123    {contBirthday,  4, ADDRESS_GUI_BIRTHDAY},
  124    {contCustom1,   4, ADDRESS_GUI_LABEL_TEXT},
  125    {contCustom2,   4, ADDRESS_GUI_LABEL_TEXT},
  126    {contCustom3,   4, ADDRESS_GUI_LABEL_TEXT},
  127    {contCustom4,   4, ADDRESS_GUI_LABEL_TEXT},
  128    {contCustom5,   4, ADDRESS_GUI_LABEL_TEXT},
  129    {contCustom6,   4, ADDRESS_GUI_LABEL_TEXT},
  130    {contCustom7,   4, ADDRESS_GUI_LABEL_TEXT},
  131    {contCustom8,   4, ADDRESS_GUI_LABEL_TEXT},
  132    {contCustom9,   4, ADDRESS_GUI_LABEL_TEXT},
  133    {contNote,      5, ADDRESS_GUI_LABEL_TEXT}
  134 };
  135 
  136 static char *ldifMapType(int label)
  137 {
  138    switch (label) {
  139     case 0:
  140       return "telephoneNumber";
  141     case 1:
  142       return "homePhone";
  143     case 2:
  144       return "facsimileTelephoneNumber";
  145     case 3:
  146       return "xotherTelephoneNumber";
  147     case 4:
  148       return "mail";
  149     case 5:
  150       return "xmainTelephoneNumber";
  151     case 6:
  152       return "pager";
  153     case 7:
  154       return "mobile";
  155     default:
  156       return "xunknownTelephoneNumber";
  157    }
  158 }
  159 
  160 static char *vCardMapType(int label)
  161 {
  162    switch (label) {
  163     case 0:
  164       return "work";
  165     case 1:
  166       return "home";
  167     case 2:
  168       return "fax";
  169     case 3:
  170       return "x-other";
  171     case 4:
  172       return "email";
  173     case 5:
  174       return "x-main";
  175     case 6:
  176       return "pager";
  177     case 7:
  178       return "cell";
  179     default:
  180       return "x-unknown";
  181    }
  182 }
  183 
  184 /****************************** Main Code *************************************/
  185 static void fprint_jpd_usage_string(FILE *out)
  186 {
  187    fprintf(out, "%s-dump [ +format [-v] || [-h] || [-f] || [-D] || [-i] || [-A] || [-C] || [-T] || [-M] || [-N] ]\n", EPN);
  188    fprintf(out, _(" +D +A +T +M format like date +format.\n"));
  189    fprintf(out, _(" -v displays version and exits.\n"));
  190    fprintf(out, _(" -h displays help and exits.\n"));
  191    fprintf(out, _(" -f displays help for format codes.\n"));
  192    fprintf(out, _(" -D dump DateBook.\n"));
  193    fprintf(out, _(" -i dump DateBook in iCalendar format.\n"));
  194    fprintf(out, _(" -N dump appts for today in DateBook.\n"));
  195    fprintf(out, _(" -NYYYY/MM/DD dump appts on YYYY/MM/DD in DateBook.\n"));
  196    fprintf(out, _(" -A dump Address book.\n"));
  197    fprintf(out, _(" -C dumps Contacts database:-\n"));
  198    fprintf(out, _("    -Ct dumps as text (default).\n"));
  199    fprintf(out, _("    -Cc dumps as csv.\n"));
  200    fprintf(out, _("    -Cv dumps as vcard.\n"));
  201    fprintf(out, _("    -Cl dumps as ldif.\n"));
  202    fprintf(out, _(" -T dump ToDo list as CSV.\n"));
  203    fprintf(out, _(" -M dump Memos.\n"));
  204 }
  205 
  206 /* convert from UTF8 to local encoding */
  207 static void utf8_to_local(char *str)
  208 {
  209    char *local_buf;
  210    
  211    if (str == NULL)
  212       return;
  213 
  214    local_buf = g_locale_from_utf8(str, -1, NULL, NULL, NULL);
  215    if (local_buf)
  216    {
  217       g_strlcpy(str, local_buf, strlen(str)+1);
  218       free(local_buf);
  219    }
  220 }
  221 
  222 /* Parse the string and replace dangerous characters with spaces */
  223 static void takeoutfunnies(char *str)
  224 {
  225    int i;
  226 
  227    if (!str) {
  228       return;
  229    }
  230    for (i=0; str[i]; i++) {
  231       if ((str[i]=='\r') ||
  232           (str[i]=='\n') ||
  233           (str[i]=='\\') ||
  234           (str[i]=='\'') ||
  235           (str[i]=='"' ) ||
  236           (str[i]=='`' )
  237          ) {
  238          str[i]=' ';
  239       }
  240    }
  241 }
  242 
  243 static int dumpical(void)
  244 {
  245    MyAppointment *mappt;
  246    AppointmentList *al, *temp_list;
  247    int i;
  248    char text[1024];
  249    char csv_text[65550];
  250    char *p;
  251    gchar *end;
  252    time_t ltime;
  253    struct tm *now;
  254    struct tm ical_time;
  255    long char_set;
  256    char username[256];
  257    char hostname[256];
  258    const char *svalue;
  259    long userid;
  260 
  261    /* ICAL setup */
  262    get_pref(PREF_CHAR_SET, &char_set, NULL);
  263    if (char_set < CHAR_SET_UTF) {
  264       fprintf(stderr, _("Warning: "
  265                         "Host character encoding is not UTF-8 based.\n"
  266                         "Exported ical file may not be standards-compliant\n"));
  267    }
  268 
  269    get_pref(PREF_USER, NULL, &svalue);
  270    g_strlcpy(text, svalue, 128);
  271    text[127] = '\0';
  272    charset_p2j(text, 128, char_set);
  273    str_to_ical_str(username, sizeof(username), text);
  274    get_pref(PREF_USER_ID, &userid, NULL);
  275    gethostname(text, sizeof(hostname));
  276    text[sizeof(hostname)-1]='\0';
  277    str_to_ical_str(hostname, sizeof(hostname), text);
  278    time(&ltime);
  279    now = gmtime(&ltime);
  280 
  281    al=NULL;
  282    get_days_appointments2(&al, NULL, 2, 2, 2, NULL);
  283 
  284    mappt=NULL;
  285    for (i=0, temp_list=al; temp_list; temp_list = temp_list->next, i++) {
  286       mappt = &(temp_list->mappt);
  287       /* RFC 2445: Internet Calendaring and Scheduling Core
  288        *           Object Specification */
  289       if (i == 0) {
  290          printf("BEGIN:VCALENDAR"CRLF);
  291          printf("VERSION:2.0"CRLF);
  292          printf("PRODID:%s"CRLF, FPI_STRING);
  293       }
  294       printf("BEGIN:VEVENT"CRLF);
  295       /* XXX maybe if it's secret export a VFREEBUSY busy instead? */
  296       if (mappt->attrib & dlpRecAttrSecret) {
  297          printf("CLASS:PRIVATE"CRLF);
  298       }
  299       printf("UID:palm-datebook-%08x-%08lx-%s@%s"CRLF,
  300               mappt->unique_id, userid, username, hostname);
  301       printf("DTSTAMP:%04d%02d%02dT%02d%02d%02dZ"CRLF,
  302               now->tm_year+1900,
  303               now->tm_mon+1,
  304               now->tm_mday,
  305               now->tm_hour,
  306               now->tm_min,
  307               now->tm_sec);
  308       if (mappt->appt.description) {
  309          g_strlcpy(text, mappt->appt.description, 51);
  310          /* truncate the string on a UTF-8 character boundary */
  311          if (char_set > CHAR_SET_UTF) {
  312             if (!g_utf8_validate(text, -1, (const gchar **)&end))
  313                *end = 0;
  314          }
  315       } else {
  316          /* Handle pathological case with null description. */
  317          text[0] = '\0';
  318       }
  319       if ((p = strchr(text, '\n'))) {
  320          *p = '\0';
  321       }
  322       str_to_ical_str(csv_text, sizeof(csv_text), text);
  323       printf("SUMMARY:%s%s"CRLF, csv_text,
  324               strlen(text) > 49 ? "..." : "");
  325       str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.description);
  326       printf("DESCRIPTION:%s", csv_text);
  327       if (mappt->appt.note && mappt->appt.note[0]) {
  328          str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.note);
  329          printf("\\n"CRLF" %s"CRLF, csv_text);
  330       } else {
  331          printf(CRLF);
  332       }
  333       if (mappt->appt.event) {
  334          printf("DTSTART;VALUE=DATE:%04d%02d%02d"CRLF,
  335                  mappt->appt.begin.tm_year+1900,
  336                  mappt->appt.begin.tm_mon+1,
  337                  mappt->appt.begin.tm_mday);
  338          /* XXX unclear: can "event" span multiple days? */
  339          /* since DTEND is "noninclusive", should this be the next day? */
  340          if (mappt->appt.end.tm_year != mappt->appt.begin.tm_year ||
  341              mappt->appt.end.tm_mon != mappt->appt.begin.tm_mon ||
  342              mappt->appt.end.tm_mday != mappt->appt.begin.tm_mday) {
  343             printf("DTEND;VALUE=DATE:%04d%02d%02d"CRLF,
  344                     mappt->appt.end.tm_year+1900,
  345                     mappt->appt.end.tm_mon+1,
  346                     mappt->appt.end.tm_mday);
  347          }
  348       } else {
  349          /*
  350           * These are "local" times, so will be treated as being in
  351           * the other person's timezone when they are imported.  This
  352           * may or may not be what is desired.  (DateBk calls this
  353           * "all time zones").
  354           *
  355           * DateBk timezones could help us decide what to do here.
  356           *
  357           * When using DateBk timezones, we could write them out
  358           * as iCalendar timezones.
  359           *
  360           * Maybe the default should be to write an absolute (UTC) time,
  361           * and only write a "local" time when using DateBk and it says to.
  362           * It'd be interesting to see if repeated events get translated
  363           * properly when doing this, or if they become not eligible for
  364           * daylight savings.  This probably depends on the importing
  365           * application.
  366           */
  367          printf("DTSTART:%04d%02d%02dT%02d%02d00"CRLF,
  368                  mappt->appt.begin.tm_year+1900,
  369                  mappt->appt.begin.tm_mon+1,
  370                  mappt->appt.begin.tm_mday,
  371                  mappt->appt.begin.tm_hour,
  372                  mappt->appt.begin.tm_min);
  373          printf("DTEND:%04d%02d%02dT%02d%02d00"CRLF,
  374                  mappt->appt.end.tm_year+1900,
  375                  mappt->appt.end.tm_mon+1,
  376                  mappt->appt.end.tm_mday,
  377                  mappt->appt.end.tm_hour,
  378                  mappt->appt.end.tm_min);
  379       }
  380       if (mappt->appt.repeatType != repeatNone) {
  381          int wcomma, rptday;
  382          const char *wday[] = {"SU","MO","TU","WE","TH","FR","SA"};
  383          printf("RRULE:FREQ=");
  384          switch (mappt->appt.repeatType) {
  385           case repeatNone:
  386             /* can't happen, just here to silence compiler warning */
  387             break;
  388           case repeatDaily:
  389             printf("DAILY");
  390             break;
  391           case repeatWeekly:
  392             printf("WEEKLY;BYDAY=");
  393             wcomma=0;
  394             for (i=0; i<7; i++) {
  395                if (mappt->appt.repeatDays[i]) {
  396                   if (wcomma) {
  397                      printf(",");
  398                   }
  399                   wcomma = 1;
  400                   printf("%s", wday[i]);
  401                }
  402             }
  403             break;
  404           case repeatMonthlyByDay:
  405             rptday = (mappt->appt.repeatDay / 7) + 1;
  406             printf("MONTHLY;BYDAY=%d%s", rptday == 5 ? -1 : rptday,
  407                     wday[mappt->appt.repeatDay % 7]);
  408             break;
  409           case repeatMonthlyByDate:
  410             printf("MONTHLY;BYMONTHDAY=%d", mappt->appt.begin.tm_mday);
  411             break;
  412           case repeatYearly:
  413             printf("YEARLY");
  414             break;
  415          }
  416          if (mappt->appt.repeatFrequency != 1) {
  417             if (mappt->appt.repeatType == repeatWeekly &&
  418                 mappt->appt.repeatWeekstart >= 0 && mappt->appt.repeatWeekstart < 7) {
  419                printf(CRLF" ");  // Weekly repeats can exceed RFC line length
  420                printf(";WKST=%s", wday[mappt->appt.repeatWeekstart]);
  421             }
  422             printf(";INTERVAL=%d", mappt->appt.repeatFrequency);
  423          }
  424          if (!mappt->appt.repeatForever) {
  425             /* RFC 2445 is unclear on how to handle inclusivity for 
  426              * dates, rather than datestamps. Because most other
  427              * ical parsers assume non-inclusivity Jpilot needs to
  428              * add one day to the end date of repeating events. */
  429             memset(&ical_time, 0, sizeof(ical_time));
  430             ical_time.tm_year = mappt->appt.repeatEnd.tm_year;
  431             ical_time.tm_mon  = mappt->appt.repeatEnd.tm_mon;
  432             ical_time.tm_mday = mappt->appt.repeatEnd.tm_mday;
  433             ical_time.tm_isdst= -1;
  434             mktime(&ical_time);
  435             printf(";UNTIL=%04d%02d%02d",
  436                     ical_time.tm_year+1900,
  437                     ical_time.tm_mon+1,
  438                     ical_time.tm_mday);
  439          }
  440          printf(CRLF);
  441          if (mappt->appt.exceptions > 0) {
  442             for (i=0; i<mappt->appt.exceptions; i++) {
  443                printf("EXDATE;VALUE=DATE:%04d%02d%02d"CRLF,
  444                           mappt->appt.exception[i].tm_year+1900,
  445                           mappt->appt.exception[i].tm_mon+1,
  446                           mappt->appt.exception[i].tm_mday);
  447             }
  448          }
  449       }
  450       if (mappt->appt.alarm) {
  451          const char *units;
  452          printf("BEGIN:VALARM"CRLF);
  453          printf("ACTION:DISPLAY"CRLF);
  454          str_to_ical_str(csv_text, sizeof(csv_text), mappt->appt.description);
  455          printf("DESCRIPTION:%s"CRLF, csv_text);
  456          switch (mappt->appt.advanceUnits) {
  457           case advMinutes:
  458             units = "M";
  459             break;
  460           case advHours:
  461             units = "H";
  462             break;
  463           case advDays:
  464             units = "D";
  465             break;
  466           default: /* XXX */
  467             units = "?";
  468             break;
  469          }
  470          printf("TRIGGER:-PT%d%s"CRLF, mappt->appt.advance, units);
  471          printf("END:VALARM"CRLF);
  472       }
  473       printf("END:VEVENT"CRLF);
  474       if (temp_list->next == NULL) {
  475          printf("END:VCALENDAR"CRLF);
  476       }
  477    }
  478    free_AppointmentList(&al);
  479    return EXIT_SUCCESS;
  480 }
  481 
  482 static int dumpbook(void)
  483 {
  484    AppointmentList *tal, *al;
  485    int num, i;
  486    int year, month, day, hour, minute;
  487    struct tm tm_dom;
  488 
  489    al = NULL;
  490    num = get_days_appointments(&al, NULL, NULL);
  491    if (num == 0) 
  492       return (0);
  493 
  494    /* get date */
  495    LIMIT(Nday,1,31);
  496    LIMIT(Nyear,1900,3000);
  497    LIMIT(Nmonth,1,12);
  498    tm_dom.tm_sec  = 0;
  499    tm_dom.tm_min  = 0;
  500    tm_dom.tm_hour = 0;
  501    tm_dom.tm_mday = Nday;
  502    tm_dom.tm_year = Nyear-1900;
  503    tm_dom.tm_mon  = Nmonth-1;
  504    tm_dom.tm_isdst = 0;
  505    mktime(&tm_dom);
  506 
  507 #ifdef JDUMP_DEBUG
  508    printf("Dumpbook:dump year=%d,month=%d,day=%d\n", Nyear, Nmonth, Nday);
  509    printf("Dumpbook:date is %s", asctime(&tm_dom));
  510 #endif
  511 
  512    for (tal=al; tal; tal = tal->next) {
  513       if (((dumpN == FALSE) || (isApptOnDate(&(tal->mappt.appt), &tm_dom) == TRUE))
  514          && (tal->mappt.rt != DELETED_PALM_REC)
  515          && (tal->mappt.rt != MODIFIED_PALM_REC)) {
  516        
  517          utf8_to_local(tal->mappt.appt.description);
  518          utf8_to_local(tal->mappt.appt.note);
  519 
  520          /* sort through format codes */
  521          for (i=2; formatD[i] != '\0'; i++) {
  522             if ( formatD[i] != '%') {
  523                printf("%c", formatD[i]);
  524             } else {
  525                switch (formatD[i+1]) {
  526                 case '\0':
  527                      break;
  528                 case 'n' :
  529                      printf("\n");
  530                      i++;
  531                      break;
  532                 case 't' :
  533                      printf("\t");
  534                      i++;
  535                      break;
  536                 case 'q' :
  537                      printf("'");
  538                      i++;
  539                      break;
  540                 case 'Q' :
  541                      printf("\"");
  542                      i++;
  543                      break;
  544                 case 'w' :
  545                      printf("%d", tal->mappt.appt.alarm);
  546                      i++;
  547                      break;
  548                 case 'v' :
  549                      printf("%d", tal->mappt.appt.advance);
  550                      i++;
  551                      break;
  552                 case 'u' :
  553                      switch (tal->mappt.appt.advanceUnits) {
  554                       case advMinutes : printf("m"); break;
  555                       case advHours   : printf("h"); break;
  556                       case advDays    : printf("d"); break;
  557                       default         : printf("x"); break;
  558                      }
  559                      i++;
  560                      break;
  561                 case 'X' :
  562                      takeoutfunnies(tal->mappt.appt.note);
  563                      /* fall thru */
  564                 case 'x' :
  565                      if (tal->mappt.appt.note != NULL) {
  566                         printf("%s", tal->mappt.appt.note);
  567                      }
  568                      i++;
  569                      break;
  570                 case 'A' :
  571                      takeoutfunnies(tal->mappt.appt.description);
  572                      /* fall thru */
  573                 case 'a' :
  574                      printf("%s", tal->mappt.appt.description);
  575                      i++;
  576                      break;
  577                 case 'N' :      /* normal output */
  578                      /* start date+time, end date+time, "description" */
  579                      takeoutfunnies(tal->mappt.appt.description);
  580                      printf("%.4d/%.2d/%.2d,%.2d:%.2d,%.4d/%.2d/%.2d,%.2d:%.2d,\"%s\"",
  581                             tal->mappt.appt.begin.tm_year+1900,
  582                             tal->mappt.appt.begin.tm_mon+1,
  583                             tal->mappt.appt.begin.tm_mday,
  584                             tal->mappt.appt.begin.tm_hour,
  585                             tal->mappt.appt.begin.tm_min,
  586                             tal->mappt.appt.end.tm_year+1900,
  587                             tal->mappt.appt.end.tm_mon+1,
  588                             tal->mappt.appt.end.tm_mday,
  589                             tal->mappt.appt.end.tm_hour,
  590                             tal->mappt.appt.end.tm_min,
  591                             tal->mappt.appt.description
  592                      );
  593                      i++;
  594                      break;
  595                 /* now process the double character format codes */
  596                 case 'b' :
  597                 case 'e' :
  598                      if (formatD[i+1] == 'b') {
  599                         year   = tal->mappt.appt.begin.tm_year+1900;
  600                         month  = tal->mappt.appt.begin.tm_mon+1;
  601                         day    = tal->mappt.appt.begin.tm_mday;
  602                         hour   = tal->mappt.appt.begin.tm_hour;
  603                         minute = tal->mappt.appt.begin.tm_min;
  604                      } else {
  605                         year   = tal->mappt.appt.end.tm_year+1900;
  606                         month  = tal->mappt.appt.end.tm_mon+1;
  607                         day    = tal->mappt.appt.end.tm_mday;
  608                         hour   = tal->mappt.appt.end.tm_hour;
  609                         minute = tal->mappt.appt.end.tm_min;
  610                      }
  611                      /* do %bx and %ex format codes */
  612                      switch (formatD[i+2]) {
  613                       case '\0':
  614                         printf("%c", formatD[i+1]);
  615                         break;
  616                       case 'm' :
  617                         printf("%.2d", month);
  618                         i++;
  619                         break;
  620                       case 'd' :
  621                         printf("%.2d", day);
  622                         i++;
  623                         break;
  624                       case 'y' :
  625                         printf("%.2d", year%100);
  626                         i++;
  627                         break;
  628                       case 'Y' :
  629                         printf("%.4d", year);
  630                         i++;
  631                         break;
  632                       case 'X' :
  633                         printf("%.2d/%.2d/%.2d", year-1900, month, day);
  634                         i++;
  635                         break;
  636                       case 'D' :
  637                         printf("%.2d/%.2d/%.2d", month, day, year%100);
  638                         i++;
  639                         break;
  640                       case 'H' :
  641                         printf("%.2d", hour);
  642                         i++;
  643                         break;
  644                       case 'k' :
  645                         printf("%d", hour);
  646                         i++;
  647                         break;
  648                       case 'I' :
  649                         if (hour < 13) {
  650                            printf("%.2d", hour);
  651                         } else {
  652                            printf("%.2d", hour-12);
  653                         }
  654                         i++;
  655                         break;
  656                       case 'l' :
  657                         if (hour < 13) {
  658                            printf("%d", hour);
  659                         } else {
  660                            printf("%d", hour-12);
  661                         }
  662                         i++;
  663                         break;
  664                       case 'M' :
  665                         printf("%.2d", minute);
  666                         i++;
  667                         break;
  668                       case 'p' :
  669                         if (hour < 13) {
  670                            printf("AM");
  671                         } else {
  672                            printf("PM");
  673                         }
  674                         i++;
  675                         break;
  676                       case 'T' :
  677                         printf("%.2d:%.2d", hour, minute);
  678                         i++;
  679                         break;
  680                       case 'r' :
  681                         if (hour < 13) {
  682                            printf("%.2d:%.2d AM", hour, minute);
  683                         } else {
  684                            printf("%.2d:%.2d PM", hour-12, minute);
  685                         }
  686                         i++;
  687                         break;
  688                       case 'h' :
  689                       case 'b' :
  690                         switch (month-1) {
  691                          case 0: printf("Jan"); break;
  692                          case 1: printf("Feb"); break;
  693                          case 2: printf("Mar"); break;
  694                          case 3: printf("Apr"); break;
  695                          case 4: printf("May"); break;
  696                          case 5: printf("Jun"); break;
  697                          case 6: printf("Jul"); break;
  698                          case 7: printf("Aug"); break;
  699                          case 8: printf("Sep"); break;
  700                          case 9: printf("Oct"); break;
  701                          case 10:printf("Nov"); break;
  702                          case 11:printf("Dec"); break;
  703                          default:printf("???"); break;
  704                         }
  705                         i++;
  706                         break;
  707                       case 'B' :
  708                         switch (month-1) {
  709                          case 0: printf("January");   break;
  710                          case 1: printf("February");  break;
  711                          case 2: printf("March");     break;
  712                          case 3: printf("April");     break;
  713                          case 4: printf("May");       break;
  714                          case 5: printf("June");      break;
  715                          case 6: printf("July");      break;
  716                          case 7: printf("August");    break;
  717                          case 8: printf("September"); break;
  718                          case 9: printf("October");   break;
  719                          case 10:printf("November");  break;
  720                          case 11:printf("December");  break;
  721                          default:printf("???");       break;
  722                         }
  723                         i++;
  724                         break;
  725                       default: /* 2 letter format codes */
  726                         printf("%c%c", formatD[i+1], formatD[i+2]);
  727                         i++;
  728                         break;
  729                      } /* end switch 2 letters format codes */
  730                      i++;
  731                      break;
  732 
  733                 default: /* one letter format codes */
  734                   printf("%c", formatD[i+1]);
  735                   i++;
  736                   break;
  737                } /* end switch one letter format codes */
  738             } /* end if % */
  739          } /* for loop over formatD */
  740          printf("\n");
  741       } /* end if excluding deleted records */
  742    } /* end for loop on tal= */
  743 
  744    free_AppointmentList(&al);
  745    return EXIT_SUCCESS;
  746 }
  747 
  748 static int dumpaddress(void)
  749 {
  750    AddressList *tal, *al;
  751    int num, i;
  752    struct AddressAppInfo ai;
  753 
  754    get_address_app_info(&ai);
  755 
  756    al = NULL;
  757    i = 0;
  758    num = get_addresses(&al, i);
  759 
  760    for (tal=al; tal; tal = tal->next) {
  761       if ((tal->maddr.rt != DELETED_PALM_REC) && 
  762           (tal->maddr.rt != MODIFIED_PALM_REC)) {
  763          for (num=0; num < 19; num++)
  764             utf8_to_local(tal->maddr.addr.entry[num]);
  765 
  766          for ( i=2 ; formatA[i] != '\0' ; i++) {
  767             if ( formatA[i] != '%') {
  768                printf("%c", formatA[i]);
  769             } else {
  770                switch (formatA[i+1]) {
  771                 case '\0':
  772                      break;
  773                 case 'n' :
  774                      printf("\n");
  775                      i++;
  776                      break;
  777                 case 't' :
  778                      printf("\t");
  779                      i++;
  780                      break;
  781                 case 'q' :
  782                      printf("'");
  783                      i++;
  784                      break;
  785                 case 'Q' :
  786                      printf("\"");
  787                      i++;
  788                      break;
  789                 case 'C' :
  790                      printf("%s", ai.category.name[tal->maddr.attrib & 0x0F]);
  791                      i++;
  792                      break;
  793                 case 'N' :   /* normal output */
  794                      for (num=0; num < 19 ; num++) {
  795                         if (tal->maddr.addr.entry[num] == NULL) {
  796                            printf("\n");
  797                         } else {
  798                            printf("%s\n", tal->maddr.addr.entry[num]);
  799                         }
  800                      }
  801                      i++;
  802                      break;
  803 
  804 #define PRIT if (tal->maddr.addr.entry[num] != NULL) { printf("%s", tal->maddr.addr.entry[num]); }
  805 
  806 #define PRITE if (tal->maddr.addr.entry[num + 3] != NULL) { printf("%d", tal->maddr.addr.phoneLabel[num]); }
  807 
  808                 case 'l' : num=0; PRIT; i++; break;
  809                 case 'f' : num=1; PRIT; i++; break;
  810                 case 'c' : num=2; PRIT; i++; break;
  811                 case 'p' : num=3;
  812                      switch  (formatA[i+2]) {
  813                      case '1' : num=3; PRIT; i++; break;
  814                      case '2' : num=4; PRIT; i++; break;
  815                      case '3' : num=5; PRIT; i++; break;
  816                      case '4' : num=6; PRIT; i++; break;
  817                      case '5' : num=7; PRIT; i++; break;
  818                      }
  819                      i++;
  820                      break;
  821                 case 'e' : num = 0;
  822                      switch (formatA[i+2]) {
  823                      case '1' : num=0; PRITE; i++; break;
  824                      case '2' : num=1; PRITE; i++; break;
  825                      case '3' : num=2; PRITE; i++; break;
  826                      case '4' : num=3; PRITE; i++; break;
  827                      case '5' : num=4; PRITE; i++; break;
  828                      }
  829                      i++;
  830                      break;
  831                 case 'a' : num=8; PRIT; i++; break;
  832                 case 'T' : num=9; PRIT; i++; break;
  833                 case 's' : num=10; PRIT; i++; break;
  834                 case 'z' : num=11; PRIT; i++; break;
  835                 case 'u' : num=12; PRIT; i++; break;
  836                 case 'm' : num=13; PRIT; i++; break;
  837                 case 'U' :
  838                      switch (formatA[i+2]) {
  839                      case '1' : num=14; PRIT; i++; break;
  840                      case '2' : num=15; PRIT; i++; break;
  841                      case '3' : num=16; PRIT; i++; break;
  842                      case '4' : num=17; PRIT; i++; break;
  843                      }
  844                      i++;
  845                      break;
  846                 case 'X' :
  847                      takeoutfunnies(tal->maddr.addr.entry[18]);
  848                      /* fall thru */
  849                 case 'x' :
  850                      if (tal->maddr.addr.entry[18] != NULL) printf("%s", tal->maddr.addr.entry[18]);
  851                      i++;
  852                      break;
  853                 default:        /* one letter ones */
  854                      printf("%c", formatA[i+1]);
  855                      i++;
  856                      break;
  857                } /* switch one letter ones */
  858             } /* fi */
  859          } /* for */
  860          printf("\n");
  861       }/* end if deleted*/
  862    }/* end for tal=*/
  863 
  864    free_AddressList(&al);
  865    return EXIT_SUCCESS;
  866 }
  867 
  868 static void dumpcontact()
  869 {
  870    MyContact *mcont;
  871    const char *short_date;
  872    time_t ltime;
  873    struct tm *now;
  874    char str1[256], str2[256];
  875    char pref_time[40];
  876    int i, n;
  877    int record_num;
  878    char text[1024];
  879    char date_string[1024];
  880    char csv_text[65550];
  881    long char_set;
  882    char username[256];
  883    char hostname[256];
  884    const char *svalue;
  885    long userid;
  886    char birthday_str[255];
  887    const char *pref_date;
  888    int address_i, IM_i, phone_i;
  889    char *utf;
  890 
  891    static struct ContactAppInfo contact_app_info;
  892 
  893    ContactList *tcl, *cl;
  894    get_contact_app_info(&contact_app_info);
  895    cl = NULL;
  896    record_num = get_contacts(&cl, SORT_ASCENDING);
  897 
  898    /* Write a header for TEXT file */
  899    if (dumpC_type == EXPORT_TYPE_TEXT) {
  900       get_pref(PREF_SHORTDATE, NULL, &short_date);
  901       get_pref_time_no_secs(pref_time);
  902       time(&ltime);
  903       now = localtime(&ltime);
  904       strftime(str1, sizeof(str1), short_date, now);
  905       strftime(str2, sizeof(str2), pref_time, now);
  906       g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2);
  907       printf("Contact exported from %s %s on %s\n\n", 
  908                                                PN,VERSION,date_string);
  909    }
  910 
  911    /* Write a header to the CSV file */
  912    if (dumpC_type == EXPORT_TYPE_CSV) {
  913       printf("CSV contacts version "VERSION": Category, Private, ");
  914 
  915       address_i=phone_i=IM_i=0;
  916       for (i=0; i<NUM_CONTACT_FIELDS; i++) {
  917           switch (contact_schema[i].type) {
  918            case ADDRESS_GUI_IM_MENU_TEXT:
  919              printf("IM %d label, ", IM_i);
  920              printf("IM %d, ", IM_i);
  921              IM_i++;
  922              break;
  923            case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
  924              printf("Phone %d label, ", phone_i);
  925              printf("Phone %d, ", phone_i);
  926              phone_i++;
  927              break;
  928            case ADDRESS_GUI_ADDR_MENU_TEXT:
  929              printf("Address %d label, ", address_i);
  930              printf("Address %d, ", address_i);
  931              address_i++;
  932              break;
  933            case ADDRESS_GUI_BIRTHDAY:
  934              printf("%s, ", contact_app_info.labels[contact_schema[i].record_field]);
  935              printf("Reminder Advance, ");
  936                   break;
  937            case ADDRESS_GUI_LABEL_TEXT:
  938            case ADDRESS_GUI_WEBSITE_TEXT:
  939              printf("%s, ", contact_app_info.labels[contact_schema[i].record_field]);
  940              break;
  941           }
  942       }
  943 
  944       printf("Show in List\n");
  945    }  /* end writing CSV header */
  946 
  947    /* Special setup for VCARD export */
  948    if (dumpC_type == EXPORT_TYPE_VCARD) {
  949       get_pref(PREF_USER, NULL, &svalue);
  950       g_strlcpy(text, svalue, sizeof(text));
  951       str_to_ical_str(username, sizeof(username), text);
  952       get_pref(PREF_USER_ID, &userid, NULL);
  953       gethostname(text, sizeof(text));
  954       text[sizeof(text)-1]='\0';
  955       str_to_ical_str(hostname, sizeof(hostname), text);
  956    }
  957 
  958    /* Check encoding for LDIF output */
  959    if (dumpC_type == EXPORT_TYPE_LDIF) {
  960       get_pref(PREF_CHAR_SET, &char_set, NULL);
  961       if (char_set < CHAR_SET_UTF) {
  962          jp_logf(JP_LOG_WARN, _("Host character encoding is not UTF-8 based.\n Exported ldif file may not be standards-compliant\n"));
  963       }
  964    }
  965 
  966    get_pref(PREF_CHAR_SET, &char_set, NULL);
  967 
  968    for (record_num=0, tcl=cl; tcl; tcl = tcl->next, record_num++) {
  969       mcont = &tcl->mcont;
  970       switch (dumpC_type) {
  971          case EXPORT_TYPE_TEXT:
  972             utf = charset_p2newj(contact_app_info.category.name[mcont->attrib & 0x0F], 16, char_set);
  973             printf(("Category: %s\n"), utf);
  974             g_free(utf);
  975             printf(("Private: %s\n"),
  976             (mcont->attrib & dlpRecAttrSecret) ? _("Yes"):_("No"));
  977 
  978             address_i=phone_i=IM_i=0;
  979             for (i=0; i<NUM_CONTACT_FIELDS; i++) {
  980                /* Special handling for birthday which doesn't have an entry
  981                 * field but instead has a flag and a tm struct field */
  982                if ((contact_schema[i].type == ADDRESS_GUI_BIRTHDAY) &&
  983                    mcont->cont.birthdayFlag)
  984                {
  985                   printf(("%s: "), contact_app_info.labels[contact_schema[i].record_field] ? contact_app_info.labels[contact_schema[i].record_field] : "");
  986                   birthday_str[0]='\0';
  987                   get_pref(PREF_SHORTDATE, NULL, &pref_date);
  988                   strftime(birthday_str, sizeof(birthday_str), pref_date, &(mcont->cont.birthday));
  989                   printf(("%s\n"), birthday_str);
  990                }
  991 
  992                if (mcont->cont.entry[contact_schema[i].record_field]) {
  993                   /* Print labels for menu selectable fields (Work, Fax, etc.) */
  994                   switch (contact_schema[i].type) {
  995                      case ADDRESS_GUI_IM_MENU_TEXT:
  996                         printf(("%s: "), contact_app_info.IMLabels[mcont->cont.IMLabel[IM_i]]);
  997                         IM_i++;
  998                         break;
  999                      case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
 1000                         printf(("%s: "), contact_app_info.phoneLabels[mcont->cont.phoneLabel[phone_i]]);
 1001                         phone_i++;
 1002                         break;
 1003                      case ADDRESS_GUI_ADDR_MENU_TEXT:
 1004                         printf(("%s: "), contact_app_info.addrLabels[mcont->cont.addressLabel[address_i]]);
 1005                         address_i++;
 1006                         break;
 1007                      default:
 1008                         printf(("%s: "), contact_app_info.labels[contact_schema[i].record_field] ? contact_app_info.labels[contact_schema[i].record_field] : "");
 1009                   }
 1010                   /* Next print the entry field */
 1011                   switch (contact_schema[i].type) {
 1012                      case ADDRESS_GUI_LABEL_TEXT:
 1013                      case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
 1014                      case ADDRESS_GUI_IM_MENU_TEXT:
 1015                      case ADDRESS_GUI_ADDR_MENU_TEXT:
 1016                      case ADDRESS_GUI_WEBSITE_TEXT:
 1017                         printf("%s\n", mcont->cont.entry[contact_schema[i].record_field]);
 1018                         break;
 1019                   }
 1020                }
 1021             }
 1022             printf("\n");
 1023 
 1024             break;
 1025 
 1026          case EXPORT_TYPE_CSV:
 1027             /* Category name */
 1028             utf = charset_p2newj(contact_app_info.category.name[mcont->attrib & 0x0F], 16, char_set);
 1029             printf("\"%s\",", utf);
 1030             g_free(utf);
 1031 
 1032             /* Private */
 1033             printf("\"%s\",", (mcont->attrib & dlpRecAttrSecret) ? "1":"0");
 1034 
 1035             address_i=phone_i=IM_i=0;
 1036             /* The Contact entry values */
 1037             for (i=0; i<NUM_CONTACT_FIELDS; i++) {
 1038                switch (contact_schema[i].type) {
 1039                   /* For labels that are menu selectable ("Work", Fax", etc)
 1040                    * we list what they are set to in the record */
 1041                   case ADDRESS_GUI_IM_MENU_TEXT:
 1042                      str_to_csv_str(csv_text, contact_app_info.IMLabels[mcont->cont.IMLabel[IM_i]]);
 1043                      printf("\"%s\",", csv_text);
 1044                      str_to_csv_str(csv_text, mcont->cont.entry[contact_schema[i].record_field] ? mcont->cont.entry[contact_schema[i].record_field] : "");
 1045                      printf("\"%s\",", csv_text);
 1046                      IM_i++;
 1047                      break;
 1048                   case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
 1049                      str_to_csv_str(csv_text, contact_app_info.phoneLabels[mcont->cont.phoneLabel[phone_i]]);
 1050                      printf("\"%s\",", csv_text);
 1051                      str_to_csv_str(csv_text, mcont->cont.entry[contact_schema[i].record_field] ? mcont->cont.entry[contact_schema[i].record_field] : "");
 1052                      printf("\"%s\",", csv_text);
 1053                      phone_i++;
 1054                      break;
 1055                   case ADDRESS_GUI_ADDR_MENU_TEXT:
 1056                      str_to_csv_str(csv_text, contact_app_info.addrLabels[mcont->cont.addressLabel[address_i]]);
 1057                      printf("\"%s\",", csv_text);
 1058                      str_to_csv_str(csv_text, mcont->cont.entry[contact_schema[i].record_field] ? mcont->cont.entry[contact_schema[i].record_field] : "");
 1059                      printf("\"%s\",", csv_text);
 1060                      address_i++;
 1061                      break;
 1062                   case ADDRESS_GUI_LABEL_TEXT:
 1063                   case ADDRESS_GUI_WEBSITE_TEXT:
 1064                      printf("\"%s\",", mcont->cont.entry[contact_schema[i].record_field] ? mcont->cont.entry[contact_schema[i].record_field] : "");
 1065                      break;
 1066                   case ADDRESS_GUI_BIRTHDAY:
 1067                      if (mcont->cont.birthdayFlag) {
 1068                         birthday_str[0]='\0'; 
 1069                         strftime(birthday_str, sizeof(birthday_str), "%Y/%02m/%02d", &(mcont->cont.birthday));
 1070                         printf("\"%s\",", birthday_str);
 1071 
 1072                            if (mcont->cont.reminder) {
 1073                                printf("\"%d\",", mcont->cont.advance);
 1074                            } else {
 1075                                printf("\"\",");
 1076                            }
 1077 
 1078                      } else {
 1079                         printf("\"\",");  /* for null Birthday field */
 1080                         printf("\"\",");  /* for null Birthday Reminder field */
 1081                      }
 1082                      break;
 1083                }
 1084             }
 1085 
 1086             printf("\"%d\"\n", mcont->cont.showPhone);
 1087             break;
 1088 
 1089          case EXPORT_TYPE_VCARD:
 1090             /* RFC 2426: vCard MIME Directory Profile */
 1091             printf("BEGIN:VCARD"CRLF);
 1092             printf("VERSION:3.0"CRLF);
 1093             printf("PRODID:%s"CRLF, FPI_STRING);
 1094             if (mcont->attrib & dlpRecAttrSecret) {
 1095                printf("CLASS:PRIVATE"CRLF);
 1096             }
 1097             printf("UID:palm-addressbook-%08x-%08lx-%s@%s"CRLF, mcont->unique_id, userid, username, hostname);
 1098             utf = charset_p2newj(contact_app_info.category.name[mcont->attrib & 0x0F], 16, char_set);
 1099             str_to_vcard_str(csv_text, sizeof(csv_text), utf);
 1100             printf("CATEGORIES:%s"CRLF, csv_text);
 1101             printf("\"%s\",", utf);
 1102             g_free(utf);
 1103             if (mcont->cont.entry[contLastname] || mcont->cont.entry[contFirstname]) {
 1104                char *last = mcont->cont.entry[contLastname];
 1105                char *first = mcont->cont.entry[contFirstname];
 1106                printf("FN:");
 1107                if (first) {
 1108                   str_to_vcard_str(csv_text, sizeof(csv_text), first);
 1109                   printf("%s", csv_text);
 1110                }
 1111                if (first && last) {
 1112                   printf(" ");
 1113                }
 1114                if (last) {
 1115                   str_to_vcard_str(csv_text, sizeof(csv_text), last);
 1116                   printf("%s", csv_text);
 1117                }
 1118                printf(CRLF);
 1119                printf("N:");
 1120                if (last) {
 1121                   str_to_vcard_str(csv_text, sizeof(csv_text), last);
 1122                   printf("%s", csv_text);
 1123                }
 1124                printf(";");
 1125                /* split up first into first + middle and do first;middle,middle*/
 1126                if (first) {
 1127                   str_to_vcard_str(csv_text, sizeof(csv_text), first);
 1128                   printf("%s", csv_text);
 1129                }
 1130                printf(CRLF);
 1131             } else if (mcont->cont.entry[contCompany]) {
 1132                str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[contCompany]);
 1133                printf("FN:%s"CRLF"N:%s"CRLF, csv_text, csv_text);
 1134             } else {
 1135                printf("FN:-Unknown-"CRLF"N:known-;-Un"CRLF);
 1136             }
 1137             if (mcont->cont.entry[contTitle]) {
 1138                str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[contTitle]);
 1139                printf("TITLE:%s"CRLF, csv_text);
 1140             }
 1141             if (mcont->cont.entry[contCompany]) {
 1142                str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[contCompany]);
 1143                printf("ORG:%s"CRLF, csv_text);
 1144             }
 1145             for (n = contPhone1; n < contPhone7 + 1; n++) {
 1146                if (mcont->cont.entry[n]) {
 1147                   str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[n]);
 1148                   if (!strcmp(contact_app_info.phoneLabels[mcont->cont.phoneLabel[n-contPhone1]], _("E-mail"))) {
 1149                      printf("EMAIL:%s"CRLF, csv_text);
 1150                   } else {
 1151                      printf("TEL;TYPE=%s", vCardMapType(mcont->cont.phoneLabel[n - contPhone1]));
 1152                      if (mcont->cont.showPhone == n - contPhone1) {
 1153                         printf(",pref");
 1154                      }
 1155                      printf(":%s"CRLF, csv_text);
 1156                   }
 1157                }
 1158             }
 1159             for (i=0; i<NUM_ADDRESSES; i++) {
 1160                int address_i = 0, city_i = 0, state_i = 0, zip_i = 0, country_i = 0;
 1161                switch (i) {
 1162                   case 0:
 1163                      address_i = contAddress1;
 1164                      city_i = contCity1;
 1165                      state_i = contState1;
 1166                      zip_i = contZip1;
 1167                      country_i = contCountry1;
 1168                      break;
 1169                   case 1:
 1170                      address_i = contAddress2;
 1171                      city_i = contCity2;
 1172                      state_i = contState2;
 1173                      zip_i = contZip2;
 1174                      country_i = contCountry2;
 1175                      break;
 1176                   case 2:
 1177                      address_i = contAddress3;
 1178                      city_i = contCity3;
 1179                      state_i = contState3;
 1180                      zip_i = contZip3;
 1181                      country_i = contCountry3;
 1182                      break;
 1183                }
 1184                if (mcont->cont.entry[address_i] ||
 1185                      mcont->cont.entry[city_i] ||
 1186                      mcont->cont.entry[state_i] ||
 1187                      mcont->cont.entry[zip_i] ||
 1188                      mcont->cont.entry[country_i]) {
 1189                   printf("ADR:;;");
 1190                   for (n = address_i; n < country_i + 1; n++) {
 1191                      if (mcont->cont.entry[n]) {
 1192                         str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[n]);
 1193                         printf("%s", csv_text);
 1194                      }
 1195                      if (n < country_i) {
 1196                         printf(";");
 1197                      }
 1198                   }
 1199                }
 1200                printf(CRLF);
 1201             }
 1202             if (mcont->cont.entry[contCustom1] ||
 1203                   mcont->cont.entry[contCustom2] ||
 1204                   mcont->cont.entry[contCustom3] ||
 1205                   mcont->cont.entry[contCustom4] ||
 1206                   mcont->cont.entry[contCustom5] ||
 1207                   mcont->cont.entry[contCustom6] ||
 1208                   mcont->cont.entry[contCustom7] ||
 1209                   mcont->cont.entry[contCustom8] ||
 1210                   mcont->cont.entry[contCustom9] ||
 1211                   mcont->cont.entry[contNote]) {
 1212                int firstnote=1;
 1213                printf("NOTE:");
 1214                for (n=contCustom1; n<=contNote; n++) {
 1215                   if (mcont->cont.entry[n]) {
 1216                      str_to_vcard_str(csv_text, sizeof(csv_text), mcont->cont.entry[n]);
 1217                      if (firstnote == 0) {
 1218                         printf(" ");
 1219                      }
 1220                      if (n == contNote && firstnote) {
 1221                         printf("%s\\n"CRLF, csv_text);
 1222                      } else {
 1223                         printf("%s:\\n"CRLF" %s\\n"CRLF, contact_app_info.labels[n], csv_text);
 1224                      }
 1225                      firstnote=0;
 1226                   }
 1227                   if (n == contCustom9) n = contNote - 1;
 1228                }
 1229             }
 1230             printf("END:VCARD"CRLF);
 1231             break;
 1232 
 1233          case EXPORT_TYPE_LDIF:
 1234             /* RFC 2256 - organizationalPerson */
 1235             /* RFC 2798 - inetOrgPerson */
 1236             /* RFC 2849 - LDIF file format */
 1237             if (record_num == 0) {
 1238                printf("version: 1\n");
 1239             }
 1240             {
 1241                char *cn;
 1242                char *email = NULL;
 1243                char *last = mcont->cont.entry[contLastname];
 1244                char *first = mcont->cont.entry[contFirstname];
 1245                for (n = contPhone1; n <= contPhone7; n++) {
 1246                   if (mcont->cont.entry[n] && mcont->cont.phoneLabel[n - contPhone1] == 4) {
 1247                      email = mcont->cont.entry[n];
 1248                      break;
 1249                   }
 1250                }
 1251                if (first || last) {
 1252                   cn = csv_text;
 1253                   snprintf(csv_text, sizeof(csv_text), "%s%s%s", first ? first : "",
 1254                   first && last ? " " : "", last ? last : "");
 1255                   if (!last) {
 1256                      last = first;
 1257                      first = NULL;
 1258                   }
 1259                } else if (mcont->cont.entry[contCompany]) {
 1260                   last = mcont->cont.entry[contCompany];
 1261                   cn = last;
 1262                } else {
 1263                   last = "Unknown";
 1264                   cn = last;
 1265                }
 1266                /* maybe add dc=%s for each part of the email address? */
 1267                /* Mozilla just does mail=%s */
 1268                printf("dn: cn=%s%s%s", cn, email ? ",mail=" : "", email ? email : "");
 1269                printf("dnQualifier: %s\n", PN);
 1270                printf("objectClass: top\nobjectClass: person\n");
 1271                printf("objectClass: organizationalPerson\n");
 1272                printf("objectClass: inetOrgPerson\n");
 1273                printf("cn: %s", cn);
 1274                printf("sn: %s", last);
 1275                if (first)
 1276                   printf("givenName: %s", first);
 1277                if (mcont->cont.entry[contCompany])
 1278                   printf("o: %s", mcont->cont.entry[contCompany]);
 1279                for (n = contPhone1; n <= contPhone7; n++) {
 1280                   if (mcont->cont.entry[n]) {
 1281                      printf("%s: %s", ldifMapType(mcont->cont.phoneLabel[n - contPhone1]), mcont->cont.entry[n]);
 1282                   }
 1283                }
 1284                if (mcont->cont.entry[contAddress1])
 1285                   printf("postalAddress: %s", mcont->cont.entry[contAddress1]);
 1286                if (mcont->cont.entry[contCity1])
 1287                   printf("l: %s", mcont->cont.entry[contCity1]);
 1288                if (mcont->cont.entry[contState1])
 1289                   printf("st: %s", mcont->cont.entry[contState1]);
 1290                if (mcont->cont.entry[contZip1])
 1291                   printf("postalCode: %s", mcont->cont.entry[contZip1]);
 1292                if (mcont->cont.entry[contCountry1])
 1293                   printf("c: %s", mcont->cont.entry[contCountry1]);
 1294 
 1295                if (mcont->cont.entry[contAddress2])
 1296                   printf("postalAddress: %s", mcont->cont.entry[contAddress2]);
 1297                if (mcont->cont.entry[contCity2])
 1298                   printf("l: %s", mcont->cont.entry[contCity2]);
 1299                if (mcont->cont.entry[contState2])
 1300                   printf("st: %s", mcont->cont.entry[contState2]);
 1301                if (mcont->cont.entry[contZip2])
 1302                   printf("postalCode: %s", mcont->cont.entry[contZip2]);
 1303                if (mcont->cont.entry[contCountry2])
 1304                   printf("c: %s", mcont->cont.entry[contCountry2]);
 1305 
 1306                if (mcont->cont.entry[contAddress3])
 1307                   printf("postalAddress: %s", mcont->cont.entry[contAddress3]);
 1308                if (mcont->cont.entry[contCity3])
 1309                   printf("l: %s", mcont->cont.entry[contCity3]);
 1310                if (mcont->cont.entry[contState3])
 1311                   printf("st: %s", mcont->cont.entry[contState3]);
 1312                if (mcont->cont.entry[contZip3])
 1313                   printf("postalCode: %s", mcont->cont.entry[contZip3]);
 1314                if (mcont->cont.entry[contCountry3])
 1315                   printf("c: %s", mcont->cont.entry[contCountry3]);
 1316 
 1317                if (mcont->cont.entry[contIM1]) {
 1318                   strncpy(text, contact_app_info.IMLabels[mcont->cont.IMLabel[0]], 100);
 1319                   printf("%s: %s", text, mcont->cont.entry[contIM1]);
 1320                }
 1321                if (mcont->cont.entry[contIM2]) {
 1322                   strncpy(text, contact_app_info.IMLabels[mcont->cont.IMLabel[1]], 100);
 1323                   printf("%s: %s", text, mcont->cont.entry[contIM2]);
 1324                }
 1325 
 1326                if (mcont->cont.entry[contWebsite])
 1327                   printf("website: %s", mcont->cont.entry[contWebsite]);
 1328                if (mcont->cont.entry[contTitle])
 1329                   printf("title: %s", mcont->cont.entry[contTitle]);
 1330                if (mcont->cont.entry[contCustom1])
 1331                   printf("custom1: %s", mcont->cont.entry[contCustom1]);
 1332                if (mcont->cont.entry[contCustom2])
 1333                   printf("custom2: %s", mcont->cont.entry[contCustom2]);
 1334                if (mcont->cont.entry[contCustom3])
 1335                   printf("custom3: %s", mcont->cont.entry[contCustom3]);
 1336                if (mcont->cont.entry[contCustom4])
 1337                   printf("custom4: %s", mcont->cont.entry[contCustom4]);
 1338                if (mcont->cont.entry[contCustom5])
 1339                   printf("custom5: %s", mcont->cont.entry[contCustom5]);
 1340                if (mcont->cont.entry[contCustom6])
 1341                   printf("custom6: %s", mcont->cont.entry[contCustom6]);
 1342                if (mcont->cont.entry[contCustom7])
 1343                   printf("custom7: %s", mcont->cont.entry[contCustom7]);
 1344                if (mcont->cont.entry[contCustom8])
 1345                   printf("custom8: %s", mcont->cont.entry[contCustom8]);
 1346                if (mcont->cont.entry[contCustom9])
 1347                   printf("custom9: %s", mcont->cont.entry[contCustom9]);
 1348                if (mcont->cont.entry[contNote])
 1349                   printf("description: %s", mcont->cont.entry[contNote]);
 1350                printf("\n");
 1351                break;
 1352             }
 1353          default:
 1354             jp_logf(JP_LOG_WARN, _("Unknown export type\n"));
 1355       }
 1356    }
 1357 }
 1358 
 1359 static int dumptodo(void)
 1360 {
 1361    ToDoList *tal, *al;
 1362    int num, i;
 1363    int year, month, day, hour, minute;
 1364    struct ToDoAppInfo ai;
 1365 
 1366    get_todo_app_info(&ai);
 1367 
 1368    al = NULL;
 1369    num = get_todos(&al, SORT_ASCENDING);
 1370    if (num == 0)
 1371       return (0);
 1372 
 1373    for (tal=al; tal; tal = tal->next) {
 1374       if ((tal->mtodo.rt != DELETED_PALM_REC) && 
 1375           (tal->mtodo.rt != MODIFIED_PALM_REC)) {
 1376 
 1377          utf8_to_local(tal->mtodo.todo.description);
 1378          utf8_to_local(tal->mtodo.todo.note);
 1379 
 1380          for ( i=2; formatT[i] != '\0'; i++) {
 1381             if ( formatT[i] != '%') {
 1382                printf("%c", formatT[i]);
 1383             } else {
 1384                switch (formatT[i+1]) {
 1385                 case '\0':
 1386                      break;
 1387                 case 'n' :
 1388                      printf("\n");
 1389                      i++;
 1390                      break;
 1391                 case 't' :
 1392                      printf("\t");
 1393                      i++;
 1394                      break;
 1395                 case 'p' :
 1396                      printf("%d", tal->mtodo.todo.priority);
 1397                      i++;
 1398                      break;
 1399                 case 'q' :
 1400                      printf("'");
 1401                      i++;
 1402                      break;
 1403                 case 'Q' :
 1404                      printf("\"");
 1405                      i++;
 1406                      break;
 1407                 case 'X' :
 1408                      takeoutfunnies(tal->mtodo.todo.note);
 1409                      /* fall thru */
 1410                 case 'x' :
 1411                      if (tal->mtodo.todo.note != NULL) 
 1412                         printf("%s", tal->mtodo.todo.note);
 1413                      i++;
 1414                      break;
 1415                 case 'C' :
 1416                      printf("%s", ai.category.name[tal->mtodo.attrib & 0x0F]);
 1417                      i++;
 1418                      break;
 1419                 case 'A' :
 1420                      takeoutfunnies(tal->mtodo.todo.description);
 1421                      /* fall thru */
 1422                 case 'a' :
 1423                      printf("%s", tal->mtodo.todo.description);
 1424                      i++;
 1425                      break;
 1426                 case 'c' :
 1427                      printf("%d", tal->mtodo.todo.complete);
 1428                      i++;
 1429                      break;
 1430                 case 'i' :
 1431                      printf("%d", tal->mtodo.todo.indefinite);
 1432                      i++;
 1433                      break;
 1434                 case 'N' :   /* normal output */
 1435                      takeoutfunnies(tal->mtodo.todo.description);
 1436                      if(tal->mtodo.todo.indefinite && 
 1437                        !tal->mtodo.todo.complete) {
 1438                         year   = 9999;
 1439                         month  = 12;
 1440                         day    = 31;
 1441                         hour   = 23;
 1442                         minute = 59;
 1443                      } else {
 1444                         year   = tal->mtodo.todo.due.tm_year+1900;
 1445                         month  = tal->mtodo.todo.due.tm_mon+1;
 1446                         day    = tal->mtodo.todo.due.tm_mday;
 1447                         hour   = tal->mtodo.todo.due.tm_hour;
 1448                         minute = tal->mtodo.todo.due.tm_min;
 1449                      }
 1450                      /* check garbage */
 1451                      LIMIT(year,1900,9999);
 1452                      LIMIT(month,1,12);
 1453                      LIMIT(day,1,31);
 1454                      LIMIT(hour,0,23);
 1455                      LIMIT(minute,0,59);
 1456                      printf("%d,%d,%d,%.4d/%.2d/%.2d,\"%s\"",
 1457                             tal->mtodo.todo.complete,
 1458                             tal->mtodo.todo.priority,
 1459                             tal->mtodo.todo.indefinite,
 1460                             year, month, day,
 1461                             tal->mtodo.todo.description
 1462                      );
 1463                      i++;
 1464                      break;
 1465                 /* now the double letter format codes */
 1466                 case 'd' :
 1467                   if(tal->mtodo.todo.indefinite && !tal->mtodo.todo.complete) {
 1468                      year   = 9999;
 1469                      month  = 12;
 1470                      day    = 31;
 1471                      hour   = 23;
 1472                      minute = 59;
 1473                   } else {
 1474                      year   = tal->mtodo.todo.due.tm_year+1900;
 1475                      month  = tal->mtodo.todo.due.tm_mon+1;
 1476                      day    = tal->mtodo.todo.due.tm_mday;
 1477                      hour   = tal->mtodo.todo.due.tm_hour;
 1478                      minute = tal->mtodo.todo.due.tm_min;
 1479                   }
 1480                   /* check garbage */
 1481                   LIMIT(year,1900,9999);
 1482                   LIMIT(month,1,12);
 1483                   LIMIT(day,1,31);
 1484                   LIMIT(hour,0,23);
 1485                   LIMIT(minute,0,59);
 1486                   /* do %dx formats */
 1487                   switch (formatT[i+2]) {
 1488                    case '\0':
 1489                      printf("%c", formatT[i+1]);
 1490                      break;
 1491                    case 'm' :
 1492                      printf("%.2d", month);
 1493                      i++;
 1494                      break;
 1495                    case 'd' :
 1496                      printf("%.2d", day);
 1497                      i++;
 1498                      break;
 1499                    case 'y' :
 1500                      printf("%.2d", year%100);
 1501                      i++;
 1502                      break;
 1503                    case 'Y' :
 1504                      printf("%.4d", year);
 1505                      i++;
 1506                      break;
 1507                    case 'X' :
 1508                      printf("%.2d/%.2d/%.2d", year-1900, month, day);
 1509                      i++;
 1510                      break;
 1511                    case 'D' :
 1512                      printf("%.2d/%.2d/%.2d", month, day, year%100);
 1513                      i++;
 1514                      break;
 1515                    case 'H' :
 1516                      printf("%.2d", hour);
 1517                      i++;
 1518                      break;
 1519                    case 'k' :
 1520                      printf("%d", hour);
 1521                      i++;
 1522                      break;
 1523                    case 'I' :
 1524                      if (hour < 13) {
 1525                         printf("%.2d", hour);
 1526                      } else {
 1527                         printf("%.2d", hour-12);
 1528                      }
 1529                      i++;
 1530                      break;
 1531                    case 'l' :
 1532                      if (hour < 13) {
 1533                         printf("%d", hour);
 1534                      } else {
 1535                         printf("%d", hour-12);
 1536                      }
 1537                      i++;
 1538                      break;
 1539                    case 'M' :
 1540                      printf("%.2d", minute);
 1541                      i++;
 1542                      break;
 1543                    case 'p' :
 1544                      if (hour < 13) {
 1545                         printf("AM");
 1546                      } else {
 1547                         printf("PM");
 1548                      }
 1549                      i++;
 1550                      break;
 1551                    case 'T' :
 1552                      printf("%.2d:%.2d", hour, minute);
 1553                      i++;
 1554                      break;
 1555                    case 'r' :
 1556                      if (hour < 13) {
 1557                         printf("%.2d:%.2d AM", hour, minute);
 1558                      } else {
 1559                         printf("%.2d:%.2d PM", hour-12, minute);
 1560                      }
 1561                      i++;
 1562                      break;
 1563                    case 'h' :
 1564                    case 'b' :
 1565                      switch (month-1) {
 1566                       case 0: printf("Jan"); break;
 1567                       case 1: printf("Feb"); break;
 1568                       case 2: printf("Mar"); break;
 1569                       case 3: printf("Apr"); break;
 1570                       case 4: printf("May"); break;
 1571                       case 5: printf("Jun"); break;
 1572                       case 6: printf("Jul"); break;
 1573                       case 7: printf("Aug"); break;
 1574                       case 8: printf("Sep"); break;
 1575                       case 9: printf("Oct"); break;
 1576                       case 10:printf("Nov"); break;
 1577                       case 11:printf("Dec"); break;
 1578                       default:printf("???"); break;
 1579                      }
 1580                      i++;
 1581                      break;
 1582                    case 'B' :
 1583                      switch (month-1) {
 1584                       case 0: printf("January");   break;
 1585                       case 1: printf("February");  break;
 1586                       case 2: printf("March");     break;
 1587                       case 3: printf("April");     break;
 1588                       case 4: printf("May");       break;
 1589                       case 5: printf("June");      break;
 1590                       case 6: printf("July");      break;
 1591                       case 7: printf("August");    break;
 1592                       case 8: printf("September"); break;
 1593                       case 9: printf("October");   break;
 1594                       case 10:printf("November");  break;
 1595                       case 11:printf("December");  break;
 1596                       default:printf("???");       break;
 1597                      }
 1598                      i++;
 1599                      break;
 1600                    default: /* 2 letter format codes */
 1601                      printf("%c%c", formatT[i+1], formatT[i+2]);
 1602                      i++;
 1603                      break;
 1604                   } /* switch 2 letter format codes*/
 1605                      i++;
 1606                      break;
 1607                 default:   /* one letter format codes */
 1608                   printf("%c", formatT[i+1]);
 1609                   i++;
 1610                   break;
 1611                } /* switch one letter format codes */
 1612             } /* fi */
 1613          } /* for */
 1614          printf("\n");
 1615       } /* end if deleted*/
 1616    } /* end for tal=*/
 1617 
 1618    free_ToDoList(&al);
 1619    return EXIT_SUCCESS;
 1620 }
 1621 
 1622 static int dumpmemo(void)
 1623 {
 1624    MemoList *tal, *al;
 1625    int num,i;
 1626    struct MemoAppInfo ai;
 1627 
 1628    get_memo_app_info(&ai);
 1629 
 1630    al = NULL;
 1631    i = 0;
 1632    num = get_memos(&al, i);
 1633    if (num == 0)
 1634       return (0);
 1635 
 1636    for (tal=al; tal; tal = tal->next) {
 1637       if ((tal->mmemo.rt != DELETED_PALM_REC) && 
 1638           (tal->mmemo.rt != MODIFIED_PALM_REC)) {
 1639 
 1640          utf8_to_local(tal->mmemo.memo.text);
 1641 
 1642          for ( i=2 ; formatM[i] != '\0' ; i++) {
 1643             if ( formatM[i] != '%') {
 1644                printf("%c", formatM[i]);
 1645             } else {
 1646                switch (formatM[i+1]) {
 1647                 case '\0':
 1648                      break;
 1649                 case 'n' :
 1650                      printf("\n");
 1651                      i++;
 1652                      break;
 1653                 case 't' :
 1654                      printf("\t");
 1655                      i++;
 1656                      break;
 1657                 case 'q' :
 1658                      printf("'");
 1659                      i++;
 1660                      break;
 1661                 case 'Q' :
 1662                      printf("\"");
 1663                      i++;
 1664                      break;
 1665                 case 'X' :
 1666                      takeoutfunnies(tal->mmemo.memo.text);
 1667                      /* fall thru */
 1668                 case 'x' :
 1669                      if (tal->mmemo.memo.text != NULL) 
 1670                         printf("%s", tal->mmemo.memo.text);
 1671                      i++;
 1672                      break;
 1673                 case 'C' :
 1674                      printf("%s", ai.category.name[tal->mmemo.attrib & 0x0F]);
 1675                      i++;
 1676                      break;
 1677                 case 'N' :   /* normal output */
 1678                      printf("%s\n", tal->mmemo.memo.text);
 1679                      i++;
 1680                      break;
 1681                 default:    /* one letter ones */
 1682                      printf("%c", formatM[i+1]);
 1683                      i++;
 1684                      break;
 1685                } /* switch one letter ones */
 1686             } /* fi */
 1687          } /* for */
 1688          printf("\n");
 1689       } /* end if deleted */
 1690    } /* end for tal= */
 1691 
 1692    free_MemoList(&al);
 1693    return EXIT_SUCCESS;
 1694 }
 1695 
 1696 int main(int argc, char *argv[])
 1697 {
 1698    int i;
 1699    time_t ltime;
 1700    struct tm *now;
 1701 
 1702    /* fill dump format with default */
 1703    formatD="+D%N";
 1704    formatM="+M%N";
 1705    formatA="+A%N";
 1706    formatT="+T%N";
 1707    dumpD  = FALSE;
 1708    dumpI  = FALSE;
 1709    dumpN  = FALSE;
 1710    Nyear  = 1997;
 1711    Nmonth = 12;
 1712    Nday   = 31;
 1713    dumpA  = FALSE;
 1714    dumpM  = FALSE;
 1715    dumpT  = FALSE;
 1716 
 1717    /* enable internationalization(i18n) before printing any output */
 1718 #if defined(ENABLE_NLS)
 1719 #  ifdef HAVE_LOCALE_H
 1720    setlocale(LC_ALL, "");
 1721 #  endif
 1722    bindtextdomain(EPN, LOCALEDIR);
 1723    textdomain(EPN);
 1724 #endif
 1725 
 1726    /* If called with no arguments then print usage information */
 1727    if (argc == 1)
 1728    {
 1729       fprint_jpd_usage_string(stderr);
 1730       exit(0);
 1731    }
 1732 
 1733    /* process command line options */
 1734    for (i=1; i<argc; i++) {
 1735       if (!strncasecmp(argv[i], "+D", 2)) {
 1736          formatD=argv[i];
 1737       }
 1738       if (!strncasecmp(argv[i], "+M", 2)) {
 1739          formatM=argv[i];
 1740       }
 1741       if (!strncasecmp(argv[i], "+A", 2)) {
 1742          formatA=argv[i];
 1743       }
 1744       if (!strncasecmp(argv[i], "+T", 2)) {
 1745          formatT=argv[i];
 1746       }
 1747       if (!strncasecmp(argv[i], "-v", 2)) {
 1748          printf("jpilot-dump %s Copyright (C) hvrietsc@yahoo.com\n", VERSION);
 1749          exit(0);
 1750       }
 1751       if (!strncasecmp(argv[i], "-h", 2)) {
 1752          fprint_jpd_usage_string(stderr);
 1753          exit(0);
 1754       }
 1755       if (!strncasecmp(argv[i], "-D", 2)) {
 1756          dumpD = TRUE;
 1757       }
 1758       if (!strncasecmp(argv[i], "-I", 2)) {
 1759          dumpI = TRUE;
 1760       }
 1761       if (!strncasecmp(argv[i], "-N", 2)) {
 1762          dumpN = TRUE;
 1763          dumpD = TRUE;
 1764          if ( strlen(argv[i]) < 12) { 
 1765             /* illegal format, use today's date */
 1766             time(&ltime);
 1767             now = localtime(&ltime);
 1768             Nyear = 1900+now->tm_year;
 1769             Nmonth= 1+now->tm_mon;
 1770             Nday  = now->tm_mday;
 1771          } else {
 1772             Nyear = (argv[i][2]-'0')*1000+(argv[i][3]-'0')*100+(argv[i][4]-'0')*10 +argv[i][5]-'0';
 1773             Nmonth= (argv[i][7]-'0')*10+(argv[i][8]-'0');
 1774             Nday  = (argv[i][10]-'0')*10+(argv[i][11]-'0');
 1775          }
 1776 #ifdef JDUMP_DEBUG
 1777          printf("-N option: year=%d,month=%d,day=%d\n", Nyear, Nmonth, Nday);
 1778 #endif
 1779       }
 1780       if (!strncasecmp(argv[i], "-A", 2)) {
 1781          dumpA = TRUE;
 1782       }
 1783       if (!strncasecmp(argv[i], "-C", 2)) {
 1784          dumpC = TRUE;
 1785          dumpC_type = EXPORT_TYPE_TEXT;
 1786          if ( strlen(argv[i]) == 3 ) {
 1787             switch (argv[i][2]) {
 1788                case 't':
 1789                   dumpC_type = EXPORT_TYPE_TEXT;
 1790                   break;
 1791                case 'c':
 1792                   dumpC_type = EXPORT_TYPE_CSV;
 1793                   break;
 1794                case 'v':
 1795                   dumpC_type = EXPORT_TYPE_VCARD;
 1796                   break;
 1797                case 'l':
 1798                   dumpC_type = EXPORT_TYPE_LDIF;
 1799                   break;
 1800             }
 1801          }
 1802       }
 1803       if (!strncasecmp(argv[i], "-T", 2)) {
 1804          dumpT = TRUE;
 1805       }
 1806       if (!strncasecmp(argv[i], "-M", 2)) {
 1807          dumpM = TRUE;
 1808       }
 1809       if (!strncasecmp(argv[i], "-f", 2)) {
 1810          puts("+format GENERAL string:");
 1811          puts("%% prints a %");
 1812          puts("%n prints a newline");
 1813          puts("%t prints a tab");
 1814          puts("%q prints a \'");
 1815          puts("%Q prints a \"");
 1816          puts("%a prints appointment/todo description");
 1817          puts("%A prints appointment/todo description CR,LF,\',\",//,` removed");
 1818          puts("%x prints attached note");
 1819          puts("%X prints attached note CR,LF,etc removed");
 1820          puts("GENERAL date&time fields for value of %b see below:");
 1821          puts("%bm prints month 00-12");
 1822          puts("%bd prints day 01-31");
 1823          puts("%by prints year 00-99");
 1824          puts("%bY prints year 1970-....");
 1825          puts("%bX prints years since 1900 00-999");
 1826          puts("%bD prints mm/dd/yy");
 1827          puts("%bH prints hour 00-23");
 1828          puts("%bk prints hour 0-23");
 1829          puts("%bI prints hour 01-12");
 1830          puts("%bl prints hour 1-12");
 1831          puts("%bM prints minute 00-59");
 1832          puts("%bp prints AM or PM");
 1833          puts("%bT prints HH:MM HH=00-23");
 1834          puts("%br prints hh:mm [A|P]M hh=01-12");
 1835          puts("%bh prints month Jan-Dec");
 1836          puts("%bb prints month Jan-Dec");
 1837          puts("%bB prints month January-December");
 1838          printf("+D Datebook SPECIFIC strings (Default is %s):\n", formatD);
 1839          puts("if %b=%b then begin date/time, if %b=%e then end date/time");
 1840          puts("%N prints start-date,start-time,end-date,end-time,\"description\"");
 1841          puts("%w prints 1 if alarm on else prints 0");
 1842          puts("%v prints nr of advance alarm units");
 1843          puts("%u prints unit of advance m(inute), h(our), d(ay)");
 1844          printf("+A Address SPECIFIC strings (Default is %s):\n", formatA);
 1845          puts("%N prints every field from last name to note on a separate line");
 1846          puts("%C prints category of address as text");
 1847          puts("%l last name");
 1848          puts("%f first name");
 1849          puts("%c company");
 1850          puts("%p phone1, %p1 phone1, %p2 phone2, %p3 phone3, %p4 phone4 %p5 phone5");
 1851          puts("%e phone label1, %e1 phone label1, %e2 phone label2, %e3 phone label3, %e4 phone label4 %e5 phone label5");
 1852          puts("%a address");
 1853          puts("%T town/city");
 1854          puts("%s state");
 1855          puts("%z zip");
 1856          puts("%u country");
 1857          puts("%m title");
 1858          puts("%U1 user defined 1, %U2-%U4");
 1859          puts("%x prints memo");
 1860          puts("%X prints memo CR,LF,etc removed");
 1861          printf("+T Todo SPECIFIC strings (Default is %s):\n", formatT);
 1862          puts("if %b=%d then due date/time");
 1863          puts("%N prints completed,priority,indefinite,due-date,\"description\"");
 1864          puts("%c prints 1 if completed else 0");
 1865          puts("%i prints 1 if indefinite else 0");
 1866          puts("%p prints priority of todo item");
 1867          printf("+M memo SPECIFIC strings (Default is %s):\n", formatM);
 1868          puts("%N prints each memo separated by a blank line");
 1869          puts("%x prints memo");
 1870          puts("%X prints memo CR,LF,etc removed");
 1871          puts("%C prints category of memo as text");
 1872          exit(0);
 1873       }  /* end printing format usage */
 1874    }  /* end for over argc */
 1875 
 1876    pref_init();
 1877    pref_read_rc_file();
 1878 
 1879    if (otherconv_init()) {
 1880       printf("Error: could not set encoding\n");
 1881       return EXIT_FAILURE;
 1882    }
 1883 
 1884    /* dump selected database */
 1885    if (dumpD) {
 1886       dumpbook();
 1887    }
 1888 
 1889    if (dumpI) {
 1890       dumpical();
 1891    }
 1892 
 1893    if (dumpA) {
 1894       dumpaddress();
 1895    }
 1896 
 1897    if (dumpC) {
 1898       dumpcontact();
 1899    }
 1900 
 1901    if (dumpT) {
 1902       dumptodo();
 1903    }
 1904 
 1905    if (dumpM) {
 1906       dumpmemo();
 1907    }
 1908 
 1909    /* clean up */
 1910    otherconv_free();
 1911 
 1912    return EXIT_SUCCESS;
 1913 }
 1914