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

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.27    ! frystyk     6: **     @(#) $Id: HTDialog.c,v 2.26 1996/11/30 23:31:09 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) {
                     74:                long b_write = HTRequest_bytesWritten(request);
                     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.22      frystyk    85:        HTTrace("Connection closed\n");
2.1       frystyk    86:        break;
                     87: 
                     88:       case HT_PROG_WAIT:
2.12      frystyk    89:        HTTrace("Waiting for free socket...\n");
2.24      frystyk    90:        break;
                     91: 
                     92:       case HT_PROG_GC:
                     93:        HTTrace("Garbage colleting persistent cache - please wait...\n");
2.1       frystyk    94:        break;
                     95: 
                     96:       default:
2.8       eric       97:        HTTrace("UNKNOWN PROGRESS STATE\n");
2.1       frystyk    98:        break;
                     99:     }
                    100:     return YES;
                    101: }
                    102: 
                    103: PUBLIC BOOL HTConfirm (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   104:                       int msgnum, const char * dfault, void * input,
2.1       frystyk   105:                       HTAlertPar * reply)
                    106: {
                    107:     char response[4];  /* One more for terminating NULL -- AL */
2.8       eric      108:     HTTrace("%s", HTDialogs[msgnum]);
                    109:     if (input) HTTrace(" (%s)", (char *) input);
                    110:     HTTrace(" (y/n) ");
2.1       frystyk   111: #ifndef NO_STDIO
2.2       frystyk   112:     if (fgets(response, 4, stdin))                /* get reply, max 3 chars */
2.1       frystyk   113: #endif
2.2       frystyk   114:     {
2.1       frystyk   115:        char *ptr = response;
                    116:        while (*ptr) {
                    117:            if (*ptr == '\n') {
                    118:                *ptr = '\0';
                    119:                break;
                    120:            }
                    121:            *ptr = TOUPPER(*ptr);
                    122:            ptr++;
                    123:        }
                    124:        return (!strcmp(response, "YES") || !strcmp(response, "Y")) ? YES : NO;
                    125:     }
                    126:     return NO;
                    127: }
                    128: 
                    129: /*     Prompt for answer and get text back. Reply text is either NULL on
2.10      frystyk   130: **     error or a dynamic string which the caller must HT_FREE.
2.1       frystyk   131: */
                    132: PUBLIC BOOL HTPrompt (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   133:                      int msgnum, const char * dfault, void * input,
2.1       frystyk   134:                      HTAlertPar * reply)
                    135: {
2.8       eric      136:     HTTrace("%s ", HTDialogs[msgnum]);
                    137:     if (input) HTTrace(" (%s) ", (char *) input);
                    138:     if (dfault) HTTrace("(RETURN for [%s]) ", (char *) dfault);
2.1       frystyk   139:     if (reply && msgnum>=0) {
                    140: #ifndef NO_STDIO
2.5       frystyk   141:         char buffer[200];
2.1       frystyk   142:        if (!fgets(buffer, 200, stdin)) return NO;
                    143:        buffer[strlen(buffer)-1] = '\0';                /* Overwrite newline */
                    144:        if (*buffer)
                    145:            HTAlert_setReplyMessage(reply, buffer);
                    146:        else if (dfault)
                    147:            HTAlert_setReplyMessage(reply, (char *) dfault);
                    148:        else
                    149:            return NO;
                    150:        return YES;
                    151: #endif
                    152:     }
                    153:     return NO;
                    154: }
                    155: 
                    156: /*     Prompt for password without echoing the reply. Reply text is
2.10      frystyk   157: **     either NULL on error or a dynamic string which the caller must HT_FREE.
2.1       frystyk   158: */
                    159: PUBLIC BOOL HTPromptPassword (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   160:                              int msgnum, const char * dfault, void * input,
2.1       frystyk   161:                              HTAlertPar * reply)
                    162: {
                    163:     if (reply && msgnum>=0) {
2.10      frystyk   164: #ifdef HAVE_GETPASS
2.1       frystyk   165:        char * pw = (char *) getpass(HTDialogs[msgnum]);
2.2       frystyk   166:        if (pw) HTAlert_setReplySecret(reply, pw);
2.1       frystyk   167:        return YES;
2.10      frystyk   168: #else
2.27    ! frystyk   169:        /*
        !           170:        **  This is just to be able to get it wo work when getpass() 
        !           171:        **  isn't available.
        !           172:        */
        !           173:         char buffer[100];
        !           174:        memset(buffer, '\0', 100);
        !           175:         HTTrace("%s ", HTDialogs[msgnum]);
        !           176:        if (!fgets(buffer, 99, stdin)) return NO;
        !           177:        buffer[strlen(buffer)-1] = '\0';                /* Overwrite newline */
        !           178:         if (*buffer) {
        !           179:             HTAlert_setReplySecret(reply, buffer);
        !           180:             return YES;
        !           181:         }
        !           182:         return NO;
2.10      frystyk   183: #endif /* HAVE_GETPASS */
2.1       frystyk   184:     }
                    185:     return NO;
                    186: }
                    187: 
                    188: /*     Username and password
                    189: **     ---------------------
                    190: **     Prompt Username and password as an atomic operation
                    191: */
                    192: PUBLIC BOOL HTPromptUsernameAndPassword (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   193:                                         int msgnum, const char * dfault,
2.1       frystyk   194:                                         void * input, HTAlertPar * reply)
                    195: {
2.21      frystyk   196:     BOOL status = HTPrompt(request, op, msgnum, dfault, input, reply);
2.1       frystyk   197:     return status ?
                    198:        HTPromptPassword(request, op, HT_MSG_PW, dfault, input, reply) : NO;
                    199: }
                    200: 
                    201: /*     HTError_print
                    202: **     -------------
                    203: **     Default function that creates an error message using HTAlert() to
                    204: **     put out the contents of the error_stack messages. Furthermore, the
                    205: **     error_info structure contains a name of a help file that might be put
                    206: **     up as a link. This file can then be multi-linguistic.
                    207: */
                    208: PUBLIC BOOL HTError_print (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   209:                           int msgnum, const char * dfault, void * input,
2.1       frystyk   210:                           HTAlertPar * reply)
                    211: {
                    212:     HTList *cur = (HTList *) input;
                    213:     HTError *pres;
                    214:     HTErrorShow showmask = HTError_show();
                    215:     HTChunk *msg = NULL;
                    216:     int code;
2.8       eric      217:     if (WWWTRACE) HTTrace("HTError..... Generating message\n");
2.1       frystyk   218:     if (!request || !cur) return NO;
                    219:     while ((pres = (HTError *) HTList_nextObject(cur))) {
                    220:        int index = HTError_index(pres);
                    221:        if (HTError_doShow(pres)) {
                    222:            if (!msg) {
                    223:                HTSeverity severity = HTError_severity(pres);
2.3       frystyk   224:                msg = HTChunk_new(128);
2.1       frystyk   225:                if (severity == ERR_WARN)
2.3       frystyk   226:                    HTChunk_puts(msg, "Warning: ");
2.1       frystyk   227:                else if (severity == ERR_NON_FATAL)
2.3       frystyk   228:                    HTChunk_puts(msg, "Non Fatal Error: ");
2.1       frystyk   229:                else if (severity == ERR_FATAL)
2.3       frystyk   230:                    HTChunk_puts(msg, "Fatal Error: ");
2.1       frystyk   231:                else if (severity == ERR_INFO)
2.3       frystyk   232:                    HTChunk_puts(msg, "Information: ");
2.1       frystyk   233:                else {
                    234:                    if (WWWTRACE)
2.8       eric      235:                        HTTrace("HTError..... Unknown Classification of Error (%d)...\n", severity);
2.3       frystyk   236:                    HTChunk_delete(msg);
2.1       frystyk   237:                    return NO;
                    238:                }
                    239: 
                    240:                /* Error number */
                    241:                if ((code = HTErrors[index].code) > 0) {
                    242:                    char buf[10];
                    243:                    sprintf(buf, "%d ", code);
2.3       frystyk   244:                    HTChunk_puts(msg, buf);
2.1       frystyk   245:                }
                    246:            } else
2.3       frystyk   247:                HTChunk_puts(msg, "\nReason: ");
                    248:            HTChunk_puts(msg, HTErrors[index].msg);         /* Error message */
2.1       frystyk   249: 
                    250:            if (showmask & HT_ERR_SHOW_PARS) {           /* Error parameters */
                    251:                int length;
                    252:                int cnt;                
                    253:                char *pars = (char *) HTError_parameter(pres, &length);
                    254:                if (length && pars) {
2.3       frystyk   255:                    HTChunk_puts(msg, " (");
2.1       frystyk   256:                    for (cnt=0; cnt<length; cnt++) {
                    257:                        char ch = *(pars+cnt);
                    258:                        if (ch < 0x20 || ch >= 0x7F)
2.3       frystyk   259:                            HTChunk_putc(msg, '#');
2.1       frystyk   260:                        else
2.3       frystyk   261:                            HTChunk_putc(msg, ch);
2.1       frystyk   262:                    }
2.3       frystyk   263:                    HTChunk_puts(msg, ") ");
2.1       frystyk   264:                }
                    265:            }
                    266: 
                    267:            if (showmask & HT_ERR_SHOW_LOCATION) {         /* Error Location */
2.3       frystyk   268:                HTChunk_puts(msg, "This occured in ");
                    269:                HTChunk_puts(msg, HTError_location(pres));
                    270:                HTChunk_putc(msg, '\n');
2.1       frystyk   271:            }
                    272: 
                    273:            /*
                    274:            ** Make sure that we don't get this error more than once even
                    275:            ** if we are keeping the error stack from one request to another
                    276:            */
                    277:            HTError_setIgnore(pres);
                    278:            
                    279:            /* If we only are show the most recent entry then break here */
                    280:            if (showmask & HT_ERR_SHOW_FIRST)
                    281:                break;
                    282:        }
                    283:     }
                    284:     if (msg) {
2.3       frystyk   285:        HTChunk_putc(msg, '\n');
2.8       eric      286:        HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.3       frystyk   287:        HTChunk_delete(msg);
2.1       frystyk   288:     }
                    289:     return YES;
                    290: }
                    291: 
2.6       frystyk   292: /*     HTError_response
                    293: **     ----------------
                    294: **     Default function that creates an error message using HTAlert() to
                    295: **     put out the contents of the error_stack messages. Furthermore, the
                    296: **     error_info structure contains a name of a help file that might be put
                    297: **     up as a link. This file can then be multi-linguistic.
                    298: */
                    299: PUBLIC BOOL HTError_response (HTRequest * request, HTAlertOpcode op,
2.10      frystyk   300:                              int msgnum, const char * dfault, void * input,
2.6       frystyk   301:                              HTAlertPar * reply)
                    302: {
                    303:     HTList * cur = (HTList *) input;
                    304:     HTError * pres;
                    305:     HTErrorShow showmask = HTError_show();
                    306:     HTChunk * msg = NULL;
                    307:     int code;
2.8       eric      308:     if (WWWTRACE) HTTrace("HTError..... Generating HTTP response\n");
2.6       frystyk   309:     if (!request || !cur || !reply) return NO;
                    310:     while ((pres = (HTError *) HTList_nextObject(cur))) {
                    311:        int index = HTError_index(pres);
                    312:        if (HTError_doShow(pres)) {
                    313:            if (!msg) {
                    314:                msg = HTChunk_new(128);
                    315:                if ((code = HTErrors[index].code) > 0) {
                    316:                    char * reason = HTErrors[index].msg;
2.7       frystyk   317:                    char * buf;
                    318:                    if ((buf = (char  *) HT_MALLOC(20 + strlen(reason))) == NULL)
                    319:                        HT_OUTOFMEM("HTError_response");
2.6       frystyk   320:                    sprintf(buf,"%s %d %s%c%c",HTTP_VERSION,code,reason,CR,LF);
                    321:                    HTAlert_assignReplyMessage(reply, buf);
                    322:                }
                    323:            } else {
                    324:                HTChunk_puts(msg, "\nReason: ");
                    325:                HTChunk_puts(msg, HTErrors[index].msg);     /* Error message */
                    326:            }
                    327: 
                    328:            if (showmask & HT_ERR_SHOW_PARS) {           /* Error parameters */
                    329:                int length;
                    330:                int cnt;                
                    331:                char *pars = (char *) HTError_parameter(pres, &length);
                    332:                if (length && pars) {
                    333:                    HTChunk_puts(msg, " (");
                    334:                    for (cnt=0; cnt<length; cnt++) {
                    335:                        char ch = *(pars+cnt);
                    336:                        if (ch < 0x20 || ch >= 0x7F)
                    337:                            HTChunk_putc(msg, '#');
                    338:                        else
                    339:                            HTChunk_putc(msg, ch);
                    340:                    }
                    341:                    HTChunk_puts(msg, ") ");
                    342:                }
                    343:            }
                    344: 
                    345:            if (showmask & HT_ERR_SHOW_LOCATION) {         /* Error Location */
                    346:                HTChunk_puts(msg, "This occured in ");
                    347:                HTChunk_puts(msg, HTError_location(pres));
                    348:                HTChunk_putc(msg, '\n');
                    349:            }
                    350: 
                    351:            /*
                    352:            ** Make sure that we don't get this error more than once even
                    353:            ** if we are keeping the error stack from one request to another
                    354:            */
                    355:            HTError_setIgnore(pres);
                    356:            
                    357:            /* If we only are show the most recent entry then break here */
                    358:            if (showmask & HT_ERR_SHOW_FIRST)
                    359:                break;
                    360:        }
                    361:     }
                    362:     if (msg) {
                    363:        HTChunk_putc(msg, '\n');
                    364: #if 0
2.8       eric      365:        HTTrace("WARNING: %s\n", HTChunk_data(msg));
2.6       frystyk   366: #endif
                    367:        HTChunk_delete(msg);
                    368:     }
                    369:     return YES;
                    370: }

Webmaster