Annotation of libwww/Library/src/HTDialog.c, revision 2.32
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.32 ! frystyk 6: ** @(#) $Id: HTDialog.c,v 2.31 1998/10/13 19:18: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: /* ------------------------------------------------------------------------- */
2.31 frystyk 36: /* Functions for generating messages */
37: /* ------------------------------------------------------------------------- */
2.1 frystyk 38:
2.31 frystyk 39: PUBLIC char * HTDialog_progressMessage (HTRequest * request, HTAlertOpcode op,
40: int msgnum, const char * dfault,
41: void * input)
2.1 frystyk 42: {
2.31 frystyk 43: char * result = NULL;
2.1 frystyk 44: switch (op) {
45: case HT_PROG_DNS:
2.31 frystyk 46: StrAllocMCopy(&result, "Looking up ",
47: input ? (char *) input : "",
48: NULL);
2.1 frystyk 49: break;
50:
51: case HT_PROG_CONNECT:
2.31 frystyk 52: StrAllocMCopy(&result, "Contacting ",
53: input ? (char *) input : "",
54: NULL);
2.1 frystyk 55: break;
56:
57: case HT_PROG_ACCEPT:
2.31 frystyk 58: StrAllocCopy(result, "Waiting for connection...");
2.1 frystyk 59: break;
60:
2.32 ! frystyk 61: case HT_PROG_LOGIN:
! 62: StrAllocCopy(result, "Logging in...");
! 63: break;
! 64:
2.1 frystyk 65: case HT_PROG_READ:
2.24 frystyk 66: if (request) {
2.1 frystyk 67: long cl = HTAnchor_length(HTRequest_anchor(request));
68: if (cl > 0) {
2.26 frystyk 69: long b_read = HTRequest_bodyRead(request);
2.1 frystyk 70: double pro = (double) b_read/cl*100;
71: char buf[10];
2.31 frystyk 72: char pct[10];
2.1 frystyk 73: HTNumToStr((unsigned long) cl, buf, 10);
2.31 frystyk 74: sprintf(pct, "%d%%", (int) pro);
75: StrAllocMCopy(&result, "Read (", pct, "of ", buf, ")", NULL);
76: } else {
77: long b_read = HTRequest_bytesRead(request);
2.32 ! frystyk 78: int * raw_read = input ? (int *) input : NULL;
! 79: if (b_read > 0) {
! 80: char buf[10];
! 81: HTNumToStr(b_read, buf, 10);
! 82: StrAllocMCopy(&result, "Read ", buf, "bytes", NULL);
! 83: } else if (raw_read && *raw_read>0) {
! 84: char buf[10];
! 85: HTNumToStr(*raw_read, buf, 10);
! 86: StrAllocMCopy(&result, "Read ", buf, "bytes", NULL);
! 87: } else {
! 88: StrAllocCopy(result, "Reading...");
! 89: }
! 90: }
2.1 frystyk 91: }
92: break;
93:
94: case HT_PROG_WRITE:
2.24 frystyk 95: if (request && HTMethod_hasEntity(HTRequest_method(request))) {
2.4 frystyk 96: HTParentAnchor *anchor=HTRequest_anchor(HTRequest_source(request));
97: long cl = HTAnchor_length(anchor);
98: if (cl > 0) {
2.29 frystyk 99: long b_write = HTRequest_bodyWritten(request);
2.4 frystyk 100: double pro = (double) b_write/cl*100;
101: char buf[10];
2.31 frystyk 102: char pct[10];
2.4 frystyk 103: HTNumToStr((unsigned long) cl, buf, 10);
2.31 frystyk 104: sprintf(pct, "%d%%", (int) pro);
105: StrAllocMCopy(&result, "Writing (", pct, "of ", buf, ")", NULL);
106: } else {
107: long b_written = HTRequest_bytesWritten(request);
2.32 ! frystyk 108: int * raw_written = input ? (int *) input : NULL;
! 109: if (b_written > 0) {
! 110: char buf[10];
! 111: HTNumToStr(b_written>0 ? b_written : 0, buf, 10);
! 112: StrAllocMCopy(&result, "Writing ", buf, "bytes", NULL);
! 113: } if (raw_written && *raw_written>0) {
! 114: char buf[10];
! 115: HTNumToStr(*raw_written, buf, 10);
! 116: StrAllocMCopy(&result, "Writing ", buf, "bytes", NULL);
! 117: } else {
! 118: StrAllocCopy(result, "Writing...");
! 119: }
2.31 frystyk 120: }
121: }
2.1 frystyk 122: break;
123:
124: case HT_PROG_DONE:
2.31 frystyk 125: StrAllocCopy(result, "Done!");
2.1 frystyk 126: break;
127:
2.28 frystyk 128: case HT_PROG_INTERRUPT:
2.31 frystyk 129: StrAllocCopy(result, "Interrupted!");
2.24 frystyk 130: break;
131:
2.28 frystyk 132: case HT_PROG_OTHER:
2.31 frystyk 133: StrAllocCopy(result, "Working - please wait...");
2.30 frystyk 134: break;
135:
136: case HT_PROG_TIMEOUT:
2.31 frystyk 137: StrAllocCopy(result, "Request timeout - server did not respond.");
2.1 frystyk 138: break;
139:
140: default:
2.31 frystyk 141: StrAllocCopy(result, "UNKNOWN PROGRESS STATE");
2.1 frystyk 142: break;
143: }
2.31 frystyk 144: return result;
145: }
146:
147: PUBLIC char * HTDialog_errorMessage (HTRequest * request, HTAlertOpcode op,
148: int msgnum, const char * dfault,
149: void * input)
150: {
151: HTList * cur = (HTList *) input;
152: HTError * pres;
153: HTErrorShow showmask = HTError_show();
154: HTChunk * msg = NULL;
155: int code;
156: if (!request || !cur) return NULL;
157: while ((pres = (HTError *) HTList_nextObject(cur))) {
158: int index = HTError_index(pres);
159: if (HTError_doShow(pres)) {
160: if (!msg) {
161: HTSeverity severity = HTError_severity(pres);
162: msg = HTChunk_new(128);
163: if (severity == ERR_WARN)
164: HTChunk_puts(msg, "Warning: ");
165: else if (severity == ERR_NON_FATAL)
166: HTChunk_puts(msg, "Non Fatal Error: ");
167: else if (severity == ERR_FATAL)
168: HTChunk_puts(msg, "Fatal Error: ");
169: else if (severity == ERR_INFO)
170: HTChunk_puts(msg, "Information: ");
171: else {
172: HTChunk_puts(msg, "UNKNOWN ERROR TYPE");
173: return HTChunk_toCString(msg);
174: }
175:
176: /* Error number */
177: if ((code = HTErrors[index].code) > 0) {
178: char buf[10];
179: sprintf(buf, "%d ", code);
180: HTChunk_puts(msg, buf);
181: }
182: } else
183: HTChunk_puts(msg, "\nReason: ");
184:
185: if (index == HTERR_SYSTEM) {
186: int length = 0;
187: char * pars = (char *) HTError_parameter(pres, &length);
188: HTChunk_puts(msg, HTError_location(pres));
189: HTChunk_puts(msg, " ");
190: HTChunk_puts(msg, HTErrors[index].msg);
191: if (length && pars) {
192: HTChunk_puts(msg, " (");
193: HTChunk_puts(msg, pars);
194: HTChunk_puts(msg, ")");
195: }
196:
197: } else {
198:
199: /* Error message */
200: HTChunk_puts(msg, HTErrors[index].msg);
201:
202: /* Error parameters */
203: if (showmask & HT_ERR_SHOW_PARS) {
204: int length;
205: int cnt;
206: char *pars = (char *) HTError_parameter(pres, &length);
207: if (length && pars) {
208: HTChunk_puts(msg, " (");
209: for (cnt=0; cnt<length; cnt++) {
210: char ch = *(pars+cnt);
211: if (ch < 0x20 || ch >= 0x7F)
212: HTChunk_putc(msg, '#');
213: else
214: HTChunk_putc(msg, ch);
215: }
216: HTChunk_puts(msg, ") ");
217: }
218: }
219:
220: /* Error Location */
221: if (showmask & HT_ERR_SHOW_LOCATION) {
222: HTChunk_puts(msg, "This occured in ");
223: HTChunk_puts(msg, HTError_location(pres));
224: HTChunk_putc(msg, '\n');
225: }
226: }
227:
228: /*
229: ** Make sure that we don't get this error more than once even
230: ** if we are keeping the error stack from one request to another
231: */
232: HTError_setIgnore(pres);
233:
234: /* If we only are show the most recent entry then break here */
235: if (showmask & HT_ERR_SHOW_FIRST)
236: break;
237: }
238: }
239: return HTChunk_toCString(msg);
240: }
241:
242: /* ------------------------------------------------------------------------- */
243:
244: /*
245: ** Functions for providing user interactions registered in the
246: ** HTAlert module. These functions are the default set of user
247: ** inteactions that are provided by libwww. You are likely to want to generate your own versions
248: ** that can be registered instead.
249: */
250: PUBLIC BOOL HTProgress (HTRequest * request, HTAlertOpcode op,
251: int msgnum, const char * dfault, void * input,
252: HTAlertPar * reply)
253: {
254: char * msg = HTDialog_progressMessage(request, op, msgnum, dfault, input);
255: if (msg) {
256: HTTrace("%s\n", msg);
257: HT_FREE(msg);
258: }
2.1 frystyk 259: return YES;
260: }
261:
262: PUBLIC BOOL HTConfirm (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 263: int msgnum, const char * dfault, void * input,
2.1 frystyk 264: HTAlertPar * reply)
265: {
266: char response[4]; /* One more for terminating NULL -- AL */
2.8 eric 267: HTTrace("%s", HTDialogs[msgnum]);
268: if (input) HTTrace(" (%s)", (char *) input);
269: HTTrace(" (y/n) ");
2.1 frystyk 270: #ifndef NO_STDIO
2.2 frystyk 271: if (fgets(response, 4, stdin)) /* get reply, max 3 chars */
2.1 frystyk 272: #endif
2.2 frystyk 273: {
2.1 frystyk 274: char *ptr = response;
275: while (*ptr) {
276: if (*ptr == '\n') {
277: *ptr = '\0';
278: break;
279: }
280: *ptr = TOUPPER(*ptr);
281: ptr++;
282: }
283: return (!strcmp(response, "YES") || !strcmp(response, "Y")) ? YES : NO;
284: }
285: return NO;
286: }
287:
288: /* Prompt for answer and get text back. Reply text is either NULL on
2.10 frystyk 289: ** error or a dynamic string which the caller must HT_FREE.
2.1 frystyk 290: */
291: PUBLIC BOOL HTPrompt (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 292: int msgnum, const char * dfault, void * input,
2.1 frystyk 293: HTAlertPar * reply)
294: {
2.8 eric 295: HTTrace("%s ", HTDialogs[msgnum]);
296: if (input) HTTrace(" (%s) ", (char *) input);
297: if (dfault) HTTrace("(RETURN for [%s]) ", (char *) dfault);
2.1 frystyk 298: if (reply && msgnum>=0) {
299: #ifndef NO_STDIO
2.5 frystyk 300: char buffer[200];
2.1 frystyk 301: if (!fgets(buffer, 200, stdin)) return NO;
302: buffer[strlen(buffer)-1] = '\0'; /* Overwrite newline */
303: if (*buffer)
304: HTAlert_setReplyMessage(reply, buffer);
305: else if (dfault)
306: HTAlert_setReplyMessage(reply, (char *) dfault);
307: else
308: return NO;
309: return YES;
310: #endif
311: }
312: return NO;
313: }
314:
315: /* Prompt for password without echoing the reply. Reply text is
2.10 frystyk 316: ** either NULL on error or a dynamic string which the caller must HT_FREE.
2.1 frystyk 317: */
318: PUBLIC BOOL HTPromptPassword (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 319: int msgnum, const char * dfault, void * input,
2.1 frystyk 320: HTAlertPar * reply)
321: {
322: if (reply && msgnum>=0) {
2.10 frystyk 323: #ifdef HAVE_GETPASS
2.1 frystyk 324: char * pw = (char *) getpass(HTDialogs[msgnum]);
2.2 frystyk 325: if (pw) HTAlert_setReplySecret(reply, pw);
2.1 frystyk 326: return YES;
2.10 frystyk 327: #else
2.27 frystyk 328: /*
329: ** This is just to be able to get it wo work when getpass()
330: ** isn't available.
331: */
332: char buffer[100];
333: memset(buffer, '\0', 100);
334: HTTrace("%s ", HTDialogs[msgnum]);
335: if (!fgets(buffer, 99, stdin)) return NO;
336: buffer[strlen(buffer)-1] = '\0'; /* Overwrite newline */
337: if (*buffer) {
338: HTAlert_setReplySecret(reply, buffer);
339: return YES;
340: }
341: return NO;
2.10 frystyk 342: #endif /* HAVE_GETPASS */
2.1 frystyk 343: }
344: return NO;
345: }
346:
347: /* Username and password
348: ** ---------------------
349: ** Prompt Username and password as an atomic operation
350: */
351: PUBLIC BOOL HTPromptUsernameAndPassword (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 352: int msgnum, const char * dfault,
2.1 frystyk 353: void * input, HTAlertPar * reply)
354: {
2.21 frystyk 355: BOOL status = HTPrompt(request, op, msgnum, dfault, input, reply);
2.1 frystyk 356: return status ?
357: HTPromptPassword(request, op, HT_MSG_PW, dfault, input, reply) : NO;
358: }
359:
360: /* HTError_print
361: ** -------------
362: ** Default function that creates an error message using HTAlert() to
363: ** put out the contents of the error_stack messages. Furthermore, the
364: ** error_info structure contains a name of a help file that might be put
365: ** up as a link. This file can then be multi-linguistic.
366: */
367: PUBLIC BOOL HTError_print (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 368: int msgnum, const char * dfault, void * input,
2.1 frystyk 369: HTAlertPar * reply)
370: {
2.31 frystyk 371: char * msg = HTDialog_errorMessage(request, op, msgnum, dfault, input);
2.1 frystyk 372: if (msg) {
2.31 frystyk 373: HTTrace("%s\n", msg);
374: HT_FREE(msg);
2.1 frystyk 375: }
376: return YES;
377: }
378:
2.31 frystyk 379: /* NOT USED - HTError_response - NOT USED!!!
380: ** -----------------------------------------
2.6 frystyk 381: ** Default function that creates an error message using HTAlert() to
382: ** put out the contents of the error_stack messages. Furthermore, the
383: ** error_info structure contains a name of a help file that might be put
384: ** up as a link. This file can then be multi-linguistic.
385: */
386: PUBLIC BOOL HTError_response (HTRequest * request, HTAlertOpcode op,
2.10 frystyk 387: int msgnum, const char * dfault, void * input,
2.6 frystyk 388: HTAlertPar * reply)
389: {
2.31 frystyk 390: return NO;
2.6 frystyk 391: }
Webmaster