Annotation of libwww/Library/src/HTDialog.c, revision 2.8

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.
                      6: **
                      7: **     This module provides a default implementation of the application part
                      8: **     of the Message and Dialog part or the Library. You do not have to do
                      9: **     it like this - you can use exactly the model for mapping codes into
                     10: **     messages as you like
                     11: **
                     12: ** Authors
                     13: **     HFN     Henrik Frystyk
                     14: */
                     15: 
                     16: /* Library include files */
                     17: #include "WWWLib.h"
                     18: #include "WWWApp.h"
2.6       frystyk    19: #include "WWWHTTP.h"
2.1       frystyk    20: #include "HTReqMan.h"
                     21: #include "HTDialog.h"                                   /* Implemented here */
                     22: 
                     23: /*
                     24: ** Dialog Messages
                     25: */
                     26: PRIVATE char *HTDialogs[HT_MSG_ELEMENTS] = {
                     27:     "Please enter username:",
                     28:     "Password:",
                     29:     "Please give name of file to save in:",
                     30:     "Plase enter account:",
                     31:     "It might not be allowed to use this method, continue?",
                     32:     "Location has moved, continue?",
                     33:     "A new set of rules is to be added to your setup - continue?"
                     34: };
                     35: 
                     36: /*
                     37: ** All errors that are not strictly HTTP errors but originates from, e.g., 
                     38: ** the FTP protocol all have element numbers > HTERR_HTTP_CODES_END, i.e.,
                     39: ** they should be placed after the blank line
                     40: */
                     41: typedef struct _HTErrorMessage {
                     42:     int        code;                   /* Error number */
                     43:     char *     msg;                    /* Short explanation */
                     44:     char *     url;                    /* Explaning URL */
                     45: } HTErrorMessage;
                     46: 
                     47: PRIVATE HTErrorMessage HTErrors[HTERR_ELEMENTS] = {
                     48: 
                     49: /*    CODE  ERROR MESSAGE                              ERROR URL */
                     50: 
                     51:     { 200, "OK",                                       "ok" },
                     52:     { 201, "Created",                                  "created" },
                     53:     { 202, "Accepted",                                         "accepted" },
                     54:     { 203, "Provisional Information",                  "partial" },
                     55:     { 204, "No Content",                               "no_response" },
                     56:     { 301, "Moved Permanently",                                "moved" },
                     57:     { 302, "Moved Temporarily",                        "moved" },
                     58:     { 303, "Method",                                   "method" },
                     59:     { 304, "Not Modified",                             "not_modified" },
                     60:     { 400, "Bad Request",                              "bad_request" },
                     61:     { 401, "Unauthorized",                             "unauthorized" },
                     62:     { 402, "Payment Required",                                 "payment" },
                     63:     { 403, "Forbidden",                                "forbidden" },
                     64:     { 404, "Not Found",                                        "not_found" },
                     65:     { 405, "Method Not Allowed",                       "method" },
                     66:     { 406, "None Acceptable",                          "none" },
                     67:     { 407, "Proxy Authentication Required",            "proxy" },
                     68:     { 408, "Request Timeout",                          "timeout" },
                     69:     { 500, "Internal Server Error",                    "internal" },
                     70:     { 501, "Not Implemented",                          "not_made" },
                     71:     { 502, "Bad Gateway",                              "bad_gate" },
                     72:     { 503, "Service Unavailable",                      "unavailable" },
                     73:     { 504, "Gateway Timeout",                          "timeout" },
                     74:     { 0,   "-------------------------", "----------------------------------" },
                     75:     { 0,   "Can't locate remote host",                         "host" },
                     76:     { 0,   "No host name found",                       "host" },
                     77:     { 0,   "No file name found or file not accessible", "file" },
                     78:     { 0,   "FTP-server replies",                       "ftp" },
                     79:     { 0,   "FTP-server doesn't reply",                         "no_server" },
                     80:     { 0,   "Server timed out",                                 "time_out" },
                     81:     { 0,   "Gopher-server replies",                    "gopher" },
                     82:     { 0,   "Data transfer interrupted",                "interrupt" },
                     83:     { 0,   "Connection establishment interrupted",     "interrupt" },
                     84:     { 0,   "CSO-server replies",                       "cso" },
                     85:     { 0,   "This is probably a HTTP server 0.9 or less","http_version" },
                     86:     { 0,   "Bad, Incomplete, or Unknown Response",     "bad_reply" },
                     87:     { 0,   "Unknown access authentication scheme",     "control" },
                     88:     { 0,   "News-server replies",                      "news" },
                     89:     { 0,   "Trying `ftp://' instead of `file://'",     "ftpfile" },
                     90:     { 0,   "Too many redirections",                    "redirections" },
                     91:     { 0,   "Premature End Of File",                    "EOF" },
                     92:     { 0,   "Response from WAIS Server too Large - Extra lines ignored",
                     93:                                                        "wais" },
                     94:     { 0,   "WAIS-server doesn't return any data",      "wais" },
                     95:     { 0,   "Can't connect to WAIS-server",             "wais" },
                     96:     { 0,   "System replies",                           "system" },
                     97:     { 0,   "Wrong or unknown access scheme",           "class" },
                     98:     { 0,   "Access scheme not allowed in this context",        "class" },
                     99:     { 0,   "When you are connected, you can log in",   "telnet" }
                    100: };
                    101: 
                    102: /* ------------------------------------------------------------------------- */
                    103: 
                    104: PUBLIC BOOL HTProgress (HTRequest * request, HTAlertOpcode op,
                    105:                        int msgnum, CONST char * dfault, void * input,
                    106:                        HTAlertPar * reply)
                    107: {
                    108:     if (!request) {
2.8     ! eric      109:        if (WWWTRACE) HTTrace("HTProgress.. Bad argument\n");
2.1       frystyk   110:        return NO;
                    111:     }
                    112:     switch (op) {
                    113:       case HT_PROG_DNS:
2.8     ! eric      114:        HTTrace("Looking up %s\n", (char *) input);
2.1       frystyk   115:        break;
                    116: 
                    117:       case HT_PROG_CONNECT:
2.8     ! eric      118:        HTTrace("Contacting host...\n");
2.1       frystyk   119:        break;
                    120: 
                    121:       case HT_PROG_ACCEPT:
2.8     ! eric      122:        HTTrace("Waiting for connection...\n");
2.1       frystyk   123:        break;
                    124: 
                    125:       case HT_PROG_READ:
                    126:        {
                    127:            long cl = HTAnchor_length(HTRequest_anchor(request));
                    128:            if (cl > 0) {
                    129:                long b_read = HTRequest_bytesRead(request);
                    130:                double pro = (double) b_read/cl*100;
                    131:                char buf[10];
                    132:                HTNumToStr((unsigned long) cl, buf, 10);
2.8     ! eric      133:                HTTrace("Read (%d%% of %s)\n", (int) pro, buf);
2.1       frystyk   134:            } else
2.8     ! eric      135:                HTTrace("Reading...\n");
2.1       frystyk   136:        }
                    137:        break;
                    138: 
                    139:       case HT_PROG_WRITE:
2.4       frystyk   140:        if (HTRequest_isPostWeb(request)) {
                    141:            HTParentAnchor *anchor=HTRequest_anchor(HTRequest_source(request));
                    142:            long cl = HTAnchor_length(anchor);
                    143:            if (cl > 0) {
                    144:                long b_write = HTRequest_bytesWritten(request);
                    145:                double pro = (double) b_write/cl*100;
                    146:                char buf[10];
                    147:                HTNumToStr((unsigned long) cl, buf, 10);
2.8     ! eric      148:                HTTrace("Written (%d%% of %s)\n", (int) pro, buf);
2.4       frystyk   149:            } else
2.8     ! eric      150:                HTTrace("Writing...\n");
2.4       frystyk   151:        }
2.1       frystyk   152:        break;
                    153: 
                    154:       case HT_PROG_DONE:
2.8     ! eric      155:        HTTrace("Finished\n");
2.1       frystyk   156:        break;
                    157: 
                    158:       case HT_PROG_WAIT:
2.8     ! eric      159:        HTTrace("Waiting for free socket...\n");
2.1       frystyk   160:        break;
                    161: 
                    162:       default:
2.8     ! eric      163:        HTTrace("UNKNOWN PROGRESS STATE\n");
2.1       frystyk   164:        break;
                    165:     }
                    166:     return YES;
                    167: }
                    168: 
                    169: PUBLIC BOOL HTConfirm (HTRequest * request, HTAlertOpcode op,
                    170:                       int msgnum, CONST char * dfault, void * input,
                    171:                       HTAlertPar * reply)
                    172: {
                    173:     char response[4];  /* One more for terminating NULL -- AL */
2.8     ! eric      174:     HTTrace("%s", HTDialogs[msgnum]);
        !           175:     if (input) HTTrace(" (%s)", (char *) input);
        !           176:     HTTrace(" (y/n) ");
2.1       frystyk   177: #ifndef NO_STDIO
2.2       frystyk   178:     if (fgets(response, 4, stdin))                /* get reply, max 3 chars */
2.1       frystyk   179: #endif
2.2       frystyk   180:     {
2.1       frystyk   181:        char *ptr = response;
                    182:        while (*ptr) {
                    183:            if (*ptr == '\n') {
                    184:                *ptr = '\0';
                    185:                break;
                    186:            }
                    187:            *ptr = TOUPPER(*ptr);
                    188:            ptr++;
                    189:        }
                    190:        return (!strcmp(response, "YES") || !strcmp(response, "Y")) ? YES : NO;
                    191:     }
                    192:     return NO;
                    193: }
                    194: 
                    195: /*     Prompt for answer and get text back. Reply text is either NULL on
                    196: **     error or a dynamic string which the caller must free.
                    197: */
                    198: PUBLIC BOOL HTPrompt (HTRequest * request, HTAlertOpcode op,
                    199:                      int msgnum, CONST char * dfault, void * input,
                    200:                      HTAlertPar * reply)
                    201: {
2.8     ! eric      202:     HTTrace("%s ", HTDialogs[msgnum]);
        !           203:     if (input) HTTrace(" (%s) ", (char *) input);
        !           204:     if (dfault) HTTrace("(RETURN for [%s]) ", (char *) dfault);
2.1       frystyk   205:     if (reply && msgnum>=0) {
                    206: #ifndef NO_STDIO
2.5       frystyk   207:         char buffer[200];
2.1       frystyk   208:        if (!fgets(buffer, 200, stdin)) return NO;
                    209:        buffer[strlen(buffer)-1] = '\0';                /* Overwrite newline */
                    210:        if (*buffer)
                    211:            HTAlert_setReplyMessage(reply, buffer);
                    212:        else if (dfault)
                    213:            HTAlert_setReplyMessage(reply, (char *) dfault);
                    214:        else
                    215:            return NO;
                    216:        return YES;
                    217: #endif
                    218:     }
                    219:     return NO;
                    220: }
                    221: 
                    222: /*     Prompt for password without echoing the reply. Reply text is
                    223: **     either NULL on error or a dynamic string which the caller must free.
                    224: */
                    225: PUBLIC BOOL HTPromptPassword (HTRequest * request, HTAlertOpcode op,
                    226:                              int msgnum, CONST char * dfault, void * input,
                    227:                              HTAlertPar * reply)
                    228: {
                    229:     if (reply && msgnum>=0) {
                    230: #ifndef NO_PASSWD
                    231:        char * pw = (char *) getpass(HTDialogs[msgnum]);
2.2       frystyk   232:        if (pw) HTAlert_setReplySecret(reply, pw);
2.1       frystyk   233:        return YES;
                    234: #endif
                    235:     }
                    236:     return NO;
                    237: }
                    238: 
                    239: /*     Username and password
                    240: **     ---------------------
                    241: **     Prompt Username and password as an atomic operation
                    242: */
                    243: PUBLIC BOOL HTPromptUsernameAndPassword (HTRequest * request, HTAlertOpcode op,
                    244:                                         int msgnum, CONST char * dfault,
                    245:                                         void * input, HTAlertPar * reply)
                    246: {
                    247:     BOOL status = HTPrompt(request, op, HT_MSG_UID, dfault, input, reply);
                    248:     return status ?
                    249:        HTPromptPassword(request, op, HT_MSG_PW, dfault, input, reply) : NO;
                    250: }
                    251: 
                    252: /*     HTError_print
                    253: **     -------------
                    254: **     Default function that creates an error message using HTAlert() to
                    255: **     put out the contents of the error_stack messages. Furthermore, the
                    256: **     error_info structure contains a name of a help file that might be put
                    257: **     up as a link. This file can then be multi-linguistic.
                    258: */
                    259: PUBLIC BOOL HTError_print (HTRequest * request, HTAlertOpcode op,
                    260:                           int msgnum, CONST char * dfault, void * input,
                    261:                           HTAlertPar * reply)
                    262: {
                    263:     HTList *cur = (HTList *) input;
                    264:     HTError *pres;
                    265:     HTErrorShow showmask = HTError_show();
                    266:     HTChunk *msg = NULL;
                    267:     int code;
2.8     ! eric      268:     if (WWWTRACE) HTTrace("HTError..... Generating message\n");
2.1       frystyk   269:     if (!request || !cur) return NO;
                    270:     while ((pres = (HTError *) HTList_nextObject(cur))) {
                    271:        int index = HTError_index(pres);
                    272:        if (HTError_doShow(pres)) {
                    273:            if (!msg) {
                    274:                HTSeverity severity = HTError_severity(pres);
2.3       frystyk   275:                msg = HTChunk_new(128);
2.1       frystyk   276:                if (severity == ERR_WARN)
2.3       frystyk   277:                    HTChunk_puts(msg, "Warning: ");
2.1       frystyk   278:                else if (severity == ERR_NON_FATAL)
2.3       frystyk   279:                    HTChunk_puts(msg, "Non Fatal Error: ");
2.1       frystyk   280:                else if (severity == ERR_FATAL)
2.3       frystyk   281:                    HTChunk_puts(msg, "Fatal Error: ");
2.1       frystyk   282:                else if (severity == ERR_INFO)
2.3       frystyk   283:                    HTChunk_puts(msg, "Information: ");
2.1       frystyk   284:                else {
                    285:                    if (WWWTRACE)
2.8     ! eric      286:                        HTTrace("HTError..... Unknown Classification of Error (%d)...\n", severity);
2.3       frystyk   287:                    HTChunk_delete(msg);
2.1       frystyk   288:                    return NO;
                    289:                }
                    290: 
                    291:                /* Error number */
                    292:                if ((code = HTErrors[index].code) > 0) {
                    293:                    char buf[10];
                    294:                    sprintf(buf, "%d ", code);
2.3       frystyk   295:                    HTChunk_puts(msg, buf);
2.1       frystyk   296:                }
                    297:            } else
2.3       frystyk   298:                HTChunk_puts(msg, "\nReason: ");
                    299:            HTChunk_puts(msg, HTErrors[index].msg);         /* Error message */
2.1       frystyk   300: 
                    301:            if (showmask & HT_ERR_SHOW_PARS) {           /* Error parameters */
                    302:                int length;
                    303:                int cnt;                
                    304:                char *pars = (char *) HTError_parameter(pres, &length);
                    305:                if (length && pars) {
2.3       frystyk   306:                    HTChunk_puts(msg, " (");
2.1       frystyk   307:                    for (cnt=0; cnt<length; cnt++) {
                    308:                        char ch = *(pars+cnt);
                    309:                        if (ch < 0x20 || ch >= 0x7F)
2.3       frystyk   310:                            HTChunk_putc(msg, '#');
2.1       frystyk   311:                        else
2.3       frystyk   312:                            HTChunk_putc(msg, ch);
2.1       frystyk   313:                    }
2.3       frystyk   314:                    HTChunk_puts(msg, ") ");
2.1       frystyk   315:                }
                    316:            }
                    317: 
                    318:            if (showmask & HT_ERR_SHOW_LOCATION) {         /* Error Location */
2.3       frystyk   319:                HTChunk_puts(msg, "This occured in ");
                    320:                HTChunk_puts(msg, HTError_location(pres));
                    321:                HTChunk_putc(msg, '\n');
2.1       frystyk   322:            }
                    323: 
                    324:            /*
                    325:            ** Make sure that we don't get this error more than once even
                    326:            ** if we are keeping the error stack from one request to another
                    327:            */
                    328:            HTError_setIgnore(pres);
                    329:            
                    330:            /* If we only are show the most recent entry then break here */
                    331:            if (showmask & HT_ERR_SHOW_FIRST)
                    332:                break;
                    333:        }
                    334:     }
                    335:     if (msg) {
2.3       frystyk   336:        HTChunk_putc(msg, '\n');
2.8     ! eric      337:        HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.3       frystyk   338:        HTChunk_delete(msg);
2.1       frystyk   339:     }
                    340:     return YES;
                    341: }
                    342: 
2.6       frystyk   343: /*     HTError_response
                    344: **     ----------------
                    345: **     Default function that creates an error message using HTAlert() to
                    346: **     put out the contents of the error_stack messages. Furthermore, the
                    347: **     error_info structure contains a name of a help file that might be put
                    348: **     up as a link. This file can then be multi-linguistic.
                    349: */
                    350: PUBLIC BOOL HTError_response (HTRequest * request, HTAlertOpcode op,
                    351:                              int msgnum, CONST char * dfault, void * input,
                    352:                              HTAlertPar * reply)
                    353: {
                    354:     HTList * cur = (HTList *) input;
                    355:     HTError * pres;
                    356:     HTErrorShow showmask = HTError_show();
                    357:     HTChunk * msg = NULL;
                    358:     int code;
2.8     ! eric      359:     if (WWWTRACE) HTTrace("HTError..... Generating HTTP response\n");
2.6       frystyk   360:     if (!request || !cur || !reply) return NO;
                    361:     while ((pres = (HTError *) HTList_nextObject(cur))) {
                    362:        int index = HTError_index(pres);
                    363:        if (HTError_doShow(pres)) {
                    364:            if (!msg) {
                    365:                msg = HTChunk_new(128);
                    366:                if ((code = HTErrors[index].code) > 0) {
                    367:                    char * reason = HTErrors[index].msg;
2.7       frystyk   368:                    char * buf;
                    369:                    if ((buf = (char  *) HT_MALLOC(20 + strlen(reason))) == NULL)
                    370:                        HT_OUTOFMEM("HTError_response");
2.6       frystyk   371:                    sprintf(buf,"%s %d %s%c%c",HTTP_VERSION,code,reason,CR,LF);
                    372:                    HTAlert_assignReplyMessage(reply, buf);
                    373:                }
                    374:            } else {
                    375:                HTChunk_puts(msg, "\nReason: ");
                    376:                HTChunk_puts(msg, HTErrors[index].msg);     /* Error message */
                    377:            }
                    378: 
                    379:            if (showmask & HT_ERR_SHOW_PARS) {           /* Error parameters */
                    380:                int length;
                    381:                int cnt;                
                    382:                char *pars = (char *) HTError_parameter(pres, &length);
                    383:                if (length && pars) {
                    384:                    HTChunk_puts(msg, " (");
                    385:                    for (cnt=0; cnt<length; cnt++) {
                    386:                        char ch = *(pars+cnt);
                    387:                        if (ch < 0x20 || ch >= 0x7F)
                    388:                            HTChunk_putc(msg, '#');
                    389:                        else
                    390:                            HTChunk_putc(msg, ch);
                    391:                    }
                    392:                    HTChunk_puts(msg, ") ");
                    393:                }
                    394:            }
                    395: 
                    396:            if (showmask & HT_ERR_SHOW_LOCATION) {         /* Error Location */
                    397:                HTChunk_puts(msg, "This occured in ");
                    398:                HTChunk_puts(msg, HTError_location(pres));
                    399:                HTChunk_putc(msg, '\n');
                    400:            }
                    401: 
                    402:            /*
                    403:            ** Make sure that we don't get this error more than once even
                    404:            ** if we are keeping the error stack from one request to another
                    405:            */
                    406:            HTError_setIgnore(pres);
                    407:            
                    408:            /* If we only are show the most recent entry then break here */
                    409:            if (showmask & HT_ERR_SHOW_FIRST)
                    410:                break;
                    411:        }
                    412:     }
                    413:     if (msg) {
                    414:        HTChunk_putc(msg, '\n');
                    415: #if 0
2.8     ! eric      416:        HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.6       frystyk   417: #endif
                    418:        HTChunk_delete(msg);
                    419:     }
                    420:     return YES;
                    421: }

Webmaster