From 7127d4eb29312a7df6772f22ab9a8e814240a87f Mon Sep 17 00:00:00 2001 From: Peter Kallden Date: Mon, 23 Feb 2004 08:13:52 +0000 Subject: [PATCH] add support for renaming and unlinking printer caches. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@610 423420c4-83ab-492f-b58f-81f9feb106b5 --- printercache.c | 146 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 134 insertions(+), 12 deletions(-) diff --git a/printercache.c b/printercache.c index d1499de..ee48237 100644 --- a/printercache.c +++ b/printercache.c @@ -41,12 +41,13 @@ printercache_mkdir(char *base, char *printer) { char *path; - path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer)); + path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + 1); sprintf(path, "%s/.rdesktop", base); if ((mkdir(path, 0700) == -1) && errno != EEXIST) { perror(path); + xfree(path); return False; } @@ -54,6 +55,7 @@ printercache_mkdir(char *base, char *printer) if ((mkdir(path, 0700) == -1) && errno != EEXIST) { perror(path); + xfree(path); return False; } @@ -62,6 +64,7 @@ printercache_mkdir(char *base, char *printer) if ((mkdir(path, 0700) == -1) && errno != EEXIST) { perror(path); + xfree(path); return False; } @@ -69,6 +72,84 @@ printercache_mkdir(char *base, char *printer) return True; } +BOOL +printercache_unlink_blob(char *printer) +{ + char *path; + char *home; + + if (printer == NULL) + return False; + + home = getenv("HOME"); + if (home == NULL) + return False; + + path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + + sizeof("/AutoPrinterCacheData") + 1); + + sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer); + + if (unlink(path) < 0) + { + xfree(path); + return False; + } + + sprintf(path, "%s/.rdesktop/rdpdr/%s", home, printer); + + if (rmdir(path) < 0) + { + xfree(path); + return False; + } + + xfree(path); + return True; +} + + +BOOL +printercache_rename_blob(char *printer, char *new_printer) +{ + char *printer_path; + char *new_printer_path; + int printer_maxlen; + + char *home; + + if (printer == NULL) + return False; + + home = getenv("HOME"); + if (home == NULL) + return False; + + printer_maxlen = + (strlen(printer) > + strlen(new_printer) ? strlen(printer) : strlen(new_printer)) + strlen(home) + + sizeof("/.rdesktop/rdpdr/") + 1; + + printer_path = (char *) xmalloc(printer_maxlen); + new_printer_path = (char *) xmalloc(printer_maxlen); + + sprintf(printer_path, "%s/.rdesktop/rdpdr/%s", home, printer); + sprintf(new_printer_path, "%s/.rdesktop/rdpdr/%s", home, new_printer); + + printf("%s,%s\n", printer_path, new_printer_path); + if (rename(printer_path, new_printer_path) < 0) + { + xfree(printer_path); + xfree(new_printer_path); + return False; + } + + xfree(printer_path); + xfree(new_printer_path); + return True; +} + + int printercache_load_blob(char *printer_name, uint8 ** data) { @@ -86,15 +167,21 @@ printercache_load_blob(char *printer_name, uint8 ** data) return 0; path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) + - sizeof("/AutoPrinterCacheData")); + sizeof("/AutoPrinterCacheData") + 1); sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name); fd = open(path, O_RDONLY); if (fd == -1) + { + xfree(path); return 0; + } if (fstat(fd, &st)) + { + xfree(path); return 0; + } *data = (uint8 *) xmalloc(st.st_size); length = read(fd, *data, st.st_size); @@ -120,13 +207,14 @@ printercache_save_blob(char *printer_name, uint8 * data, uint32 length) return; path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) + - sizeof("/AutoPrinterCacheData")); + sizeof("/AutoPrinterCacheData") + 1); sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name); fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd == -1) { perror(path); + xfree(path); return; } @@ -149,9 +237,28 @@ printercache_process(STREAM s) in_uint32_le(s, type); switch (type) { - /*case 4: renaming of item old name and then new name */ - /*case 3: delete item name */ - case 2: + case 4: /* rename item */ + in_uint8(s, printer_length); + in_uint8s(s, 0x3); // padding + in_uint8(s, driver_length); + in_uint8s(s, 0x3); // padding + + /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */ + + rdp_in_unistr(s, printer, printer_length); + rdp_in_unistr(s, driver, driver_length); + + printercache_rename_blob(printer, driver); + break; + + case 3: /* delete item */ + in_uint8(s, printer_unicode_length); + in_uint8s(s, 0x3); // padding + printer_length = rdp_in_unistr(s, printer, printer_unicode_length); + printercache_unlink_blob(printer); + break; + + case 2: /* save printer data */ in_uint32_le(s, printer_unicode_length); in_uint32_le(s, blob_length); @@ -162,13 +269,28 @@ printercache_process(STREAM s) } break; - /*case 1: */ - // TODO: I think this one just tells us what printer is on LPT? but why? + case 1: /* save device data */ + in_uint8a(s, device_name, 5); // get LPTx/COMx name - // - // your name and the "users choice" of printer driver - // my guess is that you can store it and automagically reconnect - // the printer with correct driver next time. + // need to fetch this data so that we can get the length of the packet to store. + in_uint8s(s, 0x2); // ??? + in_uint8s(s, 0x2) // pad?? + in_uint32_be(s, driver_length); + in_uint32_be(s, printer_length); + in_uint8s(s, 0x7) // pad?? + // next is driver in unicode + // next is printer in unicode + /* TODO: figure out how to use this information when reconnecting */ + /* actually - all we need to store is the driver and printer */ + /* and figure out what the first word is. */ + /* rewind stream so that we can save this blob */ + /* length is driver_length + printer_length + 19 */ + // rewind stream + s->p = s->p - 19; + + printercache_save_blob(device_name, s->p, + driver_length + printer_length + 19); + break; default: unimpl("RDPDR Printer Cache Packet Type: %d\n", type);