Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 285 lines (249 sloc) 7.517 kb
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
1 /**
2
3 File: main.c
4
5 Project: DCPU-16 Tools
6 Component: Module Manager
7
8 Authors: James Rhodes
9
10 Description: Main entry point.
11
12 **/
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <bstring.h>
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
17 #include <simclist.h>
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
18 #include <version.h>
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
19 #include <dirent.portable.h>
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
20 #include <argtable2.h>
21 #include <curl/curl.h>
22 #include <curl/easy.h>
14317f1 @hach-que Implemented support for referencing variables in inline assembly.
hach-que authored
23 #include <sys/stat.h>
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
24 #include <osutil.h>
25 #include <debug.h>
26
27 size_t write_data(void* ptr, size_t size, size_t nmemb, FILE* stream)
28 {
29 return fwrite(ptr, size, nmemb, stream);
30 }
31
32 size_t read_data(void* buff, size_t elsize, size_t nelem, void* param)
33 {
34 return fread(buff, elsize, nelem, (FILE*)param);
35 }
36
37 bool do_search(CURL* curl, bstring name)
38 {
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
39 DIR* dir;
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
40 bool printed;
41 CURLcode res;
42 FILE* fp;
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
43 list_t installed;
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
44 struct bStream* stream;
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
45 long httpcode = 0;
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
46 bstring buffer, fname, sstr;
47 bstring ext = bfromcstr(".lua");
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
48 bstring url = bfromcstr("http://dms.dcputoolcha.in/modules/search?q=");
49 bstring modpath = osutil_getmodulepath();
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
50 struct dirent* entry;
51 list_init(&installed);
52 list_attributes_copy(&installed, list_meter_string, 1);
53 list_attributes_comparator(&installed, list_comparator_string);
54
55 // Attempt to open the modules directory.
56 dir = opendir(modpath->data);
57 if (dir == NULL)
58 {
59 printd(LEVEL_ERROR, "unable to query local repository.\n");
60 return 1;
61 }
62
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
63 // Append the temporary search file name.
64 bcatcstr(modpath, "/.search");
65 bconcat(url, name);
66
67 // Open the file and do the cURL transfer.
68 printd(LEVEL_DEFAULT, "querying module repository...\n");
69 fp = fopen(modpath->data, "wb");
70 curl_easy_setopt(curl, CURLOPT_URL, url->data);
71 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
72 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
73 res = curl_easy_perform(curl);
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
74 curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
c340eca @hach-que Fixing issue #130.
hach-que authored
75 if (res != 0 || httpcode != 200)
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
76 {
77 bdestroy(url);
78 bdestroy(name);
79 bdestroy(modpath);
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
80 printd(LEVEL_ERROR, "curl failed with error code %i, HTTP error code %i.\n", res, httpcode);
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
81 return 1;
82 }
83 fclose(fp);
84
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
85 // Print the local results.
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
86 printd(LEVEL_DEFAULT, "search results for %s:\n", name->data);
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
87 while ((entry = readdir(dir)) != NULL)
88 {
89 fname = bfromcstr(&entry->d_name[0]);
90 if (binstr(fname, blength(fname) - 4, ext) == BSTR_ERR)
91 {
92 bdestroy(fname);
93 continue;
94 }
4371d80 @hach-que Fixed search command in module manager showing all results.
hach-que authored
95 if (binstr(fname, 0, name) == BSTR_ERR)
96 {
97 bdestroy(fname);
98 continue;
99 }
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
100 if (entry->d_type != DT_REG)
101 {
102 bdestroy(fname);
103 continue;
104 }
105 sstr = bmidstr(fname, 0, blength(fname) - 4);
106 printd(LEVEL_DEFAULT, " %s (installed)\n", sstr->data);
107 list_append(&installed, sstr->data);
108 bdestroy(sstr);
109 bdestroy(fname);
110 }
111
112 // Print the online results.
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
113 fp = fopen(modpath->data, "r");
114 stream = bsopen(&read_data, fp);
115 buffer = bfromcstr("");
116 printed = false;
117 while (bsreadln(buffer, stream, '\n') != BSTR_ERR)
118 {
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
119 btrimws(buffer);
120 sstr = bmidstr(buffer, 0, blength(buffer) - 4);
121 if (!list_contains(&installed, sstr->data))
122 printd(LEVEL_DEFAULT, " %s\n", sstr->data);
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
123 printed = true;
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
124 bdestroy(sstr);
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
125 }
126 if (!printed)
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
127 printd(LEVEL_DEFAULT, " <no online results>\n");
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
128 bsclose(stream);
129 fclose(fp);
4371d80 @hach-que Fixed search command in module manager showing all results.
hach-que authored
130
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
131 // Clean up.
132 curl_easy_cleanup(curl);
133 return 0;
134 }
135
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
136 bool do_install(CURL* curl, bstring name)
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
137 {
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
138 FILE* fp;
139 CURLcode res;
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
140 long httpcode = 0;
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
141 struct stat buffer;
142 bstring url = bfromcstr("http://dms.dcputoolcha.in/modules/download?name=");
143 bstring modpath = osutil_getmodulepath();
144
145 // Append the file name.
146 bconchar(modpath, '/');
147 bconcat(modpath, name);
148 bcatcstr(modpath, ".lua");
149 bconcat(url, name);
150 bcatcstr(url, ".lua");
151
152 // Check to see if the module is already installed.
153 if (stat(modpath->data, &buffer) == 0)
154 {
155 if (unlink(modpath->data) == 0)
156 printd(LEVEL_WARNING, "removed existing %s module.\n", name->data);
157 else
158 {
159 printd(LEVEL_ERROR, "unable to remove existing %s module.\n", name->data);
160 return 1;
161 }
162 }
163
164 // Open the file and do the cURL transfer.
165 printd(LEVEL_DEFAULT, "querying module repository...\n");
166 fp = fopen(modpath->data, "wb");
167 curl_easy_setopt(curl, CURLOPT_URL, url->data);
168 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
169 curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
170 res = curl_easy_perform(curl);
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
171 curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &httpcode);
c340eca @hach-que Fixing issue #130.
hach-que authored
172 if (res != 0 && httpcode != 200)
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
173 {
174 bdestroy(url);
175 bdestroy(name);
176 bdestroy(modpath);
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
177 printd(LEVEL_ERROR, "curl failed with error code %i, HTTP error code %i.\n", res, httpcode);
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
178 return 1;
179 }
180 fclose(fp);
181 printd(LEVEL_DEFAULT, "module %s installed.\n", name->data);
182
183 return 0;
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
184 }
185
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
186 bool do_uninstall(CURL* curl, bstring name)
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
187 {
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
188 bstring modpath = osutil_getmodulepath();
189 struct stat buffer;
190
191 // Append the file name.
192 bconchar(modpath, '/');
193 bconcat(modpath, name);
194 bcatcstr(modpath, ".lua");
4371d80 @hach-que Fixed search command in module manager showing all results.
hach-que authored
195
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
196 // Check to see if the module is installed.
197 if (stat(modpath->data, &buffer) == 0)
198 {
199 if (unlink(modpath->data) == 0)
200 printd(LEVEL_DEFAULT, "removed existing %s module.\n", name->data);
201 else
202 {
203 printd(LEVEL_ERROR, "unable to remove existing %s module.\n", name->data);
204 return 1;
205 }
206 }
207 else
208 printd(LEVEL_WARNING, "module %s is not installed.\n", name->data);
209
210 return 0;
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
211 }
212
213 int main(int argc, char* argv[])
214 {
215 CURL* curl;
216 bstring command;
217 bstring name;
218 bstring modpath;
219
220 // Define arguments.
221 struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
222 struct arg_str* cmdopt = arg_str1(NULL, NULL, "<command>", "The command; either 'search', 'install' or 'uninstall'.");
223 struct arg_str* nameopt = arg_str1(NULL, NULL, "<name>", "The name of the module to search for, install or uninstall.");
7133593 @hach-que Added verbosity options to tools.
hach-que authored
224 struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
225 struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
226 struct arg_end* end = arg_end(20);
7133593 @hach-que Added verbosity options to tools.
hach-que authored
227 void* argtable[] = { show_help, cmdopt, nameopt, verbose, quiet, end };
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
228
229 // Parse arguments.
230 int nerrors = arg_parse(argc, argv, argtable);
231
232 version_print(bautofree(bfromcstr("Module Manager")));
233 if (nerrors != 0 || show_help->count != 0)
234 {
235 if (show_help->count != 0)
236 arg_print_errors(stderr, end, "mm");
237
238 fprintf(stderr, "syntax:\n dtmm");
239 arg_print_syntax(stderr, argtable, "\n");
240 fprintf(stderr, "options:\n");
241 arg_print_glossary(stderr, argtable, " %-25s %s\n");
242 arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
243 return 1;
244 }
7402262 @hach-que Implemented module Lua bindings for expression system.
hach-que authored
245
7133593 @hach-que Added verbosity options to tools.
hach-que authored
246 // Set verbosity level.
247 debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
248
249 // Set argument 0 and convert parameters.
250 osutil_setarg0(bautofree(bfromcstr(argv[0])));
251 command = bfromcstr(cmdopt->sval[0]);
252 name = bfromcstr(nameopt->sval[0]);
253
254 // Initialize curl or exit.
255 curl = curl_easy_init();
256 if (!curl)
257 {
258 printd(LEVEL_ERROR, "unable to initialize curl.\n");
259 return 1;
260 }
261
262 // Ensure module path exists.
263 modpath = osutil_getmodulepath();
264 if (modpath == NULL)
265 {
266 printd(LEVEL_ERROR, "module path does not exist (searched TOOLCHAIN_MODULES and modules/).\n");
267 return 1;
268 }
269 bdestroy(modpath);
270
271 if (biseqcstrcaseless(command, "search") || biseqcstrcaseless(command, "se"))
e3d569d @hach-que Completed implementation of module manager.
hach-que authored
272 return do_search(curl, name);
273 else if (biseqcstrcaseless(command, "install") || biseqcstrcaseless(command, "in"))
274 return do_install(curl, name);
275 else if (biseqcstrcaseless(command, "uninstall") || biseqcstrcaseless(command, "rm"))
276 return do_uninstall(curl, name);
a1fabb9 @hach-que Partially implemented toolchain module manager.
hach-que authored
277 else
278 {
279 printd(LEVEL_ERROR, "unknown command (must be search, install or uninstall).");
280 return 1;
281 }
282
283 return 0;
284 }
Something went wrong with that request. Please try again.