/* 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; }
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); }
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); }
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; }
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); } }
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; }