/* * SPL - The SPL Programming Language * Copyright (C) 2004, 2005 Clifford Wolf * * 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 * * webspl_common.c: Common functions for webspl.c and webspld */ #include #include #include #include #include #include #include #include #include #include #include #include #ifndef USEWIN32API # include #endif #include "spl.h" #include "webspl_common.h" #include "compat.h" void create_dumpdir(const char *basedir) { char *dumpdir; my_asprintf(&dumpdir, "%s/webspl_cache", basedir ? basedir : "."); #ifndef USEWIN32API mkdir(dumpdir, 0700); #else mkdir(dumpdir); #endif free(dumpdir); } void expire_dumpdir(const char *basedir, int timeout, int interval) { char *dumpdir; char *timestamp_file; int dumpdir_len; struct stat statbuf; time_t now = time(0); DIR *dir = 0; my_asprintf(&dumpdir, "%s/webspl_cache", basedir ? basedir : "."); my_asprintf(×tamp_file, "%s/LAST_EXPIRE", dumpdir); dumpdir_len = strlen(dumpdir); #ifdef USEWIN32API if (stat(timestamp_file, &statbuf) || (statbuf.st_mtime+interval < now)) #else if (lstat(timestamp_file, &statbuf) || (statbuf.st_mtime+interval < now)) #endif dir = opendir(dumpdir); if (dir) { struct dirent *ent; while ((ent=readdir(dir)) != NULL) { int filename_len = dumpdir_len + strlen(ent->d_name) + 2; char filename[filename_len]; snprintf(filename, filename_len, "%s/%s", dumpdir, ent->d_name); #ifdef USEWIN32API if (!stat(filename, &statbuf)) { #else if (!lstat(filename, &statbuf)) { #endif if (statbuf.st_mtime+timeout < now) unlink(filename); } } closedir(dir); #ifdef USEWIN32API close(open(timestamp_file, O_WRONLY|O_CREAT, 0666)); #else close(open(timestamp_file, O_WRONLY|O_NONBLOCK|O_CREAT|O_NOCTTY, 0666)); #endif utime(timestamp_file, NULL); } free(timestamp_file); free(dumpdir); } char *get_new_session() { static char sid_chars[]="0123456789abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char ch, *ret = strdup("XXXXXXXXXXXXXXXXXXXXXXXX"); int fd = open("/dev/urandom", O_RDONLY|MY_O_BINARY); for (int i=0; fd>0 && i<20; i++) { if ( read(fd, &ch,1) != 1 ) continue; ret[i] = sid_chars[ch % (sizeof(sid_chars)-1)]; } close(fd); long randat = (getpid()<<16) ^ (getpid()<<24) ^ ~time(0); for (int i=20; i<24; i++) { ret[i] = sid_chars[ randat % (sizeof(sid_chars)-1) ]; randat = randat >> 8; } return ret; } static void cgi_config_read_file(struct cgi_config *cfg, char *configfile, char *scriptpath) { FILE *f = fopen(configfile, "rt"); if (!f) return; int active = 0; char buffer[1024]; while (fgets(buffer, 1024, f) != 0) { if (*buffer == '[') { char *pattern = buffer + strspn(buffer, "[ \r\n\t"); int pattern_len = strcspn(pattern, "] \r\n\t"); pattern[pattern_len] = 0; #if !defined USEWIN32API && !defined USEIRIXAPI active = !fnmatch(pattern, scriptpath, FNM_PATHNAME|FNM_LEADING_DIR); #else // Win32 has no fnmatch() function. -> Never match. active = !strcmp(pattern, scriptpath); #endif } else if (*buffer == '#') { /* nothing to do */ } else if (active) { char *name = buffer + strspn(buffer, " \r\n\t"); int name_len = strcspn(name, "= \r\n\t"); char *value = (name+name_len) + strspn(name+name_len, "= \r\n\t"); int value_len = strcspn(value, "\r\n"); name[name_len] = 0; value[value_len] = 0; for (value_len--; value_len>=0 && (value[value_len] == ' ' || value[value_len] == '\t'); value_len--) value[value_len] = 0; if (*name && *value) { struct cgi_config_item *cfg_item = malloc(sizeof(struct cgi_config_item)); cfg_item->name = strdup(name); cfg_item->value = strdup(value); cfg_item->next = cfg->items; cfg->items = cfg_item; } } } fclose(f); } struct cgi_config *cgi_config_read(char *path) { struct cgi_config *cfg = malloc(sizeof(struct cgi_config)); cfg->items = 0; char *path_start = path; char *path_sep = strchr(path, '/'); while (path_sep) { char configfile[(path_sep - path_start) + 1 + strlen(WEBSPL_CONFIG_NAME)]; memcpy(configfile, path, (path_sep - path_start) + 1); strcpy(configfile + (path_sep - path_start) + 1, WEBSPL_CONFIG_NAME); if (!access(configfile, R_OK)) cgi_config_read_file(cfg, configfile, path_sep + 1); path_sep = strchr(path_sep+1, '/'); } return cfg; } void cgi_config_free(struct cgi_config *cfg) { if (cfg) { struct cgi_config_item *i = cfg->items; while (i) { struct cgi_config_item *n = i->next; free(i->name); free(i->value); free(i); i = n; } free(cfg); } return; }