2 * Copyright (c) 2007 Svante Kvarnström <sjk@ankeborg.nu>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 char *username
; /* Mysql username */
29 char *password
; /* Mysql password */
30 char *host
; /* Mysql hostname */
31 char *vhosttable
; /* Mysql vhost table */
32 char *db
; /* Mysql database */
33 char *outfile
; /* Vhost config file to write */
34 char *logpath
; /* basepath for logfiles */
37 int load_config_file(const char *, struct config_list
*);
41 main(int argc
, char *argv
[])
50 char *query
; /* Points at a mysql (INSERT/DELETE/SELECT/WHATEVER) query */
51 int qlen
; /* Length of query string */
52 FILE *out
; /* File handler for vhost config file (/var/www/conf/vhosts.conf or so) */
54 struct config_list
*clist
;
55 clist
= malloc(sizeof(struct config_list
));
57 /* Populate the clist struct with information taken from CONFIG_FILE */
58 /* If we can't open the config file, exit. */
59 if (load_config_file(CONFIG_FILE
, clist
)) {
63 /* Initialize mysql database connection, select database, etc */
64 mysql_init(&sql_conn
);
66 if (!mysql_real_connect(&sql_conn
, clist
->host
, clist
->username
, clist
->password
, clist
->db
, 0, NULL
, 0)) {
67 if (mysql_errno(&sql_conn
)) {
68 fprintf(stderr
, "Connection error %d: %s\n", mysql_errno(&sql_conn
), mysql_error(&sql_conn
));
74 * Since mysql_query doesn't support printf's %s/%d/whatever format, we'll
75 * have to craft the exact SELECT message with snprintf first, and then send
76 * that to mysql_query. snprintf wants the length of the string, so we start
79 qlen
= strlen("SELECT * FROM ") + strlen(clist
->vhosttable
) + 1;
81 /* Next we allocate enough memory for our sql query. */
82 query
= malloc(sizeof(char) * qlen
);
85 * And now we put the query into "query" (or well, we put it into memory and
86 * have query direct us to it :)
88 snprintf(query
, qlen
, "SELECT * FROM %s", clist
->vhosttable
);
90 res
= mysql_query(&sql_conn
, query
);
93 fprintf(stderr
, "SELECT error: %s\n", mysql_error(&sql_conn
));
95 res_ptr
= mysql_use_result(&sql_conn
);
98 * Alright, we've got stuff from the database. Now we need to write it
99 * to the vhost config file. Let's see if we can open the config file for
100 * writing. If not we're screwed.
102 if ((out
= fopen(clist
->outfile
, "w")) == NULL
) {
103 fprintf(stderr
, "ERROR: %s could not be opened for writing\n", clist
->outfile
);
107 fprintf(out
, "# This file was generated by vhostgen %s.\n"
108 "# DO NOT EDIT THIS FILE MANUALLY AS ANY CHANGES WILL BE"
109 " LOST. \n# Make any changes to the database instead.\n \n\n", mkdate());
111 while ((sqlrow
= mysql_fetch_row(res_ptr
))) {
112 if (sqlrow
[2] && *sqlrow
[2] != '\0')
113 fprintf(out
,"# %d - %s (%s), maintained by %s\n",
114 atoi(sqlrow
[0]), sqlrow
[1], sqlrow
[2], sqlrow
[4]);
116 fprintf(out
, "\n# %d - %s, maintained by %s\n",
117 atoi(sqlrow
[0]), sqlrow
[1], sqlrow
[4]);
118 fprintf(out
, "<VirtualHost *>\n\tServerName %s\n", sqlrow
[1]);
119 if (sqlrow
[2] && *sqlrow
[2] != '\0')
120 fprintf(out
, "\tServerAlias %s\n", sqlrow
[2]);
121 fprintf(out
, "\tDocumentRoot %s\n", sqlrow
[3]);
122 fprintf(out
, "\tCustomLog %s%s.log combined\n", clist
->logpath
, sqlrow
[1]);
123 fprintf(out
, "\tErrorLog %s%s.error.log\n", clist
->logpath
, sqlrow
[1]);
125 if (sqlrow
[5] && *sqlrow
[5] != '\0' && sqlrow
[6] && sqlrow
[6] != '\0')
126 fprintf(out
, "\tsuPHP_UserGroup %s %s\n", sqlrow
[5], sqlrow
[6]);
128 fprintf(out
, "</VirtualHost>\n\n");
130 if (mysql_errno(&sql_conn
))
131 fprintf(stderr
, "Retrieve error: %s\n", mysql_error(&sql_conn
));
135 mysql_free_result(res_ptr
);
140 chk_alloc_mem(char **dest
, char *from
)
142 /* strip trailing \n */
143 int length
= strlen(from
) - 1;
144 *dest
= malloc(length
);
146 printf("ERROR: Couldn't allocate memory\n");
149 strncpy(*dest
, from
, length
);
150 (*dest
)[length
] = '\0';
154 load_config_file(const char *file_name
, struct config_list
*clist
)
161 if ((fp
= fopen(file_name
, "r")) == NULL
) {
162 fprintf(stderr
, "Couldn't open configuration file %s\n", file_name
);
166 while (fgets(line
, sizeof(line
), fp
)) {
167 if (line
[0] == '#') /* Ignore comments */
170 if (strchr(line
, '\n') == NULL
) { /* Got huge line, ignore it. */
171 fprintf(stderr
, "Got huge config line. This can't be right, please "
172 "fix your config.\n");
176 if (*line
== '\0' || *line
== '\n')
179 if (line
[1] == ':') {
183 fprintf(stderr
, "Invalid line in config file:\n%s", line
);
187 chk_alloc_mem(&clist
->username
, value
);
190 chk_alloc_mem(&clist
->password
, value
);
193 chk_alloc_mem(&clist
->outfile
, value
);
196 chk_alloc_mem(&clist
->host
, value
);
199 chk_alloc_mem(&clist
->db
, value
);
202 chk_alloc_mem(&clist
->vhosttable
, value
);
205 chk_alloc_mem(&clist
->logpath
, value
);
208 fprintf(stderr
, "Invalid option '%c' given.\n", option
);
218 * This function returns a pointer to a malloced string containing the current
219 * date, month, date, hour, minute and second in format
220 * YYYY-MM-DD HH:SS UTC(+/-)HH.
230 (void) time(&the_time
);
231 tm_ptr
= gmtime(&the_time
);
233 strftime(buf
, sizeof(buf
), "%y-%m-%d %H:%M UTC%z", tm_ptr
);
235 our_date
= malloc(strlen(buf
) + 1);
237 if (our_date
== NULL
) {
238 printf("ERROR: Couldn't allocate memory\n");
242 strcpy(our_date
, buf
);