summaryrefslogtreecommitdiffstats
path: root/debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c
diff options
context:
space:
mode:
Diffstat (limited to 'debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c')
-rw-r--r--debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c b/debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c
new file mode 100644
index 00000000..50156242
--- /dev/null
+++ b/debian/pilot-link/pilot-link-0.12.5-dfsg/src/pilot-dedupe.c
@@ -0,0 +1,275 @@
+/*
+ * $Id: pilot-dedupe.c,v 1.44 2006/10/12 14:21:21 desrod Exp $
+ *
+ * pilot-dedupe.c: Palm utility to remove duplicate records
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pi-header.h"
+#include "pi-source.h"
+#include "pi-dlp.h"
+#include "pi-userland.h"
+
+struct record {
+ struct record *next;
+ unsigned long id_;
+ char *data;
+ int cat;
+ int index;
+ int len;
+};
+
+/***********************************************************************
+ *
+ * Function: compare_r
+ *
+ * Summary: Compare records
+ *
+ * Parameters: None
+ *
+ * Returns: Nothing
+ *
+ ***********************************************************************/
+static int compare_r(const void *av, const void *bv)
+{
+ int i,
+ o;
+ struct record *a = *(struct record **) av;
+ struct record *b = *(struct record **) bv;
+
+ if (a->cat < b->cat)
+ o = -1;
+ else if (a->cat > b->cat)
+ o = 1;
+ else if (a->len < b->len)
+ o = -1;
+ else if (a->len > b->len)
+ o = 1;
+ else if ((i = memcmp(a->data, b->data, a->len)))
+ o = i;
+ else if (a->index < b->index)
+ o = -1;
+ else if (a->index > b->index)
+ o = 1;
+ else
+ o = 0;
+
+ return o;
+}
+
+static int DeDupe (int sd, const char *dbname)
+{
+ int c,
+ db,
+ dupe = 0,
+ j,
+ k,
+ l;
+ struct record *r,
+ **sortidx,
+ *records = NULL;
+ pi_buffer_t *buffer;
+ char buf[200];
+
+ /* Open the database, store access handle in db */
+ printf("Opening %s\n", dbname);
+ if (dlp_OpenDB(sd, 0, dlpOpenReadWrite, dbname, &db) < 0) {
+ printf("Unable to open %s\n", dbname);
+ return -1;
+ }
+
+ printf("Reading records...\n");
+
+ l = 0;
+ c = 0;
+ buffer = pi_buffer_new (0xffff);
+ for (;;) {
+ int attr,
+ cat;
+ recordid_t id_;
+ int len =
+ dlp_ReadRecordByIndex(sd, db, l,
+ buffer,
+ &id_,
+ &attr, &cat);
+
+ l++;
+
+ if (len < 0)
+ break;
+
+ /* Skip deleted records */
+ if ((attr & dlpRecAttrDeleted)
+ || (attr & dlpRecAttrArchived))
+ continue;
+
+ c++;
+
+ r = (struct record *)
+ malloc(sizeof(struct record));
+
+ r->data = (char *) malloc(buffer->used);
+ memcpy(r->data, buffer->data, buffer->used);
+ r->len = len;
+ r->cat = cat;
+ r->id_ = id_;
+ r->index = l;
+
+ r->next = records;
+ records = r;
+
+ }
+
+ pi_buffer_free (buffer);
+
+ sortidx = malloc(sizeof(struct record *) * c);
+
+ r = records;
+ for (k = 0; r && (k < c); k++, r = r->next)
+ sortidx[k] = r;
+
+ qsort(sortidx, c, sizeof(struct record *), compare_r);
+
+ printf("Scanning for duplicates...\n");
+
+ for (k = 0; k < c; k++) {
+ struct record *r2;
+ int d = 0;
+
+ r = sortidx[k];
+
+ if (r->len < 0)
+ continue;
+
+ for (j = k + 1; j < c; j++) {
+ r2 = sortidx[j];
+
+ if (r2->len < 0)
+ continue;
+
+ if ((r->len != r2->len)
+ || memcmp(r->data, r2->data, r->len))
+ break;
+
+ printf
+ ("Deleting record %d, duplicate #%d of record %d\n",
+ r2->index, ++d, r->index);
+ dupe++;
+ dlp_DeleteRecord(sd, db, 0, r2->id_);
+
+ r2->len = -1;
+ r2->id_ = 0;
+
+ }
+ k = j - 1;
+
+ }
+
+ free(sortidx);
+
+ while (records) {
+ if (records->data)
+ free(records->data);
+ r = records;
+ records = records->next;
+ free(r);
+ }
+
+ /* Close the database */
+ dlp_CloseDB(sd, db);
+ sprintf(buf, "Removed %d duplicates from %s\n", dupe,
+ dbname);
+ printf("%s", buf);
+ dlp_AddSyncLogEntry(sd, buf);
+
+ return 0;
+}
+
+
+
+int main(int argc, const char *argv[])
+{
+ int c, /* switch */
+ sd = -1;
+
+ const char
+ *db = NULL;
+
+ poptContext pc;
+
+ struct poptOption options[] = {
+ USERLAND_RESERVED_OPTIONS
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext("pilot-dedupe", argc, argv, options, 0);
+ poptSetOtherOptionHelp(pc,"<database> ...\n\n"
+ " Removes duplicate records from any Palm database\n\n"
+ " Example arguments:\n"
+ " -p /dev/pilot AddressDB ToDoDB\n\n");
+
+ if (argc < 2) {
+ poptPrintUsage(pc,stderr,0);
+ return 1;
+ }
+ while ((c = poptGetNextOpt(pc)) >= 0) {
+ fprintf(stderr," ERROR: Unhandled option %d.\n", c);
+ return 1;
+ }
+
+ if (c < -1) {
+ plu_badoption(pc,c);
+ }
+
+ if(poptPeekArg(pc) == NULL) {
+ fprintf(stderr, " ERROR: You must specify at least one database\n");
+ return -1;
+ }
+
+ sd = plu_connect ();
+ if (sd < 0)
+ goto error;
+
+ while((db = poptGetArg(pc)) != NULL)
+ DeDupe(sd, db);
+
+ if (dlp_ResetLastSyncPC(sd) < 0)
+ goto error_close;
+
+ if (pi_close(sd) < 0)
+ goto error;
+
+ return 0;
+
+ error_close:
+ pi_close(sd);
+
+ error:
+
+ return -1;
+}
+
+/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
+/* ex: set tabstop=4 expandtab: */
+/* Local Variables: */
+/* indent-tabs-mode: t */
+/* c-basic-offset: 8 */
+/* End: */