logo

badwolf

minimalist and privacy-oriented web browser based on WebKitGTK git clone https://hacktivis.me/git/badwolf.git
commit: acde5dfc614ee549b5c1f0119c7e3c8c777c4a82
parent a49df8ad9869a47a10138738b38fd0ffdb95e402
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Wed,  8 Jul 2020 07:42:06 +0200

Merge branch 'release-1.0' into missy for 1.0.1

Fixes
-------
- Support for relative paths as command line arguments
- Downloads tab: no longer resizes the main window
- Manpage: Syntax is now correct, unbreaking GNU groff formatting.

Changes
-------
- When an user requests as new tab (ctrl-t, new tab button), switch to it
- Downloads tab: A scrollable list view is used instead of a stack of labels

Diffstat:

MMakefile2+-
MREADME.md6+++++-
Mbadwolf.152++++++++++++++++++++++++++++------------------------
Mbadwolf.c34++++++++++++++--------------------
Mbadwolf.h2+-
Mconfig.h11+++++++++++
Mdownloads.c18+++++++++++-------
Mkeybindings.c4++--
Mpo/messages.pot62+++++++++++++++++++++++++++++++-------------------------------
Muri.c22++++++++++++++++++++--
Muri_test.c5++++-
11 files changed, 128 insertions(+), 90 deletions(-)

diff --git a/Makefile b/Makefile @@ -33,7 +33,7 @@ EXE_test = uri_test TRANS = fr.mo pt_BR.mo DOCS = usr.bin.badwolf README.md KnowledgeBase.md interface.txt -CDEPS = -DDATADIR=\"$(DATADIR)\" -DPACKAGE=\"$(PACKAGE)\" -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION_FULL)\" +CDEPS = -DDATADIR=\"$(DATADIR)\" -DPACKAGE=\"$(PACKAGE)\" -D_XOPEN_SOURCE=500 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION_FULL)\" CDEPS += `$(PKGCONFIG) --cflags $(DEPS)` LIBS = `$(PKGCONFIG) --libs $(DEPS)` diff --git a/README.md b/README.md @@ -33,6 +33,10 @@ You need to have gettext installed. If you want a GUI, poedit exists and Weblate - Syncing PO file with the POT file: ``make po/de.po`` - Initialising a new PO file (example for German, `de_DE`): ``msginit -l de_DE -i po/messages.pot -o po/de.po`` +## Contacts / Discussions +- IRC: `#badwolf-browser` on FreeNode +- Matrix (bridge): <https://matrix.to/#/#freenode_#badwolf-browser:matrix.org> + ## Repositories ### git - Main: <https://hacktivis.me/git/badwolf/>, <git://hacktivis.me/git/badwolf.git> @@ -56,7 +60,7 @@ Dependencies are: Compilation is done with `make`, install with `make install` (`DESTDIR` and `PREFIX` environment variables are supported, amongs other common ones). An example AppArmor profile is provided at `usr.bin.badwolf`, please do some long runtime checks before shipping it or a modified version, help can be provided but with no support. -You'll also need `rsvg-convert(1)` (from librsvg) and scour if you want to regenerate the icons, for example after modifying them or adding a new size. These aren't needed for normal installation as it is bundled. +You'll also need inkscape (command line only) if you want to regenerate the icons, for example after modifying them or adding a new size. These aren't needed for normal installation as it is bundled. ## Notes Most of the privacy/security stuff will be done with patches against WebKit as quite a lot isn’t into [WebKitSettings](https://webkitgtk.org/reference/webkit2gtk/stable/WebKitSettings.html) and with generic WebKit extensions that should be resuseable. diff --git a/badwolf.1 b/badwolf.1 @@ -2,7 +2,7 @@ ./" Copyright © 2019-2020 Badwolf Authors <https://hacktivis.me/projects/badwolf> ./" SPDX-License-Identifier: BSD-3-Clause .Dd 2019-10-31 -.Dt badwolf 1 +.Dt BADWOLF 1 .Sh NAME .Nm badwolf .Nd minimalist and privacy-oriented WebkitGTK browser @@ -20,21 +20,21 @@ will probably get added at a later release. .Sh KEYBINDINGS The following section lists the keybinding by their action, each item is described by the widget the focus is on or .Aq any -if it works for the whole window, followed by the keybind it grabs. A is short for Alt, C is short for Control, S is short for Shift. -.Bl -width Ds -tag -.It webview C-Scroll +if it works for the whole window, followed by the keybind it grabs. +.Bl -tag -width Ds +.It webview Ctrl-Scroll Zooms the webpage in/out. -.It webview C-0 +.It webview Ctrl-0 Resets webpage zoom to 100%. -.It any C-t +.It any Ctrl-t Creates a new tab (in a new session, similar as pressing the button) -.It browser C-F4, browser A-d +.It browser Ctrl-F4, browser Alt-d Closes the current tab -.It browser C-f +.It browser Ctrl-f Focuses on the search entry -.It browser C-l +.It browser Ctrl-l Focuses on the location(URL) entry -.It browser C-S-r / C-r, browser F5 +.It browser Ctrl-Shift-r / Ctrl-r, browser F5 Reloads the content in the current tab (with/without clearing cache) .It browser Escape Stops loading the content in the current tab @@ -42,33 +42,36 @@ Stops loading the content in the current tab Toggles caret browsing. .It browser F12 Opens the web inspector. -.It browser C-[ / C-] +.It browser Ctrl-[ / Ctrl-] Go back/forward in current tab’s history -.It browser C-p +.It browser Ctrl-p Print the current page. (spawns a dialog) -.It any A-Left / A-Right +.It any Alt-Left / Alt-Right Go to the previous/next tab .It any F1 Shows the about dialog .It any Alt-n -Where n is any numeric-row key. Go to the n-th tab, 0 goes to the last one. +Where n is any numeric-row key. +Go to the n-th tab, 0 goes to the last one. .El .Ss DEFAULT ONES Here is a incomplete list of the default Webkit/GTK keybindings: -.Bl -width Ds -tag -.It any C-PageUp / C-PageDown +.Bl -tag -width Ds +.It any Ctrl-PageUp / Ctrl-PageDown Go to the previous/next tab -.It search C-g / C-S-g +.It search Ctrl-g / Ctrl-Shift-g When the search box is focused it goes to the Next/Previous search term. .It search Escape Cancels current search .El .Sh ENVIRONMENT -.Bl -width Ds -tag +.Bl -tag -width Ds .It Ev BADWOLF_L10N -A colon-separated list in the form lang_COUNTRY where lang is in ISO-639 and COUNTRY in ISO-3166. For example +A colon-separated list in the form lang_COUNTRY where lang is in ISO-639 and COUNTRY in ISO-3166. +For example .Ic BADWOLF_L10N="en_GB:fr_FR:de_DE" . -When this variable isn't set, spelling isn't activated. A more generic variable name is also intended to be used in the future. +When this variable isn't set, spelling isn't activated. +A more generic variable name is also intended to be used in the future. .El .Sh FILES .Bl -tag -width Ds -compact @@ -79,13 +82,14 @@ to be loaded into .Nm . Note: They aren't the JavaScript-based Web-Extensions supported by Firefox or Chrome, but native code in shared objects using the WebKitGTK API. .Pp Examples of useful extensions may be found at: -.Bl -compact +.Bl -item -compact .Lk https://hacktivis.me/git/badwolf-extensions .Lk https://github.com/jun7/wyebadblock .El .It Pa ${DATADIR:-/usr/local/share}/badwolf/interface.css .It Pa ${XDG_DATA_HOME:-$HOME/.local/share}/badwolf/interface.css -CSS files (respectively system and user-level) for styling badwolf interface. See +CSS files (respectively system and user-level) for styling badwolf interface. +See .Lk https://developer.gnome.org/gtk3/stable/chap-css-properties.html for the properties being available. .Pp @@ -95,6 +99,8 @@ environment variable on launching .Nm and going to the CSS tab. .El +.Sh AUTHORS +.An Haelwenn (lanodan) Monnier Aq Mt contact+badwolf@hacktivis.me .Sh BUGS You can submit contributions or tickets to .Lk https://gitlab.com/lanodan/badwolf @@ -102,5 +108,3 @@ or .Mt contact+badwolf@hacktivis.me , with .Xr git-send-email 1 for patches. -.Sh AUTHORS -.An Haelwenn (lanodan) Monnier Aq Mt contact+badwolf@hacktivis.me diff --git a/badwolf.c b/badwolf.c @@ -74,8 +74,7 @@ WebViewCb_close(WebKitWebView *webView, gpointer user_data) struct Client *browser = (struct Client *)user_data; GtkNotebook *notebook = GTK_NOTEBOOK(browser->window->notebook); - gtk_notebook_remove_page(notebook, - badwolf_get_tab_position(GTK_CONTAINER(notebook), browser->box)); + gtk_notebook_remove_page(notebook, gtk_notebook_page_num(GTK_NOTEBOOK(notebook), browser->box)); gtk_widget_destroy(browser->box); @@ -212,7 +211,7 @@ webView_tab_label_change(struct Client *browser, const gchar *title) gtk_notebook_set_menu_label_text(GTK_NOTEBOOK(notebook), browser->box, title); // Set the window title if the title change was on the current tab - if(badwolf_get_tab_position(GTK_CONTAINER(notebook), browser->box) == + if(gtk_notebook_page_num(GTK_NOTEBOOK(notebook), browser->box) == gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook))) gtk_window_set_title(GTK_WINDOW(browser->window->main_window), title); } @@ -287,7 +286,7 @@ WebViewCb_create(WebKitWebView *related_web_view, struct Window *window = (struct Window *)user_data; struct Client *browser = new_browser(window, NULL, related_web_view); - if(badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser) < 0) + if(badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser, FALSE) < 0) return NULL; else return browser->webView; @@ -825,7 +824,8 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat return browser; } -/* badwolf_new_tab: Inserts struct Client *browser in GtkNotebook *notebook +/* badwolf_new_tab: Inserts struct Client *browser in GtkNotebook *notebook + * and optionally switches selected tab to it. * * returns: * 0 : Ran successfully @@ -833,7 +833,7 @@ new_browser(struct Window *window, const gchar *target_url, WebKitWebView *relat * -2 : browser is NULL */ int -badwolf_new_tab(GtkNotebook *notebook, struct Client *browser) +badwolf_new_tab(GtkNotebook *notebook, struct Client *browser, bool auto_switch) { gint current_page = gtk_notebook_get_current_page(notebook); gchar *title = _("New tab"); @@ -850,6 +850,11 @@ badwolf_new_tab(GtkNotebook *notebook, struct Client *browser) gtk_widget_queue_draw(GTK_WIDGET(notebook)); + if(auto_switch) + { + gtk_notebook_set_current_page(notebook, gtk_notebook_page_num(notebook, browser->box)); + } + return 0; } @@ -860,7 +865,7 @@ new_tabCb_clicked(GtkButton *new_tab, gpointer user_data) struct Window *window = (struct Window *)user_data; struct Client *browser = new_browser(window, NULL, NULL); - badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser); + badwolf_new_tab(GTK_NOTEBOOK(window->notebook), browser, TRUE); } static void @@ -883,17 +888,6 @@ notebookCb_switch__page(GtkNotebook *notebook, GtkWidget *page, guint page_num, gtk_window_set_title(GTK_WINDOW(window->main_window), gtk_widget_get_tooltip_text(label)); } -gint -badwolf_get_tab_position(GtkContainer *notebook, GtkWidget *child) -{ - GValue position = G_VALUE_INIT; - g_value_init(&position, G_TYPE_INT); - - gtk_container_child_get_property(notebook, child, "position", &position); - - return g_value_get_int(&position); -} - int main(int argc, char *argv[]) { @@ -979,10 +973,10 @@ main(int argc, char *argv[]) gtk_widget_show_all(window->main_window); if(argc == 1) - badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, NULL, NULL)); + badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, NULL, NULL), FALSE); else for(int i = 1; i < argc; ++i) - badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, argv[i], NULL)); + badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, argv[i], NULL), FALSE); gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), 1); diff --git a/badwolf.h b/badwolf.h @@ -38,6 +38,6 @@ GtkWidget *badwolf_new_tab_box(const gchar *title, struct Client *browser); void webView_tab_label_change(struct Client *browser, const gchar *title); struct Client * new_browser(struct Window *window, const gchar *target_url, WebKitWebView *related_web_view); -int badwolf_new_tab(GtkNotebook *notebook, struct Client *browser); +int badwolf_new_tab(GtkNotebook *notebook, struct Client *browser, bool auto_switch); gint badwolf_get_tab_position(GtkContainer *notebook, GtkWidget *child); #endif /* BADWOLF_H_INCLUDED */ diff --git a/config.h b/config.h @@ -93,4 +93,15 @@ */ #define BADWOLF_STATUSLABEL_ELLIPSIZE PANGO_ELLIPSIZE_MIDDLE +/* BADWOLF_DOWNLOAD_FILE_PATH_ELLIPSIZE: pango ellipsize mode of the download destination path, + * can be one of: + * - PANGO_ELLIPSIZE_NONE + * - PANGO_ELLIPSIZE_START + * - PANGO_ELLIPSIZE_MIDDLE + * - PANGO_ELLIPSIZE_END + * + * See https://developer.gnome.org/pango/stable/pango-Layout-Objects.html#PangoEllipsizeMode + */ +#define BADWOLF_DOWNLOAD_FILE_PATH_ELLIPSIZE PANGO_ELLIPSIZE_MIDDLE + #endif /* CONFIG_H_INCLUDED */ diff --git a/downloads.c b/downloads.c @@ -42,6 +42,7 @@ download_new_entry(WebKitDownload *webkit_download, struct Download *download) download->stop_icon = gtk_button_new_from_icon_name("process-stop", GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(download->progress), TRUE); + gtk_label_set_ellipsize(GTK_LABEL(download->file_path), BADWOLF_DOWNLOAD_FILE_PATH_ELLIPSIZE); g_signal_connect( download->stop_icon, "clicked", G_CALLBACK(download_stop_iconCb_clicked), webkit_download); @@ -52,8 +53,7 @@ download_new_entry(WebKitDownload *webkit_download, struct Download *download) gtk_box_pack_start(GTK_BOX(download->container), download->status, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(download->container), download->file_path, FALSE, FALSE, 0); - gtk_box_pack_start( - GTK_BOX(download->window->downloads_tab), download->container, FALSE, FALSE, 0); + gtk_list_box_insert(GTK_LIST_BOX(download->window->downloads_tab), download->container, -1); gtk_widget_show_all(download->container); } @@ -179,14 +179,18 @@ downloadCb_received_data(WebKitDownload *webkit_download, guint64 data_lenght, g GtkWidget * badwolf_downloads_tab_new() { - return gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + return gtk_list_box_new(); } void badwolf_downloads_tab_attach(struct Window *window) { - gtk_notebook_insert_page(GTK_NOTEBOOK(window->notebook), window->downloads_tab, NULL, 0); - gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook), window->downloads_tab, TRUE); + GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_set_name(scrolled_window, "browser__scrollwin_downloads"); + gtk_container_add(GTK_CONTAINER(scrolled_window), window->downloads_tab); + gtk_notebook_insert_page(GTK_NOTEBOOK(window->notebook), scrolled_window, NULL, 0); + + gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(window->notebook), scrolled_window, TRUE); GtkWidget *tab_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_widget_set_name(tab_box, "browser__tabbox"); @@ -210,9 +214,9 @@ badwolf_downloads_tab_attach(struct Window *window) gtk_box_pack_start(GTK_BOX(tab_box), label, TRUE, TRUE, 0); gtk_widget_set_tooltip_text(tab_box, _("Badwolf Downloads")); - gtk_notebook_set_tab_label(GTK_NOTEBOOK(window->notebook), window->downloads_tab, tab_box); + gtk_notebook_set_tab_label(GTK_NOTEBOOK(window->notebook), scrolled_window, tab_box); gtk_notebook_set_menu_label_text( - GTK_NOTEBOOK(window->notebook), window->downloads_tab, _("Badwolf Downloads")); + GTK_NOTEBOOK(window->notebook), scrolled_window, _("Badwolf Downloads")); gtk_widget_show_all(tab_box); } diff --git a/keybindings.c b/keybindings.c @@ -14,7 +14,7 @@ about_dialogCb_activate_link(GtkAboutDialog *about_dialog, gchar *uri, gpointer (void)about_dialog; struct Window *window = (struct Window *)user_data; - badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, uri, NULL)); + badwolf_new_tab(GTK_NOTEBOOK(window->notebook), new_browser(window, uri, NULL), FALSE); gtk_widget_destroy(GTK_WIDGET(about_dialog)); @@ -112,7 +112,7 @@ commonCb_key_press_event(struct Window *window, GdkEvent *event, struct Client * { case GDK_KEY_Page_Down: gtk_notebook_next_page(notebook); return TRUE; case GDK_KEY_Page_Up: gtk_notebook_prev_page(notebook); return TRUE; - case GDK_KEY_t: badwolf_new_tab(notebook, new_browser(window, NULL, NULL)); return TRUE; + case GDK_KEY_t: badwolf_new_tab(notebook, new_browser(window, NULL, NULL), TRUE); return TRUE; } } } diff --git a/po/messages.pot b/po/messages.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: Badwolf 0.5.1+gf25fc89.HEAD\n" +"Project-Id-Version: Badwolf 1.0.0+g1d4e9c3.0\n" "Report-Msgid-Bugs-To: contact+badwolf-msgid@hacktivis.me\n" -"POT-Creation-Date: 2020-05-18 04:14+0200\n" +"POT-Creation-Date: 2020-07-08 07:20+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -37,27 +37,27 @@ msgstr "" msgid "%02i:%02i:%02i Downloading…" msgstr "" -#: downloads.c:195 downloads.c:212 downloads.c:215 +#: downloads.c:199 downloads.c:216 downloads.c:219 msgid "Badwolf Downloads" msgstr "" -#: badwolf.c:910 +#: badwolf.c:904 #, c-format msgid "Buildtime WebKit version: %d.%d.%d\n" msgstr "" -#: badwolf.c:403 +#: badwolf.c:402 msgid "Continue" msgstr "" -#: badwolf.c:353 +#: badwolf.c:352 msgid "" "Couldn't verify the TLS certificate to ensure a better security of the " "connection. You might want to verify your machine and network.\n" "\n" msgstr "" -#: badwolf.c:99 +#: badwolf.c:98 msgid "Crashed" msgstr "" @@ -65,31 +65,31 @@ msgstr "" msgid "Download starting…" msgstr "" -#: badwolf.c:376 +#: badwolf.c:375 msgid "Error: Some unknown error occurred validating the certificate.\n" msgstr "" -#: badwolf.c:357 +#: badwolf.c:356 msgid "Error: The X509 Certificate Authority is unknown.\n" msgstr "" -#: badwolf.c:370 +#: badwolf.c:369 msgid "Error: The certificate has been revoked.\n" msgstr "" -#: badwolf.c:367 +#: badwolf.c:366 msgid "Error: The certificate has expired. Check your system's clock.\n" msgstr "" -#: badwolf.c:373 +#: badwolf.c:372 msgid "Error: The certificate is considered to be insecure.\n" msgstr "" -#: badwolf.c:364 +#: badwolf.c:363 msgid "Error: The certificate isn't valid yet. Check your system's clock.\n" msgstr "" -#: badwolf.c:360 +#: badwolf.c:359 msgid "Error: The given identity doesn't match the expected one.\n" msgstr "" @@ -104,75 +104,75 @@ msgstr "" msgid "New tab" msgstr "" -#: badwolf.c:959 +#: badwolf.c:953 msgid "Open new tab" msgstr "" -#: badwolf.c:103 +#: badwolf.c:102 msgid "Out of Memory" msgstr "" -#: badwolf.c:908 +#: badwolf.c:902 #, c-format msgid "Running Badwolf version: %s\n" msgstr "" -#: badwolf.c:915 +#: badwolf.c:909 #, c-format msgid "Runtime WebKit version: %d.%d.%d\n" msgstr "" -#: badwolf.c:400 +#: badwolf.c:399 #, c-format msgid "TLS Error for %s." msgstr "" -#: badwolf.c:403 +#: badwolf.c:402 msgid "Temporarily Add Exception" msgstr "" -#: badwolf.c:610 +#: badwolf.c:609 msgid "Toggle javascript" msgstr "" -#: badwolf.c:615 +#: badwolf.c:614 msgid "Toggle loading images automatically" msgstr "" -#: badwolf.c:107 +#: badwolf.c:106 msgid "Unknown Crash" msgstr "" -#: badwolf.c:613 +#: badwolf.c:612 msgid "_IMG" msgstr "" -#: badwolf.c:608 +#: badwolf.c:607 msgid "_JS" msgstr "" -#: badwolf.c:728 +#: badwolf.c:727 msgid "search in current page" msgstr "" -#: badwolf.c:98 +#: badwolf.c:97 msgid "the web process crashed.\n" msgstr "" -#: badwolf.c:102 +#: badwolf.c:101 msgid "the web process exceeded the memory limit.\n" msgstr "" -#: badwolf.c:106 +#: badwolf.c:105 msgid "the web process terminated for an unknown reason.\n" msgstr "" -#: badwolf.c:922 +#: badwolf.c:916 #, c-format msgid "webkit-web-extension directory set to: %s\n" msgstr "" #. TRANSLATOR Ignore this entry. Done for forcing Unicode in xgettext. -#: badwolf.c:993 +#: badwolf.c:987 msgid "ø" msgstr "" diff --git a/uri.c b/uri.c @@ -4,19 +4,37 @@ #include "uri.h" -#include <glib.h> /* g_strcmp0() */ +#include <glib.h> /* g_strcmp0(), g_uri_parse_scheme(), g_strdup_printf */ +#include <stdlib.h> /* realpath(), free() */ #include <unistd.h> /* access() */ const gchar * badwolf_ensure_uri_scheme(const gchar *text, gboolean try_file) { const gchar *fallback = "about:blank"; + char *path = NULL; if(g_strcmp0(text, "") <= 0) return fallback; if(g_uri_parse_scheme(text)) return text; - if(try_file && (access(text, R_OK) == 0)) return g_strdup_printf("file://%s", text); + if(try_file) + { + path = realpath(text, NULL); + gchar *f = NULL; + + if(path != NULL) + { + if(access(path, R_OK) == 0) + { + f = g_strdup_printf("file://%s", path); + } + + free(path); + + return f; + } + } return g_strdup_printf("http://%s", text); } diff --git a/uri_test.c b/uri_test.c @@ -29,10 +29,13 @@ badwolf_ensure_uri_scheme_test(void) {fallback, "", TRUE}, {"http:///dev/null", "/dev/null", FALSE}, {"file:///dev/null", "/dev/null", TRUE}, + {"http:///usr/../dev/null", "/usr/../dev/null", FALSE}, + {"file:///dev/null", "/usr/../dev/null", TRUE}, {"http://example.org", "example.org", FALSE}, {"http://example.org", "example.org", TRUE}, {"http://", "http://", FALSE}, - {"http://", "http://", TRUE} // + {"http://", "http://", TRUE}, + {"http://badwolf.c", "badwolf.c", FALSE} // }; for(size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)