Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "common.h"
#include "send.h"

static void
mboxfile(dest *dp, String *user, String *path, char *file)
{
        char *cp;

        mboxpath(s_to_c(user), s_to_c(dp->addr), path, 0);
        cp = strrchr(s_to_c(path), '/');
        if(cp)
                path->ptr = cp+1;
        else
                path->ptr = path->base;
        s_append(path, file);
}

/*
 *  Check forwarding requests
 */
extern dest*
expand_local(dest *dp)
{
        Biobuf *fp;
        String *file, *line, *s;
        dest *rv;
        int forwardok;
        char *user;

        /* short circuit obvious security problems */
        if(strstr(s_to_c(dp->addr), "/../")){
                dp->status = d_unknown;
                return 0;
        }

        /* isolate user's name if part of a path */
        user = strrchr(s_to_c(dp->addr), '!');
        if(user)
                user++;
        else
                user = s_to_c(dp->addr);

        /* if no replacement string, plug in user's name */
        if(dp->repl1 == 0){
                dp->repl1 = s_new();
                mboxname(user, dp->repl1);
        }

        s = unescapespecial(s_clone(dp->repl1));

        /*
         *  if this is the descendant of a `forward' file, don't
         *  look for a forward.
         */
        forwardok = 1;
        for(rv = dp->parent; rv; rv = rv->parent)
                if(rv->status == d_cat){
                        forwardok = 0;
                        break;
                }
        file = s_new();
        if(forwardok){
                /*
                 *  look for `forward' file for forwarding address(es)
                 */
                mboxfile(dp, s, file, "forward");
                fp = sysopen(s_to_c(file), "r", 0);
                if (fp != 0) {
                        line = s_new();
                        for(;;){
                                if(s_read_line(fp, line) == nil)
                                        break;
                                if(*(line->ptr - 1) != '\n')
                                        break;
                                if(*(line->ptr - 2) == '\\')
                                        *(line->ptr-2) = ' ';
                                *(line->ptr-1) = ' ';
                        }
                        sysclose(fp);
                        if(debug)
                                fprint(2, "forward = %s\n", s_to_c(line));
                        rv = s_to_dest(s_restart(line), dp);
                        s_free(line);
                        if(rv){
                                s_free(file);
                                s_free(s);
                                return rv;
                        }
                }
        }

        /*
         *  look for a 'pipe' file.  This won't work if there are
         *  special characters in the account name since the file
         *  name passes through a shell.  tdb.
         */
        mboxfile(dp, dp->repl1, s_reset(file), "pipeto");
        if(sysexist(s_to_c(file))){
                if(debug)
                        fprint(2, "found a pipeto file\n");
                dp->status = d_pipeto;
                line = s_new();
                s_append(line, "upasname='");
                s_append(line, user);
                s_append(line, "' ");
                s_append(line, s_to_c(file));
                s_append(line, " ");
                s_append(line, s_to_c(dp->addr));
                s_append(line, " ");
                s_append(line, s_to_c(dp->repl1));
                s_free(dp->repl1);
                dp->repl1 = line;
                s_free(file);
                s_free(s);
                return dp;
        }

        /*
         *  see if the mailbox directory exists
         */
        mboxfile(dp, s, s_reset(file), ".");
        if(sysexist(s_to_c(file)))
                dp->status = d_cat;
        else
                dp->status = d_unknown;
        s_free(file);
        s_free(s);
        return 0;
}