1 /* ugly ugly. avert your eyes. */
11 #include <sys/types.h>
16 #include <Ecore_File.h>
17 #include <Ecore_Evas.h>
19 #include "edje_decc.h"
21 int _edje_cc_log_dom = -1;
22 char *progname = NULL;
24 char *file_out = NULL;
26 Edje_File *edje_file = NULL;
27 SrcFile_List *srcfiles = NULL;
28 Font_List *fontlist = NULL;
36 static int compiler_cmd_is_sane();
37 static int root_filename_is_sane();
44 "\t%s input_file.edj [-main-out file.edc] [-no-build-sh] [-current-dir]\n"
46 " -main-out\tCreate a symbolic link to the main edc \n"
47 " -no-build-sh\tDon't output build.sh \n"
48 " -current-dir\tOutput to current directory \n"
57 main(int argc, char **argv)
61 setlocale(LC_NUMERIC, "C");
64 _edje_cc_log_dom = eina_log_domain_register
65 ("edje_decc", EDJE_CC_DEFAULT_LOG_COLOR);
66 if (_edje_cc_log_dom < 0)
68 EINA_LOG_ERR("Impossible to create a log domain.");
73 for (i = 1; i < argc; i++)
75 if (!strcmp(argv[i], "-h"))
82 else if ((!strcmp(argv[i], "-main-out")) && (i < (argc - 1)))
87 else if (!strcmp(argv[i], "-no-build-sh"))
89 else if (!strcmp(argv[i], "-current-dir"))
94 ERR("%s: Error: no input file specified.", progname);
103 if (!decomp()) return -1;
106 fprintf(stderr, "WARNING! If any Image or audio data was encoded in a LOSSY way, then\n"
107 "re-encoding will drop quality even more. You need access to the original\n"
108 "data to ensure no loss of quality.\n");
111 eina_log_domain_unregister(_edje_cc_log_dom);
112 _edje_cc_log_dom = -1;
120 ef = eet_open(file_in, EET_FILE_MODE_READ);
123 ERR("ERROR: cannot open %s", file_in);
127 srcfiles = source_load(ef);
128 if (!srcfiles || !srcfiles->list)
130 ERR("ERROR: %s has no decompile information", file_in);
134 if (!eina_list_data_get(srcfiles->list) || !root_filename_is_sane())
136 ERR("ERROR: Invalid root filename: '%s'", (char *) eina_list_data_get(srcfiles->list));
140 edje_file = eet_data_read(ef, _edje_edd_edje_file, "edje/file");
143 ERR("ERROR: %s does not appear to be an edje file", file_in);
147 /* force compiler to be edje_cc */
148 edje_file->compiler = strdup("edje_cc");
149 if (!edje_file->compiler)
151 edje_file->compiler = strdup("edje_cc");
153 else if (!compiler_cmd_is_sane())
155 ERR("ERROR: invalid compiler executable: '%s'", edje_file->compiler);
159 fontlist = source_fontmap_load(ef);
172 outdir = strdup(".");
175 p = strrchr(file_in, '/');
177 outdir = strdup(p + 1);
179 outdir = strdup(file_in);
180 p = strrchr(outdir, '.');
182 ecore_file_mkpath(outdir);
186 tef = eet_open(file_in, EET_FILE_MODE_READ);
188 if (edje_file->image_dir)
190 Edje_Image_Directory_Entry *ei;
193 for (i = 0; i < edje_file->image_dir->entries_count; ++i)
195 ei = &edje_file->image_dir->entries[i];
197 if ((ei->source_type > EDJE_IMAGE_SOURCE_TYPE_NONE) &&
198 (ei->source_type < EDJE_IMAGE_SOURCE_TYPE_LAST) &&
199 (ei->source_type != EDJE_IMAGE_SOURCE_TYPE_EXTERNAL) &&
211 ee = ecore_evas_buffer_new(1, 1);
214 ERR("Cannot create buffer engine canvas for image save.");
217 evas = ecore_evas_get(ee);
218 im = evas_object_image_add(evas);
221 ERR("Cannot create image object for save.");
224 snprintf(buf, sizeof(buf), "edje/images/%i", ei->id);
225 evas_object_image_file_set(im, file_in, buf);
226 snprintf(out, sizeof(out), "%s/%s", outdir, ei->entry);
227 printf("Output Image: %s\n", out);
229 p = strrchr(pp, '/');
231 if (strstr(pp, "../"))
233 ERR("Potential security violation. attempt to write in parent dir.");
236 ecore_file_mkpath(pp);
238 if (!evas_object_image_save(im, out, NULL, "quality=100 compress=9"))
240 ERR("Cannot write file %s. Perhaps missing JPEG or PNG saver modules for Evas.", out);
245 ecore_evas_shutdown();
251 EINA_LIST_FOREACH(srcfiles->list, l, sf)
257 snprintf(out, sizeof(out), "%s/%s", outdir, sf->name);
258 INF("Output Source File: %s\n", out);
260 p = strrchr(pp, '/');
262 if (strstr(pp, "../"))
264 ERR("Potential security violation. attempt to write in parent dir.");
267 ecore_file_mkpath(pp);
269 if (strstr(out, "../"))
271 ERR("Potential security violation. attempt to write in parent dir.");
274 f = fopen(out, "wb");
277 ERR("Unable to write file (%s).", out);
281 /* if the file is empty, sf->file will be NULL.
282 * note that that's not an error
284 if (sf->file) fputs(sf->file, f);
287 if (edje_file->fonts)
289 Edje_Font_Directory_Entry *fn;
292 it = eina_hash_iterator_data_new(edje_file->fonts);
293 EINA_ITERATOR_FOREACH(it, fn)
299 /* should be fn->entry -v */
300 snprintf(out, sizeof(out), "edje/fonts/%s", fn->file);
301 font = eet_read(tef, out, &fontsize);
307 /* should be fn->file -v */
308 snprintf(out, sizeof(out), "%s/%s", outdir, fn->entry);
309 INF("Output Font: %s", out);
311 p = strrchr(pp, '/');
313 if (strstr(pp, "../"))
315 ERR("Potential security violation. attempt to write in parent dir.");
318 ecore_file_mkpath(pp);
320 if (strstr(out, "../"))
322 ERR("Potential security violation. attempt to write in parent dir.");
325 if (!(f = fopen(out, "wb")))
327 ERR("Could not open file: %s", out);
330 if (fwrite(font, fontsize, 1, f) != 1)
331 ERR("Could not write font: %s", strerror(errno));
336 eina_iterator_free(it);
341 sf = eina_list_data_get(srcfiles->list);
346 snprintf(out, sizeof(out), "%s/build.sh", outdir);
347 printf("Output Build Script: %s\n", out);
348 if (strstr(out, "../"))
350 ERR("potential security violation. attempt to write in parent dir.\n");
353 f = fopen(out, "wb");
354 fprintf(f, "#!/bin/sh\n");
355 fprintf(f, "%s $@ -id . -fd . %s -o %s.edj\n", edje_file->compiler, sf->name, outdir);
358 WRN("\n*** CAUTION ***\n"
359 "Please check the build script for anything malicious "
360 "before running it!\n\n");
365 snprintf(out, sizeof(out), "%s/%s", outdir, file_out);
366 if (ecore_file_symlink(sf->name, out) != EINA_TRUE)
368 ERR("symlink %s -> %s failed\n", sf->name, out);
372 chmod(out, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP);
376 if (edje_file->sound_dir)
378 Edje_Sound_Sample *sample;
387 for (i = 0; i < (int)edje_file->sound_dir->samples_count; i++)
389 sample = &edje_file->sound_dir->samples[i];
390 if ((!sample) || (!sample->name)) continue;
391 snprintf(out, sizeof(out), "edje/sounds/%i", sample->id);
392 sound_data = (void *)eet_read_direct(tef, out, &sound_data_size);
395 snprintf(out1, sizeof(out1), "%s/%s", outdir, sample->name);
397 p = strrchr(pp, '/');
399 if (strstr(pp, "../"))
401 ERR("Potential security violation. attempt to write in parent dir.");
404 ecore_file_mkpath(pp);
406 if (strstr(out, "../"))
408 ERR("Potential security violation. attempt to write in parent dir.");
411 f = fopen(out1, "wb");
412 if (fwrite(sound_data, sound_data_size, 1, f) != 1)
413 ERR("Could not write sound: %s", strerror(errno));
424 compiler_cmd_is_sane()
426 const char *c = edje_file->compiler, *ptr;
433 for (ptr = c; ptr && *ptr; ptr++)
435 /* only allow [a-z][A-Z][0-9]_- */
436 if ((!isalnum(*ptr)) && (*ptr != '_') && (*ptr != '-'))
446 root_filename_is_sane()
448 SrcFile *sf = eina_list_data_get(srcfiles->list);
449 char *f = sf->name, *ptr;
456 for (ptr = f; ptr && *ptr; ptr++)
458 /* only allow [a-z][A-Z][0-9]_-./ */
461 case '_': case '-': case '.': case '/':