Esempio n. 1
0
static char *
errorTryLoadText(const char *page_name, const char *dir)
{
    int fd;
    char path[MAXPATHLEN];
    struct stat sb;
    char *text;

    snprintf(path, sizeof(path), "%s/%s", dir, page_name);
#ifdef _SQUID_MSWIN_
    fd = file_open(path, O_RDONLY | O_BINARY);
#else
    fd = file_open(path, O_RDONLY | O_TEXT);
#endif
    if (fd < 0 || fstat(fd, &sb) < 0) {
	debug(4, 0) ("errorTryLoadText: '%s': %s\n", path, xstrerror());
	if (fd >= 0)
	    file_close(fd);
	return NULL;
    }
    text = xcalloc((size_t) sb.st_size + 2 + 1, 1);	/* 2 == space for %S */
    if (FD_READ_METHOD(fd, text, (int) sb.st_size) != sb.st_size) {
	debug(4, 0) ("errorTryLoadText: failed to fully read: '%s': %s\n",
	    path, xstrerror());
	safe_free(text);
    }
    file_close(fd);
    if (text && strstr(text, "%s") == NULL)
	strcat(text, "%S");	/* add signature */
    return text;
}
static void
squidaio_fdhandler(int fd, void *data)
{
    char junk[256];
    FD_READ_METHOD(done_fd_read, junk, sizeof(junk));
    commSetSelect(fd, COMM_SELECT_READ, squidaio_fdhandler, NULL, 0);
}
Esempio n. 3
0
static void
identReadReply(int fd, void *data)
{
    IdentStateData *state = data;
    LOCAL_ARRAY(char, buf, BUFSIZ);
    char *ident = NULL;
    char *t = NULL;
    int len = -1;
    buf[0] = '\0';
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, BUFSIZ - 1);
    fd_bytes(fd, len, FD_READ);
    if (len <= 0) {
	comm_close(fd);
	return;
    }
    /*
     * XXX This isn't really very tolerant. It should read until EOL
     * or EOF and then decode the answer... If the reply is fragmented
     * then this will fail
     */
    buf[len] = '\0';
    if ((t = strchr(buf, '\r')))
	*t = '\0';
    if ((t = strchr(buf, '\n')))
	*t = '\0';
    debug(30, 5) ("identReadReply: FD %d: Read '%s'\n", fd, buf);
    if (strstr(buf, "USERID")) {
	if ((ident = strrchr(buf, ':'))) {
	    while (xisspace(*++ident));
	    identCallback(state, ident);
	}
    }
    comm_close(fd);
}
Esempio n. 4
0
static void
idnsReadTcp(int fd, void *data)
{
    ssize_t n;
    idns_query *q = data;
    int ns = (q->nsends - 1) % nns;
    if (!q->tcp_buffer)
	q->tcp_buffer = memAllocBuf(1024, &q->tcp_buffer_size);
    statCounter.syscalls.sock.reads++;
    n = FD_READ_METHOD(q->tcp_socket, q->tcp_buffer + q->tcp_buffer_offset, q->tcp_buffer_size - q->tcp_buffer_offset);
    if (n < 0 && ignoreErrno(errno)) {
	commSetSelect(q->tcp_socket, COMM_SELECT_READ, idnsReadTcp, q, 0);
	return;
    }
    if (n <= 0) {
	debug(78, 1) ("idnsReadTcp: Short response from nameserver %d for %s.\n", ns + 1, q->name);
	idnsTcpCleanup(q);
	return;
    }
    fd_bytes(fd, n, FD_READ);
    q->tcp_buffer_offset += n;
    if (q->tcp_buffer_offset > 2) {
	unsigned short response_size = ntohs(*(short *) q->tcp_buffer);
	if (q->tcp_buffer_offset >= response_size + 2) {
	    nameservers[ns].nreplies++;
	    idnsGrokReply(q->tcp_buffer + 2, response_size);
	    return;
	}
	if (q->tcp_buffer_size < response_size + 2)
	    q->tcp_buffer = memReallocBuf(q->tcp_buffer, response_size + 2, &q->tcp_buffer_size);
    }
    commSetSelect(q->tcp_socket, COMM_SELECT_READ, idnsReadTcp, q, 0);
}
static void
whoisReadReply(int fd, void *data)
{
    WhoisState *p = data;
    StoreEntry *entry = p->entry;
    char *buf = memAllocate(MEM_4K_BUF);
    MemObject *mem = entry->mem_obj;
    int len;
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, 4095);
    buf[len] = '\0';
    debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
    debug(75, 5) ("{%s}\n", buf);
    if (len > 0) {
	if (0 == mem->inmem_hi) {
	    http_reply *reply = mem->reply;
	    http_version_t version;
	    storeBuffer(entry);
	    httpBuildVersion(&version, 1, 0);
	    httpReplySetHeaders(reply, version, HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
	    httpReplySwapOut(reply, entry);
	}
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.http.kbytes_in, len);
	storeAppend(entry, buf, len);
	storeBufferFlush(entry);
	commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
    } else if (len < 0) {
	debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
	} else {
	    ErrorState *err;
	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, p->fwd->request);
	    err->xerrno = errno;
	    fwdFail(p->fwd, err);
	    comm_close(fd);
	}
    } else {
	storeTimestampsSet(entry);
	storeBufferFlush(entry);
	if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
	    storeSetPublicKey(entry);
	fwdComplete(p->fwd);
	debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
	comm_close(fd);
    }
    memFree(buf, MEM_4K_BUF);
}
Esempio n. 6
0
static void
helperStatefulHandleRead(int fd, void *data)
{
    int len;
    char *t = NULL;
    helper_stateful_server *srv = data;
    helper_stateful_request *r;
    statefulhelper *hlp = srv->parent;
    assert(fd == srv->rfd);
    assert(cbdataValid(data));
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, srv->buf + srv->offset, srv->buf_sz - srv->offset);
    fd_bytes(fd, len, FD_READ);
    debug(84, 5) ("helperStatefulHandleRead: %d bytes from %s #%d.\n",
	len, hlp->id_name, srv->index + 1);
    if (len <= 0) {
	if (len < 0)
	    debug(84, 1) ("helperStatefulHandleRead: FD %d read: %s\n", fd, xstrerror());
	comm_close(fd);
	return;
    }
    srv->offset += len;
    srv->buf[srv->offset] = '\0';
    r = srv->request;
    if (r == NULL) {
	/* someone spoke without being spoken to */
	debug(84, 1) ("helperStatefulHandleRead: unexpected read from %s #%d, %d bytes\n",
	    hlp->id_name, srv->index + 1, len);
	srv->offset = 0;
    } else if ((t = strchr(srv->buf, '\n'))) {
	/* end of reply found */
	debug(84, 3) ("helperStatefulHandleRead: end of reply found\n");
	*t = '\0';
	srv->flags.busy = 0;
	srv->offset = 0;
	srv->request = NULL;
	hlp->stats.replies++;
	hlp->stats.avg_svc_time =
	    intAverage(hlp->stats.avg_svc_time,
	    tvSubMsec(srv->dispatch_time, current_time),
	    hlp->stats.replies, REDIRECT_AV_FACTOR);
	if (cbdataValid(r->data)) {
	    r->callback(r->data, srv, srv->buf);
	} else {
	    debug(84, 1) ("StatefulHandleRead: no callback data registered\n");
	}
	helperStatefulRequestFree(r);
    } else {
	commSetSelect(srv->rfd, COMM_SELECT_READ, helperStatefulHandleRead, srv, 0);
    }
}
Esempio n. 7
0
File: disk.c Progetto: selecli/squid
/* Read from FD */
static void
diskHandleRead(int fd, void *data)
{
	dread_ctrl *ctrl_dat = data;
	fde *F = &fd_table[fd];
	int len;
	int rc = DISK_OK;
	/*
	 * FD < 0 indicates premature close; we just have to free
	 * the state data.
	 */
	if (fd < 0)
	{
		memFree(ctrl_dat, MEM_DREAD_CTRL);
		return;
	}
	if (F->disk.offset != ctrl_dat->file_offset)
	{
		debug(6, 3) ("diskHandleRead: FD %d seeking to offset %d\n",
					 fd, (int) ctrl_dat->file_offset);
		lseek(fd, ctrl_dat->file_offset, SEEK_SET);	/* XXX ignore return? */
		statCounter.syscalls.disk.seeks++;
		F->disk.offset = ctrl_dat->file_offset;
	}
	errno = 0;
	len = FD_READ_METHOD(fd, ctrl_dat->buf, ctrl_dat->req_len);
	if (len > 0)
		F->disk.offset += len;
	statCounter.syscalls.disk.reads++;
	fd_bytes(fd, len, FD_READ);
	if (len < 0)
	{
		if (ignoreErrno(errno))
		{
			commSetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);
			return;
		}
		debug(50, 1) ("diskHandleRead: FD %d: %s\n", fd, xstrerror());
		len = 0;
		rc = DISK_ERROR;
	}
	else if (len == 0)
	{
		rc = DISK_EOF;
	}
	if (cbdataValid(ctrl_dat->client_data))
		ctrl_dat->handler(fd, ctrl_dat->buf, len, rc, ctrl_dat->client_data);
	cbdataUnlock(ctrl_dat->client_data);
	memFree(ctrl_dat, MEM_DREAD_CTRL);
}
Esempio n. 8
0
static void
pconnRead(int fd, void *data)
{
    LOCAL_ARRAY(char, buf, 256);
    struct _pconn *p = data;
    int n;
    assert(table != NULL);
    statCounter.syscalls.sock.reads++;
    n = FD_READ_METHOD(fd, buf, 256);
    debug(48, 3) ("pconnRead: %d bytes from FD %d, %s\n", n, fd,
	hashKeyStr(&p->hash));
    pconnRemoveFD(p, fd);
    comm_close(fd);
}
Esempio n. 9
0
/* This will be called when data is ready to be read from fd.  Read until
 * error or connection closed. */
static void
gopherReadReply(int fd, void *data)
{
    GopherStateData *gopherState = data;
    StoreEntry *entry = gopherState->entry;
    char *buf = NULL;
    int len;
    int clen;
    int bin;
    size_t read_sz;
#if DELAY_POOLS
    delay_id delay_id;
#endif
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    buf = memAllocate(MEM_4K_BUF);
    read_sz = 4096 - 1;		/* leave room for termination */
#if DELAY_POOLS
    delay_id = delayMostBytesAllowed(entry->mem_obj, &read_sz);
#endif
    /* leave one space for \0 in gopherToHTML */
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, read_sz);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
#if DELAY_POOLS
	delayBytesIn(delay_id, len);
#endif
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.other.kbytes_in, len);
    }
    debug(10, 5) ("gopherReadReply: FD %d read len=%d\n", fd, len);
    if (len > 0) {
	commSetTimeout(fd, Config.Timeout.read, NULL, NULL);
	IOStats.Gopher.reads++;
	for (clen = len - 1, bin = 0; clen; bin++)
	    clen >>= 1;
	IOStats.Gopher.read_hist[bin]++;
    }
Esempio n. 10
0
static void
whoisReadReply(int fd, void *data)
{
    WhoisState *p = data;
    StoreEntry *entry = p->entry;
    char *buf = memAllocate(MEM_4K_BUF);
    MemObject *mem = entry->mem_obj;
    int len;
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, 4095);
    buf[len] = '\0';
    debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
    debug(75, 5) ("{%s}\n", buf);
    if (len > 0) {
	if (0 == mem->inmem_hi)
	    mem->reply->sline.status = HTTP_OK;
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.http.kbytes_in, len);
	storeAppend(entry, buf, len);
	commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
    } else if (len < 0) {
	debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
	} else if (mem->inmem_hi == 0) {
	    ErrorState *err;
	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
	    err->xerrno = errno;
	    fwdFail(p->fwd, err);
	    comm_close(fd);
	} else {
	    comm_close(fd);
	}
    } else {
	fwdComplete(p->fwd);
	debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
	comm_close(fd);
    }
    memFree(buf, MEM_4K_BUF);
}
Esempio n. 11
0
/*
 * Gobble up (read) some bytes until we get to the start of the body
 */
static void
icapRespModGobble(int fd, void *data)
{
    IcapStateData *icap = data;
    int len;
    LOCAL_ARRAY(char, junk, SQUID_TCP_SO_RCVBUF);
    debug(81, 3) ("icapRespModGobble: FD %d gobbling %d bytes\n", fd,
	icap->bytes_to_gobble);
    len = FD_READ_METHOD(fd, junk, icap->bytes_to_gobble);
    debug(81, 3) ("icapRespModGobble: gobbled %d bytes\n", len);
    if (len < 0) {
	/* XXX error */
	abort();
    }
    icap->bytes_to_gobble -= len;
    if (icap->bytes_to_gobble)
	commSetSelect(fd, COMM_SELECT_READ, icapRespModGobble, icap, 0);
    else
	icapReadReply(fd, icap);
}
/* This will be called when data is ready to be read from fd.  Read until
 * error or connection closed. */
static void
waisReadReply(int fd, void *data)
{
    WaisStateData *waisState = data;
    LOCAL_ARRAY(char, buf, 4096);
    StoreEntry *entry = waisState->entry;
    int len;
    int clen;
    int bin;
    size_t read_sz;
#if DELAY_POOLS
    delay_id delay_id;
#endif
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    read_sz = 4096;
#if DELAY_POOLS
    delay_id = delayMostBytesAllowed(entry->mem_obj, &read_sz);
#endif
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, read_sz);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
#if DELAY_POOLS
	delayBytesIn(delay_id, len);
#endif
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.other.kbytes_in, len);
    }
    debug(24, 5) ("waisReadReply: FD %d read len:%d\n", fd, len);
    if (len > 0) {
	commSetTimeout(fd, Config.Timeout.read, NULL, NULL);
	IOStats.Wais.reads++;
	for (clen = len - 1, bin = 0; clen; bin++)
	    clen >>= 1;
	IOStats.Wais.read_hist[bin]++;
    }
squidaio_result_t *
squidaio_poll_done(void)
{
    squidaio_request_t *request;
    squidaio_result_t *resultp;
    int cancelled;
    int polled = 0;

  AIO_REPOLL:
    request = done_requests.head;
    if (request == NULL && !polled) {
	if (done_signalled) {
	    char junk[256];
	    FD_READ_METHOD(done_fd_read, junk, sizeof(junk));
	    done_signalled = 0;
	}
	squidaio_poll_queues();
	polled = 1;
	request = done_requests.head;
    }
    if (!request) {
	return NULL;
    }
    debug(43, 9) ("squidaio_poll_done: %p type=%d result=%p\n",
	request, request->request_type, request->resultp);
    done_requests.head = request->next;
    if (!done_requests.head)
	done_requests.tailp = &done_requests.head;
    resultp = request->resultp;
    cancelled = request->cancelled;
    squidaio_debug(request);
    debug(43, 5) ("DONE: %d -> %d\n", request->ret, request->err);
    squidaio_cleanup_request(request);
    if (cancelled)
	goto AIO_REPOLL;
    return resultp;
}				/* squidaio_poll_done */
Esempio n. 14
0
static void
mimeLoadIconFile(const char *icon)
{
    int fd;
    int n;
    request_flags flags;
    struct stat sb;
    StoreEntry *e;
    LOCAL_ARRAY(char, path, MAXPATHLEN);
    LOCAL_ARRAY(char, url, MAX_URL);
    char *buf;
    const char *type = mimeGetContentType(icon);
    HttpReply *reply;
    http_version_t version;
    request_t *r;
    if (type == NULL)
	fatal("Unknown icon format while reading mime.conf\n");
    buf = internalLocalUri("/squid-internal-static/icons/", icon);
    xstrncpy(url, buf, MAX_URL);
    if (storeGetPublic(url, METHOD_GET))
	return;
    snprintf(path, MAXPATHLEN, "%s/%s", Config.icons.directory, icon);
    fd = file_open(path, O_RDONLY | O_BINARY);
    if (fd < 0) {
	debug(25, 0) ("mimeLoadIconFile: %s: %s\n", path, xstrerror());
	return;
    }
    if (fstat(fd, &sb) < 0) {
	debug(25, 0) ("mimeLoadIconFile: FD %d: fstat: %s\n", fd, xstrerror());
	file_close(fd);
	return;
    }
    flags = null_request_flags;
    flags.cachable = 1;
    e = storeCreateEntry(url,
	url,
	flags,
	METHOD_GET);
    assert(e != NULL);
    EBIT_SET(e->flags, ENTRY_SPECIAL);
    storeSetPublicKey(e);
    storeBuffer(e);
    r = urlParse(METHOD_GET, url);
    if (NULL == r)
	fatal("mimeLoadIcon: cannot parse internal URL");
    e->mem_obj->request = requestLink(r);
    httpReplyReset(reply = e->mem_obj->reply);
    httpBuildVersion(&version, 1, 0);
    httpReplySetHeaders(reply, version, HTTP_OK, NULL,
	type, (int) sb.st_size, sb.st_mtime, -1);
    reply->cache_control = httpHdrCcCreate();
    httpHdrCcSetMaxAge(reply->cache_control, 86400);
    httpHeaderPutCc(&reply->header, reply->cache_control);
    httpReplySwapOut(reply, e);
    reply->hdr_sz = e->mem_obj->inmem_hi;	/* yuk */
    /* read the file into the buffer and append it to store */
    buf = memAllocate(MEM_4K_BUF);
    while ((n = FD_READ_METHOD(fd, buf, 4096)) > 0)
	storeAppend(e, buf, n);
    file_close(fd);
    storeBufferFlush(e);
    storeComplete(e);
    storeTimestampsSet(e);
    debug(25, 3) ("Loaded icon %s\n", url);
    storeUnlockObject(e);
    memFree(buf, MEM_4K_BUF);
}
Esempio n. 15
0
static void
netdbReloadState(void)
{
    char *buf;
    char *t;
    char *s;
    int fd;
    int l;
    struct stat sb;
    netdbEntry *n;
    netdbEntry N;
    struct in_addr addr;
    int count = 0;
    struct timeval start = current_time;

    if (strcmp(Config.netdbFilename, "none") == 0)
        return;

    /*
     * This was nicer when we were using stdio, but thanks to
     * Solaris bugs, its a bad idea.  fopen can fail if more than
     * 256 FDs are open.
     */
    fd = file_open(Config.netdbFilename, O_RDONLY | O_BINARY);
    if (fd < 0)
        return;
    if (fstat(fd, &sb) < 0) {
        file_close(fd);
        return;
    }
    t = buf = xcalloc(1, (size_t) sb.st_size + 1);
    l = FD_READ_METHOD(fd, buf, (int) sb.st_size);
    file_close(fd);
    if (l <= 0)
        return;
    while ((s = strchr(t, '\n'))) {
        char *q;
        assert(s - buf < l);
        *s = '\0';
        memset(&N, '\0', sizeof(netdbEntry));
        q = strtok(t, w_space);
        t = s + 1;
        if (NULL == q)
            continue;
        if (!safe_inet_addr(q, &addr))
            continue;
        if (netdbLookupAddr(addr) != NULL)	/* no dups! */
            continue;
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.pings_sent = atoi(q);
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.pings_recv = atoi(q);
        if (N.pings_recv == 0)
            continue;
        /* give this measurement low weight */
        N.pings_sent = 1;
        N.pings_recv = 1;
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.hops = atof(q);
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.rtt = atof(q);
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.next_ping_time = (time_t) atoi(q);
        if ((q = strtok(NULL, w_space)) == NULL)
            continue;
        N.last_use_time = (time_t) atoi(q);
        n = memAllocate(MEM_NETDBENTRY);
        xmemcpy(n, &N, sizeof(netdbEntry));
        netdbHashInsert(n, addr);
        while ((q = strtok(NULL, w_space)) != NULL) {
            if (netdbLookupHost(q) != NULL)	/* no dups! */
                continue;
            netdbHostInsert(n, q);
        }
        count++;
    }
    xfree(buf);
    getCurrentTime();
    debug(38, 1) ("NETDB state reloaded; %d entries, %d msec\n",
                  count, tvSubMsec(start, current_time));
}