summaryrefslogtreecommitdiffstats
path: root/tdelfeditor/tdelfeditor.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-12-31 17:36:26 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-12-31 17:36:26 -0600
commitd6a4fe9ca855e094bbfe2e1ba1bba565557b1891 (patch)
tree7a2aed881ccd01bcc47a676d5aa9c6076b2389f2 /tdelfeditor/tdelfeditor.cpp
parent43f19fb8a02775dca1d0701f7a7eb3ce775439ff (diff)
downloadtdelibs-d6a4fe9ca855e094bbfe2e1ba1bba565557b1891.tar.gz
tdelibs-d6a4fe9ca855e094bbfe2e1ba1bba565557b1891.zip
Add tdelfeditor
Diffstat (limited to 'tdelfeditor/tdelfeditor.cpp')
-rw-r--r--tdelfeditor/tdelfeditor.cpp561
1 files changed, 561 insertions, 0 deletions
diff --git a/tdelfeditor/tdelfeditor.cpp b/tdelfeditor/tdelfeditor.cpp
new file mode 100644
index 000000000..14de9d973
--- /dev/null
+++ b/tdelfeditor/tdelfeditor.cpp
@@ -0,0 +1,561 @@
+/*
+ *
+ * Copyright (c) 2008-2011 Erich E. Hoover
+ * TDE version (c) 2011 Timothy Pearson
+ *
+ * elfres - Adds resources into ELF files
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * To provide feedback, report bugs, or otherwise contact me:
+ * ehoover at mines dot edu
+ *
+ */
+
+/* Obtaining command-line options */
+#include <getopt.h>
+
+/* Internationalization support */
+extern "C" {
+ #include <libr-i18n.h>
+}
+
+#include "tdelfeditor.h"
+
+#include <tqstring.h>
+#include <tqstringlist.h>
+
+#include <kglobal.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kstandarddirs.h>
+
+/* return application name */
+extern const char *__progname;
+#define progname() __progname
+
+typedef enum {
+ PARAM_PROGNAME = 0,
+ PARAM_OPTIONS = 1,
+ PARAM_ELF_FILE = 2,
+ PARAM_UUID = 3,
+ PARAM_RESOURCE_NAME = 3,
+ PARAM_ICON_NAME = 3,
+ PARAM_ICON_SIZE = 3,
+ PARAM_RESOURCE_FILE = 4,
+ PARAM_ICON_FILE = 4,
+} eParams;
+
+typedef struct {
+ char short_options[ELFICON_OPTIONS+1];
+ struct option long_options[ELFICON_OPTIONS+1];
+ char descriptions[ELFICON_OPTIONS][100];
+} IconOptions;
+
+IconOptions elficon_options = {
+ "acefgrstv",
+ {
+ {"add-icon", 0, 0, 'a'},
+ {"clear-icons", 0, 0, 'c'},
+ {"set-empty-uuid", 0, 0, 'e'},
+ {"find-icon", 0, 0, 'f'},
+ {"get-uuid", 0, 0, 'g'},
+ {"retrieve-icon", 0, 0, 'r'},
+ {"set-uuid", 0, 0, 's'},
+ {"tde-autoadd-icon", 0, 0, 't'},
+ {"version", 0, 0, 'v'},
+ {NULL, 0, 0, 0}
+ },
+ {
+ N_("add an icon to the ELF file"),
+ N_("clear the file's ELF icon"),
+ N_("set an empty icon UUID for the ELF file"),
+ N_("find an ELF icon in the file by closest size"),
+ N_("get the icon UUID for the file"),
+ N_("retrieve an icon from the ELF file"),
+ N_("set the icon UUID for the ELF file"),
+ N_("automatically add the appropriate TDE icon to the ELF file"),
+ N_("display the current application revision"),
+ }
+};
+
+typedef struct {
+ char short_options[ELFRES_OPTIONS+1];
+ struct option long_options[ELFRES_OPTIONS+1];
+ char descriptions[ELFRES_OPTIONS][100];
+} RcOptions;
+
+RcOptions elfres_options = {
+ "aclrv",
+ {
+ {"add", 0, 0, 'a'},
+ {"clear", 0, 0, 'c'},
+ {"list", 0, 0, 'l'},
+ {"retrieve", 0, 0, 'r'},
+ {"version", 0, 0, 'v'},
+ {NULL, 0, 0, 0}
+ },
+ {
+ N_("add a resource to the ELF file"),
+ N_("clear an ELF file resource"),
+ N_("list libr-compatible resources"),
+ N_("retrieve a resource from the ELF file"),
+ N_("display the current application revision"),
+ }
+};
+
+typedef enum {
+ MODE_ADD_RESOURCE,
+ MODE_CLEAR_RESOURCE,
+ MODE_RETRIEVE_RESOURCE,
+ MODE_LIST_RESOURCES,
+ MODE_ADD_ICON,
+ MODE_TDE_AUTOADD_ICON,
+ MODE_RETRIEVE_ICON,
+ MODE_CLEAR_ICON,
+ MODE_SET_UUID,
+ MODE_SET_EMPTY_UUID,
+ MODE_GET_UUID,
+ MODE_FIND_ICON,
+ MODE_LAUNCH_GUI
+} eMode;
+
+/*
+ * Return the size of the file represented by the file handle
+ */
+off_t file_size(FILE *file)
+{
+ struct stat file_stat;
+
+ if(fstat(fileno(file), &file_stat) == ERROR)
+ return ERROR;
+ return file_stat.st_size;
+}
+
+/*
+ * Output the application version
+ */
+void output_version(char *progname)
+{
+ printf(_("%s: Version %s\n"), progname, VERSION);
+}
+
+/*
+ * Use command-line arguments to set the appropriate data mode
+ */
+int handle_arguments(int argc, char **argv, eMode *mode)
+{
+ int required_params = 0;
+ int i, c, index = 0;
+
+ opterr = 0; /* Prevent automatic getopt() error message */
+
+ while ((c = getopt_long(argc, argv, elficon_options.short_options, elficon_options.long_options, &index)) != EOF)
+ {
+ switch(c)
+ {
+ case 'a':
+ *mode = MODE_ADD_ICON;
+ required_params = 5;
+ break;
+ case 'c':
+ *mode = MODE_CLEAR_ICON;
+ required_params = 3;
+ break;
+ case 'e':
+ *mode = MODE_SET_EMPTY_UUID;
+ required_params = 3;
+ break;
+ case 'f':
+ *mode = MODE_FIND_ICON;
+ required_params = 5;
+ break;
+ case 'g':
+ *mode = MODE_GET_UUID;
+ required_params = 3;
+ break;
+ case 'r':
+ *mode = MODE_RETRIEVE_ICON;
+ required_params = 5;
+ break;
+ case 's':
+ *mode = MODE_SET_UUID;
+ required_params = 4;
+ break;
+ case 't':
+ *mode = MODE_TDE_AUTOADD_ICON;
+ required_params = 4;
+ break;
+ case 'v':
+ output_version(argv[PARAM_PROGNAME]);
+ return FALSE;
+ default:
+ goto print_icon_usage;
+ }
+ index++;
+ if(argc != required_params)
+ goto print_icon_usage;
+ }
+ return TRUE;
+print_icon_usage:
+ fprintf(stderr, _("usage: %s [-a|-r] elf-file-name icon-name svg-file-name\n"), argv[PARAM_PROGNAME]);
+ fprintf(stderr, _("usage: %s [-t] elf-file-name icon-name\n"), argv[PARAM_PROGNAME]);
+ fprintf(stderr, _("usage: %s [-c|-e|-g] elf-file-name\n"), argv[PARAM_PROGNAME]);
+ fprintf(stderr, _("usage: %s [-s] elf-file-name uuid\n"), argv[PARAM_PROGNAME]);
+ fprintf(stderr, _("If -t is set the TDEDIRS environment variable must include your TDE installation prefix\n"));
+ fprintf(stderr, _("for example: TDEDIRS=/opt/trinity ./tdelfeditor -t ./konqueror konqueror\n"));
+ for(i=0;i<ELFICON_OPTIONS;i++)
+ {
+ fprintf(stderr, "\t-%c, --%s\t= %s\n", elficon_options.short_options[i],
+ elficon_options.long_options[i].name, gettext(elficon_options.descriptions[i]));
+ }
+ return FALSE;
+}
+
+/*
+ * Add a resource to an ELF file
+ */
+int add_resource(libr_file *libr_handle, char *resource_name, char *input_file)
+{
+ char *buffer = NULL;
+ FILE *handle = NULL;
+ off_t size, len;
+ int ret = FALSE;
+
+ if((handle = fopen(input_file, "r")) == NULL)
+ {
+ errorf(_("open \"%s\" failed: %m"), input_file);
+ return FALSE;
+ }
+ /* Get the size of the file */
+ if((size = file_size(handle)) == ERROR)
+ {
+ errorf(_("failed to obtain file size: %m"));
+ goto done_handle;
+ }
+ /* Allocate buffers for the uncompressed and compressed data */
+ buffer = (char *) malloc(size);
+ if(buffer == NULL)
+ {
+ errorf(_("failed to create buffer: %m"));
+ goto done_handle;
+ }
+ /* Read the uncompressed data from the disk */
+ if((len = fread(buffer, 1, size, handle)) <= 0)
+ {
+ errorf(_("failed to read input file: %m"));
+ goto done_buffer;
+ }
+ if(len != size)
+ {
+ errorf(_("failed to read entire file."));
+ goto done_buffer;
+ }
+ /* Compress the data */
+ if(!libr_write(libr_handle, resource_name, buffer, size, LIBR_COMPRESSED, LIBR_OVERWRITE))
+ {
+ errorf(_("failed to write ELF resource: %s"), libr_errmsg());
+ goto done_buffer;
+ }
+
+ ret = TRUE;
+ /* Close remaining resources */
+done_buffer:
+ free(buffer);
+done_handle:
+ fclose(handle);
+ return ret;
+}
+
+/*
+ * Get a resource stored in an ELF file
+ */
+void get_resource(libr_file *handle, char *section_name, char *output_file)
+{
+ size_t buffer_size = 0;
+ char *buffer = NULL;
+ FILE *file = NULL;
+ off_t len;
+
+ /* Get the resource from the ELF binary */
+ if(!libr_size(handle, section_name, &buffer_size))
+ {
+ errorf(_("failed to obtain ELF resource size: %s"), libr_errmsg());
+ return;
+ }
+ /* Get the resource from the ELF file */
+ buffer = (char *) malloc(buffer_size);
+ if(!libr_read(handle, section_name, buffer))
+ {
+ errorf(_("failed to obtain ELF resource: %s"), libr_errmsg());
+ goto fail;
+ }
+ /* Store the resource to the disk */
+ if((file = fopen(output_file, "w")) == NULL)
+ {
+ errorf(_("open \"%s\" failed"), output_file);
+ goto fail;
+ }
+ if((len = fwrite(buffer, 1, buffer_size, file)) <= 0)
+ {
+ errorf(_("failed to write output file: %m"));
+ goto fail;
+ }
+
+fail:
+ /* Close remaining resources */
+ if(file != NULL)
+ fclose(file);
+ free(buffer);
+}
+
+/*
+ * Clear the icon stored in an ELF file
+ */
+void clear_resource(libr_file *handle, char *resource_name)
+{
+ if(!libr_clear(handle, resource_name))
+ errorf(_("failed to remove resource: %s"), libr_errmsg());
+}
+
+/*
+ * List all libr-compatible resources
+ */
+void list_resources(libr_file *handle)
+{
+ int i, res = libr_resources(handle);
+
+ if(res == 0)
+ {
+ printf(_("The file contains no libr-compatible resources.\n"));
+ return;
+ }
+ printf(_("%d resource(s):\n"), res);
+ for(i=0;i<res;i++)
+ {
+ char *name = libr_list(handle, i);
+
+ if(name == NULL)
+ {
+ printf(_("error!\n"));
+ continue;
+ }
+ printf(_("resource %d: %s\n"), i, name);
+ free(name);
+ }
+}
+
+/*
+ * Started from console
+ */
+int main_console(int argc, char **argv)
+{
+ char *section = NULL, *input_file = NULL, *output_file = NULL;
+ libr_access_t access = LIBR_READ;
+ libr_file *handle = NULL;
+ eMode mode;
+
+ /* Process command-line arguments */
+ if(!handle_arguments(argc, argv, &mode))
+ return EX_USAGE;
+
+ /* Open the ELF file to be edited */
+ if(mode == MODE_CLEAR_ICON || mode == MODE_CLEAR_RESOURCE
+ || mode == MODE_ADD_ICON || mode == MODE_ADD_RESOURCE
+ || mode == MODE_SET_UUID || mode == MODE_TDE_AUTOADD_ICON
+ || mode == MODE_SET_EMPTY_UUID)
+ {
+ access = LIBR_READ_WRITE;
+ }
+ printf("opening executable file %s...\n\r", argv[PARAM_ELF_FILE]); fflush(stdout);
+ if((handle = libr_open(argv[PARAM_ELF_FILE], access)) == NULL)
+ {
+ errorf(_("failed to open file \"%s\": %s"), argv[PARAM_ELF_FILE], libr_errmsg());
+ return EX_SOFTWARE;
+ }
+
+ /* Perform the requested user operation */
+ switch(mode)
+ {
+ case MODE_FIND_ICON:
+ {
+ unsigned int icon_size;
+ libr_icon *icon = NULL;
+
+ sscanf(argv[PARAM_ICON_SIZE], "%d", &icon_size);
+ icon = libr_icon_geticon_bysize(handle, icon_size);
+ if(icon == NULL)
+ {
+ errorf(_("failed to obtain ELF icon: %s"), libr_errmsg());
+ goto fail;
+ }
+ if(!libr_icon_save(icon, argv[PARAM_ICON_FILE]))
+ {
+ libr_icon_close(icon);
+ errorf(_("failed to save the icon to a file: %s"), libr_errmsg());
+ goto fail;
+ }
+ libr_icon_close(icon);
+ } break;
+ case MODE_GET_UUID:
+ {
+ char uuid[UUIDSTR_LENGTH];
+
+ if(!libr_icon_getuuid(handle, uuid))
+ {
+ errorf(_("Failed to get UUID: %s\n"), libr_errmsg());
+ goto fail;
+ }
+ printf("%s\n", uuid);
+ } break;
+ case MODE_SET_UUID:
+ if(!libr_icon_setuuid(handle, argv[PARAM_UUID]))
+ {
+ errorf(_("Failed to set UUID: %s\n"), libr_errmsg());
+ goto fail;
+ }
+ break;
+ case MODE_SET_EMPTY_UUID:
+ if(!libr_icon_setuuid(handle, "00000000-0000-0000-0000-000000000000"))
+ {
+ errorf(_("Failed to set UUID: %s\n"), libr_errmsg());
+ goto fail;
+ }
+ break;
+ case MODE_LIST_RESOURCES:
+ list_resources(handle);
+ break;
+ case MODE_CLEAR_ICON:
+ section = ICON_SECTION;
+ /* intentional fall-through */
+ case MODE_CLEAR_RESOURCE:
+ if(section == NULL)
+ section = argv[PARAM_RESOURCE_NAME];
+ clear_resource(handle, section);
+ break;
+ case MODE_ADD_ICON:
+ {
+ libr_icon *icon = NULL;
+
+ icon = libr_icon_newicon_byfile(LIBR_SVG, 0, argv[PARAM_ICON_FILE]);
+ if(icon == NULL)
+ {
+ errorf(_("failed to open icon file \"%s\": %s"), argv[PARAM_ICON_FILE], libr_errmsg());
+ goto fail;
+ }
+ if(!libr_icon_write(handle, icon, argv[PARAM_ICON_NAME], LIBR_OVERWRITE))
+ {
+ libr_icon_close(icon);
+ errorf(_("failed to add icon to ELF file: %s"), libr_errmsg());
+ goto fail;
+ }
+ libr_icon_close(icon);
+ } break;
+ case MODE_TDE_AUTOADD_ICON:
+ {
+ printf("Searching for standard icon for name %s in the following directories:\n\r", argv[PARAM_ICON_NAME]);
+ KApplication::disableAutoDcopRegistration();
+ KAboutData aboutd("tdelfeditor", "tdelfeditor", "0.0.1");
+ KCmdLineArgs::init(&aboutd);
+ KApplication app(false, false);
+
+ TQStringList rds = KGlobal::dirs()->resourceDirs("icon");
+ for ( TQStringList::Iterator it = rds.begin(); it != rds.end(); ++it ) {
+ printf(" * %s\n\r", (*it).ascii()); fflush(stdout);
+ }
+ TQString systemIcon = KGlobal::iconLoader()->iconPath(argv[PARAM_ICON_NAME], 0, true);
+ if (systemIcon.isNull()) {
+ systemIcon = KGlobal::iconLoader()->iconPath(argv[PARAM_ICON_NAME], 0, false);
+ printf("NOT FOUND, using %s\n\r", systemIcon.ascii());
+ }
+ else {
+ printf("found %s\n\r", systemIcon.ascii());
+ }
+
+ libr_icon *icon = NULL;
+
+ icon = libr_icon_newicon_byfile(LIBR_SVG, 0, const_cast<char*>(systemIcon.ascii()));
+ if(icon == NULL)
+ {
+ errorf(_("failed to open icon file \"%s\": %s"), systemIcon.ascii(), libr_errmsg());
+ goto fail;
+ }
+ if(!libr_icon_write(handle, icon, const_cast<char*>(systemIcon.ascii()), LIBR_OVERWRITE))
+ {
+ libr_icon_close(icon);
+ errorf(_("failed to add icon to ELF file: %s"), libr_errmsg());
+ goto fail;
+ }
+ libr_icon_close(icon);
+ } break;
+ case MODE_ADD_RESOURCE:
+ if(section == NULL)
+ {
+ section = argv[PARAM_RESOURCE_NAME];
+ input_file = argv[PARAM_RESOURCE_FILE];
+ }
+ add_resource(handle, section, input_file);
+ break;
+ case MODE_RETRIEVE_ICON:
+ {
+ libr_icon *icon = NULL;
+
+ icon = libr_icon_geticon_byname(handle, argv[PARAM_ICON_NAME]);
+ if(icon == NULL)
+ {
+ errorf(_("failed to get icon named \"%s\": %s"), argv[PARAM_ICON_NAME], libr_errmsg());
+ goto fail;
+ }
+ if(!libr_icon_save(icon, argv[PARAM_ICON_FILE]))
+ {
+ libr_icon_close(icon);
+ errorf(_("failed to save the icon to a file: %s"), libr_errmsg());
+ goto fail;
+ }
+ libr_icon_close(icon);
+ } break;
+ case MODE_RETRIEVE_RESOURCE:
+ if(section == NULL)
+ {
+ section = argv[PARAM_RESOURCE_NAME];
+ output_file = argv[PARAM_RESOURCE_FILE];
+ }
+ get_resource(handle, section, output_file);
+ break;
+ default:
+ errorf(_("Unhandled operation code."));
+ goto fail;
+ }
+
+fail:
+ /* Close file handle and exit */
+ libr_close(handle);
+ return EX_OK;
+}
+
+/*
+ * Main execution routine
+ */
+int main(int argc, char **argv)
+{
+ libr_i18n_autoload(PACKAGE);
+ return main_console(argc, argv);
+}