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