#include "repmgr.h" #include "../xmlapi/xmlcgi.h" XML * cgi; XML * env; XML * query; XML * headers; /* TODO: in case I decide to build a general CGI framework, this would be useful. */ XML * retval = NULL; See Global variable definitions int handle_error (const char * message); int main(int argc, char* argv[]) { cgi = xmlcgi_init(); env = xml_loc (cgi, ".environment"); query = xml_loc (cgi, ".query"); xml_set (cgi, "mimetype", "text/html"); See Opening the repository definition See Authenticating the user See Figuring out what to do if (*xml_attrval (cgi, "redirect")) printf ("Location: %s\n", xml_attrval (cgi, "redirect")); printf ("Content-type: %s\n\n", xml_attrval (cgi, "mimetype")); if (retval) { xml_writehtml (stdout, retval); printf ("\n\n"); } else { printf ("<h2>No result from script</h2><hr>No result was returned from this script.\n"); /* TODO: configuration value. */ } printf ("<br><br><hr width=30%%><font size=-1 color=gray><center>Site managed brilliantly with <a href=http://www.vivtek.com/wftk/doc/code/repmgr/repmgr_cgi.html>repmgr CGI front end</a></center></font>\n\n"); xml_free (cgi); return 0; } See Handling error display |
FILE * file; XML * repos = NULL; XML * list; XML * layout; XML * form; XML * defn; XML * obj; XML * holder; XML * mark; const char * username; const char * mode; XML * action; |
file = fopen ("site.opm", "r");
if (!file) {
return handle_error ("No site definition file was found. Please notify the site administrator.");
}
repos = xml_read (file);
if (!repos) {
return handle_error ("The site definition file is corrupt. Please notify the site administrator.");
}
repos_open (repos, NULL, "cgi");
|
username = xml_attrval (env, "REMOTE_USER");
list = repos_defn (repos, "_users");
if (list) {
/* Here's where we'll do repmgr-local user authentication. TODO: do it. */
}
|
| Mode | Meth | Action |
| new | GET | Presents blank HTML form for adding an object |
| add | POST | Adds an object from said blank form |
| edit | GET | Presents a filled HTML form for editing an object |
| copy | GET | Presents a filled HTML form for copying an object |
| mod | POST | Edits an existing object using form input |
| del | POST | Deletes an object |
| list | GET | Lists keys from a given list |
| info | GET | Gets installation information or a set editor home page. |
| attach | POST | Uploads file attachment |
| retrieve | GET | Downloads file attachment |
| checkout | POST? | Downloads for modification (i.e. locks the attachment) |
| search? | GET | Search objects -- I've got some pretty detailed plans for searching |
mode = xml_attrval (query, "mode");
if (!*mode) mode = "info";
repos_log (repos, 5, 0, NULL, "CGI", "Call with mode %s", mode);
if (!strcmp (mode, "new")) {
See Displaying a blank form
} else if (!strcmp (mode, "add")) {
See Adding an object from form input
} else if (!strcmp (mode, "edit")) {
See Displaying a filled form for edit
} else if (!strcmp (mode, "copy")) {
See Displaying a filled form for adding
} else if (!strcmp (mode, "mod")) {
See Updating object content from form input
} else if (!strcmp (mode, "del")) {
See Deleting an object
} else if (!strcmp (mode, "list")) {
See Listing the members of a list
} else {
xml_setf (cgi, "error", "Mode '%s' not supported.\n", mode);
return handle_error (xml_attrval (cgi, "error"));
}
|
if (!*xml_attrval (query, "list")) { return handle_error ("No list specified in 'new' mode."); }
form = repos_form (repos, xml_attrval (query, "list"), NULL, "new");
if (!form) {
xml_setf (env, "error", "List '%s' is not defined in the system.", xml_attrval (query, "list"));
handle_error (xml_attrval (env, "error"));
}
/* Build form for output. */
retval = xml_create ("form");
xml_setf (retval, "action", "repmgr.cgi?mode=add&list=%s", xml_attrval (query, "list")); /* TODO: parametrize the URL */
xml_set (retval, "method", "POST");
if (xml_search (form, "input", "type", "file")) xml_set (retval, "enctype", "multipart/form-data");
xml_append_pretty (retval, form);
if (!xml_search (form, "input", "type", "submit")) {
form = xml_create ("input");
xml_set (form, "type", "submit");
xml_set (form, "value", "Add object"); /* TODO: decorate with label of object. */
xml_append_pretty (retval, xml_create ("br"));
xml_append_pretty (retval, form);
}
|
if (!*xml_attrval (query, "list")) { return handle_error ("No list specified in 'edit' mode."); }
if (!*xml_attrval (query, "key")) { return handle_error ("No key specified in 'edit' mode."); }
form = repos_form (repos, xml_attrval (query, "list"), xml_attrval (query, "key"), "edit");
if (!form) {
xml_setf (env, "error", "Key '%s' in list '%s' can't be found.", xml_attrval (query, "key"), xml_attrval (query, "list"));
handle_error (xml_attrval (env, "error"));
}
/* Build form for output. */
retval = xml_create ("form");
xml_setf (retval, "action", "repmgr.cgi?mode=mod&list=%s&key=%s", xml_attrval (query, "list"), xml_attrval (query, "key")); /* TODO: parametrize. */
xml_set (retval, "method", "POST");
xml_append_pretty (retval, form);
if (xml_search (form, "input", "type", "file")) xml_set (retval, "enctype", "multipart/form-data");
if (!xml_search (form, "input", "type", "submit")) {
form = xml_create ("input");
xml_set (form, "type", "submit");
xml_set (form, "value", "Modify object"); /* TODO: decorate with label of object. */
xml_append_pretty (retval, xml_create ("br"));
xml_append_pretty (retval, form);
}
|
if (!*xml_attrval (query, "list")) { return handle_error ("No list specified in 'copy' mode."); }
if (!*xml_attrval (query, "key")) { return handle_error ("No key specified in 'copy' mode."); }
form = repos_form (repos, xml_attrval (query, "list"), xml_attrval (query, "key"), "edit");
if (!form) {
xml_setf (env, "error", "Key '%s' in list '%s' can't be found.", xml_attrval (query, "key"), xml_attrval (query, "list"));
handle_error (xml_attrval (env, "error"));
}
/* Build form for output. */
retval = xml_create ("form");
xml_setf (retval, "action", "repmgr.cgi?mode=add&list=%s", xml_attrval (query, "list")); /* TODO: parametrize the URL */
xml_set (retval, "method", "POST");
xml_append_pretty (retval, form);
if (xml_search (form, "input", "type", "file")) xml_set (retval, "enctype", "multipart/form-data");
if (!xml_search (form, "input", "type", "submit")) {
form = xml_create ("input");
xml_set (form, "type", "submit");
xml_set (form, "value", "Add object"); /* TODO: decorate with label of object. */
xml_append_pretty (retval, xml_create ("br"));
xml_append_pretty (retval, form);
}
|
if (!*xml_attrval (query, "list")) { return handle_error ("No list specified in 'add' mode."); }
defn = repos_defn (repos, xml_attrval (query, "list"));
if (!defn) {
xml_setf (cgi, "error", "List '%s' undefined.", xml_attrval (query, "list"));
return (handle_error (xml_attrval (cgi, "error")));
}
obj = xmlcgi_readstdin (cgi, defn);
repos_add (repos, xml_attrval (query, "list"), obj);
mark = xml_search (repos, "page", "displays", xml_attrval (query, "list"));
if (mark) {
xml_set (cgi, "redirect", xml_attrval (mark, "page"));
} else {
xml_setf (cgi, "redirect", "repmgr.cgi?mode=list&list=%s", xml_attrval (query, "list"));
}
retval = xml_parse ("<h2>Change made</h2>Your addition was made. The server should redirect you to the main list page.");
|
if (!*xml_attrval (query, "list")) { return handle_error ("No list specified in 'add' mode."); }
defn = repos_defn (repos, xml_attrval (query, "list"));
if (!defn) {
xml_setf (cgi, "error", "List '%s' undefined.", xml_attrval (query, "list"));
return (handle_error (xml_attrval (cgi, "error")));
}
obj = xmlcgi_readstdin (cgi, defn);
action = xml_search (obj, "field", "id", "_action");
if (action) {
for (mark = xml_firstelem (action); mark; mark = xml_nextelem (mark)) {
repos_log (repos, 6, 0, NULL, "CGI", "Action code %s", xml_attrval (mark, "id"));
if (!strncmp (xml_attrval (mark, "id"), "state-", 6)) xmlobj_set (obj, defn, "state", xml_attrval (mark, "id") + 6);
}
}
repos_merge (repos, xml_attrval (query, "list"), obj, xml_attrval (query, "key"));
mark = xml_search (repos, "page", "displays", xml_attrval (query, "list"));
if (mark) {
xml_set (cgi, "redirect", xml_attrval (mark, "page"));
} else {
xml_setf (cgi, "redirect", "repmgr.cgi?mode=list&list=%s", xml_attrval (query, "list"));
}
retval = xml_parse ("<h2>Change made</h2>Your modification was made. The server should redirect you to the main list page.");
|
defn = repos_defn (repos, xml_attrval (query, "list"));
if (!defn) {
xml_setf (cgi, "error", "List '%s' undefined.", xml_attrval (query, "list"));
return (handle_error (xml_attrval (cgi, "error")));
}
list = xml_create ("list");
xml_set (list, "id", xml_attrval (query, "list"));
repos_list (repos, list);
|
int handle_error (const char * message) {
printf ("Content-type: text/html\n\n");
printf ("<html><head><title>Error</title></head>\n");
printf ("<body><h2>Error</h2><hr>%s</body></html>\n", message);
return 0;
}
|
| This code and documentation are released under the terms of the GNU license. They are copyright (c) 2002-2004, Vivtek. All rights reserved except those explicitly granted under the terms of the GNU license. This presentation was prepared with LPML. Try literate programming. You'll like it. |