fixed GTKHTML detection
[k8lowj.git] / src / network.c
blobca2d892ce42a30bdd40b842fb3a7cf79d0428d20
1 /* logjam - a GTK client for LiveJournal.
2 * Copyright (C) 2000-2004 Evan Martin <martine@danga.com>
4 * vim: tabstop=4 shiftwidth=4 noexpandtab :
5 */
7 #include "glib-all.h"
8 #include <stdlib.h>
10 #include "liblj/livejournal.h"
11 #include "liblj/getchallenge.h"
13 #include "conf.h"
14 #include "network.h"
15 #include "network-internal.h"
17 GQuark
18 net_error_quark(void) {
19 static GQuark quark = 0;
20 if (quark == 0)
21 quark = g_quark_from_static_string("logjam-net-error-quark");
22 return quark;
25 static GString*
26 real_run_request(const char *url, GString *post,
27 NetStatusCallback cb, gpointer data,
28 GError **err) {
29 /* XXX forking disabled on win32 until they fix a GTK bug--
30 * see network-win32.c for details. */
31 #if defined(HAVE_GTK) && !defined(G_OS_WIN32)
32 if (conf.options.nofork || app.cli) {
33 return net_post_blocking(url, NULL, post, cb, data, err);
34 } else {
35 return net_post_mainloop(url, NULL, post, cb, data, err);
37 #else
38 return net_post_blocking(url, NULL, post, cb, data, err);
39 #endif
42 gboolean
43 net_verb_run_directly(LJVerb *verb,
44 NetStatusCallback cb, gpointer data,
45 GError **err) {
46 GString *post, *res;
47 const char *urlbase;
48 char *url;
49 gboolean ret;
51 urlbase = lj_request_get_user(verb->request)->server->url;
52 url = g_strdup_printf("%s/interface/flat", urlbase);
54 post = lj_request_to_string(verb->request);
55 res = real_run_request(url, post, cb, data, err);
56 g_string_free(post, TRUE);
57 g_free(url);
59 if (res == NULL)
60 return FALSE;
62 ret = lj_verb_handle_response(verb, res->str, err);
63 g_string_free(res, TRUE);
65 return ret;
68 gboolean
69 net_verb_run_internal(LJVerb *verb,
70 NetStatusCallback cb, gpointer data,
71 GError **err) {
72 LJUser *user = lj_request_get_user(verb->request);
73 LJServer *server = user->server;
75 if (server->authscheme == LJ_AUTH_SCHEME_UNKNOWN ||
76 server->authscheme == LJ_AUTH_SCHEME_C0) {
77 LJGetChallenge *getchal = lj_getchallenge_new(user);
78 GError *chalerr = NULL;
79 if (!net_verb_run_directly((LJVerb*)getchal, cb, data, &chalerr)) {
80 /* failed. no auth scheme available? */
81 server->authscheme = LJ_AUTH_SCHEME_NONE;
82 } else {
83 server->authscheme = getchal->authscheme;
84 if (server->authscheme == LJ_AUTH_SCHEME_C0)
85 lj_verb_use_challenge(verb, getchal->challenge);
87 lj_getchallenge_free(getchal);
89 if (chalerr) {
90 /* if there was a total failure when we tried to send the
91 * challenge, stop here. we don't even need to attempt
92 * the subsequent request. */
93 if (g_error_matches(chalerr, NET_ERROR, NET_ERROR_CANCELLED) ||
94 g_error_matches(chalerr, NET_ERROR, NET_ERROR_GENERIC)) {
95 g_propagate_error(err, chalerr);
96 return FALSE;
98 g_error_free(chalerr);
102 return net_verb_run_directly(verb, cb, data, err);
109 void
110 ctx_cmdline_print_string(NetContext *ctx, const char *text) {
111 if (!app.quiet)
112 g_print("%s\n", text);
115 static void
116 cmdline_statuscb(NetStatusType status, gpointer statusdata, gpointer data) {
117 /* what do we do? */
120 static GString*
121 ctx_cmdline_http(NetContext *ctx, const char *url, GSList *headers,
122 GString *post, GError **err) {
123 return net_post_blocking(url, NULL, post, cmdline_statuscb, ctx, err);
126 void
127 ctx_cmdline_error(NetContext *ctx, GError *err) {
128 g_printerr(_("Error: %s\n"), err->message);
131 /* f() means *any* argument list, not just void */
132 void
133 ctx_silent_noop() {
136 static NetContext network_ctx_silent_real = {
137 .title = NULL,
138 .progress_str = ctx_silent_noop,
139 .progress_int = NULL,
140 .error = ctx_silent_noop,
141 .http = ctx_cmdline_http,
143 NetContext *network_ctx_silent = &network_ctx_silent_real;
145 static NetContext network_ctx_cmdline_real = {
146 .title = NULL,
147 .progress_str = ctx_cmdline_print_string,
148 .progress_int = NULL,
149 .error = ctx_cmdline_error,
150 .http = ctx_cmdline_http,
152 NetContext *network_ctx_cmdline = &network_ctx_cmdline_real;
154 gboolean
155 run_verb(LJVerb *verb, NetContext *ctx, GError **err) {
156 GString *post, *res;
157 const char *urlbase;
158 char *url;
159 gboolean ret;
161 urlbase = lj_request_get_user(verb->request)->server->url;
162 url = g_strdup_printf("%s/interface/flat", urlbase);
164 post = lj_request_to_string(verb->request);
165 res = ctx->http(ctx, url, NULL, post, err);
166 g_string_free(post, TRUE);
167 g_free(url);
169 if (res == NULL)
170 return FALSE;
172 ret = lj_verb_handle_response(verb, res->str, err);
173 g_string_free(res, TRUE);
175 return ret;
179 gboolean
180 net_run_verb_ctx(LJVerb *verb, NetContext *ctx, GError **reterr) {
181 LJUser *user = lj_request_get_user(verb->request);
182 LJServer *server = user->server;
183 GError *err = FALSE;
184 gboolean success = FALSE;
186 if (server->authscheme == LJ_AUTH_SCHEME_UNKNOWN ||
187 server->authscheme == LJ_AUTH_SCHEME_C0) {
188 LJGetChallenge *getchal = lj_getchallenge_new(user);
190 ctx->progress_str(ctx, _("Requesting challenge..."));
191 if (!run_verb((LJVerb*)getchal, ctx, &err)) {
192 /* failed. no auth scheme available? */
193 server->authscheme = LJ_AUTH_SCHEME_NONE;
194 } else {
195 server->authscheme = getchal->authscheme;
196 if (server->authscheme == LJ_AUTH_SCHEME_C0)
197 lj_verb_use_challenge(verb, getchal->challenge);
199 lj_getchallenge_free(getchal);
201 if (err) {
202 /* if there was a total failure when we tried to send the
203 * challenge, stop here. we don't even need to attempt
204 * the subsequent request. */
205 if (g_error_matches(err, NET_ERROR, NET_ERROR_CANCELLED) ||
206 g_error_matches(err, NET_ERROR, NET_ERROR_GENERIC)) {
207 goto out;
209 g_error_free(err);
210 err = NULL;
214 ctx->progress_str(ctx, _("Running request..."));
215 success = run_verb(verb, ctx, &err);
216 out:
217 if (!success) {
218 if (ctx->error)
219 ctx->error(ctx, err);
220 g_propagate_error(reterr, err);
222 return success;