Import Debian changes 0.7.3-1.1
[jigdo.git] / src / gtk / jigdo.cc
1 /* $Id: jigdo.cc,v 1.14 2005/07/09 22:21:04 atterer Exp $ -*- C++ -*-
2   __   _
3   |_) /|  Copyright (C) 2001-2002  |  richard@
4   | \/¯|  Richard Atterer          |  atterer.net
5   ¯ '` ¯
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License, version 2. See
8   the file COPYING for details.
9
10 */
11
12 #include <config.h>
13
14 #if DEBUG
15 #  include <unistd-jigdo.h>
16 #endif
17
18 #include <string.h>
19 #include <iostream>
20 #include <string>
21 #include <vector>
22
23 #include <debug.hh>
24 #include <download.hh>
25 #include <glibc-getopt.h>
26 #include <glibwww.hh>
27 #include <gui.hh>
28 #include <jobline.hh>
29 #include <proxyguess.hh>
30 #include <string-utf.hh>
31 #include <support.hh>
32
33 #if WINDOWS
34 #  include <windows.h>
35 #endif
36 //______________________________________________________________________
37
38 #if WINDOWS
39 string packageDataDir;
40 #endif
41 //______________________________________________________________________
42
43 namespace {
44
45 #if WINDOWS
46 const char* binaryName = "jigdo";
47 #else
48 const char* binaryName;
49 #endif
50
51 vector<string> optUris;
52 enum OptProxy { GUESS, ON, OFF } optProxy = GUESS;
53 string optDebug;
54
55 void tryHelp() {
56   cerr << subst(_("%L1: Try `%L1 -h' or `man jigdo' for more "
57                   "information"), binaryName) << endl;
58   exit(3);
59 }
60
61 enum {
62   LONGOPT_DEBUG = 0x100, LONGOPT_NODEBUG
63 };
64
65 inline void cmdOptions(int argc, char* argv[]) {
66   bool optHelp = false;
67   bool optVersion = false;
68
69   if (!WINDOWS) binaryName = argv[0];
70   bool error = false;
71   while (true) {
72     static const struct option longopts[] = {
73       { "debug",              optional_argument, 0, LONGOPT_DEBUG },
74       { "help",               no_argument,       0, 'h' },
75       { "no-debug",           no_argument,       0, LONGOPT_NODEBUG },
76       { "proxy",              required_argument, 0, 'Y' },
77       { "version",            no_argument,       0, 'v' },
78       { 0, 0, 0, 0 }
79     };
80     int c = getopt_long(argc, argv, "hvY:", longopts, 0);
81     if (c == -1) break;
82     switch (c) {
83     case 'h': optHelp = true; break;
84     case 'v': optVersion = true; break;
85     case 'Y':
86       if (strcmp(optarg, "guess") == 0) optProxy = GUESS;
87       else if (strcmp(optarg, "on") == 0) optProxy = ON;
88       else if (strcmp(optarg, "off") == 0) optProxy = OFF;
89       else cerr << subst(_("%L1: Please specify `on', `off' or `guess' after"
90                            " --proxy"), binaryName) << endl;
91       break;
92     case LONGOPT_DEBUG:
93       if (optarg) optDebug = optarg; else optDebug = "all";
94       break;
95     case LONGOPT_NODEBUG: optDebug.erase(); break;
96     case '?': error = true;
97     case ':': break;
98     default:
99       msg("getopt returned %1", static_cast<int>(c));
100       break;
101     }
102   }
103   if (error) tryHelp();
104   if (optHelp || optVersion) {
105     if (optVersion) cout << "jigdo version " JIGDO_VERSION << endl;
106     if (optHelp) cout << subst(_(
107     "Usage: %L1 [OPTIONS] [URL]\n"
108     "Options:\n"
109     "  -h  --help       Output help\n"
110     "  -Y  --proxy=on/off/guess [guess]\n"
111     "                   Turn proxy on (i.e. use env vars http_proxy,\n"
112     "                   ftp_proxy, all_proxy) or off, or guess (from\n"
113     "                   Mozilla/KDE/wget/lynx settings)\n"
114     "  -v  --version    Output version info\n"
115     "  --debug[=all|=UNIT1,UNIT2...|=help]\n"
116     "                   Print debugging information for all units, or for\n"
117     "                   specified units, or print list of units.\n"
118     "                   Can use `~', e.g. `all,~libwww'\n"
119     "  --no-debug       No debugging info [default]\n"),
120     binaryName) << endl;
121     exit(0);
122   }
123
124   Logger::scanOptions(optDebug, binaryName);
125
126   while (optind < argc) optUris.push_back(argv[optind++]);
127 }
128
129 #if WINDOWS
130 inline void getPackageDataDir() {
131   char buf[MAX_PATH];
132   GetModuleFileName(NULL, buf, MAX_PATH);
133   char* end = strrchr(buf, '\\');
134   packageDataDir.append(buf, end - buf + 1);
135 }
136
137 void noPrintHandler(const char*) {
138   return;
139 }
140
141 void noLogHandler(const gchar*, GLogLevelFlags, const gchar*, gpointer) {
142   return;
143 }
144 #endif
145
146 } // local namespace
147 //______________________________________________________________________
148
149 int main(int argc, char *argv[]) {
150 # if WINDOWS
151   getPackageDataDir();
152   if (!DEBUG) {
153     // Switch off error messages, to avoid that the console window is opened
154     g_set_print_handler(noPrintHandler);
155     g_set_printerr_handler(noPrintHandler);
156     g_log_set_handler(0, static_cast<GLogLevelFlags>(-1), noLogHandler, 0);
157   }
158 # endif
159 # if ENABLE_NLS
160   bindtextdomain(PACKAGE, packageLocaleDir);
161   textdomain(PACKAGE);
162   bind_textdomain_codeset(PACKAGE, "UTF-8");
163 # endif
164 # if DEBUG
165   Logger::setEnabled("general");
166 # else
167   Debug::abortAfterFailedAssertion = false;
168 # endif
169
170   try {
171     // Initialize GTK+ and display window
172     gtk_set_locale();
173     gtk_init(&argc, &argv);
174     {
175 #     if !WINDOWS
176       add_pixmap_directory("../gfx");
177       add_pixmap_directory("gfx");
178 #     endif
179       string pixDir = packageDataDir; pixDir += "pixmaps";
180       add_pixmap_directory("..\\gfx");
181       add_pixmap_directory(pixDir.c_str());
182     }
183     cmdOptions(argc, argv);
184     GUI::create();
185     gtk_widget_show(GUI::window.window);
186
187     // Initialize networking code
188     Download::init();
189     if (optProxy == OFF) {
190       // Make libcurl ignore environment variables, simply by unsetting them
191       putenv("http_proxy=");
192       putenv("https_proxy=");
193       putenv("ftp_proxy=");
194       putenv("gopher_proxy=");
195       putenv("no_proxy=");
196       putenv("all_proxy=");
197     } else if (optProxy == GUESS) {
198       proxyGuess();
199     }
200
201     // Start downloads of any URIs specified on command line
202     const char* dest = g_get_current_dir();
203     for (vector<string>::const_iterator i = optUris.begin(),
204            e = optUris.end(); i != e; ++i)
205       JobLine::create(i->c_str(), dest);
206     optUris.clear();
207     g_free((gpointer)dest);
208
209     gtk_main(); // Here be dragons
210   }
211   catch (Cleanup c) {
212     msg("[Cleanup %1]", c.returnValue);
213     GUI::jobList.finalize();
214     Download::cleanup();
215     return c.returnValue;
216   }
217   GUI::jobList.finalize();
218   Download::cleanup();
219
220 # if DEBUG && !WINDOWS
221   const char* preload = getenv("LD_PRELOAD");
222   if (preload != 0 && strstr(preload, "libmemintercept") != 0) {
223     msg("Detected memprof - doing sleep() to allow you to find leaks");
224     while (true) sleep(1024);
225   }
226 # endif
227   return 0;
228 }