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