summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-09-24 00:28:27 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2014-09-24 00:28:27 +0900
commit7ef6b73bb1ccd34e669682cb13c83f067e89332a (patch)
treeb616bd228fa9bbc107450277614add41bef2b4d4
initial marakesh import - appstore and build system for efl apps
-rwxr-xr-xbuild.sh4
-rw-r--r--mrk-db.h7
-rw-r--r--mrk-index.c153
-rw-r--r--mrk-proto.h17
-rwxr-xr-xmrk-srv-build.sh25
-rw-r--r--mrk-srv.c352
-rw-r--r--mrk.c1320
7 files changed, 1878 insertions, 0 deletions
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..7b17756
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,4 @@
1#!/bin/sh
2gcc mrk.c -o mrk `pkg-config --cflags --libs eina ecore ecore-file ecore-ipc eet`
3gcc mrk-srv.c -o mrk-srv `pkg-config --cflags --libs eina ecore ecore-ipc ecore-file eet`
4gcc mrk-index.c -o mrk-index `pkg-config --cflags --libs eina ecore ecore-ipc ecore-file eet`
diff --git a/mrk-db.h b/mrk-db.h
new file mode 100644
index 0000000..891f6c1
--- /dev/null
+++ b/mrk-db.h
@@ -0,0 +1,7 @@
1typedef struct
2{
3 Eina_Hash *name_hash;
4 Eina_Hash *category_hash;
5 Eina_Hash *tag_hash;
6 Eina_Hash *key_hash;
7} Mdb;
diff --git a/mrk-index.c b/mrk-index.c
new file mode 100644
index 0000000..151dc7a
--- /dev/null
+++ b/mrk-index.c
@@ -0,0 +1,153 @@
1#include <Eina.h>
2#include <Ecore.h>
3#include <Eet.h>
4#include <Ecore_Ipc.h>
5#include <Ecore_File.h>
6
7#include "mrk-db.h"
8
9static char *repodir = "./repo";
10static Mdb *db = NULL;
11
12static char *
13read_string(Eet_File *ef, const char *key)
14{
15 int size = 0;
16 char *str;
17 char *s = eet_read(ef, key, &size);
18 if (!s) return NULL;
19 str = malloc(size + 1);
20 if (!str)
21 {
22 free(s);
23 return NULL;
24 }
25 memcpy(str, s, size);
26 str[size] = 0;
27 free(s);
28 return str;
29}
30
31static void
32key_add(Eina_Hash *hash, const char *key, const char *entry)
33{
34 const char *ss;
35 Eina_List *entries;
36
37 ss = eina_stringshare_add(entry);
38 entries = eina_hash_find(hash, key);
39 entries = eina_list_sorted_insert(entries, EINA_COMPARE_CB(strcasecmp), ss);
40 eina_hash_add(hash, key, entries);
41}
42
43static void
44key_str_add(Eina_Hash *hash, const char *string, const char *entry)
45{
46 // XXX: parse "words" from string - add each to the key given
47}
48
49static int
50index_file(const char *file, const char *fname)
51{
52 Eet_File *ef;
53 char *s;
54 int i;
55 char tmp[4096];
56
57 ef = eet_open(file, EET_FILE_MODE_READ);
58 if (!ef) return 0;
59
60 s = read_string(ef, "name");
61 if (s)
62 {
63 key_add(db->name_hash, s, fname);
64 key_add(db->key_hash, s, fname);
65 free(s);
66 }
67 s = read_string(ef, "version");
68 if (s)
69 {
70 key_add(db->key_hash, s, fname);
71 free(s);
72 }
73 for (i = 0; i < 9999; i++)
74 {
75 snprintf(tmp, sizeof(tmp), "tag/%i", i);
76 s = read_string(ef, tmp);
77 if (s)
78 {
79 key_add(db->tag_hash, s, fname);
80 key_add(db->key_hash, s, fname);
81 free(s);
82 }
83 }
84 for (i = 0; i < 9999; i++)
85 {
86 snprintf(tmp, sizeof(tmp), "category/%i", i);
87 s = read_string(ef, tmp);
88 if (s)
89 {
90 key_add(db->category_hash, s, fname);
91 key_add(db->key_hash, s, fname);
92 free(s);
93 }
94 }
95
96 // XXX: weed duplicates from every key
97 eet_close(ef);
98 return 1;
99}
100
101static int
102index_dir(const char *dir)
103{
104 Eina_List *files;
105 char *s;
106 char tmp[4096];
107
108 db = calloc(1, sizeof(Mdb));
109 if (!db) return 0;
110 db->name_hash = eina_hash_string_superfast_new(NULL);
111 db->category_hash = eina_hash_string_superfast_new(NULL);
112 db->tag_hash = eina_hash_string_superfast_new(NULL);
113 db->key_hash = eina_hash_string_superfast_new(NULL);
114 files = ecore_file_ls(dir);
115 EINA_LIST_FREE(files, s)
116 {
117 char *lnk;
118
119 if (s[0] == '.') continue;
120 snprintf(tmp, sizeof(tmp), "%s/%s", dir, s);
121 lnk = ecore_file_readlink(tmp);
122 if (!lnk) continue;
123 index_file(tmp, s);
124 free(lnk);
125 free(s);
126 }
127 return 1;
128}
129
130int
131main(int argc, char **argv)
132{
133 if (argc < 2)
134 {
135 printf("usage:\n"
136 " mrk-index /path/to/repo\n"
137 "\n");
138 exit(1);
139 }
140 eina_init();
141 ecore_init();
142 eet_init();
143 ecore_file_init();
144
145 if (argc > 1) repodir = ecore_file_realpath(argv[1]);
146 index_dir(repodir);
147
148 ecore_file_shutdown();
149 eet_shutdown();
150 ecore_shutdown();
151 eina_shutdown();
152 return 0;
153}
diff --git a/mrk-proto.h b/mrk-proto.h
new file mode 100644
index 0000000..2c6f554
--- /dev/null
+++ b/mrk-proto.h
@@ -0,0 +1,17 @@
1#define M_UP_START 1
2#define M_UP_DATA 2
3#define M_UP_END 3
4#define M_UP_OK 4
5#define M_UP_FAIL 5
6
7#define M_DOWN_START 11
8#define M_DOWN_DATA 12
9#define M_DOWN_END 13
10
11#define M_QRY_LIST 21
12#define M_QRY_SEARCH 22
13#define M_QRY_GET 23
14
15#define M_ANS_START 31
16#define M_ANS_DATA 32
17#define M_ANS_END 33
diff --git a/mrk-srv-build.sh b/mrk-srv-build.sh
new file mode 100755
index 0000000..ce061b5
--- /dev/null
+++ b/mrk-srv-build.sh
@@ -0,0 +1,25 @@
1#!/bin/sh
2# build dir dstdir
3set -e
4
5cd "$1"
6rm -f *.mkb || true
7rm -rf Marrakesh || true
8
9export CC=gcc
10export CFLAGS="-O3 -ffast-math"
11export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"
12
13mrk extract *.mks
14mrk build
15mrk bin
16cp *.mkb "$2"/
17
18export NAME=`grep "^PROJ:" Marrakesh.mrk | tail -1 | sed -e 's/PROJ://g' | sed -e 's/ *$//' -e 's/^ *//'`
19rm -f "$2"/"$NAME" || true
20ln -sf *.mkb "$2"/"$NAME"
21
22cd /tmp
23rm -rf "$1"
24
25exit 0
diff --git a/mrk-srv.c b/mrk-srv.c
new file mode 100644
index 0000000..8815a14
--- /dev/null
+++ b/mrk-srv.c
@@ -0,0 +1,352 @@
1#include <Eina.h>
2#include <Ecore.h>
3#include <Eet.h>
4#include <Ecore_Ipc.h>
5#include <Ecore_File.h>
6
7#include "mrk-proto.h"
8#include "mrk-db.h"
9
10static const char *sane_name_veto[] = {"../", "./", "/", NULL};
11static const char *sane_name_ok = "01234567890-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
12
13static char *repodir = "./repo";
14
15static int
16sane_forbidden_path(const char *file, const char **forbidden)
17{
18 int i;
19
20 for (i = 0; forbidden[i]; i++)
21 {
22 if (strstr(forbidden[i], file)) return 0;
23 }
24 return 1;
25}
26
27static int
28sane_allowed_path(const char *file, const char *allowed)
29{
30 int i, j;
31
32 for (i = 0; file[i]; i++)
33 {
34 int ok;
35
36 ok = 0;
37 for (j = 0; allowed[j]; j++)
38 {
39 if (file[i] == allowed[j])
40 {
41 ok = 1;
42 break;
43 }
44 }
45 if (!ok) return 0;
46 }
47 return 1;
48}
49
50typedef struct
51{
52 Ecore_Ipc_Client *client;
53 char *file;
54 char *dir;
55 FILE *f;
56 Ecore_Exe *exe;
57} Client;
58
59static Ecore_Ipc_Server *ipc = NULL;
60static Eina_List *clients = NULL;
61
62static Client *
63client_find(Ecore_Ipc_Client *ipc_client)
64{
65 Eina_List *l;
66 Client *c;
67
68 EINA_LIST_FOREACH(clients, l, c)
69 {
70 if (c->client == ipc_client) return c;
71 }
72 return NULL;
73}
74
75static Client *
76client_exe_find(Ecore_Exe *exe)
77{
78 Eina_List *l;
79 Client *c;
80
81 EINA_LIST_FOREACH(clients, l, c)
82 {
83 if (c->exe == exe) return c;
84 }
85 return NULL;
86}
87
88static Client *
89client_new(void)
90{
91 Client *c;
92
93 c = calloc(1, sizeof(Client));
94 clients = eina_list_append(clients, c);
95 return c;
96}
97
98static void
99client_free(Client *c)
100{
101 if (c->f) fclose(c->f);
102 if (c->file) free(c->file);
103 if (c->dir)
104 {
105 ecore_file_recursive_rm(c->dir);
106 free(c->dir);
107 }
108 clients = eina_list_remove(clients, c);
109 free(c);
110}
111
112static void
113client_upload_new(Client *c)
114{
115 char tmp[4096];
116 Eina_Tmpstr *s = NULL;
117
118 if (c->f) fclose(c->f);
119 if (c->dir)
120 {
121 ecore_file_recursive_rm(c->dir);
122 free(c->dir);
123 c->dir = NULL;
124 }
125 if (eina_file_mkdtemp("marrekesh-up-XXXXXX", &s))
126 {
127 c->dir = strdup(s);
128 eina_tmpstr_del(s);
129 if (c->dir)
130 {
131 snprintf(tmp, sizeof(tmp), "%s/%s", c->dir, c->file);
132 c->f = fopen(tmp, "wb");
133 }
134 }
135}
136
137static void
138client_upload_end(Client *c)
139{
140 char tmp[4096];
141
142 if (c->f)
143 {
144 fclose(c->f);
145 c->f = NULL;
146 snprintf(tmp, sizeof(tmp),
147 "./mrk-srv-build.sh %s %s",
148 c->dir, repodir);
149 c->exe = ecore_exe_pipe_run(tmp,
150 ECORE_EXE_TERM_WITH_PARENT |
151 ECORE_EXE_NOT_LEADER, c);
152 }
153}
154
155static void
156client_upload_fail(Client *c)
157{
158 if (c->f) fclose(c->f);
159 if (c->file) free(c->file);
160 if (c->dir)
161 {
162 ecore_file_recursive_rm(c->dir);
163 free(c->dir);
164 }
165 c->f = NULL;
166 c->file = NULL;
167 c->dir = NULL;
168}
169
170static void
171client_upload_data(Client *c, void *data, int size)
172{
173 if (c->f) fwrite(data, size, 1, c->f);
174}
175
176static void
177client_send(Client *c, const char *name)
178{
179 char tmp[4096];
180 char *lnk;
181
182 snprintf(tmp, sizeof(tmp), "%s/%s", repodir, name);
183 lnk = ecore_file_readlink(tmp);
184 if (!lnk)
185 ecore_ipc_client_send(c->client, 10, M_DOWN_START, 0, 0, 0, NULL, 0);
186 else
187 {
188 FILE *f;
189
190 f = fopen(tmp, "rb");
191 if (!f)
192 ecore_ipc_client_send(c->client, 10, M_DOWN_START, 0, 0, 0, NULL, 0);
193 else
194 {
195 ecore_ipc_client_send(c->client, 10, M_DOWN_START, 0, 0, 0, lnk, strlen(lnk));
196 for (;;)
197 {
198 size_t size;
199 char buf[10000];
200
201 size = fread(buf, 1, 10000, f);
202 if (size <= 0) break;
203 ecore_ipc_client_send(c->client, 10, M_DOWN_DATA, 0, 0, 0, buf, size);
204 }
205 ecore_ipc_client_send(c->client, 10, M_DOWN_END, 0, 0, 0, NULL, 0);
206 fclose(f);
207 }
208 }
209}
210
211static Eina_Bool
212_ipc_cb_add(void *data, int type, void *event)
213{
214 Ecore_Ipc_Event_Client_Add *e = event;
215 Client *c = client_new();
216 c->client = e->client;
217 return EINA_TRUE;
218}
219
220static Eina_Bool
221_ipc_cb_del(void *data, int type, void *event)
222{
223 Ecore_Ipc_Event_Client_Del *e = event;
224 Client *c = client_find(e->client);
225 if (c) client_free(c);
226 return EINA_TRUE;
227}
228
229static Eina_Bool
230_ipc_cb_dat(void *data, int type, void *event)
231{
232 Ecore_Ipc_Event_Client_Data *e = event;
233 Client *c = client_find(e->client);
234 // e->major e->minor e->ref e->ref_to e->response | e->data e->size
235 if (e->major != 10) return EINA_TRUE;
236 switch (e->minor)
237 {
238 case M_UP_START:
239 // e->data == filename
240 if ((e->size > 0) && (e->size < 1000))
241 {
242 if (c->file) free(c->file);
243 c->file = malloc(e->size + 1);
244 memcpy(c->file, e->data, e->size);
245 c->file[e->size] = 0;
246 if (sane_forbidden_path(c->file, sane_name_veto) &&
247 sane_allowed_path(c->file, sane_name_ok))
248 {
249 client_upload_new(c);
250 }
251 else client_upload_fail(c);
252 }
253 else client_upload_fail(c);
254 break;
255 case M_UP_DATA:
256 // e->data == chunk of bytes to append
257 if ((e->size > 0) && (e->size <= 10000))
258 {
259 client_upload_data(c, e->data, e->size);
260 }
261 else client_upload_fail(c);
262 break;
263 case M_UP_END:
264 // e->data == ignored (EOF)
265 client_upload_end(c);
266 break;
267 case M_QRY_LIST:
268 // e->data == category (none if all)
269 break;
270 case M_QRY_SEARCH:
271 // e->data == query string
272 break;
273 case M_QRY_GET:
274 if ((e->size > 0) && (e->size < 1000))
275 {
276 char *name = malloc(e->size + 1);
277 if (name)
278 {
279 memcpy(name, e->data, e->size);
280 name[e->size] = 0;
281 client_send(c, name);
282 free(name);
283 }
284 }
285 // e->data == appname (Terminology, Rage etc.)
286 break;
287 default:
288 break;
289 }
290
291 return EINA_TRUE;
292}
293
294static Eina_Bool
295_exe_cb_del(void *data, int type, void *event)
296{
297 Ecore_Exe_Event_Del *ev = event;
298 Client *c = client_exe_find(ev->exe);
299 if (c)
300 {
301 if (ev->exit_code == 0)
302 ecore_ipc_client_send(c->client, 10, M_UP_OK, 0, 0, 0, NULL, 0);
303 else
304 ecore_ipc_client_send(c->client, 10, M_UP_FAIL, 0, 0, 0, NULL, 0);
305 c->exe = NULL;
306 }
307 return EINA_TRUE;
308}
309
310static int
311ipc_init(void)
312{
313 ipc = ecore_ipc_server_add(ECORE_IPC_REMOTE_SYSTEM, "0.0.0.0", 10077, NULL);
314 if (!ipc) return 0;
315 ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_ADD, _ipc_cb_add, NULL);
316 ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DEL, _ipc_cb_del, NULL);
317 ecore_event_handler_add(ECORE_IPC_EVENT_CLIENT_DATA, _ipc_cb_dat, NULL);
318 return 1;
319}
320
321int
322main(int argc, char **argv)
323{
324 if (argc < 2)
325 {
326 printf("usage:\n"
327 " mrk-srv /path/to/repo\n"
328 "\n");
329 exit(1);
330 }
331 eina_init();
332 ecore_init();
333 eet_init();
334 ecore_file_init();
335 ecore_ipc_init();
336
337 if (argc > 1) repodir = ecore_file_realpath(argv[1]);
338
339 if (ipc_init())
340 {
341 ecore_exe_run_priority_set(10);
342 ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _exe_cb_del, NULL);
343 ecore_main_loop_begin();
344 }
345
346 ecore_ipc_shutdown();
347 ecore_file_shutdown();
348 eet_shutdown();
349 ecore_shutdown();
350 eina_shutdown();
351 return 0;
352}
diff --git a/mrk.c b/mrk.c
new file mode 100644
index 0000000..42b323a
--- /dev/null
+++ b/mrk.c
@@ -0,0 +1,1320 @@
1/*
2gcc mrk.c -o mrk `pkg-config --cflags --libs eina ecore-file eet`
3 */
4// note that this code is far from clean or nice at all. it's not very robust
5// but it works for the purposes of a proof of concept and getting things off
6// the ground - so please judge it by that for now
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <unistd.h>
11#include <sys/stat.h>
12#include <Eina.h>
13#include <Ecore.h>
14#include <Ecore_File.h>
15#include <Ecore_Ipc.h>
16#include <Eet.h>
17
18#include "mrk-proto.h"
19
20typedef enum
21{
22 TMODE_EOL,
23 TMODE_PATH,
24 TMODE_TEXT,
25 TMODE_PATH_CP,
26 TMODE_PATH_CP_LIST,
27 TMODE_PATH_LIST,
28} Tag_Mode;
29
30typedef struct
31{
32 const char *tag;
33 Tag_Mode mode;
34} Tag_Type;
35
36typedef struct
37{
38 char *bin;
39 Eina_List *srcs;
40 Eina_List *deps;
41 Eina_List *incs;
42} Build_Bin;
43
44typedef struct
45{
46 char *src;
47 char *dest;
48} Build_Data;
49
50typedef struct
51{
52 char *name;
53 char *icon;
54 char *brief;
55 char *version;
56 char *license;
57 char *domain;
58 char *repo;
59 char *devrepo;
60 char *contact;
61 Eina_List *tags;
62 Eina_List *categories;
63 Eina_List *copying;
64 char *needs;
65 Eina_List *bins;
66 Eina_List *data;
67 Eina_List *desktops;
68 Eina_List *icons;
69 Eina_List *po;
70} Build;
71
72
73static const Tag_Type tags[] =
74{
75 {"PROJ:", TMODE_EOL},
76 {"PROJICON:", TMODE_PATH},
77 {"BRIEF:", TMODE_TEXT},
78 {"VERSION:", TMODE_EOL},
79 {"LICENSE:", TMODE_EOL},
80 {"COPYING:", TMODE_PATH_LIST},
81 {"NEEDS:", TMODE_EOL},
82 {"DOMAIN:", TMODE_PATH},
83 {"REPO:", TMODE_EOL},
84 {"DEVREPO:", TMODE_EOL},
85 {"CONTACT:", TMODE_TEXT},
86 {"CATEGORY:", TMODE_PATH_LIST},
87 {"TAGS:", TMODE_PATH_LIST},
88 {"BIN:", TMODE_PATH},
89 {"SRC:", TMODE_PATH_LIST},
90 {"DEPS:", TMODE_PATH_LIST},
91 {"INC:", TMODE_PATH_LIST},
92 {"DATA:", TMODE_PATH_CP_LIST},
93 {"DESKTOP:", TMODE_PATH_LIST},
94 {"ICON:", TMODE_PATH_LIST},
95 {"PODOMAIN:", TMODE_PATH},
96 {"PO:", TMODE_PATH_LIST},
97 {NULL, 0} // END OF LIST
98};
99
100static Build build = { 0 };
101static char *tmpd = "Marrakesh";
102static const char *sane_name_veto[] = {"../", "./", "/", NULL};
103static const char *sane_name_ok = "01234567890-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. ";
104static const char *sane_path_veto[] = {"../", "./", NULL};
105static const char *sane_path_ok = "01234567890-_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. ";
106
107static void
108err(char *msg)
109{
110 fprintf(stderr, "ERROR: %s\n", msg);
111 exit(1);
112}
113
114static int
115sane_forbidden_path(const char *file, const char **forbidden)
116{
117 int i;
118
119 for (i = 0; forbidden[i]; i++)
120 {
121 if (strstr(forbidden[i], file)) return 0;
122 }
123 return 1;
124}
125
126static int
127sane_allowed_path(const char *file, const char *allowed)
128{
129 int i, j;
130
131 for (i = 0; file[i]; i++)
132 {
133 int ok;
134
135 ok = 0;
136 for (j = 0; allowed[j]; j++)
137 {
138 if (file[i] == allowed[j])
139 {
140 ok = 1;
141 break;
142 }
143 }
144 if (!ok) return 0;
145 }
146 return 1;
147}
148
149static char *
150parse_token(char **p, char *end)
151{
152 char *tok, *seg;
153
154 while ((*p < end) && (isspace(**p))) (*p)++;
155 if (*p >= end) return NULL;
156 tok = *p;
157
158 while (*p < end)
159 {
160 if (isspace(**p)) goto token;
161 (*p)++;
162 }
163token:
164 seg = malloc(*p - tok + 1);
165 if (!seg) return NULL;
166 memcpy(seg, tok, *p - tok);
167 seg[*p - tok] = 0;
168 return seg;
169}
170
171static char *
172parse_eol(char **p, char *end)
173{
174 char *tok, *seg;
175
176 while ((*p < end) && (isspace(**p))) (*p)++;
177 if (*p >= end) return NULL;
178 tok = *p;
179
180 while (*p < end)
181 {
182 if (**p == '\n') goto token;
183 (*p)++;
184 }
185token:
186 seg = malloc(*p - tok + 1);
187 if (!seg) return NULL;
188 memcpy(seg, tok, *p - tok);
189 seg[*p - tok] = 0;
190 return seg;
191}
192
193static char *
194path_check(char *tok)
195{
196 // XXX: check me
197 return strdup(tok);
198}
199
200static int
201parse_content(char *mem, size_t size)
202{
203 char prevc = '\n';
204 char *end = mem + size;
205 char *p = mem;
206 int skipline = 0;
207 int startline = 0;
208 char *seg = NULL, *s;
209 char *data1 = NULL, *data2 = NULL;
210 int i;
211 Tag_Mode mode = TMODE_TEXT;
212
213 while (p < end)
214 {
215 if (prevc == '\n')
216 {
217 if (*p == '#') skipline = 1;
218 else skipline = 0;
219 startline = 1;
220 }
221 if (!skipline)
222 {
223 char *tok;
224 char *prevp;
225
226 prevp = p;
227 tok = parse_token(&p, end);
228 if (!tok) return 1;
229 if (startline)
230 {
231 for (i = 0; tags[i].tag; i++)
232 {
233 if (!strcmp(tok, tags[i].tag))
234 {
235// printf("#: %s\n", tok);
236 free(seg);
237 seg = strdup(tok);
238 mode = tags[i].mode;
239 break;
240 }
241 }
242 if (!tags[i].tag) goto not_tag;
243 }
244 else
245 {
246not_tag:
247 switch (mode)
248 {
249 case TMODE_EOL:
250 case TMODE_TEXT:
251 // prse eol of prevp
252 p = prevp;
253 data1 = parse_eol(&p, end);
254 if (!data1) err("no content");
255 break;
256 case TMODE_PATH:
257 case TMODE_PATH_LIST:
258 // sanitize (check) path tok put into data1
259 data1 = path_check(tok);
260 if (!data1) err("path invalid");
261 break;
262 case TMODE_PATH_CP:
263 case TMODE_PATH_CP_LIST:
264 // sanitize path, then next token > then path 2 -> data1, data2
265 data1 = path_check(tok);
266 if (!data1) err("path invalid");
267 s = parse_token(&p, end);
268 if (!s) err("missing > in path copy");
269 if (!(!strcmp(s, ">"))) err("copy token is not >");
270 free(s);
271 s = parse_token(&p, end);
272 if (!s) err("missing destination path in path copy");
273 data2 = path_check(s);
274 if (!data2) err("destination path not valid");
275 free(s);
276 break;
277 default:
278 break;
279 }
280// if (data2)
281// printf(" %i> %s '%s' '%s'\n",
282// mode, seg, data1, data2);
283// else
284// printf(" %i> %s '%s'\n",
285// mode, seg, data1);
286 if (seg)
287 {
288 if (!strcmp(seg, "PROJ:"))
289 {
290 if (!(sane_forbidden_path(data1, sane_name_veto) &&
291 sane_allowed_path(data1, sane_name_ok)))
292 err("name failed sanity check");
293 free(build.name);
294 build.name = strdup(data1);
295 }
296 else if (!strcmp(seg, "PROJICON:"))
297 {
298 free(build.icon);
299 build.icon = strdup(data1);
300 }
301 else if (!strcmp(seg, "BRIEF:"))
302 {
303 if (!build.brief) build.brief = strdup(data1);
304 else
305 {
306 s = malloc(strlen(build.brief) + 1 + strlen(data1) + 1);
307 if (s)
308 {
309 strcpy(s, build.brief);
310 strcat(s, " ");
311 strcat(s, data1);
312 free(build.brief);
313 build.brief = s;
314 }
315 }
316 }
317 else if (!strcmp(seg, "VERSION:"))
318 {
319 free(build.version);
320 build.version = strdup(data1);
321 }
322 else if (!strcmp(seg, "LICENSE:"))
323 {
324 free(build.license);
325 build.license = strdup(data1);
326 }
327 else if (!strcmp(seg, "COPYING:"))
328 {
329 build.copying = eina_list_append(build.copying,
330 strdup(data1));
331 }
332 else if (!strcmp(seg, "NEEDS:"))
333 {
334 free(build.needs);
335 build.license = strdup(data1);
336 }
337 else if (!strcmp(seg, "DOMAIN:"))
338 {
339 free(build.domain);
340 build.domain = strdup(data1);
341 }
342 else if (!strcmp(seg, "REPO:"))
343 {
344 free(build.repo);
345 build.repo = strdup(data1);
346 }
347 else if (!strcmp(seg, "DEVREPO:"))
348 {
349 free(build.devrepo);
350 build.devrepo = strdup(data1);
351 }
352 else if (!strcmp(seg, "CATEGORY:"))
353 {
354 build.categories = eina_list_append(build.categories,
355 strdup(data1));
356 }
357 else if (!strcmp(seg, "TAGS:"))
358 {
359 build.tags = eina_list_append(build.tags,
360 strdup(data1));
361 }
362 else if (!strcmp(seg, "CONTACT:"))
363 {
364 if (!build.contact) build.contact = strdup(data1);
365 else
366 {
367 s = malloc(strlen(build.contact) + 1 + strlen(data1) + 1);
368 if (s)
369 {
370 strcpy(s, build.contact);
371 strcat(s, " ");
372 strcat(s, data1);
373 free(build.contact);
374 build.contact = s;
375 }
376 }
377 }
378 else if (!strcmp(seg, "BIN:"))
379 {
380 Build_Bin *build_bin = calloc(1, sizeof(Build_Bin));
381 if (build_bin)
382 {
383 build_bin->bin = strdup(data1);
384 build.bins = eina_list_append(build.bins,
385 build_bin);
386 }
387 }
388 else if (!strcmp(seg, "SRC:"))
389 {
390 Build_Bin *build_bin = eina_list_data_get(eina_list_last(build.bins));
391 if (build_bin)
392 {
393 build_bin->srcs = eina_list_append(build_bin->srcs,
394 strdup(data1));
395 }
396 }
397 else if (!strcmp(seg, "DEPS:"))
398 {
399 Build_Bin *build_bin = eina_list_data_get(eina_list_last(build.bins));
400 if (build_bin)
401 {
402 build_bin->deps = eina_list_append(build_bin->deps,
403 strdup(data1));
404 }
405 }
406 else if (!strcmp(seg, "INC:"))
407 {
408 Build_Bin *build_bin = eina_list_data_get(eina_list_last(build.bins));
409 if (build_bin)
410 {
411 build_bin->incs = eina_list_append(build_bin->incs,
412 strdup(data1));
413 }
414 }
415 else if (!strcmp(seg, "DATA:"))
416 {
417 Build_Data *build_data = calloc(1, sizeof(Build_Data));
418 if (build_data)
419 {
420 build_data->src = strdup(data1);
421 build_data->dest = strdup(data2);
422 build.data = eina_list_append(build.data,
423 build_data);
424 }
425 }
426 else if (!strcmp(seg, "DESKTOP:"))
427 {
428 build.desktops = eina_list_append(build.desktops,
429 strdup(data1));
430 }
431 else if (!strcmp(seg, "ICON:"))
432 {
433 build.icons = eina_list_append(build.icons,
434 strdup(data1));
435 }
436 else if (!strcmp(seg, "PO:"))
437 {
438 build.po = eina_list_append(build.po,
439 strdup(data1));
440 }
441 }
442 free(data1);
443 free(data2);
444 data1 = NULL;
445 data2 = NULL;
446 }
447 free(tok);
448 prevc = *p;
449 }
450 else
451 {
452 prevc = *p;
453 p++;
454 }
455 startline = 0;
456 }
457 return 1;
458}
459
460static int
461parse_bld(const char *file)
462{
463 Eina_File *ef;
464 char *mem;
465 size_t size;
466 int ret;
467
468 ef = eina_file_open(file, EINA_FALSE);
469 if (!ef) return 0;
470
471 size = eina_file_size_get(ef);
472 mem = eina_file_map_all(ef, EINA_FILE_SEQUENTIAL);
473 if ((size == 0) || (!mem)) return 0;
474
475 ret = parse_content(mem, size);
476
477 eina_file_close(ef);
478 return ret;
479}
480
481static int
482build_proj(void)
483{
484 Eina_List *l, *ll;
485 Build_Bin *bin;
486 Build_Data *data;
487 Eina_Strbuf *buf;
488 char *s, *extn, *s2;
489 char tmp[4096];
490 char tmp2[4096];
491 const char *ss, *cc;
492
493 EINA_LIST_FOREACH(build.po, l, s)
494 {
495 snprintf(tmp, sizeof(tmp), "%s/share/locale/%s/LC_MESSAGES/", tmpd, s);
496 ecore_file_mkpath(tmp);
497 snprintf(tmp2, sizeof(tmp2), "po/%s.gmo", s);
498 snprintf(tmp, sizeof(tmp), "%s/share/locale/%s/LC_MESSAGES/%s.mo", tmpd, s, build.domain);
499 ecore_file_cp(tmp2, tmp);
500 }
501 EINA_LIST_FOREACH(build.data, l, data)
502 {
503 s = ecore_file_dir_get(data->dest);
504 if (s)
505 {
506 snprintf(tmp, sizeof(tmp), "%s/%s", tmpd, s);
507 ecore_file_mkpath(tmp);
508 free(s);
509 }
510 snprintf(tmp, sizeof(tmp), "%s/%s", tmpd, data->dest);
511 ecore_file_cp(data->src, tmp);
512 }
513 snprintf(tmp, sizeof(tmp), "%s/%s", tmpd, "share/applications");
514 ecore_file_mkpath(tmp);
515 EINA_LIST_FOREACH(build.desktops, l, s)
516 {
517 ss = ecore_file_file_get(s);
518 if (!(!strncmp(ss, build.domain, strlen(build.domain))))
519 err("destkop file wrong domain");
520 snprintf(tmp, sizeof(tmp), "%s/share/applications/%s", tmpd, ss);
521 ecore_file_cp(s, tmp);
522 }
523 snprintf(tmp, sizeof(tmp), "%s/%s", tmpd, "share/icons");
524 ecore_file_mkpath(tmp);
525 EINA_LIST_FOREACH(build.icons, l, s)
526 {
527 ss = ecore_file_file_get(s);
528 if (!(!strncmp(ss, build.domain, strlen(build.domain))))
529 err("icon file wrong domain");
530 snprintf(tmp, sizeof(tmp), "%s/share/icons/%s", tmpd, ss);
531 ecore_file_cp(s, tmp);
532 }
533 EINA_LIST_FOREACH(build.copying, l, s)
534 {
535 if (strchr(s, '/'))
536 {
537 s2 = ecore_file_dir_get(s);
538 snprintf(tmp, sizeof(tmp), "%s/share/licenses/%s", tmpd, s2);
539 free(s2);
540 }
541 else
542 snprintf(tmp, sizeof(tmp), "%s/share/licenses", tmpd);
543 ecore_file_mkpath(tmp);
544 snprintf(tmp, sizeof(tmp), "%s/share/licenses/%s", tmpd, s);
545 ecore_file_cp(s, tmp);
546 }
547 EINA_LIST_FOREACH(build.bins, l, bin)
548 {
549 if ((buf = eina_strbuf_new()))
550 {
551 s = ecore_file_dir_get(bin->bin);
552 if (s)
553 {
554 snprintf(tmp, sizeof(tmp), "%s/%s", tmpd, s);
555 ecore_file_mkpath(tmp);
556 free(s);
557 }
558 cc = getenv("CC");
559 if (!cc) cc = "gcc";
560 eina_strbuf_append(buf, cc);
561 eina_strbuf_append(buf, " -I. -lm -o ");
562 eina_strbuf_append(buf, tmpd);
563 eina_strbuf_append(buf, "/");
564 eina_strbuf_append(buf, bin->bin);
565
566 eina_strbuf_append(buf, " -DLOCALEDIR=\\\"/tmp/X/share/locale\\\"");
567 eina_strbuf_append(buf, " -DPACKAGE_BIN_DIR=\\\"/tmp/X/bin\\\"");
568 eina_strbuf_append(buf, " -DPACKAGE_LIB_DIR=\\\"/tmp/X/lib\\\"");
569 eina_strbuf_append(buf, " -DPACKAGE_DATA_DIR=\\\"/tmp/X/share/");
570 eina_strbuf_append(buf, build.domain);
571 eina_strbuf_append(buf, "\\\"");
572
573 eina_strbuf_append(buf, " -DPACKAGE_NAME=\\\"");
574 eina_strbuf_append(buf, build.domain);
575 eina_strbuf_append(buf, "\\\"");
576
577 eina_strbuf_append(buf, " -DPACKAGE_VERSION=\\\"");
578 eina_strbuf_append(buf, build.version);
579 eina_strbuf_append(buf, "\\\"");
580
581 eina_strbuf_append(buf, " -D_REENTRANT -DHAVE_CONFIG_H -pthread ");
582 eina_strbuf_append(buf, " $CFLAGS ");
583
584 EINA_LIST_FOREACH(bin->srcs, ll, s)
585 {
586 extn = strrchr(s, '.');
587 if ((extn) && (!strcasecmp(extn, ".c")))
588 {
589 eina_strbuf_append(buf, s);
590 eina_strbuf_append(buf, " ");
591 }
592 }
593 EINA_LIST_FOREACH(bin->deps, ll, s)
594 {
595 eina_strbuf_append(buf, " `pkg-config --cflags --libs ");
596 eina_strbuf_append(buf, s);
597 eina_strbuf_append(buf, "` ");
598 }
599 EINA_LIST_FOREACH(bin->incs, ll, s)
600 {
601 eina_strbuf_append(buf, " -I");
602 eina_strbuf_append(buf, s);
603 eina_strbuf_append(buf, " ");
604 }
605 s = (char *)eina_strbuf_string_get(buf);
606 if (s) system(s);
607 eina_strbuf_free(buf);
608 }
609 }
610 return 1;
611}
612
613static void
614package_file(Eet_File *ef, const char *file, const char *key)
615{
616 Eina_File *enf = eina_file_open(file, EINA_FALSE);
617 if (enf)
618 {
619 void *mem = eina_file_map_all(enf, EINA_FILE_SEQUENTIAL);
620 if (mem)
621 {
622 size_t size = eina_file_size_get(enf);
623 eet_write(ef, key, mem, size, EET_COMPRESSION_VERYFAST);
624 }
625 eina_file_close(enf);
626 }
627}
628
629static void
630package_bin_iter(Eet_File *ef, const char *dir, const char *key)
631{
632 Eina_List *files;
633 Eina_File *enf;
634 char *s;
635 char tmp[4096];
636 char tmp2[4096];
637
638 files = ecore_file_ls(dir);
639 EINA_LIST_FREE(files, s)
640 {
641 if (!strcmp(s, ".")) continue;
642 else if (!strcmp(s, "..")) continue;
643 snprintf(tmp, sizeof(tmp), "%s/%s", dir, s);
644 snprintf(tmp2, sizeof(tmp2), "%s/%s", key, s);
645 if (ecore_file_is_dir(tmp))
646 {
647 if (ecore_file_can_exec(tmp)) tmp2[4] = 'D';
648 package_bin_iter(ef, tmp, tmp2);
649 }
650 else
651 {
652 if (ecore_file_can_exec(tmp)) tmp2[4] = 'X';
653 else tmp2[4] = 'f';
654 package_file(ef, tmp, tmp2);
655 }
656 free(s);
657 }
658}
659
660static int
661pakage_bin(void)
662{
663 Eet_File *ef;
664 char tmp[4096];
665 Eina_List *l;
666 char *s;
667 int i;
668
669 snprintf(tmp, sizeof(tmp), "%s-%s.mkb", build.name, build.version);
670 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
671 if (ef)
672 {
673#define WRTS(key, var) \
674 if (var) eet_write(ef, key, var, strlen(var), EET_COMPRESSION_VERYFAST)
675 WRTS("name", build.name);
676 if (build.icon) package_file(ef, build.icon, "icon");
677 WRTS("brief", build.brief);
678 WRTS("version", build.version);
679 WRTS("license", build.license);
680 WRTS("repo", build.repo);
681 WRTS("devrepo", build.devrepo);
682 WRTS("contact", build.contact);
683 WRTS("needs", build.needs);
684 i = 0;
685 EINA_LIST_FOREACH(build.tags, l, s)
686 {
687 snprintf(tmp, sizeof(tmp), "tag/%i", i++);
688 WRTS(tmp, s);
689 }
690 i = 0;
691 EINA_LIST_FOREACH(build.categories, l, s)
692 {
693 snprintf(tmp, sizeof(tmp), "category/%i", i++);
694 WRTS(tmp, s);
695 }
696 package_bin_iter(ef, tmpd, "bin/f");
697 eet_close(ef);
698 return 1;
699 }
700 return 0;
701}
702
703static int
704pakage_src(const char *file)
705{
706 Eet_File *ef;
707 char tmp[4096];
708 char tmp2[4096];
709
710 snprintf(tmp, sizeof(tmp), "%s-%s.mks", build.name, build.version);
711 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
712 if (ef)
713 {
714 Eina_File *enf;
715 Eina_List *l, *ll;
716 void *mem;
717 size_t size;
718 char *s;
719 Build_Bin *bin;
720 Build_Data *data;
721
722 enf = eina_file_open(file, EINA_FALSE);
723 if (!enf) err("can't open build file");
724 mem = eina_file_map_all(enf, EINA_FILE_SEQUENTIAL);
725 if (!mem) err("can't map build file");
726 size = eina_file_size_get(enf);
727 eet_write(ef, "buildinfo", mem, size, EET_COMPRESSION_VERYFAST);
728 eina_file_close(enf);
729
730 EINA_LIST_FOREACH(build.copying, l, s)
731 {
732 snprintf(tmp, sizeof(tmp), "src/%s", s);
733 package_file(ef, s, tmp);
734 }
735 EINA_LIST_FOREACH(build.desktops, l, s)
736 {
737 snprintf(tmp, sizeof(tmp), "src/%s", s);
738 package_file(ef, s, tmp);
739 }
740 EINA_LIST_FOREACH(build.icons, l, s)
741 {
742 snprintf(tmp, sizeof(tmp), "src/%s", s);
743 package_file(ef, s, tmp);
744 }
745 EINA_LIST_FOREACH(build.po, l, s)
746 {
747 snprintf(tmp2, sizeof(tmp2), "po/%s.gmo", s);
748 snprintf(tmp, sizeof(tmp), "src/po/%s.gmo", s);
749 package_file(ef, tmp2, tmp);
750 }
751 EINA_LIST_FOREACH(build.bins, l, bin)
752 {
753 EINA_LIST_FOREACH(bin->srcs, ll, s)
754 {
755 snprintf(tmp, sizeof(tmp), "src/%s", s);
756 package_file(ef, s, tmp);
757 }
758 }
759 EINA_LIST_FOREACH(build.data, l, data)
760 {
761 snprintf(tmp, sizeof(tmp), "src/%s", data->src);
762 package_file(ef, data->src, tmp);
763 }
764 eet_close(ef);
765 return 1;
766 }
767 return 0;
768}
769
770static int
771write_file(Eet_File *ef, const char *key, const char *file)
772{
773 FILE *f;
774 void *mem;
775 int size;
776 char *s;
777
778 mem = eet_read(ef, key, &size);
779 if (mem)
780 {
781 s = ecore_file_dir_get(file);
782 if (s)
783 {
784 ecore_file_mkpath(s);
785 free(s);
786 }
787 f = fopen(file, "wb");
788 if (f)
789 {
790 fwrite(mem, size, 1, f);
791 fclose(f);
792 return 1;
793 }
794 }
795 err("file write failed");
796 return 0;
797}
798
799static int
800package_extract(const char *file)
801{
802 Eet_File *ef;
803
804 ef = eet_open(file, EET_FILE_MODE_READ);
805 if (ef)
806 {
807 int i, num = 0;
808 char **keys = eet_list(ef, "src/*", &num);
809
810 if (keys)
811 {
812 for (i = 0; i < num; i++)
813 {
814 if (!strncmp(keys[i], "src/", 4))
815 {
816 if (!sane_forbidden_path(keys[i], sane_path_veto)) continue;
817 write_file(ef, keys[i], &(keys[i][4]));
818 }
819 }
820 }
821 write_file(ef, "buildinfo", "Marrakesh.mrk");
822 eet_close(ef);
823 return 1;
824 }
825 err("file does not open");
826 return 0;
827}
828
829static char *
830read_string(Eet_File *ef, const char *key)
831{
832 int size = 0;
833 char *str;
834 char *s = eet_read(ef, key, &size);
835 if (!s) return NULL;
836 str = malloc(size + 1);
837 if (!str)
838 {
839 free(s);
840 return NULL;
841 }
842 memcpy(str, s, size);
843 str[size] = 0;
844 free(s);
845 return str;
846}
847
848static void
849clean_symlinks(const char *dir)
850{
851 Eina_List *files;
852 char *s, *ss;
853 char tmp[4096];
854
855 files = ecore_file_ls(dir);
856 EINA_LIST_FREE(files, s)
857 {
858 snprintf(tmp, sizeof(tmp), "%s/%s", dir, s);
859 ss = ecore_file_readlink(tmp);
860 if (ss)
861 {
862 free(ss);
863 if (!ecore_file_exists(tmp))
864 {
865 printf("clean '%s'\n", tmp);
866 ecore_file_unlink(tmp);
867 }
868 }
869 free(s);
870 }
871}
872
873static int
874field_copy(Eet_File *ef, Eet_File *ef2, const char *key)
875{
876 int size = 0;
877 char *s = eet_read(ef, key, &size);
878 if (s)
879 {
880 eet_write(ef2, key, s, size, EET_COMPRESSION_VERYFAST);
881 free(s);
882 return 1;
883 }
884 return 0;
885}
886
887static const char *
888get_home(void)
889{
890 static char buf[4096] = "";
891 const char *tmps, *home;
892
893 if (buf[0]) return buf;
894 tmps = getenv("XDG_DATA_HOME");
895 home = getenv("HOME");
896 if (!home) home = "/tmp";
897 if (tmps) snprintf(buf, sizeof(buf), "%s", tmps);
898 else snprintf(buf, sizeof(buf), "%s", home);
899 return buf;
900}
901
902static int
903package_clean(void)
904{
905 char tmp[4096];
906
907 snprintf(tmp, sizeof(tmp), "%s/.local/share/icons", get_home());
908 clean_symlinks(tmp);
909 snprintf(tmp, sizeof(tmp), "%s/.local/share/applications", get_home());
910 clean_symlinks(tmp);
911 snprintf(tmp, sizeof(tmp), "%s/Applications/.bin", get_home());
912 clean_symlinks(tmp);
913 return 1;
914}
915
916static int
917package_install(const char *file)
918{
919 Eet_File *ef, *ef2;
920
921 ef = eet_open(file, EET_FILE_MODE_READ);
922 if (ef)
923 {
924 int i, num = 0;
925 char **keys = eet_list(ef, "bin/*", &num);
926 char inst[4096];
927 char dir[4096];
928 char tmp[4096];
929 char tmp2[4096];
930 char *s;
931 Eina_List *files;
932 char *name;
933
934 name = read_string(ef, "name");
935 if (!name) err("no name");
936 if (!(sane_forbidden_path(name, sane_name_veto) &&
937 sane_allowed_path(name, sane_name_ok)))
938 err("name failed sanity check");
939 snprintf(tmp, sizeof(tmp), "%s/Applications/.bin", get_home());
940 ecore_file_mkpath(tmp);
941 snprintf(inst, sizeof(inst), "%s/Applications/%s", get_home(), name);
942 if (ecore_file_exists(inst)) err("destination already exists");
943 ecore_file_mkpath(inst);
944 if (keys)
945 {
946 for (i = 0; i < num; i++)
947 {
948 if (!strncmp(keys[i], "bin/", 4))
949 {
950 if (!sane_forbidden_path(keys[i], sane_path_veto)) continue;
951 snprintf(tmp, sizeof(tmp), "%s/%s", inst, &(keys[i][6]));
952 write_file(ef, keys[i], tmp);
953 if (keys[i][4] == 'X')
954 {
955 printf("+x '%s'\n", &(keys[i][6]));
956 chmod(tmp, 00500);
957 }
958 }
959 }
960 }
961 snprintf(dir, sizeof(dir), "%s/share/icons", inst);
962 files = ecore_file_ls(dir);
963 EINA_LIST_FREE(files, s)
964 {
965 if (!strcmp(s, ".")) continue;
966 else if (!strcmp(s, "..")) continue;
967 snprintf(tmp, sizeof(tmp), "../../../Applications/%s/share/icons/%s", name, s);
968 snprintf(tmp2, sizeof(tmp2), "%s/.local/share/icons/%s", get_home(), s);
969 if (ecore_file_exists(tmp2)) err("icon file symlink already exists");
970 ecore_file_symlink(tmp, tmp2);
971 free(s);
972 }
973 snprintf(dir, sizeof(dir), "%s/share/applications", inst);
974 files = ecore_file_ls(dir);
975 EINA_LIST_FREE(files, s)
976 {
977 if (!strcmp(s, ".")) continue;
978 else if (!strcmp(s, "..")) continue;
979 snprintf(tmp, sizeof(tmp), "../../../Applications/%s/share/applications/%s", name, s);
980 snprintf(tmp2, sizeof(tmp2), "%s/.local/share/applications/%s", get_home(), s);
981 if (ecore_file_exists(tmp2)) err("desktop file symlink already exists");
982 ecore_file_symlink(tmp, tmp2);
983 free(s);
984 }
985 snprintf(dir, sizeof(dir), "%s/bin", inst);
986 files = ecore_file_ls(dir);
987 EINA_LIST_FREE(files, s)
988 {
989 if (!strcmp(s, ".")) continue;
990 else if (!strcmp(s, "..")) continue;
991 snprintf(tmp, sizeof(tmp), "../%s/bin/%s", name, s);
992 snprintf(tmp2, sizeof(tmp2), "%s/Applications/.bin/%s", get_home(), s);
993 if (ecore_file_exists(tmp2)) err("bin file symlink already exists");
994 ecore_file_symlink(tmp, tmp2);
995 free(s);
996 }
997 snprintf(tmp, sizeof(tmp), "%s/Applications/%s/.icon.png", get_home(), name);
998 write_file(ef, "icon", tmp);
999 snprintf(tmp, sizeof(tmp), "%s/Applications/%s/.info.mki", get_home(), name);
1000 ef2 = eet_open(tmp, EET_FILE_MODE_WRITE);
1001 free(name);
1002 if (ef2)
1003 {
1004 field_copy(ef, ef2, "name");
1005 field_copy(ef, ef2, "brief");
1006 field_copy(ef, ef2, "version");
1007 field_copy(ef, ef2, "license");
1008 field_copy(ef, ef2, "repo");
1009 field_copy(ef, ef2, "devrepo");
1010 field_copy(ef, ef2, "contact");
1011 field_copy(ef, ef2, "needs");
1012 for (i = 0; i < 9999; i++)
1013 {
1014 snprintf(tmp, sizeof(tmp), "tag/%i", i);
1015 if (!field_copy(ef, ef2, tmp)) break;
1016 }
1017 for (i = 0; i < 9999; i++)
1018 {
1019 snprintf(tmp, sizeof(tmp), "category/%i", i);
1020 if (!field_copy(ef, ef2, tmp)) break;
1021 }
1022 eet_close(ef2);
1023 }
1024 eet_close(ef);
1025 return 1;
1026 }
1027 err("file does not open");
1028 return 0;
1029}
1030
1031static int
1032package_remove(const char *name)
1033{
1034 char tmp[4096];
1035
1036 snprintf(tmp, sizeof(tmp), "%s/Applications/%s", get_home(), name);
1037 if (!ecore_file_recursive_rm(tmp)) return 0;
1038 return 1;
1039}
1040
1041static Ecore_Ipc_Server *ipc = NULL;
1042static char *up_file = NULL;
1043static char *up_path = NULL;
1044
1045static Eina_Bool
1046_ipc_cb_add(void *data, int type, void *event)
1047{
1048 Ecore_Ipc_Event_Server_Add *e = event;
1049 FILE *f;
1050
1051 f = fopen(up_path, "rb");
1052 if (f)
1053 {
1054 char buf[10000];
1055 size_t size;
1056
1057 ecore_ipc_server_send(ipc, 10, M_UP_START, 0, 0, 0,
1058 up_file, strlen(up_file));
1059 for (;;)
1060 {
1061 size = fread(buf, 1, 10000, f);
1062 if (size > 0)
1063 ecore_ipc_server_send(ipc, 10, M_UP_DATA, 0, 0, 0,
1064 buf, size);
1065 else break;
1066 }
1067 ecore_ipc_server_send(ipc, 10, M_UP_END, 0, 0, 0,
1068 NULL, 0);
1069 fclose(f);
1070 }
1071 return EINA_TRUE;
1072}
1073
1074static Eina_Bool
1075_ipc_cb_del(void *data, int type, void *event)
1076{
1077 Ecore_Ipc_Event_Server_Del *e = event;
1078 err("disconnect...");
1079 ecore_main_loop_quit();
1080 return EINA_TRUE;
1081}
1082
1083static Eina_Bool
1084_ipc_cb_dat(void *data, int type, void *event)
1085{
1086 Ecore_Ipc_Event_Server_Data *e = event;
1087 if (e->major == 10)
1088 {
1089 if (e->minor == M_UP_OK)
1090 {
1091 printf("OK\n");
1092 ecore_main_loop_quit();
1093 }
1094 else if (e->minor == M_UP_FAIL)
1095 {
1096 printf("FAIL\n");
1097 err("upload rejected");
1098 }
1099 }
1100 return EINA_TRUE;
1101}
1102
1103static int
1104package_up(const char *file)
1105{
1106 ipc = ecore_ipc_server_connect(ECORE_IPC_REMOTE_SYSTEM, "localhost", 10077, NULL);
1107 if (!ipc) return 0;
1108 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _ipc_cb_add, NULL);
1109 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _ipc_cb_del, NULL);
1110 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _ipc_cb_dat, NULL);
1111 up_path = strdup(file);
1112 up_file = strdup(ecore_file_file_get(file));
1113 ecore_main_loop_begin();
1114 return 1;
1115}
1116
1117static char *down_name = NULL;
1118static char *down_file = NULL;
1119static FILE *down_f = NULL;
1120
1121static Eina_Bool
1122_ipc2_cb_add(void *data, int type, void *event)
1123{
1124 Ecore_Ipc_Event_Server_Add *e = event;
1125 ecore_ipc_server_send(ipc, 10, M_QRY_GET, 0, 0, 0,
1126 down_name, strlen(down_name));
1127 return EINA_TRUE;
1128}
1129
1130static Eina_Bool
1131_ipc2_cb_del(void *data, int type, void *event)
1132{
1133 Ecore_Ipc_Event_Server_Del *e = event;
1134 err("disconnect...");
1135 ecore_main_loop_quit();
1136 return EINA_TRUE;
1137}
1138
1139static Eina_Bool
1140_ipc2_cb_dat(void *data, int type, void *event)
1141{
1142 Ecore_Ipc_Event_Server_Data *e = event;
1143 if (e->major == 10)
1144 {
1145 switch (e->minor)
1146 {
1147 case M_DOWN_START:
1148 if ((e->size > 0) && (e->size <= 1000) && (e->data))
1149 {
1150 char *file = malloc(e->size + 1);
1151 if (file)
1152 {
1153 memcpy(file, e->data, e->size);
1154 file[e->size] = 0;
1155 if ((sane_forbidden_path(file, sane_name_veto) &&
1156 sane_allowed_path(file, sane_name_ok)))
1157 {
1158 if (!down_f)
1159 {
1160 char tmp[4096];
1161
1162 down_file = file;
1163 snprintf(tmp, sizeof(tmp), "%s", down_file);
1164 if (ecore_file_exists(tmp))
1165 err("file already exists");
1166 down_f = fopen(file, "wb");
1167 printf("%s\n", file);
1168 }
1169 else err("already have download");
1170 }
1171 else err("mangled filename");
1172 }
1173 else err("download file not sane");
1174 }
1175 else err("no such package");
1176 break;
1177 case M_DOWN_DATA:
1178 if ((down_f) && (e->data) && (e->size > 0) && (e->size <= 10000))
1179 {
1180 fwrite(e->data, e->size, 1, down_f);
1181 }
1182 break;
1183 case M_DOWN_END:
1184 if (down_f)
1185 {
1186 fclose(down_f);
1187 down_f = NULL;
1188 ecore_main_loop_quit();
1189 }
1190 break;
1191 default:
1192 break;
1193 }
1194 }
1195 return EINA_TRUE;
1196}
1197
1198static int
1199package_down(const char *name)
1200{
1201 ipc = ecore_ipc_server_connect(ECORE_IPC_REMOTE_SYSTEM, "localhost", 10077, NULL);
1202 if (!ipc) return 0;
1203 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_ADD, _ipc2_cb_add, NULL);
1204 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DEL, _ipc2_cb_del, NULL);
1205 ecore_event_handler_add(ECORE_IPC_EVENT_SERVER_DATA, _ipc2_cb_dat, NULL);
1206 down_name = strdup(name);
1207 ecore_main_loop_begin();
1208 return 1;
1209}
1210
1211int
1212main(int argc, char **argv)
1213{
1214 char *s;
1215
1216 eina_init();
1217 eet_init();
1218 ecore_ipc_init();
1219 ecore_file_init();
1220 if (argc < 2)
1221 {
1222 printf("sub commands:\n"
1223 " build\n"
1224 " src\n"
1225 " bin\n"
1226 " extract FILE\n"
1227 " install FILE\n"
1228 " clean\n"
1229 " remove PKGNAME\n"
1230 " release [FILE]\n"
1231 " down PKGNAME\n"
1232 " get PKGNAME\n"
1233// " list [CATEGORY]\n"
1234// " search KEY1 [KEY2] [KEY3] [...]\n"
1235// " new\n"
1236 "\n");
1237 return -1;
1238 }
1239
1240 s = getenv("DESTDIR");
1241 if (s) tmpd = s;
1242 if (!strcmp(argv[1], "build"))
1243 {
1244 if (!parse_bld("Marrakesh.mrk")) return 1;
1245 if (!build_proj()) return 1;
1246 }
1247 else if (!strcmp(argv[1], "src"))
1248 {
1249 if (!parse_bld("Marrakesh.mrk")) return 1;
1250 if (!pakage_src("Marrakesh.mrk")) return 1;
1251 }
1252 else if (!strcmp(argv[1], "bin"))
1253 {
1254 if (!parse_bld("Marrakesh.mrk")) return 1;
1255 if (!pakage_bin()) return 1;
1256 }
1257 else if (!strcmp(argv[1], "extract"))
1258 {
1259 if (argc < 3) err("need file to extract");
1260 if (!package_extract(argv[2])) return 1;
1261 }
1262 else if (!strcmp(argv[1], "install"))
1263 {
1264 if (argc < 3) err("need file to install");
1265 package_clean();
1266 if (!package_install(argv[2])) return 1;
1267 }
1268 else if (!strcmp(argv[1], "clean"))
1269 {
1270 package_clean();
1271 }
1272 else if (!strcmp(argv[1], "remove"))
1273 {
1274 if (argc < 3) err("need package to remove");
1275 if (!package_remove(argv[2])) return 1;
1276 package_clean();
1277 }
1278 else if (!strcmp(argv[1], "release"))
1279 {
1280 char tmp[4096];
1281 char *pk;
1282
1283 if (argc < 3)
1284 {
1285 printf("making src...\n");
1286 if (!parse_bld("Marrakesh.mrk")) return 1;
1287 if (!pakage_src("Marrakesh.mrk")) return 1;
1288 snprintf(tmp, sizeof(tmp), "%s-%s.mks", build.name, build.version);
1289 pk = tmp;
1290 }
1291 else pk = argv[2];
1292 printf("upload + build...\n");
1293 if (!package_up(pk)) return 1;
1294 }
1295 else if (!strcmp(argv[1], "down"))
1296 {
1297 if (argc < 3) err("need package to download");
1298 if (!package_down(argv[2])) return 1;
1299 }
1300 else if (!strcmp(argv[1], "get"))
1301 {
1302 if (argc < 3) err("need package to get");
1303 if (!package_down(argv[2])) return 1;
1304 if (!down_file) err("no download");
1305 package_remove(argv[2]);
1306 package_clean();
1307 if (!package_install(down_file)) return 1;
1308 ecore_file_unlink(down_file);
1309 }
1310 else
1311 {
1312 err("unknown subcommand!");
1313 return 1;
1314 }
1315 ecore_file_shutdown();
1316 ecore_ipc_shutdown();
1317 eet_shutdown();
1318 eina_shutdown();
1319 return 0;
1320}