"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "utils.c" between
jpilot-1.8.2.tar.gz and jpilot-2_0_1.tar.gz

About: J-Pilot is a desktop organizer application for Palm Pilot (PalmOS) devices. Ported to GTK3.

utils.c  (jpilot-1.8.2):utils.c  (jpilot-2_0_1)
skipping to change at line 29 skipping to change at line 29
******************************************************************************/ ******************************************************************************/
#include "config.h" #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <utime.h> #include <utime.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#ifdef USE_FLOCK #ifdef USE_FLOCK
# include <sys/file.h> # include <sys/file.h>
#else #else
# include <fcntl.h> # include <fcntl.h>
#endif #endif
#include <pi-source.h> #include <pi-source.h>
#include "utils.h" #include "utils.h"
#include "i18n.h" #include "i18n.h"
#include "log.h" #include "log.h"
#include "prefs.h" #include "prefs.h"
#include "sync.h" #include "sync.h"
#include "plugins.h" #include "plugins.h"
skipping to change at line 61 skipping to change at line 64
#define NUM_CAT_ITEMS 16 #define NUM_CAT_ITEMS 16
#define DAY_IN_SECS 86400 #define DAY_IN_SECS 86400
/* RFC2445 line length is 75. This length does not include value field such as /* RFC2445 line length is 75. This length does not include value field such as
* "DESCRIPTION:" which brings line length to nearly 75. */ * "DESCRIPTION:" which brings line length to nearly 75. */
#define ICAL_LINE_LENGTH 58 #define ICAL_LINE_LENGTH 58
/* RFCs require CRLF for newline */ /* RFCs require CRLF for newline */
#define CRLF "\x0D\x0A" #define CRLF "\x0D\x0A"
#define CR '\x0D' #define CR '\x0D'
#define LF '\x0A' #define LF '\x0A'
#define min(a,b) (((a) < (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b))
/* Uncomment for verbose debugging of the alarm code */ /* Uncomment for verbose debugging of the alarm code */
/* #define ALARMS_DEBUG */ /* #define ALARMS_DEBUG */
/******************************* Global vars **********************************/ /******************************* Global vars **********************************/
/* Stuff for the dialog window */ /* Stuff for the dialog window */
extern GtkWidget *glob_dialog; extern GtkWidget *glob_dialog;
extern GtkWidget *glob_date_label; extern GtkWidget *glob_date_label;
static int dialog_result; static int dialog_result;
unsigned int glob_find_id; unsigned int glob_find_id;
int glob_mouse_pressed = 0;
/* GTK_TIMEOUT timer identifer for "Today:" label */ /* GTK_TIMEOUT timer identifer for "Today:" label */
extern gint glob_date_timer_tag; extern gint glob_date_timer_tag;
/****************************** Prototypes ************************************/ /****************************** Prototypes ************************************/
static gboolean cb_destroy(GtkWidget *widget); static gboolean cb_destroy(GtkWidget *widget);
static void cb_quit(GtkWidget *widget, gpointer data); static void cb_quit(GtkWidget *widget, gpointer data);
static void cb_today(GtkWidget *widget, gpointer data); static void cb_today(GtkWidget *widget, gpointer data);
static int write_to_next_id(unsigned int unique_id); static int write_to_next_id(unsigned int unique_id);
static int write_to_next_id_open(FILE *pc_out, unsigned int unique_id); static int write_to_next_id_open(FILE *pc_out, unsigned int unique_id);
static int forward_backward_in_ce_time(const struct CalendarEvent *cale, static int forward_backward_in_ce_time(const struct CalendarEvent *cale,
struct tm *t, struct tm *t,
int forward_or_backward); int forward_or_backward);
static int str_to_iv_str(char *dest, int destsz, char *src, int isical); static int str_to_iv_str(char *dest, int destsz, char *src, int isical);
static struct name_list *dir_list=NULL;
/****************************** Main Code *************************************/ /****************************** Main Code *************************************/
/* /*
* This is a slow algorithm, but its not used much * This is a slow algorithm, but its not used much
*/ */
int add_days_to_date(struct tm *date, int n) int add_days_to_date(struct tm *date, int n) {
{ int ndim;
int ndim; int fdom;
int fdom; int flag;
int flag; int i;
int i;
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim);
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim); for (i = 0; i < n; i++) {
for (i=0; i<n; i++) { flag = 0;
flag = 0; if (++(date->tm_mday) > ndim) {
if (++(date->tm_mday) > ndim) { date->tm_mday = 1;
date->tm_mday=1;
flag = 1;
if (++(date->tm_mon) > 11) {
date->tm_mon=0;
flag = 1; flag = 1;
if (++(date->tm_year)>137) { if (++(date->tm_mon) > 11) {
date->tm_year = 137; date->tm_mon = 0;
flag = 1;
if (++(date->tm_year) > 137) {
date->tm_year = 137;
}
} }
} }
} if (flag) {
if (flag) { get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim);
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim); }
} }
} date->tm_isdst = -1;
date->tm_isdst=-1; mktime(date);
mktime(date);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* This function will increment the date by n number of months and * This function will increment the date by n number of months and
* adjust the day to the last day of the month if it exceeds the number * adjust the day to the last day of the month if it exceeds the number
* of days in the new month * of days in the new month
*/ */
int add_months_to_date(struct tm *date, int n) int add_months_to_date(struct tm *date, int n) {
{ int i;
int i; int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
int days_in_month[]={31,28,31,30,31,30,31,31,30,31,30,31 };
};
for (i = 0; i < n; i++) {
for (i=0; i<n; i++) { if (++(date->tm_mon) > 11) {
if (++(date->tm_mon) > 11) { date->tm_mon = 0;
date->tm_mon=0; if (++(date->tm_year) > 137) {
if (++(date->tm_year)>137) { date->tm_year = 137;
date->tm_year = 137; }
} }
} }
}
if ((date->tm_year%4 == 0) &&
!(((date->tm_year+1900)%100==0) && ((date->tm_year+1900)%400!=0))) {
days_in_month[1]++;
}
if (date->tm_mday > days_in_month[date->tm_mon]) {
date->tm_mday = days_in_month[date->tm_mon];
}
date->tm_isdst=-1; if ((date->tm_year % 4 == 0) &&
mktime(date); !(((date->tm_year + 1900) % 100 == 0) && ((date->tm_year + 1900) % 400 !
return EXIT_SUCCESS; = 0))) {
days_in_month[1]++;
}
if (date->tm_mday > days_in_month[date->tm_mon]) {
date->tm_mday = days_in_month[date->tm_mon];
}
date->tm_isdst = -1;
mktime(date);
return EXIT_SUCCESS;
} }
/* /*
* This function will increment the date by n number of years and * This function will increment the date by n number of years and
* adjust feb 29th to feb 28th if its not a leap year * adjust feb 29th to feb 28th if its not a leap year
*/ */
static int add_or_sub_years_to_date(struct tm *date, int n) static int add_or_sub_years_to_date(struct tm *date, int n) {
{ date->tm_year += n;
date->tm_year += n;
if (date->tm_year>137) { if (date->tm_year > 137) {
date->tm_year = 137; date->tm_year = 137;
} }
if (date->tm_year<3) { if (date->tm_year < 3) {
date->tm_year = 3; date->tm_year = 3;
} }
/* Leap day/year */ /* Leap day/year */
if ((date->tm_mon==1) && (date->tm_mday==29)) { if ((date->tm_mon == 1) && (date->tm_mday == 29)) {
if (!((date->tm_year%4 == 0) && if (!((date->tm_year % 4 == 0) &&
!(((date->tm_year+1900)%100==0) && ((date->tm_year+1900)%400!=0)))) !(((date->tm_year + 1900) % 100 == 0) && ((date->tm_year + 1900) %
{ 400 != 0)))) {
/* Move it back one day */ /* Move it back one day */
date->tm_mday=28; date->tm_mday = 28;
} }
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int add_years_to_date(struct tm *date, int n) int add_years_to_date(struct tm *date, int n) {
{ return add_or_sub_years_to_date(date, n);
return add_or_sub_years_to_date(date, n);
} }
/* This function is passed a bounded event description before it appears /* This function is passed a bounded event description before it appears
* on the gui (read-only) views. It checks if the event is a yearly repeat * on the gui (read-only) views. It checks if the event is a yearly repeat
* (i.e. an anniversary) and then if the last 4 characters look like a * (i.e. an anniversary) and then if the last 4 characters look like a
* year. If so then it appends a "number of years" to the description. * year. If so then it appends a "number of years" to the description.
* This is handy for viewing ages on birthdays etc. */ * This is handy for viewing ages on birthdays etc. */
/* Either a or cale can be passed as NULL */ /* Either a or cale can be passed as NULL */
void append_anni_years(char *desc, int max, struct tm *date, void append_anni_years(char *desc, int max, struct tm *date,
struct Appointment *appt, struct CalendarEvent *cale) struct Appointment *appt, struct CalendarEvent *cale) {
{ int len;
int len; int year;
int year; /* Only append the years if this is a yearly repeating type (i.e. an
/* Only append the years if this is a yearly repeating type (i.e. an
* anniversary) */ * anniversary) */
if ((!appt) && (!cale)) { if ((!appt) && (!cale)) {
return; return;
} }
if ((appt) && (appt->repeatType != repeatYearly)) if ((appt) && (appt->repeatType != repeatYearly))
return; return;
if ((cale) && (cale->repeatType != repeatYearly)) if ((cale) && (cale->repeatType != calendarRepeatYearly))
return; return;
/* Only display this if the user option is enabled */ /* Only display this if the user option is enabled */
if (!get_pref_int_default(PREF_DATEBOOK_ANNI_YEARS, FALSE)) if (!get_pref_int_default(PREF_DATEBOOK_ANNI_YEARS, FALSE))
return; return;
len = strlen(desc); len = strlen(desc);
/* Make sure we have room to insert what we want */ /* Make sure we have room to insert what we want */
if (len < 4 || len > (max - 7)) if (len < 4 || len > (max - 7))
return; return;
/* Get and check for a year */ /* Get and check for a year */
year = strtoul(&desc[len - 4], NULL, 10); year = strtoul(&desc[len - 4], NULL, 10);
/* Only allow up to 3 digits to be added */ /* Only allow up to 3 digits to be added */
if (year < 1100 || year > 3000) if (year < 1100 || year > 3000)
return; return;
/* Append the number of years */ /* Append the number of years */
sprintf(&desc[len], " (%d)", 1900 + date->tm_year - year); sprintf(&desc[len], " (%d)", 1900 + date->tm_year - year);
} }
static const char b64_dict[65] = { static const char b64_dict[65] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
"0123456789+/=" }; "0123456789+/="};
static void base64_out(FILE *f, unsigned char *str) static void base64_out(FILE *f, unsigned char *str) {
{ unsigned char *index, char1, char2, char3;
unsigned char *index, char1, char2, char3; int loop, pad;
int loop, pad;
loop = strlen((char *) str) / 3; // process groups of 3 chars at a time
loop = strlen((char *)str)/3; // process groups of 3 chars at a time pad = strlen((char *) str) % 3; // must pad if str not multiple of 3
pad = strlen((char *)str) % 3; // must pad if str not multiple of 3
/* Convert 3 bytes at a time. Padding at end calculated separately */
/* Convert 3 bytes at a time. Padding at end calculated separately */ for (index = str; loop > 0; loop--, index += 3) {
for (index = str; loop>0; loop--, index+=3) { char1 = *index;
char1 = *index; char2 = *(index+1); char3 = *(index+2); char2 = *(index + 1);
fputc(b64_dict[char1>>2], f); char3 = *(index + 2);
fputc(b64_dict[(char1<<4 & 0x30) | (char2>>4)], f); fputc(b64_dict[char1 >> 2], f);
fputc(b64_dict[(char2<<2 & 0x3c) | (char3>>6)], f); fputc(b64_dict[(char1 << 4 & 0x30) | (char2 >> 4)], f);
fputc(b64_dict[char3 & 0x3f], f); fputc(b64_dict[(char2 << 2 & 0x3c) | (char3 >> 6)], f);
} fputc(b64_dict[char3 & 0x3f], f);
}
/* Now deal with the trailing bytes */ /* Now deal with the trailing bytes */
if (pad) if (pad) {
{ char1 = *index;
char1 = *index; char2 = *(index+1); char3 = *(index+2); char2 = *(index + 1);
fputc(b64_dict[char1>>2], f); char3 = *(index + 2);
fputc(b64_dict[(char1<<4 & 0x30) | (pad==2 ? char2>>4 : 0)], f ); fputc(b64_dict[char1 >> 2], f);
fputc(pad==1 ? '=' : b64_dict[(char2<<2 & 0x3c)], f ); fputc(b64_dict[(char1 << 4 & 0x30) | (pad == 2 ? char2 >> 4 : 0)], f);
fputc('=', f); fputc(pad == 1 ? '=' : b64_dict[(char2 << 2 & 0x3c)], f);
} fputc('=', f);
}
} }
static unsigned int bytes_to_bin(unsigned char *bytes, unsigned int num_bytes) static unsigned int bytes_to_bin(unsigned char *bytes, unsigned int num_bytes) {
{ unsigned int i, n;
unsigned int i, n; n = 0;
n=0; for (i = 0; i < num_bytes; i++) {
for (i=0;i<num_bytes;i++) { n = n * 256 + bytes[i];
n = n*256+bytes[i]; }
} return n;
return n;
} }
/* mon 0-11 /* mon 0-11
* day 1-31 * day 1-31
* year (year - 1900) * year (year - 1900)
* This function will bring up the cal at mon, day, year * This function will bring up the cal at mon, day, year
* After a new date is selected it will return mon, day, year * After a new date is selected it will return mon, day, year
*/ */
int cal_dialog(GtkWindow *main_window, int cal_dialog(GtkWindow *main_window,
const char *title, int monday_is_fdow, const char *title, int monday_is_fdow,
int *mon, int *day, int *year) int *mon, int *day, int *year) {
{ GtkWidget *button;
GtkWidget *button; GtkWidget *vbox;
GtkWidget *vbox; GtkWidget *hbox;
GtkWidget *hbox; GtkWidget *cal;
GtkWidget *cal; GtkWidget *window;
GtkWidget *window; int return_code;
int return_code;
glob_mouse_pressed = 0;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), title); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE); gtk_window_set_title(GTK_WINDOW(window), title);
gtk_window_set_modal(GTK_WINDOW(window), TRUE); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(main_window)); gtk_window_set_modal(GTK_WINDOW(window), TRUE);
gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(main_window));
gtk_signal_connect(GTK_OBJECT(window), "destroy",
GTK_SIGNAL_FUNC(cb_destroy), window); g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(cb_destroy), window);
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox); vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
cal = gtk_calendar_new();
gtk_box_pack_start(GTK_BOX(vbox), cal, TRUE, TRUE, 0); cal = gtk_calendar_new();
gtk_box_pack_start(GTK_BOX(vbox), cal, TRUE, TRUE, 0);
hbox = gtk_hbutton_box_new();
gtk_container_set_border_width(GTK_CONTAINER(hbox), 12); hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END); gtk_container_set_border_width(GTK_CONTAINER(hbox), 12);
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 6); gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_END);
gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_box_set_spacing(GTK_BOX(hbox), 6);
gtk_container_add(GTK_CONTAINER(vbox), hbox);
gtk_calendar_display_options(GTK_CALENDAR(cal),
GTK_CALENDAR_SHOW_HEADING | gtk_calendar_set_display_options(GTK_CALENDAR(cal),
GTK_CALENDAR_SHOW_DAY_NAMES | GTK_CALENDAR_SHOW_HEADING |
GTK_CALENDAR_SHOW_WEEK_NUMBERS | GTK_CALENDAR_SHOW_DAY_NAMES |
(monday_is_fdow ? GTK_CALENDAR_WEEK_START_MONDAY GTK_CALENDAR_SHOW_WEEK_NUMBERS);
: 0));
/* g_signal_connect(G_OBJECT(cal), "day_selected", cb_cal_sel, NULL); */
/* gtk_signal_connect(GTK_OBJECT(cal), "day_selected", cb_cal_sel, NULL); */ g_signal_connect(G_OBJECT(cal), "day_selected_double_click", G_CALLBACK(cb_q
gtk_signal_connect(GTK_OBJECT(cal), "day_selected_double_click", GTK_SIGNAL_F uit),
UNC(cb_quit), GINT_TO_POINTER(CAL_DONE));
GINT_TO_POINTER(CAL_DONE));
gtk_calendar_select_month(GTK_CALENDAR(cal), *mon, (*year) + 1900);
gtk_calendar_select_month(GTK_CALENDAR(cal), *mon, (*year)+1900); gtk_calendar_select_day(GTK_CALENDAR(cal), *day);
gtk_calendar_select_day(GTK_CALENDAR(cal), *day);
/* Cancel/Today/OK buttons */
/* Cancel/Today/OK buttons */ button = gtk_button_new_with_label("Cancel");
button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_quit),
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cb_quit), GINT_TO_POINTER(CAL_CANCEL));
GINT_TO_POINTER(CAL_CANCEL));
button = gtk_button_new_with_label(_("Today"));
button = gtk_button_new_with_label(_("Today")); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked",
gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(cb_today), cal);
GTK_SIGNAL_FUNC(cb_today), cal);
button = gtk_button_new_with_label("OK");
button = gtk_button_new_from_stock(GTK_STOCK_OK); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cb_quit),
gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cb_quit), GINT_TO_POINTER(CAL_DONE));
GINT_TO_POINTER(CAL_DONE));
g_object_set_data(G_OBJECT(window), "mon", mon);
gtk_object_set_data(GTK_OBJECT(window), "mon", mon); g_object_set_data(G_OBJECT(window), "day", day);
gtk_object_set_data(GTK_OBJECT(window), "day", day); g_object_set_data(G_OBJECT(window), "year", year);
gtk_object_set_data(GTK_OBJECT(window), "year", year); g_object_set_data(G_OBJECT(window), "return_code", &return_code);
gtk_object_set_data(GTK_OBJECT(window), "return_code", &return_code); g_object_set_data(G_OBJECT(window), "cal", cal);
gtk_object_set_data(GTK_OBJECT(window), "cal", cal);
gtk_widget_show_all(window);
gtk_widget_show_all(window);
gtk_main();
gtk_main();
if (return_code == CAL_DONE) {
if (return_code == CAL_DONE) { *year -= 1900;
*year -= 1900; }
}
return return_code;
return return_code; }
}
int cat_compare(const void *v1, const void *v2) {
struct sorted_cats *s1, *s2;
s1 = (struct sorted_cats *) v1;
s2 = (struct sorted_cats *) v2;
if ((s1)->Pcat[0] == '\0') {
return 1;
}
if ((s2)->Pcat[0] == '\0') {
return -1;
}
return strcmp((s1)->Pcat, (s2)->Pcat);
}
static gboolean cb_destroy(GtkWidget *widget) {
gtk_main_quit();
return FALSE;
}
static gboolean cb_destroy_dialog(GtkWidget *widget) {
glob_dialog = NULL;
gtk_main_quit();
int cat_compare(const void *v1, const void *v2) return FALSE;
{
struct sorted_cats *s1, *s2;
s1=(struct sorted_cats *)v1; s2=(struct sorted_cats *)v2;
if ((s1)->Pcat[0]=='\0') {
return 1;
}
if ((s2)->Pcat[0]=='\0') {
return -1;
}
return strcmp((s1)->Pcat, (s2)->Pcat);
}
static gboolean cb_destroy(GtkWidget *widget)
{
gtk_main_quit();
return FALSE;
}
static gboolean cb_destroy_dialog(GtkWidget *widget)
{
glob_dialog = NULL;
gtk_main_quit();
return FALSE;
} }
static void cb_dialog_button(GtkWidget *widget, static void cb_dialog_button(GtkWidget *widget,
gpointer data) gpointer data) {
{ dialog_result = GPOINTER_TO_INT(data);
dialog_result=GPOINTER_TO_INT(data);
gtk_widget_destroy(glob_dialog);
}
static void cb_quit(GtkWidget *widget, gpointer data)
{
unsigned int y,m,d;
unsigned int *Py,*Pm,*Pd;
int *Preturn_code;
GtkWidget *cal=NULL;
GtkWidget *window;
window = gtk_widget_get_toplevel(widget);
Preturn_code = gtk_object_get_data(GTK_OBJECT(window), "return_code");
if (Preturn_code) *Preturn_code = GPOINTER_TO_INT(data);
cal = gtk_object_get_data(GTK_OBJECT(window), "cal");
if (Preturn_code && *Preturn_code==CAL_DONE) {
if (cal) {
gtk_calendar_get_date(GTK_CALENDAR(cal),&y,&m,&d);
Pm = gtk_object_get_data(GTK_OBJECT(window), "mon");
Pd = gtk_object_get_data(GTK_OBJECT(window), "day");
Py = gtk_object_get_data(GTK_OBJECT(window), "year");
if (Pm) *Pm=m;
if (Pd) *Pd=d;
if (Py) *Py=y;
}
}
gtk_widget_destroy(window); gtk_widget_destroy(glob_dialog);
} }
static void cb_today(GtkWidget *widget, gpointer data) static void cb_quit(GtkWidget *widget, gpointer data) {
{ unsigned int y, m, d;
time_t ltime; unsigned int *Py, *Pm, *Pd;
struct tm *now; int *Preturn_code;
GtkWidget *cal; GtkWidget *cal = NULL;
GtkWidget *window;
cal = data;
time(&ltime); window = gtk_widget_get_toplevel(widget);
now = localtime(&ltime);
Preturn_code = g_object_get_data(G_OBJECT(window), "return_code");
if (Preturn_code) *Preturn_code = GPOINTER_TO_INT(data);
cal = g_object_get_data(G_OBJECT(window), "cal");
if (Preturn_code && *Preturn_code == CAL_DONE) {
if (cal) {
gtk_calendar_get_date(GTK_CALENDAR(cal), &y, &m, &d);
Pm = g_object_get_data(G_OBJECT(window), "mon");
Pd = g_object_get_data(G_OBJECT(window), "day");
Py = g_object_get_data(G_OBJECT(window), "year");
if (Pm) *Pm = m;
if (Pd) *Pd = d;
if (Py) *Py = y;
}
}
gtk_widget_destroy(window);
}
static void cb_today(GtkWidget *widget, gpointer data) {
time_t ltime;
struct tm *now;
GtkWidget *cal;
cal = data;
time(&ltime);
now = localtime(&ltime);
gtk_calendar_select_month(GTK_CALENDAR(cal), now->tm_mon, now->tm_year+1900); gtk_calendar_select_month(GTK_CALENDAR(cal), now->tm_mon, now->tm_year + 190
gtk_calendar_select_day(GTK_CALENDAR(cal), now->tm_mday); 0);
gtk_calendar_select_day(GTK_CALENDAR(cal), now->tm_mday);
} }
/* /*
* JPA overwrite a host character set string by its * JPA overwrite a host character set string by its
* conversion to a Palm Pilot character string * conversion to a Palm Pilot character string
*/ */
void charset_j2p(char *buf, int max_len, long char_set) void charset_j2p(char *buf, int max_len, long char_set) {
{ switch (char_set) {
switch (char_set) { case CHAR_SET_JAPANESE:
case CHAR_SET_JAPANESE: Euc2Sjis(buf, max_len); break; Euc2Sjis(buf, max_len);
case CHAR_SET_LATIN1 : /* No conversion required */ break; break;
case CHAR_SET_1250 : Lat2Win(buf,max_len); break; case CHAR_SET_LATIN1 : /* No conversion required */ break;
case CHAR_SET_1251 : koi8_to_win1251(buf, max_len); break; case CHAR_SET_1250 :
case CHAR_SET_1251_B : win1251_to_koi8(buf, max_len); break; Lat2Win(buf, max_len);
default: break;
UTF_to_other(buf, max_len); case CHAR_SET_1251 :
break; koi8_to_win1251(buf, max_len);
} break;
case CHAR_SET_1251_B :
win1251_to_koi8(buf, max_len);
break;
default:
UTF_to_other(buf, max_len);
break;
}
} }
/* /*
* JPA overwrite a Palm Pilot character string by its * JPA overwrite a Palm Pilot character string by its
* conversion to host character set * conversion to host character set
*/ */
void charset_p2j(char *const buf, int max_len, int char_set) void charset_p2j(char *const buf, int max_len, int char_set) {
{ char *newbuf;
char *newbuf; gchar *end;
gchar *end;
newbuf = charset_p2newj(buf, max_len, char_set);
g_strlcpy(buf, newbuf, max_len);
if (strlen(newbuf) >= max_len) {
jp_logf(JP_LOG_WARN, "charset_p2j: buffer too small - original string be
fore truncation [%s]\n", newbuf);
if (char_set > CHAR_SET_UTF) {
/* truncate the string on a UTF-8 character boundary */
if (!g_utf8_validate(buf, -1, (const gchar **) &end))
*end = 0;
}
}
newbuf = charset_p2newj(buf, max_len, char_set); free(newbuf);
g_strlcpy(buf, newbuf, max_len);
if (strlen(newbuf) >= max_len) {
jp_logf(JP_LOG_WARN, "charset_p2j: buffer too small - original string befo
re truncation [%s]\n", newbuf);
if (char_set > CHAR_SET_UTF) {
/* truncate the string on a UTF-8 character boundary */
if (!g_utf8_validate(buf, -1, (const gchar **)&end))
*end = 0;
}
}
free(newbuf);
} }
/* /*
* JPA convert a Palm Pilot character string to host * JPA convert a Palm Pilot character string to host
* equivalent without overwriting * equivalent without overwriting
*/ */
char *charset_p2newj(const char *buf, int max_len, int char_set) char *charset_p2newj(const char *buf, int max_len, int char_set) {
{ char *newbuf = NULL;
char *newbuf = NULL;
/* Allocate a longer buffer if not done in conversion routine. /* Allocate a longer buffer if not done in conversion routine.
* Only old conversion routines don't assign a buffer */ * Only old conversion routines don't assign a buffer */
switch (char_set) { switch (char_set) {
case CHAR_SET_JAPANESE: case CHAR_SET_JAPANESE:
if (max_len == -1) { if (max_len == -1) {
max_len = 2*strlen(buf) + 1; max_len = 2 * strlen(buf) + 1;
newbuf = g_malloc(max_len); newbuf = g_malloc(max_len);
} else { } else {
newbuf = g_malloc(min(2*strlen(buf) + 1, max_len)); newbuf = g_malloc(min(2 * strlen(buf) + 1, max_len));
} }
if (newbuf) { if (newbuf) {
/* be safe, though string should fit into buf */ /* be safe, though string should fit into buf */
g_strlcpy(newbuf, buf, max_len); g_strlcpy(newbuf, buf, max_len);
} }
break; break;
case CHAR_SET_LATIN1: case CHAR_SET_LATIN1:
case CHAR_SET_1250: case CHAR_SET_1250:
case CHAR_SET_1251: case CHAR_SET_1251:
case CHAR_SET_1251_B: case CHAR_SET_1251_B:
if (max_len == -1) { if (max_len == -1) {
max_len = strlen(buf) + 1; max_len = strlen(buf) + 1;
newbuf = g_malloc(max_len); newbuf = g_malloc(max_len);
} else { } else {
newbuf = g_malloc(min(strlen(buf) + 1, max_len)); newbuf = g_malloc(min(strlen(buf) + 1, max_len));
} }
if (newbuf) { if (newbuf) {
/* be safe, though string should fit into buf */ /* be safe, though string should fit into buf */
g_strlcpy(newbuf, buf, max_len); g_strlcpy(newbuf, buf, max_len);
} }
break; break;
default: default:
/* All other encodings get a new buffer from other_to_UTF */ /* All other encodings get a new buffer from other_to_UTF */
break; break;
} }
/* Now convert character encoding */ /* Now convert character encoding */
switch (char_set) { switch (char_set) {
case CHAR_SET_JAPANESE : Sjis2Euc(newbuf, max_len); break; case CHAR_SET_JAPANESE :
case CHAR_SET_LATIN1 : /* No conversion required */ break; Sjis2Euc(newbuf, max_len);
case CHAR_SET_1250 : Win2Lat(newbuf, max_len); break; break;
case CHAR_SET_1251 : win1251_to_koi8(newbuf, max_len); break; case CHAR_SET_LATIN1 : /* No conversion required */ break;
case CHAR_SET_1251_B : koi8_to_win1251(newbuf, max_len); break; case CHAR_SET_1250 :
default: Win2Lat(newbuf, max_len);
newbuf = other_to_UTF(buf, max_len); break;
break; case CHAR_SET_1251 :
} win1251_to_koi8(newbuf, max_len);
break;
case CHAR_SET_1251_B :
koi8_to_win1251(newbuf, max_len);
break;
default:
newbuf = other_to_UTF(buf, max_len);
break;
}
return (newbuf); return (newbuf);
} }
/* This function will copy an empty DB file /* This function will copy an empty DB file
* from the share directory to the users JPILOT_HOME directory * from the share directory to the users JPILOT_HOME directory
* if it doesn't exist already and its length is > 0 */ * if it doesn't exist already and its length is > 0 */
int check_copy_DBs_to_home(void) int check_copy_DBs_to_home(void) {
{ FILE *in, *out;
FILE *in, *out; struct stat sbuf;
struct stat sbuf; int i, c, r;
int i, c, r; char destname[FILENAME_MAX];
char destname[FILENAME_MAX]; char srcname[FILENAME_MAX];
char srcname[FILENAME_MAX]; struct utimbuf times;
struct utimbuf times; char dbname_pdb[][32] = {
char dbname_pdb[][32]={ "DatebookDB.pdb",
"DatebookDB.pdb", "CalendarDB-PDat.pdb",
"CalendarDB-PDat.pdb", "AddressDB.pdb",
"AddressDB.pdb", "ContactsDB-PAdd.pdb",
"ContactsDB-PAdd.pdb", "ToDoDB.pdb",
"ToDoDB.pdb", "TasksDB-PTod.pdb",
"TasksDB-PTod.pdb", "MananaDB.pdb",
"MananaDB.pdb", "MemoDB.pdb",
"MemoDB.pdb", "MemosDB-PMem.pdb",
"MemosDB-PMem.pdb", "Memo32DB.pdb",
"Memo32DB.pdb", "ExpenseDB.pdb",
"ExpenseDB.pdb", ""
"" };
};
for (i = 0; dbname_pdb[i][0]; i++) {
for (i=0; dbname_pdb[i][0]; i++) { get_home_file_name(dbname_pdb[i], destname, sizeof(destname));
get_home_file_name(dbname_pdb[i], destname, sizeof(destname)); r = stat(destname, &sbuf);
r = stat(destname, &sbuf); if (((r) && (errno == ENOENT)) || (sbuf.st_size == 0)) {
if (((r)&&(errno==ENOENT)) || (sbuf.st_size==0)) { /* The file doesn't exist or is zero in size, copy an empty DB file
/* The file doesn't exist or is zero in size, copy an empty DB file */ */
if ((strlen(BASE_DIR) + strlen(EPN) + strlen(dbname_pdb[i])) > sizeof(s if ((strlen(BASE_DIR) + strlen(EPN) + strlen(dbname_pdb[i])) > sizeo
rcname)) { f(srcname)) {
jp_logf(JP_LOG_DEBUG, "copy_DB_to_home filename too long\n"); jp_logf(JP_LOG_DEBUG, "copy_DB_to_home filename too long\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
g_snprintf(srcname, sizeof(srcname), "%s/%s/%s/%s", BASE_DIR, "share", g_snprintf(srcname, sizeof(srcname), "%s/%s/%s/%s", BASE_DIR, "share
EPN, dbname_pdb[i]); ", EPN, dbname_pdb[i]);
in = fopen(srcname, "r"); in = fopen(srcname, "r");
out = fopen(destname, "w"); out = fopen(destname, "w");
if (!in) { if (!in) {
jp_logf(JP_LOG_WARN, _("Couldn't find empty DB file %s: %s\n"), jp_logf(JP_LOG_WARN, _("Couldn't find empty DB file %s: %s\n"),
srcname, strerror(errno)); srcname, strerror(errno));
jp_logf(JP_LOG_WARN, EPN); jp_logf(JP_LOG_WARN, EPN);
jp_logf(JP_LOG_WARN, _(" may not be installed.\n")); jp_logf(JP_LOG_WARN, _(" may not be installed.\n"));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!out) { if (!out) {
fclose(in);
return EXIT_FAILURE;
}
while ((c = fgetc(in)) != EOF) {
fputc(c, out);
}
fclose(in); fclose(in);
return EXIT_FAILURE; fclose(out);
} /* Set the dates on the file to be old (not up to date) */
while ( (c=fgetc(in)) != EOF ) { times.actime = 1;
fputc(c, out); times.modtime = 1;
} utime(destname, &times);
fclose(in); }
fclose(out); }
/* Set the dates on the file to be old (not up to date) */ return EXIT_SUCCESS;
times.actime = 1; }
times.modtime = 1;
utime(destname, &times); int check_hidden_dir(void) {
} struct stat statb;
} char hidden_dir[FILENAME_MAX];
return EXIT_SUCCESS;
}
int check_hidden_dir(void)
{
struct stat statb;
char hidden_dir[FILENAME_MAX];
get_home_file_name("", hidden_dir, sizeof(hidden_dir)); get_home_file_name("", hidden_dir, sizeof(hidden_dir));
hidden_dir[strlen(hidden_dir)-1]='\0'; hidden_dir[strlen(hidden_dir) - 1] = '\0';
if (stat(hidden_dir, &statb)) { if (stat(hidden_dir, &statb)) {
/* Directory isn't there, create it. /* Directory isn't there, create it.
* Only user is given permission to enter and change directory contents * Only user is given permission to enter and change directory contents
* which provides some primitive privacy protection. */ * which provides some primitive privacy protection. */
if (mkdir(hidden_dir, 0700)) { if (mkdir(hidden_dir, 0700)) {
/* Can't create directory */ /* Can't create directory */
jp_logf(JP_LOG_WARN, _("Can't create directory %s\n"), hidden_dir); jp_logf(JP_LOG_WARN, _("Can't create directory %s\n"), hidden_dir);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (stat(hidden_dir, &statb)) { if (stat(hidden_dir, &statb)) {
jp_logf(JP_LOG_WARN, _("Can't create directory %s\n"), hidden_dir); jp_logf(JP_LOG_WARN, _("Can't create directory %s\n"), hidden_dir);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
/* Is it a directory? */ /* Is it a directory? */
if (!S_ISDIR(statb.st_mode)) { if (!S_ISDIR(statb.st_mode)) {
jp_logf(JP_LOG_WARN, _("%s is not a directory\n"), hidden_dir); jp_logf(JP_LOG_WARN, _("%s is not a directory\n"), hidden_dir);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Can we write in it? */ /* Can we write in it? */
if (access(hidden_dir, W_OK) != 0) { if (access(hidden_dir, W_OK) != 0) {
jp_logf(JP_LOG_WARN, _("Unable to get write permission for directory %s\n" jp_logf(JP_LOG_WARN, _("Unable to get write permission for directory %s\
), hidden_dir); n"), hidden_dir);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* This function removes extra slashes from a string */ /* This function removes extra slashes from a string */
void cleanup_path(char *path) void cleanup_path(char *path) {
{ register int s, d; /* source and destination */
register int s, d; /* source and destination */
if (!path) return; if (!path) return;
for (s=d=0; path[s]!='\0'; s++,d++) { for (s = d = 0; path[s] != '\0'; s++, d++) {
if ((path[s]=='/') && (path[s+1]=='/')) { if ((path[s] == '/') && (path[s + 1] == '/')) {
d--; d--;
continue; continue;
} }
if (d!=s) { if (d != s) {
path[d]=path[s]; path[d] = path[s];
} }
} }
path[d]='\0'; path[d] = '\0';
} }
/* Compacts pc3 file by removing records which have been synced */ /* Compacts pc3 file by removing records which have been synced */
static int cleanup_pc_file(char *DB_name, unsigned int *max_id) static int cleanup_pc_file(char *DB_name, unsigned int *max_id) {
{ PC3RecordHeader header;
PC3RecordHeader header; char pc_filename[FILENAME_MAX];
char pc_filename[FILENAME_MAX]; char pc_filename2[FILENAME_MAX];
char pc_filename2[FILENAME_MAX]; FILE *pc_file;
FILE *pc_file; FILE *pc_file2;
FILE *pc_file2; char *record;
char *record; int r;
int r; int ret;
int ret; int num;
int num; int compact_it;
int compact_it; int next_id;
int next_id;
r = 0;
r=0; *max_id = 0;
*max_id = 0; next_id = 1;
next_id = 1; record = NULL;
record = NULL; pc_file = pc_file2 = NULL;
pc_file = pc_file2 = NULL;
g_snprintf(pc_filename, sizeof(pc_filename), "%s.pc3", DB_name);
g_snprintf(pc_filename, sizeof(pc_filename), "%s.pc3", DB_name); g_snprintf(pc_filename2, sizeof(pc_filename2), "%s.pct", DB_name);
g_snprintf(pc_filename2, sizeof(pc_filename2), "%s.pct", DB_name);
pc_file = jp_open_home_file(pc_filename, "r");
pc_file = jp_open_home_file(pc_filename , "r"); if (!pc_file) {
if (!pc_file) { return EXIT_FAILURE;
return EXIT_FAILURE; }
}
compact_it = 0;
compact_it = 0; /* Scan through the file and see if it needs to be compacted */
/* Scan through the file and see if it needs to be compacted */ while (!feof(pc_file)) {
while(!feof(pc_file)) { read_header(pc_file, &header);
read_header(pc_file, &header); if (feof(pc_file)) {
if (feof(pc_file)) { break;
break; }
} if (header.rt & SPENT_PC_RECORD_BIT) {
if (header.rt & SPENT_PC_RECORD_BIT) { compact_it = 1;
compact_it=1;
break;
}
if ((header.unique_id > *max_id)
&& (header.rt != PALM_REC)
&& (header.rt != MODIFIED_PALM_REC)
&& (header.rt != DELETED_PALM_REC)
&& (header.rt != REPLACEMENT_PALM_REC) ){
*max_id = header.unique_id;
}
if (fseek(pc_file, header.rec_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
}
}
if (!compact_it) {
jp_logf(JP_LOG_DEBUG, "No compacting needed\n");
jp_close_home_file(pc_file);
return EXIT_SUCCESS;
}
fseek(pc_file, 0, SEEK_SET);
pc_file2=jp_open_home_file(pc_filename2, "w");
if (!pc_file2) {
jp_close_home_file(pc_file);
return EXIT_FAILURE;
}
while(!feof(pc_file)) {
read_header(pc_file, &header);
if (feof(pc_file)) {
break;
}
if (header.rt & SPENT_PC_RECORD_BIT) {
r++;
if (fseek(pc_file, header.rec_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
r = -1;
break; break;
} }
continue; if ((header.unique_id > *max_id)
} else { && (header.rt != PALM_REC)
if (header.rt == NEW_PC_REC) { && (header.rt != MODIFIED_PALM_REC)
header.unique_id = next_id++; && (header.rt != DELETED_PALM_REC)
} && (header.rt != REPLACEMENT_PALM_REC)) {
if ((header.unique_id > *max_id)
&& (header.rt != PALM_REC)
&& (header.rt != MODIFIED_PALM_REC)
&& (header.rt != DELETED_PALM_REC)
&& (header.rt != REPLACEMENT_PALM_REC)
){
*max_id = header.unique_id; *max_id = header.unique_id;
} }
record = malloc(header.rec_len); if (fseek(pc_file, header.rec_len, SEEK_CUR)) {
if (!record) { jp_logf(JP_LOG_WARN, "fseek failed\n");
jp_logf(JP_LOG_WARN, "cleanup_pc_file(): %s\n", _("Out of memory")); }
r = -1; }
if (!compact_it) {
jp_logf(JP_LOG_DEBUG, "No compacting needed\n");
jp_close_home_file(pc_file);
return EXIT_SUCCESS;
}
fseek(pc_file, 0, SEEK_SET);
pc_file2 = jp_open_home_file(pc_filename2, "w");
if (!pc_file2) {
jp_close_home_file(pc_file);
return EXIT_FAILURE;
}
while (!feof(pc_file)) {
read_header(pc_file, &header);
if (feof(pc_file)) {
break; break;
} }
num = fread(record, header.rec_len, 1, pc_file); if (header.rt & SPENT_PC_RECORD_BIT) {
if (num != 1) { r++;
if (ferror(pc_file)) { if (fseek(pc_file, header.rec_len, SEEK_CUR)) {
r = -1; jp_logf(JP_LOG_WARN, "fseek failed\n");
break; r = -1;
break;
}
continue;
} else {
if (header.rt == NEW_PC_REC) {
header.unique_id = next_id++;
}
if ((header.unique_id > *max_id)
&& (header.rt != PALM_REC)
&& (header.rt != MODIFIED_PALM_REC)
&& (header.rt != DELETED_PALM_REC)
&& (header.rt != REPLACEMENT_PALM_REC)
) {
*max_id = header.unique_id;
}
record = malloc(header.rec_len);
if (!record) {
jp_logf(JP_LOG_WARN, "cleanup_pc_file(): %s\n", _("Out of memory
"));
r = -1;
break;
} }
} num = fread(record, header.rec_len, 1, pc_file);
ret = write_header(pc_file2, &header); if (num != 1) {
/* if (ret != 1) { if (ferror(pc_file)) {
r = -1;
break;
}
}
ret = write_header(pc_file2, &header);
/* if (ret != 1) {
r = -1; r = -1;
break; break;
}*/ }*/
ret = fwrite(record, header.rec_len, 1, pc_file2); ret = fwrite(record, header.rec_len, 1, pc_file2);
if (ret != 1) { if (ret != 1) {
r = -1; r = -1;
break; break;
} }
free(record); free(record);
record = NULL; record = NULL;
} }
} }
if (record) { if (record) {
free(record); free(record);
} }
if (pc_file) { if (pc_file) {
jp_close_home_file(pc_file); jp_close_home_file(pc_file);
} }
if (pc_file2) { if (pc_file2) {
jp_close_home_file(pc_file2); jp_close_home_file(pc_file2);
} }
if (r>=0) { if (r >= 0) {
rename_file(pc_filename2, pc_filename); rename_file(pc_filename2, pc_filename);
} else { } else {
unlink_file(pc_filename2); unlink_file(pc_filename2);
} }
return r; return r;
} }
/* Compact all pc3 files including plugins */ /* Compact all pc3 files including plugins */
int cleanup_pc_files(void) int cleanup_pc_files(void) {
{ int ret;
int ret; int fail_flag;
int fail_flag; unsigned int max_id, max_max_id;
unsigned int max_id, max_max_id;
#ifdef ENABLE_PLUGINS #ifdef ENABLE_PLUGINS
GList *plugin_list, *temp_list; GList *plugin_list, *temp_list;
struct plugin_s *plugin; struct plugin_s *plugin;
#endif #endif
int i; int i;
char dbname[][32]={ char dbname[][32] = {
"DatebookDB", "DatebookDB",
"AddressDB", "AddressDB",
"ToDoDB", "ToDoDB",
"MemoDB", "MemoDB",
"" ""
}; };
/* Convert to new database names depending on prefs */ /* Convert to new database names depending on prefs */
rename_dbnames(dbname); rename_dbnames(dbname);
fail_flag = 0; fail_flag = 0;
max_id = max_max_id = 0; max_id = max_max_id = 0;
for (i=0; dbname[i][0]; i++) { for (i = 0; dbname[i][0]; i++) {
jp_logf(JP_LOG_DEBUG, "cleanup_pc_file for %s\n", dbname[i]); jp_logf(JP_LOG_DEBUG, "cleanup_pc_file for %s\n", dbname[i]);
ret = cleanup_pc_file(dbname[i], &max_id); ret = cleanup_pc_file(dbname[i], &max_id);
jp_logf(JP_LOG_DEBUG, "max_id was %d\n", max_id); jp_logf(JP_LOG_DEBUG, "max_id was %d\n", max_id);
if (ret<0) { if (ret < 0) {
fail_flag=1; fail_flag = 1;
} else if (max_id > max_max_id) { } else if (max_id > max_max_id) {
max_max_id = max_id; max_max_id = max_id;
} }
} }
#ifdef ENABLE_PLUGINS #ifdef ENABLE_PLUGINS
plugin_list = get_plugin_list(); plugin_list = get_plugin_list();
for (temp_list = plugin_list; temp_list; temp_list = temp_list->next) { for (temp_list = plugin_list; temp_list; temp_list = temp_list->next) {
plugin = (struct plugin_s *)temp_list->data; plugin = (struct plugin_s *) temp_list->data;
if ((plugin->db_name==NULL) || (plugin->db_name[0]=='\0')) { if ((plugin->db_name == NULL) || (plugin->db_name[0] == '\0')) {
jp_logf(JP_LOG_DEBUG, "not calling cleanup_pc_file for: [%s]\n", plugin jp_logf(JP_LOG_DEBUG, "not calling cleanup_pc_file for: [%s]\n", plu
->db_name); gin->db_name);
continue; continue;
} }
jp_logf(JP_LOG_DEBUG, "cleanup_pc_file for [%s]\n", plugin->db_name); jp_logf(JP_LOG_DEBUG, "cleanup_pc_file for [%s]\n", plugin->db_name);
ret = cleanup_pc_file(plugin->db_name, &max_id); ret = cleanup_pc_file(plugin->db_name, &max_id);
jp_logf(JP_LOG_DEBUG, "max_id was %d\n", max_id); jp_logf(JP_LOG_DEBUG, "max_id was %d\n", max_id);
if (ret<0) { if (ret < 0) {
fail_flag=1; fail_flag = 1;
} else if (max_id > max_max_id) { } else if (max_id > max_max_id) {
max_max_id = max_id; max_max_id = max_id;
} }
} }
#endif #endif
if (!fail_flag) { if (!fail_flag) {
write_to_next_id(max_max_id); write_to_next_id(max_max_id);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* returns 0 if not found, 1 if found */ /* returns 0 if not found, 1 if found */
int clist_find_id(GtkWidget *clist,
unsigned int unique_id,
int *found_at)
{
int i, found;
MyAddress *maddr;
*found_at = 0;
for (found = i = 0; i<GTK_CLIST(clist)->rows; i++) {
maddr = gtk_clist_get_row_data(GTK_CLIST(clist), i);
if (maddr < (MyAddress *)CLIST_MIN_DATA) {
break;
}
if (maddr->unique_id==unique_id) {
found = TRUE;
*found_at = i;
break;
}
}
return found;
}
/* Encapsulate GTK function to make it free all resources */
void clist_clear(GtkCList *clist)
{
GtkStyle *base_style, *row_style;
int i;
base_style = gtk_widget_get_style(GTK_WIDGET(clist));
for (i=0; i<GTK_CLIST(clist)->rows ; i++)
{
row_style = gtk_clist_get_row_style(GTK_CLIST(clist), i);
if (row_style && (row_style != base_style))
{
g_object_unref(row_style);
}
}
gtk_clist_clear(GTK_CLIST(clist));
}
/* Encapsulate GTK tooltip function which no longer supports disabling as /* Encapsulate GTK tooltip function which no longer supports disabling as
* of GTK 2.12 */ * of GTK 2.12 */
void set_tooltip(int show_tooltip, void set_tooltip(int show_tooltip,
GtkTooltips *tooltips, GtkWidget *widget,
GtkWidget *widget, const gchar *tip_text) {
const gchar *tip_text, if (widget != NULL) {
const gchar *tip_private) if (show_tooltip) {
{ gtk_widget_set_tooltip_text(widget, tip_text);
if (show_tooltip) } else {
gtk_tooltips_set_tip(tooltips, widget, tip_text, tip_private); gtk_widget_set_tooltip_text(widget, NULL);
} }
}
/* Encapsulate broken GTK function to make it work as documented */ }
void clist_select_row(GtkCList *clist,
int row, int dateToDays(struct tm *tm1) {
int column) time_t t1;
{ struct tm *gmt;
clist->focus_row = row; struct tm tm2;
gtk_clist_select_row(clist, row, column); static time_t adj = -1;
}
memcpy(&tm2, tm1, sizeof(struct tm));
int dateToDays(struct tm *tm1) tm2.tm_isdst = 0;
{ tm2.tm_hour = 12;
time_t t1; t1 = mktime(&tm2);
struct tm *gmt; if (-1 == adj) {
struct tm tm2; gmt = gmtime(&t1);
static time_t adj = -1; adj = t1 - mktime(gmt);
}
memcpy(&tm2, tm1, sizeof(struct tm)); return (t1 + adj) / 86400; /* There are 86400 secs in a day */
tm2.tm_isdst = 0;
tm2.tm_hour=12;
t1 = mktime(&tm2);
if (-1 == adj) {
gmt = gmtime(&t1);
adj = t1 - mktime(gmt);
}
return (t1+adj)/86400; /* There are 86400 secs in a day */
} }
/* /*
* This deletes a record from the appropriate Datafile * This deletes a record from the appropriate Datafile
*/ */
int delete_pc_record(AppType app_type, void *VP, int flag) int delete_pc_record(AppType app_type, void *VP, int flag) {
{ FILE *pc_in;
FILE *pc_in; PC3RecordHeader header;
PC3RecordHeader header; struct Appointment *appt;
struct Appointment *appt; MyAppointment *mappt;
MyAppointment *mappt; struct CalendarEvent *cale;
struct CalendarEvent *cale; MyCalendarEvent *mcale;
MyCalendarEvent *mcale; struct Address *addr;
struct Address *addr; MyAddress *maddr;
MyAddress *maddr; struct Contact *cont;
struct Contact *cont; MyContact *mcont;
MyContact *mcont; struct ToDo *todo;
struct ToDo *todo; MyToDo *mtodo;
MyToDo *mtodo; struct Memo *memo;
struct Memo *memo; MyMemo *mmemo;
MyMemo *mmemo; char filename[FILENAME_MAX];
char filename[FILENAME_MAX]; pi_buffer_t *RecordBuffer = NULL;
pi_buffer_t *RecordBuffer = NULL; PCRecType record_type;
PCRecType record_type; unsigned int unique_id;
unsigned int unique_id; unsigned char attrib;
unsigned char attrib;
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
long ivalue; long ivalue;
#endif #endif
long memo_version; long memo_version;
long char_set; long char_set;
jp_logf(JP_LOG_DEBUG, "delete_pc_record(%d, %d)\n", app_type, flag);
if (VP==NULL) { jp_logf(JP_LOG_DEBUG, "delete_pc_record(%d, %d)\n", app_type, flag);
return EXIT_FAILURE;
}
get_pref(PREF_CHAR_SET, &char_set, NULL);
/* to keep the compiler happy with -Wall*/ if (VP == NULL) {
mappt=NULL; return EXIT_FAILURE;
mcale=NULL; }
maddr=NULL;
mcont=NULL; get_pref(PREF_CHAR_SET, &char_set, NULL);
mtodo=NULL;
mmemo=NULL; /* to keep the compiler happy with -Wall*/
switch (app_type) { mappt = NULL;
case DATEBOOK: mcale = NULL;
mappt = (MyAppointment *) VP; maddr = NULL;
record_type = mappt->rt; mcont = NULL;
unique_id = mappt->unique_id; mtodo = NULL;
attrib = mappt->attrib; mmemo = NULL;
strcpy(filename, "DatebookDB.pc3"); switch (app_type) {
break; case DATEBOOK:
case CALENDAR: mappt = (MyAppointment *) VP;
mcale = (MyCalendarEvent *) VP; record_type = mappt->rt;
record_type = mcale->rt; unique_id = mappt->unique_id;
unique_id = mcale->unique_id; attrib = mappt->attrib;
attrib = mcale->attrib; strcpy(filename, "DatebookDB.pc3");
strcpy(filename, "CalendarDB-PDat.pc3"); break;
break; case CALENDAR:
case ADDRESS: mcale = (MyCalendarEvent *) VP;
maddr = (MyAddress *) VP; record_type = mcale->rt;
record_type = maddr->rt; unique_id = mcale->unique_id;
unique_id = maddr->unique_id; attrib = mcale->attrib;
attrib = maddr->attrib; strcpy(filename, "CalendarDB-PDat.pc3");
strcpy(filename, "AddressDB.pc3"); break;
break; case ADDRESS:
case CONTACTS: maddr = (MyAddress *) VP;
mcont = (MyContact *) VP; record_type = maddr->rt;
record_type = mcont->rt; unique_id = maddr->unique_id;
unique_id = mcont->unique_id; attrib = maddr->attrib;
attrib = mcont->attrib; strcpy(filename, "AddressDB.pc3");
strcpy(filename, "ContactsDB-PAdd.pc3"); break;
break; case CONTACTS:
case TODO: mcont = (MyContact *) VP;
mtodo = (MyToDo *) VP; record_type = mcont->rt;
record_type = mtodo->rt; unique_id = mcont->unique_id;
unique_id = mtodo->unique_id; attrib = mcont->attrib;
attrib = mtodo->attrib; strcpy(filename, "ContactsDB-PAdd.pc3");
break;
case TODO:
mtodo = (MyToDo *) VP;
record_type = mtodo->rt;
unique_id = mtodo->unique_id;
attrib = mtodo->attrib;
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
get_pref(PREF_MANANA_MODE, &ivalue, NULL); get_pref(PREF_MANANA_MODE, &ivalue, NULL);
if (ivalue) { if (ivalue) {
strcpy(filename, "MananaDB.pc3"); strcpy(filename, "MananaDB.pc3");
} else { } else {
strcpy(filename, "ToDoDB.pc3"); strcpy(filename, "ToDoDB.pc3");
} }
#else #else
strcpy(filename, "ToDoDB.pc3"); strcpy(filename, "ToDoDB.pc3");
#endif #endif
break; break;
case MEMO: case MEMO:
mmemo = (MyMemo *) VP; mmemo = (MyMemo *) VP;
record_type = mmemo->rt; record_type = mmemo->rt;
unique_id = mmemo->unique_id; unique_id = mmemo->unique_id;
attrib = mmemo->attrib; attrib = mmemo->attrib;
get_pref(PREF_MEMO_VERSION, &memo_version, NULL); get_pref(PREF_MEMO_VERSION, &memo_version, NULL);
switch (memo_version) { switch (memo_version) {
case 0: case 0:
default: default:
strcpy(filename, "MemoDB.pc3"); strcpy(filename, "MemoDB.pc3");
break; break;
case 1: case 1:
strcpy(filename, "MemosDB-PMem.pc3"); strcpy(filename, "MemosDB-PMem.pc3");
break; break;
case 2: case 2:
strcpy(filename, "Memo32DB.pc3"); strcpy(filename, "Memo32DB.pc3");
break; break;
} }
break; break;
default: default:
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if ((record_type == DELETED_PALM_REC) || (record_type == MODIFIED_PALM_REC))
{
jp_logf(JP_LOG_INFO | JP_LOG_GUI, _("This record is already deleted.\n"
"It is scheduled to be deleted from
the Palm on the next sync.\n"));
return EXIT_SUCCESS;
}
RecordBuffer = pi_buffer_new(0);
switch (record_type) {
case NEW_PC_REC:
case REPLACEMENT_PALM_REC:
pc_in = jp_open_home_file(filename, "r+");
if (pc_in == NULL) {
jp_logf(JP_LOG_WARN, _("Unable to open PC records file\n"));
pi_buffer_free(RecordBuffer);
return EXIT_FAILURE;
}
while (!feof(pc_in)) {
read_header(pc_in, &header);
if (feof(pc_in)) {
jp_logf(JP_LOG_WARN, _("Couldn't find record to delete\n"));
pi_buffer_free(RecordBuffer);
jp_close_home_file(pc_in);
return EXIT_FAILURE;
}
/* Keep unique ID intact */
if (header.header_version == 2) {
if ((header.unique_id == unique_id) &&
((header.rt == NEW_PC_REC) || (header.rt == REPLACEMENT_
PALM_REC))) {
if (fseek(pc_in, -header.header_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
}
header.rt = DELETED_PC_REC;
write_header(pc_in, &header);
jp_logf(JP_LOG_DEBUG, "record deleted\n");
jp_close_home_file(pc_in);
pi_buffer_free(RecordBuffer);
return EXIT_SUCCESS;
}
} else {
jp_logf(JP_LOG_WARN, _("Unknown header version %d\n"), heade
r.header_version);
}
if (fseek(pc_in, header.rec_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
}
}
if ((record_type==DELETED_PALM_REC) || (record_type==MODIFIED_PALM_REC)) {
jp_logf(JP_LOG_INFO|JP_LOG_GUI, _("This record is already deleted.\n"
"It is scheduled to be deleted from the Palm on the next sync.\n"));
return EXIT_SUCCESS;
}
RecordBuffer = pi_buffer_new(0);
switch (record_type) {
case NEW_PC_REC:
case REPLACEMENT_PALM_REC:
pc_in=jp_open_home_file(filename, "r+");
if (pc_in==NULL) {
jp_logf(JP_LOG_WARN, _("Unable to open PC records file\n"));
pi_buffer_free(RecordBuffer);
return EXIT_FAILURE;
}
while(!feof(pc_in)) {
read_header(pc_in, &header);
if (feof(pc_in)) {
jp_logf(JP_LOG_WARN, _("Couldn't find record to delete\n"));
pi_buffer_free(RecordBuffer);
jp_close_home_file(pc_in); jp_close_home_file(pc_in);
pi_buffer_free(RecordBuffer);
return EXIT_FAILURE; return EXIT_FAILURE;
}
/* Keep unique ID intact */
if (header.header_version==2) {
if ((header.unique_id==unique_id) &&
((header.rt==NEW_PC_REC)||(header.rt==REPLACEMENT_PALM_REC))) {
if (fseek(pc_in, -header.header_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
}
header.rt=DELETED_PC_REC;
write_header(pc_in, &header);
jp_logf(JP_LOG_DEBUG, "record deleted\n");
jp_close_home_file(pc_in);
pi_buffer_free(RecordBuffer);
return EXIT_SUCCESS;
}
} else {
jp_logf(JP_LOG_WARN, _("Unknown header version %d\n"), header.header
_version);
}
if (fseek(pc_in, header.rec_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
}
}
jp_close_home_file(pc_in); case PALM_REC:
pi_buffer_free(RecordBuffer); jp_logf(JP_LOG_DEBUG, "Deleting Palm ID %d\n", unique_id);
return EXIT_FAILURE; pc_in = jp_open_home_file(filename, "a");
if (pc_in == NULL) {
case PALM_REC: jp_logf(JP_LOG_WARN, _("Unable to open PC records file\n"));
jp_logf(JP_LOG_DEBUG, "Deleting Palm ID %d\n", unique_id); pi_buffer_free(RecordBuffer);
pc_in=jp_open_home_file(filename, "a"); return EXIT_FAILURE;
if (pc_in==NULL) { }
jp_logf(JP_LOG_WARN, _("Unable to open PC records file\n"));
pi_buffer_free(RecordBuffer); header.unique_id = unique_id;
return EXIT_FAILURE; if (flag == MODIFY_FLAG) {
} header.rt = MODIFIED_PALM_REC;
} else {
header.unique_id=unique_id; header.rt = DELETED_PALM_REC;
if (flag==MODIFY_FLAG) { }
header.rt=MODIFIED_PALM_REC; header.attrib = attrib;
} else {
header.rt=DELETED_PALM_REC; switch (app_type) {
} case DATEBOOK:
header.attrib=attrib; appt = &mappt->appt;
if (pack_Appointment(appt, RecordBuffer, datebook_v1) == -1)
switch (app_type) { {
case DATEBOOK: PRINT_FILE_LINE;
appt=&mappt->appt; jp_logf(JP_LOG_WARN, "pack_Appointment %s\n", _("error")
if (pack_Appointment(appt, RecordBuffer, datebook_v1) == -1) { );
PRINT_FILE_LINE; }
jp_logf(JP_LOG_WARN, "pack_Appointment %s\n", _("error")); break;
} case CALENDAR:
break; cale = &mcale->cale;
case CALENDAR: if (pack_CalendarEvent(cale, RecordBuffer, calendar_v1) == -
cale=&mcale->cale; 1) {
if (pack_CalendarEvent(cale, RecordBuffer, calendar_v1) == -1) { PRINT_FILE_LINE;
PRINT_FILE_LINE; jp_logf(JP_LOG_WARN, "pack_CalendarEvent %s\n", _("error
jp_logf(JP_LOG_WARN, "pack_CalendarEvent %s\n", _("error")); "));
} }
break; break;
case ADDRESS: case ADDRESS:
addr=&maddr->addr; addr = &maddr->addr;
if (pack_Address(addr, RecordBuffer, address_v1) == -1) { if (pack_Address(addr, RecordBuffer, address_v1) == -1) {
PRINT_FILE_LINE; PRINT_FILE_LINE;
jp_logf(JP_LOG_WARN, "pack_Address %s\n", _("error")); jp_logf(JP_LOG_WARN, "pack_Address %s\n", _("error"));
} }
break; break;
case CONTACTS: case CONTACTS:
cont=&mcont->cont; cont = &mcont->cont;
if (jp_pack_Contact(cont, RecordBuffer) == -1) { if (jp_pack_Contact(cont, RecordBuffer) == -1) {
PRINT_FILE_LINE; PRINT_FILE_LINE;
jp_logf(JP_LOG_WARN, "jp_pack_Contact %s\n", _("error")); jp_logf(JP_LOG_WARN, "jp_pack_Contact %s\n", _("error"))
} ;
break; }
case TODO: break;
todo=&mtodo->todo; case TODO:
if (pack_ToDo(todo, RecordBuffer, todo_v1) == -1) { todo = &mtodo->todo;
PRINT_FILE_LINE; if (pack_ToDo(todo, RecordBuffer, todo_v1) == -1) {
jp_logf(JP_LOG_WARN, "pack_ToDo %s\n", _("error")); PRINT_FILE_LINE;
} jp_logf(JP_LOG_WARN, "pack_ToDo %s\n", _("error"));
break; }
case MEMO: break;
memo=&mmemo->memo; case MEMO:
if (pack_Memo(memo, RecordBuffer, memo_v1) == -1) { memo = &mmemo->memo;
PRINT_FILE_LINE; if (pack_Memo(memo, RecordBuffer, memo_v1) == -1) {
jp_logf(JP_LOG_WARN, "pack_Memo %s\n", _("error")); PRINT_FILE_LINE;
} jp_logf(JP_LOG_WARN, "pack_Memo %s\n", _("error"));
break; }
default: break;
jp_close_home_file(pc_in); default:
pi_buffer_free(RecordBuffer); jp_close_home_file(pc_in);
return EXIT_SUCCESS; pi_buffer_free(RecordBuffer);
} /* switch */ return EXIT_SUCCESS;
} /* switch */
header.rec_len = RecordBuffer->used;
header.rec_len = RecordBuffer->used;
jp_logf(JP_LOG_DEBUG, "writing header to pc file\n");
write_header(pc_in, &header); jp_logf(JP_LOG_DEBUG, "writing header to pc file\n");
/* This record is used during sync to make sure that the palm record write_header(pc_in, &header);
/* This record is used during sync to make sure that the palm record
* hasn't changed before we delete it */ * hasn't changed before we delete it */
jp_logf(JP_LOG_DEBUG, "writing record to pc file, %d bytes\n", header.rec_ jp_logf(JP_LOG_DEBUG, "writing record to pc file, %d bytes\n", heade
len); r.rec_len);
fwrite(RecordBuffer->data, header.rec_len, 1, pc_in); fwrite(RecordBuffer->data, header.rec_len, 1, pc_in);
jp_logf(JP_LOG_DEBUG, "record deleted\n"); jp_logf(JP_LOG_DEBUG, "record deleted\n");
jp_close_home_file(pc_in); jp_close_home_file(pc_in);
pi_buffer_free(RecordBuffer); pi_buffer_free(RecordBuffer);
return EXIT_SUCCESS; return EXIT_SUCCESS;
break; break;
default: default:
break; break;
} /* switch (record_type) */ } /* switch (record_type) */
if (RecordBuffer) if (RecordBuffer)
pi_buffer_free(RecordBuffer); pi_buffer_free(RecordBuffer);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* nob = number of buttons */ /* nob = number of buttons */
int dialog_generic(GtkWindow *main_window, int dialog_generic(GtkWindow *main_window,
char *title, int type, char *title, int type,
char *text, int nob, char *button_text[]) char *text, int nob, char *button_text[]) {
{ GtkWidget *button, *label1;
GtkWidget *button, *label1; GtkWidget *hbox1, *vbox1, *vbox2;
GtkWidget *hbox1, *vbox1, *vbox2; int i;
int i; GtkWidget *image;
GtkWidget *image; char *markup;
char *markup;
glob_mouse_pressed = 0;
/* This gdk function call is required in order to avoid a GTK
* error which causes X and the mouse pointer to lock up. /* This gdk function call is required in order to avoid a GTK
* The lockup is generated whenever a modal dialog is created * error which causes X and the mouse pointer to lock up.
* from the callback routine of a clist. */ * The lockup is generated whenever a modal dialog is created
gdk_pointer_ungrab(GDK_CURRENT_TIME); * from the callback routine of a treeView.
*/
dialog_result=0; #if GTK_MAJOR_VERSION >= 3 && GTK_MINOR_VERSION >= 20
glob_dialog = gtk_widget_new(GTK_TYPE_WINDOW, GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(main_window));
"type", GTK_WINDOW_TOPLEVEL, GdkDisplay *display = gdk_window_get_display(GDK_WINDOW(gdk_window));
"window_position", GTK_WIN_POS_MOUSE, GdkSeat *seat = gdk_display_get_default_seat(display);
NULL); gdk_seat_ungrab(seat);
gtk_window_set_title(GTK_WINDOW(glob_dialog), title); #else
gtk_window_set_modal(GTK_WINDOW(glob_dialog), TRUE); gdk_pointer_ungrab(GDK_CURRENT_TIME);
if (main_window) { #endif
gtk_window_set_transient_for(GTK_WINDOW(glob_dialog), GTK_WINDOW(main_wind
ow));
}
gtk_signal_connect(GTK_OBJECT(glob_dialog), "destroy",
GTK_SIGNAL_FUNC(cb_destroy_dialog), glob_dialog);
vbox1 = gtk_vbox_new(FALSE, 5);
gtk_container_add(GTK_CONTAINER(glob_dialog), vbox1);
hbox1 = gtk_hbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(vbox1), hbox1);
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 12);
switch (type)
{
case DIALOG_INFO:
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_D
IALOG);
break;
case DIALOG_QUESTION:
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SI
ZE_DIALOG);
break;
case DIALOG_ERROR:
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_
DIALOG);
break;
case DIALOG_WARNING:
image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZ
E_DIALOG);
break;
default:
image = NULL;
}
if (image)
gtk_box_pack_start(GTK_BOX(hbox1), image, FALSE, FALSE, 2);
vbox2 = gtk_vbox_new(FALSE, 5); dialog_result = 0;
gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5); glob_dialog = gtk_widget_new(GTK_TYPE_WINDOW,
gtk_box_pack_start(GTK_BOX(hbox1), vbox2, FALSE, FALSE, 2); "type", GTK_WINDOW_TOPLEVEL,
"window_position", GTK_WIN_POS_MOUSE,
/* Title and Information text */ NULL);
label1 = gtk_label_new(NULL); gtk_window_set_title(GTK_WINDOW(glob_dialog), title);
markup = g_markup_printf_escaped("<b><big>%s</big></b>\n\n%s", title, text); gtk_window_set_modal(GTK_WINDOW(glob_dialog), TRUE);
gtk_label_set_markup(GTK_LABEL(label1), markup); if (main_window) {
g_free(markup); gtk_window_set_transient_for(GTK_WINDOW(glob_dialog), GTK_WINDOW(main_wi
gtk_box_pack_start(GTK_BOX(vbox2), label1, FALSE, FALSE, 2); ndow));
}
/* Create buttons */
hbox1 = gtk_hbutton_box_new(); g_signal_connect(G_OBJECT(glob_dialog), "destroy",
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 12); G_CALLBACK(cb_destroy_dialog), glob_dialog);
gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END);
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox1), 6); vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
gtk_container_add(GTK_CONTAINER(glob_dialog), vbox1);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
for (i=0; i < nob; i++) { gtk_container_add(GTK_CONTAINER(vbox1), hbox1);
if (0 == strcmp("OK", button_text[i])) gtk_container_set_border_width(GTK_CONTAINER(hbox1), 12);
button = gtk_button_new_from_stock(GTK_STOCK_OK); switch (type) {
else case DIALOG_INFO:
if (0 == strcmp("Cancel", button_text[i])) image = gtk_image_new_from_icon_name("dialog-information", GTK_ICON_
button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); SIZE_DIALOG);
else break;
if (0 == strcmp("Yes", button_text[i])) case DIALOG_QUESTION:
button = gtk_button_new_from_stock(GTK_STOCK_YES); image = gtk_image_new_from_icon_name("dialog-question", GTK_ICON_SIZ
else E_DIALOG);
if (0 == strcmp("No", button_text[i])) break;
button = gtk_button_new_from_stock(GTK_STOCK_NO); case DIALOG_ERROR:
else image = gtk_image_new_from_icon_name("dialog-error", GTK_ICON_SIZE_D
button = gtk_button_new_with_label(_(button_text[i])); IALOG);
gtk_signal_connect(GTK_OBJECT(button), "clicked", break;
GTK_SIGNAL_FUNC(cb_dialog_button), case DIALOG_WARNING:
GINT_TO_POINTER(DIALOG_SAID_1 + i)); image = gtk_image_new_from_icon_name("dialog-warning", GTK_ICON_SIZE
gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 1); _DIALOG);
break;
/* default button is the last one */ default:
if (i == nob-1) image = NULL;
{ }
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); if (image)
gtk_widget_grab_default(button); gtk_box_pack_start(GTK_BOX(hbox1), image, FALSE, FALSE, 2);
gtk_widget_grab_focus(button);
} vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
} gtk_container_set_border_width(GTK_CONTAINER(vbox2), 5);
gtk_box_pack_start(GTK_BOX(hbox1), vbox2, FALSE, FALSE, 2);
/* Title and Information text */
label1 = gtk_label_new(NULL);
markup = g_markup_printf_escaped("<b><big>%s</big></b>\n\n%s", title, text);
gtk_label_set_markup(GTK_LABEL(label1), markup);
g_free(markup);
gtk_box_pack_start(GTK_BOX(vbox2), label1, FALSE, FALSE, 2);
/* Create buttons */
hbox1 = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 12);
gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END);
gtk_box_set_spacing(GTK_BOX(hbox1), 6);
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2);
for (i = 0; i < nob; i++) {
if (0 == strcmp("OK", button_text[i]))
button = gtk_button_new_with_label("OK");
else if (0 == strcmp("Cancel", button_text[i]))
button = gtk_button_new_with_label("Cancel");
else if (0 == strcmp("Yes", button_text[i]))
button = gtk_button_new_with_label("Yes");
else if (0 == strcmp("No", button_text[i]))
button = gtk_button_new_with_label("No");
else
button = gtk_button_new_with_label(_(button_text[i]));
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(cb_dialog_button),
GINT_TO_POINTER(DIALOG_SAID_1 + i));
gtk_box_pack_start(GTK_BOX(hbox1), button, TRUE, TRUE, 1);
/* default button is the last one */
if (i == nob - 1) {
gtk_widget_set_can_default(button,TRUE);
gtk_widget_grab_default(button);
gtk_widget_grab_focus(button);
}
}
gtk_widget_show_all(glob_dialog); gtk_widget_show_all(glob_dialog);
gtk_main(); gtk_main();
return dialog_result; return dialog_result;
} }
int dialog_generic_ok(GtkWidget *widget, int dialog_generic_ok(GtkWidget *widget,
char *title, int type, char *text) char *title, int type, char *text) {
{ char *button_text[] = {N_("OK")};
char *button_text[] = {N_("OK")};
if (widget) { glob_mouse_pressed = 0;
return dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widget
))), if (widget) {
title, type, text, 1, button_text); return dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(widg
} et))),
return dialog_generic(NULL, title, type, text, 1, button_text); title, type, text, 1, button_text);
}
return dialog_generic(NULL, title, type, text, 1, button_text);
} }
/* /*
* Widget must be some widget used to get the main window from. * Widget must be some widget used to get the main window from.
* The main window passed in would be fastest. * The main window passed in would be fastest.
* changed is MODIFY_FLAG, or NEW_FLAG * changed is MODIFY_FLAG, or NEW_FLAG
*/ */
int dialog_save_changed_record(GtkWidget *widget, int changed) int dialog_save_changed_record(GtkWidget *widget, int changed) {
{ int b = 0;
int b=0; char *button_text[] = {N_("No"), N_("Yes")};
char *button_text[] = {N_("No"), N_("Yes")};
glob_mouse_pressed = 0;
if ((changed!=MODIFY_FLAG) && (changed!=NEW_FLAG)) {
return EXIT_SUCCESS; if ((changed != MODIFY_FLAG) && (changed != NEW_FLAG)) {
} return EXIT_SUCCESS;
}
if (changed==MODIFY_FLAG) {
b=dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)), if (changed == MODIFY_FLAG) {
_("Save Changed Record?"), DIALOG_QUESTION, b = dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
_("Do you want to save the changes to this record?"), _("Save Changed Record?"), DIALOG_QUESTION,
2, button_text); _("Do you want to save the changes to this record?"),
} 2, button_text);
if (changed==NEW_FLAG) { }
b=dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)), if (changed == NEW_FLAG) {
_("Save New Record?"), DIALOG_QUESTION, b = dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
_("Do you want to save this new record?"), _("Save New Record?"), DIALOG_QUESTION,
2, button_text); _("Do you want to save this new record?"),
} 2, button_text);
}
return b;
} return b;
int dialog_save_changed_record_with_cancel(GtkWidget *widget, int changed) }
{
int b=0; int dialog_save_changed_record_with_cancel(GtkWidget *widget, int changed) {
char *button_text[] = {N_("Cancel"), N_("No"), N_("Yes")}; int b = 0;
char *button_text[] = {N_("Cancel"), N_("No"), N_("Yes")};
if ((changed!=MODIFY_FLAG) && (changed!=NEW_FLAG)) {
return EXIT_SUCCESS; glob_mouse_pressed = 0;
}
if ((changed != MODIFY_FLAG) && (changed != NEW_FLAG)) {
if (changed==MODIFY_FLAG) { return EXIT_SUCCESS;
b=dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)), }
_("Save Changed Record?"), DIALOG_QUESTION,
_("Do you want to save the changes to this record?"), if (changed == MODIFY_FLAG) {
3, button_text); b = dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
} _("Save Changed Record?"), DIALOG_QUESTION,
if (changed==NEW_FLAG) { _("Do you want to save the changes to this record?"),
b=dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)), 3, button_text);
_("Save New Record?"), DIALOG_QUESTION, }
_("Do you want to save this new record?"), if (changed == NEW_FLAG) {
3, button_text); b = dialog_generic(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
} _("Save New Record?"), DIALOG_QUESTION,
_("Do you want to save this new record?"),
return b; 3, button_text);
} }
void entry_set_multiline_truncate(GtkEntry *entry, gboolean value) return b;
{ }
# if GTK_MINOR_VERSION >= 10
entry->truncate_multiline = value; void entry_set_multiline_truncate(GtkEntry *entry, gboolean value) {
# if GTK_MINOR_VERSION >= 10 || GTK_MAJOR_VERSION >= 3
g_object_set(entry,"truncate-multiline",value,NULL);
# endif # endif
} }
/* returns 1 if found */ /* returns 1 if found */
/* 0 if eof */ /* 0 if eof */
int find_next_offset(mem_rec_header *mem_rh, long fpos, int find_next_offset(mem_rec_header *mem_rh, long fpos,
unsigned int *next_offset, unsigned int *next_offset,
unsigned char *attrib, unsigned int *unique_id) unsigned char *attrib, unsigned int *unique_id) {
{ mem_rec_header *temp_mem_rh;
mem_rec_header *temp_mem_rh; unsigned char found = 0;
unsigned char found = 0; unsigned long found_at;
unsigned long found_at;
found_at = 0xFFFFFF;
found_at=0xFFFFFF; for (temp_mem_rh = mem_rh; temp_mem_rh; temp_mem_rh = temp_mem_rh->next) {
for (temp_mem_rh=mem_rh; temp_mem_rh; temp_mem_rh = temp_mem_rh->next) { if ((temp_mem_rh->offset > fpos) && (temp_mem_rh->offset < found_at)) {
if ((temp_mem_rh->offset > fpos) && (temp_mem_rh->offset < found_at)) { found_at = temp_mem_rh->offset;
found_at = temp_mem_rh->offset; }
} if ((temp_mem_rh->offset == fpos)) {
if ((temp_mem_rh->offset == fpos)) { found = 1;
found = 1; *attrib = temp_mem_rh->attrib;
*attrib = temp_mem_rh->attrib; *unique_id = temp_mem_rh->unique_id;
*unique_id = temp_mem_rh->unique_id; }
} }
} *next_offset = found_at;
*next_offset = found_at; return found;
return found;
} }
/* Finds next repeating event occurrence closest to srch_start_tm */ /* Finds next repeating event occurrence closest to srch_start_tm */
int find_next_rpt_event(struct CalendarEvent *cale, int find_next_rpt_event(struct CalendarEvent *cale,
struct tm *srch_start_tm, struct tm *srch_start_tm,
struct tm *next_tm) struct tm *next_tm) {
{ struct tm prev_tm;
struct tm prev_tm; int prev_found, next_found;
int prev_found, next_found;
find_prev_next(cale,
find_prev_next(cale, 0,
0, srch_start_tm,
srch_start_tm, srch_start_tm,
srch_start_tm, &prev_tm,
&prev_tm, next_tm,
next_tm, &prev_found,
&prev_found, &next_found);
&next_found);
return next_found; return next_found;
} }
/* /*
* Search forwards and backwards in time to find alarms which bracket * Search forwards and backwards in time to find alarms which bracket
* date1 and date2. * date1 and date2.
* For non-repeating appointments no searching is necessary. * For non-repeating appointments no searching is necessary.
* The appt is either in the range or it is not. * The appt is either in the range or it is not.
* The algorithm for searching is time consuming. To improve performance * The algorithm for searching is time consuming. To improve performance
* this subroutine seeks to seed the search with a close guess for the * this subroutine seeks to seed the search with a close guess for the
* correct time before launching the search. * correct time before launching the search.
skipping to change at line 1438 skipping to change at line 1401
* Alternatively the C math functions such as floor could be used but there * Alternatively the C math functions such as floor could be used but there
* seems little point in invoking such overhead. * seems little point in invoking such overhead.
*/ */
int find_prev_next(struct CalendarEvent *cale, int find_prev_next(struct CalendarEvent *cale,
time_t adv, time_t adv,
struct tm *date1, struct tm *date1,
struct tm *date2, struct tm *date2,
struct tm *tm_prev, struct tm *tm_prev,
struct tm *tm_next, struct tm *tm_next,
int *prev_found, int *prev_found,
int *next_found) int *next_found) {
{ struct tm t;
struct tm t; time_t t1, t2;
time_t t1, t2; time_t t_begin, t_end;
time_t t_begin, t_end; time_t t_alarm;
time_t t_alarm; time_t t_offset;
time_t t_offset; time_t t_temp;
time_t t_temp; int forward, backward;
int forward, backward; int offset;
int offset; int freq;
int freq; int date1_days, begin_days;
int date1_days, begin_days; int fdom, ndim;
int fdom, ndim; int found, count, i;
int found, count, i; int safety_counter;
int safety_counter; int found_exception;
int found_exception; int kill_update_next;
int kill_update_next; #ifdef ALARMS_DEBUG
char str[100];
#endif
#ifdef ALARMS_DEBUG
printf("fpn: entered find_previous_next\n");
#endif
*prev_found = *next_found = 0;
forward = backward = 1;
t1 = mktime_dst_adj(date1);
t2 = mktime_dst_adj(date2);
memset(tm_prev, 0, sizeof(*tm_prev));
memset(tm_next, 0, sizeof(*tm_next));
/* Initialize search time with cale start time */
memset(&t, 0, sizeof(t));
t.tm_year = cale->begin.tm_year;
t.tm_mon = cale->begin.tm_mon;
t.tm_mday = cale->begin.tm_mday;
t.tm_hour = cale->begin.tm_hour;
t.tm_min = cale->begin.tm_min;
t.tm_isdst = -1;
mktime(&t);
#ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t);
printf("fpn: appt_start=%s\n", str);
#endif
/* Handle non-repeating appointments */
if (cale->repeatType == calendarRepeatNone) {
#ifdef ALARMS_DEBUG
printf("fpn: repeatNone\n");
#endif
t_alarm = mktime_dst_adj(&(cale->begin)) - adv;
if ((t_alarm <= t2) && (t_alarm >= t1)) {
memcpy(tm_prev, &(cale->begin), sizeof(struct tm));
*prev_found = 1;
#ifdef ALARMS_DEBUG
printf("fpn: prev_found none\n");
#endif
} else if (t_alarm > t2) {
memcpy(tm_next, &(cale->begin), sizeof(struct tm));
*next_found = 1;
#ifdef ALARMS_DEBUG
printf("fpn: next_found none\n");
#endif
}
return EXIT_SUCCESS;
}
/* Optimize initial start position of search */
switch (cale->repeatType) {
case repeatNone:
/* Already handled. Here only to shut up compiler warnings */
break;
case repeatDaily:
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
char str[100]; printf("fpn: repeatDaily\n");
#endif #endif
freq = cale->repeatFrequency;
t_offset = freq * DAY_IN_SECS;
t_alarm = mktime_dst_adj(&t);
/* Jump to closest current date if appt. started in the past */
if (t1 - adv > t_alarm) {
t_alarm = ((((t1 + adv) - t_alarm) / t_offset) * t_offset) + t_a
larm;
memcpy(&t, localtime(&t_alarm), sizeof(struct tm));
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: entered find_previous_next\n");
strftime(str, sizeof(str
), "%B %d, %Y %H:%M", &t);
printf("fpn: initial daily=%s\n", str);
#endif
}
break;
case repeatWeekly:
#ifdef ALARMS_DEBUG
printf("fpn: repeatWeekly\n");
#endif
freq = cale->repeatFrequency;
begin_days = dateToDays(&(cale->begin));
date1_days = dateToDays(date1);
/* Jump to closest current date if appt. started in the past */
if (date1_days > begin_days) {
#ifdef ALARMS_DEBUG
printf("fpn: begin_days
%d date1_days %d\n", begin_days, date1_days);
printf("fpn: date1->tm_wday %d appt->begin.tm_wday %d\n", date1->tm_wda
y, cale->begin.tm_wday);
#endif
/* Jump by appropriate number of weeks */
offset = date1_days - begin_days;
offset = (offset / (freq * 7)) * (freq * 7);
#ifdef ALARMS_DEBUG
printf("fpn: offset %d\n", offset);
#endif #endif
*prev_found=*next_found=0;
forward=backward=1;
t1=mktime_dst_adj(date1);
t2=mktime_dst_adj(date2);
memset(tm_prev, 0, sizeof(*tm_prev)); add_days_to_date(&t, offset);
memset(tm_next, 0, sizeof(*tm_next)); }
/* Initialize search time with cale start time */ /* Within the week find which day is a repeat */
memset(&t, 0, sizeof(t)); found = 0;
t.tm_year=cale->begin.tm_year; for (count = 0, i = t.tm_wday; i >= 0; i--, count++) {
t.tm_mon=cale->begin.tm_mon; if (cale->repeatDays[i]) {
t.tm_mday=cale->begin.tm_mday; sub_days_from_date(&t, count);
t.tm_hour=cale->begin.tm_hour; found = 1;
t.tm_min=cale->begin.tm_min; break;
t.tm_isdst=-1; }
mktime(&t); }
if (!found) {
for (count = 0, i = t.tm_wday; i < 7; i++, count++) {
if (cale->repeatDays[i]) {
add_days_to_date(&t, count);
found = 1;
break;
}
}
}
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t); strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t);
printf("fpn: appt_start=%s\n", str); printf("fpn: initial weekly=%s\n", str);
#endif #endif
break;
/* Handle non-repeating appointments */ case repeatMonthlyByDay:
if (cale->repeatType == repeatNone) {
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: repeatNone\n"); printf("fpn: repeatMonthlyByDay\n");
#endif
/* Jump to closest current date if appt. started in the past */
if ((date1->tm_year > cale->begin.tm_year) ||
(date1->tm_mon > cale->begin.tm_mon)) {
/* First, adjust month */
freq = cale->repeatFrequency;
offset = ((date1->tm_year - cale->begin.tm_year) * 12) -
cale->begin.tm_mon +
date1->tm_mon;
offset = (offset / freq) * freq;
add_months_to_date(&t, offset);
/* Second, adjust to correct day in new month */
get_month_info(t.tm_mon, 1, t.tm_year, &fdom, &ndim);
t.tm_mday = ((cale->repeatDay + 7 - fdom) % 7) - ((cale->repeatD
ay) % 7) + cale->repeatDay + 1;
#ifdef ALARMS_DEBUG
printf("fpn: months offs
et = %d\n", offset);
printf("fpn: %02d/01/%02d, fdom=%d\n", t.tm_mon+1, t.tm_year+1900, fdom
);
printf("fpn: mday = %d\n", t.tm_mday);
#endif #endif
t_alarm=mktime_dst_adj(&(cale->begin)) - adv; if (t.tm_mday > ndim - 1) {
if ((t_alarm <= t2) && (t_alarm >= t1)) { t.tm_mday -= 7;
memcpy(tm_prev, &(cale->begin), sizeof(struct tm)); }
*prev_found=1;
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: prev_found none\n");
strftime(str, sizeof(str
), "%B %d, %Y %H:%M", &t);
printf("fpn: initial monthly by day=%s\n", str);
#endif #endif
} else if (t_alarm > t2) { }
memcpy(tm_next, &(cale->begin), sizeof(struct tm)); break;
*next_found=1; case repeatMonthlyByDate:
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: next_found none\n"); printf("fpn: repeatMonthlyByDate\n");
#endif #endif
} /* Jump to closest current date if appt. started in the past */
return EXIT_SUCCESS; if ((date1->tm_year > cale->begin.tm_year) ||
} (date1->tm_mon > cale->begin.tm_mon)) {
freq = cale->repeatFrequency;
/* Optimize initial start position of search */ offset = ((date1->tm_year - cale->begin.tm_year) * 12) -
switch (cale->repeatType) { cale->begin.tm_mon +
case repeatNone: date1->tm_mon;
/* Already handled. Here only to shut up compiler warnings */ offset = (offset / freq) * freq;
break;
case repeatDaily:
#ifdef ALARMS_DEBUG
printf("fpn: repeatDaily\n");
#endif
freq = cale->repeatFrequency;
t_offset = freq * DAY_IN_SECS;
t_alarm = mktime_dst_adj(&t);
/* Jump to closest current date if appt. started in the past */
if (t1 - adv > t_alarm)
{
t_alarm = ((((t1+adv)-t_alarm) / t_offset) * t_offset) + t_alarm;
memcpy(&t, localtime(&t_alarm), sizeof(struct tm));
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t); printf("fpn: months offset = %d\n", offset);
printf("fpn: initial daily=%s\n", str);
#endif #endif
} add_months_to_date(&t, offset);
break; }
case repeatWeekly: break;
#ifdef ALARMS_DEBUG case repeatYearly:
printf("fpn: repeatWeekly\n");
#endif
freq = cale->repeatFrequency;
begin_days = dateToDays(&(cale->begin));
date1_days = dateToDays(date1);
/* Jump to closest current date if appt. started in the past */
if (date1_days > begin_days) {
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: begin_days %d date1_days %d\n", begin_days, date1_days); printf("fpn: repeatYearly\n");
printf("fpn: date1->tm_wday %d appt->begin.tm_wday %d\n", date1->tm_wda
y, cale->begin.tm_wday);
#endif #endif
/* Jump by appropriate number of weeks */ /* Jump to closest current date if appt. started in the past */
offset = date1_days - begin_days; if (date1->tm_year > cale->begin.tm_year) {
offset = (offset/(freq*7))*(freq*7); freq = cale->repeatFrequency;
offset = ((date1->tm_year - cale->begin.tm_year) / freq) * freq;
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: offset %d\n", offset);
printf("fpn: (%d - %d)%%
%d\n", date1->tm_year, cale->begin.tm_year, freq);
printf("fpn: years offset = %d\n", offset);
#endif #endif
add_years_to_date(&t, offset);
}
break;
add_days_to_date(&t, offset); } /* end switch on repeatType */
}
/* Within the week find which day is a repeat */ /* Search forwards/backwards through time for alarms */
found=0; safety_counter = 0;
for (count=0, i=t.tm_wday; i>=0; i--, count++) { while (forward || backward) {
if (cale->repeatDays[i]) { safety_counter++;
sub_days_from_date(&t, count); if (safety_counter > 3000) {
found=1; jp_logf(JP_LOG_STDOUT | JP_LOG_FILE, "find_prev_next(): %s\n", _("in
finite loop, breaking\n"));
if (cale->description) {
jp_logf(JP_LOG_STDOUT | JP_LOG_FILE, "desc=[%s]\n", cale->descri
ption);
}
break; break;
} }
}
if (!found) { kill_update_next = 0;
for (count=0, i=t.tm_wday; i<7; i++, count++) { t_temp = mktime_dst_adj(&t);
if (cale->repeatDays[i]) {
add_days_to_date(&t, count);
found=1;
break;
}
}
}
#ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t);
printf("fpn: initial weekly=%s\n", str);
#endif
break;
case repeatMonthlyByDay:
#ifdef ALARMS_DEBUG
printf("fpn: repeatMonthlyByDay\n");
#endif
/* Jump to closest current date if appt. started in the past */
if ((date1->tm_year > cale->begin.tm_year) ||
(date1->tm_mon > cale->begin.tm_mon)) {
/* First, adjust month */
freq = cale->repeatFrequency;
offset = ((date1->tm_year - cale->begin.tm_year)*12) -
cale->begin.tm_mon +
date1->tm_mon;
offset = (offset/freq)*freq;
add_months_to_date(&t, offset);
/* Second, adjust to correct day in new month */
get_month_info(t.tm_mon, 1, t.tm_year, &fdom, &ndim);
t.tm_mday=((cale->repeatDay+7-fdom)%7) - ((cale->repeatDay)%7) + cale->
repeatDay + 1;
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: months offset = %d\n", offset);
printf("fpn: %02d/01/%02d, fdom=%d\n", t.tm_mon+1, t.tm_year+1900, fdom strftime(str, sizeof(str), "%B %
); d, %Y %H:%M", &t);
printf("fpn: mday = %d\n", t.tm_mday); printf("fpn: trying with=%s\n", str);
#endif #endif
if (t.tm_mday > ndim-1) {
t.tm_mday -= 7; /* Check for exceptions in repeat appointments */
} found_exception = 0;
for (i = 0; i < cale->exceptions; i++) {
if ((t.tm_mday == cale->exception[i].tm_mday) &&
(t.tm_mon == cale->exception[i].tm_mon) &&
(t.tm_year == cale->exception[i].tm_year)
) {
found_exception = 1;
break;
}
}
if (found_exception) {
if (forward) {
forward_backward_in_ce_time(cale, &t, 1);
continue;
}
if (backward) {
forward_backward_in_ce_time(cale, &t, -1);
continue;
}
}
/* Check that proposed alarm is not before the appt begin date */
t_begin = mktime_dst_adj(&(cale->begin));
if (t_temp < t_begin) {
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t); printf("fpn: before begin date\n");
printf("fpn: initial monthly by day=%s\n", str);
#endif #endif
} backward = 0;
break; kill_update_next = 1;
case repeatMonthlyByDate: }
#ifdef ALARMS_DEBUG /* Check that proposed alarm is not past appt end date */
printf("fpn: repeatMonthlyByDate\n"); if (!(cale->repeatForever)) {
#endif t_end = mktime_dst_adj(&(cale->repeatEnd));
/* Jump to closest current date if appt. started in the past */ if (t_temp >= t_end) {
if ((date1->tm_year > cale->begin.tm_year) ||
(date1->tm_mon > cale->begin.tm_mon)) {
freq = cale->repeatFrequency;
offset = ((date1->tm_year - cale->begin.tm_year)*12) -
cale->begin.tm_mon +
date1->tm_mon;
offset = (offset/freq)*freq;
#ifdef ALARMS_DEBUG
printf("fpn: months offset = %d\n", offset);
#endif
add_months_to_date(&t, offset);
}
break;
case repeatYearly:
#ifdef ALARMS_DEBUG
printf("fpn: repeatYearly\n");
#endif
/* Jump to closest current date if appt. started in the past */
if (date1->tm_year > cale->begin.tm_year) {
freq = cale->repeatFrequency;
offset = ((date1->tm_year - cale->begin.tm_year)/freq)*freq;
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fpn: (%d - %d)%%%d\n", date1->tm_year, cale->begin.tm_year, fre printf("fpn: after end date\n");
q);
printf("fpn: years offset = %d\n", offset);
#endif #endif
add_years_to_date(&t, offset); forward = 0;
} }
break; }
} /* end switch on repeatType */
/* Search forwards/backwards through time for alarms */
safety_counter=0;
while (forward || backward) {
safety_counter++;
if (safety_counter > 3000) {
jp_logf(JP_LOG_STDOUT|JP_LOG_FILE, "find_prev_next(): %s\n", _("infinit
e loop, breaking\n"));
if (cale->description) {
jp_logf(JP_LOG_STDOUT|JP_LOG_FILE, "desc=[%s]\n", cale->description)
;
}
break;
}
kill_update_next = 0; /* Check if proposed alarm falls within the desired window [t1,t2] */
t_temp = mktime_dst_adj(&t); t_temp -= adv;
if (t_temp >= t2) {
if (!kill_update_next) {
memcpy(tm_next, &t, sizeof(t));
*next_found = 1;
forward = 0;
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
strftime(str, sizeof(str), "%B %d, %Y %H:%M", &t); printf("fpn: next found\n");
printf("fpn: trying with=%s\n", str); #endif
}
} else {
memcpy(tm_prev, &t, sizeof(t));
*prev_found = 1;
backward = 0;
#ifdef ALARMS_DEBUG
printf("fpn: prev_found\n");
#endif #endif
}
/* Check for exceptions in repeat appointments */ /* Change &t to the next/previous occurrence of the appointment
found_exception=0; * and try search again */
for (i=0; i<cale->exceptions; i++) { if (forward) {
if ((t.tm_mday==cale->exception[i].tm_mday) &&
(t.tm_mon==cale->exception[i].tm_mon) &&
(t.tm_year==cale->exception[i].tm_year)
) {
found_exception=1;
break;
}
}
if (found_exception) {
if (forward) {
forward_backward_in_ce_time(cale, &t, 1); forward_backward_in_ce_time(cale, &t, 1);
continue; continue;
} }
if (backward) { if (backward) {
forward_backward_in_ce_time(cale, &t, -1); forward_backward_in_ce_time(cale, &t, -1);
continue; continue;
} }
}
/* Check that proposed alarm is not before the appt begin date */
t_begin = mktime_dst_adj(&(cale->begin));
if (t_temp < t_begin) {
#ifdef ALARMS_DEBUG
printf("fpn: before begin date\n");
#endif
backward=0;
kill_update_next = 1;
}
/* Check that proposed alarm is not past appt end date */
if (!(cale->repeatForever)) {
t_end = mktime_dst_adj(&(cale->repeatEnd));
if (t_temp >= t_end) {
#ifdef ALARMS_DEBUG
printf("fpn: after end date\n");
#endif
forward=0;
}
}
/* Check if proposed alarm falls within the desired window [t1,t2] */
t_temp-=adv;
if (t_temp >= t2) {
if (!kill_update_next) {
memcpy(tm_next, &t, sizeof(t));
*next_found=1;
forward=0;
#ifdef ALARMS_DEBUG
printf("fpn: next found\n");
#endif
}
} else {
memcpy(tm_prev, &t, sizeof(t));
*prev_found=1;
backward=0;
#ifdef ALARMS_DEBUG
printf("fpn: prev_found\n");
#endif
}
/* Change &t to the next/previous occurrence of the appointment } /* end of while loop going forward/backward */
* and try search again */
if (forward) {
forward_backward_in_ce_time(cale, &t, 1);
continue;
}
if (backward) {
forward_backward_in_ce_time(cale, &t, -1);
continue;
}
} /* end of while loop going forward/backward */
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* This routine takes time (t) and either advances t to the next * This routine takes time (t) and either advances t to the next
* occurrence of a repeating appointment, or the previous occurrence * occurrence of a repeating appointment, or the previous occurrence
* *
* appt is the appointment passed in * appt is the appointment passed in
* t is an in/out parameter * t is an in/out parameter
* forward_or_backward should be 1 for forward or -1 for backward * forward_or_backward should be 1 for forward or -1 for backward
*/ */
int forward_backward_in_ce_time(const struct CalendarEvent *cale, int forward_backward_in_ce_time(const struct CalendarEvent *cale,
struct tm *t, struct tm *t,
int forward_or_backward) int forward_or_backward) {
{ int count, dow, freq, fdom, ndim;
int count, dow, freq, fdom, ndim;
freq = cale->repeatFrequency;
/* Go forward in time */
if (forward_or_backward==1) {
switch (cale->repeatType) {
case calendarRepeatNone:
#ifdef ALARMS_DEBUG
printf("fbiat: repeatNone encountered. This should never happen!\n");
#endif
break;
case calendarRepeatDaily:
add_days_to_date(t, freq);
break;
case calendarRepeatWeekly:
for (count=0, dow=t->tm_wday; count<14; count++) {
add_days_to_date(t, 1);
#ifdef ALARMS_DEBUG
printf("fbiat: weekly forward t.tm_wday=%d, freq=%d\n", t->tm_wday,
freq);
#endif
dow++;
if (dow==7) {
#ifdef ALARMS_DEBUG
printf("fbiat: dow==7\n");
#endif
add_days_to_date(t, (freq-1)*7);
dow=0;
}
if (cale->repeatDays[dow]) {
#ifdef ALARMS_DEBUG
printf("fbiat: repeatDay[dow] dow=%d\n", dow);
#endif
break;
}
}
break;
case calendarRepeatMonthlyByDay:
add_months_to_date(t, freq);
get_month_info(t->tm_mon, 1, t->tm_year, &fdom, &ndim);
t->tm_mday=((cale->repeatDay+7-fdom)%7) - ((cale->repeatDay)%7) + cale-
>repeatDay + 1;
if (t->tm_mday > ndim-1) {
t->tm_mday -= 7;
}
break;
case calendarRepeatMonthlyByDate:
t->tm_mday=cale->begin.tm_mday;
add_months_to_date(t, freq);
break;
case calendarRepeatYearly:
t->tm_mday=cale->begin.tm_mday;
add_years_to_date(t, freq);
break;
} /* switch on repeatType */
return EXIT_SUCCESS; freq = cale->repeatFrequency;
}
/* Go back in time */ /* Go forward in time */
if (forward_or_backward==-1) { if (forward_or_backward == 1) {
switch (cale->repeatType) { switch (cale->repeatType) {
case calendarRepeatNone: case calendarRepeatNone:
#ifdef ALARMS_DEBUG #ifdef ALARMS_DEBUG
printf("fbiat: repeatNone encountered. This should never happen!\n"); printf("fbiat: repeatNone encountered. This should never happen
#endif !\n");
break; #endif
case calendarRepeatDaily: break;
sub_days_from_date(t, freq); case calendarRepeatDaily:
break; add_days_to_date(t, freq);
case calendarRepeatWeekly: break;
for (count=0, dow=t->tm_wday; count<14; count++) { case calendarRepeatWeekly:
sub_days_from_date(t, 1); for (count = 0, dow = t->tm_wday; count < 14; count++) {
#ifdef ALARMS_DEBUG add_days_to_date(t, 1);
printf("fbiat: weekly backward t.tm_wday=%d, freq=%d\n", t->tm_wday, #ifdef ALARMS_DEBUG
freq); printf("fbiat: weekly forward t.tm_wday=%d, freq=%d\n", t->t
#endif m_wday, freq);
dow--; #endif
if (dow==-1) { dow++;
#ifdef ALARMS_DEBUG if (dow == 7) {
printf("fbiat: dow==-1\n"); #ifdef ALARMS_DEBUG
#endif printf("fbiat: dow==7\n");
sub_days_from_date(t, (freq-1)*7); #endif
dow=6; add_days_to_date(t, (freq - 1) * 7);
} dow = 0;
if (cale->repeatDays[dow]) { }
#ifdef ALARMS_DEBUG if (cale->repeatDays[dow]) {
printf("fbiat: repeatDay[dow] dow=%d\n", dow); #ifdef ALARMS_DEBUG
#endif printf("fbiat: repeatDay[dow] dow=%d\n", dow);
break; #endif
} break;
} }
break; }
case calendarRepeatMonthlyByDay: break;
sub_months_from_date(t, freq); case calendarRepeatMonthlyByDay:
get_month_info(t->tm_mon, 1, t->tm_year, &fdom, &ndim); add_months_to_date(t, freq);
t->tm_mday=((cale->repeatDay+7-fdom)%7) - ((cale->repeatDay)%7) + cale- get_month_info(t->tm_mon, 1, t->tm_year, &fdom, &ndim);
>repeatDay + 1; t->tm_mday = ((cale->repeatDay + 7 - fdom) % 7) - ((cale->repeat
if (t->tm_mday > ndim-1) { Day) % 7) + cale->repeatDay + 1;
t->tm_mday -= 7; if (t->tm_mday > ndim - 1) {
} t->tm_mday -= 7;
break; }
case calendarRepeatMonthlyByDate: break;
t->tm_mday=cale->begin.tm_mday; case calendarRepeatMonthlyByDate:
sub_months_from_date(t, freq); t->tm_mday = cale->begin.tm_mday;
break; add_months_to_date(t, freq);
case calendarRepeatYearly: break;
t->tm_mday=cale->begin.tm_mday; case calendarRepeatYearly:
sub_years_from_date(t, freq); t->tm_mday = cale->begin.tm_mday;
break; add_years_to_date(t, freq);
} /* switch on repeatType */ break;
} } /* switch on repeatType */
return EXIT_SUCCESS;
}
/* Go back in time */
if (forward_or_backward == -1) {
switch (cale->repeatType) {
case calendarRepeatNone:
#ifdef ALARMS_DEBUG
printf("fbiat: repeatNone encountered. This should never happen
!\n");
#endif
break;
case calendarRepeatDaily:
sub_days_from_date(t, freq);
break;
case calendarRepeatWeekly:
for (count = 0, dow = t->tm_wday; count < 14; count++) {
sub_days_from_date(t, 1);
#ifdef ALARMS_DEBUG
printf("fbiat: weekly backward t.tm_wday=%d, freq=%d\n", t->
tm_wday, freq);
#endif
dow--;
if (dow == -1) {
#ifdef ALARMS_DEBUG
printf("fbiat: dow==-1\n");
#endif
sub_days_from_date(t, (freq - 1) * 7);
dow = 6;
}
if (cale->repeatDays[dow]) {
#ifdef ALARMS_DEBUG
printf("fbiat: repeatDay[dow] dow=%d\n", dow);
#endif
break;
}
}
break;
case calendarRepeatMonthlyByDay:
sub_months_from_date(t, freq);
get_month_info(t->tm_mon, 1, t->tm_year, &fdom, &ndim);
t->tm_mday = ((cale->repeatDay + 7 - fdom) % 7) - ((cale->repeat
Day) % 7) + cale->repeatDay + 1;
if (t->tm_mday > ndim - 1) {
t->tm_mday -= 7;
}
break;
case calendarRepeatMonthlyByDate:
t->tm_mday = cale->begin.tm_mday;
sub_months_from_date(t, freq);
break;
case calendarRepeatYearly:
t->tm_mday = cale->begin.tm_mday;
sub_years_from_date(t, freq);
break;
} /* switch on repeatType */
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* Displays usage string on supplied file handle */ /* Displays usage string on supplied file handle */
void fprint_usage_string(FILE *out) void fprint_usage_string(FILE *out) {
{ fprintf(out, "%s [ -v || -h || [-d] [-p] [-a || -A] [-s] [-i] [-geometry] ]\
fprintf(out, "%s [ -v || -h || [-d] [-p] [-a || -A] [-s] [-i] [-geometry] ]\n n", EPN);
", EPN); fprintf(out, _(" -v display version and compile options\n"));
fprintf(out, _(" -v display version and compile options\n")); fprintf(out, _(" -h display help text\n"));
fprintf(out, _(" -h display help text\n")); fprintf(out, _(" -d display debug info to stdout\n"));
fprintf(out, _(" -d display debug info to stdout\n")); fprintf(out, _(" -p skip loading plugins\n"));
fprintf(out, _(" -p skip loading plugins\n")); fprintf(out, _(" -a ignore missed alarms since the last time program was run
fprintf(out, _(" -a ignore missed alarms since the last time program was run\ \n"));
n")); fprintf(out, _(" -A ignore all alarms past and future\n"));
fprintf(out, _(" -A ignore all alarms past and future\n")); fprintf(out, _(" -s start sync using existing instance of GUI\n"));
fprintf(out, _(" -s start sync using existing instance of GUI\n")); fprintf(out, _(" -i iconify program immediately after launch\n"));
fprintf(out, _(" -i iconify program immediately after launch\n")); fprintf(out, _(" -geometry {X geometry} use specified geometry for main wind
fprintf(out, _(" -geometry {X geometry} use specified geometry for main windo ow\n\n"));
w\n\n")); fprintf(out, _(" The PILOTPORT and PILOTRATE environment variables specify\n
fprintf(out, _(" The PILOTPORT and PILOTRATE environment variables specify\n" "));
)); fprintf(out, _(" which port to sync on, and at what speed.\n"));
fprintf(out, _(" which port to sync on, and at what speed.\n")); fprintf(out, _(" If PILOTPORT is not set then it defaults to /dev/pilot.\n")
fprintf(out, _(" If PILOTPORT is not set then it defaults to /dev/pilot.\n")) );
; }
}
void free_mem_rec_header(mem_rec_header **mem_rh) {
void free_mem_rec_header(mem_rec_header **mem_rh) mem_rec_header *h, *next_h;
{
mem_rec_header *h, *next_h; for (h = *mem_rh; h; h = next_h) {
next_h = h->next;
for (h=*mem_rh; h; h=next_h) { free(h);
next_h=h->next; }
free(h); *mem_rh = NULL;
} }
*mem_rh=NULL;
} void free_search_record_list(struct search_record **sr) {
struct search_record *temp_sr, *temp_sr_next;
void free_search_record_list(struct search_record **sr)
{ for (temp_sr = *sr; temp_sr; temp_sr = temp_sr_next) {
struct search_record *temp_sr, *temp_sr_next; temp_sr_next = temp_sr->next;
free(temp_sr);
for (temp_sr = *sr; temp_sr; temp_sr=temp_sr_next) { }
temp_sr_next = temp_sr->next; *sr = NULL;
free(temp_sr);
}
*sr = NULL;
} }
/* Warning, this function will move the file pointer */ /* Warning, this function will move the file pointer */
int get_app_info_size(FILE *in, int *size) int get_app_info_size(FILE *in, int *size) {
{ unsigned char raw_header[LEN_RAW_DB_HEADER];
unsigned char raw_header[LEN_RAW_DB_HEADER]; DBHeader dbh;
DBHeader dbh; unsigned int offset;
unsigned int offset; record_header rh;
record_header rh;
fseek(in, 0, SEEK_SET);
fseek(in, 0, SEEK_SET);
if (fread(raw_header, LEN_RAW_DB_HEADER, 1, in) < 1) {
if (fread(raw_header, LEN_RAW_DB_HEADER, 1, in) < 1) { jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__);
jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__); }
} if (feof(in)) {
if (feof(in)) { jp_logf(JP_LOG_WARN, "get_app_info_size(): %s\n", _("Error reading file"
jp_logf(JP_LOG_WARN, "get_app_info_size(): %s\n", _("Error reading file")) ));
; return EXIT_FAILURE;
return EXIT_FAILURE; }
}
unpack_db_header(&dbh, raw_header);
unpack_db_header(&dbh, raw_header);
if (dbh.app_info_offset == 0) {
if (dbh.app_info_offset==0) { *size = 0;
*size=0; return EXIT_SUCCESS;
return EXIT_SUCCESS; }
} if (dbh.sort_info_offset != 0) {
if (dbh.sort_info_offset!=0) { *size = dbh.sort_info_offset - dbh.app_info_offset;
*size = dbh.sort_info_offset - dbh.app_info_offset; return EXIT_SUCCESS;
return EXIT_SUCCESS; }
} if (dbh.number_of_records == 0) {
if (dbh.number_of_records==0) { fseek(in, 0, SEEK_END);
fseek(in, 0, SEEK_END); *size = ftell(in) - dbh.app_info_offset;
*size=ftell(in) - dbh.app_info_offset; return EXIT_SUCCESS;
return EXIT_SUCCESS; }
}
if (fread(&rh, sizeof(record_header), 1, in) < 1) {
if (fread(&rh, sizeof(record_header), 1, in) < 1) { jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__);
jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__); }
} offset = ((rh.Offset[0] * 256 + rh.Offset[1]) * 256 + rh.Offset[2]) * 256 +
offset = ((rh.Offset[0]*256+rh.Offset[1])*256+rh.Offset[2])*256+rh.Offset[3]; rh.Offset[3];
*size=offset - dbh.app_info_offset; *size = offset - dbh.app_info_offset;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
void get_compile_options(char *string, int len) void get_compile_options(char *string, int len) {
{ g_snprintf(string, len,
g_snprintf(string, len, PN" version "VERSION"\n"
PN" version "VERSION"\n" " Copyright (C) 1999-2014 by Judd Montgomery\n"
" Copyright (C) 1999-2014 by Judd Montgomery\n" " judd@jpilot.org, http://jpilot.org\n"
" judd@jpilot.org, http://jpilot.org\n" "\n"
"\n" PN" comes with ABSOLUTELY NO WARRANTY; for details see the file\n
PN" comes with ABSOLUTELY NO WARRANTY; for details see the file\n" "
"COPYING included with the source code, or in /usr/share/docs/jpil "COPYING included with the source code, or in /usr/share/docs/jpi
ot/.\n\n" lot/.\n\n"
"This program is free software; you can redistribute it and/or mod "This program is free software; you can redistribute it and/or mo
ify\n" dify\n"
"it under the terms of the GNU General Public License as published "it under the terms of the GNU General Public License as publishe
by\n" d by\n"
"the Free Software Foundation; version 2 of the License.\n\n" "the Free Software Foundation; version 2 of the License.\n\n"
"%s %s %s\n" "%s %s %s\n"
"%s\n" "%s\n"
" %s - %s\n" " %s - %s\n"
" %s - %d.%d.%d\n" " %s - %d.%d.%d\n"
" %s - %s\n" " %s - %s\n"
" %s - %s\n" " %s - %s\n"
" %s - %s\n" " %s - %s\n"
" %s - %s\n" " %s - %s\n"
" %s - %s\n" " %s - %s\n"
" %s - %s\n" " %s - %s\n"
" %s - %s", " %s - %s",
_("Date compiled"), __DATE__, __TIME__, _("Date compiled"), __DATE__, __TIME__,
_("Compiled with these options:"), _("Compiled with these options:"),
_("Installed Path"), _("Installed Path"),
BASE_DIR, BASE_DIR,
_("pilot-link version"), _("pilot-link version"),
PILOT_LINK_VERSION, PILOT_LINK_VERSION,
PILOT_LINK_MAJOR, PILOT_LINK_MAJOR,
PILOT_LINK_MINOR, PILOT_LINK_MINOR,
_("USB support"), _("USB support"),
_("yes"), _("yes"),
_("Private record support"), _("Private record support"),
#ifdef ENABLE_PRIVATE #ifdef ENABLE_PRIVATE
_("yes"), _("yes"),
#else #else
_("no"), _("no"),
#endif #endif
_("Datebk support"), _("Datebk support"),
#ifdef ENABLE_DATEBK #ifdef ENABLE_DATEBK
_("yes"), _("yes"),
#else #else
_("no"), _("no"),
#endif #endif
_("Plugin support"), _("Plugin support"),
#ifdef ENABLE_PLUGINS #ifdef ENABLE_PLUGINS
_("yes"), _("yes"),
#else #else
_("no"), _("no"),
#endif #endif
_("Manana support"), _("Manana support"),
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
_("yes"), _("yes"),
#else #else
_("no"), _("no"),
#endif #endif
_("NLS support (foreign languages)"), _("NLS support (foreign languages)"),
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
_("yes"), _("yes"),
#else #else
_("no"), _("no"),
#endif #endif
_("GTK2 support"), _("GTK3 support"),
_("yes") _("yes")
); );
} }
/* Get today's date and work out day in month. This is used to highlight /* Get today's date and work out day in month. This is used to highlight
* today in the gui (read-only) views. Returns the day of month if today * today in the gui (read-only) views. Returns the day of month if today
* is in the passed month else returns -1. */ * is in the passed month else returns -1. */
int get_highlighted_today(struct tm *date) int get_highlighted_today(struct tm *date) {
{ time_t now;
time_t now; struct tm *now_tm;
struct tm* now_tm;
/* Quit immediately if the user option is not enabled */
if (!get_pref_int_default(PREF_DATEBOOK_HI_TODAY, FALSE))
return -1;
/* Get now time */
now = time(NULL);
now_tm = localtime(&now);
/* Quit immediately if the user option is not enabled */ /* Check if option is on and return today's day of month if the month
if (!get_pref_int_default(PREF_DATEBOOK_HI_TODAY, FALSE))
return -1;
/* Get now time */
now = time(NULL);
now_tm = localtime(&now);
/* Check if option is on and return today's day of month if the month
* and year match was was passed in */ * and year match was was passed in */
if (now_tm->tm_mon != date->tm_mon || now_tm->tm_year != date->tm_year) if (now_tm->tm_mon != date->tm_mon || now_tm->tm_year != date->tm_year)
return -1; return -1;
/* Today is within the passed month, return the day of month */ /* Today is within the passed month, return the day of month */
return now_tm->tm_mday; return now_tm->tm_mday;
} }
/* creates the full path name of a file in the ~/.jpilot dir */ /* creates the full path name of a file in the ~/.jpilot dir */
int get_home_file_name(const char *file, char *full_name, int max_size) int get_home_file_name(const char *file, char *full_name, int max_size) {
{ char *home, default_path[] = ".";
char *home, default_path[]=".";
#ifdef ENABLE_PROMETHEON #ifdef ENABLE_PROMETHEON
home = getenv("COPILOT_HOME"); home = getenv("COPILOT_HOME");
#else #else
home = getenv("JPILOT_HOME"); home = getenv("JPILOT_HOME");
#endif #endif
if (!home) {/* No JPILOT_HOME var */ if (!home) {/* No JPILOT_HOME var */
home = getenv("HOME"); home = getenv("HOME");
if (!home) {/* No HOME var */ if (!home) {/* No HOME var */
fprintf(stderr, _("Can't get HOME environment variable\n")); fprintf(stderr, _("Can't get HOME environment variable\n"));
} }
} }
if (!home) { if (!home) {
home = default_path; home = default_path;
} }
if (strlen(home)>(max_size-strlen(file)-strlen("/."EPN"/")-2)) { if (strlen(home) > (max_size - strlen(file) - strlen("/."EPN"/") - 2)) {
fprintf(stderr, _("HOME environment variable is too long to process\n")); fprintf(stderr, _("HOME environment variable is too long to process\n"))
home=default_path; ;
} home = default_path;
sprintf(full_name, "%s/."EPN"/%s", home, file); }
return EXIT_SUCCESS; sprintf(full_name, "%s/."EPN"/%s", home, file);
return EXIT_SUCCESS;
} }
/* /*
* month = 0-11 * month = 0-11
* day = day of month 1-31 * day = day of month 1-31
* returns: * returns:
* dow = day of week for this date * dow = day of week for this date
* ndim = number of days in month 28-31 * ndim = number of days in month 28-31
*/ */
void get_month_info(int month, int day, int year, int *dow, int *ndim) void get_month_info(int month, int day, int year, int *dow, int *ndim) {
{ time_t ltime;
time_t ltime; struct tm *now;
struct tm *now; struct tm new_time;
struct tm new_time; int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
int days_in_month[]={31,28,31,30,31,30,31,31,30,31,30,31 };
};
time(&ltime);
time(&ltime); now = localtime(&ltime);
now = localtime(&ltime);
new_time.tm_sec = 0;
new_time.tm_sec=0; new_time.tm_min = 0;
new_time.tm_min=0; new_time.tm_hour = 11;
new_time.tm_hour=11; new_time.tm_mday = day; /* day of month 1-31 */
new_time.tm_mday=day; /* day of month 1-31 */ new_time.tm_mon = month;
new_time.tm_mon=month; new_time.tm_year = year;
new_time.tm_year=year; new_time.tm_isdst = now->tm_isdst;
new_time.tm_isdst=now->tm_isdst;
mktime(&new_time);
mktime(&new_time); *dow = new_time.tm_wday;
*dow = new_time.tm_wday;
/* leap year */
/* leap year */ if (month == 1) {
if (month == 1) { if ((year % 4 == 0) &&
if ((year%4 == 0) && !(((year + 1900) % 100 == 0) && ((year + 1900) % 400 != 0))
!(((year+1900)%100==0) && ((year+1900)%400!=0)) ) {
) { days_in_month[1]++;
days_in_month[1]++; }
} }
} *ndim = days_in_month[month];
*ndim = days_in_month[month]; }
}
int get_next_unique_pc_id(unsigned int *next_unique_id) {
int get_next_unique_pc_id(unsigned int *next_unique_id) FILE *pc_in_out;
{ char file_name[FILENAME_MAX];
FILE *pc_in_out; char str[256];
char file_name[FILENAME_MAX];
char str[256];
/* Check that file exists and is not empty. If not, /* Check that file exists and is not empty. If not,
* create it and start unique id numbering from 1 */ * create it and start unique id numbering from 1 */
pc_in_out = jp_open_home_file(EPN".next_id", "a"); pc_in_out = jp_open_home_file(EPN".next_id", "a");
if (pc_in_out==NULL) { if (pc_in_out == NULL) {
jp_logf(JP_LOG_WARN, _("Error opening file: %s\n"),file_name); jp_logf(JP_LOG_WARN, _("Error opening file: %s\n"), file_name);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (ftell(pc_in_out)==0) { if (ftell(pc_in_out) == 0) {
/* The file is new. We have to write out the file header */ /* The file is new. We have to write out the file header */
*next_unique_id=1; *next_unique_id = 1;
write_to_next_id_open(pc_in_out, *next_unique_id); write_to_next_id_open(pc_in_out, *next_unique_id);
} }
jp_close_home_file(pc_in_out); jp_close_home_file(pc_in_out);
/* Now that file has been verified we can use it to find the next id */ /* Now that file has been verified we can use it to find the next id */
pc_in_out = jp_open_home_file(EPN".next_id", "r+"); pc_in_out = jp_open_home_file(EPN".next_id", "r+");
if (pc_in_out==NULL) { if (pc_in_out == NULL) {
jp_logf(JP_LOG_WARN, _("Error opening file: %s\n"),file_name); jp_logf(JP_LOG_WARN, _("Error opening file: %s\n"), file_name);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
memset(str, '\0', sizeof(FILE_VERSION)+4); memset(str, '\0', sizeof(FILE_VERSION) + 4);
if (fread(str, strlen(FILE_VERSION), 1, pc_in_out) < 1) { if (fread(str, strlen(FILE_VERSION), 1, pc_in_out) < 1) {
jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__); jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__);
} }
if (!strcmp(str, FILE_VERSION)) { if (!strcmp(str, FILE_VERSION)) {
/* Must be a versioned file */ /* Must be a versioned file */
fseek(pc_in_out, 0, SEEK_SET); fseek(pc_in_out, 0, SEEK_SET);
if (fgets(str, 200, pc_in_out) == NULL) { if (fgets(str, 200, pc_in_out) == NULL) {
jp_logf(JP_LOG_WARN, "fgets failed %s %d\n", __FILE__, __LINE__); jp_logf(JP_LOG_WARN, "fgets failed %s %d\n", __FILE__, __LINE__);
} }
if (fgets(str, 200, pc_in_out) == NULL) { if (fgets(str, 200, pc_in_out) == NULL) {
jp_logf(JP_LOG_WARN, "fgets failed %s %d\n" __FILE__, __LINE__); jp_logf(JP_LOG_WARN, "fgets failed %s %d\n" __FILE__, __LINE__);
} }
str[200]='\0'; str[200] = '\0';
*next_unique_id = atoi(str); *next_unique_id = atoi(str);
} else { } else {
fseek(pc_in_out, 0, SEEK_SET); fseek(pc_in_out, 0, SEEK_SET);
if (fread(next_unique_id, sizeof(*next_unique_id), 1, pc_in_out) < 1) { if (fread(next_unique_id, sizeof(*next_unique_id), 1, pc_in_out) < 1) {
jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__); jp_logf(JP_LOG_WARN, "fread failed %s %d\n", __FILE__, __LINE__);
} }
} }
(*next_unique_id)++; (*next_unique_id)++;
if (fseek(pc_in_out, 0, SEEK_SET)) { if (fseek(pc_in_out, 0, SEEK_SET)) {
jp_logf(JP_LOG_WARN, "fseek failed %s %d\n", __FILE__, __LINE__); jp_logf(JP_LOG_WARN, "fseek failed %s %d\n", __FILE__, __LINE__);
} }
/* rewind(pc_in_out); */ /* rewind(pc_in_out); */
/* todo - if > 16777216 then cleanup */ /* todo - if > 16777216 then cleanup */
write_to_next_id_open(pc_in_out, *next_unique_id); write_to_next_id_open(pc_in_out, *next_unique_id);
jp_close_home_file(pc_in_out); jp_close_home_file(pc_in_out);
return EXIT_SUCCESS;
}
int get_pixbufs(int which_pixbuf,
GdkPixbuf **out_pixbuf) {
/* Externally stored icon definitions */
#include "icons/list_mini_icons.h"
static int init_done = 0;
static GdkPixbuf *pixbuf_note;
static GdkPixbuf *pixbuf_alarm;
static GdkPixbuf *pixbuf_check;
static GdkPixbuf *pixbuf_checked;
static GdkPixbuf *pixbuf_float_check;
static GdkPixbuf *pixbuf_float_checked;
static GdkPixbuf *pixbuf_sdcard;
/* Pixbufs are created only once when procedure is first called */
if (!init_done) {
init_done = 1;
/* Make the note pixmap */
pixbuf_note = gdk_pixbuf_new_from_xpm_data(xpm_note);
/* Make the alarm pixmap */
pixbuf_alarm = gdk_pixbuf_new_from_xpm_data(xpm_alarm);
/* Make the check pixmap */
pixbuf_check = gdk_pixbuf_new_from_xpm_data(xpm_check);
/* Make the checked pixmap */
pixbuf_checked = gdk_pixbuf_new_from_xpm_data(xpm_checked);
/* Make the float_checked pixmap */
pixbuf_float_check = gdk_pixbuf_new_from_xpm_data(xpm_float_check);
/* Make the float_checked pixmap */
pixbuf_float_checked = gdk_pixbuf_new_from_xpm_data(xpm_float_checked);
/* Make the sdcard pixmap */
pixbuf_sdcard = gdk_pixbuf_new_from_xpm_data(xpm_sdcard);
} /* End initialization of pixmaps */
switch (which_pixbuf) {
case PIXMAP_NOTE:
*out_pixbuf = pixbuf_note;
return EXIT_SUCCESS; break;
} case PIXMAP_ALARM:
*out_pixbuf = pixbuf_alarm;
int get_pixmaps(GtkWidget *widget, break;
int which_pixmap, case PIXMAP_BOX_CHECK:
GdkPixmap **out_pixmap, *out_pixbuf = pixbuf_check;
GdkBitmap **out_mask)
{
/* Externally stored icon definitions */
#include "icons/clist_mini_icons.h"
static int init_done=0; break;
static GdkPixmap *pixmap_note; case PIXMAP_BOX_CHECKED:
static GdkPixmap *pixmap_alarm; *out_pixbuf = pixbuf_checked;
static GdkPixmap *pixmap_check; break;
static GdkPixmap *pixmap_checked; case PIXMAP_FLOAT_CHECK:
static GdkPixmap *pixmap_float_check; *out_pixbuf = pixbuf_float_check;
static GdkPixmap *pixmap_float_checked; break;
static GdkPixmap *pixmap_sdcard; case PIXMAP_FLOAT_CHECKED:
static GdkBitmap *mask_note; *out_pixbuf = pixbuf_float_checked;
static GdkBitmap *mask_alarm; break;
static GdkBitmap *mask_check; case PIXMAP_SDCARD:
static GdkBitmap *mask_checked; *out_pixbuf = pixbuf_sdcard;
static GdkBitmap *mask_float_check; break;
static GdkBitmap *mask_float_checked; default:
static GdkBitmap *mask_sdcard; *out_pixbuf = NULL;
GtkStyle *style; }
/* Pixmaps are created only once when procedure is first called */
if (!init_done) {
init_done = 1;
/* Make the note pixmap */
style = gtk_widget_get_style(widget);
pixmap_note = gdk_pixmap_create_from_xpm_d(widget->window, &mask_note,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_note);
/* Make the alarm pixmap */
pixmap_alarm = gdk_pixmap_create_from_xpm_d(widget->window, &mask_alarm,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_alarm);
/* Make the check pixmap */
pixmap_check = gdk_pixmap_create_from_xpm_d(widget->window, &mask_check,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_check);
/* Make the checked pixmap */
pixmap_checked = gdk_pixmap_create_from_xpm_d
(widget->window, &mask_checked,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_checked);
/* Make the float_checked pixmap */
pixmap_float_check = gdk_pixmap_create_from_xpm_d
(widget->window, &mask_float_check,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_float_check);
/* Make the float_checked pixmap */
pixmap_float_checked = gdk_pixmap_create_from_xpm_d
(widget->window, &mask_float_checked,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_float_checked);
/* Make the sdcard pixmap */
pixmap_sdcard = gdk_pixmap_create_from_xpm_d(widget->window, &mask_sdcard,
&style->bg[GTK_STATE_NORMAL],
(gchar **)xpm_sdcard);
} /* End initialization of pixmaps */
switch (which_pixmap) {
case PIXMAP_NOTE:
*out_pixmap = pixmap_note;
*out_mask = mask_note;
break;
case PIXMAP_ALARM:
*out_pixmap = pixmap_alarm;
*out_mask = mask_alarm;
break;
case PIXMAP_BOX_CHECK:
*out_pixmap = pixmap_check;
*out_mask = mask_check;
break;
case PIXMAP_BOX_CHECKED:
*out_pixmap = pixmap_checked;
*out_mask = mask_checked;
break;
case PIXMAP_FLOAT_CHECK:
*out_pixmap = pixmap_float_check;
*out_mask = mask_float_check;
break;
case PIXMAP_FLOAT_CHECKED:
*out_pixmap = pixmap_float_checked;
*out_mask = mask_float_checked;
break;
case PIXMAP_SDCARD:
*out_pixmap = pixmap_sdcard;
*out_mask = mask_sdcard;
break;
default:
*out_pixmap = NULL;
*out_mask = NULL;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int get_timeout_interval(void) int get_timeout_interval(void) {
{ const char *svalue;
const char *svalue;
get_pref(PREF_TIME, NULL, &svalue); get_pref(PREF_TIME, NULL, &svalue);
if (strstr(svalue,"%S")) if (strstr(svalue, "%S"))
return CLOCK_TICK; return CLOCK_TICK;
else else
return 60*CLOCK_TICK; return 60 * CLOCK_TICK;
} }
int jp_cal_dialog(GtkWindow *main_window, int jp_cal_dialog(GtkWindow *main_window,
const char *title, int monday_is_fdow, const char *title, int monday_is_fdow,
int *mon, int *day, int *year) int *mon, int *day, int *year) {
{ return cal_dialog(main_window,
return cal_dialog(main_window, title, monday_is_fdow,
title, monday_is_fdow, mon, day, year);
mon, day, year);
} }
void jp_charset_j2p(char *const buf, int max_len) void jp_charset_j2p(char *const buf, int max_len) {
{ long char_set;
long char_set;
get_pref(PREF_CHAR_SET, &char_set, NULL); get_pref(PREF_CHAR_SET, &char_set, NULL);
charset_j2p(buf, max_len, char_set); charset_j2p(buf, max_len, char_set);
} }
void jp_charset_p2j(char *const buf, int max_len) void jp_charset_p2j(char *const buf, int max_len) {
{ long char_set;
long char_set;
get_pref(PREF_CHAR_SET, &char_set, NULL); get_pref(PREF_CHAR_SET, &char_set, NULL);
if (char_set == CHAR_SET_JAPANESE) if (char_set == CHAR_SET_JAPANESE)
jp_Sjis2Euc(buf, max_len); jp_Sjis2Euc(buf, max_len);
else else
charset_p2j(buf, max_len, char_set); charset_p2j(buf, max_len, char_set);
} }
char* jp_charset_p2newj(const char *buf, int max_len) char *jp_charset_p2newj(const char *buf, int max_len) {
{ long char_set;
long char_set;
get_pref(PREF_CHAR_SET, &char_set, NULL); get_pref(PREF_CHAR_SET, &char_set, NULL);
return(charset_p2newj(buf, max_len, char_set)); return (charset_p2newj(buf, max_len, char_set));
} }
int jp_close_home_file(FILE *pc_in) int jp_close_home_file(FILE *pc_in) {
{ /* unlock access */
/* unlock access */
#ifndef USE_FLOCK #ifndef USE_FLOCK
struct flock lock; struct flock lock;
int r; int r;
lock.l_type = F_UNLCK; lock.l_type = F_UNLCK;
lock.l_start = 0; lock.l_start = 0;
lock.l_whence = SEEK_SET; lock.l_whence = SEEK_SET;
lock.l_len = 0; lock.l_len = 0;
r = fcntl(fileno(pc_in), F_SETLK, &lock); r = fcntl(fileno(pc_in), F_SETLK, &lock);
if (r == -1) if (r == -1)
#else #else
if (flock(fileno(pc_in), LOCK_UN) < 0) if (flock(fileno(pc_in), LOCK_UN) < 0)
#endif #endif
jp_logf(JP_LOG_WARN, "unlocking failed: %s\n", strerror(errno)); jp_logf(JP_LOG_WARN, "unlocking failed: %s\n", strerror(errno));
return fclose(pc_in);
}
int jp_copy_file(char *src, char *dest)
{
FILE *in, *out;
int r;
struct stat statb;
struct utimbuf times;
unsigned char buf[10002];
if (!strcmp(src, dest)) {
return EXIT_SUCCESS;
}
in = fopen(src, "r"); return fclose(pc_in);
out = fopen(dest, "w");
if (!in) {
return EXIT_FAILURE;
}
if (!out) {
fclose(in);
return EXIT_FAILURE;
}
while ((r = fread(buf, 1, sizeof(buf)-2, in))) {
fwrite(buf, 1, r, out);
}
fclose(in);
fclose(out);
/* Set the create and modify times of new file to the same as the old */
stat(src, &statb);
times.actime = statb.st_atime;
times.modtime = statb.st_mtime;
utime(dest, &times);
return EXIT_SUCCESS;
} }
FILE *jp_open_home_file(const char *filename, const char *mode) int jp_copy_file(char *src, char *dest) {
{ FILE *in, *out;
char fullname[FILENAME_MAX]; int r;
FILE *pc_in; struct stat statb;
struct utimbuf times;
get_home_file_name(filename, fullname, sizeof(fullname)); unsigned char buf[10002];
pc_in = fopen(fullname, mode); if (!strcmp(src, dest)) {
if (pc_in == NULL) { return EXIT_SUCCESS;
pc_in = fopen(fullname, "w+"); }
if (pc_in) {
fclose(pc_in); in = fopen(src, "r");
pc_in = fopen(fullname, mode); if (!in) {
} return EXIT_FAILURE;
} }
out = fopen(dest, "w");
/* if the file exists */ if (!out) {
if (pc_in) fclose(in);
{ return EXIT_FAILURE;
/* lock access */ }
while ((r = fread(buf, 1, sizeof(buf) - 2, in))) {
fwrite(buf, 1, r, out);
}
fclose(in);
fclose(out);
/* Set the create and modify times of new file to the same as the old */
stat(src, &statb);
times.actime = statb.st_atime;
times.modtime = statb.st_mtime;
utime(dest, &times);
return EXIT_SUCCESS;
}
FILE *jp_open_home_file(const char *filename, const char *mode) {
char fullname[FILENAME_MAX];
FILE *pc_in;
get_home_file_name(filename, fullname, sizeof(fullname));
pc_in = fopen(fullname, mode);
if (pc_in == NULL) {
pc_in = fopen(fullname, "w+");
if (pc_in) {
fclose(pc_in);
pc_in = fopen(fullname, mode);
}
}
/* if the file exists */
if (pc_in) {
/* lock access */
#ifndef USE_FLOCK #ifndef USE_FLOCK
struct flock lock; struct flock lock;
int r; int r;
if (*mode == 'r') if (*mode == 'r')
lock.l_type = F_RDLCK; lock.l_type = F_RDLCK;
else else
lock.l_type = F_WRLCK; lock.l_type = F_WRLCK;
lock.l_start = 0; lock.l_start = 0;
lock.l_whence = SEEK_SET; lock.l_whence = SEEK_SET;
lock.l_len = 0; /* Lock to the end of file */ lock.l_len = 0; /* Lock to the end of file */
r = fcntl(fileno(pc_in), F_SETLK, &lock); r = fcntl(fileno(pc_in), F_SETLK, &lock);
if (r == -1) if (r == -1)
#else #else
if (flock(fileno(pc_in), LOCK_EX) < 0) if (flock(fileno(pc_in), LOCK_EX) < 0)
#endif #endif
{ {
jp_logf(JP_LOG_WARN, "locking %s failed: %s\n", filename, strerror(errn jp_logf(JP_LOG_WARN, "locking %s failed: %s\n", filename, strerror(e
o)); rrno));
if (ENOLCK != errno) if (ENOLCK != errno) {
{ fclose(pc_in);
fclose(pc_in); return NULL;
return NULL; } else
} jp_logf(JP_LOG_WARN, "continue without locking\n");
else }
jp_logf(JP_LOG_WARN, "continue without locking\n");
}
/* Enhance privacy by only allowing user to read & write files */ /* Enhance privacy by only allowing user to read & write files */
chmod(fullname, 0600); chmod(fullname, 0600);
} }
return pc_in; return pc_in;
} }
size_t jp_strftime(char *s, size_t max, const char *format, const struct tm *tm) size_t jp_strftime(char *s, size_t max, const char *format, const struct tm *tm)
{ {
size_t ret; size_t ret;
gchar *utf8_text; gchar *utf8_text;
gchar *local_format; gchar *local_format;
/* the format string is UTF-8 encoded since it comes from a .po file */ /* the format string is UTF-8 encoded since it comes from a .po file */
local_format = g_locale_from_utf8(format, -1, NULL, NULL, NULL); local_format = g_locale_from_utf8(format, -1, NULL, NULL, NULL);
ret = strftime(s, max, local_format, tm); ret = strftime(s, max, local_format, tm);
g_free(local_format); g_free(local_format);
utf8_text = g_locale_to_utf8(s, -1, NULL, NULL, NULL); utf8_text = g_locale_to_utf8(s, -1, NULL, NULL, NULL);
g_strlcpy(s, utf8_text, max); g_strlcpy(s, utf8_text, max);
g_free(utf8_text); g_free(utf8_text);
return ret; return ret;
} }
/* RFC 2849 */ /* RFC 2849 */
void ldif_out(FILE *f, const char *name, const char *fmt, ...) void ldif_out(FILE *f, const char *name, const char *fmt, ...) {
{ va_list ap;
va_list ap; unsigned char buf[8192];
unsigned char buf[8192]; char *p;
char *p; int printable = 1;
int printable = 1;
va_start(ap, fmt);
va_start(ap, fmt); vsnprintf((char *) buf, sizeof(buf), fmt, ap);
vsnprintf((char *)buf, sizeof(buf), fmt, ap); if (buf[0] == ' ' || buf[0] == ':' || buf[0] == '<') /* SAFE-INIT-CHAR */ {
if (buf[0] == ' ' || buf[0] == ':' || buf[0] == '<') /* SAFE-INIT-CHAR */ { printable = 0;
printable = 0; }
} for (p = (char *) buf; *p && printable; p++) {
for (p = (char *)buf; *p && printable; p++) { if (*p < 32 || *p > 126) { /* SAFE-CHAR, excluding all control chars */
if (*p < 32 || *p > 126) { /* SAFE-CHAR, excluding all control chars */ printable = 0;
printable = 0; }
} if (*p == ' ' && *(p + 1) == '\0') { /* note 8 */
if (*p == ' ' && *(p + 1) == '\0') { /* note 8 */ printable = 0;
printable = 0; }
} }
} if (printable) {
if (printable) { fprintf(f, "%s: %s\n", name, buf);
fprintf(f, "%s: %s\n", name, buf); } else {
} else { fprintf(f, "%s:: ", name);
fprintf(f, "%s:: ", name); base64_out(f, buf);
base64_out(f, buf); fprintf(f, "\n");
fprintf(f, "\n"); }
}
} }
/* Parse the string and replace CR and LFs with spaces /* Parse the string and replace CR and LFs with spaces
* a null is written if len is reached */ * a null is written if len is reached */
void lstrncpy_remove_cr_lfs(char *dest, char *src, int len) void lstrncpy_remove_cr_lfs(char *dest, char *src, int len) {
{ int i;
int i; gchar *end;
gchar* end;
if ((!src) || (!dest)) {
if ((!src) || (!dest)) { return;
return; }
}
dest[0] = '\0';
dest[0]='\0'; for (i = 0; src[i] && (i < len); i++) {
for (i=0; src[i] && (i<len); i++) { if ((src[i] == '\r') || (src[i] == '\n')) {
if ((src[i]=='\r') || (src[i]=='\n')) { dest[i] = ' ';
dest[i]=' '; } else {
} else { dest[i] = src[i];
dest[i]=src[i]; }
} }
} if (i == len) {
if (i==len) { dest[i - 1] = '\0';
dest[i-1]='\0'; } else {
} else { dest[i] = '\0';
dest[i]='\0'; }
}
/* truncate the string on a UTF-8 character boundary */
/* truncate the string on a UTF-8 character boundary */ if (!g_utf8_validate(dest, -1, (const gchar **) &end))
if (!g_utf8_validate(dest, -1, (const gchar **)&end)) *end = 0;
*end = 0;
} }
int make_category_menu(GtkWidget **category_menu, int make_category_menu(GtkWidget **category_menu,
GtkWidget **cat_menu_item,
struct sorted_cats *sort_l, struct sorted_cats *sort_l,
void (*selection_callback) void (*selection_callback)
(GtkWidget *item, int selection), (GtkComboBox *item, int selection),
int add_an_all_item, int add_an_all_item,
int add_edit_cat_item) int add_edit_cat_item) {
{
GtkWidget *menu;
GSList *group;
int i;
int offset;
*category_menu = gtk_option_menu_new();
menu = gtk_menu_new();
group = NULL;
offset=0;
if (add_an_all_item) {
cat_menu_item[0] = gtk_radio_menu_item_new_with_label(group, _("All"));
if (selection_callback) {
gtk_signal_connect(GTK_OBJECT(cat_menu_item[0]), "activate",
GTK_SIGNAL_FUNC(selection_callback), GINT_TO_POINTER
(CATEGORY_ALL));
}
group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(cat_menu_item[0]));
gtk_menu_append(GTK_MENU(menu), cat_menu_item[0]);
gtk_widget_show(cat_menu_item[0]);
offset=1;
}
for (i=0; i<NUM_CAT_ITEMS; i++) {
if (sort_l[i].Pcat[0]) {
cat_menu_item[i+offset] = gtk_radio_menu_item_new_with_label(
group, sort_l[i].Pcat);
if (selection_callback) {
gtk_signal_connect(GTK_OBJECT(cat_menu_item[i+offset]), "activate",
GTK_SIGNAL_FUNC(selection_callback), GINT_TO_POIN
TER(sort_l[i].cat_num));
}
group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(cat_menu_item[i+o
ffset]));
gtk_menu_append(GTK_MENU(menu), cat_menu_item[i+offset]);
gtk_widget_show(cat_menu_item[i+offset]);
}
else
cat_menu_item[i+offset] = NULL;
}
if (add_edit_cat_item) {
cat_menu_item[i+offset] = gtk_radio_menu_item_new_with_label(group,
_("Edit Categories..."));
if (selection_callback) {
gtk_signal_connect(GTK_OBJECT(cat_menu_item[i+offset]), "activate",
GTK_SIGNAL_FUNC(selection_callback), GINT_TO_POINTER
(i+offset));
}
group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(cat_menu_item[i+offs
et]));
gtk_menu_append(GTK_MENU(menu), cat_menu_item[i+offset]);
gtk_widget_show(cat_menu_item[i+offset]);
}
gtk_option_menu_set_menu(GTK_OPTION_MENU(*category_menu), menu);
return EXIT_SUCCESS;
}
time_t mktime_dst_adj(struct tm *tm)
{
struct tm t;
memcpy(&t, tm, sizeof(t));
t.tm_isdst=-1;
return mktime(&t);
}
char *multibyte_safe_memccpy(char *dst, const char *src, int c, size_t len)
{
long char_set;
if (len == 0) return NULL; int i;
if (dst == NULL) return NULL; GtkListStore *catListStore = gtk_list_store_new(2,G_TYPE_STRING,G_TYPE_INT);
if (src == NULL) return NULL; GtkTreeIter iter;
get_pref(PREF_CHAR_SET, &char_set, NULL); if (add_an_all_item) {
gtk_list_store_append (catListStore, &iter);
if (char_set == CHAR_SET_JAPANESE || gtk_list_store_set (catListStore, &iter, 0, _("All"), 1, CATEGORY_ALL, -
char_set == CHAR_SET_TRADITIONAL_CHINESE || 1);
char_set == CHAR_SET_KOREAN }
) { /* Multibyte Characters */
char *p, *q; for (i = 0; i < NUM_CAT_ITEMS; i++) {
int n = 0; if (sort_l[i].Pcat[0]) {
gtk_list_store_append (catListStore, &iter);
p = (char *)src; gtk_list_store_set (catListStore, &iter, 0, sort_l[i].Pcat, 1, sort_
q = dst; l[i].cat_num, -1);
while ((*p) && (n < (len -2))) { }
if ((*p) & 0x80) { }
*q++ = *p++;
n++; if (add_edit_cat_item) {
if (*p) { gtk_list_store_append (catListStore, &iter);
*q++ = *p++; gtk_list_store_set (catListStore, &iter, 0, _("Edit Categories..."), 1,
n++; CATEGORY_EDIT, -1);
}
*category_menu = gtk_combo_box_new_with_model (GTK_TREE_MODEL (catListStore)
);
GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (*category_menu), renderer, TRUE
);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (*category_menu), renderer,
"text", 0,
NULL);
if (selection_callback) {
g_signal_connect(G_OBJECT(*category_menu),"changed",G_CALLBACK(selection
_callback),
GINT_TO_POINTER(add_an_all_item));
}
return EXIT_SUCCESS;
}
int findSortedPostion(int sorted_position,GtkComboBox * box) {
GtkTreeModel * model = gtk_combo_box_get_model(GTK_COMBO_BOX(box));
GtkTreeIter iter;
gtk_tree_model_get_iter_first(model,&iter);
int pos;
gchar * label;
gtk_tree_model_get(model,&iter,0,&label,1,&pos,-1);
while(pos != sorted_position && gtk_tree_model_iter_next(model,&iter)){
gtk_tree_model_get(model,&iter,0,&label,1,&pos,-1);
}
return pos;
}
/** assuming the gtkcombobox box was made from make_category_menu
* If the box is not active or null, it will return -1;
*/
int get_selected_category_from_combo_box(GtkComboBox * box){
if(box == NULL || gtk_combo_box_get_active(GTK_COMBO_BOX(box)) < 0){
return -1;
}
GtkTreeIter activeIter;
gtk_combo_box_get_active_iter(GTK_COMBO_BOX(box),&activeIter);
GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(box));
int selectedItem = -1;
gtk_tree_model_get(model,&activeIter,1,&selectedItem,-1);
return selectedItem;
}
time_t mktime_dst_adj(struct tm *tm) {
struct tm t;
memcpy(&t, tm, sizeof(t));
t.tm_isdst = -1;
return mktime(&t);
}
char *multibyte_safe_memccpy(char *dst, const char *src, int c, size_t len) {
long char_set;
if (len == 0) return NULL;
if (dst == NULL) return NULL;
if (src == NULL) return NULL;
get_pref(PREF_CHAR_SET, &char_set, NULL);
if (char_set == CHAR_SET_JAPANESE ||
char_set == CHAR_SET_TRADITIONAL_CHINESE ||
char_set == CHAR_SET_KOREAN
) { /* Multibyte Characters */
char *p, *q;
int n = 0;
p = (char *) src;
q = dst;
while ((*p) && (n < (len - 2))) {
if ((*p) & 0x80) {
*q++ = *p++;
n++;
if (*p) {
*q++ = *p++;
n++;
}
} else {
*q++ = *p++;
n++;
} }
} else { if (*(p - 1) == (char) (c & 0xff))
return q;
}
if (!(*p & 0x80) && (n < len - 1))
*q++ = *p++; *q++ = *p++;
n++;
}
if (*(p-1) == (char)(c & 0xff))
return q;
}
if (!(*p & 0x80) && (n < len-1))
*q++ = *p++;
*q = '\0';
return NULL;
} else
return memccpy(dst, src, c, len);
}
void multibyte_safe_strncpy(char *dst, char *src, size_t len)
{
long char_set;
get_pref(PREF_CHAR_SET, &char_set, NULL);
if (char_set == CHAR_SET_JAPANESE || *q = '\0';
char_set == CHAR_SET_TRADITIONAL_CHINESE || return NULL;
char_set == CHAR_SET_KOREAN } else
) { return memccpy(dst, src, c, len);
char *p, *q; }
int n = 0;
p = src; q = dst; void multibyte_safe_strncpy(char *dst, char *src, size_t len) {
while ((*p) && n < (len-2)) { long char_set;
if ((*p) & 0x80) {
*q++ = *p++; get_pref(PREF_CHAR_SET, &char_set, NULL);
n++;
if (*p) { if (char_set == CHAR_SET_JAPANESE ||
*q++ = *p++; char_set == CHAR_SET_TRADITIONAL_CHINESE ||
n++; char_set == CHAR_SET_KOREAN
) {
char *p, *q;
int n = 0;
p = src;
q = dst;
while ((*p) && n < (len - 2)) {
if ((*p) & 0x80) {
*q++ = *p++;
n++;
if (*p) {
*q++ = *p++;
n++;
}
} else {
*q++ = *p++;
n++;
} }
} else { }
if (!(*p & 0x80) && (n < len - 1))
*q++ = *p++; *q++ = *p++;
n++;
}
}
if (!(*p & 0x80 ) && (n < len-1))
*q++ = *p++;
*q = '\0';
} else {
strncpy(dst, src, len);
}
}
int pdb_file_count_recs(char *DB_name, int *num)
{
char local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX];
struct pi_file *pf;
jp_logf(JP_LOG_DEBUG, "pdb_file_count_recs\n");
*num = 0;
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pdb
_file));
pf = pi_file_open(full_local_pdb_file);
if (!pf) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file);
return EXIT_FAILURE;
}
pi_file_get_entries(pf, num);
pi_file_close(pf);
return EXIT_SUCCESS;
}
int pdb_file_delete_record_by_id(char *DB_name, pi_uid_t uid_in)
{
char local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX];
char full_local_pdb_file2[FILENAME_MAX];
struct pi_file *pf1, *pf2;
struct DBInfo infop;
void *app_info;
void *sort_info;
void *record;
int r;
int idx;
size_t size;
int attr;
int cat;
pi_uid_t uid;
jp_logf(JP_LOG_DEBUG, "pdb_file_delete_record_by_id\n");
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pdb
_file));
strcpy(full_local_pdb_file2, full_local_pdb_file);
strcat(full_local_pdb_file2, "2");
pf1 = pi_file_open(full_local_pdb_file);
if (!pf1) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file);
return EXIT_FAILURE;
}
pi_file_get_info(pf1, &infop);
pf2 = pi_file_create(full_local_pdb_file2, &infop);
if (!pf2) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file2)
;
return EXIT_FAILURE;
}
pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, app_info, size);
pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size);
for(idx=0;;idx++) { *q = '\0';
r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid); } else {
if (r<0) break; strncpy(dst, src, len);
if (uid==uid_in) continue; }
pi_file_append_record(pf2, record, size, attr, cat, uid); }
}
int pdb_file_count_recs(char *DB_name, int *num) {
pi_file_close(pf1); char local_pdb_file[FILENAME_MAX];
pi_file_close(pf2); char full_local_pdb_file[FILENAME_MAX];
struct pi_file *pf;
jp_logf(JP_LOG_DEBUG, "pdb_file_count_recs\n");
*num = 0;
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pd
b_file));
pf = pi_file_open(full_local_pdb_file);
if (!pf) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
);
return EXIT_FAILURE;
}
pi_file_get_entries(pf, num);
pi_file_close(pf);
return EXIT_SUCCESS;
}
int pdb_file_delete_record_by_id(char *DB_name, pi_uid_t uid_in) {
char local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX];
char full_local_pdb_file2[FILENAME_MAX];
struct pi_file *pf1, *pf2;
struct DBInfo infop;
void *app_info;
void *sort_info;
void *record;
int r;
int idx;
size_t size;
int attr;
int cat;
pi_uid_t uid;
jp_logf(JP_LOG_DEBUG, "pdb_file_delete_record_by_id\n");
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pd
b_file));
strcpy(full_local_pdb_file2, full_local_pdb_file);
strcat(full_local_pdb_file2, "2");
pf1 = pi_file_open(full_local_pdb_file);
if (!pf1) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
);
return EXIT_FAILURE;
}
pi_file_get_info(pf1, &infop);
pf2 = pi_file_create(full_local_pdb_file2, &infop);
if (!pf2) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
2);
return EXIT_FAILURE;
}
pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, app_info, size);
pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size);
for (idx = 0;; idx++) {
r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid);
if (r < 0) break;
if (uid == uid_in) continue;
pi_file_append_record(pf2, record, size, attr, cat, uid);
}
pi_file_close(pf1);
pi_file_close(pf2);
if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) {
jp_logf(JP_LOG_WARN, "pdb_file_delete_record_by_id(): %s\n", _("rename f
ailed"));
}
if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) { return EXIT_SUCCESS;
jp_logf(JP_LOG_WARN, "pdb_file_delete_record_by_id(): %s\n", _("rename fai
led"));
}
return EXIT_SUCCESS;
} }
/* /*
* Original ID is in the case of a modification * Original ID is in the case of a modification
* new ID is used in the case of an add record * new ID is used in the case of an add record
*/ */
int pdb_file_modify_record(char *DB_name, void *record_in, int size_in, int pdb_file_modify_record(char *DB_name, void *record_in, int size_in,
int attr_in, int cat_in, pi_uid_t uid_in) int attr_in, int cat_in, pi_uid_t uid_in) {
{ char local_pdb_file[FILENAME_MAX];
char local_pdb_file[FILENAME_MAX]; char full_local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX]; char full_local_pdb_file2[FILENAME_MAX];
char full_local_pdb_file2[FILENAME_MAX]; struct pi_file *pf1, *pf2;
struct pi_file *pf1, *pf2; struct DBInfo infop;
struct DBInfo infop; void *app_info;
void *app_info; void *sort_info;
void *sort_info; void *record;
void *record; int r;
int r; int idx;
int idx; size_t size;
size_t size; int attr;
int attr; int cat;
int cat; int found;
int found; pi_uid_t uid;
pi_uid_t uid;
jp_logf(JP_LOG_DEBUG, "pdb_file_modify_record\n");
jp_logf(JP_LOG_DEBUG, "pdb_file_modify_record\n");
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name); get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pd
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pdb b_file));
_file)); strcpy(full_local_pdb_file2, full_local_pdb_file);
strcpy(full_local_pdb_file2, full_local_pdb_file); strcat(full_local_pdb_file2, "2");
strcat(full_local_pdb_file2, "2");
pf1 = pi_file_open(full_local_pdb_file);
pf1 = pi_file_open(full_local_pdb_file); if (!pf1) {
if (!pf1) { jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file); );
return EXIT_FAILURE; return EXIT_FAILURE;
} }
pi_file_get_info(pf1, &infop); pi_file_get_info(pf1, &infop);
pf2 = pi_file_create(full_local_pdb_file2, &infop); pf2 = pi_file_create(full_local_pdb_file2, &infop);
if (!pf2) { if (!pf2) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file2) jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
; 2);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
pi_file_get_app_info(pf1, &app_info, &size); pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, app_info, size); pi_file_set_app_info(pf2, app_info, size);
pi_file_get_sort_info(pf1, &sort_info, &size); pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size); pi_file_set_sort_info(pf2, sort_info, size);
found = 0; found = 0;
for(idx=0;;idx++) { for (idx = 0;; idx++) {
r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid); r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid);
if (r<0) break; if (r < 0) break;
if (uid==uid_in) { if (uid == uid_in) {
pi_file_append_record(pf2, record_in, size_in, attr_in, cat_in, uid_in) pi_file_append_record(pf2, record_in, size_in, attr_in, cat_in, uid_
; in);
found=1; found = 1;
} else { } else {
pi_file_append_record(pf2, record, size, attr, cat, uid); pi_file_append_record(pf2, record, size, attr, cat, uid);
} }
} }
if (!found) { if (!found) {
pi_file_append_record(pf2, record_in, size_in, attr_in, cat_in, uid_in); pi_file_append_record(pf2, record_in, size_in, attr_in, cat_in, uid_in);
} }
pi_file_close(pf1); pi_file_close(pf1);
pi_file_close(pf2); pi_file_close(pf2);
if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) { if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) {
jp_logf(JP_LOG_WARN, "pdb_file_modify_record(): %s\n", _("rename failed")) jp_logf(JP_LOG_WARN, "pdb_file_modify_record(): %s\n", _("rename failed"
; ));
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
int pdb_file_read_record_by_id(char *DB_name, int pdb_file_read_record_by_id(char *DB_name,
pi_uid_t uid, pi_uid_t uid,
void **bufp, size_t *sizep, int *idxp, void **bufp, size_t *sizep, int *idxp,
int *attrp, int *catp) int *attrp, int *catp) {
{ char local_pdb_file[FILENAME_MAX];
char local_pdb_file[FILENAME_MAX]; char full_local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX]; struct pi_file *pf1;
struct pi_file *pf1; void *temp_buf;
void *temp_buf; int r;
int r;
jp_logf(JP_LOG_DEBUG, "pdb_file_read_record_by_id\n");
jp_logf(JP_LOG_DEBUG, "pdb_file_read_record_by_id\n");
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name); get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pd
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pdb b_file));
_file));
pf1 = pi_file_open(full_local_pdb_file);
pf1 = pi_file_open(full_local_pdb_file); if (!pf1) {
if (!pf1) { jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file); );
return EXIT_FAILURE; return EXIT_FAILURE;
} }
r = pi_file_read_record_by_id(pf1, uid, &temp_buf, sizep, idxp, attrp, catp); r = pi_file_read_record_by_id(pf1, uid, &temp_buf, sizep, idxp, attrp, catp)
/* during the close bufp will be freed, so we copy it */ ;
if ( (r>=0) && (*sizep>0) ) { /* during the close bufp will be freed, so we copy it */
*bufp=malloc(*sizep); if ((r >= 0) && (*sizep > 0)) {
if (*bufp) { *bufp = malloc(*sizep);
memcpy(*bufp, temp_buf, *sizep); if (*bufp) {
} memcpy(*bufp, temp_buf, *sizep);
} else { }
*bufp=NULL; } else {
} *bufp = NULL;
}
pi_file_close(pf1);
pi_file_close(pf1);
return r;
} return r;
}
int pdb_file_write_app_block(char *DB_name, void *bufp, size_t size_in)
{ int pdb_file_write_app_block(char *DB_name, void *bufp, size_t size_in) {
char local_pdb_file[FILENAME_MAX]; char local_pdb_file[FILENAME_MAX];
char full_local_pdb_file[FILENAME_MAX]; char full_local_pdb_file[FILENAME_MAX];
char full_local_pdb_file2[FILENAME_MAX]; char full_local_pdb_file2[FILENAME_MAX];
struct pi_file *pf1, *pf2; struct pi_file *pf1, *pf2;
struct DBInfo infop; struct DBInfo infop;
void *app_info; void *app_info;
void *sort_info; void *sort_info;
void *record; void *record;
int r; int r;
int idx; int idx;
size_t size; size_t size;
int attr; int attr;
int cat; int cat;
pi_uid_t uid; pi_uid_t uid;
struct stat statb; struct stat statb;
struct utimbuf times; struct utimbuf times;
jp_logf(JP_LOG_DEBUG, "pdb_file_write_app_block\n"); jp_logf(JP_LOG_DEBUG, "pdb_file_write_app_block\n");
g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name); g_snprintf(local_pdb_file, sizeof(local_pdb_file), "%s.pdb", DB_name);
get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pdb get_home_file_name(local_pdb_file, full_local_pdb_file, sizeof(full_local_pd
_file)); b_file));
strcpy(full_local_pdb_file2, full_local_pdb_file); strcpy(full_local_pdb_file2, full_local_pdb_file);
strcat(full_local_pdb_file2, "2"); strcat(full_local_pdb_file2, "2");
/* After we are finished, set the create and modify times of new file /* After we are finished, set the create and modify times of new file
to the same as the old */ to the same as the old */
stat(full_local_pdb_file, &statb); stat(full_local_pdb_file, &statb);
times.actime = statb.st_atime; times.actime = statb.st_atime;
times.modtime = statb.st_mtime; times.modtime = statb.st_mtime;
pf1 = pi_file_open(full_local_pdb_file); pf1 = pi_file_open(full_local_pdb_file);
if (!pf1) { if (!pf1) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file); jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
return EXIT_FAILURE; );
} return EXIT_FAILURE;
pi_file_get_info(pf1, &infop); }
pf2 = pi_file_create(full_local_pdb_file2, &infop); pi_file_get_info(pf1, &infop);
if (!pf2) { pf2 = pi_file_create(full_local_pdb_file2, &infop);
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file2) if (!pf2) {
; jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
return EXIT_FAILURE; 2);
} return EXIT_FAILURE;
}
pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, bufp, size_in); pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, bufp, size_in);
pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size); pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size);
for(idx=0;;idx++) {
r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid); for (idx = 0;; idx++) {
if (r<0) break; r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid);
pi_file_append_record(pf2, record, size, attr, cat, uid); if (r < 0) break;
} pi_file_append_record(pf2, record, size, attr, cat, uid);
}
pi_file_close(pf1);
pi_file_close(pf2); pi_file_close(pf1);
pi_file_close(pf2);
if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) {
jp_logf(JP_LOG_WARN, "pdb_file_write_app_block(): %s\n", _("rename faile
d"));
}
if (rename(full_local_pdb_file2, full_local_pdb_file) < 0) { utime(full_local_pdb_file, &times);
jp_logf(JP_LOG_WARN, "pdb_file_write_app_block(): %s\n", _("rename failed"
));
}
utime(full_local_pdb_file, &times); return EXIT_SUCCESS;
return EXIT_SUCCESS;
} }
/* DB_name is filename with extention and path, i.e: "/tmp/Net Prefs.prc" */ /* DB_name is filename with extention and path, i.e: "/tmp/Net Prefs.prc" */
int pdb_file_write_dbinfo(char *full_DB_name, struct DBInfo *Pinfo_in) int pdb_file_write_dbinfo(char *full_DB_name, struct DBInfo *Pinfo_in) {
{ char full_local_pdb_file2[FILENAME_MAX];
char full_local_pdb_file2[FILENAME_MAX]; struct pi_file *pf1, *pf2;
struct pi_file *pf1, *pf2; struct DBInfo infop;
struct DBInfo infop; void *app_info;
void *app_info; void *sort_info;
void *sort_info; void *record;
void *record; int r;
int r; int idx;
int idx; size_t size;
size_t size; int attr;
int attr; int cat;
int cat; pi_uid_t uid;
pi_uid_t uid; struct stat statb;
struct stat statb; struct utimbuf times;
struct utimbuf times;
jp_logf(JP_LOG_DEBUG, "pdb_file_write_dbinfo\n"); jp_logf(JP_LOG_DEBUG, "pdb_file_write_dbinfo\n");
g_snprintf(full_local_pdb_file2, sizeof(full_local_pdb_file2), "%s2", full_DB _name); g_snprintf(full_local_pdb_file2, sizeof(full_local_pdb_file2), "%s2", full_D B_name);
/* After we are finished, set the create and modify times of new file /* After we are finished, set the create and modify times of new file
to the same as the old */ to the same as the old */
stat(full_DB_name, &statb); stat(full_DB_name, &statb);
times.actime = statb.st_atime; times.actime = statb.st_atime;
times.modtime = statb.st_mtime; times.modtime = statb.st_mtime;
pf1 = pi_file_open(full_DB_name); pf1 = pi_file_open(full_DB_name);
if (!pf1) { if (!pf1) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_DB_name); jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_DB_name);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
pi_file_get_info(pf1, &infop); pi_file_get_info(pf1, &infop);
/* Set the DBInfo to the one coming into the function */ /* Set the DBInfo to the one coming into the function */
pf2 = pi_file_create(full_local_pdb_file2, Pinfo_in); pf2 = pi_file_create(full_local_pdb_file2, Pinfo_in);
if (!pf2) { if (!pf2) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file2) jp_logf(JP_LOG_WARN, _("Unable to open file: %s\n"), full_local_pdb_file
; 2);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
pi_file_get_app_info(pf1, &app_info, &size); pi_file_get_app_info(pf1, &app_info, &size);
pi_file_set_app_info(pf2, app_info, size); pi_file_set_app_info(pf2, app_info, size);
pi_file_get_sort_info(pf1, &sort_info, &size); pi_file_get_sort_info(pf1, &sort_info, &size);
pi_file_set_sort_info(pf2, sort_info, size); pi_file_set_sort_info(pf2, sort_info, size);
for(idx=0;;idx++) { for (idx = 0;; idx++) {
r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid); r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid);
if (r<0) break; if (r < 0) break;
pi_file_append_record(pf2, record, size, attr, cat, uid); pi_file_append_record(pf2, record, size, attr, cat, uid);
} }
pi_file_close(pf1); pi_file_close(pf1);
pi_file_close(pf2); pi_file_close(pf2);
if (rename(full_local_pdb_file2, full_DB_name) < 0) { if (rename(full_local_pdb_file2, full_DB_name) < 0) {
jp_logf(JP_LOG_WARN, "pdb_file_write_dbinfo(): %s\n", _("rename failed")); jp_logf(JP_LOG_WARN, "pdb_file_write_dbinfo(): %s\n", _("rename failed")
} );
}
utime(full_DB_name, &times);
utime(full_DB_name, &times);
return EXIT_SUCCESS;
} return EXIT_SUCCESS;
}
void print_string(char *str, int len) gboolean
{ motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
unsigned char c; GtkTreePath * path = NULL;
int i; GtkTreeIter iter;
GtkTreeModel * model;
for (i=0;i<len;i++) { if(GTK_IS_TREE_VIEW(widget) && glob_mouse_pressed) {
c=str[i]; gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), event->x, event->y,
if (c < ' ' || c >= 0x7f) &path, NULL, NULL, NULL);
jp_logf(JP_LOG_STDOUT, "%x", c); if (path != NULL) {
else GtkTreeSelection *selection = NULL;
jp_logf(JP_LOG_STDOUT, "%c", c); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
} gtk_tree_selection_select_path(selection, path);
jp_logf(JP_LOG_STDOUT, "\n"); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(widget),path,0, FALSE, 1.
} 0, 0.0);
}
int read_gtkrc_file(void) // keep scrolling up/selecting after the mouse pointer is above the tre
{ eview.
char filename[FILENAME_MAX]; if(path == NULL && (gint) event->y < 0){
char fullname[FILENAME_MAX]; GtkTreeSelection *selection = NULL;
struct stat buf; model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
const char *svalue; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
gtk_tree_selection_get_selected(selection,&model,&iter);
get_pref(PREF_RCFILE, NULL, &svalue); path = gtk_tree_model_get_path(model,&iter);
if (svalue) { if(gtk_tree_path_prev(path)){
jp_logf(JP_LOG_DEBUG, "rc file from prefs is %s\n", svalue); gtk_tree_selection_select_path(selection, path);
} else { gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(widget),path,0, FALSE
jp_logf(JP_LOG_DEBUG, "rc file from prefs is NULL\n"); , 1.0, 0.0);
} }
}
gtk_tree_path_free(path);
}
return TRUE;
}
void print_string(char *str, int len) {
unsigned char c;
int i;
for (i = 0; i < len; i++) {
c = str[i];
if (c < ' ' || c >= 0x7f)
jp_logf(JP_LOG_STDOUT, "%x", c);
else
jp_logf(JP_LOG_STDOUT, "%c", c);
}
jp_logf(JP_LOG_STDOUT, "\n");
}
int read_gtkrc_file(void) {
char filename[FILENAME_MAX];
char fullname[FILENAME_MAX];
struct stat buf;
const char *svalue;
GtkCssProvider *provider;
//GtkCssProvider *providerold;
provider = gtk_css_provider_new ();
//providerold = gtk_css_provider_new ();
get_pref(PREF_RCFILE, NULL, &svalue);
if (svalue) {
jp_logf(JP_LOG_DEBUG, "rc file from prefs is %s\n", svalue);
} else {
jp_logf(JP_LOG_DEBUG, "rc file from prefs is NULL\n");
}
g_strlcpy(filename, svalue, sizeof(filename));
/* Try to read the file out of the home directory first */
get_home_file_name(filename, fullname, sizeof(fullname));
if (stat(fullname, &buf) == 0) {
jp_logf(JP_LOG_DEBUG, "parsing %s\n", fullname);
/* char loadedFullName[MAX_PREF_LEN];
for (int i = 0; i < MAX_NUM_PREFS; i++) {
get_rcfile_name(i, loadedFullName);
if(loadedFullName != NULL && strncmp(loadedFullName, "jpilotcss", st
rlen("jpilotcss")) == 0) {
gtk_css_provider_load_from_path(GTK_CSS_PROVIDER (providerold),
loadedFullName, NULL);
gtk_style_context_remove_provider_for_screen(gdk_screen_get_defa
ult(), GTK_STYLE_PROVIDER(providerold));
}
}
g_strlcpy(filename, svalue, sizeof(filename)); GtkSettings *settings;
gchar *theme_name;
/* Try to read the file out of the home directory first */ settings = gtk_settings_get_default();
get_home_file_name(filename, fullname, sizeof(fullname)); g_object_get(settings, "gtk-theme-name", &theme_name, NULL);
if (stat(fullname, &buf)==0) { gtk_style_context_remove_provider_for_screen(gdk_screen_get_default(), G
jp_logf(JP_LOG_DEBUG, "parsing %s\n", fullname); TK_STYLE_PROVIDER(gtk_css_provider_get_named(theme_name,NULL)));
gtk_rc_parse(fullname); gtk_style_context_remove_provider_for_screen(gdk_screen_get_default(), G
return EXIT_SUCCESS; TK_STYLE_PROVIDER(gtk_css_provider_new()));
} gtk_css_provider_load_from_path(GTK_CSS_PROVIDER (provider),
fullname, NULL);
g_snprintf(fullname, sizeof(fullname), "%s/%s/%s/%s", BASE_DIR, "share", EPN, gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_
filename); STYLE_PROVIDER(gtk_css_provider_new()),GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
if (stat(fullname, &buf)==0) { gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
jp_logf(JP_LOG_DEBUG, "parsing %s\n", fullname); GTK_STYLE_PROVIDER (gtk_css_pr
gtk_rc_parse(fullname); ovider_get_named(theme_name,NULL)),
return EXIT_SUCCESS; GTK_STYLE_PROVIDER_PRIORITY_AP
} PLICATION);*/
return EXIT_FAILURE; gtk_css_provider_load_from_path(GTK_CSS_PROVIDER (provider),
fullname, NULL);
gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_AP
PLICATION);
g_object_unref (provider);
//g_object_unref (providerold);
return EXIT_SUCCESS;
}
g_snprintf(fullname, sizeof(fullname), "%s/%s/%s/%s", BASE_DIR, "share", EPN
, filename);
if (stat(fullname, &buf) == 0) {
jp_logf(JP_LOG_DEBUG, "parsing %s\n", fullname);
gtk_css_provider_load_from_path(GTK_CSS_PROVIDER (provider),
fullname, NULL);
gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_AP
PLICATION);
g_object_unref (provider);
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
} }
/* Parse the string and replace CR and LFs with spaces */ /* Parse the string and replace CR and LFs with spaces */
void remove_cr_lfs(char *str) void remove_cr_lfs(char *str) {
{ int i;
int i;
if (!str) { if (!str) {
return; return;
} }
for (i=0; str[i]; i++) { for (i = 0; str[i]; i++) {
if ((str[i]=='\r') || (str[i]=='\n')) { if ((str[i] == '\r') || (str[i] == '\n')) {
str[i]=' '; str[i] = ' ';
} }
} }
} }
int get_rcfile_name(int n, char *rc_copy)
{
DIR *dir;
struct dirent *dirent;
char full_name[FILENAME_MAX];
int i;
char filename[FILENAME_MAX];
int found, count;
struct name_list *temp_list, *new_entry;
if (dir_list == NULL) {
i = found = count = 0;
sprintf(filename, "%s/%s/%s/", BASE_DIR, "share", EPN);
jp_logf(JP_LOG_DEBUG, "opening dir %s\n", filename);
dir = opendir(filename);
if (dir) {
for(i=0; (dirent = readdir(dir)); i++) {
sprintf(filename, "%s%s", EPN, "css");
if (strncmp(filename, dirent->d_name, strlen(filename))) {
continue;
} else {
jp_logf(JP_LOG_DEBUG, "found %s\n", dirent->d_name);
new_entry = malloc(sizeof(struct name_list));
if (!new_entry) {
jp_logf(JP_LOG_FATAL, "get_rcfile_name(): %s\n", _("Out
of memory"));
return EXIT_FAILURE;
}
new_entry->name = strdup(dirent->d_name);
new_entry->next = dir_list;
dir_list = new_entry;
}
}
}
if (dir) {
closedir(dir);
}
get_home_file_name("", full_name, sizeof(full_name));
jp_logf(JP_LOG_DEBUG, "opening dir %s\n", full_name);
dir = opendir(full_name);
if (dir) {
for(; (dirent = readdir(dir)); i++) {
sprintf(filename, "%s%s", EPN, "rc");
if (strncmp(filename, dirent->d_name, strlen(filename))) {
continue;
} else {
jp_logf(JP_LOG_DEBUG, "found %s\n", dirent->d_name);
new_entry = malloc(sizeof(struct name_list));
if (!new_entry) {
jp_logf(JP_LOG_FATAL, "get_rcfile_name(): %s 2\n", _("Ou
t of memory"));
return EXIT_FAILURE;
}
new_entry->name = strdup(dirent->d_name);
new_entry->next = dir_list;
dir_list = new_entry;
}
}
}
if (dir) {
closedir(dir);
}
}
found = 0;
for (i=0, temp_list=dir_list; temp_list; temp_list=temp_list->next, i++) {
if (i == n) {
g_strlcpy(rc_copy, temp_list->name, MAX_PREF_LEN);
found=1;
break;
}
}
void rename_dbnames(char dbname[][32]) if (found) {
{ return EXIT_SUCCESS;
int i; } else {
long datebook_version, address_version, todo_version, memo_version; rc_copy[0]='\0';
return EXIT_FAILURE;
}
}
void rename_dbnames(char dbname[][32]) {
int i;
long datebook_version, address_version, todo_version, memo_version;
get_pref(PREF_DATEBOOK_VERSION, &datebook_version, NULL);
get_pref(PREF_ADDRESS_VERSION, &address_version, NULL);
get_pref(PREF_TODO_VERSION, &todo_version, NULL);
get_pref(PREF_MEMO_VERSION, &memo_version, NULL);
for (i = 0; dbname[i] && dbname[i][0]; i++) {
if (datebook_version == 1) {
if (!strcmp(dbname[i], "DatebookDB.pdb")) {
strcpy(dbname[i], "CalendarDB-PDat.pdb");
}
if (!strcmp(dbname[i], "DatebookDB.pc3")) {
strcpy(dbname[i], "CalendarDB-PDat.pc3");
}
if (!strcmp(dbname[i], "DatebookDB")) {
strcpy(dbname[i], "CalendarDB-PDat");
}
}
get_pref(PREF_DATEBOOK_VERSION, &datebook_version, NULL); if (address_version == 1) {
get_pref(PREF_ADDRESS_VERSION, &address_version, NULL); if (!strcmp(dbname[i], "AddressDB.pdb")) {
get_pref(PREF_TODO_VERSION, &todo_version, NULL); strcpy(dbname[i], "ContactsDB-PAdd.pdb");
get_pref(PREF_MEMO_VERSION, &memo_version, NULL); }
for (i=0; dbname[i] && dbname[i][0]; i++) { if (!strcmp(dbname[i], "AddressDB.pc3")) {
if (datebook_version==1) { strcpy(dbname[i], "ContactsDB-PAdd.pc3");
if (!strcmp(dbname[i], "DatebookDB.pdb")) { }
strcpy(dbname[i], "CalendarDB-PDat.pdb"); if (!strcmp(dbname[i], "AddressDB")) {
} strcpy(dbname[i], "ContactsDB-PAdd");
if (!strcmp(dbname[i], "DatebookDB.pc3")) { }
strcpy(dbname[i], "CalendarDB-PDat.pc3"); }
}
if (!strcmp(dbname[i], "DatebookDB")) {
strcpy(dbname[i], "CalendarDB-PDat");
}
}
if (address_version==1) {
if (!strcmp(dbname[i], "AddressDB.pdb")) {
strcpy(dbname[i], "ContactsDB-PAdd.pdb");
}
if (!strcmp(dbname[i], "AddressDB.pc3")) {
strcpy(dbname[i], "ContactsDB-PAdd.pc3");
}
if (!strcmp(dbname[i], "AddressDB")) {
strcpy(dbname[i], "ContactsDB-PAdd");
}
}
if (todo_version==1) {
if (!strcmp(dbname[i], "ToDoDB.pdb")) {
strcpy(dbname[i], "TasksDB-PTod.pdb");
}
if (!strcmp(dbname[i], "ToDoDB.pc3")) {
strcpy(dbname[i], "TasksDB-PTod.pc3");
}
if (!strcmp(dbname[i], "ToDoDB")) {
strcpy(dbname[i], "TasksDB-PTod");
}
}
if (memo_version==1) {
if (!strcmp(dbname[i], "MemoDB.pdb")) {
strcpy(dbname[i], "MemosDB-PMem.pdb");
}
if (!strcmp(dbname[i], "MemoDB.pc3")) {
strcpy(dbname[i], "MemosDB-PMem.pc3");
}
if (!strcmp(dbname[i], "MemoDB")) {
strcpy(dbname[i], "MemosDB-PMem");
}
}
if (memo_version==2) {
if (!strcmp(dbname[i], "MemoDB.pdb")) {
strcpy(dbname[i], "Memo32DB.pdb");
}
if (!strcmp(dbname[i], "MemoDB.pc3")) {
strcpy(dbname[i], "Memo32DB.pc3");
}
if (!strcmp(dbname[i], "MemoDB")) {
strcpy(dbname[i], "Memo32DB");
}
}
}
}
int rename_file(char *old_filename, char *new_filename) if (todo_version == 1) {
{ if (!strcmp(dbname[i], "ToDoDB.pdb")) {
char old_fullname[FILENAME_MAX]; strcpy(dbname[i], "TasksDB-PTod.pdb");
char new_fullname[FILENAME_MAX]; }
if (!strcmp(dbname[i], "ToDoDB.pc3")) {
strcpy(dbname[i], "TasksDB-PTod.pc3");
}
if (!strcmp(dbname[i], "ToDoDB")) {
strcpy(dbname[i], "TasksDB-PTod");
}
}
get_home_file_name(old_filename, old_fullname, sizeof(old_fullname)); if (memo_version == 1) {
get_home_file_name(new_filename, new_fullname, sizeof(new_fullname)); if (!strcmp(dbname[i], "MemoDB.pdb")) {
strcpy(dbname[i], "MemosDB-PMem.pdb");
}
if (!strcmp(dbname[i], "MemoDB.pc3")) {
strcpy(dbname[i], "MemosDB-PMem.pc3");
}
if (!strcmp(dbname[i], "MemoDB")) {
strcpy(dbname[i], "MemosDB-PMem");
}
}
return rename(old_fullname, new_fullname); if (memo_version == 2) {
if (!strcmp(dbname[i], "MemoDB.pdb")) {
strcpy(dbname[i], "Memo32DB.pdb");
}
if (!strcmp(dbname[i], "MemoDB.pc3")) {
strcpy(dbname[i], "Memo32DB.pc3");
}
if (!strcmp(dbname[i], "MemoDB")) {
strcpy(dbname[i], "Memo32DB");
}
}
}
} }
void set_bg_rgb_clist_row(GtkWidget *clist, int row, int r, int g, int b) int rename_file(char *old_filename, char *new_filename) {
{ char old_fullname[FILENAME_MAX];
GtkStyle *old_style, *new_style; char new_fullname[FILENAME_MAX];
GdkColor color;
if ((old_style = gtk_widget_get_style(clist))) {
new_style = gtk_style_copy(old_style);
}
else {
new_style = gtk_style_new();
}
color.red=r; get_home_file_name(old_filename, old_fullname, sizeof(old_fullname));
color.green=g; get_home_file_name(new_filename, new_fullname, sizeof(new_fullname));
color.blue=b;
color.pixel=0;
new_style->base[GTK_STATE_NORMAL] = color; return rename(old_fullname, new_fullname);
gtk_clist_set_row_style(GTK_CLIST(clist), row, new_style);
} }
GdkRGBA get_color(int r, int g, int b) {
void set_fg_rgb_clist_cell(GtkWidget *clist, int row, int col, int r, int g, int GdkRGBA color;
b) char rgb[50];
{ sprintf(rgb, "#%02X%02X%02X", r,g,b);
GtkStyle *old_style, *new_style; gdk_rgba_parse(&color,rgb);
GdkColor fg_color; return color;
if ((old_style = gtk_clist_get_row_style(GTK_CLIST(clist), row)) ||
(old_style = gtk_widget_get_style(clist))) {
new_style = gtk_style_copy(old_style);
}
else {
new_style = gtk_style_new();
}
fg_color.red=r;
fg_color.green=g;
fg_color.blue=b;
fg_color.pixel=0;
new_style->fg[GTK_STATE_NORMAL] = fg_color;
new_style->fg[GTK_STATE_SELECTED] = fg_color;
gtk_clist_set_cell_style(GTK_CLIST(clist), row, col, new_style);
} }
int setup_sync(unsigned int flags) int setup_sync(unsigned int flags) {
{ long num_backups;
long num_backups; const char *svalue;
const char *svalue; const char *port;
const char *port; int r;
int r;
#ifndef HAVE_SETENV #ifndef HAVE_SETENV
char str[80]; char str[80];
#endif #endif
struct my_sync_info sync_info; struct my_sync_info sync_info;
/* look in env for PILOTRATE first */ /* look in env for PILOTRATE first */
if (!(getenv("PILOTRATE"))) { if (!(getenv("PILOTRATE"))) {
get_pref(PREF_RATE, NULL, &svalue); get_pref(PREF_RATE, NULL, &svalue);
jp_logf(JP_LOG_DEBUG, "setting PILOTRATE=[%s]\n", svalue); jp_logf(JP_LOG_DEBUG, "setting PILOTRATE=[%s]\n", svalue);
if (svalue) { if (svalue) {
#ifdef HAVE_SETENV #ifdef HAVE_SETENV
setenv("PILOTRATE", svalue, TRUE); setenv("PILOTRATE", svalue, TRUE);
#else #else
sprintf(str, "PILOTRATE=%s", svalue); sprintf(str, "PILOTRATE=%s", svalue);
putenv(str); putenv(str);
#endif #endif
} }
} }
get_pref(PREF_PORT, NULL, &port); get_pref(PREF_PORT, NULL, &port);
get_pref(PREF_NUM_BACKUPS, &num_backups, NULL); get_pref(PREF_NUM_BACKUPS, &num_backups, NULL);
jp_logf(JP_LOG_DEBUG, "pref port=[%s]\n", port); jp_logf(JP_LOG_DEBUG, "pref port=[%s]\n", port);
jp_logf(JP_LOG_DEBUG, "num_backups=%d\n", num_backups); jp_logf(JP_LOG_DEBUG, "num_backups=%d\n", num_backups);
get_pref(PREF_USER, NULL, &svalue); get_pref(PREF_USER, NULL, &svalue);
g_strlcpy(sync_info.username, svalue, sizeof(sync_info.username)); g_strlcpy(sync_info.username, svalue, sizeof(sync_info.username));
get_pref(PREF_USER_ID, &(sync_info.userID), NULL); get_pref(PREF_USER_ID, &(sync_info.userID), NULL);
get_pref(PREF_PC_ID, &(sync_info.PC_ID), NULL); get_pref(PREF_PC_ID, &(sync_info.PC_ID), NULL);
if (sync_info.PC_ID == 0) { if (sync_info.PC_ID == 0) {
srandom(time(NULL)); srandom(time(NULL));
/* RAND_MAX is 32768 on Solaris machines for some reason. /* RAND_MAX is 32768 on Solaris machines for some reason.
* If someone knows how to fix this, let me know. */ * If someone knows how to fix this, let me know. */
if (RAND_MAX==32768) { if (RAND_MAX == 32768) {
sync_info.PC_ID = 1+(2000000000.0*random()/(2147483647+1.0)); sync_info.PC_ID = 1 + (2000000000.0 * random() / (2147483647 + 1.0))
} else { ;
sync_info.PC_ID = 1+(2000000000.0*random()/(RAND_MAX+1.0)); } else {
} sync_info.PC_ID = 1 + (2000000000.0 * random() / (RAND_MAX + 1.0));
jp_logf(JP_LOG_WARN, _("PC ID is 0.\n")); }
jp_logf(JP_LOG_WARN, _("Generated a new PC ID. It is %lu\n"), sync_info.P jp_logf(JP_LOG_WARN, _("PC ID is 0.\n"));
C_ID); jp_logf(JP_LOG_WARN, _("Generated a new PC ID. It is %lu\n"), sync_info
set_pref(PREF_PC_ID, sync_info.PC_ID, NULL, TRUE); .PC_ID);
} set_pref(PREF_PC_ID, sync_info.PC_ID, NULL, TRUE);
}
sync_info.sync_over_ride = 0;
g_strlcpy(sync_info.port, port, sizeof(sync_info.port)); sync_info.sync_over_ride = 0;
sync_info.flags=flags; g_strlcpy(sync_info.port, port, sizeof(sync_info.port));
sync_info.num_backups=num_backups; sync_info.flags = flags;
sync_info.num_backups = num_backups;
r = sync_once(&sync_info); r = sync_once(&sync_info);
return r; return r;
} }
/* /*
* Copy src string into dest while escaping quotes with double quotes. * Copy src string into dest while escaping quotes with double quotes.
* dest could be as long as strlen(src)*2. * dest could be as long as strlen(src)*2.
* Return value is the number of chars written to dest. * Return value is the number of chars written to dest.
*/ */
int str_to_csv_str(char *dest, char *src) int str_to_csv_str(char *dest, char *src) {
{ int s, d;
int s, d;
if (dest) dest[0]='\0';
if ((!src) || (!dest)) {
return EXIT_SUCCESS;
}
s=d=0; if (dest) dest[0] = '\0';
while (src[s]) { if ((!src) || (!dest)) {
if (src[s]=='\"') { return EXIT_SUCCESS;
dest[d++]='\"'; }
}
dest[d++]=src[s++]; s = d = 0;
} while (src[s]) {
dest[d++]='\0'; if (src[s] == '\"') {
dest[d++] = '\"';
}
dest[d++] = src[s++];
}
dest[d++] = '\0';
return d; return d;
} }
/* /*
* Copy src string into dest while escaping carriage returns with <br/> * Copy src string into dest while escaping carriage returns with <br/>
* dest could be as long as strlen(src)*5. * dest could be as long as strlen(src)*5.
* Return value is the number of chars written to dest. * Return value is the number of chars written to dest.
*/ */
int str_to_keepass_str(char *dest, char *src) int str_to_keepass_str(char *dest, char *src) {
{ int s, d;
int s, d;
if (dest) dest[0]='\0'; if (dest) dest[0] = '\0';
if ((!src) || (!dest)) { if ((!src) || (!dest)) {
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
s=d=0; s = d = 0;
while (src[s]) { while (src[s]) {
if (src[s]=='\n') { if (src[s] == '\n') {
dest[d++]='<'; dest[d++] = '<';
dest[d++]='b'; dest[d++] = 'b';
dest[d++]='r'; dest[d++] = 'r';
dest[d++]='/'; dest[d++] = '/';
dest[d++]='>'; dest[d++] = '>';
s++; s++;
continue; continue;
} }
if (src[s]=='&') { if (src[s] == '&') {
dest[d++]='&'; dest[d++] = '&';
dest[d++]='a'; dest[d++] = 'a';
dest[d++]='m'; dest[d++] = 'm';
dest[d++]='p'; dest[d++] = 'p';
dest[d++]=';'; dest[d++] = ';';
s++; s++;
continue; continue;
} }
if (src[s]=='<') { if (src[s] == '<') {
dest[d++]='&'; dest[d++] = '&';
dest[d++]='l'; dest[d++] = 'l';
dest[d++]='t'; dest[d++] = 't';
dest[d++]=';'; dest[d++] = ';';
s++; s++;
continue; continue;
} }
if (src[s]=='>') { if (src[s] == '>') {
dest[d++]='&'; dest[d++] = '&';
dest[d++]='g'; dest[d++] = 'g';
dest[d++]='t'; dest[d++] = 't';
dest[d++]=';'; dest[d++] = ';';
s++; s++;
continue; continue;
} }
dest[d++]=src[s++]; dest[d++] = src[s++];
} }
dest[d++]='\0'; dest[d++] = '\0';
return d; return d;
} }
/* /*
* Quote a TEXT format string as specified by RFC 2445. * Quote a TEXT format string as specified by RFC 2445.
* Wrap it at 60-ish characters. * Wrap it at 60-ish characters.
*/ */
int str_to_ical_str(char *dest, int destsz, char *src) int str_to_ical_str(char *dest, int destsz, char *src) {
{ return str_to_iv_str(dest, destsz, src, 1);
return str_to_iv_str(dest, destsz, src, 1);
} }
/* /*
* Quote for iCalendar (RFC 2445) or vCard (RFC 2426). * Quote for iCalendar (RFC 2445) or vCard (RFC 2426).
* The only difference is that iCalendar also quotes semicolons. * The only difference is that iCalendar also quotes semicolons.
* Wrap at 70-ish characters. * Wrap at 70-ish characters.
*/ */
static int str_to_iv_str(char *dest, int destsz, char *src, int isical) static int str_to_iv_str(char *dest, int destsz, char *src, int isical) {
{ int c, i;
int c, i; char *destend, *odest;
char *destend, *odest;
if ((!src) || (!dest)) {
if ((!src) || (!dest)) { return EXIT_SUCCESS;
return EXIT_SUCCESS; }
}
odest = dest;
destend = dest + destsz - 4; /* max 4 chars into dest per loop iteration */
c = 0;
while (*src) {
if (dest >= destend) {
break;
}
if (c > ICAL_LINE_LENGTH) {
/* Assume UTF-8 coding and stop on a valid character boundary */
for (i = 0; i < 4; i++) {
if ((*src & 0xC0) != 0x80) {
if (*src) {
*dest++ = CR;
*dest++ = LF;
*dest++ = ' ';
}
c = 0;
break;
}
*dest++ = *src++;
}
odest = dest; if (c != 0) {
destend = dest + destsz - 4; /* max 4 chars into dest per loop iteration */ jp_logf(JP_LOG_WARN, _("Invalid UTF-8 encoding in export string\
c=0; n"));
while (*src) { /* Force truncation of line anyways */
if (dest >= destend) { *dest++ = CR;
break; *dest++ = LF;
} *dest++ = ' ';
if (c>ICAL_LINE_LENGTH) { c = 0;
/* Assume UTF-8 coding and stop on a valid character boundary */ }
for (i=0; i<4; i++) { continue;
if ((*src & 0xC0) != 0x80) { }
if (*src) { if (*src == '\n') {
*dest++= CR; *dest++= LF; *dest++ = '\\';
*dest++=' '; *dest++ = 'n';
} c += 2;
c=0; src++;
break; continue;
} }
*dest++=*src++; if (*src == '\\' || (isical && *src == ';') || *src == ',') {
} *dest++ = '\\';
c++;
if (c != 0) { }
jp_logf(JP_LOG_WARN,_("Invalid UTF-8 encoding in export string\n")); *dest++ = *src++;
/* Force truncation of line anyways */ c++;
*dest++= CR; *dest++= LF; }
*dest++=' '; *dest++ = '\0';
c=0;
}
continue;
}
if (*src=='\n') {
*dest++='\\';
*dest++='n';
c+=2;
src++;
continue;
}
if (*src=='\\' || (isical && *src == ';') || *src == ',') {
*dest++='\\';
c++;
}
*dest++=*src++;
c++;
}
*dest++='\0';
return dest - odest; return dest - odest;
} }
/* /*
* Quote a *TEXT-LIST-CHAR format string as specified by RFC 2426. * Quote a *TEXT-LIST-CHAR format string as specified by RFC 2426.
* Wrap it at 60-ish characters. * Wrap it at 60-ish characters.
*/ */
int str_to_vcard_str(char *dest, int destsz, char *src) int str_to_vcard_str(char *dest, int destsz, char *src) {
{ return str_to_iv_str(dest, destsz, src, 0);
return str_to_iv_str(dest, destsz, src, 0);
} }
/* /*
* This is a slow algorithm, but its not used much * This is a slow algorithm, but its not used much
*/ */
int sub_days_from_date(struct tm *date, int n) int sub_days_from_date(struct tm *date, int n) {
{ int ndim;
int ndim; int fdom;
int fdom; int flag;
int flag; int reset_days;
int reset_days; int i;
int i;
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim);
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim); for (i = 0; i < n; i++) {
for (i=0; i<n; i++) { flag = reset_days = 0;
flag = reset_days = 0; if (--(date->tm_mday) < 1) {
if (--(date->tm_mday) < 1) { date->tm_mday = 28;
date->tm_mday=28; reset_days = 1;
reset_days = 1;
flag = 1;
if (--(date->tm_mon) < 0) {
date->tm_mon=11;
flag = 1; flag = 1;
if (--(date->tm_year)<3) { if (--(date->tm_mon) < 0) {
date->tm_year = 3; date->tm_mon = 11;
flag = 1;
if (--(date->tm_year) < 3) {
date->tm_year = 3;
}
} }
} }
} if (flag) {
if (flag) { get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim);
get_month_info(date->tm_mon, 1, date->tm_year, &fdom, &ndim); }
} /* this assumes that flag is always set when reset_days is set */
/* this assumes that flag is always set when reset_days is set */ if (reset_days) {
if (reset_days) { date->tm_mday = ndim;
date->tm_mday=ndim; }
} }
} date->tm_isdst = -1;
date->tm_isdst=-1; mktime(date);
mktime(date);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* /*
* This function will decrement the date by n number of months and * This function will decrement the date by n number of months and
* adjust the day to the last day of the month if it exceeds the number * adjust the day to the last day of the month if it exceeds the number
* of days in the new month * of days in the new month
*/ */
int sub_months_from_date(struct tm *date, int n) int sub_months_from_date(struct tm *date, int n) {
{ int i;
int i; int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days_in_month[]={31,28,31,30,31,30,31,31,30,31,30,31};
for (i = 0; i < n; i++) {
for (i=0; i<n; i++) { if (--(date->tm_mon) < 0) {
if (--(date->tm_mon) < 0) { date->tm_mon = 11;
date->tm_mon=11; if (--(date->tm_year) < 3) {
if (--(date->tm_year)<3) { date->tm_year = 3;
date->tm_year = 3; }
} }
} }
}
if ((date->tm_year%4 == 0) &&
!(((date->tm_year+1900)%100==0) && ((date->tm_year+1900)%400!=0))) {
days_in_month[1]++;
}
if (date->tm_mday > days_in_month[date->tm_mon]) {
date->tm_mday = days_in_month[date->tm_mon];
}
date->tm_isdst=-1;
mktime(date);
return EXIT_SUCCESS;
}
int sub_years_from_date(struct tm *date, int n)
{
return add_or_sub_years_to_date(date, -n);
}
gint timeout_sync_up(gpointer data)
{
time_t ltime;
struct tm *now;
int secs, diff_secs;
int timeout_interval = get_timeout_interval();
if (timeout_interval == CLOCK_TICK) {
glob_date_timer_tag = gtk_timeout_add(timeout_interval, timeout_date, NULL
);
} else {
/* Interval is in minutes. Sync up with current time */
time(&ltime);
now = localtime(&ltime);
secs = now->tm_sec;
if (secs < 2) {
glob_date_timer_tag = gtk_timeout_add(timeout_interval, timeout_date, N
ULL);
} else {
diff_secs = (secs < 61) ? 60-secs : 59; // Account for leap seconds
glob_date_timer_tag = gtk_timeout_add(diff_secs*CLOCK_TICK, timeout_syn
c_up, NULL);
}
}
timeout_date(NULL); // Update label
return FALSE; // Destroy this timeout
}
gint timeout_date(gpointer data)
{
char str[102];
char datef[102];
const char *svalue1, *svalue2;
time_t ltime;
struct tm *now;
if (glob_date_label==NULL) {
return FALSE;
}
time(&ltime);
now = localtime(&ltime);
/* Build a long date string */ if ((date->tm_year % 4 == 0) &&
get_pref(PREF_LONGDATE, NULL, &svalue1); !(((date->tm_year + 1900) % 100 == 0) && ((date->tm_year + 1900) % 400 !
get_pref(PREF_TIME, NULL, &svalue2); = 0))) {
if ((svalue1==NULL)||(svalue2==NULL)) { days_in_month[1]++;
strcpy(datef, _("Today is %A, %x %X")); }
} else {
sprintf(datef, _("Today is %%A, %s %s"), svalue1, svalue2); if (date->tm_mday > days_in_month[date->tm_mon]) {
} date->tm_mday = days_in_month[date->tm_mon];
jp_strftime(str, 100, datef, now); }
str[100]='\0';
date->tm_isdst = -1;
mktime(date);
return EXIT_SUCCESS;
}
int sub_years_from_date(struct tm *date, int n) {
return add_or_sub_years_to_date(date, -n);
}
gint timeout_sync_up(gpointer data) {
time_t ltime;
struct tm *now;
int secs, diff_secs;
int timeout_interval = get_timeout_interval();
if (timeout_interval == CLOCK_TICK) {
glob_date_timer_tag = g_timeout_add(timeout_interval, timeout_date, NULL
);
} else {
/* Interval is in minutes. Sync up with current time */
time(&ltime);
now = localtime(&ltime);
secs = now->tm_sec;
if (secs < 2) {
glob_date_timer_tag = g_timeout_add(timeout_interval, timeout_date,
NULL);
} else {
diff_secs = (secs < 61) ? 60 - secs : 59; // Account for leap seco
nds
glob_date_timer_tag = g_timeout_add(diff_secs * CLOCK_TICK, timeout_
sync_up, NULL);
}
}
timeout_date(NULL); // Update label
return FALSE; // Destroy this timeout
}
gint timeout_date(gpointer data) {
char str[102];
char datef[102];
const char *svalue1, *svalue2;
time_t ltime;
struct tm *now;
if (glob_date_label == NULL) {
return FALSE;
}
time(&ltime);
now = localtime(&ltime);
/* Build a long date string */
get_pref(PREF_LONGDATE, NULL, &svalue1);
get_pref(PREF_TIME, NULL, &svalue2);
if ((svalue1 == NULL) || (svalue2 == NULL)) {
strcpy(datef, _("Today is %A, %x %X"));
} else {
sprintf(datef, _("Today is %%A, %s %s"), svalue1, svalue2);
}
jp_strftime(str, 100, datef, now);
str[100] = '\0';
gtk_label_set_text(GTK_LABEL(glob_date_label), str); gtk_label_set_text(GTK_LABEL(glob_date_label), str);
return TRUE; return TRUE;
} }
/* /*
* This undeletes a record from the appropriate Datafile * This undeletes a record from the appropriate Datafile
*/ */
int undelete_pc_record(AppType app_type, void *VP, int flag) int undelete_pc_record(AppType app_type, void *VP, int flag) {
{ PC3RecordHeader header;
PC3RecordHeader header; MyAppointment *mappt;
MyAppointment *mappt; MyCalendarEvent *mcale;
MyCalendarEvent *mcale; MyAddress *maddr;
MyAddress *maddr; MyContact *mcont;
MyContact *mcont; MyToDo *mtodo;
MyToDo *mtodo; MyMemo *mmemo;
MyMemo *mmemo; unsigned int unique_id;
unsigned int unique_id; char filename[FILENAME_MAX];
char filename[FILENAME_MAX]; char filename2[FILENAME_MAX];
char filename2[FILENAME_MAX]; FILE *pc_file = NULL;
FILE *pc_file = NULL; FILE *pc_file2 = NULL;
FILE *pc_file2 = NULL; char *record;
char *record; int found;
int found; int ret = -1;
int ret = -1; int num;
int num;
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
long ivalue; long ivalue;
#endif #endif
char dbname[][32]={ char dbname[][32] = {
"DatebookDB.pc3", "DatebookDB.pc3",
"AddressDB.pc3", "AddressDB.pc3",
"ToDoDB.pc3", "ToDoDB.pc3",
"MemoDB.pc3", "MemoDB.pc3",
"" ""
}; };
if (VP==NULL) { if (VP == NULL) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
/* Convert to new database names if prefs set */ /* Convert to new database names if prefs set */
rename_dbnames(dbname); rename_dbnames(dbname);
/* to keep the compiler happy with -Wall*/ /* to keep the compiler happy with -Wall*/
mappt = NULL; mappt = NULL;
mcale = NULL; mcale = NULL;
maddr = NULL; maddr = NULL;
mcont = NULL; mcont = NULL;
mmemo = NULL; mmemo = NULL;
switch (app_type) { switch (app_type) {
case DATEBOOK: case DATEBOOK:
mappt = (MyAppointment *) VP; mappt = (MyAppointment *) VP;
unique_id = mappt->unique_id; unique_id = mappt->unique_id;
strcpy(filename, dbname[0]); strcpy(filename, dbname[0]);
break; break;
case CALENDAR: case CALENDAR:
mcale = (MyCalendarEvent *) VP; mcale = (MyCalendarEvent *) VP;
unique_id = mcale->unique_id; unique_id = mcale->unique_id;
strcpy(filename, dbname[0]); strcpy(filename, dbname[0]);
break; break;
case ADDRESS: case ADDRESS:
maddr = (MyAddress *) VP; maddr = (MyAddress *) VP;
unique_id = maddr->unique_id; unique_id = maddr->unique_id;
strcpy(filename, dbname[1]); strcpy(filename, dbname[1]);
break; break;
case CONTACTS: case CONTACTS:
mcont = (MyContact *) VP; mcont = (MyContact *) VP;
unique_id = mcont->unique_id; unique_id = mcont->unique_id;
strcpy(filename, dbname[1]); strcpy(filename, dbname[1]);
break; break;
case TODO: case TODO:
mtodo = (MyToDo *) VP; mtodo = (MyToDo *) VP;
unique_id = mtodo->unique_id; unique_id = mtodo->unique_id;
#ifdef ENABLE_MANANA #ifdef ENABLE_MANANA
get_pref(PREF_MANANA_MODE, &ivalue, NULL); get_pref(PREF_MANANA_MODE, &ivalue, NULL);
if (ivalue) { if (ivalue) {
strcpy(filename, "MananaDB.pc3"); strcpy(filename, "MananaDB.pc3");
} else { } else {
strcpy(filename, dbname[2]); strcpy(filename, dbname[2]);
} }
#else #else
strcpy(filename, dbname[2]); strcpy(filename, dbname[2]);
#endif #endif
break; break;
case MEMO: case MEMO:
mmemo = (MyMemo *) VP; mmemo = (MyMemo *) VP;
unique_id = mmemo->unique_id; unique_id = mmemo->unique_id;
strcpy(filename, dbname[3]); strcpy(filename, dbname[3]);
break; break;
default: default:
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
found = FALSE; found = FALSE;
record = NULL; record = NULL;
g_snprintf(filename2, sizeof(filename2), "%s.pct", filename); g_snprintf(filename2, sizeof(filename2), "%s.pct", filename);
pc_file = jp_open_home_file(filename , "r"); pc_file = jp_open_home_file(filename, "r");
if (!pc_file) { if (!pc_file) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
pc_file2=jp_open_home_file(filename2, "w"); pc_file2 = jp_open_home_file(filename2, "w");
if (!pc_file2) { if (!pc_file2) {
jp_close_home_file(pc_file); jp_close_home_file(pc_file);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
while(!feof(pc_file)) { while (!feof(pc_file)) {
read_header(pc_file, &header); read_header(pc_file, &header);
if (feof(pc_file)) { if (feof(pc_file)) {
break; break;
} }
/* Skip copying DELETED_PALM_REC entry which undeletes it */ /* Skip copying DELETED_PALM_REC entry which undeletes it */
if (header.unique_id == unique_id && if (header.unique_id == unique_id &&
header.rt == DELETED_PALM_REC) { header.rt == DELETED_PALM_REC) {
found = TRUE; found = TRUE;
if (fseek(pc_file, header.rec_len, SEEK_CUR)) { if (fseek(pc_file, header.rec_len, SEEK_CUR)) {
jp_logf(JP_LOG_WARN, "fseek failed\n"); jp_logf(JP_LOG_WARN, "fseek failed\n");
ret = -1;
break;
}
continue;
}
/* Change header on DELETED_PC_REC to undelete this type */
if ((header.unique_id == unique_id) &&
(header.rt == DELETED_PC_REC)) {
found = TRUE;
header.rt = NEW_PC_REC;
}
/* Otherwise, keep whatever is there by copying it to the new pc3 file *
/
record = malloc(header.rec_len);
if (!record) {
jp_logf(JP_LOG_WARN, "cleanup_pc_file(): Out of memory\n");
ret = -1; ret = -1;
break; break;
} }
continue; num = fread(record, header.rec_len, 1, pc_file);
} if (num != 1) {
/* Change header on DELETED_PC_REC to undelete this type */ if (ferror(pc_file)) {
if ((header.unique_id == unique_id) && ret = -1;
(header.rt == DELETED_PC_REC)) { break;
found = TRUE; }
header.rt = NEW_PC_REC; }
} ret = write_header(pc_file2, &header);
ret = fwrite(record, header.rec_len, 1, pc_file2);
/* Otherwise, keep whatever is there by copying it to the new pc3 file */ if (ret != 1) {
record = malloc(header.rec_len);
if (!record) {
jp_logf(JP_LOG_WARN, "cleanup_pc_file(): Out of memory\n");
ret = -1;
break;
}
num = fread(record, header.rec_len, 1, pc_file);
if (num != 1) {
if (ferror(pc_file)) {
ret = -1; ret = -1;
break; break;
} }
} free(record);
ret = write_header(pc_file2, &header); record = NULL;
ret = fwrite(record, header.rec_len, 1, pc_file2); }
if (ret != 1) {
ret = -1; if (record) {
break; free(record);
} }
free(record); if (pc_file) {
record = NULL; jp_close_home_file(pc_file);
} }
if (pc_file2) {
if (record) { jp_close_home_file(pc_file2);
free(record); }
}
if (pc_file) { if (found) {
jp_close_home_file(pc_file); rename_file(filename2, filename);
} } else {
if (pc_file2) { unlink_file(filename2);
jp_close_home_file(pc_file2); }
}
return ret;
if (found) { }
rename_file(filename2, filename);
} else { int unlink_file(char *filename) {
unlink_file(filename2); char fullname[FILENAME_MAX];
}
get_home_file_name(filename, fullname, sizeof(fullname));
return ret;
} return unlink(fullname);
}
int unlink_file(char *filename)
{ int unpack_db_header(DBHeader *dbh, unsigned char *buffer) {
char fullname[FILENAME_MAX]; unsigned long temp;
get_home_file_name(filename, fullname, sizeof(fullname)); g_strlcpy(dbh->db_name, (char *) buffer, 32);
dbh->flags = bytes_to_bin(buffer + 32, 2);
return unlink(fullname); dbh->version = bytes_to_bin(buffer + 34, 2);
} temp = bytes_to_bin(buffer + 36, 4);
dbh->creation_time = pilot_time_to_unix_time(temp);
int unpack_db_header(DBHeader *dbh, unsigned char *buffer) temp = bytes_to_bin(buffer + 40, 4);
{ dbh->modification_time = pilot_time_to_unix_time(temp);
unsigned long temp; temp = bytes_to_bin(buffer + 44, 4);
dbh->backup_time = pilot_time_to_unix_time(temp);
dbh->modification_number = bytes_to_bin(buffer + 48, 4);
dbh->app_info_offset = bytes_to_bin(buffer + 52, 4);
dbh->sort_info_offset = bytes_to_bin(buffer + 56, 4);
g_strlcpy(dbh->type, (char *) (buffer + 60), 5);
g_strlcpy(dbh->creator_id, (char *) (buffer + 64), 5);
g_strlcpy(dbh->unique_id_seed, (char *) (buffer + 68), 5);
dbh->next_record_list_id = bytes_to_bin(buffer + 72, 4);
dbh->number_of_records = bytes_to_bin(buffer + 76, 2);
g_strlcpy(dbh->db_name, (char *)buffer, 32); return EXIT_SUCCESS;
dbh->flags = bytes_to_bin(buffer + 32, 2);
dbh->version = bytes_to_bin(buffer + 34, 2);
temp = bytes_to_bin(buffer + 36, 4);
dbh->creation_time = pilot_time_to_unix_time(temp);
temp = bytes_to_bin(buffer + 40, 4);
dbh->modification_time = pilot_time_to_unix_time(temp);
temp = bytes_to_bin(buffer + 44, 4);
dbh->backup_time = pilot_time_to_unix_time(temp);
dbh->modification_number = bytes_to_bin(buffer + 48, 4);
dbh->app_info_offset = bytes_to_bin(buffer + 52, 4);
dbh->sort_info_offset = bytes_to_bin(buffer + 56, 4);
g_strlcpy(dbh->type, (char *)(buffer + 60), 5);
g_strlcpy(dbh->creator_id, (char *)(buffer + 64), 5);
g_strlcpy(dbh->unique_id_seed, (char *)(buffer + 68), 5);
dbh->next_record_list_id = bytes_to_bin(buffer + 72, 4);
dbh->number_of_records = bytes_to_bin(buffer + 76, 2);
return EXIT_SUCCESS;
} }
/* Validate CSV header before import /* Validate CSV header before import
* Current test merely checks for the correct number of fields in the header * Current test merely checks for the correct number of fields in the header
* but does not check name, type, etc. More tests could also be added * but does not check name, type, etc. More tests could also be added
* to compare the jpilot version that produced the file with the jpilot * to compare the jpilot version that produced the file with the jpilot
* version that is importing the file. */ * version that is importing the file. */
int verify_csv_header(const char *header, int num_fields, const char *file_name) int verify_csv_header(const char *header, int num_fields, const char *file_name)
{ {
int i, comma_cnt; int i, comma_cnt;
for (i=0, comma_cnt=0; i<strlen(header); i++) {
if (header[i] == ',') comma_cnt++;
}
if (comma_cnt != num_fields-1) {
jp_logf(JP_LOG_WARN, _("Incorrect header format for CSV import\n"
"Check line 1 of file %s\n"
"Aborting import\n"), file_name);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static int write_to_next_id(unsigned int unique_id)
{
FILE *pc_out;
int ret;
pc_out = jp_open_home_file(EPN".next_id", "r+");
if (pc_out==NULL) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s%s\n"), EPN, ".next_id");
return EXIT_FAILURE;
}
ret = write_to_next_id_open(pc_out, unique_id);
jp_close_home_file(pc_out);
return ret; for (i = 0, comma_cnt = 0; i < strlen(header); i++) {
if (header[i] == ',') comma_cnt++;
}
if (comma_cnt != num_fields - 1) {
jp_logf(JP_LOG_WARN, _("Incorrect header format for CSV import\n"
"Check line 1 of file %s\n"
"Aborting import\n"), file_name);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
static int write_to_next_id(unsigned int unique_id) {
FILE *pc_out;
int ret;
pc_out = jp_open_home_file(EPN".next_id", "r+");
if (pc_out == NULL) {
jp_logf(JP_LOG_WARN, _("Unable to open file: %s%s\n"), EPN, ".next_id");
return EXIT_FAILURE;
}
ret = write_to_next_id_open(pc_out, unique_id);
jp_close_home_file(pc_out);
return ret;
}
static int write_to_next_id_open(FILE *pc_out, unsigned int unique_id) {
char id_str[50];
if (fseek(pc_out, 0, SEEK_SET)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
return EXIT_FAILURE;
}
if (fwrite(FILE_VERSION2_CR, strlen(FILE_VERSION2_CR), 1, pc_out) != 1) {
jp_logf(JP_LOG_WARN, _("Error writing version header to file: %s%s\n"),
EPN, ".next_id");
return EXIT_FAILURE;
}
sprintf(id_str, "%d\n", unique_id);
if (fwrite(id_str, strlen(id_str), 1, pc_out) != 1) {
jp_logf(JP_LOG_WARN, _("Error writing next id to file: %s%s"), EPN, ".ne
xt_id\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
gboolean button_pressed_for_motion(GtkWidget *widget, GdkEvent *event, gpointer
user_data) {
guint button;
gdk_event_get_button(event,&button);
//left mouse button
if(button == 1) {
glob_mouse_pressed = 1;
}
return FALSE;
}
gboolean button_released_for_motion(GtkWidget *widget, GdkEvent *event, gpointe
r user_data) {
guint button;
gdk_event_get_button(event,&button);
//left mouse button
if(button == 1) {
glob_mouse_pressed = 0;
}
return FALSE;
} }
static int write_to_next_id_open(FILE *pc_out, unsigned int unique_id) void button_set_for_motion(int x) {
{ glob_mouse_pressed = x;
char id_str[50];
if (fseek(pc_out, 0, SEEK_SET)) {
jp_logf(JP_LOG_WARN, "fseek failed\n");
return EXIT_FAILURE;
}
if (fwrite(FILE_VERSION2_CR, strlen(FILE_VERSION2_CR), 1, pc_out) != 1) {
jp_logf(JP_LOG_WARN, _("Error writing version header to file: %s%s\n"), EP
N, ".next_id");
return EXIT_FAILURE;
}
sprintf(id_str, "%d\n", unique_id);
if (fwrite(id_str, strlen(id_str), 1, pc_out) != 1) {
jp_logf(JP_LOG_WARN, _("Error writing next id to file: %s%s"), EPN, ".next
_id\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} }
 End of changes. 273 change blocks. 
3286 lines changed or deleted 3360 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)