Пример #1
0
/* retrieval of a single record (present, and piggy back search) */
static int my_fetch(void *handle, bend_fetch_rr *r)
{
    const Odr_oid *oid = r->request_format;

    r->last_in_set = 0;
    r->basename = "Default";
    r->output_format = r->request_format;

    /* if no record syntax was given assume XML */
    if (!oid || !oid_oidcmp(oid, yaz_oid_recsyn_xml))
    {
        char buf[40];
        yaz_snprintf(buf, sizeof(buf), "<record>%d</record>\n", r->number);

        r->output_format = odr_oiddup(r->stream, yaz_oid_recsyn_xml);
        r->record = odr_strdup(r->stream, buf);
        r->len = strlen(r->record);
    }
    else
    {   /* only xml syntax supported . Return diagnostic */
        char buf[OID_STR_MAX];
        r->errcode = YAZ_BIB1_RECORD_SYNTAX_UNSUPP;
        r->errstring = odr_strdup(r->stream, oid_oid_to_dotstring(oid, buf));
    }
    return 0;
}
Пример #2
0
static void yaz_panic_sig_handler(int sig)
{
    char buf[512];
    FILE *file;

    signal(SIGABRT, SIG_DFL);
    signal(SIGSEGV, SIG_DFL);
    signal(SIGFPE, SIG_DFL);
    signal(SIGBUS, SIG_DFL);
    strcpy(buf, "\nYAZ panic received ");
    switch (sig)
    {
    case SIGSEGV:
        strcat(buf, "SIGSEGV");
        break;
    case SIGABRT:
        strcat(buf, "SIGABRT");
        break;
    case SIGFPE:
        strcat(buf, "SIGFPE");
        break;
    case SIGBUS:
        strcat(buf, "SIGBUS");
        break;
    default:
        yaz_snprintf(buf + strlen(buf), sizeof buf, "signo=%d", sig);
        break;
    }
    yaz_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf) - 1,
                 " PID=" NMEM_INT_PRINTF "\n", (nmem_int_t) getpid());

    file = yaz_log_file();
    /* static variable to be used in the following + handlers */
    yaz_panic_fd = fileno(file);

    write(yaz_panic_fd, buf, strlen(buf));
    yaz_invoke_backtrace(sig);
    yaz_invoke_gdb();
    kill(getpid(), sig);
}
Пример #3
0
static void http_error(struct http_channel *hc, int no, const char *msg)
{
    struct http_response *rs = http_create_response(hc);

    hc->response = rs;
    hc->keep_alive = 0;  // not keeping this HTTP session alive

    sprintf(rs->code, "%d", no);

    rs->msg = nmem_strdup(hc->nmem, msg);
    rs->payload = nmem_malloc(hc->nmem, 100);
    yaz_snprintf(rs->payload, 99, "<error>HTTP Error %d: %s</error>\n",
                 no, msg);
    http_send_response(hc);
}
Пример #4
0
char *oid_oid_to_dotstring(const Odr_oid *oid, char *oidbuf)
{
    char tmpbuf[20];
    int i;

    oidbuf[0] = '\0';
    for (i = 0; oid[i] != -1 && i < OID_SIZE; i++)
    {
        yaz_snprintf(tmpbuf, sizeof(tmpbuf)-1, "%d", oid[i]);
        if (i > 0)
            strcat(oidbuf, ".");
        strcat(oidbuf, tmpbuf);
    }
    return oidbuf;
}
Пример #5
0
static void write_pidfile(int pid_fd)
{
    if (pid_fd != -1)
    {
        char buf[40];
        yaz_snprintf(buf, sizeof(buf), "%ld", (long) getpid());
        if (ftruncate(pid_fd, 0))
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "ftruncate");
            exit(1);
        }
        if (write(pid_fd, buf, strlen(buf)) != strlen(buf))
        {
            yaz_log(YLOG_FATAL|YLOG_ERRNO, "write");
            exit(1);
        }
        close(pid_fd);
    }
}
Пример #6
0
static int http_proxy(struct http_request *rq)
{
    struct http_channel *c = rq->channel;
    struct http_proxy *p = c->proxy;
    struct http_header *hp;
    struct http_buf *requestbuf;
    char server_port[16] = "";
    struct conf_server *ser = c->server;

    if (!p) // This is a new connection. Create a proxy channel
    {
        int sock;
        struct protoent *pe;
        int one = 1;

        if (!(pe = getprotobyname("tcp"))) {
            abort();
        }
        if ((sock = socket(PF_INET, SOCK_STREAM, pe->p_proto)) < 0)
        {
            yaz_log(YLOG_WARN|YLOG_ERRNO, "socket");
            return -1;
        }
        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)
                        &one, sizeof(one)) < 0)
            abort();
        enable_nonblock(sock);
        if (connect(sock, (struct sockaddr *)
                    c->server->http_server->proxy_addr, 
                    sizeof(*c->server->http_server->proxy_addr)) < 0)
        {
            if (!is_inprogress()) 
            {
                yaz_log(YLOG_WARN|YLOG_ERRNO, "Proxy connect");
                return -1;
            }
        }
        p = xmalloc(sizeof(struct http_proxy));
        p->oqueue = 0;
        p->channel = c;
        p->first_response = 1;
        c->proxy = p;
        // We will add EVENT_OUTPUT below
        p->iochan = iochan_create(sock, proxy_io, EVENT_INPUT, "http_proxy");
        iochan_setdata(p->iochan, p);

        iochan_add(ser->iochan_man, p->iochan);
    }

    // Do _not_ modify Host: header, just checking it's existence

    if (!http_lookup_header(rq->headers, "Host"))
    {
        yaz_log(YLOG_WARN, "Failed to find Host header in proxy");
        return -1;
    }
    
    // Add new header about paraz2 version, host, remote client address, etc.
    {
        char server_via[128];

        hp = rq->headers;
        hp = http_header_append(c, hp, 
                                "X-Pazpar2-Version", PACKAGE_VERSION);
        hp = http_header_append(c, hp, 
                                "X-Pazpar2-Server-Host", ser->host);
        sprintf(server_port, "%d",  ser->port);
        hp = http_header_append(c, hp, 
                                "X-Pazpar2-Server-Port", server_port);
        yaz_snprintf(server_via, sizeof(server_via), 
                     "1.1 %s:%s (%s/%s)",  
                     ser->host ? ser->host : "@",
                     server_port, PACKAGE_NAME, PACKAGE_VERSION);
        hp = http_header_append(c, hp, "Via" , server_via);
        hp = http_header_append(c, hp, "X-Forwarded-For", c->addr);
    }
    
    requestbuf = http_serialize_request(rq);

    http_buf_enqueue(&p->oqueue, requestbuf);
    iochan_setflag(p->iochan, EVENT_OUTPUT);
    return 0;
}