Usage Example 2
Accessing HTTPFS (HFS822 server) via a POSIX File API
Let me show another example of reading and inquiring of remote files using the familiar open()
, fopen()
, etc. POSIX calls. As this example shows a remote resource being manipulated as a file not necessarily is a file on remote computer's filesystem.
|
int main(void)
{
show_stat("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1");
show_file("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1");
...
|
where show_stat()
is a function that does stat()
on its argument -- file name -- and prints out the result; show_file()
opens a given file name via fopen()
and copies the file contents to stdout
. Here is the output produced by the show_stat()
function above:
|
Information for a file 'http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1'...
The file is a regular file, permission flags 644
devno:ino 8388614:12 nlinks 1
uid:gid 760:60
size 1851 blocks 4
Last access time: Sun May 16 22:09:46 1999
Last modif time: Sun May 16 21:56:25 1999
inode time: Sun May 16 22:09:40 1999
|
The contents of the message (as printed out by the show_file()
function) is as follows. The message is from the honorable Freenix track chairman. Some hostnames and IP addresses have been modified to protect him from spam. Note familiar message headers, followed by the body.
|
A 1851-byte long file 'http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1' is as follows
>>>From jkh@his.com Tue Mar 30 03:01:19 1999
Received: by chai (Postfix, from userid 201)
id E4FAC6472; Mon, 29 Mar 1999 18:48:02 -0500 (EST)
Date: Mon, 29 Mar 1999 15:48:00 -0800 (PST)
From: "Jordan K. Hubbard" <jkh@his.com>
Message-Id: <199903292348.PAA42143@his.com>
To: oleg
Subject: final confirmation for FREENIX track
Content-Length: 1167
Status: OR
This message is just a final confirmation that you or one of
your co-conspirators have had a paper accepted at this year's
FREENIX track at the USENIX annual technical conference on
June 6th - June 11th.
...
<<<
|
Let's try a slight variation:
|
...
show_stat("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1/");
show_stat("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1/.");
...
|
Note a slash at the end of message1
. These two functions produce the same output:
|
Information for a file 'http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1/'...
The file is a directory, permission flags 644
devno:ino -12:1 nlinks 2
uid:gid 760:60
size 1851 blocks 4
Last access time: Sun May 16 22:10:08 1999
Last modif time: Tue Mar 30 03:01:19 1999
inode time: Tue Mar 30 03:01:19 1999
|
The stat()
function now reports that /tmp/message1/
is a directory. Note its modification time: the time when the message was received.
As /tmp/message1
now acts as a directory, it should contain files. Let's try one of them:
|
...
show_stat("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/
message1/date");
...
|
which prints:
|
Information for a file 'http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1/date'...
The file is a regular file, permission flags 644
devno:ino -12:9 nlinks 1
uid:gid 760:60
size 37 blocks 4
Last access time: Sun May 16 22:10:08 1999
Last modif time: Tue Mar 30 03:01:19 1999
inode time: Tue Mar 30 03:01:19 1999
|
It is a regular file, of 37 bytes. Again, note the modification time. To see this file's contents, we'll invoke
|
...
show_file("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/
message1/Date");
...
|
This gives us:
|
A 37-byte long file 'http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/message1/Date' is as follows
>>>Mon, 29 Mar 1999 15:48:00 -0800 (PST)
<<<
|
which is exactly the Date
header of the original RFC822 message. Note that the HFS822 filesystem is case-insensitive.
The other statements in this sample code
|
...
show_file("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/
message1/Subject");
show_file("http://sunhost/cgi-bin/admin/
HFS822-server.pl/DeepestRoot/tmp/
message1/body");
return 0;
}
|
work exactly as expected. The body is a special "header" that contains the body of the message.
This particular HTTPFS server allows access to a remote structured document as if it were a directory, and to its separate entities as if they were files. One can open these files with familiar open()
, fopen()
, ifstream
, with-input-from-file
system calls and library functions.
I could easily write a HTTPFS server that provides access to and probably modification of a remote XML document. It would've been a better example. However, parsing of an XML document is a little bit more involved than that of a RFC822 message -- and I simply didn't have time. The whole RFC822 server -- along with 200 lines of comments-specifications was written from scratch over one evening.
This main function itself ran on a Sun/Solaris and Linux/i686 computers. The entire code of this example -- file vhttp822.c
-- is a part of the testing suite in the HTTPFS distribution.
Last updated June 25, 1999
oleg-at-okmij.org
Your comments, problem reports, questions are very welcome!