1 /*      helper_functions.c
2  *
3  *      Copyright 2011 Hans Alves <alves.h88@gmail.com>
4  *
5  *      This program is free software; you can redistribute it and/or modify
6  *      it under the terms of the GNU General Public License as published by
7  *      the Free Software Foundation; either version 2 of the License, or
8  *      (at your option) any later version.
9  *
10  *      This program is distributed in the hope that it will be useful,
11  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *      GNU General Public License for more details.
14  *
15  *      You should have received a copy of the GNU General Public License
16  *      along with this program; if not, write to the Free Software
17  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  *      MA 02110-1301, USA.
19  */
20 
21 
22 #include "geanypg.h"
23 
geanypg_init_ed(encrypt_data * ed)24 void geanypg_init_ed(encrypt_data * ed)
25 {
26     ed->key_array = NULL;
27     ed->nkeys = 0;
28     ed->skey_array = NULL;
29     ed->nskeys = 0;
30 }
31 
geanypg_get_keys(encrypt_data * ed)32 int geanypg_get_keys(encrypt_data * ed)
33 {
34     gpgme_error_t err;
35     unsigned long size = SIZE;
36     /* initialize idx to 0 */
37     unsigned long idx = 0;
38     /* allocate array of size 1N */
39     gpgme_key_t * key;
40     ed->key_array = (gpgme_key_t*) malloc(SIZE * sizeof(gpgme_key_t));
41     err = gpgme_op_keylist_start(ed->ctx, NULL, 0);
42     while (!err)
43     {
44         key = ed->key_array + idx;
45         err = gpgme_op_keylist_next(ed->ctx, key);
46         if (err)
47             break;
48         if ((*key)->revoked  || /* key cannot be used */
49             (*key)->expired  ||
50             (*key)->disabled ||
51             (*key)->invalid)
52            gpgme_key_unref(*key);
53         else /* key is valid */
54             ++idx;
55         if (idx >= size)
56         {
57             size += SIZE;
58             ed->key_array = (gpgme_key_t*) realloc(ed->key_array, size * sizeof(gpgme_key_t));
59         }
60     }
61     ed->nkeys = idx;
62     if (gpg_err_code(err) != GPG_ERR_EOF)
63     {
64         geanypg_show_err_msg(err);
65         return 0;
66     }
67     return 1;
68 }
69 
geanypg_get_secret_keys(encrypt_data * ed)70 int geanypg_get_secret_keys(encrypt_data * ed)
71 {
72     gpgme_error_t err;
73     unsigned long size = SIZE;
74     /* initialize idx to 0 */
75     unsigned long idx = 0;
76     /* allocate array of size 1N */
77     gpgme_key_t * key;
78     ed->skey_array = (gpgme_key_t*) malloc(SIZE * sizeof(gpgme_key_t));
79     err = gpgme_op_keylist_start(ed->ctx, NULL, 1);
80     while (!err)
81     {
82         key = ed->skey_array + idx;
83         err = gpgme_op_keylist_next(ed->ctx, key);
84         if (err)
85             break;
86         if ((*key)->revoked  || /* key cannot be used */
87             (*key)->expired  ||
88             (*key)->disabled ||
89             (*key)->invalid)
90            gpgme_key_unref(*key);
91         else /* key is valid */
92             ++idx;
93         if (idx >= size)
94         {
95             size += SIZE;
96             ed->skey_array = (gpgme_key_t*) realloc(ed->skey_array, size * sizeof(gpgme_key_t));
97         }
98     }
99     ed->nskeys = idx;
100     if (gpg_err_code(err) != GPG_ERR_EOF)
101     {
102         geanypg_show_err_msg(err);
103         return 0;
104     }
105     return 1;
106 }
107 
geanypg_release_keys(encrypt_data * ed)108 void geanypg_release_keys(encrypt_data * ed)
109 {
110     gpgme_key_t * ptr;
111     if (ed->key_array)
112     {
113         ptr = ed->key_array;
114         while (ptr < ed->key_array + ed->nkeys)
115             gpgme_key_unref(*(ptr++));
116         free(ed->key_array);
117         ed->key_array = NULL;
118         ed->nkeys = 0;
119     }
120     if (ed->skey_array)
121     {
122         ptr = ed->skey_array;
123         while (ptr < ed->skey_array + ed->nskeys)
124             gpgme_key_unref(*(ptr++));
125         free(ed->skey_array);
126         ed->skey_array = NULL;
127         ed->nskeys = 0;
128     }
129 }
130 
131 
geanypg_load_buffer(gpgme_data_t * buffer)132 void geanypg_load_buffer(gpgme_data_t * buffer)
133 {
134     /* gpgme_data_new_from_mem(buffer, text, size, 0); */
135     GeanyDocument * doc = document_get_current();
136     char * data = NULL;
137     unsigned long size = 0;
138     if (sci_has_selection(doc->editor->sci))
139     {
140         size = scintilla_send_message(doc->editor->sci, SCI_GETSELTEXT, 0, 0) - 1;
141         data = (char *) malloc(size + 1);
142         scintilla_send_message(doc->editor->sci, SCI_GETSELTEXT, 0, (sptr_t)data);
143         gpgme_data_new_from_mem(buffer, data, size, 1);
144     }
145     else
146     {
147         size = scintilla_send_message(doc->editor->sci, SCI_GETLENGTH, 0, 0);
148         data = (char *) malloc(size + 1);
149         scintilla_send_message(doc->editor->sci, SCI_GETTEXT, (uptr_t)(size + 1), (sptr_t)data);
150         gpgme_data_new_from_mem(buffer, data, size, 1);
151     }
152     if (data) /* if there is no text data may still be NULL */
153         free(data);
154     gpgme_data_set_encoding(*buffer, GPGME_DATA_ENCODING_BINARY);
155 }
156 
geanypg_write_file(FILE * file)157 void geanypg_write_file(FILE * file)
158 {
159 #define BUFSIZE 2048
160     unsigned long size;
161     char buffer[BUFSIZE] = {0};
162     GeanyDocument * doc = document_get_current();
163     sci_start_undo_action(doc->editor->sci);
164     if (sci_has_selection(doc->editor->sci))
165     {   /* replace selected text
166          * clear selection, cursor should be at the end or beginneng of the selection */
167         scintilla_send_message(doc->editor->sci, SCI_REPLACESEL, 0, (sptr_t)"");
168         while ((size = fread(buffer, 1, BUFSIZE, file)))
169             /* add at the cursor */
170             scintilla_send_message(doc->editor->sci, SCI_ADDTEXT, (uptr_t) size, (sptr_t) buffer);
171     }
172     else
173     {   /* replace complete document */
174         scintilla_send_message(doc->editor->sci, SCI_CLEARALL, 0, 0);
175         while ((size = fread(buffer, 1, BUFSIZE, file)))
176             scintilla_send_message(doc->editor->sci, SCI_APPENDTEXT, (uptr_t) size, (sptr_t) buffer);
177     }
178     sci_end_undo_action(doc->editor->sci);
179 #undef BUFSIZE
180 }
181