I fixed your shit, bitch. :)
[rarcrack.git] / src / file.c
blob9ccc3dfa1653b0aa79e36636aed759117609b27c
1 #include "file.h"
2 #include <string.h> /* for strncmp/strlen */
3 #include <stdio.h> /* for FILE */
4 #include <stdlib.h> /* for system */
6 types TYPES[] = {
7 {"rar", "unrar", "t -y -p%s %s", {0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0}},
8 {"zip", "unzip", "-P%s -t %s", {0x50, 0x4B, 0x03, 0x04, 0}},
9 {"7zip", "7z", "t -y -p%s %s", {0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C, 0}},
10 {NULL, NULL, NULL, {0}} /* end of types */ };
13 * Try to run unpacker command,
14 * if there is no such command/program
15 * this function returns FALSE
17 static gboolean test_for_packer(gchar* packer) {
18 gboolean ret = FALSE;
19 #ifdef WIN32
20 packer = g_strdup_printf("%s > NUL", packer);
21 #else
22 packer = g_strdup_printf("%s 2> /dev/null > /dev/null", packer);
23 #endif
24 gint totest = system(packer);
26 g_free(packer);
28 if ( (totest >= 0) && /* if result negative, error occured */
29 (totest != 127) && /* result = 127 -> execve failed */
30 (totest != 32512) ) { /* same from shell 127 << 8 WTF? */
31 ret = TRUE; /* everything seems ok */
33 return ret;
37 * Open file, and try to identify archive type
38 * returns id in TYPES array (so we know type/packer/...)
40 guint file_identify(const gchar* filename, gboolean force) {
41 guint i = 0;
42 gint j = 0;
43 gchar totest[11] = {0};
44 guint ret = FILE_NOTYPE; /* if we can't get packer for this type,
45 we return FILE_NOTYPE */
46 FILE* fp = (FILE*) g_fopen(filename, "r");
47 if (!fp)
48 return FILE_ERROR; /* file opening error */
49 fread(totest, sizeof(gchar), 10, fp);
50 fclose(fp);
51 if (!totest[0])
52 return FILE_ERROR; /* file reading error */
54 for (i = 0; TYPES[i].name; ++i) {
55 j = 0;
56 while ( (TYPES[i].magic[j] != 0) && (j < 10) ) {
57 if (TYPES[i].magic[j] != totest[j]) {
58 j = 100; /* no similarity */
59 break;
61 j++;
63 if (j != 100) { /* yeah, we found the type/packer/... */
64 ret = i; /* we return this TYPES id */
65 break;
69 /* on forcing we don't check unpacker... */
70 if ((!force) && (ret != FILE_NOTYPE)) {
71 if (! test_for_packer(TYPES[ret].cmd))
72 ret = FILE_NOPACKER; /* RarCrack can't run unpacker ... :-( */
75 return ret; /* we return the type or FILE_NOTYPE */
79 * Returns id in TYPES array for 'type_ext' archive type
81 guint file_packer_get_id(const gchar* type_ext, gboolean force) {
82 guint i = 0;
83 guint ret = FILE_NOTYPE; /* if we can't get packer for this type,
84 we return FILE_NOTYPE */
85 if (!type_ext) /* if someone provide NULL parameter to this function */
86 return ret;
88 for (i = 0; TYPES[i].name; ++i) {
89 if (strcmp(type_ext, TYPES[i].name) == 0) {
90 ret = i;
91 break;
95 /* on forcing we don't check unpacker ... */
96 if ((!force) && (ret != FILE_NOTYPE)) {
97 if (! test_for_packer(TYPES[ret].cmd))
98 ret = FILE_NOPACKER; /* RarCrack can't run unpacker ... :-( */
101 return ret;
105 * Return unpacker command with needed arguments.
106 * NonForcing: Returned string must be freed after use.
107 * Forcing: Do not free returned string...
109 * // Yeah it is really st0pid c0de.... FIXME
111 gchar* file_packer_get_command(guint id, gboolean force) {
112 gchar* ret;
113 if (!force) {
114 #ifdef WIN32
115 ret = g_strdup_printf("%s %s > NUL", TYPES[id].cmd,
116 TYPES[id].arg);
117 #else
118 ret = g_strdup_printf("%s %s 2>&1 > /dev/null", TYPES[id].cmd,
119 TYPES[id].arg);
120 #endif
121 } else {
122 ret = TYPES[id].cmd; /* i just need the program name, *
123 * without any junk. */
125 return ret;
129 * Return archive type name (eg.: rar/zip/7zip),
130 * You shall not free this string (if you don't want SIGSERV)
132 gchar* file_packer_get_type(guint id) {
133 return TYPES[id].name;
136 void file_packer_list_supported() {
137 guint i = 0;
139 g_printf(" Supported archive types: \n");
140 g_printf("-----------------------------------------------\n");
141 g_printf("| Type | Needed executable | Installed? |\n");
142 g_printf("-----------------------------------------------\n");
143 for (i = 0; TYPES[i].name; ++i) {
144 g_printf("| %-6s| %-14s| %-8s|\n",
145 TYPES[i].name, TYPES[i].cmd,
146 ( test_for_packer(TYPES[i].cmd) ? "Yes" : "No" ));
148 g_printf("-----------------------------------------------\n\n");
149 return;