00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025
00026 #include "pi-source.h"
00027 #include "pi-dlp.h"
00028 #include "pi-expense.h"
00029 #include "pi-userland.h"
00030
00031 int main(int argc, const char *argv[])
00032 {
00033 int db,
00034 sd = -1,
00035 i,
00036 l,
00037 category,
00038 po_err = -1,
00039 replace_category = 0;
00040
00041 char
00042 *category_name = NULL,
00043 *expenseType = NULL,
00044 *paymentType = NULL;
00045 size_t size;
00046 int found;
00047
00048 unsigned char buf[0xffff];
00049 unsigned char *b;
00050 pi_buffer_t *appblock;
00051
00052 struct PilotUser User;
00053 struct ExpenseAppInfo eai;
00054 struct Expense theExpense;
00055
00056 poptContext po;
00057
00058 struct poptOption options[] = {
00059 USERLAND_RESERVED_OPTIONS
00060 {"ptype", 't', POPT_ARG_STRING, &paymentType, 0,"Payment type (Cash, Check, etc.)"},
00061 {"etype", 'e', POPT_ARG_STRING, &expenseType, 0, "Expense type (Airfare, Hotel, etc.)"},
00062 {"amount", 'a', POPT_ARG_STRING, &theExpense.amount, 0, "Payment amount"},
00063 {"vendor", 'V', POPT_ARG_STRING, &theExpense.vendor, 0, "Expense vendor name (Joe's Restaurant)"},
00064 {"city", 'i', POPT_ARG_STRING, &theExpense.city, 0, "Location/city for this expense entry"},
00065 {"guests", 'g', POPT_ARG_STRING, &theExpense.attendees, 0, "Number of guests for this expense entry","NUMBER"},
00066 {"note", 'n', POPT_ARG_STRING, &theExpense.note, 0, "Notes for this expense entry"},
00067 {"category", 'c', POPT_ARG_STRING, &category_name, 0, "Install entry into this category", "CATEGORY" },
00068 {"replace", 0, POPT_ARG_VAL, &replace_category, 1, "Replace all entries in category by this one"},
00069 POPT_TABLEEND
00070 };
00071
00072
00073 theExpense.amount=theExpense.vendor=theExpense.city=
00074 theExpense.attendees=theExpense.note = NULL ;
00075
00076 po = poptGetContext("pilot-install-expenses", argc, argv, options, 0);
00077 poptSetOtherOptionHelp(po,"\n\n"
00078 " Install Expense application entries to your Palm device\n\n"
00079 " Example arguments:\n"
00080 " %s -p /dev/pilot -c Unfiled -t Cash -e Meals -a 10.00 -V McDonalds \n"
00081 " -g 21 -l \"San Francisco\" -N \"This is a note\"\n\n");
00082
00083 if (argc < 2) {
00084 poptPrintUsage(po,stderr,0);
00085 return 1;
00086 }
00087
00088 while ((po_err = poptGetNextOpt(po)) >= 0) {
00089 fprintf(stderr," ERROR: Unhandled option %d.\n",po_err);
00090 return 1;
00091 }
00092
00093 theExpense.type = etBus;
00094 found = 0;
00095 for (i = 0; expenseType && ExpenseTypeNames[i] != NULL; i++)
00096 {
00097 if (strcasecmp(expenseType, ExpenseTypeNames[i]) == 0)
00098 {
00099 theExpense.type = i;
00100 found = 1;
00101 break;
00102 }
00103 }
00104 if (!found) {
00105 fprintf(stderr," WARNING: Expense type '%s' not recognized, using 'Bus Fare'.\n",expenseType);
00106 }
00107
00108 theExpense.payment = epCash;
00109 found = 0;
00110 for (i = 0; paymentType && ExpensePaymentNames[i] != NULL; i++)
00111 {
00112 if (strcasecmp(paymentType, ExpensePaymentNames[i]) == 0)
00113 {
00114 theExpense.payment = i;
00115 found = 1;
00116 break;
00117 }
00118 }
00119 if (!found) {
00120 fprintf(stderr," WARNING: Payment type '%s' not recognized, using 'Cash'.\n", paymentType);
00121 }
00122
00123 if (replace_category && (!category_name)) {
00124 fprintf(stderr,
00125 " ERROR: category required when specifying replace\n");
00126 return 1;
00127 }
00128
00129
00130 if (!(theExpense.amount || theExpense.vendor || theExpense.city ||
00131 theExpense.attendees ||theExpense.note)) {
00132 fprintf(stderr," ERROR: Must specify at least one of amount, vendor, city, attendees or note.\n");
00133 return 1;
00134 }
00135
00136 sd = plu_connect();
00137 if (sd < 0)
00138 goto error;
00139
00140 if (dlp_OpenConduit(sd) < 0)
00141 goto error_close;
00142
00143 dlp_ReadUserInfo(sd, &User);
00144 dlp_OpenConduit(sd);
00145
00146
00147 if (dlp_OpenDB(sd, 0, 0x80 | 0x40, Expense_DB, &db) < 0) {
00148 fprintf(stderr," ERROR: Unable to open ExpenseDB on Palm.");
00149 dlp_AddSyncLogEntry(sd, "Unable to open ExpenseDB.\n");
00150 goto error_close;
00151 }
00152
00153 appblock = pi_buffer_new(0xffff);
00154 l = dlp_ReadAppBlock(sd, db, 0, 0xffff, appblock);
00155 unpack_ExpenseAppInfo(&eai, appblock->data, l);
00156 pi_buffer_free(appblock);
00157
00158 category = 0;
00159 if (category_name) {
00160 category = plu_findcategory(&eai.category,category_name,
00161 PLU_CAT_CASE_INSENSITIVE | PLU_CAT_WARN_UNKNOWN);
00162 if (category < 0) {
00163 goto error_close;
00164 }
00165
00166 if (replace_category) {
00167 dlp_DeleteCategory(sd, db, category);
00168 }
00169
00170 }
00171
00172 theExpense.currency = 0;
00173
00174 if (!theExpense.amount) {
00175 theExpense.amount = "";
00176 }
00177 if (!theExpense.vendor) {
00178 theExpense.vendor = "";
00179 }
00180 if (!theExpense.city) {
00181 theExpense.city = "";
00182 }
00183 if (!theExpense.attendees) {
00184 theExpense.attendees = "";
00185 }
00186 if (!theExpense.note) {
00187 theExpense.note = "";
00188 }
00189
00190 b = buf;
00191
00192
00193 *(b++) = 0xc3;
00194 *(b++) = 0x45;
00195
00196 *(b++) = theExpense.type;
00197 *(b++) = theExpense.payment;
00198 *(b++) = theExpense.currency;
00199 *(b++) = 0x00;
00200
00201 strcpy(b, theExpense.amount);
00202 b += strlen(theExpense.amount) + 1;
00203
00204 strcpy(b, theExpense.vendor);
00205 b += strlen(theExpense.vendor) + 1;
00206
00207 strcpy(b, theExpense.city);
00208 b += strlen(theExpense.city) + 1;
00209
00210 strcpy(b, theExpense.attendees);
00211 b += strlen(theExpense.attendees) + 1;
00212
00213 strcpy(b, theExpense.note);
00214 b += strlen(theExpense.note) + 1;
00215
00216 size = b - buf;
00217 dlp_WriteRecord(sd, (unsigned char)db, 0, 0, category,
00218 (unsigned char *)buf, size, 0);
00219
00220
00221 dlp_CloseDB(sd, db);
00222
00223
00224 User.lastSyncPC = 0x00010000;
00225 User.successfulSyncDate = time(NULL);
00226 User.lastSyncDate = User.successfulSyncDate;
00227 dlp_WriteUserInfo(sd, &User);
00228
00229 dlp_AddSyncLogEntry(sd, "Wrote expense entry to Palm.\n");
00230 dlp_EndOfSync(sd, 0);
00231 pi_close(sd);
00232 poptFreeContext(po);
00233 return 0;
00234
00235 error_close:
00236 pi_close(sd);
00237
00238 error:
00239 return -1;
00240 }
00241
00242
00243
00244
00245
00246
00247