perl questions
Jon Knight
jon at net.lut.ac.uk
Fri Mar 6 10:48:49 EST 1998
On Fri, 6 Mar 1998, laura hudson wrote:
> Has anybody written, or considered writing, a CGI for Librarians book?
> Librarians want to do different things than most businesses, "real"
> programmers, or amateur web-page designers, which is who most of the books
> are written for.
I often end up writing the CGI scripts for the library here but I must
admit that I think of them in the same way as I do any of the other
programs I write. I don't really see anything special about the scripts
themselves. Then again programming comes pretty naturally to me so YMMV.
> I have been asked to write a script which passes a password to a database so
> that we don't have to give the password to our users. I know how to do this
> with a form button for a database such as GeoRef where the password
> interface is actually a Web page, but these databases seem to be using fmpro
> or some other database protection--a box pops up asking for a password. Can
> this be scripted with CGI? I find nothing about it out there. The sites in
> question are the Harvard Educational Review (www.edreview.org) and the
> Directory of Electronic Journals, Newsletters, and Academic Discussions
> (www.arl.org:591/).
These sites might be asking for a username and password as part of their
web server's authentication mechanism. One way "round" that for your
users would be to install a small proxy server for those services that
inserted the appropriate username and password into the HTTP protocol
stream and relayed the results to and from the user. You could go this
fairly easily using a Perl CGI script (remember to parse the incoming HTML
from the remote servers to insert the URL of the proxy CGI script
> This line checks IP and it works:
> if ($user_ip =~
> /^132\.235\.\d*\.\d*|^198\.234\.69\.[241-254]|^198\.234\.122\.d*/){
>
> However, I want to screen out several ranges within the "d*"s. So I wrote this:
>
> if ($user_ip =~
> /^132\.235\.\[1-100|102-119|121-129|131|133-500]\.\d*|^198\.234\.69\.[241-25
> 4]|^198\.234\.122\.d*/){
The first square bracket has been backslashed and thus isn't being
interpreted as a multiple character matching bracket. However the bigger
problem is that Perl regexps use character classes and the range
expression matches a single character, not a range of numbers. Therefore
the expression [1-100] really says that you should match a single
character from the set of characters {1, 1, 0 ,0}. This means that your
"working" example isn't really: it will match a single character in the
last octet of the dotted quad address that is in the set of characters {2,
4, 1, 2, 5, 4}. Now it just so happens that 241-254's leading "2" matches
this and so is passed. But so is 234, 264, 436, etc!
The "working" example should really be something more like:
if ($user_ip =~
/^132\.235\.\d*\.\d*|^198\.234\.69\.((24[1-9])|(25[0-4]))]|^198\.234\.122\.d*/){
As for the more complex ranges, you could carry on along this path or move
away from complex regexps by doing something like:
$user_ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)/;
$a = $1;
$b = $2;
$c = $3;
$d = $4;
if( ($a == 132 && $b == 235 && ( (1<=$c && $c<=100)
|| (102<=$c && $c<=119)
|| (121<=$c && $c<=129)
|| $c == 131
|| (133<=$c && $c<=500)
)
) || ($a == 198 && $b == 234 && $c == 69 && (241<=$d && $d<=254)
) || ($a == 198 && $b == 234 && $c == 122
)
) {
print "OK!\n";
} else {
print "Blah!\n";
}
I tried to split the if statement's clause up there for you to make it a
bit clearer what's going on. Hope that helps. Maybe someone has an
easier way of doing this as well; this is Perl after all... :-)
Tatty bye,
Jim'll
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Jon "Jim'll" Knight, Researcher, Sysop and General Dogsbody, Dept. Computer
Studies, Loughborough University of Technology, Leics., ENGLAND. LE11 3TU.
* I've found I now dream in Perl. More worryingly, I enjoy those dreams. *
More information about the Web4lib
mailing list