# FUP ate my db (and I did RTFM)

ThwartedEfforts (abakun@scinc.com)
Tue, 28 May 1996 14:34:40 PDT

- Messages sorted by:[ date ][ thread ][ subject ][ author ]

    At 09:45 AM 5/28/96 PDT, dg@dcs.st-and.ac.uk wrote:
    >I've got a sysadmin's file management room, which provides a Unix-shell like
    >interface. So all I'm getting from the user is a single string. I can't split
    >it because there isn't an intelligent way to split it (besides, it's too much
    >work). If /foo/bar is a directory, should that be ("/foo", "bar") or
    >("/foo/bar", ".") or (".", "foo/bar")? And what about references to /? Anyway,
    >this isn't the problem. Everything works fine.

    Whatever . means, I'm not sure, I never used that to reference files.  I
    assume you are keeping the cwd stored somewhere, then prepending it to path
    they are specifing if they don't start it with a /.  We have code that
    resolves relative path names also (altho, /dir_that_doesnt_exist/../bin =>
    /bin, but shouldn't matter if you use the below code to determine that the
    cwd is valid before you let them "enter" it).

    If /foo/bar is a directory, then it should be referenced via "/foo/bar", no
    questions.  Keep it consistant.  Note that:

    ;filelist("home", "rules")
    => the contents of "home"
    whereas
    ;filelist("home/rules")
    => the contents of "home/rules"
    Thusly, you'll have to always reference directories via a single string
    (which is how I think it should be done anyway) if you want it to be
    consistant.  (sidenote: filelist()'s second optional argument is the regexp
    to match against, which doesn't match directories.)

    This splits it "intelligently" (whatever that means):
    @program $file_utils:valid_dir_or_file   this none this
    " Takes one argument, a path, and returns a three element list";
    " The first of which is boolean, the second of which is a string";
    " If false, then the second is an error message";
    " If true, then the second is the type of the argument (dir or file)";
    " The third element is the parsed path, ready for splicing into one of the";
    " builtins";
    "";
    " :valid_dir_or_file(\"home\")";
    " => {1, \"dir\", {\"home\", \"\"}}";
    " :valid_dir_or_file(\"home/Scrytch\")";
    " => {1, \"dir\", {\"home/Scrytch\", \"\"}}";
    " :valid_dir_or_file(\"/core.mods\")";
    " => {0, \"file\", {\"\", \"core.mods\"}}";
    " :valid_dir_or_file(\"home/nodir/\")";
    " => {0, \"No such directory.\", {\"home/nodir\", \"\"}";
    " :valid_dir_or_file(\"home/nofile\")";
    " => {0, \"No such file or directory.\", {\"home\", \"nofile\"}}";
    "";
    " It assumes that you mean a directory if you end in a /";
    "";
    " Written by ThwartedEfforts for all those out there who need it.";
    " Never tell a hacker that it can't be done or that it's too much work.";
    {path} = args;
    r = rindex(path, "/");
    type = 0;
    " by default";
    if (r == length(path))
      " ends in /, they wanted a dir";
      type = 1;
    endif
    " parse it into before the last / and after the last /";
    before = path[1..r - 1];
    after = path[r + 1..$];
    "";
    if (type == 0)
      " check for the existances of files";
      {flist, dlist} = filelist(before);
      if (after in flist)
        return {1, "file", {before, after}};
      endif
      if (after in dlist)
        dir = tostr(before, before ? "/" | "", after);
        return {1, "dir", {dir, ""}};
      endif
    endif
    if (type == 1)
      " check for the existance of directories";
      dir = tostr(before, before ? "/" | "", after);
      if (fileexists(before, after))
        return {1, "dir", {dir, ""}};
      else
        return {0, "No such directory.", {dir, ""}};
      endif
    endif
    return {0, "No such file or directory.", {before, after}};
    /* Last edited by ThwartedEfforts (#2) <~ThwartedEfforts> on Tuesday, May
    28, 1996 at 10:57:38 PM */

    Hope this helps in some way.

    >>>I know it's an `invalid indirection'... whatever that is. What does it mean?
    >>
    >>In terms of FUP or in terms of when that error is raised normally?
    >
    >Normally.

    ;#-1:someverb()
    ;#-1.someprop

    Trying to access something indirectly through an invalid source.  Perhaps it
    does make sense that FUP raise that...

    >>So don't let them do just anything.  Check to make sure that a file exists
    >>using fileexists before calling file{read,write,append,delete,...}.  Use
    >>filelist to determine if it's a directory or a file and only them them do
    >>operations that are directory operations on directories and file operations
    >>on files.  If you want some semblence of security, don't just pass the
    >>arguments they pass you onto the builtins blindly.

    What I said there is quite verbose. :)  Just use the above code.

    >That's exactly what I'm doing! The user API to FUP is going to be very
    >limited. No subdirectories (each object gets its own directory), for example.
    >Bit the bit I ran into problems with is the wizard section, which will let you
    >do arbitrary file management.

    I like to assume that those I have given wizard bits to know what they are
    doing.. altho, I know I'm playing with fire when I do that. :)

    >(BTW, I got your message twice for some reason.)

    Because I sent it to you, and cc'ed moo-cows.

    And Judy Anderson <yduj@cs.stanford.edu> put me in my place with:
    >I haven't been following this discussion closely, but some of the
    >responses I see are "why are you doing <illegal thing X>"---that's not
    >a proper kind of response.  If there's a MOO eating bug, even if the
    >user has to do something really grotty to trigger it, FUP should armor
    >itself against the user, returning E_INVARG or whatever the
    >appropriate error is for that particular illegal thing.  How does that
    >saying go?  "It's not good enough to be foolproof---fools are too
    >ingenious!"

    How true!  And of course, I realized that as soon as I sent off the mail.  I
    never tried to do something illegal, specificly because it's usually dumb to
    do something like that (there is no valid reason for opening a directory as
    a file and reading from it) -- which is the exact reason programmers can not
    effectively debug their own code.  They are too familar with it.

    Andy.