From 8ad30b6cd9011f856db0c8fdc70e2c9f0e5a1ed4 Mon Sep 17 00:00:00 2001
From: deuce <>
Date: Thu, 8 Mar 2018 08:37:19 +0000
Subject: [PATCH] Add support for ftpalias.cfg to parsepath().  Directory
 aliases now work like symlinks... note that they aren't shown as symlinks in
 the directory output, so it may be a bit of a surprise when relative paths
 are relative to the target rather than the alias.

---
 src/sbbs3/ftpsrvr.c | 185 ++++++++++++++++++++++++--------------------
 1 file changed, 101 insertions(+), 84 deletions(-)

diff --git a/src/sbbs3/ftpsrvr.c b/src/sbbs3/ftpsrvr.c
index 3d97bce484..1c81b4b65e 100644
--- a/src/sbbs3/ftpsrvr.c
+++ b/src/sbbs3/ftpsrvr.c
@@ -2228,14 +2228,93 @@ static BOOL can_list(lib_t *lib, dir_t *dir, user_t *user, client_t *client)
 	return FALSE;
 }
 
+static BOOL ftpalias(char* fullalias, char* filename, user_t* user, client_t* client, int* curdir)
+{
+	char*	p;
+	char*	tp;
+	char*	fname="";
+	char	line[512];
+	char	alias[512];
+	char	aliasfile[MAX_PATH+1];
+	int		dir=-1;
+	FILE*	fp;
+	BOOL	result=FALSE;
+
+	sprintf(aliasfile,"%sftpalias.cfg",scfg.ctrl_dir);
+	if((fp=fopen(aliasfile,"r"))==NULL) 
+		return(FALSE);
+
+	SAFECOPY(alias,fullalias);
+	p=strrchr(alias+1,'/');
+	if(p) {
+		*p=0;
+		fname=p+1;
+	}
+
+	if(filename==NULL /* directory */ && *fname /* filename specified */) {
+		fclose(fp);
+		return(FALSE);
+	}
+
+	while(!feof(fp)) {
+		if(!fgets(line,sizeof(line),fp))
+			break;
+
+		p=line;	/* alias */
+		SKIP_WHITESPACE(p);
+		if(*p==';')	/* comment */
+			continue;
+
+		tp=p;		/* terminator */
+		FIND_WHITESPACE(tp);
+		if(*tp) *tp=0;
+
+		if(stricmp(p,alias))	/* Not a match */
+			continue;
+
+		p=tp+1;		/* filename */
+		SKIP_WHITESPACE(p);
+
+		tp=p;		/* terminator */
+		FIND_WHITESPACE(tp);
+		if(*tp) *tp=0;
+
+		if(!strnicmp(p,BBS_VIRTUAL_PATH,strlen(BBS_VIRTUAL_PATH))) {
+			if((dir=getdir(p+strlen(BBS_VIRTUAL_PATH),user,client))<0)	{
+				lprintf(LOG_WARNING,"0000 !Invalid virtual path (%s) for %s",p,user->alias);
+				/* invalid or no access */
+				continue;
+			}
+			p=strrchr(p,'/');
+			if(p!=NULL) p++;
+			if(p!=NULL && filename!=NULL) {
+				if(*p)
+					sprintf(filename,"%s%s",scfg.dir[dir]->path,p);
+				else
+					sprintf(filename,"%s%s",scfg.dir[dir]->path,fname);
+			}
+		} else if(filename!=NULL)
+			strcpy(filename,p);
+
+		result=TRUE;	/* success */
+		break;
+	}
+	fclose(fp);
+	if(curdir!=NULL)
+		*curdir=dir;
+	return(result);
+}
+
 /*
  * Parses a path into *curlib, *curdir, and sets *pp to point to the filename
  */
 static int parsepath(char** pp, user_t* user, client_t* client, int* curlib, int* curdir)
 {
+	char filename[MAX_PATH+1];
 	int lib = *curlib;
 	int dir = *curdir;
 	char *p = *pp;
+	char *tmp;
 	char *fname = strchr(p, 0);
 	int ret = 0;
 	size_t len;
@@ -2288,14 +2367,29 @@ static int parsepath(char** pp, user_t* user, client_t* client, int* curlib, int
 				}
 			}
 			if (lib == scfg.total_libs) {
-				ret = -1;
-				lib = -1;
-				if (strchr(p, '/') != NULL) {
-					p = strchr(p, '/');
-					p++;
+				strcpy(filename, p);
+				tmp = strchr(filename, '/');
+				if (tmp != NULL)
+					*tmp = 0;
+				if (ftpalias(filename, filename, user, client, &dir) == TRUE) {
+					lib = scfg.dir[dir]->lib;
+					if (strchr(p, '/') != NULL) {
+						p = strchr(p, '/');
+						p++;
+					}
+					else
+						p = strchr(p, 0);
+				}
+				else {
+					ret = -1;
+					lib = -1;
+					if (strchr(p, '/') != NULL) {
+						p = strchr(p, '/');
+						p++;
+					}
+					else
+						p = strchr(p, 0);
 				}
-				else
-					p = strchr(p, 0);
 			}
 		}
 		else if (dir < 0) {
@@ -2345,83 +2439,6 @@ static int parsepath(char** pp, user_t* user, client_t* client, int* curlib, int
 	return ret;
 }
 
-static BOOL ftpalias(char* fullalias, char* filename, user_t* user, client_t* client, int* curdir)
-{
-	char*	p;
-	char*	tp;
-	char*	fname="";
-	char	line[512];
-	char	alias[512];
-	char	aliasfile[MAX_PATH+1];
-	int		dir=-1;
-	FILE*	fp;
-	BOOL	result=FALSE;
-
-	sprintf(aliasfile,"%sftpalias.cfg",scfg.ctrl_dir);
-	if((fp=fopen(aliasfile,"r"))==NULL) 
-		return(FALSE);
-
-	SAFECOPY(alias,fullalias);
-	p=strrchr(alias+1,'/');
-	if(p) {
-		*p=0;
-		fname=p+1;
-	}
-
-	if(filename==NULL /* directory */ && *fname /* filename specified */) {
-		fclose(fp);
-		return(FALSE);
-	}
-
-	while(!feof(fp)) {
-		if(!fgets(line,sizeof(line),fp))
-			break;
-
-		p=line;	/* alias */
-		SKIP_WHITESPACE(p);
-		if(*p==';')	/* comment */
-			continue;
-
-		tp=p;		/* terminator */
-		FIND_WHITESPACE(tp);
-		if(*tp) *tp=0;
-
-		if(stricmp(p,alias))	/* Not a match */
-			continue;
-
-		p=tp+1;		/* filename */
-		SKIP_WHITESPACE(p);
-
-		tp=p;		/* terminator */
-		FIND_WHITESPACE(tp);
-		if(*tp) *tp=0;
-
-		if(!strnicmp(p,BBS_VIRTUAL_PATH,strlen(BBS_VIRTUAL_PATH))) {
-			if((dir=getdir(p+strlen(BBS_VIRTUAL_PATH),user,client))<0)	{
-				lprintf(LOG_WARNING,"0000 !Invalid virtual path (%s) for %s",p,user->alias);
-				/* invalid or no access */
-				continue;
-			}
-			p=strrchr(p,'/');
-			if(p!=NULL) p++;
-			if(p!=NULL && filename!=NULL) {
-				if(*p)
-					sprintf(filename,"%s%s",scfg.dir[dir]->path,p);
-				else
-					sprintf(filename,"%s%s",scfg.dir[dir]->path,fname);
-			}
-		} else if(filename!=NULL)
-			strcpy(filename,p);
-
-		result=TRUE;	/* success */
-		break;
-	}
-	fclose(fp);
-	if(curdir!=NULL)
-		*curdir=dir;
-	return(result);
-}
-
 char* root_dir(char* path)
 {
 	char*	p;
-- 
GitLab