/* * Copyright (c) by Allin Cottrell * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* server.c : main for gretl database server */ #include #include #include #include "server.h" #include "cgi.h" #if SDEBUG FILE *fdb; #endif #define MAXLEN 48 #define MAXENTRIES 8 enum cgi_options { LIST_DBS = 1, GRAB_IDX, GRAB_DATA, SHOW_IDX, SHOW_DBS, GRAB_NBO_DATA, LIST_FUNCS, SHOW_FUNCS, GRAB_FUNC_INFO, GRAB_FUNC, CHECK_DB, UPLOAD }; #if SDEBUG static const char *opt_string (int opt) { if (opt == LIST_DBS) return "LIST_DBS"; if (opt == GRAB_IDX) return "LIST_DBS"; if (opt == GRAB_DATA) return "LIST_DBS"; if (opt == SHOW_IDX) return "LIST_DBS"; if (opt == SHOW_DBS) return "LIST_DBS"; if (opt == GRAB_NBO_DATA) return "LIST_DBS"; if (opt == LIST_FUNCS) return "LIST_FUNCS"; if (opt == SHOW_FUNCS) return "SHOW_FUNCS"; if (opt == GRAB_FUNC_INFO) return "GRAB_FUNC_INFO"; if (opt == GRAB_FUNC) return "GRAB_FUNC"; if (opt == UPLOAD) return "UPLOAD"; if (opt == CHECK_DB) return "CHECK_DB"; return "unknown"; } #endif static void move_to_invalid (const char *fullname) { char iname[128] = "fnfiles/invalid"; const char *p = strrchr(fullname, '/'); if (p != NULL) { strncat(iname, p, 128 - strlen(iname) - 1); rename(fullname, iname); } else { remove(fullname); } } static int login_ok (const char *login, const char *pass) { char line[64]; char s1[32], s2[16]; FILE *fp; int ok = 0; fp = fopen("admin/passwd", "r"); if (fp == NULL) { return 0; } while (fgets(line, sizeof line, fp)) { if (sscanf(line, "%31s %15s", s1, s2)) { if (!strcmp(s1, login) && !strcmp(s2, pass)) { ok = 1; break; } } } fclose(fp); return ok; } static void html_start (char *dbase) { puts(""); printf("%s\n", dbase); puts("\n"); } static void html_stop (void) { puts("\n"); puts(""); } static int parse_opt (const char *s) { if (!strcmp(s, "LIST_DBS")) return LIST_DBS; if (!strcmp(s, "GRAB_IDX")) return GRAB_IDX; if (!strcmp(s, "SHOW_IDX")) return SHOW_IDX; if (!strcmp(s, "SHOW_DBS")) return SHOW_DBS; if (!strcmp(s, "GRAB_DATA")) return GRAB_DATA; if (!strcmp(s, "GRAB_NBO_DATA")) return GRAB_NBO_DATA; if (!strcmp(s, "LIST_FUNCS")) return LIST_FUNCS; if (!strcmp(s, "SHOW_FUNCS")) return SHOW_FUNCS; if (!strcmp(s, "GRAB_FUNC_INFO")) return GRAB_FUNC_INFO; if (!strcmp(s, "GRAB_FUNC")) return GRAB_FUNC; if (!strcmp(s, "UPLOAD")) return UPLOAD; if (!strcmp(s, "CHECK_DB")) return CHECK_DB; return 0; } static int handle_file_upload (char *login, char *pass, char *fname, char *buf) { char fullname[128]; FILE *fp; int err = 0; #if SDEBUG char passdots[32]; int i, n = strlen(pass); for (i=0; iname, "opt")) { opt = parse_opt(entry->val); } else if (!strcmp(entry->name, "opt")) { opt = parse_opt(entry->val); } else if (!strcmp(entry->name, "fname")) { strcpy(fname, entry->val); } else if (!strcmp(entry->name, "dbase")) { strcpy(fname, entry->val); if (*fname) { strcat(fname, ".gz"); } } else if (!strcmp(entry->name, "series")) { strcpy(series, entry->val); } else if (!strcmp(entry->name, "login")) { strcpy(login, entry->val); } else if (!strcmp(entry->name, "pass")) { strcpy(pass, entry->val); } else if (!strcmp(entry->name, "content")) { buf = entry->val; } entry = entry->next; } if (buf != NULL) { #if SDEBUG > 1 fprintf(fdb, "got buf, length %d\n", strlen(buf)); #endif content_line(TEXT); handle_file_upload(login, pass, fname, buf); } if (List != NULL) { cgi_destroy_list(List); } return opt; } static int cgi_get_wfu_client (void) { char *client_ip = getenv("REMOTE_ADDR"); int wfu = 0; if (client_ip != NULL) { if (!strncmp(client_ip, "152.17", 6) || !strncmp(client_ip, "10.112", 6)) { wfu = 1; } } return wfu; } static int cgi_get_client_version (void) { char *agent = getenv("HTTP_USER_AGENT"); int version = 0; if (agent != NULL && !strncmp(agent, "gretl-", 6)) { char tmp[8]; *tmp = 0; strncat(tmp, agent + 6, 7); version = atoi(delchar('.', tmp)); } return version; } void content_line (int conttype) { fputs("Content-type: ", stdout); /* note: put only one newline if we're going to append a content length field (XML, GZ) */ switch (conttype) { case TEXT: printf("text/plain\n\n"); break; case HTML: printf("text/html\n\n"); break; case XML: printf("text/xml\n"); break; case BIN: printf("application/octet-stream\n\n"); break; case GZ: printf("application/x-gzip-compressed\n"); break; default: break; } } int main (void) { int opt, client_version; int wfu_client; char fname[MAXLEN], series[MAXLEN]; char *listbuf; #if SDEBUG fdb = fopen("server.log", "a"); #endif fname[0] = series[0] = 0; opt = cgi_get_task(fname, series); if (opt == UPLOAD) { #if SDEBUG fputs("ending upload transaction\n", fdb); fclose(fdb); #endif return 0; } client_version = cgi_get_client_version(); wfu_client = cgi_get_wfu_client(); #if SDEBUG fprintf(fdb, "opt=%s, client_version=%d, wfu_client=%d\n", opt_string(opt), client_version, wfu_client); #endif if (opt != LIST_DBS && opt != SHOW_DBS && opt != LIST_FUNCS && opt != SHOW_FUNCS && *fname == '\0') { content_line(TEXT); printf("No filename was supplied\n"); exit(EXIT_FAILURE); } switch (opt) { case 0: /* no option given */ break; case LIST_DBS: content_line(TEXT); list_files(&listbuf, 0, 0, client_version, wfu_client); break; case SHOW_DBS: content_line(HTML); list_files(&listbuf, 1, 0, client_version, wfu_client); break; case CHECK_DB: content_line(TEXT); check_for_db_file(fname); break; case GRAB_IDX: ggz_stream_file(fname, TEXT, client_version); break; case SHOW_IDX: content_line(HTML); html_start(fname); printf("
\n");
	ggz_stream_file(fname, HTML, client_version);
	printf("
\n"); html_stop(); break; case GRAB_DATA: if (*series) { content_line(BIN); ggz_stream_series(fname, series, 0); } else { ggz_stream_file(fname, GZ, client_version); } break; case GRAB_NBO_DATA: if (*series) { content_line(BIN); ggz_stream_series(fname, series, 1); } else { content_line(GZ); nbo_send_file(fname); } break; case LIST_FUNCS: content_line(TEXT); list_files(&listbuf, 0, 1, client_version, wfu_client); break; case SHOW_FUNCS: content_line(HTML); list_files(&listbuf, 1, 1, client_version, wfu_client); break; case GRAB_FUNC_INFO: break; case GRAB_FUNC: stream_function_file(fname); break; default: break; } #if SDEBUG fclose(fdb); #endif return 0; }