13 #include <sys/types.h>
19 #include <sigc++/bind.h>
21 #include <libwfut/WFUT.h>
22 #include <libwfut/Encoder.h>
23 #include <libwfut/platform.h>
27 static const bool debug =
true;
30 static struct option long_options [] =
32 {
"update", 1, 0,
'u' },
33 {
"system", 1, 0,
's' },
34 {
"server", 1, 0,
'S' },
35 {
"prefix", 1, 0,
'p' },
36 {
"version", 0, 0,
'v' },
37 {
"help", 0, 0,
'h' },
43 static char short_options [] =
"u:s:p:vS:h";
45 static void recordUpdate(
const FileObject &fo,
const std::string &tmpfile) {
47 if (!os_exists(tmpfile)) {
49 fp = fopen(tmpfile.c_str(),
"wt");
54 fprintf(fp,
"<?xml version=\"1.0\"?>\n");
55 fprintf(fp,
"<fileList dir=\"\">\n");
57 fp = fopen(tmpfile.c_str(),
"at");
63 fprintf(fp,
"<file filename=\"%s\" version=\"%d\" crc32=\"%lu\" size=\"%ld\" execute=\"%s\"/>\n",
Encoder::encodeString(fo.filename).c_str(), fo.version, fo.crc32, fo.size, (fo.execute) ? (
"true") : (
"false"));
71 void onDownloadComplete(
const std::string& u,
const std::string& f,
const ChannelFileList& updates,
ChannelFileList* local,
const std::string& tmpfile) {
72 printf(
"Downloaded: %s\n", f.c_str());
74 const WFUT::FileMap& ulist = updates.
getFiles();
75 WFUT::FileMap::const_iterator I = ulist.find(f);
77 assert (I != ulist.end());
85 recordUpdate(I->second, tmpfile);
89 void onDownloadFailed(
const std::string& u,
const std::string& f,
const std::string& r,
int* error) {
90 fprintf(stderr,
"Error downloading: %s - %s\n", u.c_str(), r.c_str());
95 void onUpdateReason(
const std::string& filename,
const WFUT::WFUTUpdateReason wu) {
96 if (wu == WFUT::WFUT_UPDATE_MODIFIED) {
97 printf(
"%s has been modified, will not update.\n", filename.c_str());
101 void print_usage(
const char* name) {
102 printf(
"WFUT Version: %s\n", VERSION);
103 printf(
"Usage: %s [options]\n", name);
104 printf(
"\nOptions:\n");
105 printf(
"\t-p, --prefix channel_name -- The destination directory. (Optional)\n");
106 printf(
"\t-s, --system channel_name -- The system channels directory. (Optional)\n");
107 printf(
"\t-S, --server channel_name -- The URL to the update server.(Optional)\n");
108 printf(
"\t-u, --update channel_name -- The name of the channel to update.\n");
109 printf(
"\t-v, --version -- Display the version information.\n");
110 printf(
"\t-h, --help -- Display this message.\n");
114 int main(
int argc,
char *argv[]) {
117 std::string server_root =
"http://white.worldforgedev.org/WFUT/";
118 std::string mirror_file =
"mirrors.xml";
119 std::string channel_file =
"wfut.xml";
120 std::string tmpfile =
"tempwfut.xml";
122 std::string channel =
".";
123 std::string local_path =
"./";
124 std::string system_path =
"";
127 print_usage(argv[0]);
133 int c = getopt_long(argc, argv, short_options, long_options, &opt_index);
138 print_usage(argv[0]);
142 fprintf(stderr,
"WFUT Version: %s\n", VERSION);
149 fprintf(stderr,
"Missing channel name\n");
154 system_path = optarg;
156 fprintf(stderr,
"Missing system path\n");
163 fprintf(stderr,
"Missing prefix\n");
168 server_root = optarg;
170 fprintf(stderr,
"Missing system path\n");
175 fprintf(stderr,
"Unknown command: %c\n", c);
179 if (debug) printf(
"Channel name: %s\n", channel.c_str());
181 const std::string &local_root = local_path +
"/" + channel +
"/";
189 const std::string mirror_url = server_root +
"/" + mirror_file;
193 if (mirrors.empty() ==
false) {
195 srand((
unsigned)time(NULL));
196 #if defined (WIN32) || defined (_WIN32) || defined( __WIN32__)
198 srand48((
unsigned)time(NULL));
201 std::random_shuffle(mirrors.begin(), mirrors.end());
203 server_root = (*mirrors.begin()).url;
211 const std::string &local_wfut = local_path +
"/" + channel +
"/" + channel_file;
212 if (debug) printf(
"Local wfut: %s\n", local_wfut.c_str());
214 if (os_exists(local_wfut)) {
216 fprintf(stderr,
"Error reading local wfut.xml file\n");
220 if (channel ==
".") channel = local.
getName();
225 const std::string &tmp_wfut = local_path +
"/" + tmpfile;
226 if (debug) printf(
"Tmp wfut: %s\n", tmp_wfut.c_str());
228 if (os_exists(tmp_wfut)) {
230 fprintf(stderr,
"Error reading tmpwfut.xml file\n");
234 const FileMap &fm = tmplist.
getFiles();
235 FileMap::const_iterator I = fm.begin();
236 FileMap::const_iterator Iend = fm.end();
237 for (; I != Iend; ++I) {
244 if (!system_path.empty()) {
245 const std::string &system_wfut = system_path +
"/" + channel +
"/" + channel_file;
246 if (debug) printf(
"System wfut: %s\n", system_wfut.c_str());
248 if (os_exists(system_wfut)) {
250 fprintf(stderr,
"Error reading system wfut.xml file\n");
254 if (channel ==
".") channel = system.
getName();
260 if (channel.empty() || channel ==
".") {
261 fprintf(stderr,
"Unable to determine channel name.\n");
266 const std::string &server_wfut = server_root +
"/" + channel +
"/" + channel_file;
267 if (debug) printf(
"Server wfut: %s\n", server_wfut.c_str());
270 printf(
"Error downloading server channel file\n");
275 if (debug) printf(
"Local Root: %s\n", local_root.c_str());
277 printf(
"Updating Channel: %s\n", channel.c_str());
281 wfut.
UpdateReason.connect(sigc::ptr_fun(onUpdateReason));
283 printf(
"Error determining file to update\n");
292 wfut.
updateChannel(updates, server_root +
"/" + channel, local_root);
298 wfut.
DownloadComplete.connect(sigc::bind(sigc::ptr_fun(onDownloadComplete), updates, &local, tmp_wfut));
299 wfut.
DownloadFailed.connect(sigc::bind(sigc::ptr_fun(onDownloadFailed), &error));
308 if (os_exists(tmp_wfut)) remove(tmp_wfut.c_str());
314 fprintf(stderr,
"%d files failed to download.\n", error);