MSWSP: fix scope of VT_TYPE
[wireshark-wip.git] / update.c
blob13bb7adfbe325f51e03a37e40d4701e424edfaaf
1 /* update.c
3 * $Id$
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 #include "config.h"
27 #include <glib.h>
28 #include <string.h>
29 #include <stdio.h>
31 #include <epan/prefs.h>
32 #include <epan/prefs-int.h>
33 #include <epan/filesystem.h>
35 #include "simple_dialog.h"
36 #include "version_info.h"
38 #ifdef HAVE_LIBPCAP
39 #include "capture-pcap-util.h"
40 #endif
42 #include <wsutil/file_util.h>
44 #include <wininet.h>
45 #include "nio-ie5.h"
48 /* update information about a single component */
49 typedef struct update_info_s {
50 char *prefix; /* prefix of the update file keys */
51 gboolean needs_update; /* does this component need an update */
52 char *version_installed; /* the version currently installed */
54 char *title; /* the component title (name) */
55 char *description; /* description of the component */
56 char *version_recommended; /* the version recommended */
57 char *url; /* the URL for an update */
58 char *md5; /* md5 checksum for that update */
59 char *size; /* size of that update */
60 } update_info_t;
63 /* download a complete file from the internet */
64 int
65 download_file(const char *url, const char *filename) {
66 netio_ie5_t * conn;
67 char buf[100];
68 int chunk_len;
69 int fd;
70 int stream_len;
71 int ret = 0;
74 /* open output file */
75 fd = ws_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
76 if(fd == -1) {
77 g_warning("Couldn't open output file %s!", filename);
78 return -1;
81 /* connect to url */
82 conn = netio_ie5_connect (url);
83 if (conn == NULL) {
84 ws_close(fd);
85 g_warning("Couldn't connect to %s!", url);
86 return -1;
89 do {
90 /* XXX - maybe add a progress bar here */
92 /* read some bytes from the url */
93 chunk_len = netio_ie5_read (conn, buf, sizeof(buf));
95 /* write bytes to the output file */
96 stream_len = ws_write( fd, buf, chunk_len);
97 if(stream_len != chunk_len) {
98 g_warning("output failed: stream_len %u != chunk_len %u", stream_len, chunk_len);
99 ret = -1;
100 break;
102 } while(chunk_len > 0);
104 netio_ie5_disconnect(conn);
106 ws_close(fd);
108 return ret;
111 update_info_t *
112 update_info_new(void)
114 return g_malloc0(sizeof(update_info_t));
117 void
118 update_info_delete(update_info_t *update_info)
120 g_free(update_info->prefix);
121 g_free(update_info->version_installed);
122 g_free(update_info->title);
123 g_free(update_info->description);
124 g_free(update_info->version_recommended);
125 g_free(update_info->url);
126 g_free(update_info->md5);
127 g_free(update_info->size);
129 g_free(update_info);
132 /* check a single key value pair */
133 static void
134 update_pref_check(gchar *pref_name, gchar *value, char *check_prefix, char *check_name, char **check_value)
136 GString *check = g_string_new(check_prefix);
138 g_string_append(check, check_name);
140 if(strcmp(pref_name, check->str) == 0) {
141 if(*check_value)
142 /* there shouldn't be a duplicate entry in the update file */
143 g_warning("Duplicate of %s: current %s former %s", pref_name, value, *check_value);
144 else
145 *check_value = g_strdup(value);
148 g_string_free(check, TRUE);
151 /* a new key value pair from the update file */
152 static prefs_set_pref_e
153 update_pref(gchar *pref_name, gchar *value, void *private_data)
155 update_info_t *update_info = private_data;
157 update_pref_check(pref_name, value, update_info->prefix, "title", &update_info->title);
158 update_pref_check(pref_name, value, update_info->prefix, "description", &update_info->description);
159 update_pref_check(pref_name, value, update_info->prefix, "version", &update_info->version_recommended);
160 update_pref_check(pref_name, value, update_info->prefix, "update.url", &update_info->url);
161 update_pref_check(pref_name, value, update_info->prefix, "update.md5", &update_info->md5);
162 update_pref_check(pref_name, value, update_info->prefix, "update.size", &update_info->size);
164 return PREFS_SET_OK;
167 /* display an update_info */
168 static void
169 update_info_display(update_info_t *update_info)
171 GString *overview;
174 overview = g_string_new("");
176 if(update_info->title) {
177 g_string_append_printf(overview, "%s%s%s",
178 simple_dialog_primary_start(), update_info->title, simple_dialog_primary_end());
179 } else {
180 g_string_append_printf(overview, "%sComponent%s",
181 simple_dialog_primary_start(), simple_dialog_primary_end());
184 g_string_append(overview, "\n\n");
186 if(update_info->description)
187 g_string_append_printf(overview, "%s\n\n", update_info->description);
189 g_string_append_printf(overview, "Installed: %s\n", update_info->version_installed);
191 if(update_info->version_recommended)
192 g_string_append_printf(overview, "Recommended: %s\n", update_info->version_recommended);
193 else
194 g_string_append(overview, "Recommenced: unknown\n");
196 if(update_info->version_recommended && update_info->url)
197 g_string_append_printf(overview, "From: %s\n", update_info->url);
199 if(update_info->size)
200 g_string_append_printf(overview, "Size: %s", update_info->size);
202 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, overview->str);
204 g_string_free(overview, TRUE);
208 /* check the version of the wireshark program */
209 static update_info_t *
210 update_check_wireshark(const char *local_file)
212 FILE *pf;
213 update_info_t *update_info = update_info_new();
216 update_info->version_installed = g_strdup(VERSION);
217 update_info->prefix = "wireshark.setup.";
219 pf = ws_fopen(local_file, "r");
220 if(pf != NULL) {
221 /* read in update_info of Wireshark */
222 read_prefs_file(local_file, pf, update_pref, update_info);
223 fclose(pf);
225 /* check if Wireshark needs an update */
226 if(update_info->version_installed && update_info->version_recommended &&
227 strcmp(update_info->version_installed, update_info->version_recommended) != 0)
229 update_info->needs_update = TRUE;
231 } else {
232 g_warning("Could not open %s", local_file);
235 return update_info;
238 /* check the version of winpcap */
239 static update_info_t *
240 update_check_winpcap(const char *local_file)
242 FILE *pf;
243 update_info_t * update_info = update_info_new();
244 GString *pcap_version_tmp;
245 char *pcap_version = NULL;
246 char *pcap_vstart;
247 char *pcap_vend;
250 update_info->prefix = "winpcap.";
252 pf = ws_fopen(local_file, "r");
253 if(pf != NULL) {
254 /* read in update_info of WinPcap */
255 read_prefs_file(local_file, pf, update_pref, update_info);
256 fclose(pf);
258 /* get WinPcap version */
259 /* XXX - what's the "approved" method to get the WinPcap version? */
260 pcap_version_tmp = g_string_new("");
261 get_runtime_pcap_version(pcap_version_tmp);
263 /* cut out real version from "combined" version string */
264 pcap_vstart = strstr(pcap_version_tmp->str, "with WinPcap version ");
265 if(pcap_vstart != NULL) {
266 pcap_vstart += sizeof("with WinPcap version");
267 pcap_vend = strstr(pcap_vstart, " ");
268 if(pcap_vend != NULL) {
269 pcap_vend[0] = 0;
270 pcap_version = g_strdup(pcap_vstart);
274 update_info->version_installed = g_strdup(pcap_version);
276 if(pcap_version && update_info->version_recommended &&
277 strcmp(pcap_version, update_info->version_recommended) != 0)
279 update_info->needs_update = TRUE;
281 } else {
282 g_warning("Could not open %s", local_file);
285 g_string_free(pcap_version_tmp, TRUE);
286 g_free(pcap_version);
288 return update_info;
292 /* check for all updates */
293 void
294 update_check(gboolean interactive)
296 char *local_file;
297 const char *url_file = "http://127.0.0.1/wsupdate"; /* XXX - build the URL depending on platform, versions, ... */
298 update_info_t *update_info_wireshark;
299 update_info_t *update_info_winpcap;
302 /* build update file name */
303 /* XXX - using the personal path, use temp dir instead? */
304 local_file = get_persconffile_path("wsupdate", FALSE);
305 if(local_file == NULL) {
306 g_warning("Couldn't create output path!");
307 return;
310 /* download update file */
311 if(download_file(url_file, local_file) == -1) {
312 g_warning("Couldn't download update file: %s", local_file);
313 g_free(local_file);
314 return;
317 /* check wireshark */
318 update_info_wireshark = update_check_wireshark(local_file);
320 /* check winpcap */
321 update_info_winpcap = update_check_winpcap(local_file);
323 /* display results */
324 if(update_info_wireshark->needs_update || update_info_winpcap->needs_update) {
325 if(update_info_wireshark->needs_update)
326 update_info_display(update_info_wireshark);
327 if(update_info_winpcap->needs_update)
328 update_info_display(update_info_winpcap);
329 } else {
330 if(interactive) {
331 simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK, "No updates available");
335 /* cleanup */
336 update_info_delete(update_info_wireshark);
337 update_info_delete(update_info_winpcap);
339 g_free(local_file);