--- http_config.c.orig Sun Feb 1 11:47:38 1998 +++ http_config.c Fri Jun 19 08:51:54 1998 @@ -513,7 +513,19 @@ return pstrcat (parms->pool, cmd->name, " takes two arguments", cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); - return (*cmd->func) (parms, mconfig, w, w2); + return (*cmd->func) (parms, mconfig, w, w2, ""); + + case TAKE2OR3: + + w = getword_conf (parms->pool, &args); + w2 = getword_conf (parms->pool, &args); + w3 = getword_conf (parms->pool, &args); + + if (*w == '\0' || *w2 == '\0' || *args != 0) + return pstrcat (parms->pool, cmd->name, " takes two or three arguments", + cmd->errmsg ? ", " : NULL, cmd->errmsg, NULL); + + return (*cmd->func) (parms, mconfig, w, w2, w3); case TAKE12: --- http_config.h.orig Fri Jan 30 18:13:54 1998 +++ http_config.h Fri Jun 19 08:52:31 1998 @@ -60,6 +60,7 @@ RAW_ARGS, /* cmd_func parses command line itself */ TAKE1, /* one argument only */ TAKE2, /* two arguments only */ + TAKE2OR3, /* two or three arguments */ ITERATE, /* one argument, occuring multiple times * (e.g., IndexIgnore) */ --- mod_alias.c.orig Mon Apr 14 10:09:13 1997 +++ mod_alias.c Fri Jun 19 09:02:35 1998 @@ -65,6 +65,7 @@ char *real; char *fake; char *handler; + char *user; int redir_status; /* 301, 302, 303, 410, etc */ } alias_entry; @@ -117,7 +118,7 @@ return a; } -const char *add_alias(cmd_parms *cmd, void *dummy, char *f, char *r) +const char *add_alias(cmd_parms *cmd, void *dummy, char *f, char *r, char *u) { server_rec *s = cmd->server; alias_server_conf *conf = @@ -126,7 +127,7 @@ /* XX r can NOT be relative to DocumentRoot here... compat bug. */ - new->fake = f; new->real = r; new->handler = cmd->info; + new->user = u; new->fake = f; new->real = r; new->handler = cmd->info; return NULL; } @@ -169,7 +170,7 @@ else new = push_array (serverconf->redirects); - new->fake = f; new->real = url; + new->user = ""; new->fake = f; new->real = url; new->redir_status = status; return NULL; } @@ -177,8 +178,8 @@ command_rec alias_cmds[] = { { "Alias", add_alias, NULL, RSRC_CONF, TAKE2, "a fakename and a realname"}, -{ "ScriptAlias", add_alias, "cgi-script", RSRC_CONF, TAKE2, - "a fakename and a realname"}, +{ "ScriptAlias", add_alias, "cgi-script", RSRC_CONF, TAKE2OR3, + "a fakename and a realname and an optional user id"}, { "Redirect", add_redirect, (void*)HTTP_MOVED_TEMPORARILY, OR_FILEINFO, TAKE23, "an optional status, then document to be redirected and destination URL" }, @@ -191,10 +192,14 @@ { NULL } }; -int alias_matches (char *uri, char *alias_fakename) +int alias_matches (char *uri, char *alias_fakename, char *wild) { char *end_fakename = alias_fakename + strlen (alias_fakename); char *aliasp = alias_fakename, *urip = uri; + char *wp = wild; + enum { normal, peruser } wild_type; + + wild_type = (uri[1] == '~' ? peruser : normal); while (aliasp < end_fakename) { if (*aliasp == '/') { @@ -206,6 +211,16 @@ while (*aliasp == '/') ++ aliasp; while (*urip == '/') ++ urip; } + else if (wild_type == normal && *aliasp == '*') { + aliasp++; + while (*urip != *aliasp && *urip) + *wp++ = *urip++; + } + else if (wild_type == peruser && *aliasp == '~' && *(aliasp+1) == '/') { + aliasp++; + while (*urip != *aliasp && *urip) + *wp++ = *urip++; + } else { /* Other characters are compared literally */ if (*urip++ != *aliasp++) return 0; @@ -222,6 +237,7 @@ * doubled slashes) */ + *wp = '\0'; return urip - uri; } @@ -229,26 +245,46 @@ { alias_entry *entries = (alias_entry *)aliases->elts; int i; + char wild[MAX_PATH_LEN]; for (i = 0; i < aliases->nelts; ++i) { alias_entry *p = &entries[i]; - int l = alias_matches (r->uri, p->fake); + int l = alias_matches (r->uri, p->fake, wild); if (l > 0) { + char *rp; + char real[MAX_PATH_LEN]; + char per_user_web = 0; + + strcpy(real,p->real); + if (rp = (char *)index(real,'*')) { + strcpy(rp, wild); + strcpy(rp+strlen(wild),p->real+(rp-real+1)); + } + if (real[1] == '~' && wild[0]) { + per_user_web = 1; + strcpy(real+1, wild); + strcpy(real+1+strlen(wild),p->real+2); + } + if (p->user[0]) { + struct stat finfo; + if(stat(real,&finfo) != -1 && + finfo.st_uid != uname2id(p->user)) continue; + } if (p->handler) { /* Set handler, and leave a note for mod_cgi */ r->handler = pstrdup(r->pool, p->handler); table_set (r->notes, "alias-forced-type", p->handler); } *status = p->redir_status; - if (doesc) { char *escurl; escurl = os_escape_path(r->pool, r->uri + l, 1); - - return pstrcat(r->pool, p->real, escurl, NULL); - } else - return pstrcat(r->pool, p->real, r->uri + l, NULL); + rp = pstrcat(r->pool, real, escurl, NULL); + } else + rp = pstrcat(r->pool, real, r->uri + l, NULL); + if (per_user_web) return PARTIAL; + return rp; } } @@ -283,6 +319,9 @@ } if ((ret = try_alias_list (r, serverconf->aliases, 0, &status)) != NULL) { + /* a little bit of a kludge, but it forces the + userdir module to get called */ + if (ret == PARTIAL) return DECLINED; r->filename = ret; return OK; } --- httpd.h.orig Thu Feb 19 16:42:59 1998 +++ httpd.h Fri Jun 19 09:03:50 1998 @@ -206,6 +206,7 @@ /* The default string lengths */ #define MAX_STRING_LEN HUGE_STRING_LEN #define HUGE_STRING_LEN 8192 +#define MAX_PATH_LEN 1024 /* The timeout for waiting for messages */ #define DEFAULT_TIMEOUT 300 @@ -290,6 +291,9 @@ #define SERVER_SUPPORT "http://www.apache.org/" #define DECLINED -1 /* Module declines to handle */ +#define PARTIAL -2 /* Module has done some work, there's more */ + /* to do -- used to indicate more modules */ + /* need to be called */ #define OK 0 /* Module has handled this stage. */