"Fossies" - the Fresh Open Source Software Archive 
Member "jpilot-2_0_1/jpilot-merge.c" (3 Apr 2021, 9762 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*******************************************************************************
2 * merge.c
3 * A module of J-Pilot http://jpilot.org
4 *
5 * Copyright (C) 2010-2014 by Judd Montgomery
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ******************************************************************************/
20
21 /********************************* Includes ***********************************/
22 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <dirent.h>
27 #include <sys/wait.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <signal.h>
32 #include <utime.h>
33 #include <stdio.h>
34 #include <ctype.h>
35 #ifdef HAVE_LOCALE_H
36 # include <locale.h>
37 #endif
38
39 /* Pilot-link header files */
40 #include <pi-source.h>
41 #include <pi-socket.h>
42 #include <pi-dlp.h>
43 #include <pi-file.h>
44
45 #include <gdk/gdk.h>
46
47 /* Jpilot header files */
48 #include "utils.h"
49 #include "i18n.h"
50 #include "otherconv.h"
51 #include "libplugin.h"
52 #include "sync.h"
53
54 /******************************* Global vars **********************************/
55 /* Start Hack */
56 /* FIXME: The following is a hack.
57 * The variables below are global variables in jpilot.c which are unused in
58 * this code but must be instantiated for the code to compile.
59 * The same is true of the functions which are only used in GUI mode. */
60 int pipe_to_parent = 0;
61 pid_t jpilot_master_pid = -1;
62 GtkWidget *glob_dialog;
63 GtkWidget *glob_date_label;
64 gint glob_date_timer_tag;
65
66 void output_to_pane(const char *str) {}
67 int sync_once(struct my_sync_info *sync_info) { return EXIT_SUCCESS; }
68 int jp_pack_Contact(struct Contact *c, pi_buffer_t *buf) { return 0; }
69 int edit_cats(GtkWidget *widget, char *db_name, struct CategoryAppInfo *cai)
70 {
71 return 0;
72 }
73 /* End Hack */
74
75 /****************************** Main Code *************************************/
76
77 static int read_pc_recs(char *file_name, GList **records)
78 {
79 FILE *pc_in;
80 int recs_returned;
81 buf_rec *temp_br;
82 int r;
83
84 /* Get the records out of the PC database */
85 pc_in = fopen(file_name, "r");
86 if (pc_in==NULL) {
87 fprintf(stderr, _("Unable to open file: %s\n"), file_name);
88 return -1;
89 }
90
91 while(!feof(pc_in)) {
92 temp_br = malloc(sizeof(buf_rec));
93 if (!temp_br) {
94 fprintf(stderr, _("Out of memory"));
95 recs_returned = -1;
96 break;
97 }
98 r = pc_read_next_rec(pc_in, temp_br);
99 if ((r==JPILOT_EOF) || (r<0)) {
100 free(temp_br);
101 break;
102 }
103
104 *records = g_list_prepend(*records, temp_br);
105 recs_returned++;
106
107 }
108 fclose(pc_in);
109
110 return 0;
111 }
112
113 static int merge_pdb_file(char *src_pdb_file,
114 char *src_pc_file,
115 char *dest_pdb_file)
116 {
117 struct pi_file *pf1, *pf2;
118 struct DBInfo infop;
119 void *app_info;
120 void *sort_info;
121 void *record;
122 int r;
123 int idx;
124 size_t size;
125 int attr;
126 int cat;
127 pi_uid_t uid;
128 buf_rec *temp_br_pdb;
129 buf_rec *temp_br_pc;
130 GList *Ppdb_record = NULL;
131 GList *Ppc_record = NULL;
132 GList *pdb_records = NULL;
133 GList *pc_records = NULL;
134 int dont_add;
135 unsigned int next_available_unique_id;
136 // Statistics
137 int pdb_count=0;
138 int recs_added = 0;
139 int recs_deleted = 0;
140 int recs_modified = 0;
141 int recs_written = 0;
142
143
144 if (access(src_pdb_file, R_OK)) {
145 fprintf(stderr, _("Unable to open file: %s\n"), src_pdb_file);
146 return 1;
147 }
148
149 if (access(src_pc_file, R_OK)) {
150 fprintf(stderr, _("Unable to open file: %s\n"), src_pc_file);
151 return 1;
152 }
153
154 r = read_pc_recs(src_pc_file, &pc_records);
155 if (r < 0) {
156 fprintf(stderr, "read_pc_recs returned %d\n", r);
157 exit(1);
158 }
159
160 pf1 = pi_file_open(src_pdb_file);
161 if (!pf1) {
162 fprintf(stderr, _("%s: Unable to open file:%s\n"), "pi_file_open", src_pdb_file);
163 exit(1);
164 }
165 pi_file_get_info(pf1, &infop);
166 pf2 = pi_file_create(dest_pdb_file, &infop);
167 if (!pf2) {
168 fprintf(stderr, _("%s: Unable to open file:%s\n"), "pi_file_open", dest_pdb_file);
169 exit(1);
170 }
171
172 pi_file_get_app_info(pf1, &app_info, &size);
173 pi_file_set_app_info(pf2, app_info, size);
174
175 pi_file_get_sort_info(pf1, &sort_info, &size);
176 pi_file_set_sort_info(pf2, sort_info, size);
177
178 for(idx=0;;idx++) {
179 r = pi_file_read_record(pf1, idx, &record, &size, &attr, &cat, &uid);
180 //printf("attr=%d, cat=%d\n", attr, cat);
181 if (r<0) break;
182
183 pdb_count++;
184
185 temp_br_pdb = malloc(sizeof(buf_rec));
186 temp_br_pdb->rt = PALM_REC;
187 temp_br_pdb->unique_id = uid;
188 temp_br_pdb->attrib = attr | cat;
189 //temp_br_pdb->buf = record;
190 temp_br_pdb->buf = malloc(size);
191 memcpy(temp_br_pdb->buf, record, size);
192 temp_br_pdb->size = size;
193
194 dont_add=0;
195
196 // Look through the pc record list
197 for (Ppc_record=pc_records; Ppc_record; Ppc_record=Ppc_record->next) {
198 temp_br_pc = (buf_rec *)Ppc_record->data;
199 if ((temp_br_pc->rt==DELETED_PC_REC) ||
200 (temp_br_pc->rt==DELETED_DELETED_PALM_REC)) {
201 continue;
202 }
203 if ((temp_br_pc->rt==DELETED_PALM_REC) ||
204 (temp_br_pc->rt==MODIFIED_PALM_REC)) {
205 if (temp_br_pdb->unique_id == temp_br_pc->unique_id) {
206 // Don't add it to the pdb list
207 dont_add=1;
208 if (temp_br_pc->rt==DELETED_PALM_REC) {
209 recs_deleted++;
210 }
211 break;
212 }
213 }
214
215 if ((temp_br_pc->rt==REPLACEMENT_PALM_REC)) {
216 if (temp_br_pdb->unique_id == temp_br_pc->unique_id) {
217 // Replace the record data in the pdb record with replacement record data
218 //printf("REPLACEMENT\n");
219 dont_add=1;
220 pdb_records = g_list_prepend(pdb_records, temp_br_pc);
221 recs_modified++;
222 //break;
223 }
224 }
225 }
226
227 if (! dont_add) {
228 pdb_records = g_list_prepend(pdb_records, temp_br_pdb);
229 }
230 }
231
232
233 // Find the next available unique ID
234 next_available_unique_id = 0;
235 for (Ppdb_record=pdb_records; Ppdb_record; Ppdb_record=Ppdb_record->next) {
236 temp_br_pdb = (buf_rec *)Ppdb_record->data;
237 if (temp_br_pdb->unique_id > next_available_unique_id) {
238 next_available_unique_id = temp_br_pdb->unique_id + 1;
239 }
240 }
241
242 // Add the NEW records to the list
243 for (Ppc_record=pc_records; Ppc_record; Ppc_record=Ppc_record->next) {
244 temp_br_pc = (buf_rec *)Ppc_record->data;
245 if ((temp_br_pc->rt==NEW_PC_REC)) {
246 temp_br_pc->unique_id = next_available_unique_id++;
247 pdb_records = g_list_prepend(pdb_records, temp_br_pc);
248 recs_added++;
249 continue;
250 }
251 }
252
253
254 pdb_records = g_list_reverse(pdb_records);
255
256 for (Ppdb_record=pdb_records; Ppdb_record; Ppdb_record=Ppdb_record->next) {
257 temp_br_pdb = (buf_rec *)Ppdb_record->data;
258 //printf("rt=%d\n", temp_br_pdb->rt);
259 //printf("unique_id=%d\n", temp_br_pdb->unique_id);
260 //printf("attrib=%d\n", temp_br_pdb->attrib);
261 //printf("buf=%ld\n", temp_br_pdb->buf);
262 //printf("size=%d\n", temp_br_pdb->size);
263 pi_file_append_record(pf2, temp_br_pdb->buf, temp_br_pdb->size, (temp_br_pdb->attrib)&0xF0, (temp_br_pdb->attrib)&0x0F, temp_br_pdb->unique_id);
264 recs_written++;
265 }
266
267 pi_file_close(pf1);
268 pi_file_close(pf2);
269
270 printf(_("Records read from pdb = %d\n"), pdb_count);
271 printf(_("Records added = %d\n"), recs_added);
272 printf(_("Records deleted = %d\n"), recs_deleted);
273 printf(_("Records modified = %d\n"), recs_modified);
274 printf(_("Records written = %d\n"), recs_written);
275
276 return 0;
277 }
278
279
280 int main(int argc, char *argv[])
281 {
282 /* enable internationalization(i18n) before printing any output */
283 #if defined(ENABLE_NLS)
284 # ifdef HAVE_LOCALE_H
285 setlocale(LC_ALL, "");
286 # endif
287 bindtextdomain(EPN, LOCALEDIR);
288 textdomain(EPN);
289 #endif
290
291 if (argc != 4) {
292 fprintf(stderr, _("Usage: %s {input pdb file} {input pc3 file} {output pdb file}\n"), argv[0]);
293 fprintf(stderr, _(" This program will merge an unsynced records file (pc3)\n"));
294 fprintf(stderr, _(" into the corresponding palm database (pdb) file.\n\n"));
295 fprintf(stderr, _(" WARNING: Only run this utility if you understand the consequences!\n"));
296 fprintf(stderr, _(" The merge will leave your databases in an unsync-able state.\n"));
297 fprintf(stderr, _(" It is intended for cases where J-pilot is being used as a standalone PIM\n"));
298 fprintf(stderr, _(" and where no syncing occurs to physical hardware.\n"));
299 fprintf(stderr, _(" WARNING: Make a backup copy of your databases before proceeding.\n"));
300 fprintf(stderr, _(" It is quite simple to destroy your databases by accidentally merging\n"));
301 fprintf(stderr, _(" address records into datebook databases, etc.\n"));
302
303 exit(EXIT_FAILURE);
304 }
305 char *in_pdb;
306 char *in_pc;
307 char *out_pdb;
308 in_pdb = argv[1];
309 in_pc = argv[2];
310 out_pdb = argv[3];
311
312 merge_pdb_file(in_pdb, in_pc, out_pdb);
313
314 return EXIT_SUCCESS;
315 }