keyring.c (jpilot-1.8.2) | : | keyring.c (jpilot-2_0_1) | ||
---|---|---|---|---|
skipping to change at line 34 | skipping to change at line 34 | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <stdio.h> | #include <stdio.h> | |||
#include <string.h> | #include <string.h> | |||
#include <time.h> | #include <time.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <errno.h> | #include <errno.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include <gtk/gtk.h> | #include <gtk/gtk.h> | |||
#include "config.h" | #include "config.h" | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
# include <gcrypt.h> | # include <gcrypt.h> | |||
#else | #else | |||
/* OpenSSL header files */ | /* OpenSSL header files */ | |||
# include <openssl/md5.h> | # include <openssl/md5.h> | |||
# include <openssl/des.h> | # include <openssl/des.h> | |||
#endif | #endif | |||
/* Pilot-link header files */ | /* Pilot-link header files */ | |||
#include <pi-appinfo.h> | #include <pi-appinfo.h> | |||
#include <pi-dlp.h> | #include <pi-dlp.h> | |||
#include <pi-file.h> | #include <pi-file.h> | |||
/* Jpilot header files */ | /* Jpilot header files */ | |||
#include "libplugin.h" | #include "libplugin.h" | |||
#include "utils.h" | #include "utils.h" | |||
skipping to change at line 86 | skipping to change at line 90 | |||
#define PLUGIN_MAX_INACTIVE_TIME 10 | #define PLUGIN_MAX_INACTIVE_TIME 10 | |||
/* for password hashes */ | /* for password hashes */ | |||
#define SALT_SIZE 4 | #define SALT_SIZE 4 | |||
#define MESSAGE_BUF_SIZE 64 | #define MESSAGE_BUF_SIZE 64 | |||
#define MD5_HASH_SIZE 16 | #define MD5_HASH_SIZE 16 | |||
#define MIN_KR_PASS (20) /* Minimum auto-generated passwd length */ | #define MIN_KR_PASS (20) /* Minimum auto-generated passwd length */ | |||
#define MAX_KR_PASS (25) /* Maximum auto-generated passwd length */ | #define MAX_KR_PASS (25) /* Maximum auto-generated passwd length */ | |||
enum { | ||||
KEYRING_CHANGED_COLUMN_ENUM, | ||||
KEYRING_NAME_COLUMN_ENUM, | ||||
KEYRING_ACCOUNT_COLUMN_ENUM, | ||||
KEYRING_DATA_COLUMN_ENUM, | ||||
KEYRING_BACKGROUND_COLOR_ENUM, | ||||
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, | ||||
KEYRING_FOREGROUND_COLOR_ENUM, | ||||
KEYRINGS_FOREGROUND_COLOR_ENABLED_ENUM, | ||||
KEYRING_NUM_COLS | ||||
}; | ||||
struct KeyRing { | struct KeyRing { | |||
char *name; /* Unencrypted */ | char *name; /* Unencrypted */ | |||
char *account; /* Encrypted */ | char *account; /* Encrypted */ | |||
char *password; /* Encrypted */ | char *password; /* Encrypted */ | |||
char *note; /* Encrypted */ | char *note; /* Encrypted */ | |||
struct tm last_changed; /* Encrypted */ | struct tm last_changed; /* Encrypted */ | |||
}; | }; | |||
/* My wrapper to the KeyRing structure so that I can put a few more | /* My wrapper to the KeyRing structure so that I can put a few more | |||
* fields in with it. */ | * fields in with it. */ | |||
struct MyKeyRing { | struct MyKeyRing { | |||
PCRecType rt; | PCRecType rt; | |||
unsigned int unique_id; | unsigned int unique_id; | |||
unsigned char attrib; | unsigned char attrib; | |||
struct KeyRing kr; | struct KeyRing kr; | |||
struct MyKeyRing *next; | struct MyKeyRing *next; | |||
}; | }; | |||
/******************************* Global vars **********************************/ | /******************************* Global vars **********************************/ | |||
/* This is the category that is currently being displayed */ | /* This is the category that is currently being displayed */ | |||
static struct CategoryAppInfo keyr_app_info; | static struct CategoryAppInfo keyr_app_info; | |||
static int keyr_category = CATEGORY_ALL; | static int keyr_category = CATEGORY_ALL; | |||
static GtkWidget *clist; | static GtkWidget *treeView; | |||
static GtkListStore *listStore; | ||||
static GtkWidget *entry_name; | static GtkWidget *entry_name; | |||
static GtkWidget *entry_account; | static GtkWidget *entry_account; | |||
static GtkWidget *entry_password; | static GtkWidget *entry_password; | |||
static GtkWidget *keyr_note; | static GtkWidget *keyr_note; | |||
static GObject *keyr_note_buffer; | static GObject *keyr_note_buffer; | |||
/* Need 1 extra slot for All category */ | ||||
static GtkWidget *keyr_cat_menu_item1[NUM_KEYRING_CAT_ITEMS+1]; | ||||
static GtkWidget *keyr_cat_menu_item2[NUM_KEYRING_CAT_ITEMS]; | ||||
static GtkWidget *category_menu1; | static GtkWidget *category_menu1; | |||
static GtkWidget *category_menu2; | static GtkWidget *category_menu2; | |||
static struct sorted_cats sort_l[NUM_KEYRING_CAT_ITEMS]; | static struct sorted_cats sort_l[NUM_KEYRING_CAT_ITEMS]; | |||
static GtkWidget *pane = NULL; | static GtkWidget *pane = NULL; | |||
static GtkWidget *scrolled_window; | static GtkWidget *scrolled_window; | |||
static GtkWidget *new_record_button; | static GtkWidget *new_record_button; | |||
static GtkWidget *apply_record_button; | static GtkWidget *apply_record_button; | |||
static GtkWidget *add_record_button; | static GtkWidget *add_record_button; | |||
static GtkWidget *delete_record_button; | static GtkWidget *delete_record_button; | |||
static GtkWidget *undelete_record_button; | static GtkWidget *undelete_record_button; | |||
static GtkWidget *copy_record_button; | static GtkWidget *copy_record_button; | |||
static GtkWidget *cancel_record_button; | static GtkWidget *cancel_record_button; | |||
static GtkWidget *date_button; | static GtkWidget *date_button; | |||
static struct tm glob_date; | static struct tm glob_date; | |||
#ifndef ENABLE_STOCK_BUTTONS | #ifndef ENABLE_STOCK_BUTTONS | |||
static GtkAccelGroup *accel_group; | static GtkAccelGroup *accel_group; | |||
#endif | #endif | |||
static int record_changed; | static int record_changed; | |||
static int clist_col_selected; | static int column_selected; | |||
static int clist_row_selected; | static int row_selected; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
static unsigned char key[24]; | static unsigned char key[24]; | |||
#else | #else | |||
#ifdef HEADER_NEW_DES_H | #ifdef HEADER_NEW_DES_H | |||
static DES_cblock current_key1; | static DES_cblock current_key1; | |||
static DES_cblock current_key2; | static DES_cblock current_key2; | |||
static DES_key_schedule s1, s2; | static DES_key_schedule s1, s2; | |||
#else | #else | |||
static des_cblock current_key1; | static des_cblock current_key1; | |||
static des_cblock current_key2; | static des_cblock current_key2; | |||
static des_key_schedule s1, s2; | static des_key_schedule s1, s2; | |||
#endif | #endif | |||
#endif | #endif | |||
static time_t plugin_last_time = 0; | static time_t plugin_last_time = 0; | |||
static gboolean plugin_active = FALSE; | static gboolean plugin_active = FALSE; | |||
static struct MyKeyRing *glob_keyring_list=NULL; | static struct MyKeyRing *glob_keyring_list = NULL; | |||
static struct MyKeyRing *export_keyring_list=NULL; | static struct MyKeyRing *export_keyring_list = NULL; | |||
/****************************** Prototypes ************************************/ | /****************************** Prototypes ************************************/ | |||
static void keyr_update_clist(GtkWidget *clist, struct MyKeyRing **keyring_list, | ||||
int category, int main); | ||||
static void connect_changed_signals(int con_or_dis); | void keyr_update_liststore(GtkListStore *pListStore, struct MyKeyRing **keyring_ | |||
list, | ||||
int category, int main); | ||||
static void cb_clist_selection(GtkWidget *clist, | static void connect_changed_signals(int con_or_dis); | |||
gint row, | ||||
gint column, | ||||
GdkEventButton *event, | ||||
gpointer data); | ||||
static int keyring_find(int unique_id); | static int keyring_find(int unique_id); | |||
static void update_date_button(GtkWidget *button, struct tm *t); | static void update_date_button(GtkWidget *button, struct tm *t); | |||
static gboolean handleKeyringRowSelection(GtkTreeSelection *selection, | ||||
GtkTreeModel *model, | ||||
GtkTreePath *path, | ||||
gboolean path_currently_selected, | ||||
gpointer userdata); | ||||
void deleteKeyRing(struct MyKeyRing *mkr, gpointer data); | ||||
void undeleteKeyRing(struct MyKeyRing *mkr, gpointer data); | ||||
void addKeyRing(struct MyKeyRing *mkr, gpointer data); | ||||
static GtkWidget *cb_keyr_export_init_treeView(); | ||||
/****************************** Main Code *************************************/ | /****************************** Main Code *************************************/ | |||
/* Routine to get category app info from raw buffer. | /* Routine to get category app info from raw buffer. | |||
* KeyRing is broken and uses a non-standard length CategoryAppInfo. | * KeyRing is broken and uses a non-standard length CategoryAppInfo. | |||
* The KeyRing structure is 276 bytes whereas pilot-link uses 278. | * The KeyRing structure is 276 bytes whereas pilot-link uses 278. | |||
* Code below is taken from unpack_CategoryAppInfo in pilot-link but modified | * Code below is taken from unpack_CategoryAppInfo in pilot-link but modified | |||
* for the shortened structure. */ | * for the shortened structure. */ | |||
static int keyr_plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, | static int keyr_plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, | |||
unsigned char *record, | unsigned char *record, | |||
int len) | int len) { | |||
{ | int i, rec; | |||
int i, rec; | ||||
jp_logf(JP_LOG_DEBUG, "unpack_keyring_cai_from_ai\n"); | ||||
jp_logf(JP_LOG_DEBUG, "unpack_keyring_cai_from_ai\n"); | ||||
if (len < 2 + 16 * 16 + 16 + 2) | ||||
return EXIT_FAILURE; | ||||
rec = get_short(record); | ||||
for (i = 0; i < 16; i++) { | ||||
if (rec & (1 << i)) | ||||
cai->renamed[i] = 1; | ||||
else | ||||
cai->renamed[i] = 0; | ||||
} | ||||
record += 2; | ||||
for (i = 0; i < 16; i++) { | ||||
memcpy(cai->name[i], record, 16); | ||||
record += 16; | ||||
} | ||||
memcpy(cai->ID, record, 16); | ||||
record += 16; | ||||
cai->lastUniqueID = get_byte(record); | ||||
return EXIT_SUCCESS; | if (len < 2 + 16 * 16 + 16 + 2) | |||
return EXIT_FAILURE; | ||||
rec = get_short(record); | ||||
for (i = 0; i < 16; i++) { | ||||
if (rec & (1 << i)) | ||||
cai->renamed[i] = 1; | ||||
else | ||||
cai->renamed[i] = 0; | ||||
} | ||||
record += 2; | ||||
for (i = 0; i < 16; i++) { | ||||
memcpy(cai->name[i], record, 16); | ||||
record += 16; | ||||
} | ||||
memcpy(cai->ID, record, 16); | ||||
record += 16; | ||||
cai->lastUniqueID = get_byte(record); | ||||
return EXIT_SUCCESS; | ||||
} | } | |||
int plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, | int plugin_unpack_cai_from_ai(struct CategoryAppInfo *cai, | |||
unsigned char *record, | unsigned char *record, | |||
int len) | int len) { | |||
{ | return keyr_plugin_unpack_cai_from_ai(cai, record, len); | |||
return keyr_plugin_unpack_cai_from_ai(cai, record, len); | ||||
} | } | |||
/* Routine to pack CategoryAppInfo struct into non-standard size buffer */ | /* Routine to pack CategoryAppInfo struct into non-standard size buffer */ | |||
int plugin_pack_cai_into_ai(struct CategoryAppInfo *cai, | int plugin_pack_cai_into_ai(struct CategoryAppInfo *cai, | |||
unsigned char *record, | unsigned char *record, | |||
int len) | int len) { | |||
{ | int i, rec; | |||
int i, rec; | ||||
if (!record) { | ||||
if (!record) { | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | } | |||
} | if (len < (2 + 16 * 16 + 16 + 2)) | |||
if (len < (2 + 16 * 16 + 16 + 2)) | return EXIT_FAILURE; /* not enough room */ | |||
return EXIT_FAILURE; /* not enough room */ | rec = 0; | |||
rec = 0; | for (i = 0; i < 16; i++) { | |||
for (i = 0; i < 16; i++) { | if (cai->renamed[i]) | |||
if (cai->renamed[i]) | rec |= (1 << i); | |||
rec |= (1 << i); | } | |||
} | set_short(record, rec); | |||
set_short(record, rec); | record += 2; | |||
record += 2; | for (i = 0; i < 16; i++) { | |||
for (i = 0; i < 16; i++) { | memcpy(record, cai->name[i], 16); | |||
memcpy(record, cai->name[i], 16); | record += 16; | |||
record += 16; | } | |||
} | memcpy(record, cai->ID, 16); | |||
memcpy(record, cai->ID, 16); | record += 16; | |||
record += 16; | set_byte(record, cai->lastUniqueID); | |||
set_byte(record, cai->lastUniqueID); | record++; | |||
record++; | set_byte(record, 0); /* gapfill */ | |||
set_byte(record, 0); /* gapfill */ | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
static int pack_KeyRing(struct KeyRing *kr, | static int pack_KeyRing(struct KeyRing *kr, | |||
unsigned char *buf, | unsigned char *buf, | |||
int buf_size, | int buf_size, | |||
int *wrote_size) | int *wrote_size) { | |||
{ | int n; | |||
int n; | int i; | |||
int i; | char empty[] = ""; | |||
char empty[]=""; | char last_changed[2]; | |||
char last_changed[2]; | unsigned short packed_date; | |||
unsigned short packed_date; | ||||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_error_t err; | gcry_error_t err; | |||
gcry_cipher_hd_t hd; | gcry_cipher_hd_t hd; | |||
#endif | #endif | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: pack_KeyRing()\n"); | jp_logf(JP_LOG_DEBUG, "KeyRing: pack_KeyRing()\n"); | |||
packed_date = (((kr->last_changed.tm_year - 4) << 9) & 0xFE00) | | packed_date = (((kr->last_changed.tm_year - 4) << 9) & 0xFE00) | | |||
(((kr->last_changed.tm_mon+1) << 5) & 0x01E0) | | (((kr->last_changed.tm_mon + 1) << 5) & 0x01E0) | | |||
(kr->last_changed.tm_mday & 0x001F); | (kr->last_changed.tm_mday & 0x001F); | |||
set_short(last_changed, packed_date); | set_short(last_changed, packed_date); | |||
*wrote_size=0; | *wrote_size = 0; | |||
if (!(kr->name)) kr->name=empty; | if (!(kr->name)) kr->name = empty; | |||
if (!(kr->account)) kr->account=empty; | if (!(kr->account)) kr->account = empty; | |||
if (!(kr->password)) kr->password=empty; | if (!(kr->password)) kr->password = empty; | |||
if (!(kr->note)) kr->note=empty; | if (!(kr->note)) kr->note = empty; | |||
/* 2 is for the lastChanged date */ | /* 2 is for the lastChanged date */ | |||
/* 3 chars accounts for NULL string terminators */ | /* 3 chars accounts for NULL string terminators */ | |||
n=strlen(kr->account) + strlen(kr->password) + strlen(kr->note) + 2 + 3; | n = strlen(kr->account) + strlen(kr->password) + strlen(kr->note) + 2 + 3; | |||
/* The encrypted portion must be a multiple of 8 */ | /* The encrypted portion must be a multiple of 8 */ | |||
if ((n%8)) { | if ((n % 8)) { | |||
n=n+(8-(n%8)); | n = n + (8 - (n % 8)); | |||
} | } | |||
/* Now we can add in the unencrypted part */ | /* Now we can add in the unencrypted part */ | |||
n=n+strlen(kr->name)+1; | n = n + strlen(kr->name) + 1; | |||
jp_logf(JP_LOG_DEBUG, "pack n=%d\n", n); | jp_logf(JP_LOG_DEBUG, "pack n=%d\n", n); | |||
if (n+2>buf_size) { | if (n + 2 > buf_size) { | |||
jp_logf(JP_LOG_WARN, _("KeyRing: pack_KeyRing(): buf_size too small\n")); | jp_logf(JP_LOG_WARN, _("KeyRing: pack_KeyRing(): buf_size too small\n")) | |||
return EXIT_FAILURE; | ; | |||
} | return EXIT_FAILURE; | |||
} | ||||
memset(buf, 0, n+1); | ||||
*wrote_size = n; | memset(buf, 0, n + 1); | |||
strcpy((char *)buf, kr->name); | *wrote_size = n; | |||
i = strlen(kr->name)+1; | strcpy((char *) buf, kr->name); | |||
strcpy((char *)&buf[i], kr->account); | i = strlen(kr->name) + 1; | |||
i += strlen(kr->account)+1; | strcpy((char *) &buf[i], kr->account); | |||
strcpy((char *)&buf[i], kr->password); | i += strlen(kr->account) + 1; | |||
i += strlen(kr->password)+1; | strcpy((char *) &buf[i], kr->password); | |||
strcpy((char *)&buf[i], kr->note); | i += strlen(kr->password) + 1; | |||
i += strlen(kr->note)+1; | strcpy((char *) &buf[i], kr->note); | |||
strncpy((char *)&buf[i], last_changed, 2); | i += strlen(kr->note) + 1; | |||
strncpy((char *) &buf[i], last_changed, 2); | ||||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); | err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); | |||
if (err) | if (err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); | jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); | |||
err = gcry_cipher_setkey(hd, key, sizeof(key)); | err = gcry_cipher_setkey(hd, key, sizeof(key)); | |||
if (err) | if (err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); | jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); | |||
for (i = strlen(kr->name)+1; i<n; i+=8) | for (i = strlen(kr->name) + 1; i < n; i += 8) { | |||
{ | char tmp[8]; | |||
char tmp[8]; | err = gcry_cipher_encrypt(hd, tmp, 8, &buf[i], 8); | |||
err = gcry_cipher_encrypt(hd, tmp, 8, &buf[i], 8); | if (err) | |||
if (err) | jp_logf(JP_LOG_DEBUG, "gcry_cipher_encrypt: %s\n", gpg_strerror(err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_encrypt: %s\n", gpg_strerror(err)); | ); | |||
memcpy(&buf[i], tmp, 8); | memcpy(&buf[i], tmp, 8); | |||
} | } | |||
gcry_cipher_close(hd); | gcry_cipher_close(hd); | |||
#else | #else | |||
for (i=strlen(kr->name)+1; i<n; i=i+8) { | for (i=strlen(kr->name)+1; i<n; i=i+8) { | |||
#ifdef HEADER_NEW_DES_H | #ifdef HEADER_NEW_DES_H | |||
DES_ecb3_encrypt((DES_cblock *)&buf[i], (DES_cblock *)&buf[i], | DES_ecb3_encrypt((DES_cblock *)&buf[i], (DES_cblock *)&buf[i], | |||
&s1, &s2, &s1, DES_ENCRYPT); | &s1, &s2, &s1, DES_ENCRYPT); | |||
#else | #else | |||
des_ecb3_encrypt((const_des_cblock *)&buf[i], (des_cblock *)(&buf[i]), | des_ecb3_encrypt((const_des_cblock *)&buf[i], (des_cblock *)(&buf[i]), | |||
s1, s2, s1, DES_ENCRYPT); | s1, s2, s1, DES_ENCRYPT); | |||
#endif | #endif | |||
} | } | |||
#endif | #endif | |||
#ifdef JPILOT_DEBUG | #ifdef JPILOT_DEBUG | |||
for (i=0;i<n; i++) { | for (i=0;i<n; i++) { | |||
printf("%02x ", (unsigned char)buf[i]); | printf("%02x ", (unsigned char)buf[i]); | |||
} | } | |||
printf("\n"); | printf("\n"); | |||
#endif | #endif | |||
return n; | return n; | |||
} | } | |||
static int unpack_KeyRing(struct KeyRing *kr, | static int unpack_KeyRing(struct KeyRing *kr, | |||
unsigned char *buf, | unsigned char *buf, | |||
int buf_size) | int buf_size) { | |||
{ | int i, j; | |||
int i, j; | int n; | |||
int n; | int rem; | |||
int rem; | unsigned char *clear_text; | |||
unsigned char *clear_text; | unsigned char *P; | |||
unsigned char *P; | unsigned char *Pstr[4]; | |||
unsigned char *Pstr[4]; | const char *safety[] = {"", "", "", ""}; | |||
const char *safety[]= {"","","",""}; | unsigned short packed_date; | |||
unsigned short packed_date; | ||||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_error_t err; | gcry_error_t err; | |||
gcry_cipher_hd_t hd; | gcry_cipher_hd_t hd; | |||
#endif | #endif | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing\n"); | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing\n"); | |||
if (!memchr(buf, '\0', buf_size)) { | if (!memchr(buf, '\0', buf_size)) { | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): No null terminator found | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): No null terminator fou | |||
in buf\n"); | nd in buf\n"); | |||
return 0; | return 0; | |||
} | } | |||
n=strlen((char *)buf)+1; | n = strlen((char *) buf) + 1; | |||
rem=buf_size-n; | rem = buf_size - n; | |||
if (rem>0xFFFF) { | if (rem > 0xFFFF) { | |||
/* This can be caused by a bug in libplugin.c from jpilot 0.99.1 | /* This can be caused by a bug in libplugin.c from jpilot 0.99.1 | |||
* and before. It occurs on the last record */ | * and before. It occurs on the last record */ | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): buffer too big n=%d, buf | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): buffer too big n=%d, b | |||
_size=%d\n", n, buf_size); | uf_size=%d\n", n, buf_size); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): truncating\n"); | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): truncating\n"); | |||
rem=0xFFFF-n; | rem = 0xFFFF - n; | |||
rem=rem-(rem%8); | rem = rem - (rem % 8); | |||
} | } | |||
clear_text=malloc(rem+8); /* Allow for some safety NULLs */ | clear_text = malloc(rem + 8); /* Allow for some safety NULLs */ | |||
memset(clear_text, 0, rem+8); | memset(clear_text, 0, rem + 8); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem (should be multiple of | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem (should be multiple of | |||
8)=%d\n", rem); | 8)=%d\n", rem); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem%%8=%d\n", rem%8); | jp_logf(JP_LOG_DEBUG, "KeyRing: unpack_KeyRing(): rem%%8=%d\n", rem % 8); | |||
P=&buf[n]; | P = &buf[n]; | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); | err = gcry_cipher_open(&hd, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB, 0); | |||
if (err) | if (err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); | jp_logf(JP_LOG_DEBUG, "gcry_cipher_open: %s\n", gpg_strerror(err)); | |||
err = gcry_cipher_setkey(hd, key, sizeof(key)); | err = gcry_cipher_setkey(hd, key, sizeof(key)); | |||
if (err) | if (err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); | jp_logf(JP_LOG_DEBUG, "gcry_cipher_setkey: %s\n", gpg_strerror(err)); | |||
err = gcry_cipher_decrypt(hd, clear_text, rem, P, rem); | err = gcry_cipher_decrypt(hd, clear_text, rem, P, rem); | |||
if (err) | if (err) | |||
jp_logf(JP_LOG_DEBUG, "gcry_cipher_decrypt: %s\n", gpg_strerror(err)); | jp_logf(JP_LOG_DEBUG, "gcry_cipher_decrypt: %s\n", gpg_strerror(err)); | |||
gcry_cipher_close(hd); | gcry_cipher_close(hd); | |||
#else | #else | |||
for (i=0; i<rem; i+=8) { | for (i=0; i<rem; i+=8) { | |||
#ifdef HEADER_NEW_DES_H | #ifdef HEADER_NEW_DES_H | |||
DES_ecb3_encrypt((DES_cblock *)&P[i], (DES_cblock *)(clear_text+i), | DES_ecb3_encrypt((DES_cblock *)&P[i], (DES_cblock *)(clear_text+i), | |||
&s1, &s2, &s1, DES_DECRYPT); | &s1, &s2, &s1, DES_DECRYPT); | |||
#else | #else | |||
des_ecb3_encrypt((const_des_cblock *)&P[i], (des_cblock *)(clear_text+i), | des_ecb3_encrypt((const_des_cblock *)&P[i], (des_cblock *)(clear_text+i), | |||
s1, s2, s1, DES_DECRYPT); | s1, s2, s1, DES_DECRYPT); | |||
#endif | #endif | |||
} | } | |||
#endif | #endif | |||
Pstr[0]=clear_text; | Pstr[0] = clear_text; | |||
Pstr[1]=(unsigned char *)safety[1]; | Pstr[1] = (unsigned char *) safety[1]; | |||
Pstr[2]=(unsigned char *)safety[2]; | Pstr[2] = (unsigned char *) safety[2]; | |||
Pstr[3]=(unsigned char *)safety[3]; | Pstr[3] = (unsigned char *) safety[3]; | |||
for (i=0, j=1; (i<rem) && (j<4); i++) { | for (i = 0, j = 1; (i < rem) && (j < 4); i++) { | |||
if (!clear_text[i]) { | if (!clear_text[i]) { | |||
Pstr[j]=&clear_text[i+1]; | Pstr[j] = &clear_text[i + 1]; | |||
j++; | j++; | |||
} | } | |||
} | } | |||
/* | /* | |||
kr->name=strdup((char *)buf); | kr->name=strdup((char *)buf); | |||
kr->account=strdup((char *)Pstr[0]); | kr->account=strdup((char *)Pstr[0]); | |||
kr->password=strdup((char *)Pstr[1]); | kr->password=strdup((char *)Pstr[1]); | |||
kr->note=strdup((char *)Pstr[2]); | kr->note=strdup((char *)Pstr[2]); | |||
*/ | */ | |||
kr->name=jp_charset_p2newj((char *)buf,-1); | kr->name = jp_charset_p2newj((char *) buf, -1); | |||
kr->account=jp_charset_p2newj((char *)Pstr[0],-1); | kr->account = jp_charset_p2newj((char *) Pstr[0], -1); | |||
kr->password=jp_charset_p2newj((char *)Pstr[1],-1); | kr->password = jp_charset_p2newj((char *) Pstr[1], -1); | |||
kr->note=jp_charset_p2newj((char *)Pstr[2],-1); | kr->note = jp_charset_p2newj((char *) Pstr[2], -1); | |||
packed_date = get_short(Pstr[3]); | packed_date = get_short(Pstr[3]); | |||
kr->last_changed.tm_year = ((packed_date & 0xFE00) >> 9) + 4; | kr->last_changed.tm_year = ((packed_date & 0xFE00) >> 9) + 4; | |||
kr->last_changed.tm_mon = ((packed_date & 0x01E0) >> 5) - 1; | kr->last_changed.tm_mon = ((packed_date & 0x01E0) >> 5) - 1; | |||
kr->last_changed.tm_mday = (packed_date & 0x001F); | kr->last_changed.tm_mday = (packed_date & 0x001F); | |||
kr->last_changed.tm_hour = 0; | kr->last_changed.tm_hour = 0; | |||
kr->last_changed.tm_min = 0; | kr->last_changed.tm_min = 0; | |||
kr->last_changed.tm_sec = 0; | kr->last_changed.tm_sec = 0; | |||
kr->last_changed.tm_isdst= -1; | kr->last_changed.tm_isdst = -1; | |||
if (0 == packed_date) | if (0 == packed_date) { | |||
{ | kr->last_changed.tm_year = 0; | |||
kr->last_changed.tm_year = 0; | kr->last_changed.tm_mon = 0; | |||
kr->last_changed.tm_mon = 0; | kr->last_changed.tm_mday = 0; | |||
kr->last_changed.tm_mday = 0; | } | |||
} | ||||
#ifdef DEBUG | #ifdef DEBUG | |||
printf("name [%s]\n", buf); | printf("name [%s]\n", buf); | |||
printf("Pstr0 [%s]\n", Pstr[0]); | printf("Pstr0 [%s]\n", Pstr[0]); | |||
printf("Pstr1 [%s]\n", Pstr[1]); | printf("Pstr1 [%s]\n", Pstr[1]); | |||
printf("Pstr2 [%s]\n", Pstr[2]); | printf("Pstr2 [%s]\n", Pstr[2]); | |||
printf("last_changed %d-%d-%d\n", | printf("last_changed %d-%d-%d\n", | |||
kr->last_changed.tm_year, | kr->last_changed.tm_year, | |||
kr->last_changed.tm_mon, | kr->last_changed.tm_mon, | |||
kr->last_changed.tm_mday); | kr->last_changed.tm_mday); | |||
#endif | #endif | |||
free(clear_text); | free(clear_text); | |||
return 1; | return 1; | |||
} | } | |||
static int get_keyr_cat_info(struct CategoryAppInfo *cai) | static int get_keyr_cat_info(struct CategoryAppInfo *cai) { | |||
{ | unsigned char *buf; | |||
unsigned char *buf; | int buf_size; | |||
int buf_size; | ||||
memset(cai, 0, sizeof(struct CategoryAppInfo)); | memset(cai, 0, sizeof(struct CategoryAppInfo)); | |||
jp_get_app_info("Keys-Gtkr", &buf, &buf_size); | jp_get_app_info("Keys-Gtkr", &buf, &buf_size); | |||
keyr_plugin_unpack_cai_from_ai(cai, buf, buf_size); | keyr_plugin_unpack_cai_from_ai(cai, buf, buf_size); | |||
free(buf); | free(buf); | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
/* | /* | |||
* Return EXIT_FAILURE if password isn't good. | * Return EXIT_FAILURE if password isn't good. | |||
* Return EXIT_SUCCESS if good and global and also sets s1, and s2 set | * Return EXIT_SUCCESS if good and global and also sets s1, and s2 set | |||
*/ | */ | |||
static int set_password_hash(unsigned char *buf, int buf_size, char *passwd) | static int set_password_hash(unsigned char *buf, int buf_size, char *passwd) { | |||
{ | unsigned char buffer[MESSAGE_BUF_SIZE]; | |||
unsigned char buffer[MESSAGE_BUF_SIZE]; | unsigned char md[MD5_HASH_SIZE]; | |||
unsigned char md[MD5_HASH_SIZE]; | ||||
if (buf_size < MD5_HASH_SIZE) { | ||||
if (buf_size < MD5_HASH_SIZE) { | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | } | |||
} | /* Must wipe passwd out of memory after using it */ | |||
/* Must wipe passwd out of memory after using it */ | memset(buffer, 0, MESSAGE_BUF_SIZE); | |||
memset(buffer, 0, MESSAGE_BUF_SIZE); | memcpy(buffer, buf, SALT_SIZE); | |||
memcpy(buffer, buf, SALT_SIZE); | strncpy((char *) (buffer + SALT_SIZE), passwd, MESSAGE_BUF_SIZE - SALT_SIZE | |||
strncpy((char *)(buffer+SALT_SIZE), passwd, MESSAGE_BUF_SIZE - SALT_SIZE - 1) | - 1); | |||
; | ||||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
<span class="insert">1);</span> | gcry_md_hash_buffer(GCRY_MD_MD5, md, buffer, MESSAGE_BUF_SIZE); | |||
gcry_md_hash_buffer(GCRY_MD_MD5, md, buffer, MESSAGE_BUF_SIZE); | ||||
#else | #else | |||
MD5(buffer, MESSAGE_BUF_SIZE, md); | MD5(buffer, MESSAGE_BUF_SIZE, md); | |||
#endif | #endif | |||
/* wipe out password traces */ | /* wipe out password traces */ | |||
memset(buffer, 0, MESSAGE_BUF_SIZE); | memset(buffer, 0, MESSAGE_BUF_SIZE); | |||
if (memcmp(md, buf+SALT_SIZE, MD5_HASH_SIZE)) { | if (memcmp(md, buf + SALT_SIZE, MD5_HASH_SIZE)) { | |||
return EXIT_FAILURE; | return EXIT_FAILURE; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
gcry_md_hash_buffer(GCRY_MD_MD5, md, passwd, strlen(passwd)); | gcry_md_hash_buffer(GCRY_MD_MD5, md, passwd, strlen(passwd)); | |||
memcpy(key, md, 16); /* k1 and k2 */ | memcpy(key, md, 16); /* k1 and k2 */ | |||
memcpy(key+16, md, 8); /* k1 again */ | memcpy(key + 16, md, 8); /* k1 again */ | |||
#else | #else | |||
MD5((unsigned char *)passwd, strlen(passwd), md); | MD5((unsigned char *)passwd, strlen(passwd), md); | |||
memcpy(current_key1, md, 8); | memcpy(current_key1, md, 8); | |||
memcpy(current_key2, md+8, 8); | memcpy(current_key2, md+8, 8); | |||
#ifdef HEADER_NEW_DES_H | #ifdef HEADER_NEW_DES_H | |||
DES_set_key(¤t_key1, &s1); | DES_set_key(¤t_key1, &s1); | |||
DES_set_key(¤t_key2, &s2); | DES_set_key(¤t_key2, &s2); | |||
#else | #else | |||
des_set_key(¤t_key1, s1); | des_set_key(¤t_key1, s1); | |||
des_set_key(¤t_key2, s2); | des_set_key(¤t_key2, s2); | |||
#endif | #endif | |||
#endif | #endif | |||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
/* Start password change code */ | /* Start password change code */ | |||
/* | /* | |||
* Code for this is written, just need to add another jpilot API for | * Code for this is written, just need to add another jpilot API for | |||
* cancelling a sync if the passwords don't match. | * cancelling a sync if the passwords don't match. | |||
*/ | */ | |||
/* End password change code */ | /* End password change code */ | |||
/* Utility function to read keyring data file and filter out unwanted records | /* Utility function to read keyring data file and filter out unwanted records | |||
* | * | |||
* Returns the number of records read */ | * Returns the number of records read */ | |||
static int get_keyring(struct MyKeyRing **mkr_list, int category) | static int get_keyring(struct MyKeyRing **mkr_list, int category) { | |||
{ | GList *records = NULL; | |||
GList *records=NULL; | GList *temp_list; | |||
GList *temp_list; | buf_rec *br; | |||
buf_rec *br; | struct MyKeyRing *mkr; | |||
struct MyKeyRing *mkr; | int rec_count; | |||
int rec_count; | long keep_modified, keep_deleted; | |||
long keep_modified, keep_deleted; | ||||
jp_logf(JP_LOG_DEBUG, "get_keyring()\n"); | ||||
jp_logf(JP_LOG_DEBUG, "get_keyring()\n"); | ||||
*mkr_list = NULL; | ||||
*mkr_list = NULL; | rec_count = 0; | |||
rec_count = 0; | ||||
/* Read raw database of records */ | ||||
/* Read raw database of records */ | if (jp_read_DB_files("Keys-Gtkr", &records) == -1) | |||
if (jp_read_DB_files("Keys-Gtkr", &records) == -1) | return 0; | |||
return 0; | ||||
/* Get preferences used for filtering */ | ||||
/* Get preferences used for filtering */ | get_pref(PREF_SHOW_MODIFIED, &keep_modified, NULL); | |||
get_pref(PREF_SHOW_MODIFIED, &keep_modified, NULL); | get_pref(PREF_SHOW_DELETED, &keep_deleted, NULL); | |||
get_pref(PREF_SHOW_DELETED, &keep_deleted, NULL); | ||||
/* Sort through list of records masking out unwanted ones */ | ||||
/* Sort through list of records masking out unwanted ones */ | for (temp_list = records; temp_list; temp_list = temp_list->next) { | |||
for (temp_list = records; temp_list; temp_list = temp_list->next) { | if (temp_list->data) { | |||
if (temp_list->data) { | br = temp_list->data; | |||
br=temp_list->data; | } else { | |||
} else { | continue; | |||
continue; | } | |||
} | if (!br->buf) { | |||
if (!br->buf) { | continue; | |||
continue; | } | |||
} | /* record 0 is the hash-key record */ | |||
/* record 0 is the hash-key record */ | if (br->attrib & dlpRecAttrSecret) { | |||
if (br->attrib & dlpRecAttrSecret) { | continue; | |||
continue; | } | |||
} | ||||
/* Filter out deleted or deleted/modified records */ | ||||
/* Filter out deleted or deleted/modified records */ | if (((br->rt == DELETED_PALM_REC) && (!keep_deleted)) || | |||
if ( ((br->rt==DELETED_PALM_REC) && (!keep_deleted)) || | ((br->rt == DELETED_PC_REC) && (!keep_deleted)) || | |||
((br->rt==DELETED_PC_REC) && (!keep_deleted)) || | ((br->rt == MODIFIED_PALM_REC) && (!keep_modified))) { | |||
((br->rt==MODIFIED_PALM_REC) && (!keep_modified)) ) { | continue; | |||
continue; | } | |||
} | ||||
/* Filter by category */ | ||||
/* Filter by category */ | if (((br->attrib & 0x0F) != category) && category != CATEGORY_ALL) { | |||
if ( ((br->attrib & 0x0F) != category) && category != CATEGORY_ALL) { | continue; | |||
continue; | } | |||
} | ||||
mkr = malloc(sizeof(struct MyKeyRing)); | ||||
mkr = malloc(sizeof(struct MyKeyRing)); | mkr->next = NULL; | |||
mkr->next=NULL; | mkr->attrib = br->attrib; | |||
mkr->attrib = br->attrib; | mkr->unique_id = br->unique_id; | |||
mkr->unique_id = br->unique_id; | mkr->rt = br->rt; | |||
mkr->rt = br->rt; | ||||
if (unpack_KeyRing(&(mkr->kr), br->buf, br->size) <= 0) { | ||||
if (unpack_KeyRing(&(mkr->kr), br->buf, br->size) <=0) { | free(mkr); | |||
free(mkr); | continue; | |||
continue; | } | |||
} | ||||
/* prepend to list */ | ||||
/* prepend to list */ | mkr->next = *mkr_list; | |||
mkr->next=*mkr_list; | *mkr_list = mkr; | |||
*mkr_list=mkr; | ||||
rec_count++; | ||||
rec_count++; | } | |||
} | ||||
jp_free_DB_records(&records); | ||||
jp_free_DB_records(&records); | ||||
jp_logf(JP_LOG_DEBUG, "Leaving get_keyring()\n"); | ||||
jp_logf(JP_LOG_DEBUG, "Leaving get_keyring()\n"); | ||||
return rec_count; | ||||
return rec_count; | } | |||
} | ||||
static void set_new_button_to(int new_state) { | ||||
static void set_new_button_to(int new_state) | jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record | |||
{ | _changed); | |||
jp_logf(JP_LOG_DEBUG, "set_new_button_to new %d old %d\n", new_state, record_ | ||||
changed); | if (record_changed == new_state) { | |||
return; | ||||
if (record_changed==new_state) { | } | |||
return; | ||||
} | switch (new_state) { | |||
case MODIFY_FLAG: | ||||
switch (new_state) { | gtk_widget_show(cancel_record_button); | |||
case MODIFY_FLAG: | gtk_widget_show(copy_record_button); | |||
gtk_widget_show(cancel_record_button); | gtk_widget_show(apply_record_button); | |||
gtk_widget_show(copy_record_button); | ||||
gtk_widget_show(apply_record_button); | gtk_widget_hide(add_record_button); | |||
gtk_widget_hide(delete_record_button); | ||||
gtk_widget_hide(add_record_button); | gtk_widget_hide(new_record_button); | |||
gtk_widget_hide(delete_record_button); | gtk_widget_hide(undelete_record_button); | |||
gtk_widget_hide(new_record_button); | ||||
gtk_widget_hide(undelete_record_button); | break; | |||
case NEW_FLAG: | ||||
break; | gtk_widget_show(cancel_record_button); | |||
case NEW_FLAG: | gtk_widget_show(add_record_button); | |||
gtk_widget_show(cancel_record_button); | ||||
gtk_widget_show(add_record_button); | gtk_widget_hide(apply_record_button); | |||
gtk_widget_hide(copy_record_button); | ||||
gtk_widget_hide(apply_record_button); | gtk_widget_hide(delete_record_button); | |||
gtk_widget_hide(copy_record_button); | gtk_widget_hide(new_record_button); | |||
gtk_widget_hide(delete_record_button); | gtk_widget_hide(undelete_record_button); | |||
gtk_widget_hide(new_record_button); | ||||
gtk_widget_hide(undelete_record_button); | break; | |||
case CLEAR_FLAG: | ||||
break; | gtk_widget_show(delete_record_button); | |||
case CLEAR_FLAG: | gtk_widget_show(copy_record_button); | |||
gtk_widget_show(delete_record_button); | gtk_widget_show(new_record_button); | |||
gtk_widget_show(copy_record_button); | ||||
gtk_widget_show(new_record_button); | gtk_widget_hide(add_record_button); | |||
gtk_widget_hide(apply_record_button); | ||||
gtk_widget_hide(add_record_button); | gtk_widget_hide(cancel_record_button); | |||
gtk_widget_hide(apply_record_button); | gtk_widget_hide(undelete_record_button); | |||
gtk_widget_hide(cancel_record_button); | ||||
gtk_widget_hide(undelete_record_button); | break; | |||
case UNDELETE_FLAG: | ||||
break; | gtk_widget_show(undelete_record_button); | |||
case UNDELETE_FLAG: | gtk_widget_show(copy_record_button); | |||
gtk_widget_show(undelete_record_button); | gtk_widget_show(new_record_button); | |||
gtk_widget_show(copy_record_button); | ||||
gtk_widget_show(new_record_button); | gtk_widget_hide(add_record_button); | |||
gtk_widget_hide(apply_record_button); | ||||
gtk_widget_hide(add_record_button); | gtk_widget_hide(cancel_record_button); | |||
gtk_widget_hide(apply_record_button); | gtk_widget_hide(delete_record_button); | |||
gtk_widget_hide(cancel_record_button); | break; | |||
gtk_widget_hide(delete_record_button); | ||||
break; | ||||
default: | ||||
return; | ||||
} | ||||
record_changed=new_state; | default: | |||
return; | ||||
} | ||||
record_changed = new_state; | ||||
} | } | |||
/* Find position of category in sorted category array | /* Find position of category in sorted category array | |||
* via its assigned category number */ | * via its assigned category number */ | |||
static int find_sort_cat_pos(int cat) | static int find_sort_cat_pos(int cat) { | |||
{ | int i; | |||
int i; | ||||
for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) { | ||||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | if (sort_l[i].cat_num == cat) { | |||
if (sort_l[i].cat_num==cat) { | return i; | |||
return i; | } | |||
} | } | |||
} | ||||
return -1; | return -1; | |||
} | } | |||
/* Find a category's position in the category menu. | /* Find a category's position in the category menu. | |||
* This is equal to the category number except for the Unfiled category. | * This is equal to the category number except for the Unfiled category. | |||
* The Unfiled category is always in the last position which changes as | * The Unfiled category is always in the last position which changes as | |||
* the number of categories changes */ | * the number of categories changes */ | |||
static int find_menu_cat_pos(int cat) | static int find_menu_cat_pos(int cat) { | |||
{ | int i; | |||
int i; | ||||
if (cat != NUM_KEYRING_CAT_ITEMS - 1) { | ||||
if (cat != NUM_KEYRING_CAT_ITEMS-1) { | return cat; | |||
return cat; | } else { /* Unfiled category */ | |||
} else { /* Unfiled category */ | /* Count how many category entries are filled */ | |||
/* Count how many category entries are filled */ | for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) { | |||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | if (!sort_l[i].Pcat[0]) { | |||
if (!sort_l[i].Pcat[0]) { | return i; | |||
return i; | } | |||
} | } | |||
} | return 0; | |||
return 0; | } | |||
} | } | |||
} | ||||
static gint GtkTreeModelKeyrCompareDates(GtkTreeModel *model, | ||||
/* Function is used to sort clist based on the Last Changed date field */ | GtkTreeIter *left, | |||
static gint GtkClistKeyrCompareDates(GtkCList *clist, | GtkTreeIter *right, | |||
gconstpointer ptr1, | gpointer columnId) { | |||
gconstpointer ptr2) | ||||
{ | struct MyKeyRing *mkr1, *mkr2; | |||
GtkCListRow *row1, *row2; | ||||
struct MyKeyRing *mkr1,*mkr2; | struct KeyRing *keyr1, *keyr2; | |||
struct KeyRing *keyr1, *keyr2; | time_t time1, time2; | |||
time_t time1, time2; | gtk_tree_model_get(GTK_TREE_MODEL(model), left, KEYRING_DATA_COLUMN_ENUM, &m | |||
kr1, -1); | ||||
row1 = (GtkCListRow *) ptr1; | gtk_tree_model_get(GTK_TREE_MODEL(model), right, KEYRING_DATA_COLUMN_ENUM, & | |||
row2 = (GtkCListRow *) ptr2; | mkr2, -1); | |||
keyr1 = &(mkr1->kr); | ||||
mkr1 = row1->data; | keyr2 = &(mkr2->kr); | |||
mkr2 = row2->data; | ||||
time1 = mktime(&(keyr1->last_changed)); | ||||
keyr1 = &(mkr1->kr); | time2 = mktime(&(keyr2->last_changed)); | |||
keyr2 = &(mkr2->kr); | ||||
return (time1 - time2); | ||||
time1 = mktime(&(keyr1->last_changed)); | } | |||
time2 = mktime(&(keyr2->last_changed)); | ||||
/* Function is used to sort list case insensitively | ||||
return(time1 - time2); | * not sure if this is really needed as the default sort seems to do the same th | |||
} | ing | |||
*/ | ||||
/* Function is used to sort clist case insensitively */ | static gint GtkTreeModelKeyrCompareNocase(GtkTreeModel *model, | |||
static gint GtkClistKeyrCompareNocase (GtkCList *clist, | GtkTreeIter *left, | |||
gconstpointer ptr1, | GtkTreeIter *right, | |||
gconstpointer ptr2) | gpointer columnId) { | |||
{ | ||||
GtkCListRow *row1, *row2; | gchar *str1, *str2; | |||
gchar *str1, *str2; | gtk_tree_model_get(GTK_TREE_MODEL(model), left, KEYRING_NAME_COLUMN_ENUM, &s | |||
tr1, -1); | ||||
row1 = (GtkCListRow *) ptr1; | gtk_tree_model_get(GTK_TREE_MODEL(model), right, KEYRING_NAME_COLUMN_ENUM, & | |||
row2 = (GtkCListRow *) ptr2; | str2, -1); | |||
return g_ascii_strcasecmp(str1, str2); | ||||
str1 = GTK_CELL_TEXT(row1->cell[clist->sort_column])->text; | } | |||
str2 = GTK_CELL_TEXT(row2->cell[clist->sort_column])->text; | ||||
static void cb_record_changed(GtkWidget *widget, gpointer data) { | ||||
return g_ascii_strcasecmp(str1, str2); | int flag; | |||
} | struct tm *now; | |||
time_t ltime; | ||||
static void cb_clist_click_column(GtkWidget *clist, int column) | ||||
{ | jp_logf(JP_LOG_DEBUG, "cb_record_changed\n"); | |||
struct MyKeyRing *mkr; | ||||
unsigned int unique_id; | flag = GPOINTER_TO_INT(data); | |||
/* Return to the selected record after sorting. | if (record_changed == CLEAR_FLAG) { | |||
* This is critically important because sorting without updating the | connect_changed_signals(DISCONNECT_SIGNALS); | |||
* global variable clist_row_selected can cause data loss */ | if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) > 0) | |||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); | { | |||
if (mkr < (struct MyKeyRing *)CLIST_MIN_DATA) { | set_new_button_to(MODIFY_FLAG); | |||
unique_id = 0; | /* Update the lastChanged field when password is modified */ | |||
} else { | if (flag == PASSWD_FLAG) { | |||
unique_id = mkr->unique_id; | time(<ime); | |||
} | now = localtime(<ime); | |||
memcpy(&glob_date, now, sizeof(struct tm)); | ||||
/* Clicking on same column toggles ascending/descending sort */ | update_date_button(date_button, &glob_date); | |||
if (clist_col_selected == column) | } | |||
{ | } else { | |||
if (GTK_CLIST(clist)->sort_type == GTK_SORT_ASCENDING) { | set_new_button_to(NEW_FLAG); | |||
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_DESCENDING); | } | |||
} | } else if (record_changed == UNDELETE_FLAG) { | |||
else { | jp_logf(JP_LOG_INFO | JP_LOG_GUI, | |||
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING); | _("This record is deleted.\n" | |||
} | "Undelete it or copy it to make changes.\n")); | |||
} | } | |||
else /* Always sort in ascending order when changing sort column */ | } | |||
{ | ||||
gtk_clist_set_sort_type(GTK_CLIST (clist), GTK_SORT_ASCENDING); | static void connect_changed_signals(int con_or_dis) { | |||
} | static int connected = 0; | |||
clist_col_selected = column; | /* CONNECT */ | |||
if ((con_or_dis == CONNECT_SIGNALS) && (!connected)) { | ||||
gtk_clist_set_sort_column(GTK_CLIST(clist), column); | jp_logf(JP_LOG_DEBUG, "KeyRing: connect_changed_signals\n"); | |||
switch (column) { | connected = 1; | |||
case KEYR_CHGD_COLUMN: // Last Changed column | ||||
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistKeyrCompareDates); | if(category_menu2){ | |||
break; | g_signal_connect(G_OBJECT(category_menu2),"changed",G_CALLBACK(cb_re | |||
case KEYR_NAME_COLUMN: | cord_changed),NULL); | |||
gtk_clist_set_compare_func(GTK_CLIST(clist),GtkClistKeyrCompareNocase); | } | |||
break; | ||||
default: // All other columns can use GTK default sort function | g_signal_connect(G_OBJECT(entry_name), "changed", | |||
gtk_clist_set_compare_func(GTK_CLIST(clist),NULL); | G_CALLBACK(cb_record_changed), NULL); | |||
break; | g_signal_connect(G_OBJECT(entry_account), "changed", | |||
} | G_CALLBACK(cb_record_changed), NULL); | |||
g_signal_connect(G_OBJECT(entry_password), "changed", | ||||
gtk_clist_sort(GTK_CLIST(clist)); | G_CALLBACK(cb_record_changed), | |||
GINT_TO_POINTER(PASSWD_FLAG)); | ||||
/* return to previously selected record */ | g_signal_connect(G_OBJECT(date_button), "pressed", | |||
keyring_find(unique_id); | G_CALLBACK(cb_record_changed), NULL); | |||
} | g_signal_connect(keyr_note_buffer, "changed", | |||
G_CALLBACK(cb_record_changed), NULL); | ||||
static void cb_record_changed(GtkWidget *widget, gpointer data) | } | |||
{ | ||||
int flag; | /* DISCONNECT */ | |||
struct tm *now; | if ((con_or_dis == DISCONNECT_SIGNALS) && (connected)) { | |||
time_t ltime; | jp_logf(JP_LOG_DEBUG, "KeyRing: disconnect_changed_signals\n"); | |||
connected = 0; | ||||
jp_logf(JP_LOG_DEBUG, "cb_record_changed\n"); | ||||
if(category_menu2) { | ||||
flag = GPOINTER_TO_INT(data); | g_signal_handlers_disconnect_by_func(G_OBJECT(category_menu2), G_CAL | |||
LBACK(cb_record_changed), NULL); | ||||
if (record_changed==CLEAR_FLAG) { | } | |||
connect_changed_signals(DISCONNECT_SIGNALS); | ||||
if ((GTK_CLIST(clist)->rows > 0)) { | g_signal_handlers_disconnect_by_func(G_OBJECT(entry_name), | |||
set_new_button_to(MODIFY_FLAG); | G_CALLBACK(cb_record_changed), NULL); | |||
/* Update the lastChanged field when password is modified */ | g_signal_handlers_disconnect_by_func(G_OBJECT(entry_account), | |||
if (flag == PASSWD_FLAG) | G_CALLBACK(cb_record_changed), NULL); | |||
{ | g_signal_handlers_disconnect_by_func(G_OBJECT(entry_password), | |||
time(<ime); | G_CALLBACK(cb_record_changed), | |||
now = localtime(<ime); | GINT_TO_POINTER(PASSWD_FLAG)); | |||
memcpy(&glob_date, now, sizeof(struct tm)); | g_signal_handlers_disconnect_by_func(G_OBJECT(date_button), | |||
update_date_button(date_button, &glob_date); | G_CALLBACK(cb_record_changed), NULL); | |||
} | g_signal_handlers_disconnect_by_func(keyr_note_buffer, | |||
} else { | G_CALLBACK(cb_record_changed), NULL | |||
set_new_button_to(NEW_FLAG); | ); | |||
} | } | |||
} | } | |||
else if (record_changed==UNDELETE_FLAG) | ||||
{ | static void free_mykeyring_list(struct MyKeyRing **PPmkr) { | |||
jp_logf(JP_LOG_INFO|JP_LOG_GUI, | struct MyKeyRing *mkr, *next_mkr; | |||
_("This record is deleted.\n" | ||||
"Undelete it or copy it to make changes.\n")); | jp_logf(JP_LOG_DEBUG, "KeyRing: free_mykeyring_list\n"); | |||
} | for (mkr = *PPmkr; mkr; mkr = next_mkr) { | |||
} | if (mkr->kr.name) free(mkr->kr.name); | |||
if (mkr->kr.account) free(mkr->kr.account); | ||||
static void connect_changed_signals(int con_or_dis) | if (mkr->kr.password) free(mkr->kr.password); | |||
{ | if (mkr->kr.note) free(mkr->kr.note); | |||
int i; | next_mkr = mkr->next; | |||
static int connected=0; | free(mkr); | |||
} | ||||
/* CONNECT */ | *PPmkr = NULL; | |||
if ((con_or_dis==CONNECT_SIGNALS) && (!connected)) { | } | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: connect_changed_signals\n"); | ||||
connected=1; | gboolean deleteKeyRingRecord(GtkTreeModel *model, | |||
GtkTreePath *path, | ||||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | GtkTreeIter *iter, | |||
if (keyr_cat_menu_item2[i] != NULL) { | gpointer data) { | |||
gtk_signal_connect(GTK_OBJECT(keyr_cat_menu_item2[i]), | int *i = gtk_tree_path_get_indices(path); | |||
"toggled", | if (i[0] == row_selected) { | |||
GTK_SIGNAL_FUNC(cb_record_changed), | struct MyKeyRing *mkr = NULL; | |||
NULL); | gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1); | |||
} | deleteKeyRing(mkr, data); | |||
} | return TRUE; | |||
} | ||||
gtk_signal_connect(GTK_OBJECT(entry_name), "changed", | ||||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | return FALSE; | |||
gtk_signal_connect(GTK_OBJECT(entry_account), "changed", | ||||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | } | |||
gtk_signal_connect(GTK_OBJECT(entry_password), "changed", | ||||
GTK_SIGNAL_FUNC(cb_record_changed), | gboolean undeleteKeyRingRecord(GtkTreeModel *model, | |||
GINT_TO_POINTER(PASSWD_FLAG)); | GtkTreePath *path, | |||
gtk_signal_connect(GTK_OBJECT(date_button), "pressed", | GtkTreeIter *iter, | |||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | gpointer data) { | |||
g_signal_connect(keyr_note_buffer, "changed", | int *i = gtk_tree_path_get_indices(path); | |||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | if (i[0] == row_selected) { | |||
} | struct MyKeyRing *mkr = NULL; | |||
gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1); | ||||
/* DISCONNECT */ | undeleteKeyRing(mkr, data); | |||
if ((con_or_dis==DISCONNECT_SIGNALS) && (connected)) { | return TRUE; | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: disconnect_changed_signals\n"); | } | |||
connected=0; | ||||
return FALSE; | ||||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | ||||
if (keyr_cat_menu_item2[i]) { | } | |||
gtk_signal_disconnect_by_func(GTK_OBJECT(keyr_cat_menu_item2[i]), | ||||
GTK_SIGNAL_FUNC(cb_record_changed), | void undeleteKeyRing(struct MyKeyRing *mkr, gpointer data) { | |||
NULL); | ||||
} | buf_rec br; | |||
} | char buf[0xFFFF]; | |||
int new_size; | ||||
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_name), | int flag; | |||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | if (mkr == NULL) { | |||
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_account), | return; | |||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | } | |||
gtk_signal_disconnect_by_func(GTK_OBJECT(entry_password), | ||||
GTK_SIGNAL_FUNC(cb_record_changed), | jp_logf(JP_LOG_DEBUG, "mkr->unique_id = %d\n", mkr->unique_id); | |||
GINT_TO_POINTER(PASSWD_FLAG)); | jp_logf(JP_LOG_DEBUG, "mkr->rt = %d\n", mkr->rt); | |||
gtk_signal_disconnect_by_func(GTK_OBJECT(date_button), | ||||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | pack_KeyRing(&(mkr->kr), (unsigned char *) buf, 0xFFFF, &new_size); | |||
g_signal_handlers_disconnect_by_func(keyr_note_buffer, | ||||
GTK_SIGNAL_FUNC(cb_record_changed), NULL); | br.rt = mkr->rt; | |||
} | br.unique_id = mkr->unique_id; | |||
} | br.attrib = mkr->attrib; | |||
br.buf = buf; | ||||
static void free_mykeyring_list(struct MyKeyRing **PPmkr) | br.size = new_size; | |||
{ | ||||
struct MyKeyRing *mkr, *next_mkr; | flag = GPOINTER_TO_INT(data); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: free_mykeyring_list\n"); | if (flag == UNDELETE_FLAG) { | |||
for (mkr = *PPmkr; mkr; mkr=next_mkr) { | if (mkr->rt == DELETED_PALM_REC || | |||
if (mkr->kr.name) free(mkr->kr.name); | mkr->rt == DELETED_PC_REC) { | |||
if (mkr->kr.account) free(mkr->kr.account); | jp_undelete_record("Keys-Gtkr", &br, flag); | |||
if (mkr->kr.password) free(mkr->kr.password); | } | |||
if (mkr->kr.note) free(mkr->kr.note); | /* Possible later addition of undelete for modified records | |||
next_mkr = mkr->next; | else if (mmemo->rt == MODIFIED_PALM_REC) | |||
free(mkr); | { | |||
} | cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG)); | |||
*PPmkr=NULL; | } | |||
*/ | ||||
} | ||||
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE); | ||||
} | ||||
void deleteKeyRing(struct MyKeyRing *mkr, gpointer data) { | ||||
struct KeyRing kr; | ||||
int new_size; | ||||
char buf[0xFFFF]; | ||||
buf_rec br; | ||||
int flag; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_delete_keyring\n"); | ||||
if (!mkr) { | ||||
return; | ||||
} | ||||
/* The record that we want to delete should be written to the pc file | ||||
* so that it can be deleted at sync time. We need the original record | ||||
* so that if it has changed on the pilot we can warn the user that | ||||
* the record has changed on the pilot. */ | ||||
kr = mkr->kr; | ||||
kr.name = strdup(kr.name); | ||||
jp_charset_j2p(kr.name, strlen(kr.name) + 1); | ||||
kr.account = strdup(kr.account); | ||||
jp_charset_j2p(kr.account, strlen(kr.account) + 1); | ||||
kr.password = strdup(kr.password); | ||||
jp_charset_j2p(kr.password, strlen(kr.password) + 1); | ||||
kr.note = strdup(kr.note); | ||||
jp_charset_j2p(kr.note, strlen(kr.note) + 1); | ||||
pack_KeyRing(&kr, (unsigned char *) buf, 0xFFFF, &new_size); | ||||
free(kr.name); | ||||
free(kr.account); | ||||
free(kr.password); | ||||
free(kr.note); | ||||
br.rt = mkr->rt; | ||||
br.unique_id = mkr->unique_id; | ||||
br.attrib = mkr->attrib; | ||||
br.buf = buf; | ||||
br.size = new_size; | ||||
flag = GPOINTER_TO_INT(data); | ||||
if ((flag == MODIFY_FLAG) || (flag == DELETE_FLAG)) { | ||||
jp_delete_record("Keys-Gtkr", &br, flag); | ||||
if (flag == DELETE_FLAG) { | ||||
/* when we redraw we want to go to the line above the deleted one */ | ||||
if (row_selected > 0) { | ||||
row_selected--; | ||||
} | ||||
} | ||||
} | ||||
if (flag == DELETE_FLAG) { | ||||
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE | ||||
); | ||||
} | ||||
} | } | |||
/* This function gets called when the "delete" button is pressed */ | /* This function gets called when the "delete" button is pressed */ | |||
static void cb_delete_keyring(GtkWidget *widget, gpointer data) | static void cb_delete_keyring(GtkWidget *widget, gpointer data) { | |||
{ | gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), deleteKeyRingRecord, data) | |||
struct MyKeyRing *mkr; | ; | |||
struct KeyRing kr; | } | |||
int new_size; | ||||
char buf[0xFFFF]; | static void cb_undelete_keyring(GtkWidget *widget, gpointer data) { | |||
buf_rec br; | gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), undeleteKeyRingRecord, dat | |||
int flag; | a); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_delete_keyring\n"); | } | |||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); | static void cb_cancel(GtkWidget *widget, gpointer data) { | |||
if (!mkr) { | set_new_button_to(CLEAR_FLAG); | |||
return; | keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE); | |||
} | } | |||
/* The record that we want to delete should be written to the pc file | static void update_date_button(GtkWidget *button, struct tm *t) { | |||
* so that it can be deleted at sync time. We need the original record | const char *short_date; | |||
* so that if it has changed on the pilot we can warn the user that | char str[255]; | |||
* the record has changed on the pilot. */ | ||||
kr = mkr->kr; | ||||
kr.name = strdup(kr.name); | ||||
jp_charset_j2p(kr.name, strlen(kr.name)+1); | ||||
kr.account = strdup(kr.account); | ||||
jp_charset_j2p(kr.account, strlen(kr.account)+1); | ||||
kr.password = strdup(kr.password); | ||||
jp_charset_j2p(kr.password, strlen(kr.password)+1); | ||||
kr.note = strdup(kr.note); | ||||
jp_charset_j2p(kr.note, strlen(kr.note)+1); | ||||
pack_KeyRing(&kr, (unsigned char *)buf, 0xFFFF, &new_size); | ||||
free(kr.name); | ||||
free(kr.account); | ||||
free(kr.password); | ||||
free(kr.note); | ||||
br.rt = mkr->rt; | ||||
br.unique_id = mkr->unique_id; | ||||
br.attrib = mkr->attrib; | ||||
br.buf = buf; | ||||
br.size = new_size; | ||||
flag = GPOINTER_TO_INT(data); | ||||
if ((flag==MODIFY_FLAG) || (flag==DELETE_FLAG)) { | ||||
jp_delete_record("Keys-Gtkr", &br, flag); | ||||
if (flag==DELETE_FLAG) { | ||||
/* when we redraw we want to go to the line above the deleted one */ | ||||
if (clist_row_selected>0) { | ||||
clist_row_selected--; | ||||
} | ||||
} | ||||
} | ||||
if (flag == DELETE_FLAG) { | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | ||||
} | ||||
} | ||||
static void cb_undelete_keyring(GtkWidget *widget, gpointer data) | ||||
{ | ||||
struct MyKeyRing *mkr; | ||||
buf_rec br; | ||||
char buf[0xFFFF]; | ||||
int new_size; | ||||
int flag; | ||||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); | ||||
if (mkr==NULL) { | ||||
return; | ||||
} | ||||
jp_logf(JP_LOG_DEBUG, "mkr->unique_id = %d\n",mkr->unique_id); | ||||
jp_logf(JP_LOG_DEBUG, "mkr->rt = %d\n",mkr->rt); | ||||
pack_KeyRing(&(mkr->kr), (unsigned char *)buf, 0xFFFF, &new_size); | ||||
br.rt = mkr->rt; | ||||
br.unique_id = mkr->unique_id; | ||||
br.attrib = mkr->attrib; | ||||
br.buf = buf; | ||||
br.size = new_size; | ||||
flag = GPOINTER_TO_INT(data); | ||||
if (flag==UNDELETE_FLAG) { | ||||
if (mkr->rt == DELETED_PALM_REC || | ||||
mkr->rt == DELETED_PC_REC) | ||||
{ | ||||
jp_undelete_record("Keys-Gtkr", &br, flag); | ||||
} | ||||
/* Possible later addition of undelete for modified records | ||||
else if (mmemo->rt == MODIFIED_PALM_REC) | ||||
{ | ||||
cb_add_new_record(widget, GINT_TO_POINTER(COPY_FLAG)); | ||||
} | ||||
*/ | ||||
} | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | ||||
} | ||||
static void cb_cancel(GtkWidget *widget, gpointer data) | ||||
{ | ||||
set_new_button_to(CLEAR_FLAG); | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | ||||
} | ||||
static void update_date_button(GtkWidget *button, struct tm *t) | ||||
{ | ||||
const char *short_date; | ||||
char str[255]; | ||||
get_pref(PREF_SHORTDATE, NULL, &short_date); | get_pref(PREF_SHORTDATE, NULL, &short_date); | |||
strftime(str, sizeof(str), short_date, t); | strftime(str, sizeof(str), short_date, t); | |||
gtk_label_set_text(GTK_LABEL(GTK_BIN(button)->child), str); | gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(button))), str); | |||
} | } | |||
/* | /* | |||
* This is called when the "New" button is pressed. | * This is called when the "New" button is pressed. | |||
* It clears out all the detail fields on the right-hand side. | * It clears out all the detail fields on the right-hand side. | |||
*/ | */ | |||
static int keyr_clear_details(void) | static int keyr_clear_details(void) { | |||
{ | struct tm *now; | |||
struct tm *now; | time_t ltime; | |||
time_t ltime; | int new_cat; | |||
int new_cat; | int sorted_position; | |||
int sorted_position; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clear\n"); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clear\n"); | ||||
connect_changed_signals(DISCONNECT_SIGNALS); | ||||
connect_changed_signals(DISCONNECT_SIGNALS); | GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW( | |||
treeView)); | ||||
/* Put the current time in the lastChanged part of the record */ | ||||
time(<ime); | gtk_tree_selection_set_select_function(treeSelection, NULL, NULL, NULL); | |||
now = localtime(<ime); | ||||
memcpy(&glob_date, now, sizeof(struct tm)); | gtk_list_store_clear(listStore); | |||
update_date_button(date_button, &glob_date); | gtk_tree_selection_set_select_function(treeSelection, handleKeyringRowSelect | |||
ion, NULL, NULL); | ||||
gtk_entry_set_text(GTK_ENTRY(entry_name), ""); | /* Put the current time in the lastChanged part of the record */ | |||
gtk_entry_set_text(GTK_ENTRY(entry_account), ""); | time(<ime); | |||
gtk_entry_set_text(GTK_ENTRY(entry_password), ""); | now = localtime(<ime); | |||
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1); | memcpy(&glob_date, now, sizeof(struct tm)); | |||
if (keyr_category==CATEGORY_ALL) { | update_date_button(date_button, &glob_date); | |||
new_cat = 0; | ||||
} else { | gtk_entry_set_text(GTK_ENTRY(entry_name), ""); | |||
new_cat = keyr_category; | gtk_entry_set_text(GTK_ENTRY(entry_account), ""); | |||
} | gtk_entry_set_text(GTK_ENTRY(entry_password), ""); | |||
sorted_position = find_sort_cat_pos(new_cat); | gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1); | |||
if (sorted_position<0) { | if (keyr_category == CATEGORY_ALL) { | |||
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | new_cat = 0; | |||
} else { | } else { | |||
gtk_check_menu_item_set_active | new_cat = keyr_category; | |||
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[sorted_position]), TRUE); | } | |||
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2), | sorted_position = find_sort_cat_pos(new_cat); | |||
find_menu_cat_pos(sorted_position)); | if (sorted_position < 0) { | |||
} | jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | |||
} else { | ||||
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2),find_menu_cat_pos | ||||
(sorted_position)); | ||||
} | ||||
set_new_button_to(CLEAR_FLAG); | ||||
connect_changed_signals(CONNECT_SIGNALS); | ||||
return EXIT_SUCCESS; | ||||
} | ||||
set_new_button_to(CLEAR_FLAG); | gboolean addKeyRingRecord(GtkTreeModel *model, | |||
connect_changed_signals(CONNECT_SIGNALS); | GtkTreePath *path, | |||
GtkTreeIter *iter, | ||||
gpointer data) { | ||||
int *i = gtk_tree_path_get_indices(path); | ||||
if (i[0] == row_selected) { | ||||
struct MyKeyRing *mkr = NULL; | ||||
gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1); | ||||
addKeyRing(mkr, data); | ||||
return TRUE; | ||||
} | ||||
return FALSE; | ||||
} | ||||
void addKeyRing(struct MyKeyRing *mkr, gpointer data) { | ||||
struct KeyRing kr; | ||||
buf_rec br; | ||||
unsigned char buf[0x10000]; | ||||
int new_size; | ||||
int flag; | ||||
GtkTextIter start_iter; | ||||
GtkTextIter end_iter; | ||||
unsigned int unique_id; | ||||
unique_id = 0; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_add_new_record\n"); | ||||
flag = GPOINTER_TO_INT(data); | ||||
if (flag == CLEAR_FLAG) { | ||||
keyr_clear_details(); | ||||
connect_changed_signals(DISCONNECT_SIGNALS); | ||||
set_new_button_to(NEW_FLAG); | ||||
gtk_widget_grab_focus(GTK_WIDGET(entry_name)); | ||||
return; | ||||
} | ||||
if ((flag != NEW_FLAG) && (flag != MODIFY_FLAG) && (flag != COPY_FLAG)) { | ||||
return; | ||||
} | ||||
kr.name = (char *) gtk_entry_get_text(GTK_ENTRY(entry_name)); | ||||
kr.account = (char *) gtk_entry_get_text(GTK_ENTRY(entry_account)); | ||||
kr.password = (char *) gtk_entry_get_text(GTK_ENTRY(entry_password)); | ||||
/* Put the glob_date in the lastChanged part of the record */ | ||||
memcpy(&(kr.last_changed), &glob_date, sizeof(struct tm)); | ||||
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(keyr_note_buffer), &start_iter, & | ||||
end_iter); | ||||
kr.note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(keyr_note_buffer), &start | ||||
_iter, &end_iter, TRUE); | ||||
kr.name = strdup(kr.name); | ||||
jp_charset_j2p(kr.name, strlen(kr.name) + 1); | ||||
kr.account = strdup(kr.account); | ||||
jp_charset_j2p(kr.account, strlen(kr.account) + 1); | ||||
kr.password = strdup(kr.password); | ||||
jp_charset_j2p(kr.password, strlen(kr.password) + 1); | ||||
jp_charset_j2p(kr.note, strlen(kr.note) + 1); | ||||
pack_KeyRing(&kr, buf, 0xFFFF, &new_size); | ||||
/* free allocated memory now that kr structure is packed into buf */ | ||||
if (kr.name) free(kr.name); | ||||
if (kr.account) free(kr.account); | ||||
if (kr.password) free(kr.password); | ||||
if (kr.note) free(kr.note); | ||||
/* Any attributes go here. Usually just the category */ | ||||
/* grab category from menu */ | ||||
if (GTK_IS_WIDGET(category_menu2)) { | ||||
br.attrib = get_selected_category_from_combo_box(GTK_COMBO_BOX(category_ | ||||
menu2)); | ||||
} | ||||
jp_logf(JP_LOG_DEBUG, "category is %d\n", br.attrib); | ||||
br.buf = buf; | ||||
br.size = new_size; | ||||
set_new_button_to(CLEAR_FLAG); | ||||
/* Keep unique ID intact */ | ||||
if (flag == MODIFY_FLAG) { | ||||
if (!mkr) { | ||||
return; | ||||
} | ||||
unique_id = mkr->unique_id; | ||||
if ((mkr->rt == DELETED_PALM_REC) || | ||||
(mkr->rt == DELETED_PC_REC) || | ||||
(mkr->rt == MODIFIED_PALM_REC)) { | ||||
jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n" | ||||
)); | ||||
return; | ||||
} | ||||
} | ||||
/* Keep unique ID intact */ | ||||
if (flag == MODIFY_FLAG) { | ||||
cb_delete_keyring(NULL, data); | ||||
if ((mkr->rt == PALM_REC) || (mkr->rt == REPLACEMENT_PALM_REC)) { | ||||
br.unique_id = unique_id; | ||||
br.rt = REPLACEMENT_PALM_REC; | ||||
} else { | ||||
br.unique_id = 0; | ||||
br.rt = NEW_PC_REC; | ||||
} | ||||
} else { | ||||
br.unique_id = 0; | ||||
br.rt = NEW_PC_REC; | ||||
} | ||||
/* Write out the record. It goes to the .pc3 file until it gets synced */ | ||||
jp_pc_write("Keys-Gtkr", &br); | ||||
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE); | ||||
keyring_find(br.unique_id); | ||||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This function is called when the user presses the "Add" button. | * This function is called when the user presses the "Add" button. | |||
* We collect all of the data from the GUI and pack it into a keyring | * We collect all of the data from the GUI and pack it into a keyring | |||
* record and then write it out. | * record and then write it out. | |||
kr->name=strdup((char *)buf); | kr->name=strdup((char *)buf); | |||
kr->account=strdup((char *)Pstr[0]); | kr->account=strdup((char *)Pstr[0]); | |||
kr->password=strdup((char *)Pstr[1]); | kr->password=strdup((char *)Pstr[1]); | |||
kr->note=strdup((char *)Pstr[2]); | kr->note=strdup((char *)Pstr[2]); | |||
*/ | */ | |||
static void cb_add_new_record(GtkWidget *widget, gpointer data) | static void cb_add_new_record(GtkWidget *widget, gpointer data) { | |||
{ | ||||
struct KeyRing kr; | ||||
buf_rec br; | ||||
unsigned char buf[0x10000]; | ||||
int new_size; | ||||
int flag; | ||||
struct MyKeyRing *mkr; | ||||
GtkTextIter start_iter; | ||||
GtkTextIter end_iter; | ||||
int i; | ||||
unsigned int unique_id; | ||||
mkr = NULL; | ||||
unique_id=0; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_add_new_record\n"); | ||||
flag=GPOINTER_TO_INT(data); | ||||
if (flag==CLEAR_FLAG) { | ||||
keyr_clear_details(); | ||||
connect_changed_signals(DISCONNECT_SIGNALS); | ||||
set_new_button_to(NEW_FLAG); | ||||
gtk_widget_grab_focus(GTK_WIDGET(entry_name)); | ||||
return; | ||||
} | ||||
if ((flag!=NEW_FLAG) && (flag!=MODIFY_FLAG) && (flag!=COPY_FLAG)) { | ||||
return; | ||||
} | ||||
kr.name = (char *)gtk_entry_get_text(GTK_ENTRY(entry_name)); | ||||
kr.account = (char *)gtk_entry_get_text(GTK_ENTRY(entry_account)); | ||||
kr.password = (char *)gtk_entry_get_text(GTK_ENTRY(entry_password)); | ||||
/* Put the glob_date in the lastChanged part of the record */ | ||||
memcpy(&(kr.last_changed), &glob_date, sizeof(struct tm)); | ||||
gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(keyr_note_buffer),&start_iter,&end | ||||
_iter); | ||||
kr.note = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(keyr_note_buffer),&start_i | ||||
ter,&end_iter,TRUE); | ||||
kr.name = strdup(kr.name); | ||||
jp_charset_j2p(kr.name, strlen(kr.name)+1); | ||||
kr.account = strdup(kr.account); | ||||
jp_charset_j2p(kr.account, strlen(kr.account)+1); | ||||
kr.password = strdup(kr.password); | ||||
jp_charset_j2p(kr.password, strlen(kr.password)+1); | ||||
jp_charset_j2p(kr.note, strlen(kr.note)+1); | ||||
pack_KeyRing(&kr, buf, 0xFFFF, &new_size); | ||||
/* free allocated memory now that kr structure is packed into buf */ | ||||
if (kr.name) free(kr.name); | ||||
if (kr.account) free(kr.account); | ||||
if (kr.password) free(kr.password); | ||||
if (kr.note) free(kr.note); | ||||
/* Any attributes go here. Usually just the category */ | ||||
/* grab category from menu */ | ||||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | ||||
if (GTK_IS_WIDGET(keyr_cat_menu_item2[i])) { | ||||
if (GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[i])->active) { | ||||
br.attrib = sort_l[i].cat_num; | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
jp_logf(JP_LOG_DEBUG, "category is %d\n", br.attrib); | ||||
br.buf = buf; | ||||
br.size = new_size; | ||||
set_new_button_to(CLEAR_FLAG); | ||||
/* Keep unique ID intact */ | ||||
if (flag==MODIFY_FLAG) { | ||||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), clist_row_selected); | ||||
if (!mkr) { | ||||
return; | ||||
} | ||||
unique_id = mkr->unique_id; | ||||
if ((mkr->rt==DELETED_PALM_REC) || | ||||
(mkr->rt==DELETED_PC_REC) || | ||||
(mkr->rt==MODIFIED_PALM_REC)) { | ||||
jp_logf(JP_LOG_INFO, _("You can't modify a record that is deleted\n")); | ||||
return; | ||||
} | ||||
} | ||||
/* Keep unique ID intact */ | ||||
if (flag==MODIFY_FLAG) { | ||||
cb_delete_keyring(NULL, data); | ||||
if ((mkr->rt==PALM_REC) || (mkr->rt==REPLACEMENT_PALM_REC)) { | ||||
br.unique_id = unique_id; | ||||
br.rt = REPLACEMENT_PALM_REC; | ||||
} else { | ||||
br.unique_id = 0; | ||||
br.rt = NEW_PC_REC; | ||||
} | ||||
} else { | ||||
br.unique_id = 0; | ||||
br.rt = NEW_PC_REC; | ||||
} | ||||
/* Write out the record. It goes to the .pc3 file until it gets synced */ | ||||
jp_pc_write("Keys-Gtkr", &br); | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | ||||
keyring_find(br.unique_id); | ||||
return; | ||||
} | ||||
static void cb_date_button(GtkWidget *widget, gpointer data) | ||||
{ | ||||
long fdow; | ||||
int ret; | ||||
struct tm temp_glob_date = glob_date; | ||||
get_pref(PREF_FDOW, &fdow, NULL); | ||||
/* date is not set */ | ||||
if (glob_date.tm_mon < 0) | ||||
{ | ||||
/* use today date */ | ||||
time_t t = time(NULL); | ||||
glob_date = *localtime(&t); | ||||
} | ||||
ret = jp_cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), "", fdow, | ||||
&(glob_date.tm_mon), | ||||
&(glob_date.tm_mday), | ||||
&(glob_date.tm_year)); | ||||
if (ret == CAL_DONE) | ||||
update_date_button(date_button, &glob_date); | ||||
else | ||||
glob_date = temp_glob_date; | ||||
} | ||||
/* First pass at password generating code */ | ||||
static void cb_gen_password(GtkWidget *widget, gpointer data) | ||||
{ | ||||
GtkWidget *entry; | ||||
int i, | ||||
length, | ||||
alpha_size, | ||||
numer_size; | ||||
char alpha[] = "abcdfghjklmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||||
char numer[] = "1234567890"; | ||||
char passwd[MAX_KR_PASS + 1]; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_gen_password\n"); | if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStore), NULL) != 0) { | |||
gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), addKeyRingRecord, data | ||||
); | ||||
} else { | ||||
//no records exist in category yet. | ||||
addKeyRing(NULL, data); | ||||
} | ||||
entry=data; | } | |||
srand(time(NULL) * getpid()); | static void cb_date_button(GtkWidget *widget, gpointer data) { | |||
alpha_size = strlen(alpha); | long fdow; | |||
numer_size = strlen(numer); | int ret; | |||
struct tm temp_glob_date = glob_date; | ||||
get_pref(PREF_FDOW, &fdow, NULL); | ||||
/* date is not set */ | ||||
if (glob_date.tm_mon < 0) { | ||||
/* use today date */ | ||||
time_t t = time(NULL); | ||||
glob_date = *localtime(&t); | ||||
} | ||||
length = rand() % (MAX_KR_PASS - MIN_KR_PASS) + MIN_KR_PASS; | ret = jp_cal_dialog(GTK_WINDOW(gtk_widget_get_toplevel(widget)), "", fdow, | |||
&(glob_date.tm_mon), | ||||
&(glob_date.tm_mday), | ||||
&(glob_date.tm_year)); | ||||
if (ret == CAL_DONE) | ||||
update_date_button(date_button, &glob_date); | ||||
else | ||||
glob_date = temp_glob_date; | ||||
} | ||||
for (i = 0; i < length; i++) { | /* First pass at password generating code */ | |||
if ((i % 2) == 0) { | static void cb_gen_password(GtkWidget *widget, gpointer data) { | |||
passwd[i] = alpha[rand() % alpha_size]; | GtkWidget *entry; | |||
} else { | int i, | |||
passwd[i] = numer[rand() % numer_size]; | length, | |||
} | alpha_size, | |||
} | numer_size; | |||
char alpha[] = "abcdfghjklmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||||
char numer[] = "1234567890"; | ||||
char passwd[MAX_KR_PASS + 1]; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_gen_password\n"); | ||||
entry = data; | ||||
srand(time(NULL) * getpid()); | ||||
alpha_size = strlen(alpha); | ||||
numer_size = strlen(numer); | ||||
length = rand() % (MAX_KR_PASS - MIN_KR_PASS) + MIN_KR_PASS; | ||||
for (i = 0; i < length; i++) { | ||||
if ((i % 2) == 0) { | ||||
passwd[i] = alpha[rand() % alpha_size]; | ||||
} else { | ||||
passwd[i] = numer[rand() % numer_size]; | ||||
} | ||||
} | ||||
passwd[length] = '\0'; | passwd[length] = '\0'; | |||
gtk_entry_set_text(GTK_ENTRY(entry), passwd); | gtk_entry_set_text(GTK_ENTRY(entry), passwd); | |||
return; | return; | |||
} | } | |||
/* | /* | |||
* This function just adds the record to the clist on the left side of | * This function just adds the record to the treeView on the left side of | |||
* the screen. | * the screen. | |||
*/ | */ | |||
static int display_record(struct MyKeyRing *mkr, int row) | static int display_record(struct MyKeyRing *mkr, int row, GtkTreeIter *iter) { | |||
{ | char temp[8]; | |||
char temp[8]; | char *nameTxt; | |||
const char *svalue; | char *accountTxt; | |||
char str[50]; | const char *svalue; | |||
char changedTxt[50]; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record\n"); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record\n"); | ||||
/* Highlight row background depending on status */ | ||||
switch (mkr->rt) { | /* Highlight row background depending on status */ | |||
case NEW_PC_REC: | GdkRGBA bgColor; | |||
case REPLACEMENT_PALM_REC: | gboolean showBgColor; | |||
set_bg_rgb_clist_row(clist, row, | switch (mkr->rt) { | |||
CLIST_NEW_RED, CLIST_NEW_GREEN, CLIST_NEW_BLUE); | case NEW_PC_REC: | |||
case REPLACEMENT_PALM_REC: | ||||
break; | bgColor = get_color(LIST_NEW_RED, LIST_NEW_GREEN, LIST_NEW_BLUE); | |||
case DELETED_PALM_REC: | showBgColor = TRUE; | |||
case DELETED_PC_REC: | break; | |||
set_bg_rgb_clist_row(clist, row, | case DELETED_PALM_REC: | |||
CLIST_DEL_RED, CLIST_DEL_GREEN, CLIST_DEL_BLUE); | case DELETED_PC_REC: | |||
break; | bgColor = get_color(LIST_DEL_RED, LIST_DEL_GREEN, LIST_DEL_BLUE); | |||
case MODIFIED_PALM_REC: | showBgColor = TRUE; | |||
set_bg_rgb_clist_row(clist, row, | break; | |||
CLIST_MOD_RED, CLIST_MOD_GREEN, CLIST_MOD_BLUE); | case MODIFIED_PALM_REC: | |||
break; | bgColor = get_color(LIST_MOD_RED, LIST_MOD_GREEN, LIST_MOD_BLUE); | |||
default: | showBgColor = TRUE; | |||
gtk_clist_set_row_style(GTK_CLIST(clist), row, NULL); | break; | |||
} | default: | |||
showBgColor = FALSE; | ||||
gtk_clist_set_row_data(GTK_CLIST(clist), row, mkr); | } | |||
if (mkr->kr.last_changed.tm_year==0) { | if (mkr->kr.last_changed.tm_year == 0) { | |||
sprintf(str, _("No date")); | sprintf(changedTxt, _("No date")); | |||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_CHGD_COLUMN, str); | } else { | |||
} else { | get_pref(PREF_SHORTDATE, NULL, &svalue); | |||
get_pref(PREF_SHORTDATE, NULL, &svalue); | strftime(changedTxt, sizeof(changedTxt), svalue, &(mkr->kr.last_changed) | |||
strftime(str, sizeof(str), svalue, &(mkr->kr.last_changed)); | ); | |||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_CHGD_COLUMN, str); | } | |||
} | ||||
if ((!(mkr->kr.name)) || (mkr->kr.name[0] == '\0')) { | ||||
if ( (!(mkr->kr.name)) || (mkr->kr.name[0]=='\0') ) { | sprintf(temp, "#%03d", row); | |||
sprintf(temp, "#%03d", row); | nameTxt = temp; | |||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_NAME_COLUMN, temp); | } else { | |||
} else { | nameTxt = mkr->kr.name; | |||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_NAME_COLUMN, mkr->kr.name); | } | |||
} | ||||
if ( (!(mkr->kr.account)) || (mkr->kr.account[0]=='\0') ) { | ||||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_ACCT_COLUMN, ""); | ||||
} else { | ||||
gtk_clist_set_text(GTK_CLIST(clist), row, KEYR_ACCT_COLUMN, mkr->kr.accoun | ||||
t); | ||||
} | ||||
return EXIT_SUCCESS; | ||||
} | ||||
static int display_record_export(GtkWidget *clist, struct MyKeyRing *mkr, int ro | ||||
w) | ||||
{ | ||||
char temp[8]; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record_export\n"); | ||||
gtk_clist_set_row_data(GTK_CLIST(clist), row, mkr); | ||||
if ( (!(mkr->kr.name)) || (mkr->kr.name[0]=='\0') ) { | ||||
sprintf(temp, "#%03d", row); | ||||
gtk_clist_set_text(GTK_CLIST(clist), row, 0, temp); | ||||
} else { | ||||
gtk_clist_set_text(GTK_CLIST(clist), row, 0, mkr->kr.name); | ||||
} | ||||
return EXIT_SUCCESS; | if ((!(mkr->kr.account)) || (mkr->kr.account[0] == '\0')) { | |||
accountTxt = ""; | ||||
} else { | ||||
accountTxt = mkr->kr.account; | ||||
} | ||||
gtk_list_store_append(listStore, iter); | ||||
gtk_list_store_set(listStore, iter, | ||||
KEYRING_CHANGED_COLUMN_ENUM, changedTxt, | ||||
KEYRING_NAME_COLUMN_ENUM, nameTxt, | ||||
KEYRING_ACCOUNT_COLUMN_ENUM, accountTxt, | ||||
KEYRING_DATA_COLUMN_ENUM, mkr, | ||||
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, showBgColor, | ||||
KEYRING_BACKGROUND_COLOR_ENUM, showBgColor ? &bgColor : N | ||||
ULL, -1); | ||||
return EXIT_SUCCESS; | ||||
} | ||||
static int | ||||
display_record_export(GtkListStore *pListStore, struct MyKeyRing *mkr, int row, | ||||
GtkTreeIter *iter) { | ||||
char temp[8]; | ||||
char *nameTxt; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: display_record_export\n"); | ||||
if ((!(mkr->kr.name)) || (mkr->kr.name[0] == '\0')) { | ||||
sprintf(temp, "#%03d", row); | ||||
nameTxt = temp; | ||||
} else { | ||||
nameTxt = mkr->kr.name; | ||||
} | ||||
//KEYRING_CHANGED_COLUMN_ENUM | ||||
gtk_list_store_append(pListStore, iter); | ||||
gtk_list_store_set(pListStore, iter, | ||||
KEYRING_CHANGED_COLUMN_ENUM, nameTxt, | ||||
KEYRING_DATA_COLUMN_ENUM, mkr, -1); | ||||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | void keyr_update_liststore(GtkListStore *pListStore, struct MyKeyRing **keyring_ | |||
* This function lists the records in the clist on the left side of | list, | |||
* the screen. | int category, int main) { | |||
*/ | GtkTreeIter iter; | |||
static void keyr_update_clist(GtkWidget *clist, struct MyKeyRing **keyring_list, | int entries_shown; | |||
int category, int main) | struct MyKeyRing *temp_list; | |||
{ | ||||
int entries_shown; | jp_logf(JP_LOG_DEBUG, "KeyRing: keyr_update_liststore\n"); | |||
struct MyKeyRing *temp_list; | ||||
gchar *empty_line[] = { "", "", "" }; | free_mykeyring_list(keyring_list); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: keyr_update_clist\n"); | /* This function takes care of reading the database for us */ | |||
get_keyring(keyring_list, category); | ||||
free_mykeyring_list(keyring_list); | ||||
if (main) { | ||||
/* This function takes care of reading the database for us */ | keyr_clear_details(); | |||
get_keyring(keyring_list, category); | } | |||
if (main) { | entries_shown = 0; | |||
keyr_clear_details(); | ||||
} | for (temp_list = *keyring_list; temp_list; temp_list = temp_list->next) { | |||
/* Freeze clist to prevent flicker during updating */ | if (main) { | |||
gtk_clist_freeze(GTK_CLIST(clist)); | display_record(temp_list, entries_shown, &iter); | |||
if (main) { | } else { | |||
gtk_signal_disconnect_by_func(GTK_OBJECT(clist), | display_record_export(pListStore, temp_list, entries_shown, &iter); | |||
GTK_SIGNAL_FUNC(cb_clist_selection), NULL); | } | |||
} | entries_shown++; | |||
clist_clear(GTK_CLIST(clist)); | } | |||
#ifdef __APPLE__ | jp_logf(JP_LOG_DEBUG, "KeyRing: leave keyr_update_liststore\n"); | |||
gtk_clist_thaw(GTK_CLIST(clist)); | } | |||
gtk_widget_hide(clist); | ||||
gtk_widget_show_all(clist); | static gboolean handleKeyringRowSelection(GtkTreeSelection *selection, | |||
gtk_clist_freeze(GTK_CLIST(clist)); | GtkTreeModel *model, | |||
#endif | GtkTreePath *path, | |||
gboolean path_currently_selected, | ||||
entries_shown=0; | gpointer userdata) { | |||
GtkTreeIter iter; | ||||
for (temp_list = *keyring_list; temp_list; temp_list = temp_list->next) { | struct MyKeyRing *mkr; | |||
gtk_clist_append(GTK_CLIST(clist), empty_line); | int index, sorted_position; | |||
if (main) | int b; | |||
display_record(temp_list, entries_shown); | unsigned int unique_id = 0; | |||
else | ||||
display_record_export(clist, temp_list, entries_shown); | jp_logf(JP_LOG_DEBUG, "KeyRing: handleKeyringRowSelection\n"); | |||
entries_shown++; | if ((gtk_tree_model_get_iter(model, &iter, path)) && (!path_currently_select | |||
} | ed)) { | |||
int *i = gtk_tree_path_get_indices(path); | ||||
/* Sort the clist */ | row_selected = i[0]; | |||
gtk_clist_sort(GTK_CLIST(clist)); | gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1); | |||
if ((record_changed == MODIFY_FLAG) || (record_changed == NEW_FLAG)) { | ||||
if (main) | ||||
gtk_signal_connect(GTK_OBJECT(clist), "select_row", | if (mkr != NULL) { | |||
GTK_SIGNAL_FUNC(cb_clist_selection), NULL); | unique_id = mkr->unique_id; | |||
} | ||||
/* If there are items in the list, highlight the selected row */ | ||||
if ((main) && (entries_shown>0)) { | // We need to turn this "scroll with mouse held down" thing off | |||
/* Select the existing requested row, or row 0 if that is impossible */ | button_set_for_motion(0); | |||
if (clist_row_selected <= entries_shown) { | ||||
clist_select_row(GTK_CLIST(clist), clist_row_selected, 0); | b = dialog_save_changed_record_with_cancel(pane, record_changed); | |||
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), clist_row_selected)) { | if (b == DIALOG_SAID_1) { /* Cancel */ | |||
gtk_clist_moveto(GTK_CLIST(clist), clist_row_selected, 0, 0.5, 0.0); | return TRUE; | |||
} | } | |||
} | if (b == DIALOG_SAID_3) { /* Save */ | |||
else | cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | |||
{ | } | |||
clist_select_row(GTK_CLIST(clist), 0, 0); | ||||
} | set_new_button_to(CLEAR_FLAG); | |||
} | ||||
if (unique_id) { | ||||
/* Unfreeze clist after all changes */ | keyring_find(unique_id); | |||
gtk_clist_thaw(GTK_CLIST(clist)); | } | |||
/* return focus to clist after any big operation which requires a redraw */ | return TRUE; | |||
gtk_widget_grab_focus(GTK_WIDGET(clist)); | } | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: leave keyr_update_clist\n"); | if (mkr == NULL) { | |||
} | return TRUE; | |||
} | ||||
/* | ||||
* This function just displays a record on the right hand side of the screen | if (mkr->rt == DELETED_PALM_REC || | |||
* (the details) | (mkr->rt == DELETED_PC_REC)) | |||
*/ | /* Possible later addition of undelete code for modified deleted rec | |||
static void cb_clist_selection(GtkWidget *clist, | ords | |||
gint row, | || mkr->rt == MODIFIED_PALM_REC | |||
gint column, | */ | |||
GdkEventButton *event, | { | |||
gpointer data) | set_new_button_to(UNDELETE_FLAG); | |||
{ | } else { | |||
struct MyKeyRing *mkr; | set_new_button_to(CLEAR_FLAG); | |||
int index, sorted_position; | } | |||
int b; | ||||
unsigned int unique_id = 0; | connect_changed_signals(DISCONNECT_SIGNALS); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_clist_selection\n"); | index = mkr->attrib & 0x0F; | |||
sorted_position = find_sort_cat_pos(index); | ||||
if ((record_changed==MODIFY_FLAG) || (record_changed==NEW_FLAG)) { | int pos = findSortedPostion(sorted_position, GTK_COMBO_BOX(category_menu | |||
if (clist_row_selected == row) { return; } | 2)); | |||
if (pos != sorted_position && index != 0) { | ||||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), row); | /* Illegal category */ | |||
if (mkr!=NULL) { | jp_logf(JP_LOG_DEBUG, "Category is not legal\n"); | |||
unique_id = mkr->unique_id; | sorted_position = 0; | |||
} | } | |||
b=dialog_save_changed_record_with_cancel(pane, record_changed); | if (sorted_position < 0) { | |||
if (b==DIALOG_SAID_1) { /* Cancel */ | jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | |||
if (clist_row_selected >=0) | } else { | |||
{ | gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu2),find_menu_cat | |||
clist_select_row(GTK_CLIST(clist), clist_row_selected, 0); | _pos(sorted_position)); | |||
} else { | } | |||
clist_row_selected = 0; | ||||
clist_select_row(GTK_CLIST(clist), 0, 0); | if (mkr->kr.name) { | |||
} | gtk_entry_set_text(GTK_ENTRY(entry_name), mkr->kr.name); | |||
return; | } else { | |||
} | gtk_entry_set_text(GTK_ENTRY(entry_name), ""); | |||
if (b==DIALOG_SAID_3) { /* Save */ | } | |||
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | ||||
} | if (mkr->kr.account) { | |||
gtk_entry_set_text(GTK_ENTRY(entry_account), mkr->kr.account); | ||||
set_new_button_to(CLEAR_FLAG); | } else { | |||
gtk_entry_set_text(GTK_ENTRY(entry_account), ""); | ||||
if (unique_id) { | } | |||
keyring_find(unique_id); | ||||
} else { | if (mkr->kr.password) { | |||
clist_select_row(GTK_CLIST(clist), row, column); | gtk_entry_set_text(GTK_ENTRY(entry_password), mkr->kr.password); | |||
} | } else { | |||
gtk_entry_set_text(GTK_ENTRY(entry_password), ""); | ||||
return; | } | |||
} | ||||
memcpy(&glob_date, &(mkr->kr.last_changed), sizeof(struct tm)); | ||||
clist_row_selected = row; | update_date_button(date_button, &(mkr->kr.last_changed)); | |||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), row); | gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1); | |||
if (mkr==NULL) { | if (mkr->kr.note) { | |||
return; | gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), mkr->kr. | |||
} | note, -1); | |||
} | ||||
if (mkr->rt == DELETED_PALM_REC || | ||||
(mkr->rt == DELETED_PC_REC)) | ||||
/* Possible later addition of undelete code for modified deleted records | ||||
|| mkr->rt == MODIFIED_PALM_REC | ||||
*/ | ||||
{ | ||||
set_new_button_to(UNDELETE_FLAG); | ||||
} | ||||
else | ||||
{ | ||||
set_new_button_to(CLEAR_FLAG); | ||||
} | ||||
connect_changed_signals(DISCONNECT_SIGNALS); | ||||
index = mkr->attrib & 0x0F; | ||||
sorted_position = find_sort_cat_pos(index); | ||||
if (keyr_cat_menu_item2[sorted_position]==NULL) { | ||||
/* Illegal category */ | ||||
jp_logf(JP_LOG_DEBUG, "Category is not legal\n"); | ||||
sorted_position = 0; | ||||
} | ||||
if (sorted_position<0) { | ||||
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | ||||
} else { | ||||
gtk_check_menu_item_set_active | ||||
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item2[sorted_position]), TRUE); | ||||
} | ||||
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu2), | ||||
find_menu_cat_pos(sorted_position)); | ||||
if (mkr->kr.name) { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_name), mkr->kr.name); | ||||
} else { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_name), ""); | ||||
} | ||||
if (mkr->kr.account) { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_account), mkr->kr.account); | ||||
} else { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_account), ""); | ||||
} | ||||
if (mkr->kr.password) { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_password), mkr->kr.password); | ||||
} else { | ||||
gtk_entry_set_text(GTK_ENTRY(entry_password), ""); | ||||
} | ||||
memcpy(&glob_date, &(mkr->kr.last_changed), sizeof(struct tm)); | ||||
update_date_button(date_button, &(mkr->kr.last_changed)); | ||||
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), "", -1); | ||||
if (mkr->kr.note) { | ||||
gtk_text_buffer_set_text(GTK_TEXT_BUFFER(keyr_note_buffer), mkr->kr.note, | ||||
-1); | ||||
} | ||||
connect_changed_signals(CONNECT_SIGNALS); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: leaving cb_clist_selection\n"); | ||||
} | ||||
static void cb_category(GtkWidget *item, int selection) | ||||
{ | ||||
int b; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_category\n"); | ||||
if ((GTK_CHECK_MENU_ITEM(item))->active) { | ||||
if (keyr_category == selection) { return; } | ||||
b=dialog_save_changed_record_with_cancel(pane, record_changed); | ||||
if (b==DIALOG_SAID_1) { /* Cancel */ | ||||
int index, index2; | ||||
if (keyr_category==CATEGORY_ALL) { | connect_changed_signals(CONNECT_SIGNALS); | |||
index = 0; | } | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: leaving handleKeyringRowSelection\n"); | ||||
return TRUE; | ||||
} | ||||
static void cb_category(GtkComboBox *item, int selection) { | ||||
int b; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: cb_category\n"); | ||||
if (!item) return; | ||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(item)) < 0) { | ||||
return; | ||||
} | ||||
int selectedItem = get_selected_category_from_combo_box(item); | ||||
if (selectedItem == -1) { | ||||
return; | ||||
} | ||||
if (keyr_category == selectedItem) { return; } | ||||
b = dialog_save_changed_record_with_cancel(pane, record_changed); | ||||
if (b == DIALOG_SAID_1) { /* Cancel */ | ||||
int index, index2; | ||||
if (keyr_category == CATEGORY_ALL) { | ||||
index = 0; | ||||
index2 = 0; | index2 = 0; | |||
} else { | } else { | |||
index=find_sort_cat_pos(keyr_category); | index = find_sort_cat_pos(keyr_category); | |||
index2 = find_menu_cat_pos(index) + 1; | index2 = find_menu_cat_pos(index) + 1; | |||
index += 1; | index += 1; | |||
} | } | |||
if (index<0) { | if (index < 0) { | |||
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | |||
} else { | } else { | |||
gtk_check_menu_item_set_active | gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2); | |||
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item1[index]), TRUE); | } | |||
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2) | ||||
; | return; | |||
} | } | |||
if (b == DIALOG_SAID_3) { /* Save */ | ||||
return; | cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | |||
} | } | |||
if (b==DIALOG_SAID_3) { /* Save */ | ||||
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | keyr_category = selectedItem; | |||
} | row_selected = 0; | |||
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE); | ||||
keyr_category = selection; | ||||
clist_row_selected = 0; | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | ||||
} | ||||
} | } | |||
/***** PASSWORD GUI *****/ | /***** PASSWORD GUI *****/ | |||
/* | /* | |||
* Start of Dialog window code | * Start of Dialog window code | |||
*/ | */ | |||
struct dialog_data { | struct dialog_data { | |||
GtkWidget *entry; | GtkWidget *entry; | |||
int button_hit; | int button_hit; | |||
char text[PASSWD_LEN+2]; | char text[PASSWD_LEN + 2]; | |||
}; | }; | |||
static void cb_dialog_button(GtkWidget *widget, gpointer data) | static void cb_dialog_button(GtkWidget *widget, gpointer data) { | |||
{ | struct dialog_data *Pdata; | |||
struct dialog_data *Pdata; | GtkWidget *w; | |||
GtkWidget *w; | ||||
/* Find the main window from some widget */ | ||||
/* Find the main window from some widget */ | w = GTK_WIDGET(gtk_widget_get_toplevel(widget)); | |||
w = GTK_WIDGET(gtk_widget_get_toplevel(widget)); | ||||
if (GTK_IS_WINDOW(w)) { | ||||
if (GTK_IS_WINDOW(w)) { | Pdata = g_object_get_data(G_OBJECT(w), "dialog_data"); | |||
Pdata = gtk_object_get_data(GTK_OBJECT(w), "dialog_data"); | if (Pdata) { | |||
if (Pdata) { | Pdata->button_hit = GPOINTER_TO_INT(data); | |||
Pdata->button_hit = GPOINTER_TO_INT(data); | } | |||
} | gtk_widget_destroy(GTK_WIDGET(w)); | |||
gtk_widget_destroy(GTK_WIDGET(w)); | } | |||
} | } | |||
} | ||||
static gboolean cb_destroy_dialog(GtkWidget *widget) { | ||||
static gboolean cb_destroy_dialog(GtkWidget *widget) | struct dialog_data *Pdata; | |||
{ | const char *entry; | |||
struct dialog_data *Pdata; | ||||
const char *entry; | Pdata = g_object_get_data(G_OBJECT(widget), "dialog_data"); | |||
if (!Pdata) { | ||||
Pdata = gtk_object_get_data(GTK_OBJECT(widget), "dialog_data"); | return TRUE; | |||
if (!Pdata) { | } | |||
return TRUE; | entry = gtk_entry_get_text(GTK_ENTRY(Pdata->entry)); | |||
} | ||||
entry = gtk_entry_get_text(GTK_ENTRY(Pdata->entry)); | if (entry) { | |||
strncpy(Pdata->text, entry, PASSWD_LEN); | ||||
if (entry) { | Pdata->text[PASSWD_LEN] = '\0'; | |||
strncpy(Pdata->text, entry, PASSWD_LEN); | /* Clear entry field */ | |||
Pdata->text[PASSWD_LEN]='\0'; | gtk_entry_set_text(GTK_ENTRY(Pdata->entry), ""); | |||
/* Clear entry field */ | } | |||
gtk_entry_set_text(GTK_ENTRY(Pdata->entry), ""); | ||||
} | ||||
gtk_main_quit(); | gtk_main_quit(); | |||
return TRUE; | return TRUE; | |||
} | } | |||
/* | /* | |||
* returns 2 if OK was pressed, 1 if cancel was hit | * returns 2 if OK was pressed, 1 if cancel was hit | |||
*/ | */ | |||
static int dialog_password(GtkWindow *main_window, | static int dialog_password(GtkWindow *main_window, | |||
char *ascii_password, | char *ascii_password, | |||
int reason) | int reason) { | |||
{ | GtkWidget *button, *label; | |||
GtkWidget *button, *label; | GtkWidget *hbox1, *vbox1; | |||
GtkWidget *hbox1, *vbox1; | GtkWidget *dialog; | |||
GtkWidget *dialog; | GtkWidget *entry; | |||
GtkWidget *entry; | struct dialog_data Pdata; | |||
struct dialog_data Pdata; | int ret; | |||
int ret; | ||||
if (!ascii_password) { | ||||
if (!ascii_password) { | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | } | |||
} | ascii_password[0] = '\0'; | |||
ascii_password[0]='\0'; | ret = 2; | |||
ret = 2; | ||||
dialog = gtk_widget_new(GTK_TYPE_WINDOW, | ||||
dialog = gtk_widget_new(GTK_TYPE_WINDOW, | "type", GTK_WINDOW_TOPLEVEL, | |||
"type", GTK_WINDOW_TOPLEVEL, | "title", "KeyRing", | |||
"title", "KeyRing", | NULL); | |||
NULL); | ||||
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); | ||||
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); | ||||
g_signal_connect(G_OBJECT(dialog), "destroy", | ||||
gtk_signal_connect(GTK_OBJECT(dialog), "destroy", | G_CALLBACK(cb_destroy_dialog), dialog); | |||
GTK_SIGNAL_FUNC(cb_destroy_dialog), dialog); | ||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | ||||
gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); | ||||
if (main_window) { | ||||
if (main_window) { | if (GTK_IS_WINDOW(main_window)) { | |||
if (GTK_IS_WINDOW(main_window)) { | gtk_window_set_transient_for(GTK_WINDOW(dialog), | |||
gtk_window_set_transient_for(GTK_WINDOW(dialog), | GTK_WINDOW(main_window)); | |||
GTK_WINDOW(main_window)); | } | |||
} | } | |||
} | ||||
hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); | ||||
hbox1 = gtk_hbox_new(FALSE, 2); | gtk_container_add(GTK_CONTAINER(dialog), hbox1); | |||
gtk_container_add(GTK_CONTAINER(dialog), hbox1); | gtk_box_pack_start(GTK_BOX(hbox1), gtk_image_new_from_icon_name("dialog-pass | |||
gtk_box_pack_start(GTK_BOX(hbox1), gtk_image_new_from_stock(GTK_STOCK_DIALOG_ | word", GTK_ICON_SIZE_DIALOG), | |||
AUTHENTICATION, GTK_ICON_SIZE_DIALOG), FALSE, FALSE, 2); | FALSE, FALSE, 2); | |||
vbox1 = gtk_vbox_new(FALSE, 2); | vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2); | |||
gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); | gtk_container_set_border_width(GTK_CONTAINER(vbox1), 5); | |||
gtk_container_add(GTK_CONTAINER(hbox1), vbox1); | gtk_container_add(GTK_CONTAINER(hbox1), vbox1); | |||
hbox1 = gtk_hbox_new(TRUE, 2); | hbox1 = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); | |||
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); | gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); | |||
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); | gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); | |||
/* Label */ | /* Label */ | |||
if (reason==PASSWD_ENTER_RETRY) { | if (reason == PASSWD_ENTER_RETRY) { | |||
label = gtk_label_new(_("Incorrect, Reenter KeyRing Password")); | label = gtk_label_new(_("Incorrect, Reenter KeyRing Password")); | |||
} else if (reason==PASSWD_ENTER_NEW) { | } else if (reason == PASSWD_ENTER_NEW) { | |||
label = gtk_label_new(_("Enter a NEW KeyRing Password")); | label = gtk_label_new(_("Enter a NEW KeyRing Password")); | |||
} else { | } else { | |||
label = gtk_label_new(_("Enter KeyRing Password")); | label = gtk_label_new(_("Enter KeyRing Password")); | |||
} | } | |||
gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 2); | gtk_box_pack_start(GTK_BOX(hbox1), label, FALSE, FALSE, 2); | |||
entry = gtk_entry_new_with_max_length(32); | entry = gtk_entry_new(); | |||
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | gtk_entry_set_max_length(GTK_ENTRY(entry), 32); | |||
gtk_signal_connect(GTK_OBJECT(entry), "activate", | gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); | |||
GTK_SIGNAL_FUNC(cb_dialog_button), | g_signal_connect(G_OBJECT(entry), "activate", | |||
GINT_TO_POINTER(DIALOG_SAID_2)); | G_CALLBACK(cb_dialog_button), | |||
gtk_box_pack_start(GTK_BOX(hbox1), entry, TRUE, TRUE, 1); | GINT_TO_POINTER(DIALOG_SAID_2)); | |||
gtk_box_pack_start(GTK_BOX(hbox1), entry, TRUE, TRUE, 1); | ||||
/* Button Box */ | ||||
hbox1 = gtk_hbutton_box_new(); | /* Button Box */ | |||
gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END); | hbox1 = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); | |||
gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox1), 6); | gtk_button_box_set_layout(GTK_BUTTON_BOX (hbox1), GTK_BUTTONBOX_END); | |||
gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); | gtk_box_set_spacing(GTK_BOX(hbox1), 6); | |||
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); | gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5); | |||
gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 2); | ||||
/* Buttons */ | ||||
button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); | /* Buttons */ | |||
gtk_signal_connect(GTK_OBJECT(button), "clicked", | button = gtk_button_new_with_label("Cancel"); | |||
GTK_SIGNAL_FUNC(cb_dialog_button), | g_signal_connect(G_OBJECT(button), "clicked", | |||
GINT_TO_POINTER(DIALOG_SAID_1)); | G_CALLBACK(cb_dialog_button), | |||
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); | GINT_TO_POINTER(DIALOG_SAID_1)); | |||
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); | ||||
button = gtk_button_new_from_stock(GTK_STOCK_OK); | ||||
gtk_signal_connect(GTK_OBJECT(button), "clicked", | button = gtk_button_new_with_label("OK"); | |||
GTK_SIGNAL_FUNC(cb_dialog_button), | g_signal_connect(G_OBJECT(button), "clicked", | |||
GINT_TO_POINTER(DIALOG_SAID_2)); | G_CALLBACK(cb_dialog_button), | |||
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); | GINT_TO_POINTER(DIALOG_SAID_2)); | |||
gtk_box_pack_start(GTK_BOX(hbox1), button, FALSE, FALSE, 1); | ||||
/* Set the default button pressed to CANCEL */ | ||||
Pdata.button_hit = DIALOG_SAID_1; | /* Set the default button pressed to CANCEL */ | |||
Pdata.entry=entry; | Pdata.button_hit = DIALOG_SAID_1; | |||
Pdata.text[0]='\0'; | Pdata.entry = entry; | |||
Pdata.text[0] = '\0'; | ||||
gtk_object_set_data(GTK_OBJECT(dialog), "dialog_data", &Pdata); | ||||
gtk_widget_grab_focus(GTK_WIDGET(entry)); | g_object_set_data(G_OBJECT(dialog), "dialog_data", &Pdata); | |||
gtk_widget_grab_focus(GTK_WIDGET(entry)); | ||||
gtk_widget_show_all(dialog); | ||||
gtk_widget_show_all(dialog); | ||||
gtk_main(); | ||||
gtk_main(); | ||||
if (Pdata.button_hit==DIALOG_SAID_1) { | ||||
ret = 1; | ||||
} | ||||
if (Pdata.button_hit==DIALOG_SAID_2) { | ||||
ret = 2; | ||||
} | ||||
strncpy(ascii_password, Pdata.text, PASSWD_LEN); | ||||
memset(Pdata.text, 0, PASSWD_LEN); | ||||
return ret; | if (Pdata.button_hit == DIALOG_SAID_1) { | |||
ret = 1; | ||||
} | ||||
if (Pdata.button_hit == DIALOG_SAID_2) { | ||||
ret = 2; | ||||
} | ||||
strncpy(ascii_password, Pdata.text, PASSWD_LEN); | ||||
memset(Pdata.text, 0, PASSWD_LEN); | ||||
return ret; | ||||
} | } | |||
/***** End Password GUI *****/ | /***** End Password GUI *****/ | |||
static int check_for_db(void) | static int check_for_db(void) { | |||
{ | char file[] = "Keys-Gtkr.pdb"; | |||
char file[]="Keys-Gtkr.pdb"; | char full_name[1024]; | |||
char full_name[1024]; | struct stat buf; | |||
struct stat buf; | ||||
jp_get_home_file_name(file, full_name, sizeof(full_name)); | ||||
jp_get_home_file_name(file, full_name, sizeof(full_name)); | ||||
if (stat(full_name, &buf)) { | ||||
if (stat(full_name, &buf)) { | jp_logf(JP_LOG_FATAL, _("KeyRing: file %s not found.\n"), full_name); | |||
jp_logf(JP_LOG_FATAL, _("KeyRing: file %s not found.\n"), full_name); | jp_logf(JP_LOG_FATAL, _("KeyRing: Try Syncing.\n"), full_name); | |||
jp_logf(JP_LOG_FATAL, _("KeyRing: Try Syncing.\n"), full_name); | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | } | |||
} | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
/* | /* | |||
* returns EXIT_SUCCESS on password correct, | * returns EXIT_SUCCESS on password correct, | |||
* EXIT_FAILURE on password incorrect, | * EXIT_FAILURE on password incorrect, | |||
* <0 on error | * <0 on error | |||
*/ | */ | |||
static int verify_pasword(char *ascii_password) | static int verify_pasword(char *ascii_password) { | |||
{ | GList *records; | |||
GList *records; | GList *temp_list; | |||
GList *temp_list; | buf_rec *br; | |||
buf_rec *br; | int password_not_correct; | |||
int password_not_correct; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: verify_pasword\n"); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: verify_pasword\n"); | ||||
if (check_for_db()) { | ||||
if (check_for_db()) { | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | } | |||
} | ||||
/* This function takes care of reading the Database for us */ | ||||
/* This function takes care of reading the Database for us */ | records = NULL; | |||
records=NULL; | if (jp_read_DB_files("Keys-Gtkr", &records) == -1) | |||
if (jp_read_DB_files("Keys-Gtkr", &records) == -1) | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
password_not_correct = 1; | ||||
password_not_correct = 1; | /* Find special record marked as password */ | |||
/* Find special record marked as password */ | for (temp_list = records; temp_list; temp_list = temp_list->next) { | |||
for (temp_list = records; temp_list; temp_list = temp_list->next) { | if (temp_list->data) { | |||
if (temp_list->data) { | br = temp_list->data; | |||
br=temp_list->data; | } else { | |||
} else { | continue; | |||
continue; | } | |||
} | if (!br->buf) { | |||
if (!br->buf) { | continue; | |||
continue; | } | |||
} | ||||
if ((br->rt == DELETED_PALM_REC) || (br->rt == MODIFIED_PALM_REC)) { | ||||
if ((br->rt == DELETED_PALM_REC) || (br->rt == MODIFIED_PALM_REC)) { | continue; | |||
continue; | } | |||
} | ||||
/* This record should be record 0 and is the hash-key record */ | ||||
/* This record should be record 0 and is the hash-key record */ | if (br->attrib & dlpRecAttrSecret) { | |||
if (br->attrib & dlpRecAttrSecret) { | password_not_correct = | |||
password_not_correct = | set_password_hash(br->buf, br->size, ascii_password); | |||
set_password_hash(br->buf, br->size, ascii_password); | break; | |||
break; | } | |||
} | } | |||
} | ||||
jp_free_DB_records(&records); | ||||
jp_free_DB_records(&records); | ||||
if (password_not_correct) | ||||
if (password_not_correct) | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | else | |||
else | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
#define PLUGIN_MAJOR 1 | #define PLUGIN_MAJOR 1 | |||
#define PLUGIN_MINOR 1 | #define PLUGIN_MINOR 1 | |||
/* This is a mandatory plugin function. */ | /* This is a mandatory plugin function. */ | |||
void plugin_version(int *major_version, int *minor_version) | void plugin_version(int *major_version, int *minor_version) { | |||
{ | *major_version = PLUGIN_MAJOR; | |||
*major_version = PLUGIN_MAJOR; | *minor_version = PLUGIN_MINOR; | |||
*minor_version = PLUGIN_MINOR; | ||||
} | } | |||
static int static_plugin_get_name(char *name, int len) | static int static_plugin_get_name(char *name, int len) { | |||
{ | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_get_name\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_get_name\n"); | snprintf(name, len, "KeyRing %d.%d", PLUGIN_MAJOR, PLUGIN_MINOR); | |||
snprintf(name, len, "KeyRing %d.%d", PLUGIN_MAJOR, PLUGIN_MINOR); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* This is a mandatory plugin function. */ | /* This is a mandatory plugin function. */ | |||
int plugin_get_name(char *name, int len) | int plugin_get_name(char *name, int len) { | |||
{ | return static_plugin_get_name(name, len); | |||
return static_plugin_get_name(name, len); | ||||
} | } | |||
/* | /* | |||
* This is an optional plugin function. | * This is an optional plugin function. | |||
* This is the name that will show up in the plugins menu in J-Pilot. | * This is the name that will show up in the plugins menu in J-Pilot. | |||
*/ | */ | |||
int plugin_get_menu_name(char *name, int len) | int plugin_get_menu_name(char *name, int len) { | |||
{ | strncpy(name, _("KeyRing"), len); | |||
strncpy(name, _("KeyRing"), len); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is an optional plugin function. | * This is an optional plugin function. | |||
* This is the name that will show up in the plugins help menu in J-Pilot. | * This is the name that will show up in the plugins help menu in J-Pilot. | |||
* If this function is used then plugin_help must be also. | * If this function is used then plugin_help must be also. | |||
*/ | */ | |||
int plugin_get_help_name(char *name, int len) | int plugin_get_help_name(char *name, int len) { | |||
{ | g_snprintf(name, len, _("About %s"), _("KeyRing")); | |||
g_snprintf(name, len, _("About %s"), _("KeyRing")); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is an optional plugin function. | * This is an optional plugin function. | |||
* This is the palm database that will automatically be synced. | * This is the palm database that will automatically be synced. | |||
*/ | */ | |||
int plugin_get_db_name(char *name, int len) | int plugin_get_db_name(char *name, int len) { | |||
{ | strncpy(name, "Keys-Gtkr", len); | |||
strncpy(name, "Keys-Gtkr", len); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function which provides information | * This is a plugin callback function which provides information | |||
* to the user about the plugin. | * to the user about the plugin. | |||
*/ | */ | |||
int plugin_help(char **text, int *width, int *height) | int plugin_help(char **text, int *width, int *height) { | |||
{ | /* We could also pass back *text=NULL | |||
/* We could also pass back *text=NULL | * and implement whatever we wanted to here. | |||
* and implement whatever we wanted to here. | */ | |||
*/ | char plugin_name[200]; | |||
char plugin_name[200]; | ||||
static_plugin_get_name(plugin_name, sizeof(plugin_name)); | ||||
static_plugin_get_name(plugin_name, sizeof(plugin_name)); | *text = g_strdup_printf( | |||
*text = g_strdup_printf( | /*-------------------------------------------*/ | |||
/*-------------------------------------------*/ | _("%s\n" | |||
_("%s\n" | "\n" | |||
"\n" | "KeyRing plugin for J-Pilot was written by\n" | |||
"KeyRing plugin for J-Pilot was written by\n" | "Judd Montgomery (c) 2001.\n" | |||
"Judd Montgomery (c) 2001.\n" | "judd@jpilot.org, http://jpilot.org\n" | |||
"judd@jpilot.org, http://jpilot.org\n" | "\n" | |||
"\n" | "KeyRing is a free PalmOS program for storing\n" | |||
"KeyRing is a free PalmOS program for storing\n" | "passwords and other information in encrypted form\n" | |||
"passwords and other information in encrypted form\n" | "http://gnukeyring.sourceforge.net" | |||
"http://gnukeyring.sourceforge.net" | ), | |||
), | plugin_name | |||
plugin_name | ); | |||
); | *height = 0; | |||
*height = 0; | *width = 0; | |||
*width = 0; | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
/* | /* | |||
* This is a plugin callback function that is executed when J-Pilot starts up. | * This is a plugin callback function that is executed when J-Pilot starts up. | |||
* base_dir is where J-Pilot is compiled to be installed at (e.g. /usr/local/) | * base_dir is where J-Pilot is compiled to be installed at (e.g. /usr/local/) | |||
*/ | */ | |||
int plugin_startup(jp_startup_info *info) | int plugin_startup(jp_startup_info *info) { | |||
{ | jp_init(); | |||
jp_init(); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_startup\n"); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_startup\n"); | if (info) { | |||
if (info) { | if (info->base_dir) { | |||
if (info->base_dir) { | jp_logf(JP_LOG_DEBUG, "KeyRing: base_dir = [%s]\n", info->base_dir); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: base_dir = [%s]\n", info->base_dir); | } | |||
} | } | |||
} | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function that is executed before a sync occurs. | * This is a plugin callback function that is executed before a sync occurs. | |||
* Any sync preperation can be done here. | * Any sync preperation can be done here. | |||
*/ | */ | |||
int plugin_pre_sync(void) | int plugin_pre_sync(void) { | |||
{ | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_pre_sync\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_pre_sync\n"); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function that is executed during a sync. | * This is a plugin callback function that is executed during a sync. | |||
* Notice that I don't need to sync the KeyRing application. Since I used | * Notice that I don't need to sync the KeyRing application. Since I used | |||
* the plugin_get_db_name call to tell J-Pilot what to sync for me. It will | * the plugin_get_db_name call to tell J-Pilot what to sync for me. It will | |||
* be done automatically. | * be done automatically. | |||
*/ | */ | |||
int plugin_sync(int sd) | int plugin_sync(int sd) { | |||
{ | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_sync\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_sync\n"); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function called after a sync. | * This is a plugin callback function called after a sync. | |||
*/ | */ | |||
int plugin_post_sync(void) | int plugin_post_sync(void) { | |||
{ | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_post_sync\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_post_sync\n"); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
static int add_search_result(const char *line, | static int add_search_result(const char *line, | |||
int unique_id, | int unique_id, | |||
struct search_result **sr) | struct search_result **sr) { | |||
{ | struct search_result *new_sr; | |||
struct search_result *new_sr; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: add_search_result for [%s]\n", line); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: add_search_result for [%s]\n", line); | ||||
new_sr = malloc(sizeof(struct search_result)); | ||||
new_sr=malloc(sizeof(struct search_result)); | if (!new_sr) { | |||
if (!new_sr) { | return EXIT_FAILURE; | |||
return EXIT_FAILURE; | } | |||
} | new_sr->unique_id = unique_id; | |||
new_sr->unique_id=unique_id; | new_sr->line = strdup(line); | |||
new_sr->line=strdup(line); | new_sr->next = *sr; | |||
new_sr->next = *sr; | *sr = new_sr; | |||
*sr = new_sr; | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
/* | /* | |||
* This function is called when the user does a search. It should return | * This function is called when the user does a search. It should return | |||
* records which match the search string. | * records which match the search string. | |||
*/ | */ | |||
int plugin_search(const char *search_string, int case_sense, | int plugin_search(const char *search_string, int case_sense, | |||
struct search_result **sr) | struct search_result **sr) { | |||
{ | struct MyKeyRing *mkr_list; | |||
struct MyKeyRing *mkr_list; | struct MyKeyRing *temp_list; | |||
struct MyKeyRing *temp_list; | struct MyKeyRing mkr; | |||
struct MyKeyRing mkr; | int num, count; | |||
int num, count; | char *line; | |||
char *line; | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_search\n"); | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_search\n"); | ||||
*sr = NULL; | ||||
*sr=NULL; | mkr_list = NULL; | |||
mkr_list=NULL; | ||||
if (!plugin_active) { | ||||
if (!plugin_active) { | return 0; | |||
return 0; | } | |||
} | ||||
/* This function takes care of reading the Database for us */ | ||||
/* This function takes care of reading the Database for us */ | num = get_keyring(&mkr_list, CATEGORY_ALL); | |||
num = get_keyring(&mkr_list, CATEGORY_ALL); | if (-1 == num) | |||
if (-1 == num) | return 0; | |||
return 0; | ||||
count = 0; | ||||
count = 0; | ||||
/* Search through returned records */ | ||||
/* Search through returned records */ | for (temp_list = mkr_list; temp_list; temp_list = temp_list->next) { | |||
for (temp_list = mkr_list; temp_list; temp_list = temp_list->next) { | mkr = *temp_list; | |||
mkr = *temp_list; | line = NULL; | |||
line = NULL; | ||||
/* find in record name */ | ||||
/* find in record name */ | if (jp_strstr(mkr.kr.name, search_string, case_sense)) | |||
if (jp_strstr(mkr.kr.name, search_string, case_sense)) | line = mkr.kr.name; | |||
line = mkr.kr.name; | ||||
/* find in record account */ | ||||
/* find in record account */ | if (jp_strstr(mkr.kr.account, search_string, case_sense)) | |||
if (jp_strstr(mkr.kr.account, search_string, case_sense)) | line = mkr.kr.account; | |||
line = mkr.kr.account; | ||||
/* find in record password */ | ||||
/* find in record password */ | if (jp_strstr(mkr.kr.password, search_string, case_sense)) | |||
if (jp_strstr(mkr.kr.password, search_string, case_sense)) | line = mkr.kr.password; | |||
line = mkr.kr.password; | ||||
/* find in record note */ | ||||
/* find in record note */ | if (jp_strstr(mkr.kr.note, search_string, case_sense)) | |||
if (jp_strstr(mkr.kr.note, search_string, case_sense)) | line = mkr.kr.note; | |||
line = mkr.kr.note; | ||||
if (line) { | ||||
if (line) { | /* Add it to our result list */ | |||
/* Add it to our result list */ | jp_logf(JP_LOG_DEBUG, "KeyRing: calling add_search_result\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: calling add_search_result\n"); | add_search_result(line, mkr.unique_id, sr); | |||
add_search_result(line, mkr.unique_id, sr); | jp_logf(JP_LOG_DEBUG, "KeyRing: back from add_search_result\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: back from add_search_result\n"); | count++; | |||
count++; | } | |||
} | } | |||
} | ||||
free_mykeyring_list(&mkr_list); | ||||
free_mykeyring_list(&mkr_list); | ||||
return count; | ||||
return count; | } | |||
} | ||||
gboolean | ||||
static int keyring_find(int unique_id) | findKeyRingRecord(GtkTreeModel *model, | |||
{ | GtkTreePath *path, | |||
int r, found_at; | GtkTreeIter *iter, | |||
gpointer data) { | ||||
jp_logf(JP_LOG_DEBUG, "KeyRing: keyring_find\n"); | int uniqueId = GPOINTER_TO_INT(data); | |||
if (uniqueId) { | ||||
r = clist_find_id(clist, unique_id, &found_at); | struct MyKeyRing *mkr = NULL; | |||
if (r) { | ||||
clist_select_row(GTK_CLIST(clist), found_at, 0); | gtk_tree_model_get(model, iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1); | |||
if (!gtk_clist_row_is_visible(GTK_CLIST(clist), found_at)) { | if (mkr->unique_id == uniqueId) { | |||
gtk_clist_moveto(GTK_CLIST(clist), found_at, 0, 0.5, 0.0); | GtkTreeSelection *selection = NULL; | |||
} | selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView)); | |||
} | gtk_tree_selection_select_path(selection, path); | |||
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(treeView), path, KEYRING_ | ||||
return EXIT_SUCCESS; | CHANGED_COLUMN_ENUM, FALSE, 1.0, 0.0); | |||
} | return TRUE; | |||
} | ||||
static void cb_keyr_update_clist(GtkWidget *clist, int category) | } | |||
{ | return FALSE; | |||
keyr_update_clist(clist, &export_keyring_list, category, FALSE); | } | |||
} | ||||
static int keyring_find(int unique_id) { | ||||
static void cb_keyr_export_done(GtkWidget *widget, const char *filename) | gtk_tree_model_foreach(GTK_TREE_MODEL(listStore), findKeyRingRecord, GINT_TO | |||
{ | _POINTER(unique_id)); | |||
free_mykeyring_list(&export_keyring_list); | return EXIT_SUCCESS; | |||
} | ||||
set_pref(PREF_KEYR_EXPORT_FILENAME, 0, filename, TRUE); | ||||
} | static void cb_keyr_update_listStore(GtkWidget *treeView, int category) { | |||
keyr_update_liststore(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(t | ||||
static void cb_keyr_export_ok(GtkWidget *export_window, GtkWidget *clist, | reeView))), &export_keyring_list, | |||
int type, const char *filename) | category, FALSE); | |||
{ | } | |||
struct MyKeyRing *mkr; | ||||
GList *list, *temp_list; | static void cb_keyr_export_done(GtkWidget *widget, const char *filename) { | |||
FILE *out; | free_mykeyring_list(&export_keyring_list); | |||
struct stat statb; | ||||
int i, r; | set_pref(PREF_KEYR_EXPORT_FILENAME, 0, filename, TRUE); | |||
const char *short_date; | } | |||
time_t ltime; | ||||
struct tm *now; | static void cb_keyr_export_ok(GtkWidget *export_window, GtkWidget *treeView, | |||
char *button_text[]={N_("OK")}; | int type, const char *filename) { | |||
char *button_overwrite_text[]={N_("No"), N_("Yes")}; | struct MyKeyRing *mkr; | |||
char *button_keepassx_text[]={N_("Cancel"), N_("Overwrite"), N_("Append")}; | GList *list, *temp_list; | |||
enum { NA=0, cancel=DIALOG_SAID_1, overwrite=DIALOG_SAID_2, append=DIALOG_SAI | FILE *out; | |||
D_3 } keepassx_answer = NA; | struct stat statb; | |||
char text[1024]; | int i, r; | |||
char str1[256], str2[256]; | const char *short_date; | |||
char date_string[1024]; | time_t ltime; | |||
char pref_time[40]; | struct tm *now; | |||
char csv_text[65550]; | char *button_text[] = {N_("OK")}; | |||
long char_set; | char *button_overwrite_text[] = {N_("No"), N_("Yes")}; | |||
char *utf; | char *button_keepassx_text[] = {N_("Cancel"), N_("Overwrite"), N_("Append")} | |||
int cat; | ; | |||
enum { | ||||
/* Open file for export, including corner cases where file exists or | NA = 0, cancel = DIALOG_SAID_1, overwrite = DIALOG_SAID_2, append = DIAL | |||
* can't be opened */ | OG_SAID_3 | |||
if (!stat(filename, &statb)) { | } keepassx_answer = NA; | |||
if (S_ISDIR(statb.st_mode)) { | char text[1024]; | |||
g_snprintf(text, sizeof(text), _("%s is a directory"), filename); | char str1[256], str2[256]; | |||
dialog_generic(GTK_WINDOW(export_window), | char date_string[1024]; | |||
_("Error Opening File"), | char pref_time[40]; | |||
DIALOG_ERROR, text, 1, button_text); | char csv_text[65550]; | |||
return; | long char_set; | |||
} | char *utf; | |||
if (type == EXPORT_TYPE_KEEPASSX) { | int cat; | |||
g_snprintf(text, sizeof(text), _("KeePassX XML File exists, Do you want | ||||
to")); | /* Open file for export, including corner cases where file exists or | |||
keepassx_answer = dialog_generic(GTK_WINDOW(export_window), | * can't be opened */ | |||
_("Overwrite File?"), | if (!stat(filename, &statb)) { | |||
DIALOG_ERROR, text, 3, button_keepassx_text); | if (S_ISDIR(statb.st_mode)) { | |||
if (keepassx_answer==cancel) { | g_snprintf(text, sizeof(text), _("%s is a directory"), filename); | |||
return; | dialog_generic(GTK_WINDOW(export_window), | |||
} | _("Error Opening File"), | |||
} else { | DIALOG_ERROR, text, 1, button_text); | |||
g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?"), | ||||
filename); | ||||
r = dialog_generic(GTK_WINDOW(export_window), | ||||
_("Overwrite File?"), | ||||
DIALOG_ERROR, text, 2, button_overwrite_text); | ||||
if (r!=DIALOG_SAID_2) { | ||||
return; | return; | |||
} | } | |||
} | if (type == EXPORT_TYPE_KEEPASSX) { | |||
} | g_snprintf(text, sizeof(text), _("KeePassX XML File exists, Do you w | |||
ant to")); | ||||
if ((keepassx_answer==append)) { | keepassx_answer = dialog_generic(GTK_WINDOW(export_window), | |||
out = fopen(filename, "r+"); | _("Overwrite File?"), | |||
} else { | DIALOG_ERROR, text, 3, button_keepa | |||
out = fopen(filename, "w"); | ssx_text); | |||
} | if (keepassx_answer == cancel) { | |||
if (!out) { | return; | |||
g_snprintf(text,sizeof(text), _("Error opening file: %s"), filename); | } | |||
dialog_generic(GTK_WINDOW(export_window), | } else { | |||
_("Error Opening File"), | g_snprintf(text, sizeof(text), _("Do you want to overwrite file %s?" | |||
DIALOG_ERROR, text, 1, button_text); | ), filename); | |||
return; | r = dialog_generic(GTK_WINDOW(export_window), | |||
} | _("Overwrite File?"), | |||
DIALOG_ERROR, text, 2, button_overwrite_text); | ||||
/* Write a header for TEXT file */ | if (r != DIALOG_SAID_2) { | |||
if (type == EXPORT_TYPE_TEXT) { | return; | |||
get_pref(PREF_SHORTDATE, NULL, &short_date); | } | |||
get_pref_time_no_secs(pref_time); | } | |||
time(<ime); | } | |||
now = localtime(<ime); | ||||
strftime(str1, sizeof(str1), short_date, now); | if ((keepassx_answer == append)) { | |||
strftime(str2, sizeof(str2), pref_time, now); | out = fopen(filename, "r+"); | |||
g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2); | } else { | |||
fprintf(out, _("Keys exported from %s %s on %s\n\n"), | out = fopen(filename, "w"); | |||
PN,VERSION,date_string); | } | |||
} | if (!out) { | |||
g_snprintf(text, sizeof(text), _("Error opening file: %s"), filename); | ||||
/* Write a header to the CSV file */ | dialog_generic(GTK_WINDOW(export_window), | |||
if (type == EXPORT_TYPE_CSV) { | _("Error Opening File"), | |||
fprintf(out, "\"Category\",\"Name\",\"Account\",\"Password\",\"Note\"\n"); | DIALOG_ERROR, text, 1, button_text); | |||
} | return; | |||
} | ||||
/* Write a header to the B-Folders CSV file */ | ||||
if (type == EXPORT_TYPE_BFOLDERS) { | /* Write a header for TEXT file */ | |||
fprintf(out, "Login passwords:\n"); | if (type == EXPORT_TYPE_TEXT) { | |||
fprintf(out, "Title,Location,Usename,Password, " | get_pref(PREF_SHORTDATE, NULL, &short_date); | |||
"\"Custom Label 1\",\"Custom Value 1\",\"Custom Label 2\",\"Custom | get_pref_time_no_secs(pref_time); | |||
Value 2\"," | time(<ime); | |||
"\"Custom Label 3\",\"Custom Value 3\",\"Custom Label 4\",\"Custom | now = localtime(<ime); | |||
Value 4\"," | strftime(str1, sizeof(str1), short_date, now); | |||
"\"Custom Label 5\",\"Custom Value 5\", Note,Folder\n"); | strftime(str2, sizeof(str2), pref_time, now); | |||
} | g_snprintf(date_string, sizeof(date_string), "%s %s", str1, str2); | |||
fprintf(out, _("Keys exported from %s %s on %s\n\n"), | ||||
if (type == EXPORT_TYPE_KEEPASSX) { | PN, VERSION, date_string); | |||
if (keepassx_answer!=append) { | } | |||
/* Write a database header to the KeePassX XML file */ | ||||
/* If we append to an XML file we don't need another header */ | /* Write a header to the CSV file */ | |||
fprintf(out, "<!DOCTYPE KEEPASSX_DATABASE>\n"); | if (type == EXPORT_TYPE_CSV) { | |||
fprintf(out, "<database>\n"); | fprintf(out, "\"Category\",\"Name\",\"Account\",\"Password\",\"Note\"\n" | |||
} else { | ); | |||
/* We'll need to remove the last part of the XML file */ | } | |||
r = fseek(out, -12L, SEEK_END); | ||||
r = fread(text, 11, 1, out); | /* Write a header to the B-Folders CSV file */ | |||
text[11]='\0'; | if (type == EXPORT_TYPE_BFOLDERS) { | |||
if (strncmp(text, "</database>", 11)) { | fprintf(out, "Login passwords:\n"); | |||
jp_logf(JP_LOG_WARN, _("This doesn't look like a KeePassX XML file\n | fprintf(out, "Title,Location,Usename,Password, " | |||
")); | "\"Custom Label 1\",\"Custom Value 1\",\"Custom Label 2\",\ | |||
fseek(out, 0L, SEEK_END); | "Custom Value 2\"," | |||
} else { | "\"Custom Label 3\",\"Custom Value 3\",\"Custom Label 4\",\ | |||
"Custom Value 4\"," | ||||
"\"Custom Label 5\",\"Custom Value 5\", Note,Folder\n"); | ||||
} | ||||
if (type == EXPORT_TYPE_KEEPASSX) { | ||||
if (keepassx_answer != append) { | ||||
/* Write a database header to the KeePassX XML file */ | ||||
/* If we append to an XML file we don't need another header */ | ||||
fprintf(out, "<!DOCTYPE KEEPASSX_DATABASE>\n"); | ||||
fprintf(out, "<database>\n"); | ||||
} else { | ||||
/* We'll need to remove the last part of the XML file */ | ||||
fseek(out, -12L, SEEK_END); | fseek(out, -12L, SEEK_END); | |||
} | fread(text, 11, 1, out); | |||
} | text[11] = '\0'; | |||
/* Write a group header to the KeePassX XML file */ | if (strncmp(text, "</database>", 11)) { | |||
fprintf(out, " <group>\n"); | jp_logf(JP_LOG_WARN, _("This doesn't look like a KeePassX XML fi | |||
fprintf(out, " <title>Keyring</title>\n"); | le\n")); | |||
fprintf(out, " <icon>0</icon>\n"); | fseek(out, 0L, SEEK_END); | |||
} | } else { | |||
fseek(out, -12L, SEEK_END); | ||||
get_pref(PREF_CHAR_SET, &char_set, NULL); | } | |||
list=GTK_CLIST(clist)->selection; | } | |||
/* Write a group header to the KeePassX XML file */ | ||||
for (i=0, temp_list=list; temp_list; temp_list = temp_list->next, i++) { | fprintf(out, " <group>\n"); | |||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(temp_list-> | fprintf(out, " <title>Keyring</title>\n"); | |||
data)); | fprintf(out, " <icon>0</icon>\n"); | |||
if (!mkr) { | } | |||
continue; | ||||
jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_list->data | get_pref(PREF_CHAR_SET, &char_set, NULL); | |||
+ 1); | GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree | |||
} | View)); | |||
switch (type) { | GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)); | |||
case EXPORT_TYPE_CSV: | list = gtk_tree_selection_get_selected_rows(selection, &model); | |||
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], 16, char_s | ||||
et); | for (i = 0, temp_list = list; temp_list; temp_list = temp_list->next, i++) { | |||
fprintf(out, "\"%s\",", utf); | GtkTreePath *path = temp_list->data; | |||
g_free(utf); | GtkTreeIter iter; | |||
str_to_csv_str(csv_text, mkr->kr.name); | if (gtk_tree_model_get_iter(model, &iter, path)) { | |||
fprintf(out, "\"%s\",", csv_text); | gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, &mkr, -1) | |||
str_to_csv_str(csv_text, mkr->kr.account); | ; | |||
fprintf(out, "\"%s\",", csv_text); | if (!mkr) { | |||
str_to_csv_str(csv_text, mkr->kr.password); | continue; | |||
fprintf(out, "\"%s\",", csv_text); | jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_lis | |||
str_to_csv_str(csv_text, mkr->kr.note); | t->data + 1); | |||
fprintf(out, "\"%s\"\n", csv_text); | } | |||
break; | switch (type) { | |||
case EXPORT_TYPE_CSV: | ||||
case EXPORT_TYPE_BFOLDERS: | utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], | |||
str_to_csv_str(csv_text, mkr->kr.name); | 16, char_set); | |||
fprintf(out, "\"%s\",", csv_text); | fprintf(out, "\"%s\",", utf); | |||
g_free(utf); | ||||
fprintf(out, "\"\","); | str_to_csv_str(csv_text, mkr->kr.name); | |||
fprintf(out, "\"%s\",", csv_text); | ||||
str_to_csv_str(csv_text, mkr->kr.account); | str_to_csv_str(csv_text, mkr->kr.account); | |||
fprintf(out, "\"%s\",", csv_text); | fprintf(out, "\"%s\",", csv_text); | |||
str_to_csv_str(csv_text, mkr->kr.password); | str_to_csv_str(csv_text, mkr->kr.password); | |||
fprintf(out, "\"%s\",", csv_text); | fprintf(out, "\"%s\",", csv_text); | |||
str_to_csv_str(csv_text, mkr->kr.note); | ||||
fprintf(out, "\"\",\"\",\"\",\"\"," | fprintf(out, "\"%s\"\n", csv_text); | |||
"\"\",\"\",\"\",\"\"," | break; | |||
"\"\",\"\","); | ||||
case EXPORT_TYPE_BFOLDERS: | ||||
str_to_csv_str(csv_text, mkr->kr.note); | str_to_csv_str(csv_text, mkr->kr.name); | |||
fprintf(out, "\"%s\",", csv_text); | fprintf(out, "\"%s\",", csv_text); | |||
fprintf(out, "\"KeyRing > "); | fprintf(out, "\"\","); | |||
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], 16, char_se | str_to_csv_str(csv_text, mkr->kr.account); | |||
t); | fprintf(out, "\"%s\",", csv_text); | |||
fprintf(out, "%s\"\n", utf); | str_to_csv_str(csv_text, mkr->kr.password); | |||
g_free(utf); | fprintf(out, "\"%s\",", csv_text); | |||
break; | fprintf(out, "\"\",\"\",\"\",\"\"," | |||
"\"\",\"\",\"\",\"\"," | ||||
case EXPORT_TYPE_TEXT: | "\"\",\"\","); | |||
fprintf(out, "#%d\n", i+1); | ||||
fprintf(out, "Name: %s\n", mkr->kr.name); | str_to_csv_str(csv_text, mkr->kr.note); | |||
fprintf(out, "Account: %s\n", mkr->kr.account); | fprintf(out, "\"%s\",", csv_text); | |||
fprintf(out, "Password: %s\n", mkr->kr.password); | ||||
fprintf(out, "Note: %s\n", mkr->kr.note ); | fprintf(out, "\"KeyRing > "); | |||
break; | ||||
utf = charset_p2newj(keyr_app_info.name[mkr->attrib & 0x0F], | ||||
case EXPORT_TYPE_KEEPASSX: | 16, char_set); | |||
break; | fprintf(out, "%s\"\n", utf); | |||
g_free(utf); | ||||
default: | ||||
jp_logf(JP_LOG_WARN, _("Unknown export type\n")); | break; | |||
} | ||||
} | case EXPORT_TYPE_TEXT: | |||
fprintf(out, "#%d\n", i + 1); | ||||
/* I'm writing a second loop for the KeePassX XML file because I want to | fprintf(out, "Name: %s\n", mkr->kr.name); | |||
* put each category into a folder and we need to write the tag for a folder | fprintf(out, "Account: %s\n", mkr->kr.account); | |||
* and then find each record in that category/folder | fprintf(out, "Password: %s\n", mkr->kr.password); | |||
*/ | fprintf(out, "Note: %s\n", mkr->kr.note); | |||
if (type==EXPORT_TYPE_KEEPASSX) { | break; | |||
for (cat=0; cat < 16; cat++) { | ||||
if (keyr_app_info.name[cat][0]=='\0') { | case EXPORT_TYPE_KEEPASSX: | |||
continue; | break; | |||
} | ||||
/* Write a folder XML tag */ | default: | |||
utf = charset_p2newj(keyr_app_info.name[cat], 16, char_set); | jp_logf(JP_LOG_WARN, _("Unknown export type\n")); | |||
fprintf(out, " <group>\n"); | } | |||
fprintf(out, " <title>%s</title>\n", utf); | } | |||
fprintf(out, " <icon>13</icon>\n"); | } | |||
g_free(utf); | ||||
/* I'm writing a second loop for the KeePassX XML file because I want to | ||||
for (i=0, temp_list=list; temp_list; temp_list = temp_list->next, i++) { | * put each category into a folder and we need to write the tag for a folder | |||
mkr = gtk_clist_get_row_data(GTK_CLIST(clist), GPOINTER_TO_INT(temp_l | * and then find each record in that category/folder | |||
ist->data)); | */ | |||
if (!mkr) { | if (type == EXPORT_TYPE_KEEPASSX) { | |||
continue; | for (cat = 0; cat < 16; cat++) { | |||
jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) temp_list- | if (keyr_app_info.name[cat][0] == '\0') { | |||
>data + 1); | continue; | |||
} | } | |||
if ((mkr->attrib & 0x0F) != cat) { | /* Write a folder XML tag */ | |||
continue; | utf = charset_p2newj(keyr_app_info.name[cat], 16, char_set); | |||
} | fprintf(out, " <group>\n"); | |||
fprintf(out, " <entry>\n"); | fprintf(out, " <title>%s</title>\n", utf); | |||
str_to_keepass_str(csv_text, mkr->kr.name); | fprintf(out, " <icon>13</icon>\n"); | |||
fprintf(out, " <title>%s</title>\n", csv_text); | g_free(utf); | |||
str_to_keepass_str(csv_text, mkr->kr.account); | ||||
fprintf(out, " <username>%s</username>\n", csv_text); | for (i = 0, temp_list = list; temp_list; temp_list = temp_list->next | |||
str_to_keepass_str(csv_text, mkr->kr.password); | , i++) { | |||
fprintf(out, " <password>%s</password>\n", csv_text); | GtkTreePath *path = temp_list->data; | |||
/* No keyring field for url */ | GtkTreeIter iter; | |||
str_to_keepass_str(csv_text, mkr->kr.note); | if (gtk_tree_model_get_iter(model, &iter, path)) { | |||
fprintf(out, " <comment>%s</comment>\n", csv_text); | gtk_tree_model_get(model, &iter, KEYRING_DATA_COLUMN_ENUM, & | |||
fprintf(out, " <icon>0</icon>\n"); | mkr, -1); | |||
/* No keyring field for creation */ | if (!mkr) { | |||
/* No keyring field for lastaccess */ | continue; | |||
/* lastmod */ | jp_logf(JP_LOG_WARN, _("Can't export key %d\n"), (long) | |||
strftime(str1, sizeof(str1), "%Y-%m-%dT%H:%M:%S", &(mkr->kr.last_chan | temp_list->data + 1); | |||
ged)); | } | |||
fprintf(out, " <lastmod>%s</lastmod>\n", str1); | if ((mkr->attrib & 0x0F) != cat) { | |||
/* No keyring field for expire */ | continue; | |||
fprintf(out, " <expire>Never</expire>\n"); | } | |||
fprintf(out, " </entry>\n"); | fprintf(out, " <entry>\n"); | |||
} | str_to_keepass_str(csv_text, mkr->kr.name); | |||
fprintf(out, " </group>\n"); | fprintf(out, " <title>%s</title>\n", csv_text); | |||
} | str_to_keepass_str(csv_text, mkr->kr.account); | |||
fprintf(out, " <username>%s</username>\n", csv_text); | ||||
/* Write a footer to the KeePassX XML file */ | str_to_keepass_str(csv_text, mkr->kr.password); | |||
if (type == EXPORT_TYPE_KEEPASSX) { | fprintf(out, " <password>%s</password>\n", csv_text); | |||
fprintf(out, " </group>\n"); | /* No keyring field for url */ | |||
fprintf(out, "</database>\n"); | str_to_keepass_str(csv_text, mkr->kr.note); | |||
} | fprintf(out, " <comment>%s</comment>\n", csv_text); | |||
} | fprintf(out, " <icon>0</icon>\n"); | |||
/* No keyring field for creation */ | ||||
if (out) { | /* No keyring field for lastaccess */ | |||
fclose(out); | /* lastmod */ | |||
} | strftime(str1, sizeof(str1), "%Y-%m-%dT%H:%M:%S", &(mkr->kr. | |||
last_changed)); | ||||
fprintf(out, " <lastmod>%s</lastmod>\n", str1); | ||||
/* No keyring field for expire */ | ||||
fprintf(out, " <expire>Never</expire>\n"); | ||||
fprintf(out, " </entry>\n"); | ||||
} | ||||
fprintf(out, " </group>\n"); | ||||
} | ||||
} | ||||
/* Write a footer to the KeePassX XML file */ | ||||
if (type == EXPORT_TYPE_KEEPASSX) { | ||||
fprintf(out, " </group>\n"); | ||||
fprintf(out, "</database>\n"); | ||||
} | ||||
} | ||||
if (out) { | ||||
fclose(out); | ||||
} | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function to export records. | * This is a plugin callback function to export records. | |||
*/ | */ | |||
int plugin_export(GtkWidget *window) | int plugin_export(GtkWidget *window) { | |||
{ | int w, h, x, y; | |||
int w, h, x, y; | char *type_text[] = {N_("Text"), N_("CSV"), N_("B-Folders CSV"), N_("KeePass | |||
char *type_text[]={N_("Text"), N_("CSV"), N_("B-Folders CSV"), N_("KeePassX X | X XML"), NULL}; | |||
ML"), NULL}; | int type_int[] = {EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_BFOLDERS, E | |||
int type_int[]={EXPORT_TYPE_TEXT, EXPORT_TYPE_CSV, EXPORT_TYPE_BFOLDERS, EXPO | XPORT_TYPE_KEEPASSX}; | |||
RT_TYPE_KEEPASSX}; | ||||
w = gdk_window_get_width(gtk_widget_get_window(window)); | ||||
gdk_window_get_size(window->window, &w, &h); | h = gdk_window_get_height(gtk_widget_get_window(window)); | |||
gdk_window_get_root_origin(window->window, &x, &y); | gdk_window_get_root_origin(gtk_widget_get_window(window), &x, &y); | |||
w = gtk_paned_get_position(GTK_PANED(pane)); | w = gtk_paned_get_position(GTK_PANED(pane)); | |||
x+=40; | x += 40; | |||
export_gui(window, | export_gui(window, | |||
w, h, x, y, 1, sort_l, | w, h, x, y, 1, sort_l, | |||
PREF_KEYR_EXPORT_FILENAME, | PREF_KEYR_EXPORT_FILENAME, | |||
type_text, | type_text, | |||
type_int, | type_int, | |||
cb_keyr_update_clist, | cb_keyr_export_init_treeView, | |||
cb_keyr_export_done, | cb_keyr_update_listStore, | |||
cb_keyr_export_ok | cb_keyr_export_done, | |||
); | cb_keyr_export_ok | |||
); | ||||
return EXIT_SUCCESS; | ||||
} | ||||
static GtkWidget *cb_keyr_export_init_treeView() { | ||||
GtkListStore *listStore = gtk_list_store_new(KEYRING_NUM_COLS, G_TYPE_STRING | ||||
, G_TYPE_STRING, G_TYPE_STRING, | ||||
G_TYPE_POINTER, GDK_TYPE_RGBA, | ||||
G_TYPE_BOOLEAN, G_TYPE_STRING, | ||||
G_TYPE_BOOLEAN); | ||||
GtkTreeModel *model = GTK_TREE_MODEL(listStore); | ||||
GtkWidget *keyr_treeView = gtk_tree_view_new_with_model(model); | ||||
GtkCellRenderer *changedRenderer = gtk_cell_renderer_text_new(); | ||||
GtkTreeViewColumn *changedColumn = gtk_tree_view_column_new_with_attributes( | ||||
"Changed", | ||||
changedRenderer, | ||||
"text", KEYRING_CHANGED_COLUMN_ENUM, | ||||
"cell-background-rgba", | ||||
KEYRING_BACKGROUND_COLOR_ENUM, | ||||
"cell-background-set", | ||||
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, | ||||
NULL); | ||||
gtk_tree_view_column_set_sort_column_id(changedColumn, KEYRING_CHANGED_COLUM | ||||
N_ENUM); | ||||
// gtk_cell_renderer_set_fixed_size(changedRenderer, -1, 1); | ||||
GtkCellRenderer *nameRenderer = gtk_cell_renderer_text_new(); | ||||
GtkTreeViewColumn *nameColumn = gtk_tree_view_column_new_with_attributes("Na | ||||
me", | ||||
nam | ||||
eRenderer, | ||||
"te | ||||
xt", KEYRING_NAME_COLUMN_ENUM, | ||||
"ce | ||||
ll-background-rgba", | ||||
KEY | ||||
RING_BACKGROUND_COLOR_ENUM, | ||||
"ce | ||||
ll-background-set", | ||||
KEY | ||||
RING_BACKGROUND_COLOR_ENABLED_ENUM, | ||||
NUL | ||||
L); | ||||
gtk_tree_view_column_set_sort_column_id(nameColumn, KEYRING_NAME_COLUMN_ENUM | ||||
); | ||||
// gtk_cell_renderer_set_fixed_size(nameRenderer, -1, 1); | ||||
GtkCellRenderer *accountRenderer = gtk_cell_renderer_text_new(); | ||||
GtkTreeViewColumn *accountColumn = gtk_tree_view_column_new_with_attributes( | ||||
"Account", | ||||
accountRenderer, | ||||
"text", KEYRING_ACCOUNT_COLUMN_ENUM, | ||||
"cell-background-rgba", | ||||
KEYRING_BACKGROUND_COLOR_ENUM, | ||||
"cell-background-set", | ||||
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, | ||||
NULL); | ||||
gtk_tree_view_column_set_sort_column_id(accountColumn, KEYRING_ACCOUNT_COLUM | ||||
N_ENUM); | ||||
// gtk_cell_renderer_set_fixed_size(accountRenderer, -1, 1); | ||||
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), changedColumn, KEY | ||||
RING_CHANGED_COLUMN_ENUM); | ||||
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), nameColumn, KEYRIN | ||||
G_NAME_COLUMN_ENUM); | ||||
gtk_tree_view_insert_column(GTK_TREE_VIEW(keyr_treeView), accountColumn, KEY | ||||
RING_ACCOUNT_COLUMN_ENUM); | ||||
gtk_tree_view_column_set_sizing(changedColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE | ||||
); | ||||
gtk_tree_view_column_set_sizing(nameColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE); | ||||
gtk_tree_view_column_set_sizing(accountColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE | ||||
); | ||||
return EXIT_SUCCESS; | return GTK_WIDGET(keyr_treeView); | |||
} | } | |||
/* | /* | |||
* This is a plugin callback function called during Jpilot program exit. | * This is a plugin callback function called during Jpilot program exit. | |||
*/ | */ | |||
int plugin_exit_cleanup(void) | int plugin_exit_cleanup(void) { | |||
{ | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_exit_cleanup\n"); | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_exit_cleanup\n"); | return EXIT_SUCCESS; | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This is a plugin callback function called when the plugin is terminated | * This is a plugin callback function called when the plugin is terminated | |||
* such as by switching to another application(ToDo, Memo, etc.) | * such as by switching to another application(ToDo, Memo, etc.) | |||
*/ | */ | |||
int plugin_gui_cleanup(void) { | int plugin_gui_cleanup(void) { | |||
int b; | int b; | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_gui_cleanup\n"); | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin_gui_cleanup\n"); | |||
b=dialog_save_changed_record(clist, record_changed); | b = dialog_save_changed_record(GTK_WIDGET(treeView), record_changed); | |||
if (b==DIALOG_SAID_2) { | if (b == DIALOG_SAID_2) { | |||
cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | cb_add_new_record(NULL, GINT_TO_POINTER(record_changed)); | |||
} | } | |||
connect_changed_signals(DISCONNECT_SIGNALS); | connect_changed_signals(DISCONNECT_SIGNALS); | |||
free_mykeyring_list(&glob_keyring_list); | free_mykeyring_list(&glob_keyring_list); | |||
/* if the password was correct */ | /* if the password was correct */ | |||
if (plugin_last_time && (TRUE == plugin_active)) { | if (plugin_last_time && (TRUE == plugin_active)) { | |||
plugin_last_time = time(NULL); | plugin_last_time = time(NULL); | |||
} | } | |||
plugin_active = FALSE; | plugin_active = FALSE; | |||
/* the pane may not exist if the wrong password is entered and | /* the pane may not exist if the wrong password is entered and | |||
* the GUI was not built */ | * the GUI was not built */ | |||
if (pane) | if (pane) { | |||
{ | /* Remove the accelerators */ | |||
/* Remove the accelerators */ | ||||
#ifndef ENABLE_STOCK_BUTTONS | #ifndef ENABLE_STOCK_BUTTONS | |||
gtk_window_remove_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(pane)), a ccel_group); | gtk_window_remove_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(pane)), accel_group); | |||
#endif | #endif | |||
/* Record the position of the window pane to restore later */ | /* Record the position of the window pane to restore later */ | |||
set_pref(PREF_KEYRING_PANE, gtk_paned_get_position(GTK_PANED(pane)), NULL, | set_pref(PREF_KEYRING_PANE, gtk_paned_get_position(GTK_PANED(pane)), NUL | |||
TRUE); | L, TRUE); | |||
pane = NULL; | ||||
pane = NULL; | gtk_list_store_clear(listStore); | |||
} | ||||
return EXIT_SUCCESS; | ||||
} | ||||
clist_clear(GTK_CLIST(clist)); | static void column_clicked_cb(GtkTreeViewColumn *column) { | |||
} | column_selected = gtk_tree_view_column_get_sort_column_id(column); | |||
return EXIT_SUCCESS; | ||||
} | } | |||
/* | /* | |||
* This function is called by J-Pilot when the user selects this plugin | * This function is called by J-Pilot when the user selects this plugin | |||
* from the plugin menu, or from the search window when a search result | * from the plugin menu, or from the search window when a search result | |||
* record is chosen. In the latter case, unique ID will be set. This | * record is chosen. In the latter case, unique ID will be set. This | |||
* application should go directly to that record in the case. | * application should go directly to that record in the case. | |||
*/ | */ | |||
int plugin_gui(GtkWidget *vbox, GtkWidget *hbox, unsigned int unique_id) | int plugin_gui(GtkWidget *vbox, GtkWidget *hbox, unsigned int unique_id) { | |||
{ | GtkWidget *vbox1, *vbox2; | |||
GtkWidget *vbox1, *vbox2; | GtkWidget *hbox_temp; | |||
GtkWidget *hbox_temp; | GtkWidget *button; | |||
GtkWidget *button; | GtkWidget *label; | |||
GtkWidget *label; | //gtk3 GtkWidget *table; | |||
GtkWidget *table; | GtkWidget *grid; | |||
GtkWindow *w; | GtkWindow *w; | |||
GtkWidget *separator; | GtkWidget *separator; | |||
long ivalue; | long ivalue; | |||
char ascii_password[PASSWD_LEN]; | char ascii_password[PASSWD_LEN]; | |||
int r; | int r; | |||
int password_not_correct; | int password_not_correct; | |||
char *titles[3]; /* { "Changed", "Name", "Account" }; */ | int retry; | |||
int retry; | int cycle_category = FALSE; | |||
int cycle_category = FALSE; | long char_set; | |||
long char_set; | long show_tooltips; | |||
long show_tooltips; | char *cat_name; | |||
char *cat_name; | int new_cat; | |||
int new_cat; | int index, index2; | |||
int index, index2; | int i; | |||
int i; | ||||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
static int gcrypt_init = 0; | static int gcrypt_init = 0; | |||
#endif | #endif | |||
jp_logf(JP_LOG_DEBUG, "KeyRing: plugin gui started, unique_id=%d\n", unique_i d); | jp_logf(JP_LOG_DEBUG, "KeyRing: plugin gui started, unique_id=%d\n", unique_ id); | |||
if (check_for_db()) { | if (check_for_db()) { | |||
return EXIT_FAILURE; | return EXIT_FAILURE; | |||
} | } | |||
#ifdef HAVE_LIBGCRYPT | #ifdef HAVE_LIBGCRYPT | |||
if (!gcrypt_init) | if (!gcrypt_init) { | |||
{ | gcrypt_init = 1; | |||
gcrypt_init = 1; | ||||
/* Version check should be the very first call because it | ||||
/* Version check should be the very first call because it | makes sure that important subsystems are intialized. */ | |||
makes sure that important subsystems are intialized. */ | if (!gcry_check_version(GCRYPT_VERSION)) { | |||
if (!gcry_check_version (GCRYPT_VERSION)) | fputs("libgcrypt version mismatch\n", stderr); | |||
{ | return EXIT_FAILURE; | |||
fputs ("libgcrypt version mismatch\n", stderr); | } | |||
return EXIT_FAILURE; | ||||
} | /* We don't want to see any warnings, e.g. because we have not yet | |||
parsed program options which might be used to suppress such | ||||
/* We don't want to see any warnings, e.g. because we have not yet | warnings. */ | |||
parsed program options which might be used to suppress such | gcry_control(GCRYCTL_SUSPEND_SECMEM_WARN); | |||
warnings. */ | ||||
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); | /* ... If required, other initialization goes here. Note that the | |||
process might still be running with increased privileges and that | ||||
/* ... If required, other initialization goes here. Note that the | the secure memory has not been intialized. */ | |||
process might still be running with increased privileges and that | ||||
the secure memory has not been intialized. */ | /* Allocate a pool of 16k secure memory. This make the secure memory | |||
available and also drops privileges where needed. */ | ||||
/* Allocate a pool of 16k secure memory. This make the secure memory | gcry_control(GCRYCTL_INIT_SECMEM, 16384, 0); | |||
available and also drops privileges where needed. */ | ||||
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); | /* It is now okay to let Libgcrypt complain when there was/is | |||
a problem with the secure memory. */ | ||||
/* It is now okay to let Libgcrypt complain when there was/is | gcry_control(GCRYCTL_RESUME_SECMEM_WARN); | |||
a problem with the secure memory. */ | ||||
gcry_control (GCRYCTL_RESUME_SECMEM_WARN); | /* ... If required, other initialization goes here. */ | |||
/* ... If required, other initialization goes here. */ | /* Tell Libgcrypt that initialization has completed. */ | |||
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); | ||||
/* Tell Libgcrypt that initialization has completed. */ | } | |||
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); | ||||
} | ||||
#endif | #endif | |||
/* Find the main window from some widget */ | /* Find the main window from some widget */ | |||
w = GTK_WINDOW(gtk_widget_get_toplevel(hbox)); | w = GTK_WINDOW(gtk_widget_get_toplevel(hbox)); | |||
#if 0 | #if 0 | |||
/* Change Password button */ | /* Change Password button */ | |||
button = gtk_button_new_with_label(_("Change\nKeyRing\nPassword")); | button = gtk_button_new_with_label(_("Change\nKeyRing\nPassword")); | |||
gtk_signal_connect(GTK_OBJECT(button), "clicked", | g_signal_connect(G_OBJECT(button), "clicked", | |||
GTK_SIGNAL_FUNC(cb_change_password), NULL); | G_CALLBACK(cb_change_password), NULL); | |||
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); | gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); | |||
#endif | #endif | |||
if (difftime(time(NULL), plugin_last_time) > PLUGIN_MAX_INACTIVE_TIME) { | if (difftime(time(NULL), plugin_last_time) > PLUGIN_MAX_INACTIVE_TIME) { | |||
/* reset last time we entered */ | /* reset last time we entered */ | |||
plugin_last_time = 0; | plugin_last_time = 0; | |||
password_not_correct = TRUE; | password_not_correct = TRUE; | |||
retry = PASSWD_ENTER; | retry = PASSWD_ENTER; | |||
while (password_not_correct) { | while (password_not_correct) { | |||
r = dialog_password(w, ascii_password, retry); | r = dialog_password(w, ascii_password, retry); | |||
retry = PASSWD_ENTER_RETRY; | retry = PASSWD_ENTER_RETRY; | |||
if (r != 2) { | if (r != 2) { | |||
memset(ascii_password, 0, PASSWD_LEN-1); | memset(ascii_password, 0, PASSWD_LEN - 1); | |||
return 0; | return 0; | |||
} | } | |||
password_not_correct = (verify_pasword(ascii_password) > 0); | password_not_correct = (verify_pasword(ascii_password) > 0); | |||
} | } | |||
memset(ascii_password, 0, PASSWD_LEN-1); | memset(ascii_password, 0, PASSWD_LEN - 1); | |||
} else { | } else { | |||
cycle_category = TRUE; | cycle_category = TRUE; | |||
} | } | |||
/* called to display the result of a search */ | ||||
if (unique_id) { | ||||
cycle_category = FALSE; | ||||
} | ||||
/* plugin entered with correct password */ | ||||
plugin_last_time = time(NULL); | ||||
plugin_active = TRUE; | ||||
/************************************************************/ | ||||
/* Build GUI */ | ||||
record_changed=CLEAR_FLAG; | ||||
clist_row_selected = 0; | ||||
/* Do some initialization */ | ||||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | ||||
keyr_cat_menu_item2[i] = NULL; | ||||
} | ||||
get_keyr_cat_info(&keyr_app_info); | ||||
get_pref(PREF_CHAR_SET, &char_set, NULL); | ||||
for (i=1; i<NUM_KEYRING_CAT_ITEMS; i++) { | ||||
cat_name = charset_p2newj(keyr_app_info.name[i], 31, char_set); | ||||
strcpy(sort_l[i-1].Pcat, cat_name); | ||||
free(cat_name); | ||||
sort_l[i-1].cat_num = i; | ||||
} | ||||
/* put reserved 'Unfiled' category at end of list */ | ||||
cat_name = charset_p2newj(keyr_app_info.name[0], 31, char_set); | ||||
strcpy(sort_l[NUM_KEYRING_CAT_ITEMS-1].Pcat, cat_name); | ||||
free(cat_name); | ||||
sort_l[NUM_KEYRING_CAT_ITEMS-1].cat_num = 0; | ||||
qsort(sort_l, NUM_KEYRING_CAT_ITEMS-1, sizeof(struct sorted_cats), cat_compar | /* called to display the result of a search */ | |||
e); | if (unique_id) { | |||
cycle_category = FALSE; | ||||
} | ||||
/* plugin entered with correct password */ | ||||
plugin_last_time = time(NULL); | ||||
plugin_active = TRUE; | ||||
/************************************************************/ | ||||
/* Build GUI */ | ||||
record_changed = CLEAR_FLAG; | ||||
row_selected = 0; | ||||
/* Do some initialization */ | ||||
get_keyr_cat_info(&keyr_app_info); | ||||
get_pref(PREF_CHAR_SET, &char_set, NULL); | ||||
for (i = 1; i < NUM_KEYRING_CAT_ITEMS; i++) { | ||||
cat_name = charset_p2newj(keyr_app_info.name[i], 31, char_set); | ||||
strcpy(sort_l[i - 1].Pcat, cat_name); | ||||
free(cat_name); | ||||
sort_l[i - 1].cat_num = i; | ||||
} | ||||
/* put reserved 'Unfiled' category at end of list */ | ||||
cat_name = charset_p2newj(keyr_app_info.name[0], 31, char_set); | ||||
strcpy(sort_l[NUM_KEYRING_CAT_ITEMS - 1].Pcat, cat_name); | ||||
free(cat_name); | ||||
sort_l[NUM_KEYRING_CAT_ITEMS - 1].cat_num = 0; | ||||
qsort(sort_l, NUM_KEYRING_CAT_ITEMS - 1, sizeof(struct sorted_cats), cat_com | ||||
pare); | ||||
#ifdef JPILOT_DEBUG | #ifdef JPILOT_DEBUG | |||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | |||
printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat); | printf("cat %d [%s]\n", sort_l[i].cat_num, sort_l[i].Pcat); | |||
} | } | |||
#endif | #endif | |||
if (keyr_category > NUM_KEYRING_CAT_ITEMS) { | if (keyr_category > NUM_KEYRING_CAT_ITEMS) { | |||
keyr_category = CATEGORY_ALL; | keyr_category = CATEGORY_ALL; | |||
} | } | |||
/* Make accelerators for some buttons window */ | /* Make accelerators for some buttons window */ | |||
#ifndef ENABLE_STOCK_BUTTONS | #ifndef ENABLE_STOCK_BUTTONS | |||
accel_group = gtk_accel_group_new(); | accel_group = gtk_accel_group_new(); | |||
gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)), accel_g | gtk_window_add_accel_group(GTK_WINDOW(gtk_widget_get_toplevel(vbox)), accel_ | |||
roup); | group); | |||
#endif | #endif | |||
get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL); | get_pref(PREF_SHOW_TOOLTIPS, &show_tooltips, NULL); | |||
pane = gtk_hpaned_new(); | pane = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); | |||
get_pref(PREF_KEYRING_PANE, &ivalue, NULL); | get_pref(PREF_KEYRING_PANE, &ivalue, NULL); | |||
gtk_paned_set_position(GTK_PANED(pane), ivalue); | gtk_paned_set_position(GTK_PANED(pane), ivalue); | |||
gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5); | gtk_box_pack_start(GTK_BOX(hbox), pane, TRUE, TRUE, 5); | |||
/* left and right main boxes */ | /* left and right main boxes */ | |||
vbox1 = gtk_vbox_new(FALSE, 0); | vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); | |||
vbox2 = gtk_vbox_new(FALSE, 0); | vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); | |||
gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE); | gtk_paned_pack1(GTK_PANED(pane), vbox1, TRUE, FALSE); | |||
gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE); | gtk_paned_pack2(GTK_PANED(pane), vbox2, TRUE, FALSE); | |||
gtk_widget_set_usize(GTK_WIDGET(vbox1), 0, 230); | gtk_widget_set_size_request(GTK_WIDGET(vbox1), 0, 230); | |||
gtk_widget_set_usize(GTK_WIDGET(vbox2), 0, 230); | gtk_widget_set_size_request(GTK_WIDGET(vbox2), 0, 230); | |||
/**********************************************************************/ | /**********************************************************************/ | |||
/* Left half of screen */ | /* Left half of screen */ | |||
/**********************************************************************/ | /**********************************************************************/ | |||
/* Left-side Category menu */ | /* Left-side Category menu */ | |||
hbox_temp = gtk_hbox_new(FALSE, 0); | hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); | |||
gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0); | gtk_box_pack_start(GTK_BOX(vbox1), hbox_temp, FALSE, FALSE, 0); | |||
make_category_menu(&category_menu1, keyr_cat_menu_item1, | make_category_menu(&category_menu1, | |||
sort_l, cb_category, TRUE, FALSE); | sort_l, cb_category, TRUE, FALSE); | |||
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0); | ||||
gtk_box_pack_start(GTK_BOX(hbox_temp), category_menu1, TRUE, TRUE, 0); | ||||
/* Scrolled window */ | ||||
scrolled_window = gtk_scrolled_window_new(NULL, NULL); | /* Scrolled window */ | |||
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0); | scrolled_window = gtk_scrolled_window_new(NULL, NULL); | |||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), | gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 0); | |||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), | |||
gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0); | GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |||
gtk_box_pack_start(GTK_BOX(vbox1), scrolled_window, TRUE, TRUE, 0); | ||||
/* Clist */ | ||||
titles[0] = _("Changed"); | /* listStore */ | |||
titles[1] = _("Name"); | listStore = gtk_list_store_new(KEYRING_NUM_COLS, G_TYPE_STRING, G_TYPE_STRIN | |||
titles[2] = _("Account"); | G, G_TYPE_STRING, | |||
clist = gtk_clist_new_with_titles(3, titles); | G_TYPE_POINTER, GDK_TYPE_RGBA, G_TYPE_BOOLEAN | |||
, G_TYPE_STRING, G_TYPE_BOOLEAN); | ||||
gtk_clist_column_titles_active(GTK_CLIST(clist)); | GtkTreeModel *model = GTK_TREE_MODEL(listStore); | |||
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), KEYR_CHGD_COLUMN, TRUE); | treeView = gtk_tree_view_new_with_model(model); | |||
gtk_clist_set_column_width(GTK_CLIST(clist), KEYR_NAME_COLUMN, 150); | GtkCellRenderer *changedRenderer = gtk_cell_renderer_text_new(); | |||
GtkTreeViewColumn *changedColumn = gtk_tree_view_column_new_with_attributes( | ||||
gtk_clist_set_sort_column(GTK_CLIST(clist), KEYR_NAME_COLUMN); | _("Changed"), | |||
gtk_clist_set_compare_func(GTK_CLIST(clist), GtkClistKeyrCompareNocase); | ||||
gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); | changedRenderer, | |||
gtk_clist_set_shadow_type(GTK_CLIST(clist), SHADOW); | ||||
gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_BROWSE); | "text", KEYRING_CHANGED_COLUMN_ENUM, | |||
gtk_signal_connect(GTK_OBJECT(clist), "click_column", | "cell-background-rgba", | |||
GTK_SIGNAL_FUNC (cb_clist_click_column), NULL); | ||||
KEYRING_BACKGROUND_COLOR_ENUM, | ||||
gtk_signal_connect(GTK_OBJECT(clist), "select_row", | ||||
GTK_SIGNAL_FUNC(cb_clist_selection), | "cell-background-set", | |||
NULL); | ||||
KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, | ||||
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(clist)); | ||||
NULL); | ||||
/**********************************************************************/ | gtk_tree_view_column_set_sort_column_id(changedColumn, KEYRING_CHANGED_COLUM | |||
/* Right half of screen */ | N_ENUM); | |||
/**********************************************************************/ | GtkCellRenderer *nameRenderer = gtk_cell_renderer_text_new(); | |||
hbox_temp = gtk_hbox_new(FALSE, 3); | GtkTreeViewColumn *nameColumn = gtk_tree_view_column_new_with_attributes(_(" | |||
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); | Name"), | |||
nam | ||||
/* Cancel button */ | eRenderer, | |||
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modifi | "te | |||
cations"), GDK_Escape, 0, "ESC") | xt", KEYRING_NAME_COLUMN_ENUM, | |||
gtk_signal_connect(GTK_OBJECT(cancel_record_button), "clicked", | "ce | |||
GTK_SIGNAL_FUNC(cb_cancel), NULL); | ll-background-rgba", | |||
KEY | ||||
/* Delete button */ | RING_BACKGROUND_COLOR_ENUM, | |||
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the select | "ce | |||
ed record"), GDK_d, GDK_CONTROL_MASK, "Ctrl+D"); | ll-background-set", | |||
gtk_signal_connect(GTK_OBJECT(delete_record_button), "clicked", | KEY | |||
GTK_SIGNAL_FUNC(cb_delete_keyring), | RING_BACKGROUND_COLOR_ENABLED_ENUM, | |||
GINT_TO_POINTER(DELETE_FLAG)); | NUL | |||
L); | ||||
/* Undelete button */ | gtk_tree_view_column_set_sort_column_id(nameColumn, KEYRING_NAME_COLUMN_ENUM | |||
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete th | ); | |||
e selected record"), 0, 0, "") | GtkCellRenderer *accountRenderer = gtk_cell_renderer_text_new(); | |||
gtk_signal_connect(GTK_OBJECT(undelete_record_button), "clicked", | GtkTreeViewColumn *accountColumn = gtk_tree_view_column_new_with_attributes( | |||
GTK_SIGNAL_FUNC(cb_undelete_keyring), | _("Account"), | |||
GINT_TO_POINTER(UNDELETE_FLAG)); | ||||
accountRenderer, | ||||
/* Copy button */ | ||||
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected recor | "text", KEYRING_ACCOUNT_COLUMN_ENUM, | |||
d"), GDK_c, GDK_CONTROL_MASK|GDK_SHIFT_MASK, "Ctrl+Shift+C") | ||||
gtk_signal_connect(GTK_OBJECT(copy_record_button), "clicked", | "cell-background-rgba", | |||
GTK_SIGNAL_FUNC(cb_add_new_record), | ||||
GINT_TO_POINTER(COPY_FLAG)); | KEYRING_BACKGROUND_COLOR_ENUM, | |||
/* New Record button */ | "cell-background-set", | |||
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record"), | ||||
GDK_n, GDK_CONTROL_MASK, "Ctrl+N") | KEYRING_BACKGROUND_COLOR_ENABLED_ENUM, | |||
gtk_signal_connect(GTK_OBJECT(new_record_button), "clicked", | ||||
GTK_SIGNAL_FUNC(cb_add_new_record), | NULL); | |||
GINT_TO_POINTER(CLEAR_FLAG)); | gtk_tree_view_column_set_sort_column_id(accountColumn, KEYRING_ACCOUNT_COLUM | |||
N_ENUM); | ||||
/* Add Record button */ | gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), changedColumn, KEYRING_ | |||
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record" | CHANGED_COLUMN_ENUM); | |||
), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") | gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), nameColumn, KEYRING_NAM | |||
gtk_signal_connect(GTK_OBJECT(add_record_button), "clicked", | E_COLUMN_ENUM); | |||
GTK_SIGNAL_FUNC(cb_add_new_record), | gtk_tree_view_insert_column(GTK_TREE_VIEW(treeView), accountColumn, KEYRING_ | |||
GINT_TO_POINTER(NEW_FLAG)); | ACCOUNT_COLUMN_ENUM); | |||
gtk_tree_view_column_set_clickable(changedColumn, gtk_true()); | ||||
gtk_tree_view_column_set_clickable(nameColumn, gtk_true()); | ||||
gtk_tree_view_column_set_clickable(accountColumn, gtk_true()); | ||||
gtk_tree_view_column_set_sizing(changedColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE | ||||
); | ||||
gtk_tree_view_column_set_fixed_width(nameColumn, 150); | ||||
gtk_tree_view_column_set_sizing(accountColumn, GTK_TREE_VIEW_COLUMN_AUTOSIZE | ||||
); | ||||
gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeVi | ||||
ew)), | ||||
GTK_SELECTION_BROWSE); | ||||
GtkTreeSortable *sortable = GTK_TREE_SORTABLE(listStore); | ||||
gtk_tree_sortable_set_sort_func(sortable, KEYRING_CHANGED_COLUMN_ENUM, GtkTr | ||||
eeModelKeyrCompareDates, | ||||
GINT_TO_POINTER(KEYRING_CHANGED_COLUMN_ENUM) | ||||
, NULL); | ||||
gtk_tree_sortable_set_sort_func(sortable, KEYRING_NAME_COLUMN_ENUM, GtkTreeM | ||||
odelKeyrCompareNocase, | ||||
GINT_TO_POINTER(KEYRING_NAME_COLUMN_ENUM), N | ||||
ULL); | ||||
for (int x = 0; x < KEYRING_NUM_COLS - 5; x++) { | ||||
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TRE | ||||
E_VIEW(treeView), x), gtk_false()); | ||||
} | ||||
gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(GTK_TREE_VI | ||||
EW(treeView), column_selected), | ||||
gtk_true()); | ||||
gtk_widget_set_events(GTK_WIDGET(treeView), GDK_BUTTON1_MOTION_MASK); | ||||
g_signal_connect (G_OBJECT(treeView), "motion_notify_event", | ||||
G_CALLBACK(motion_notify_event), NULL); | ||||
g_signal_connect (G_OBJECT(treeView), "button-press-event", | ||||
G_CALLBACK(button_pressed_for_motion), NULL); | ||||
g_signal_connect (G_OBJECT(treeView), "button-release-event", | ||||
G_CALLBACK(button_released_for_motion), NULL); | ||||
g_signal_connect (changedColumn, "clicked", G_CALLBACK(column_clicked_cb), N | ||||
ULL); | ||||
g_signal_connect (nameColumn, "clicked", G_CALLBACK(column_clicked_cb), NULL | ||||
); | ||||
g_signal_connect (accountColumn, "clicked", G_CALLBACK(column_clicked_cb), N | ||||
ULL); | ||||
GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW( | ||||
treeView)); | ||||
gtk_tree_selection_set_select_function(treeSelection, handleKeyringRowSelect | ||||
ion, NULL, NULL); | ||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window), | ||||
GTK_POLICY_NEVER, | ||||
GTK_POLICY_AUTOMATIC); | ||||
gtk_container_add(GTK_CONTAINER(scrolled_window), GTK_WIDGET(treeView)); | ||||
/**********************************************************************/ | ||||
/* Right half of screen */ | ||||
/**********************************************************************/ | ||||
hbox_temp = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3); | ||||
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, FALSE, FALSE, 0); | ||||
/* Cancel button */ | ||||
CREATE_BUTTON(cancel_record_button, _("Cancel"), CANCEL, _("Cancel the modif | ||||
ications"), GDK_KEY_Escape, 0, "ESC") | ||||
g_signal_connect(G_OBJECT(cancel_record_button), "clicked", | ||||
G_CALLBACK(cb_cancel), NULL); | ||||
/* Delete button */ | ||||
CREATE_BUTTON(delete_record_button, _("Delete"), DELETE, _("Delete the selec | ||||
ted record"), GDK_d, GDK_CONTROL_MASK, | ||||
"Ctrl+D"); | ||||
g_signal_connect(G_OBJECT(delete_record_button), "clicked", | ||||
G_CALLBACK(cb_delete_keyring), | ||||
GINT_TO_POINTER(DELETE_FLAG)); | ||||
/* Undelete button */ | ||||
CREATE_BUTTON(undelete_record_button, _("Undelete"), UNDELETE, _("Undelete t | ||||
he selected record"), 0, 0, "") | ||||
g_signal_connect(G_OBJECT(undelete_record_button), "clicked", | ||||
G_CALLBACK(cb_undelete_keyring), | ||||
GINT_TO_POINTER(UNDELETE_FLAG)); | ||||
/* Copy button */ | ||||
CREATE_BUTTON(copy_record_button, _("Copy"), COPY, _("Copy the selected reco | ||||
rd"), GDK_c, | ||||
GDK_CONTROL_MASK | GDK_SHIFT_MASK, "Ctrl+Shift+C") | ||||
g_signal_connect(G_OBJECT(copy_record_button), "clicked", | ||||
G_CALLBACK(cb_add_new_record), | ||||
GINT_TO_POINTER(COPY_FLAG)); | ||||
/* New Record button */ | ||||
CREATE_BUTTON(new_record_button, _("New Record"), NEW, _("Add a new record") | ||||
, GDK_n, GDK_CONTROL_MASK, "Ctrl+N") | ||||
g_signal_connect(G_OBJECT(new_record_button), "clicked", | ||||
G_CALLBACK(cb_add_new_record), | ||||
GINT_TO_POINTER(CLEAR_FLAG)); | ||||
/* Add Record button */ | ||||
CREATE_BUTTON(add_record_button, _("Add Record"), ADD, _("Add the new record | ||||
"), GDK_KEY_Return, GDK_CONTROL_MASK, | ||||
"Ctrl+Enter") | ||||
g_signal_connect(G_OBJECT(add_record_button), "clicked", | ||||
G_CALLBACK(cb_add_new_record), | ||||
GINT_TO_POINTER(NEW_FLAG)); | ||||
#ifndef ENABLE_STOCK_BUTTONS | #ifndef ENABLE_STOCK_BUTTONS | |||
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(add_record_button)->child)), "label_high"); | gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(add_recor d_button)))), "label_high"); | |||
#endif | #endif | |||
/* Apply Changes button */ | /* Apply Changes button */ | |||
CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the m | CREATE_BUTTON(apply_record_button, _("Apply Changes"), APPLY, _("Commit the | |||
odifications"), GDK_Return, GDK_CONTROL_MASK, "Ctrl+Enter") | modifications"), GDK_KEY_Return, | |||
gtk_signal_connect(GTK_OBJECT(apply_record_button), "clicked", | GDK_CONTROL_MASK, "Ctrl+Enter") | |||
GTK_SIGNAL_FUNC(cb_add_new_record), | g_signal_connect(G_OBJECT(apply_record_button), "clicked", | |||
GINT_TO_POINTER(MODIFY_FLAG)); | G_CALLBACK(cb_add_new_record), | |||
GINT_TO_POINTER(MODIFY_FLAG)); | ||||
#ifndef ENABLE_STOCK_BUTTONS | #ifndef ENABLE_STOCK_BUTTONS | |||
gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(GTK_BIN(apply_record_button)->child) ), "label_high"); | gtk_widget_set_name(GTK_WIDGET(GTK_LABEL(gtk_bin_get_child(GTK_BIN(apply_rec ord_button)))), "label_high"); | |||
#endif | #endif | |||
/* Separator */ | /* Separator */ | |||
separator = gtk_hseparator_new(); | separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); | |||
gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5); | gtk_box_pack_start(GTK_BOX(vbox2), separator, FALSE, FALSE, 5); | |||
/* Table */ | /* Grid */ | |||
table = gtk_table_new(5, 10, FALSE); | grid = gtk_grid_new(); | |||
gtk_table_set_row_spacings(GTK_TABLE(table),0); | gtk_grid_set_column_homogeneous(GTK_GRID(grid), FALSE); | |||
gtk_table_set_col_spacings(GTK_TABLE(table),0); | gtk_box_pack_start(GTK_BOX(vbox2), grid, TRUE, TRUE, 5); | |||
gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0); | ||||
/* Category menu */ | ||||
/* Category menu */ | label = gtk_label_new(_("Category: ")); | |||
label = gtk_label_new(_("Category: ")); | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 0, 1); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
make_category_menu(&category_menu2, keyr_cat_menu_item2, | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END); | |||
sort_l, NULL, FALSE, FALSE); | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(category_menu2), 1, 10 | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 0, 1, 1); | |||
, 0, 1); | make_category_menu(&category_menu2, | |||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | sort_l, NULL, FALSE, FALSE); | |||
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(category_menu2), 1, 0, 2, 1); | ||||
/* Name entry */ | gtk_widget_set_halign(GTK_WIDGET(category_menu2), GTK_ALIGN_FILL); | |||
label = gtk_label_new(_("name: ")); | gtk_widget_set_valign(GTK_WIDGET(category_menu2), GTK_ALIGN_CENTER); | |||
entry_name = gtk_entry_new(); | gtk_widget_set_hexpand(GTK_WIDGET(category_menu2), TRUE); | |||
entry_set_multiline_truncate(GTK_ENTRY(entry_name), TRUE); | ||||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 1, 2); | /* Name entry */ | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_name), 1, 10, 1, | label = gtk_label_new(_("name: ")); | |||
2); | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END); | ||||
/* Account entry */ | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
label = gtk_label_new(_("account: ")); | entry_name = gtk_entry_new(); | |||
entry_account = gtk_entry_new(); | entry_set_multiline_truncate(GTK_ENTRY(entry_name), TRUE); | |||
entry_set_multiline_truncate(GTK_ENTRY(entry_account), TRUE); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 1, 1, 1); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 2, 3); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_name), 1, 1, 2, 1); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_account), 1, 10, | gtk_widget_set_halign(GTK_WIDGET(entry_name), GTK_ALIGN_FILL); | |||
2, 3); | gtk_widget_set_valign(GTK_WIDGET(entry_name), GTK_ALIGN_CENTER); | |||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | gtk_widget_set_hexpand(GTK_WIDGET(entry_name), TRUE); | |||
/* Password entry */ | /* Account entry */ | |||
label = gtk_label_new(_("password: ")); | label = gtk_label_new(_("account: ")); | |||
entry_password = gtk_entry_new(); | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 3, 4); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(entry_password), 1, 9, | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END); | |||
3, 4); | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | //gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_SHRINK) | |||
; | ||||
/* Last Changed entry */ | //gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_SHRINK) | |||
label = gtk_label_new(_("last changed: ")); | ; | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(label), 0, 1, 4, 5); | entry_account = gtk_entry_new(); | |||
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); | entry_set_multiline_truncate(GTK_ENTRY(entry_account), TRUE); | |||
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 2, 1, 1); | ||||
date_button = gtk_button_new_with_label(""); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_account), 1, 2, 2, 1); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(date_button), 1, 10, 4 | gtk_widget_set_halign(GTK_WIDGET(entry_account), GTK_ALIGN_FILL); | |||
, 5); | gtk_widget_set_valign(GTK_WIDGET(entry_account), GTK_ALIGN_FILL); | |||
gtk_signal_connect(GTK_OBJECT(date_button), "clicked", | gtk_widget_set_hexpand(GTK_WIDGET(entry_account), TRUE); | |||
GTK_SIGNAL_FUNC(cb_date_button), date_button); | ||||
/* Password entry */ | ||||
/* Generate Password button (creates random password) */ | label = gtk_label_new(_("password: ")); | |||
button = gtk_button_new_with_label(_("Generate Password")); | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(button), 9, 10, 3, 4); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
gtk_signal_connect(GTK_OBJECT(button), "clicked", | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END); | |||
GTK_SIGNAL_FUNC(cb_gen_password), entry_password); | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
entry_password = gtk_entry_new(); | ||||
/* Note textbox */ | gtk_widget_set_halign(GTK_WIDGET(entry_password), GTK_ALIGN_FILL); | |||
label = gtk_label_new(_("Note")); | gtk_widget_set_valign(GTK_WIDGET(entry_password), GTK_ALIGN_CENTER); | |||
gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0); | gtk_widget_set_hexpand(GTK_WIDGET(entry_password), TRUE); | |||
hbox_temp = gtk_hbox_new(FALSE, 0); | /* Generate Password button (creates random password) */ | |||
gtk_box_pack_start(GTK_BOX(vbox2), hbox_temp, TRUE, TRUE, 0); | button = gtk_button_new_with_label(_("Generate Password")); | |||
g_signal_connect(G_OBJECT(button), "clicked", | ||||
keyr_note = gtk_text_view_new(); | G_CALLBACK(cb_gen_password), entry_password); | |||
keyr_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyr_note) | ||||
)); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 3, 1, 1); | |||
gtk_text_view_set_editable(GTK_TEXT_VIEW(keyr_note), TRUE); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(entry_password), 1, 3, 1, 1); | |||
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyr_note), GTK_WRAP_WORD); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(button), 2, 3, 1, 1); | |||
scrolled_window = gtk_scrolled_window_new(NULL, NULL); | /* Last Changed entry */ | |||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), | label = gtk_label_new(_("last changed: ")); | |||
GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
gtk_container_add(GTK_CONTAINER(scrolled_window), keyr_note); | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_END); | |||
gtk_box_pack_start_defaults(GTK_BOX(hbox_temp), scrolled_window); | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
/**********************************************************************/ | date_button = gtk_button_new_with_label(""); | |||
g_signal_connect(G_OBJECT(date_button), "clicked", | ||||
gtk_widget_show_all(hbox); | G_CALLBACK(cb_date_button), date_button); | |||
gtk_widget_show_all(vbox); | gtk_widget_set_halign(GTK_WIDGET(date_button), GTK_ALIGN_FILL); | |||
gtk_widget_set_valign(GTK_WIDGET(date_button), GTK_ALIGN_CENTER); | ||||
gtk_widget_hide(add_record_button); | gtk_widget_set_hexpand(GTK_WIDGET(date_button), TRUE); | |||
gtk_widget_hide(apply_record_button); | ||||
gtk_widget_hide(undelete_record_button); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 4, 1, 1); | |||
gtk_widget_hide(cancel_record_button); | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(date_button), 1, 4, 2, 1); | |||
if (cycle_category) { | /* Note textbox */ | |||
/* First cycle keyr_category var */ | label = gtk_label_new(_("Note")); | |||
if (keyr_category == CATEGORY_ALL) { | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
new_cat = -1; | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
} else { | gtk_widget_set_hexpand(GTK_WIDGET(label), FALSE); | |||
new_cat = find_sort_cat_pos(keyr_category); | gtk_widget_set_vexpand(GTK_WIDGET(label), FALSE); | |||
} | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
for (i=0; i<NUM_KEYRING_CAT_ITEMS; i++) { | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_CENTER); | |||
new_cat++; | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(label), 0, 5, 3, 1); | |||
if (new_cat >= NUM_KEYRING_CAT_ITEMS) { | ||||
keyr_category = CATEGORY_ALL; | keyr_note = gtk_text_view_new(); | |||
break; | keyr_note_buffer = G_OBJECT(gtk_text_view_get_buffer(GTK_TEXT_VIEW(keyr_note | |||
} | ))); | |||
if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) { | gtk_text_view_set_editable(GTK_TEXT_VIEW(keyr_note), TRUE); | |||
keyr_category = sort_l[new_cat].cat_num; | gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(keyr_note), GTK_WRAP_WORD); | |||
break; | ||||
} | scrolled_window = gtk_scrolled_window_new(NULL, NULL); | |||
} | gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), | |||
/* Then update menu with new keyr_category */ | GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |||
if (keyr_category==CATEGORY_ALL) { | gtk_container_set_border_width(GTK_CONTAINER(scrolled_window), 1); | |||
index = 0; | gtk_container_add(GTK_CONTAINER(scrolled_window), keyr_note); | |||
index2 = 0; | gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(scrolled_window), 0, 6, 3, 1); | |||
} else { | ||||
index = find_sort_cat_pos(keyr_category); | // Make the scrolled_window take up extra space | |||
index2 = find_menu_cat_pos(index) + 1; | gtk_widget_set_halign(GTK_WIDGET(label), GTK_ALIGN_FILL); | |||
index += 1; | gtk_widget_set_valign(GTK_WIDGET(label), GTK_ALIGN_FILL); | |||
} | gtk_widget_set_hexpand(GTK_WIDGET(scrolled_window), TRUE); | |||
if (index<0) { | gtk_widget_set_vexpand(GTK_WIDGET(scrolled_window), TRUE); | |||
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | ||||
} else { | /**********************************************************************/ | |||
gtk_check_menu_item_set_active | ||||
(GTK_CHECK_MENU_ITEM(keyr_cat_menu_item1[index]), TRUE); | gtk_widget_show_all(hbox); | |||
gtk_option_menu_set_history(GTK_OPTION_MENU(category_menu1), index2); | gtk_widget_show_all(vbox); | |||
} | ||||
} | gtk_widget_hide(add_record_button); | |||
else | gtk_widget_hide(apply_record_button); | |||
{ | gtk_widget_hide(undelete_record_button); | |||
keyr_category = CATEGORY_ALL; | gtk_widget_hide(cancel_record_button); | |||
} | ||||
if (cycle_category) { | ||||
keyr_update_clist(clist, &glob_keyring_list, keyr_category, TRUE); | /* First cycle keyr_category var */ | |||
if (keyr_category == CATEGORY_ALL) { | ||||
if (unique_id) { | new_cat = -1; | |||
keyring_find(unique_id); | } else { | |||
} | new_cat = find_sort_cat_pos(keyr_category); | |||
} | ||||
for (i = 0; i < NUM_KEYRING_CAT_ITEMS; i++) { | ||||
new_cat++; | ||||
if (new_cat >= NUM_KEYRING_CAT_ITEMS) { | ||||
keyr_category = CATEGORY_ALL; | ||||
break; | ||||
} | ||||
if ((sort_l[new_cat].Pcat) && (sort_l[new_cat].Pcat[0])) { | ||||
keyr_category = sort_l[new_cat].cat_num; | ||||
break; | ||||
} | ||||
} | ||||
/* Then update menu with new keyr_category */ | ||||
if (keyr_category == CATEGORY_ALL) { | ||||
index = 0; | ||||
index2 = 0; | ||||
} else { | ||||
index = find_sort_cat_pos(keyr_category); | ||||
index2 = find_menu_cat_pos(index) + 1; | ||||
index += 1; | ||||
} | ||||
if (index < 0) { | ||||
jp_logf(JP_LOG_WARN, _("Category is not legal\n")); | ||||
} else { | ||||
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), index2); | ||||
} | ||||
} else { | ||||
keyr_category = CATEGORY_ALL; | ||||
gtk_combo_box_set_active(GTK_COMBO_BOX(category_menu1), 0); | ||||
} | ||||
keyr_update_liststore(listStore, &glob_keyring_list, keyr_category, TRUE); | ||||
if (unique_id) { | ||||
keyring_find(unique_id); | ||||
} | ||||
return EXIT_SUCCESS; | return EXIT_SUCCESS; | |||
} | } | |||
End of changes. 147 change blocks. | ||||
2377 lines changed or deleted | 2567 lines changed or added |