diff options
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.c | 275 |
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: */ |