Exemple #1
0
static void mainloop(struct gopherus *g)
{
    int exitflag;
    int bufferlen;

    for (;;) {
        struct url *url = &(g->history->url); /* a shortcut */

        if ((url->itemtype == GOPHER_ITEM_FILE) ||
            (url->itemtype == GOPHER_ITEM_DIR) ||
            (url->itemtype == GOPHER_ITEM_INDEX_SEARCH_SERVER) ||
            (url->itemtype == GOPHER_ITEM_HTML)) { /* if it's a displayable item type... */
            draw_urlbar(url, &g->cfg);

            if (g->history->cache == NULL) { /* reload the resource if not in cache already */
                bufferlen = loadfile_buff(url, g->buf, buffersize, g->statusbar, NULL, &g->cfg);
                if (bufferlen < 0) {
                    history_back(&g->history);
                    continue;
                } else {
                    history_cleanupcache(g->history);
                    g->history->cache = malloc(bufferlen);
                    if (g->history->cache == NULL) {
                        sprintf(g->statusbar, "Out of memory!");
                        exitflag = 1;
                        break;
                    }
                    if (bufferlen > 0) memcpy(g->history->cache, g->buf, bufferlen);
                    g->history->cachesize = bufferlen;
                }
            }

            switch (url->itemtype) {
                case GOPHER_ITEM_FILE: /* text file */
                    exitflag = display_text(g, TXT_FORMAT_RAW);
                    break;
                case GOPHER_ITEM_HTML: /* html file */
                    exitflag = display_text(g, TXT_FORMAT_HTM);
                    break;
                case GOPHER_ITEM_DIR: /* menu */
                case GOPHER_ITEM_INDEX_SEARCH_SERVER: /* query result (also a menu) */
                    exitflag = display_menu(g);
                    break;
                default:
                    set_statusbar(g->statusbar, "Fatal error: got an unhandled itemtype!");
                    exitflag = DISPLAY_ORDER_QUIT;
                    break;
            }

            if (exitflag == DISPLAY_ORDER_BACK) {
                history_back(&(g->history));
            } else if (exitflag == DISPLAY_ORDER_REFR) {
                free(g->history->cache);
                g->history->cache = NULL;
                g->history->cachesize = 0;
                g->history->displaymemory[0] = -1;
                g->history->displaymemory[1] = -1;
            } else if (exitflag == DISPLAY_ORDER_QUIT) {
                break;
            }
        } else { /* the itemtype is not one of the internally displayable types -> ask to download it */
            char filename[64] = {0};
            static const char prompt[] = "Download as: ";
            char *lastslash = strrchr(url->selector, '/');
            set_statusbar(filename, ""); /* make sure to clear out the status bar */
            draw_statusbar(filename, &g->cfg);
            ui_cputs(prompt, 0x70, 0, ui_rows - 1);
            if (lastslash)
                strncpy(filename, lastslash + 1, sizeof filename - 1);
            if (editstring(filename, 63, ui_cols - (sizeof prompt - 1), sizeof prompt - 1, ui_rows - 1, 0x70, NULL) != 0) {
                loadfile_buff(url, g->buf, buffersize, g->statusbar, filename, &g->cfg);
            }
            history_back(&(g->history));
        }
    }
}
Exemple #2
0
void vendor_buy_fish(int fd, gamestate_t* state, void *data, const char* input) {
	int n = atoi(input);
	state->gold -= 2*n;
	draw_statusbar(fd,state);
	show_multiline_text(fd,vendor_fish,vendor.npcdesc);
}
Exemple #3
0
/* downloads a gopher or http resource and write it to a file or a memory buffer. if *filename is not NULL, the resource will
   be written in the file (but a valid *buffer is still required) */
static long loadfile_buff(const struct url *url, char *buffer, long buffer_max, char *statusbar, char *filename, struct gopherusconfig *cfg)
{
    unsigned long int ipaddr;
    long reslength, byteread, fdlen = 0;
    char statusmsg[128];
    FILE *fd = NULL;
    int headersdone = 0; /* used notably for HTTP, to localize the end of headers */
    time_t lastactivity, curtime;
    if (url->host[0] == '#') { /* embedded start page */
        reslength = load_embedded_page(buffer, url->host + 1);
        /* open file, if downloading to a file */
        if (filename != NULL) {
            fd = fopen(filename, "rb"); /* try to open for read - this should fail */
            if (fd != NULL) {
                set_statusbar(statusbar, "!File already exists! Operation aborted.");
                fclose(fd);
                return -1;
            }
            fd = fopen(filename, "wb"); /* now open for write - this will create the file */
            if (fd == NULL) { /* this should not fail */
                set_statusbar(statusbar, "!Error: could not create the file on disk!");
                fclose(fd);
                return -1;
            }
            fwrite(buffer, 1, reslength, fd);
            fclose(fd);
        }
        return reslength;
    }
    ipaddr = dnscache_ask(url->host);
    if (ipaddr == 0) {
        sprintf(statusmsg, "Resolving '%s'...", url->host);
        draw_statusbar(statusmsg, cfg);
        ipaddr = net_dnsresolve(url->host);
        if (ipaddr == 0) {
            set_statusbar(statusbar, "!DNS resolution failed!");
            return -1;
        }
        dnscache_add(url->host, ipaddr);
    }
    sprintf(statusmsg, "Connecting to %d.%d.%d.%d...", (int)(ipaddr >> 24) & 0xFF, (int)(ipaddr >> 16) & 0xFF, (int)(ipaddr >> 8) & 0xFF, (int)(ipaddr & 0xFF));
    draw_statusbar(statusmsg, cfg);

    if (net_connect(ipaddr, url->port) != 0) {
        set_statusbar(statusbar, "!Connection error!");
        return -1;
    }
    if (url->protocol == PARSEURL_PROTO_HTTP) { /* http */
        sprintf(buffer, "GET /%s HTTP/1.0\r\nHOST: %s\r\nUSER-AGENT: Gopherus v" VERSION "\r\n\r\n", url->selector, url->host);
    } else { /* gopher */
        sprintf(buffer, "%s\r\n", url->selector);
    }
    if (net_send(buffer, strlen(buffer)) != (int)strlen(buffer)) {
        set_statusbar(statusbar, "!send() error!");
        net_close();
        return -1;
    }
    /* prepare timers */
    lastactivity = time(NULL);
    curtime = lastactivity;
    /* open file, if downloading to a file */
    if (filename != NULL) {
        fd = fopen(filename, "rb"); /* try to open for read - this should fail */
        if (fd != NULL) {
            set_statusbar(statusbar, "!File already exists! Operation aborted.");
            fclose(fd);
            net_abort();
            return -1;
        }
        fd = fopen(filename, "wb"); /* now open for write - this will create the file */
        if (fd == NULL) { /* this should not fail */
            set_statusbar(statusbar, "!Error: could not create the file on disk!");
            fclose(fd);
            net_abort();
            return -1;
        }
    }
    /* receive answer */
    reslength = 0;
    for (;;) {
        if (buffer_max + fdlen - reslength < 1) { /* too much data! */
            set_statusbar(statusbar, "!Error: Server's answer is too long!");
            reslength = -1;
            break;
        }
        byteread = net_recv(buffer + (reslength - fdlen), buffer_max + fdlen - reslength);
        curtime = time(NULL);
        if (byteread < 0) break; /* end of connection */

        if (is_int_pending()) {
            set_statusbar(statusbar, "Connection aborted by the user.");
            reslength = -1;
            break;
        }

        if (byteread > 0) {
            lastactivity = curtime;
            reslength += byteread;
            /* if protocol is http, ignore headers */
            if ((url->protocol == PARSEURL_PROTO_HTTP) && (headersdone == 0)) {
                int i;
                for (i = 0; i < reslength - 2; i++) {
                    if (buffer[i] == '\n') {
                        if (buffer[i + 1] == '\r') i++; /* skip CR if following */
                        if (buffer[i + 1] == '\n') {
                            i += 2;
                            headersdone = reslength;
                            for (reslength = 0; i < headersdone; i++) buffer[reslength++] = buffer[i];
                            break;
                        }
                    }
                }
            } else {
                sprintf(statusmsg, "Downloading... [%ld bytes]", reslength);
                set_statusbar(statusbar, statusmsg);
                draw_statusbar(statusbar, cfg);
                if ((fd != NULL) && (reslength - fdlen > 4096)) { /* if downloading to file, write stuff to disk */
                    int writeres = fwrite(buffer, 1, reslength - fdlen, fd);
                    if (writeres < 0) writeres = 0;
                    fdlen += writeres;
                }
            }
        } else {
            if (curtime - lastactivity > 2) {
                if (curtime - lastactivity > 20) { /* TIMEOUT! */
                    set_statusbar(statusbar, "!Timeout while waiting for data!");
                    reslength = -1;
                    break;
                } else {
                    usleep(250000);  /* give the cpu some time up (250ms), the transfer is really slow */
                }
            }
        }
    }

    if (reslength >= 0) {
        statusmsg[0] = 0;
        draw_statusbar(statusmsg, cfg);
        net_close();
    } else {
        net_abort();
    }

    if (fd != NULL) { /* finish the buffer */
        char tmpmsg[80];
        if (reslength - fdlen > 0) { /* if anything left in the buffer, write it now */
            fdlen += fwrite(buffer, 1, reslength - fdlen, fd);
        }
        fclose(fd);
        sprintf(tmpmsg, "Saved %ld bytes on disk", fdlen);
        set_statusbar(statusbar, tmpmsg);
    }

    return reslength;
}