Binary file htdocs/images/screenshots/tabbed.gif has changed
Binary file htdocs/images/screenshots/tabbed_t.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/aim/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/aim/activebuddy.gif has changed
Binary file htdocs/images/statusicons/aim/admin.gif has changed
Binary file htdocs/images/statusicons/aim/aol.gif has changed
Binary file htdocs/images/statusicons/aim/away.gif has changed
Binary file htdocs/images/statusicons/aim/confirmed.gif has changed
Binary file htdocs/images/statusicons/aim/offline.gif has changed
Binary file htdocs/images/statusicons/aim/unconfirmed.gif has changed
Binary file htdocs/images/statusicons/aim/wireless.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/gg/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/gg/away.gif has changed
Binary file htdocs/images/statusicons/gg/busy.gif has changed
Binary file htdocs/images/statusicons/gg/invisible.gif has changed
Binary file htdocs/images/statusicons/gg/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/icq/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/icq/away.gif has changed
Binary file htdocs/images/statusicons/icq/dnd.gif has changed
Binary file htdocs/images/statusicons/icq/ffc.gif has changed
Binary file htdocs/images/statusicons/icq/na.gif has changed
Binary file htdocs/images/statusicons/icq/occ.gif has changed
Binary file htdocs/images/statusicons/icq/offline.gif has changed
Binary file htdocs/images/statusicons/icq/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/irc/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/irc/offline.gif has changed
Binary file htdocs/images/statusicons/irc/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/jabber/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/jabber/available.gif has changed
Binary file htdocs/images/statusicons/jabber/away.gif has changed
Binary file htdocs/images/statusicons/jabber/chat.gif has changed
Binary file htdocs/images/statusicons/jabber/dnd.gif has changed
Binary file htdocs/images/statusicons/jabber/error.gif has changed
Binary file htdocs/images/statusicons/jabber/offline.gif has changed
Binary file htdocs/images/statusicons/jabber/xa.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/msn/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/msn/away.gif has changed
Binary file htdocs/images/statusicons/msn/occupied.gif has changed
Binary file htdocs/images/statusicons/msn/offline.gif has changed
Binary file htdocs/images/statusicons/msn/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/napster/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/napster/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/images/statusicons/yahoo/.cvsignore Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,1 @@
Binary file htdocs/images/statusicons/yahoo/away.gif has changed
Binary file htdocs/images/statusicons/yahoo/game.gif has changed
Binary file htdocs/images/statusicons/yahoo/idle.gif has changed
Binary file htdocs/images/statusicons/yahoo/offline.gif has changed
Binary file htdocs/images/statusicons/yahoo/online.gif has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/oldplugins/misc/grumpy.c Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,121 @@
+// grumpy.c -- inspired by the spell-check plugin, but i thought it +// would be too messy to tack this onto its split-on-punctuation +// Copyright 2000 Decklin Foster, <decklin@red-bean.com>, GPLed (see +// the top-level gaim source dir for your copy). +// isn't this next line just disgusting? +const char *munge = "<b></b>"; +// and we put that after the first char in any of these. "O:-)" has +// it's own graphic, but will be caught looking for ":-)". Entries on +// the same line have the same graphic. +const char *smileys[] = { + ":-P", ":P", ":-p", ":p", +// this is bad -- free should barf if dest is auto. either g_free +// checks this or i'm very lucky. need a better way to prevent +// memleaks here. (when i doubt, blame the plugin interface for +// forcing me to munge strings like this ;-) +static void insert_str(char **dest, size_t pos, const char *src) + char *new = g_malloc(strlen(*dest) + strlen(src) + 1); + //printf(" inserting '%s' into '%s' @ %d\n", src, *dest, pos); + fprintf(stderr, "yipes! can't g_malloc.\n"); + strcpy(new+pos+strlen(src), *dest+pos); + //printf(" result: '%s'\n", new); +// There are probably more efficent ways to do this, given that half +// our keys start with ':'. Do I care? ha! +static void munge_smileys(struct gaim_connection *gc, char *buddy, + char **im, void *cb_data) + //printf("im: '%s'\n", *im); + for (s = smileys; *s; s++) { + //printf("looking for: '%s'\n", *s); + while (p = strstr(p, *s)) { + //printf(" got substr: '%s'\n", p); + insert_str(im, p - *im + 1, munge); + //printf(" advancing %d chars\n", strlen(*s)); + //printf(" p is now: '%s'\n", p); +// what's my name? say my name, bitch! + return "Munges smiley faces so that your buddy's AIM software won't " + "display them as pictures. Fight the evil forces of cuteness!"; +// these GAIM weirdos really need to use capital letters for their +// constants or something. 'handle'? wuzzat? (hi Rob ;-) +char *gaim_plugin_init(GModule *handle) + gaim_signal_connect(handle, event_im_send, munge_smileys, NULL); + gaim_signal_connect(handle, event_chat_send, munge_smileys, NULL); +void gaim_plugin_remove() + // dave's not here, man... +void gaim_plugin_config() + // FIXME: make a dialog box for stupid people --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/database.inc.php Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,253 @@
+ * Copyright (C) 1999 Portal Web Design. All rights reserved. + * A class implementing database routines with support for + * many types of databases. + * For use with the Portal In A Bottle toolkit. + * Part of the Portal In A Bottle base utilities. + /******************************************************************** + * function Database($db_server_type, $host, $username, $password, + * $db_server_type - Database type, defaults to "mysql" + * $host - Host where the database server resides + * $username - Username for the database + * $password - Password for the database + * $database - Database name + ********************************************************************/ + function Database($dbserver_type = "mysql", $host = "localhost", $username = "", $password = "", $database = "") { + $dbserver_type = strtolower($dbserver_type); +// if (empty($host)) { fatal_error("Host required"); } + if (empty($username)) { + fatal_error("Username required"); + if ($dbserver_type == "mysql") { + $this->dbclass = new Database_MySQL(); + fatal_error("This database format is not supported!"); + $this->dbclass->host = $host; + $this->dbclass->username = $username; + $this->dbclass->password = $password; + $this->dbclass->database = $database; + /******************************************************************** + * Connects to the database + ********************************************************************/ + $this->dbclass->connect(); + /******************************************************************** + * function disconnect() + * Closes the connection to the database + ********************************************************************/ + function disconnect() { + $this->dbclass->disconnect(); + /******************************************************************** + * function set_database($db) + * Sets which database to use + ********************************************************************/ + function set_database($db) { + $this->dbclass->database = $db; + /******************************************************************** + * function get_database() + * Returns the name of the current database. + ********************************************************************/ + function get_database() { + return($this->dbclass->database); + /******************************************************************** + * function query($query) + * $query - the SQL query + ********************************************************************/ + function query($query) { +// print "SQL Call = {$query}<br />\n"; + $this->dbclass->query($query); + /******************************************************************** + * function row_exists($rowname) + * $rowname - The name of the row + * Returns TRUE if the specified row exists. FALSE otherwise. + ********************************************************************/ + function row_exists($rowname) { + return $this->row_exists($rowname); + /******************************************************************** + * function result_array() + * Returns the result in array form + ********************************************************************/ + function result_array() { + return($this->dbclass->result_array()); + /******************************************************************** + * function valid_result() + * Returns TRUE if the result is not NULL, FALSE otherwise. + ********************************************************************/ + function valid_result() { + if (empty($this->dbclass->result)) { + /******************************************************************** + * Returns the number of rows in the previous query. + ********************************************************************/ + return($this->dbclass->num_rows()); + /******************************************************************** + * function free_result() + ********************************************************************/ + function free_result() { + $this->dbclass->free_result(); + function get_insert_id() { + return $this->dbclass->get_insert_id(); +/*********************************************************************/ + /******************************************************************** + * class Database_MySQL extends Database + * MySQL database implementation + ********************************************************************/ + class Database_MySQL extends Database { + function Database_MySQL() {} + /******************************************************************** + * Connects to the database + ********************************************************************/ + mysql_pconnect($this->host, $this->username, $this->password) + or fatal_error(mysql_error()); + /******************************************************************** + * function disconnect() + * Closes the connection to the database + ********************************************************************/ + function disconnect() { + * We want a persistant connection. This would defeat the purpose. + /******************************************************************** + * function query($query) + ********************************************************************/ + function query($query) { + $this->result = mysql_db_query($this->database, $query) + or fatal_error(mysql_error()); + /******************************************************************** + * function row_exists($rowname) + * $rowname - The name of the row + * $key - The key to use in the COUNT() (optional) + * Returns TRUE if the specified row exists. FALSE otherwise. + ********************************************************************/ + function row_exists($rowname, $key = "*", $misc = "") { + $this->query("SELECT COUNT($key) FROM $this->database"); + /******************************************************************** + * function result_array() + * Returns the result in an array form + ********************************************************************/ + function result_array() { + return(mysql_fetch_array($this->result)); + /******************************************************************** + * Returns the number of rows in the previous query. + ********************************************************************/ + return(mysql_num_rows($this->result)); + /******************************************************************** + * function free_result() + ********************************************************************/ + function free_result() { + //mysql_free_result($this->result); + function get_insert_id() { + return mysql_insert_id(); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/plugins.inc.php Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,214 @@
+ function do_plugin_query($sql) + if ($db->num_rows() > 0) + while ($info = $db->result_array()) + $plugins[$info["PLUGIN_ID"]] = $info; + function get_plugin_count() + $db->query("SELECT COUNT(*) FROM Plugins"); + $result = $db->result_array(); + return $result[0]["COUNT(*)"]; + function get_all_plugins($start = 0, $limit = 25) + return $this->do_plugin_query( + "SELECT Plugins.*, Users.USER_ID, Users.USERNAME," . + " Users.FIRSTNAME, Users.LASTNAME FROM Plugins, Users" . + " WHERE Plugins.USER_ID=Users.USER_ID LIMIT $start,$limit" + function get_popular_plugins($limit = 10) + return $this->do_plugin_query( + "SELECT Plugins.*, Users.USER_ID, Users.USERNAME," . + " Users.FIRSTNAME, Users.LASTNAME FROM Plugins, Users" . + " WHERE Plugins.USER_ID=Users.USER_ID AND" . + " Plugins.DOWNLOAD_COUNT > 1" . + " ORDER BY DOWNLOAD_COUNT DESC LIMIT $limit" + function get_users_plugins($user_id) + return $this->do_plugin_query( + "SELECT * FROM Plugins WHERE USER_ID=" . $user_id + function get_plugin_author($plugin_id) + "SELECT Users.* FROM Users, Plugins" . + " WHERE Plugins.PLUGIN_ID=" . $plugin_id . + " AND Users.USER_ID=Plugins.PLUGIN_ID" + if ($db->num_rows() > 0) + return $db->result_array(); + function get_plugin($plugin_id) + "SELECT Plugins.*, Users.USER_ID, Users.USERNAME," . + " Users.FIRSTNAME, Users.LASTNAME FROM Plugins, Users" . + " WHERE Plugins.PLUGIN_ID=" . $plugin_id . " AND " . + " Plugins.USER_ID=Users.USER_ID" + if ($db->num_rows() > 0) + return $db->result_array(); + function add_plugin($userid, $name, $version, $url, $homepage, + $filesize, $brief, $description) + $name = addslashes($name); + $version = addslashes($version); + $url = addslashes($url); + $homepage = addslashes($homepage); + $brief = addslashes($brief); + $description = addslashes($description); + "INSERT INTO Plugins VALUES(0, $userid, \"$name\"," + . " \"$version\", \"$url\", \"$homepage\", $filesize," + . " \"$brief\", \"$description\", NOW(), NOW(), 0, 0)" + function update_plugin($plugin_id, $name, $version, $url, $homepage, + $filesize, $brief, $description) + $name = addslashes($name); + $version = addslashes($version); + $url = addslashes($url); + $homepage = addslashes($homepage); + $brief = addslashes($brief); + $description = addslashes($description); + "UPDATE Plugins SET NAME=\"$name\", VERSION=\"$version\"," . + " URL=\"$url\", HOMEPAGE=\"$homepage\", FILESIZE=$filesize," . + " BRIEF=\"$brief\", DESCRIPTION=\"$description\", " . + " UPDATED=NOW() WHERE PLUGIN_ID=" . $plugin_id + function delete_plugin($plugin_id) + "DELETE FROM Plugins WHERE PLUGIN_ID=" . $plugin_id + function update_download_count($plugin_id) + "UPDATE Plugins SET DOWNLOAD_COUNT=DOWNLOAD_COUNT+1" . + " WHERE PLUGIN_ID=" . $plugin_id + function update_view_count($plugin_id) + "UPDATE Plugins SET VIEW_COUNT=VIEW_COUNT+1" . + " WHERE PLUGIN_ID=" . $plugin_id + function get_search_count($keywords, $type) + $keywords = strtolower(str_replace(" ", "|", $keywords)); + $querystr = "SELECT COUNT(*) FROM Plugins WHERE LOWER("; + $querystr .= "DESCRIPTION"; + $querystr .= ") REGEXP \"(" . $keywords . ")\""; + $querystr .= " OR LOWER(BRIEF) REGEXP \"(" . $keywords . ")\""; + $result = $db->result_array(); + return $result[0]["COUNT(*)"]; + function search_plugins($keywords, $type, $start, $limit) + $keywords = strtolower(str_replace(" ", "|", $keywords)); + $querystr = "SELECT * FROM Plugins WHERE LOWER("; + $querystr .= "DESCRIPTION"; + $querystr .= ") REGEXP \"(" . $keywords . ")\""; + $querystr .= " OR LOWER(BRIEF) REGEXP \"(" . $keywords . ")\""; + $querystr .= " LIMIT $start,$limit"; + return $this->do_plugin_query($querystr); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/sessions.inc.php Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,180 @@
+ var $sid = ""; /* Session ID */ + /******************************************************************** + * The Session() constructor + ********************************************************************/ + function startSession() { + global $sid, $username, $db; + global $HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS; + if ((!isset($sid)) || (empty($sid))) { return; } + $this->sid = $sid = urldecode($sid); + "SELECT * FROM Users WHERE SESSION_ID='" . $sid . "'" + if ($db->num_rows() == 0) { + * Oops, a cookie is set but there is no session info. + * You know what we have to do... KILL THE COOKIE! + setcookie("sid", "", 0); + unset($GLOBALS["sid"]); + unset($HTTP_COOKIE_VARS["sid"]); + function login($username, $password) { + global $HTTP_USER_AGENT, $PHP_SELF, $HTTP_COOKIE_VARS; + $GLOBALS["username_missing"] = false; + $GLOBALS["password_missing"] = false; + if (!$users->user_exists($username)) { + $GLOBALS["username_missing"] = -1; + $GLOBALS["password_missing"] = -1; + $GLOBALS["username_missing"] = -1; + $GLOBALS["password_missing"] = -1; + if ($missinginfo) { return false; } + if ($users->logged_in()) { + "SELECT * FROM Users WHERE USERNAME='".$username."'" + if ($db->num_rows() > 0) { + $info = $db->result_array(); + $salt = substr($info["PASSWORD"], 0, 2); + $newpass = crypt($password, $salt); + if ($newpass != $info["PASSWORD"]) { + $this->sid = $this->generate_get_sid(); + "UPDATE Users SET SESSION_ID='" . $this->sid . "'" + . " WHERE USER_ID=" . $info["USER_ID"] + $HTTP_COOKIE_VARS["sid"] = $this->sid; + $expdate = time() + 63072000; + setcookie("sid", $this->sid, $expdate); + header("Location: " . $this->localUrl($PHP_SELF) . "\n"); + /******************************************************************** + * function generate_get_sid() + * Generates a Session ID based on the date/time and IP address. + ********************************************************************/ + function generate_get_sid() { + return "s" . md5(uniqid(rand())); + /******************************************************************** + * Returns the session ID in a pib_sessionid=... way. + ********************************************************************/ + return "sid=" . urlencode($this->sid); + /******************************************************************** + * Returns the session ID. + ********************************************************************/ + return urlencode($this->sid); + function localUrl($url) { + if (empty($this->sid)) { + return $url . "?" . $this->get_sid(); + function hidden_sid() { + if (empty($this->sid)) { + return "<input type=\"hidden\" name=\"sid\"" + . " value=\"" . $this->get_sid() . "\" />"; + /******************************************************************** + * Destroys the Session and removes all data and variables + ********************************************************************/ + "UPDATE Users SET SESSION_ID='' WHERE SESSION_ID='" . + /* We don't care if this is a valid result or not. */ + /* If it doesn't exist already, it's already deleted :) */ +// header("Location: $PHP_SELF"); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/users.inc.php Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,182 @@
+ var $user_info = array(); + var $is_logged_in = false; + $this->is_logged_in = false; + "SELECT * FROM Users WHERE SESSION_ID='" . $sid . "'" + if ($db->num_rows() > 0) { + $this->user_info = $db->result_array(); + $this->is_logged_in = true; + return $this->is_logged_in; + function login($username, $password) { + if ($session->login($username, $password)) { + $this->is_logged_in = true; + $this->is_logged_in = false; + function user_exists($username) { + $db->query("SELECT * FROM Users WHERE USERNAME='$username'"); + if ($db->num_rows() > 0) { + $info = $db->result_array(); + if (!empty($info["USERNAME"])) { + function get_user_info_from_id($userid) { + if ($userid == -1) { return NULL; } + if ($userid == $this->user_info["USER_ID"]) { + return $this->user_info; + "SELECT * FROM Users WHERE USER_ID=" . $userid + if ($db->num_rows() > 0) { + return $db->result_array(); + function get_user_info_from_username($username) { + if ($username == "") { return NULL; } + if ($username == $this->user_info["USERNAME"]) { + return $this->user_info; + "SELECT * FROM Users WHERE USERNAME='" . $username . "'" + if ($db->num_rows() > 0) { + return $db->result_array(); + function get_active_user_username() { + return $this->user_info["USERNAME"]; + function get_active_user_id() { + return $this->user_info["USER_ID"]; + function is_active_user_admin() { + return ($this->user_info["ADMIN"] == "Y"); + function get_active_user_info() { + return $this->user_info; + function change_password($username, $newpassword) { + $newpass = crypt($newpassword, $seed); + "UPDATE Users SET PASSWORD='$newpass'" + . " WHERE USERNAME='$username'" + $bakusername = $GLOBALS["username"]; + $requiredinfo = array("username", "password", "password2"); + for ($i = 0; $i < count($requiredinfo); $i++) { + if (empty($GLOBALS[$requiredinfo[$i]])) { + $GLOBALS[$requiredinfo[$i]] = -1; + if ($bakusername != "") { + if ($this->user_exists($bakusername)) { + $GLOBALS["username"] = -2; + if ($GLOBALS["password"] != $GLOBALS["password2"]) { + $GLOBALS["password"] = -1; + $GLOBALS["password2"] = -1; + if ($missinginfo) { return false; } + $newpass = crypt($GLOBALS["password"], $seed); + "INSERT INTO Users VALUES(0, '$GLOBALS[username]', " + . "'$newpass', '$GLOBALS[firstname]', '$GLOBALS[lastname]', " + . "'$GLOBALS[email]', '$GLOBALS[icquin]', '$GLOBALS[aimname]', " + . "'$GLOBALS[yahooname]', '$GLOBALS[jabbername]', " + . "'$GLOBALS[msnname]', '$GLOBALS[ggname]', '', 'N')" + if (!$db->valid_result()) { --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/utils.inc.php Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,113 @@
+ function setup_site($title = "") { + global $db, $session, $users; + global $sql_type, $sql_server, $sql_username, $sql_password; + if ($setup_ran == false) { + /* Connect to the database. */ + $db = new Database($sql_type, $sql_server, $sql_username, + $sql_password, $sql_database); + /* Session management. */ + $session = new Session(); + $session->startSession(); + function fatal_error($error) { + echo "<b>Fatal error:</b> " . $error . "<br />\n"; + function site_shutdown() { + mt_srand((double)microtime()*1000000); + $num = mt_rand(46,122); + } while (($num > 57 && $num < 65) || ($num > 90 && $num < 97)); + function form_item($desc, $name, $value = "", $required = false, + $size = "", $maxlength = "") { + print " <td align=\"right\" nowrap=\"nowrap\">"; + print "<font color=\"#FF0000\">*</font> "; + && (($value == -1 || $value == -2) + || ($name == "password" || $name == "password2"))) { + print "<font color=\"#FF0000\">" . $desc . ":</font>"; + print "</b> </td>\n"; + print " <td width=\"60%\">"; + print "<input type=\""; + if ($name == "password" || $name == "password2") { + print "\" name=\"" . $name . "\""; + if ($value != -1 && $value != -2 && $value != "") { + print " value=\"" . $value . "\""; + if ($size != "") { print " size=\"" . $size . "\""; } + if ($maxlength != "") { print " maxlength=\"" . $maxlength . "\""; } --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sql/plugins.sql Thu Sep 26 06:23:23 2002 -0400
@@ -0,0 +1,41 @@
+CREATE TABLE IF NOT EXISTS Users ( + USER_ID INT NOT NULL AUTO_INCREMENT, + USERNAME VARCHAR(15) NOT NULL, + PASSWORD VARCHAR(15) NOT NULL, + EMAIL VARCHAR(85) NOT NULL, + JABBERNAME VARCHAR(40), + SESSION_ID VARCHAR(255) NOT NULL, + ADMIN CHAR(1) NOT NULL DEFAULT 'N', +CREATE TABLE IF NOT EXISTS Plugins ( + PLUGIN_ID INT NOT NULL AUTO_INCREMENT, + NAME VARCHAR(128) NOT NULL, + VERSION VARCHAR(16) NOT NULL, + URL VARCHAR(255) NOT NULL, + BRIEF VARCHAR(255) NOT NULL + DESCRIPTION BLOB NOT NULL, + CREATED DATETIME NOT NULL, + UPDATED DATETIME NOT NULL, + PRIMARY KEY (PLUGIN_ID)