Annotation of libwww/Library/src/HTDialog.c, revision 2.30
2.1 frystyk 1: /* HTDialog.c
2: ** MESSAGES AND DIALOGS
3: **
4: ** (c) COPYRIGHT MIT 1995.
5: ** Please first read the full copyright statement in the file COPYRIGH.
2.30 ! frystyk 6: ** @(#) $Id: HTDialog.c,v 2.29 1998/07/22 19:17:30 frystyk Exp $
2.1 frystyk 7: **
8: ** This module provides a default implementation of the application part
9: ** of the Message and Dialog part or the Library. You do not have to do
10: ** it like this - you can use exactly the model for mapping codes into
11: ** messages as you like
12: **
13: ** Authors
14: ** HFN Henrik Frystyk
15: */
16:
17: /* Library include files */
18: #include "WWWLib.h"
19: #include "WWWApp.h"
2.6 frystyk 20: #include "WWWHTTP.h"
2.1 frystyk 21: #include "HTDialog.h" /* Implemented here */
22:
23: /*
24: ** Dialog Messages
25: */
2.25 eric 26: PRIVATE const char * HTDialogs[HT_MSG_ELEMENTS] = {HT_MSG_ENGLISH_INITIALIZER};
2.1 frystyk 27:
28: /*
29: ** All errors that are not strictly HTTP errors but originates from, e.g.,
30: ** the FTP protocol all have element numbers > HTERR_HTTP_CODES_END, i.e.,
31: ** they should be placed after the blank line
32: */
2.25 eric 33: PRIVATE HTErrorMessage HTErrors[HTERR_ELEMENTS] = {HTERR_ENGLISH_INITIALIZER};
2.1 frystyk 34:
35: /* ------------------------------------------------------------------------- */
36:
37: PUBLIC BOOL HTProgress (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 38: int msgnum, const char * dfault, void * input,
2.1 frystyk 39: HTAlertPar * reply)
40: {
2.24 frystyk 41: if (request && HTRequest_internal(request)) return NO;
2.1 frystyk 42: switch (op) {
43: case HT_PROG_DNS:
2.9 frystyk 44: HTTrace("Looking up %s\n", input ? (char *) input : "");
2.1 frystyk 45: break;
46:
47: case HT_PROG_CONNECT:
2.9 frystyk 48: HTTrace("Contacting %s\n", input ? (char *) input : "");
2.1 frystyk 49: break;
50:
51: case HT_PROG_ACCEPT:
2.8 eric 52: HTTrace("Waiting for connection...\n");
2.1 frystyk 53: break;
54:
55: case HT_PROG_READ:
2.24 frystyk 56: if (request) {
2.1 frystyk 57: long cl = HTAnchor_length(HTRequest_anchor(request));
58: if (cl > 0) {
2.26 frystyk 59: long b_read = HTRequest_bodyRead(request);
2.1 frystyk 60: double pro = (double) b_read/cl*100;
61: char buf[10];
62: HTNumToStr((unsigned long) cl, buf, 10);
2.8 eric 63: HTTrace("Read (%d%% of %s)\n", (int) pro, buf);
2.1 frystyk 64: } else
2.8 eric 65: HTTrace("Reading...\n");
2.1 frystyk 66: }
67: break;
68:
69: case HT_PROG_WRITE:
2.24 frystyk 70: if (request && HTMethod_hasEntity(HTRequest_method(request))) {
2.4 frystyk 71: HTParentAnchor *anchor=HTRequest_anchor(HTRequest_source(request));
72: long cl = HTAnchor_length(anchor);
73: if (cl > 0) {
2.29 frystyk 74: long b_write = HTRequest_bodyWritten(request);
2.4 frystyk 75: double pro = (double) b_write/cl*100;
76: char buf[10];
77: HTNumToStr((unsigned long) cl, buf, 10);
2.8 eric 78: HTTrace("Written (%d%% of %s)\n", (int) pro, buf);
2.4 frystyk 79: } else
2.8 eric 80: HTTrace("Writing...\n");
2.4 frystyk 81: }
2.1 frystyk 82: break;
83:
84: case HT_PROG_DONE:
2.29 frystyk 85: HTTrace("Done!\n");
2.1 frystyk 86: break;
87:
2.28 frystyk 88: case HT_PROG_INTERRUPT:
89: HTTrace("Interrupted!\n");
2.24 frystyk 90: break;
91:
2.28 frystyk 92: case HT_PROG_OTHER:
93: HTTrace("Working - please wait...\n");
2.30 ! frystyk 94: break;
! 95:
! 96: case HT_PROG_TIMEOUT:
! 97: HTTrace("Request timeout - server did not respond.\n");
2.1 frystyk 98: break;
99:
100: default:
2.8 eric 101: HTTrace("UNKNOWN PROGRESS STATE\n");
2.1 frystyk 102: break;
103: }
104: return YES;
105: }
106:
107: PUBLIC BOOL HTConfirm (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 108: int msgnum, const char * dfault, void * input,
2.1 frystyk 109: HTAlertPar * reply)
110: {
111: char response[4]; /* One more for terminating NULL -- AL */
2.8 eric 112: HTTrace("%s", HTDialogs[msgnum]);
113: if (input) HTTrace(" (%s)", (char *) input);
114: HTTrace(" (y/n) ");
2.1 frystyk 115: #ifndef NO_STDIO
2.2 frystyk 116: if (fgets(response, 4, stdin)) /* get reply, max 3 chars */
2.1 frystyk 117: #endif
2.2 frystyk 118: {
2.1 frystyk 119: char *ptr = response;
120: while (*ptr) {
121: if (*ptr == '\n') {
122: *ptr = '\0';
123: break;
124: }
125: *ptr = TOUPPER(*ptr);
126: ptr++;
127: }
128: return (!strcmp(response, "YES") || !strcmp(response, "Y")) ? YES : NO;
129: }
130: return NO;
131: }
132:
133: /* Prompt for answer and get text back. Reply text is either NULL on
2.10 frystyk 134: ** error or a dynamic string which the caller must HT_FREE.
2.1 frystyk 135: */
136: PUBLIC BOOL HTPrompt (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 137: int msgnum, const char * dfault, void * input,
2.1 frystyk 138: HTAlertPar * reply)
139: {
2.8 eric 140: HTTrace("%s ", HTDialogs[msgnum]);
141: if (input) HTTrace(" (%s) ", (char *) input);
142: if (dfault) HTTrace("(RETURN for [%s]) ", (char *) dfault);
2.1 frystyk 143: if (reply && msgnum>=0) {
144: #ifndef NO_STDIO
2.5 frystyk 145: char buffer[200];
2.1 frystyk 146: if (!fgets(buffer, 200, stdin)) return NO;
147: buffer[strlen(buffer)-1] = '\0'; /* Overwrite newline */
148: if (*buffer)
149: HTAlert_setReplyMessage(reply, buffer);
150: else if (dfault)
151: HTAlert_setReplyMessage(reply, (char *) dfault);
152: else
153: return NO;
154: return YES;
155: #endif
156: }
157: return NO;
158: }
159:
160: /* Prompt for password without echoing the reply. Reply text is
2.10 frystyk 161: ** either NULL on error or a dynamic string which the caller must HT_FREE.
2.1 frystyk 162: */
163: PUBLIC BOOL HTPromptPassword (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 164: int msgnum, const char * dfault, void * input,
2.1 frystyk 165: HTAlertPar * reply)
166: {
167: if (reply && msgnum>=0) {
2.10 frystyk 168: #ifdef HAVE_GETPASS
2.1 frystyk 169: char * pw = (char *) getpass(HTDialogs[msgnum]);
2.2 frystyk 170: if (pw) HTAlert_setReplySecret(reply, pw);
2.1 frystyk 171: return YES;
2.10 frystyk 172: #else
2.27 frystyk 173: /*
174: ** This is just to be able to get it wo work when getpass()
175: ** isn't available.
176: */
177: char buffer[100];
178: memset(buffer, '\0', 100);
179: HTTrace("%s ", HTDialogs[msgnum]);
180: if (!fgets(buffer, 99, stdin)) return NO;
181: buffer[strlen(buffer)-1] = '\0'; /* Overwrite newline */
182: if (*buffer) {
183: HTAlert_setReplySecret(reply, buffer);
184: return YES;
185: }
186: return NO;
2.10 frystyk 187: #endif /* HAVE_GETPASS */
2.1 frystyk 188: }
189: return NO;
190: }
191:
192: /* Username and password
193: ** ---------------------
194: ** Prompt Username and password as an atomic operation
195: */
196: PUBLIC BOOL HTPromptUsernameAndPassword (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 197: int msgnum, const char * dfault,
2.1 frystyk 198: void * input, HTAlertPar * reply)
199: {
2.21 frystyk 200: BOOL status = HTPrompt(request, op, msgnum, dfault, input, reply);
2.1 frystyk 201: return status ?
202: HTPromptPassword(request, op, HT_MSG_PW, dfault, input, reply) : NO;
203: }
204:
205: /* HTError_print
206: ** -------------
207: ** Default function that creates an error message using HTAlert() to
208: ** put out the contents of the error_stack messages. Furthermore, the
209: ** error_info structure contains a name of a help file that might be put
210: ** up as a link. This file can then be multi-linguistic.
211: */
212: PUBLIC BOOL HTError_print (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 213: int msgnum, const char * dfault, void * input,
2.1 frystyk 214: HTAlertPar * reply)
215: {
216: HTList *cur = (HTList *) input;
217: HTError *pres;
218: HTErrorShow showmask = HTError_show();
219: HTChunk *msg = NULL;
220: int code;
2.8 eric 221: if (WWWTRACE) HTTrace("HTError..... Generating message\n");
2.1 frystyk 222: if (!request || !cur) return NO;
223: while ((pres = (HTError *) HTList_nextObject(cur))) {
224: int index = HTError_index(pres);
225: if (HTError_doShow(pres)) {
226: if (!msg) {
227: HTSeverity severity = HTError_severity(pres);
2.3 frystyk 228: msg = HTChunk_new(128);
2.1 frystyk 229: if (severity == ERR_WARN)
2.3 frystyk 230: HTChunk_puts(msg, "Warning: ");
2.1 frystyk 231: else if (severity == ERR_NON_FATAL)
2.3 frystyk 232: HTChunk_puts(msg, "Non Fatal Error: ");
2.1 frystyk 233: else if (severity == ERR_FATAL)
2.3 frystyk 234: HTChunk_puts(msg, "Fatal Error: ");
2.1 frystyk 235: else if (severity == ERR_INFO)
2.3 frystyk 236: HTChunk_puts(msg, "Information: ");
2.1 frystyk 237: else {
238: if (WWWTRACE)
2.8 eric 239: HTTrace("HTError..... Unknown Classification of Error (%d)...\n", severity);
2.3 frystyk 240: HTChunk_delete(msg);
2.1 frystyk 241: return NO;
242: }
243:
244: /* Error number */
245: if ((code = HTErrors[index].code) > 0) {
246: char buf[10];
247: sprintf(buf, "%d ", code);
2.3 frystyk 248: HTChunk_puts(msg, buf);
2.1 frystyk 249: }
250: } else
2.3 frystyk 251: HTChunk_puts(msg, "\nReason: ");
252: HTChunk_puts(msg, HTErrors[index].msg); /* Error message */
2.1 frystyk 253:
254: if (showmask & HT_ERR_SHOW_PARS) { /* Error parameters */
255: int length;
256: int cnt;
257: char *pars = (char *) HTError_parameter(pres, &length);
258: if (length && pars) {
2.3 frystyk 259: HTChunk_puts(msg, " (");
2.1 frystyk 260: for (cnt=0; cnt<length; cnt++) {
261: char ch = *(pars+cnt);
262: if (ch < 0x20 || ch >= 0x7F)
2.3 frystyk 263: HTChunk_putc(msg, '#');
2.1 frystyk 264: else
2.3 frystyk 265: HTChunk_putc(msg, ch);
2.1 frystyk 266: }
2.3 frystyk 267: HTChunk_puts(msg, ") ");
2.1 frystyk 268: }
269: }
270:
271: if (showmask & HT_ERR_SHOW_LOCATION) { /* Error Location */
2.3 frystyk 272: HTChunk_puts(msg, "This occured in ");
273: HTChunk_puts(msg, HTError_location(pres));
274: HTChunk_putc(msg, '\n');
2.1 frystyk 275: }
276:
277: /*
278: ** Make sure that we don't get this error more than once even
279: ** if we are keeping the error stack from one request to another
280: */
281: HTError_setIgnore(pres);
282:
283: /* If we only are show the most recent entry then break here */
284: if (showmask & HT_ERR_SHOW_FIRST)
285: break;
286: }
287: }
288: if (msg) {
2.3 frystyk 289: HTChunk_putc(msg, '\n');
2.8 eric 290: HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.3 frystyk 291: HTChunk_delete(msg);
2.1 frystyk 292: }
293: return YES;
294: }
295:
2.6 frystyk 296: /* HTError_response
297: ** ----------------
298: ** Default function that creates an error message using HTAlert() to
299: ** put out the contents of the error_stack messages. Furthermore, the
300: ** error_info structure contains a name of a help file that might be put
301: ** up as a link. This file can then be multi-linguistic.
302: */
303: PUBLIC BOOL HTError_response (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 304: int msgnum, const char * dfault, void * input,
2.6 frystyk 305: HTAlertPar * reply)
306: {
307: HTList * cur = (HTList *) input;
308: HTError * pres;
309: HTErrorShow showmask = HTError_show();
310: HTChunk * msg = NULL;
311: int code;
2.8 eric 312: if (WWWTRACE) HTTrace("HTError..... Generating HTTP response\n");
2.6 frystyk 313: if (!request || !cur || !reply) return NO;
314: while ((pres = (HTError *) HTList_nextObject(cur))) {
315: int index = HTError_index(pres);
316: if (HTError_doShow(pres)) {
317: if (!msg) {
318: msg = HTChunk_new(128);
319: if ((code = HTErrors[index].code) > 0) {
320: char * reason = HTErrors[index].msg;
2.7 frystyk 321: char * buf;
322: if ((buf = (char *) HT_MALLOC(20 + strlen(reason))) == NULL)
323: HT_OUTOFMEM("HTError_response");
2.6 frystyk 324: sprintf(buf,"%s %d %s%c%c",HTTP_VERSION,code,reason,CR,LF);
325: HTAlert_assignReplyMessage(reply, buf);
326: }
327: } else {
328: HTChunk_puts(msg, "\nReason: ");
329: HTChunk_puts(msg, HTErrors[index].msg); /* Error message */
330: }
331:
332: if (showmask & HT_ERR_SHOW_PARS) { /* Error parameters */
333: int length;
334: int cnt;
335: char *pars = (char *) HTError_parameter(pres, &length);
336: if (length && pars) {
337: HTChunk_puts(msg, " (");
338: for (cnt=0; cnt<length; cnt++) {
339: char ch = *(pars+cnt);
340: if (ch < 0x20 || ch >= 0x7F)
341: HTChunk_putc(msg, '#');
342: else
343: HTChunk_putc(msg, ch);
344: }
345: HTChunk_puts(msg, ") ");
346: }
347: }
348:
349: if (showmask & HT_ERR_SHOW_LOCATION) { /* Error Location */
350: HTChunk_puts(msg, "This occured in ");
351: HTChunk_puts(msg, HTError_location(pres));
352: HTChunk_putc(msg, '\n');
353: }
354:
355: /*
356: ** Make sure that we don't get this error more than once even
357: ** if we are keeping the error stack from one request to another
358: */
359: HTError_setIgnore(pres);
360:
361: /* If we only are show the most recent entry then break here */
362: if (showmask & HT_ERR_SHOW_FIRST)
363: break;
364: }
365: }
366: if (msg) {
367: HTChunk_putc(msg, '\n');
368: #if 0
2.8 eric 369: HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.6 frystyk 370: #endif
371: HTChunk_delete(msg);
372: }
373: return YES;
374: }
Webmaster