#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. |