📄 dbmedit.cgi
字号:
if ($flags[$_]{'r'}) { print qq( <td><input type=hidden name="$fieldname" value="$safefield[$_]">$safefield[$_]</td></tr>\n) ; } else { $width= $maxwidth[$_] ? $maxwidth[$_]+1 : 20 ; print qq( <td><input name="$fieldname" value="$safefield[$_]" size="$width"></td></tr>\n) ; } } } print <<EOF ;</table><p><input type=submit value="Update this record"><input type=reset value="Reset values"></form><hr><p><font color=red><form action="$ENV{'SCRIPT_NAME'}" method=post><input type=hidden name="cmd" value="delete"><input type=hidden name="key" value="$safein{'key'}"><input type=hidden name="time" value="$now">$dbdefnpost<input type=checkbox name="confirm">Delete this record<input type=submit value="Delete this record"></form></font><p>To delete this record, check the checkbox and press the button.<hr><table width="100%" cellspacing=0 cellpadding=0><tr> <td><b><a href="$ENV{'SCRIPT_NAME'}?$dbdefnget">Go to main table</a></b></td> <td align=right><b><a href="$safein{'referer'}">Exit from database session</a></b></td></tr></table>EOF &printfooter ;} # sub displayeditform()# Display a starting form to the user if no database has been named.# jsm-- how could color improve this?sub displaystartform { print <<EOF ;Content-type: text/html<html><head><title>Edit a DBM file</title></head><body bgcolor=white vlink="#008080"> <h1>Edit a DBM file</h1><h2>Define your DBM database:</h2> <form action="$ENV{'SCRIPT_NAME'}" method=get><table><tr><td><b>File Name:</b></td> <td><input name="file"></td></tr><tr><td><b>Column Descriptions:</b></td> <td><input name="columns" size=50></td></tr><tr><td><b>ASCII Values of Delimiter:</b></td> <td><input name="delim"></td></tr></table><br><input type=submit value="Edit DBM file"></form><hr><h2>How to enter the fields</h2><dl><p><dt><b>File Name:</b><dd>Enter the DBM filename with no extension. Don't include any directory component.<p><dt><b>Column Descriptions:</b><dd>Enter a comma-separated list of text strings. Each column name may be followed by a ':' and optional one-letter flags. Currently supported flags are: <blockquote> <table border cellpadding=5> <tr><td><b><tt><font size="+1">r</font></tt></b></td> <td>Display field as read-only after it's first entered. This will protect against accidental erasure, but NOT against a malicious user.</td></tr> <tr><td><b><tt><font size="+1">t</font></tt></b></td> <td>Allow multi-line (textarea) input instead of a single-line entry field.</td></tr> </table> </blockquote> <p>An example of a list of column descriptions: <blockquote> <b><tt>Name, Birthdate:r, Favorite Quote:t</tt></b> </blockquote> <p>Column descriptions affect the display only. Nothing about them is stored in the database.<p><dt><b>ASCII Values of Delimiter:</b><dd>Enter a list of decimal numbers, representing the ASCII values of the characters in the delimiter (which may be multi-char). For example, "13 10" means CRLF. The default is "0", which is one null character. <p>Note that the data in the database fields can't contain the delimiter string, or the database will get messed up. If you need to put arbitrary binary data in a field, use a long sequence of random bytes for the delimiter, like "188 45 217 206 51". Five bytes means you'll mess it up about once for every terabyte (1000 GB) you store.</dl>EOF &printfooter ; exit ;} # sub displaystartform()#----- Utilities copied in from other places -------------------------# Read all CGI vars into an associative array; return the array.# Supports application/x-www-form-urlencoded and multipart/form-data.# Does not distinguish between file-type input and user-entered input;# entire file contents are saved in a normal array element.# When using multipart/form-data, cannot handle multiple files with same# name; cannot handle multipart/mixed type with several files.sub getcgivars { local($in, %in) ; local($name, $value) ; # First, read entire string of CGI vars into $in if ($ENV{'REQUEST_METHOD'} eq 'GET') { $in= $ENV{'QUERY_STRING'} ; } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { $env_ct= $ENV{'CONTENT_TYPE'} ; if ($env_ct=~ m#^application/x-www-form-urlencoded\b#i) { $ENV{'CONTENT_LENGTH'} || &HTMLdie("No Content-Length sent with the POST request.") ; read(STDIN, $in, $ENV{'CONTENT_LENGTH'}) ; } else { &HTMLdie("Unsupported Content-Type: $env_ct") ; } } else { &HTMLdie("Script was called with unsupported REQUEST_METHOD.") ; } # Resolve and unencode name/value pairs into %in foreach (split('&', $in)) { s/\+/ /g ; ($name, $value)= split('=', $_, 2) ; $name=~ s/%(..)/sprintf("%c",hex($1))/ge ; $value=~ s/%(..)/sprintf("%c",hex($1))/ge ; $in{$name}.= "\0" if defined($in{$name}) ; # concatenate multiple vars $in{$name}.= $value ; } return %in ;}# Die, outputting HTML error page# If no $title, use global $errtitle, or else default titlesub HTMLdie { local($msg,$title)= @_ ; $title= ($title || $errtitle || "CGI Error") ; print <<EOF ;Content-Type: text/html<html><head><title>$title</title></head><body><h1>$title</h1><h3>$msg</h3></body></html>EOF exit ;}# Returns the URL-encoded version of a string sub urlencode { local($s)= @_ ; $s=~ s/(\W)/ '%' . sprintf('%02x',ord($1)) /ge ; return $s ;}# create URL-encoded QUERY_STRING for an associative arraysub urlencodelist { local(%a)= @_ ; return join('&', map { &urlencode($_) . '=' . &urlencode($a{$_}) } grep( defined($a{$_}), keys %a) ) ;}# returns a subset of associative arraysub subhash { local(*a, @keys)= @_ ; local(%ret) ; @ret{@keys}= @a{@keys} ; return %ret ;}# Escape any &"<> chars to &xxx; and return resulting stringsub HTMLescape { local($s)= @_ ; $s=~ s/&/&/g ; # must be before all others $s=~ s/"/"/g ; $s=~ s/</</g ; $s=~ s/>/>/g ; return $s ;}# create hidden form variables for an associative arraysub hiddenvars { local(%a)= @_ ; local($ret) ; foreach (keys %a) { if (defined($a{$_})) { $ret.= '<input type=hidden name="' . &HTMLescape($_) . '" value="' . &HTMLescape($a{$_}) . "\">\n" ; } } return $ret ;}#---------------------------------------------------------------------## SOME COMMENTS, AND MINOR DOCUMENTATION ON PROGRAM INTERNALS:##---------------------------------------------------------------------## The goal of this script is to edit DBM files, not to be a# full-purpose database, and design decisions were made on this basis.# Many more powerful features could easily be added, but may place# constraints on the DBM file, or require auxilliary files, etc.## The data saved in the database is pretty flexible. It can be any data,# even binary data; the only restriction is that the fields must not# contain the delimiter string. The key is not as flexible, by design; # the user is not encouraged to use binary data in the key.## This program is made to be simple to use, so has some minor# limitations. Examples: the data cannot contain the delimiter string,# titles cannot contain commas or colons, etc. All of these could be# overcome by adding complexity to the program, if there is demand.## This uses rudimentary file locking to protect against simultaneous# accesses. A lock file is created, and an exclusive lock is held on# it for the duration of the script run.## NOTE THAT SECURITY IMPLEMENTED HERE IS LIMITED AT BEST. It relies# on the authentication of whoever's running the script. To add more# security would require implementing some scheme involving other files# (e.g. a password file) and I'm trying to keep this simple, relying # only on the DBM file.## CGI input fields:# file: name of DBM file to edit# delim: ASCII value of delimiter character to use (default is \0)# columns: comma-separated list of column titles, followed by# optional one-letter flags after a colon, e.g. # "fullname:ru". Flags may take non-alphabetic values, # e.g. "fullname:rw30".# referer: the URL to return to when finished## cmd: command to perform; default is "show"# confirm: used to confirm some commands# time: time the page was loaded; used for careful updates## key: key of record to be processed# in_001, in_002, ...: input values when a record is added or changed## Currently supported commands are:# show: show the full table of all records (default)# edit: present the user with a form to edit a record (needs "key")# add: add a new record (needs "key" and "in_nnn" values)# update: update the record (needs "key" and "in_nnn" values)# delete: delete the record with the given key (needs "key")## Currently supported column flags are:# r: read-only (for convenience only, NOT security)# t: textarea field instead of one-line input field## Not supported; which of these would be useful?# w: numeric width of column# u: unique-- when adding records, a unique value is generated# for this column.# d: date/timestamp, either for creation time or mod time of record# c: calculated from other fields, maybe takes form ":c1+2*3", as# long as value is non-alphabetic. Fancy; is it actually# useful?## Could also support __columns, possibly to pass db-wide flags (e.g.# alternate display style).## A lot of features would be relatively simple to add, if there is demand.### OTHER TO DO:# Accommodate C-style data (with no delimiters, possibly null-terminated).# This would require :w flag on every column.# Would a query function be useful?### BUGS:## If you bounce on the Add button, and you didn't enter a "key", you# may add the record multiple times. I think this is a fact of life:# How do we know several users aren't submitting the records at the # same time? To solve this would require something like keeping track# of some ID of the locking client, blech. Maybe save such an ID in# the lock file itself?##---------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -