From 7eab2e67af4a4f96d09f0b574f8c7adf5bf74c39 Mon Sep 17 00:00:00 2001 From: "Svante J. Kvarnstrom" Date: Mon, 22 Oct 2007 21:09:33 +0200 Subject: [PATCH] Initial import --- Makefile | 14 ++++ vhostgen.1 | 24 ++++++ vhostgen.c | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vhostgen.conf | 17 ++++ 4 files changed, 316 insertions(+) create mode 100644 Makefile create mode 100644 vhostgen.1 create mode 100644 vhostgen.c create mode 100644 vhostgen.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c0b4d7f --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -g -O2 +LDFLAGS = -L/usr/local/lib/mysql -lmysqlclient -lz -lm -L/usr/lib -lssl -lcrypto +INCLUDE = -I/usr/local/include/mysql -pipe + +all: vhostgen +vhostgen: vhostgen.o + $(CC) $(CFLAGS) -o vhostgen vhostgen.o $(LDFLAGS) +vhostgen.o: vhostgen.c + $(CC) $(CFLAGS) $(INCLUDE) -c vhostgen.c +clean: + -rm vhostgen.o +distclean: + -rm vhostgen.o vhostgen diff --git a/vhostgen.1 b/vhostgen.1 new file mode 100644 index 0000000..2a4fc03 --- /dev/null +++ b/vhostgen.1 @@ -0,0 +1,24 @@ +.TH VHOSTGEN 1 +.SH NAME +vhostgen - creates apache vhosts.conf using information taken from a mysql database +.SH SYNOPSIS +.B vhostgen +.SH +.PP +vhostgen fetches apache vhost information from a database and creates a vhost +configuration file which can easily be included into the httpd.conf. + +The database has to contain a table, which I chose to name "vhosts" (name +it whatever you want): + +CREATE TABLE `vhosts` ( + `id` int(11) NOT NULL auto_increment, + `servername` varchar(255) NOT NULL, + `serveralias` varchar(255) default NULL, + `documentroot` varchar(255) NOT NULL, + `maintainer` varchar(255) default NULL, + PRIMARY KEY (`id`) +); + +.SH AUTHORS +Svante Kvarnstrom diff --git a/vhostgen.c b/vhostgen.c new file mode 100644 index 0000000..f4e94a2 --- /dev/null +++ b/vhostgen.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2007 Svante Kvarnström + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include +#include + +#include "mysql.h" + +#define CONFIG_FILE "/etc/vhostgen.conf" +#define MAX_BUFF 512 + +struct config_list { + char *username; /* Mysql username */ + char *password; /* Mysql password */ + char *host; /* Mysql hostname */ + char *vhosttable; /* Mysql vhost table */ + char *db; /* Mysql database */ + char *outfile; /* Vhost config file to write */ +}; + +int load_config_file(const char *, struct config_list *); +char *mkdate(void); + +int +main(int argc, char *argv[]) +{ + MYSQL sql_conn; + MYSQL_ROW sqlrow; + MYSQL_RES *res_ptr; + + res_ptr = NULL; + + int res; + char *query; /* Points at a mysql (INSERT/DELETE/SELECT/WHATEVER) query */ + int qlen; /* Length of query string */ + FILE *out; /* File handler for vhost config file (/var/www/conf/vhosts.conf or so) */ + + struct config_list *clist; + clist = malloc(sizeof(struct config_list)); + + /* Populate the clist struct with information taken from CONFIG_FILE */ + /* If we can't open the config file, exit. */ + if (load_config_file(CONFIG_FILE, clist)) { + exit(1); + } + + /* Initialize mysql database connection, select database, etc */ + mysql_init(&sql_conn); + + if (!mysql_real_connect(&sql_conn, clist->host, clist->username, clist->password, clist->db, 0, NULL, 0)) { + if (mysql_errno(&sql_conn)) { + fprintf(stderr, "Connection error %d: %s\n", mysql_errno(&sql_conn), mysql_error(&sql_conn)); + exit(1); + } + } + + /* + * Since mysql_query doesn't support printf's %s/%d/whatever format, we'll + * have to craft the exact SELECT message with snprintf first, and then send + * that to mysql_query. snprintf wants the length of the string, so we start + * of by getting that. + */ + qlen = strlen("SELECT * FROM ") + strlen(clist->vhosttable) + 1; + + /* Next we allocate enough memory for our sql query. */ + query = malloc(sizeof(char) * qlen); + + /* + * And now we put the query into "query" (or well, we put it into memory and + * have query direct us to it :) + */ + snprintf(query, qlen, "SELECT * FROM %s", clist->vhosttable); + + res = mysql_query(&sql_conn, query); + + if (res) + fprintf(stderr, "SELECT error: %s\n", mysql_error(&sql_conn)); + else { + res_ptr = mysql_use_result(&sql_conn); + if (res_ptr) { + /* + * Alright, we've got stuff from the database. Now we need to write it + * to the vhost config file. Let's see if we can open the config file for + * writing. If not we're screwed. + */ + if ((out = fopen(clist->outfile, "w")) == NULL) { + fprintf(stderr, "ERROR: %s could not be opened for writing", clist->outfile); + exit(1); + } + + fprintf(out, "# This file was generated by vhostgen %s.\n" + "# DO NOT EDIT THIS FILE MANUALLY AS ANY CHANGES WILL BE" + " LOST. \n# Make any changes to the database instead.\n \n\n", mkdate()); + + while ((sqlrow = mysql_fetch_row(res_ptr))) { + if (sqlrow[2] && *sqlrow[2] != '\0') + fprintf(out,"# %d - %s (%s), maintained by %s\n", + atoi(sqlrow[0]), sqlrow[1], sqlrow[2], sqlrow[4]); + else + fprintf(out, "\n# %d - %s, maintained by %s\n", + atoi(sqlrow[0]), sqlrow[1], sqlrow[4]); + fprintf(out, "\n\tServerName %s\n", sqlrow[1]); + if (sqlrow[2] && *sqlrow[2] != '\0') + fprintf(out, "\tServerAlias %s\n", sqlrow[2]); + fprintf(out, "\tDocumentRoot %s\n", sqlrow[3]); + fprintf(out, "\n\n"); + } + if (mysql_errno(&sql_conn)) + fprintf(stderr, "Retrieve error: %s\n", mysql_error(&sql_conn)); + } + } + + mysql_free_result(res_ptr); + return(0); +} + +int +load_config_file(const char *file_name, struct config_list *clist) +{ + FILE *fp; + char line[MAX_BUFF]; + char *argv[MAX_BUFF]; + int argc; + char *p; + char *q; + + if ((fp = fopen(file_name, "r")) == NULL) { + fprintf(stderr, "Couldn't open configuration file %s\n", file_name); + return 1; + } + + while (fgets(line, sizeof(line), fp)) { + if (line[0] == '#') /* Ignore comments */ + continue; + + if ((p = strchr(line, '\n')) != NULL) /* Got huge line, ignore it. */ + *p = '\0'; + + if (*line == '\0') + continue; + + p = line; + argc = 0; + + for (q = strchr(p, ':'); q; q = strchr(p, ':')) { + argv[argc++] = p; + *q = '\0'; + p = q+1; + } + + argv[argc++] = p; + + switch(argv[0][0]) { + case 'u': + clist->username = malloc(strlen(argv[1]) + 1); + if (clist->username == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->username, argv[1], strlen(argv[1]) + 1); + break; + case 'p': + clist->password = malloc(strlen(argv[1]) + 1); + if (clist->password == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->password, argv[1], strlen(argv[1]) + 1); + break; + case 'o': + clist->outfile = malloc(strlen(argv[1]) + 1); + + if (clist->outfile == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->outfile, argv[1], strlen(argv[1]) + 1); + break; + case 'h': + clist->host = malloc(strlen(argv[1]) + 1); + + if (clist->host == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->host, argv[1], strlen(argv[1]) + 1); + break; + case 'd': + clist->db = malloc(strlen(argv[1]) + 1); + + if (clist->db == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->db, argv[1], strlen(argv[1]) + 1); + break; + case 't': + clist->vhosttable = malloc(strlen(argv[1]) + 1); + + if (clist->vhosttable == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(clist->vhosttable, argv[1], strlen(argv[1]) + 1); + break; + } + } + + return 0; +} + +/* + * This function returns a pointer to a malloced string containing the current + * date, month, date, hour, minute and second in format + * YYYY-MM-DD HH:SS UTC(+/-)HH. + */ +char +*mkdate(void) +{ + struct tm *tm_ptr; + time_t the_time; + char buf[256]; + char *our_date; + + (void) time(&the_time); + tm_ptr = gmtime(&the_time); + + strftime(buf, sizeof(buf), "%y-%m-%d %H:%M UTC%z", tm_ptr); + + our_date = malloc(strlen(buf) + 1); + + if (our_date == NULL) { + printf("ERROR: Couldn't allocate memory\n"); + exit(1); + } + + strlcpy(our_date, buf, strlen(buf) + 1); + + return our_date; +} diff --git a/vhostgen.conf b/vhostgen.conf new file mode 100644 index 0000000..0d24bba --- /dev/null +++ b/vhostgen.conf @@ -0,0 +1,17 @@ +#username +u:user + +#password +p:password + +#hostname +h:localhost + +#database +d:httpdconf + +#table with vhosts +t:vhosts + +#file to write +o:/var/www/conf/vhosts.conf -- 2.11.4.GIT