diff --git a/src/sbbs3/atcodes.cpp b/src/sbbs3/atcodes.cpp index 915eed0a4a8ef95e8246aae5f98ec7e606ab8854..46ba93021ae5e45647a266e5eb3d28c5962dea87 100644 --- a/src/sbbs3/atcodes.cpp +++ b/src/sbbs3/atcodes.cpp @@ -26,6 +26,7 @@ #include "cp437defs.h" #include "ver.h" #include "petdefs.h" +#include "filedat.h" #if defined(_WINSOCKAPI_) extern WSADATA WSAData; @@ -2268,6 +2269,20 @@ const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, safe_snprintf(str, maxlen, "%u", getusrdir(current_file->dir)); return str; } + if(strcmp(sp, "FILE_FTP_PATH") == 0) { + getfilevpath(&cfg, current_file, str, maxlen); + return str; + } + if(strcmp(sp, "FILE_WEB_PATH") == 0) { + char* p = ""; + if(cfg.dir[current_file->dir]->vpath[0] == '\0') { + p = startup->web_file_vpath_prefix; + if(*p == '/') + ++p; + } + safe_snprintf(str, maxlen, "%s%s", p, getfilevpath(&cfg, current_file, tmp, sizeof tmp)); + return str; + } } if(strcmp(sp, "FILE_NAME") == 0) return current_file->name; diff --git a/src/sbbs3/filedat.c b/src/sbbs3/filedat.c index 83051b759a9962cf2319543c545119d11cdb68c9..c345f3a0b9e313b4faafcc42e8ae54b8fc0f752e 100644 --- a/src/sbbs3/filedat.c +++ b/src/sbbs3/filedat.c @@ -634,13 +634,14 @@ char* getfilepath(scfg_t* cfg, file_t* f, char* path) return path; } -char* getfilevpath(scfg_t* cfg, file_t* f, char* path) +char* getfilevpath(scfg_t* cfg, file_t* f, char* path, size_t size) { + char vpath[LEN_DIR + 1]; const char* name = f->name == NULL ? f->file_idx.name : f->name; if(!is_valid_dirnum(cfg, f->dir)) return ""; - safe_snprintf(path, MAX_PATH, "%s/%s/%s" - ,cfg->lib[cfg->dir[f->dir]->lib]->vdir, cfg->dir[f->dir]->vdir, name); + safe_snprintf(path, size, "%s/%s" + ,dir_vpath(cfg, cfg->dir[f->dir], vpath, sizeof vpath), name); return path; } diff --git a/src/sbbs3/filedat.h b/src/sbbs3/filedat.h index 66cd1761b0f10623570380333fca8098d18e5c0c..e129ec3574abd29329000f18599a72c19769d29a 100644 --- a/src/sbbs3/filedat.h +++ b/src/sbbs3/filedat.h @@ -47,7 +47,7 @@ DLLEXPORT str_list_t loadfilenames(smb_t*, const char* filespec, time_t t, enum DLLEXPORT void sortfilenames(str_list_t, size_t count, enum file_sort); DLLEXPORT bool updatefile(scfg_t*, file_t*); DLLEXPORT char* getfilepath(scfg_t*, file_t*, char* path); -DLLEXPORT char* getfilevpath(scfg_t*, file_t*, char* path); +DLLEXPORT char* getfilevpath(scfg_t*, file_t*, char* path, size_t); DLLEXPORT off_t getfilesize(scfg_t*, file_t*); DLLEXPORT time_t getfiletime(scfg_t*, file_t*); DLLEXPORT ulong gettimetodl(scfg_t*, file_t*, uint rate_cps); diff --git a/src/sbbs3/js_filebase.c b/src/sbbs3/js_filebase.c index d8d9e1b5d90ea0400af197f486f47a48848cd47b..a45bd6a14fd170ac6b5b1457b94a574d45fea4f7 100644 --- a/src/sbbs3/js_filebase.c +++ b/src/sbbs3/js_filebase.c @@ -181,7 +181,7 @@ set_file_properties(JSContext *cx, JSObject* obj, file_t* f, enum file_detail de || !JS_DefineProperty(cx, obj, "name", STRING_TO_JSVAL(js_str), NULL, NULL, flags)) return false; - if((js_str = JS_NewStringCopyZ(cx, getfilevpath(scfg, f, path))) == NULL + if((js_str = JS_NewStringCopyZ(cx, getfilevpath(scfg, f, path, sizeof path))) == NULL || !JS_DefineProperty(cx, obj, "vpath", STRING_TO_JSVAL(js_str), NULL, NULL, flags | JSPROP_READONLY)) return false; diff --git a/src/sbbs3/scfg/scfgxfr2.c b/src/sbbs3/scfg/scfgxfr2.c index f09df723cbfcfb7e93c803cc4478aae24bba771d..c3476473252349418e015a12d9b028137f2c764f 100644 --- a/src/sbbs3/scfg/scfgxfr2.c +++ b/src/sbbs3/scfg/scfgxfr2.c @@ -1764,8 +1764,8 @@ void dir_cfg(int libnum) char* dir_transfer_path_help = "`Transfer File Path:`\n" "\n" - "This is the default storage path for files uploaded-to and available for\n" - "download-from this directory.\n" + "This is the physical storage path for files uploaded-to and available\n" + "for download-from this directory.\n" "\n" "If this setting is blank, the internal-code (lower-cased) is used as the\n" "default directory name.\n" @@ -1936,6 +1936,13 @@ void dir_cfg(int libnum) snprintf(opt[n++], MAX_OPLN, "%-27.27s%s%s","Internal Code" ,cfg.lib[cfg.dir[i]->lib]->code_prefix, cfg.dir[i]->code_suffix); snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","FidoNet Area Tag",area_tag); + if(cfg.dir[i]->vpath[0] != '\0') + SAFECOPY(str, cfg.dir[i]->vpath); + else { + init_vdir(&cfg, cfg.dir[i]); + SAFEPRINTF(str, "[%s]", dir_vpath(&cfg, cfg.dir[i], path, sizeof path)); + } + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Virtual File Path", str); snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Access Requirements" ,cfg.dir[i]->arstr); snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Upload Requirements" @@ -1964,8 +1971,7 @@ void dir_cfg(int libnum) SAFECOPY(str, path); else SAFEPRINTF(str, "[%s]", path); - snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Transfer File Path" - ,str); + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Transfer File Path", str); if(cfg.dir[i]->maxfiles) sprintf(str, "%u", cfg.dir[i]->maxfiles); else @@ -2061,83 +2067,104 @@ void dir_cfg(int libnum) SAFECOPY(cfg.dir[i]->area_tag, str); break; case 4: + uifc.helpbuf= + "`Virtual File Path:`\n" + "\n" + "This is the path, without leading or trailing slashes, where the files\n" + "in this directory will appear for users of the Synchronet FTP and Web\n" + "servers.\n" + "\n" + "If no path is specified here, then one is automatically generated and\n" + "displayed here within `[`brackets`]` for your information.\n" + "\n" + "Automatically generated virtual paths use the `Virtual Sub-directories`\n" + "naming convention as selected for the parent File Library.\n" + "\n" + "Setting this path implies that the sysop has `also` set corresponding\n" + "FTP and Web Server directory aliases (i.e. in their `ftpalias.cfg` and\n" + "`web_alias.ini` files).\n" + ; + uifc.input(WIN_L2R|WIN_SAV,0,17,"Virtual File Path" + ,cfg.dir[i]->vpath, sizeof(cfg.dir[i]->vpath) - 1, K_EDIT | K_NOSPACE); + break; + case 5: sprintf(str,"%s Access",cfg.dir[i]->sname); getar(str,cfg.dir[i]->arstr); break; - case 5: + case 6: sprintf(str,"%s Upload",cfg.dir[i]->sname); getar(str,cfg.dir[i]->ul_arstr); break; - case 6: + case 7: sprintf(str,"%s Download",cfg.dir[i]->sname); getar(str,cfg.dir[i]->dl_arstr); break; - case 7: + case 8: sprintf(str,"%s Operator",cfg.dir[i]->sname); getar(str,cfg.dir[i]->op_arstr); break; - case 8: + case 9: sprintf(str,"%s Exemption",cfg.dir[i]->sname); getar(str,cfg.dir[i]->ex_arstr); break; - case 9: + case 10: uifc.helpbuf = dir_transfer_path_help; uifc.input(WIN_L2R|WIN_SAV,0,17,"Transfer File Path" ,cfg.dir[i]->path,sizeof(cfg.dir[i]->path)-1,K_EDIT); break; - case 10: + case 11: uifc.helpbuf = max_files_help; sprintf(str,"%u",cfg.dir[i]->maxfiles); uifc.input(WIN_L2R|WIN_SAV,0,17,"Maximum Number of Files (0=Unlimited)" ,str,5,K_EDIT|K_NUMBER); cfg.dir[i]->maxfiles=atoi(str); break; - case 11: + case 12: sprintf(str,"%u",cfg.dir[i]->maxage); uifc.helpbuf = max_age_help; uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Files (in days)" ,str,5,K_EDIT|K_NUMBER); cfg.dir[i]->maxage=atoi(str); break; - case 12: + case 13: uifc.helpbuf = up_pct_help; uifc.input(WIN_MID|WIN_SAV,0,0 ,"Percentage of Credits to Credit Uploader on Upload" ,ultoa(cfg.dir[i]->up_pct,tmp,10),4,K_EDIT|K_NUMBER); cfg.dir[i]->up_pct=atoi(tmp); break; - case 13: + case 14: uifc.helpbuf = dn_pct_help; uifc.input(WIN_MID|WIN_SAV,0,0 ,"Percentage of Credits to Credit Uploader on Download" ,ultoa(cfg.dir[i]->dn_pct,tmp,10),4,K_EDIT|K_NUMBER); cfg.dir[i]->dn_pct=atoi(tmp); break; - case 14: + case 15: dir_toggle_options(cfg.dir[i]); break; - case 15: - while(1) { - n=0; - snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Extensions Allowed" - ,cfg.dir[i]->exts); - if(!cfg.dir[i]->data_dir[0]) - sprintf(str,"[%sdirs/]",cfg.data_dir); - else - strcpy(str,cfg.dir[i]->data_dir); - snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Data Directory" - ,str); - snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Upload Semaphore File" - ,cfg.dir[i]->upload_sem); - snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Sort Value and Direction" - ,file_sort_desc[cfg.dir[i]->sort]); - snprintf(opt[n++], MAX_OPLN, "%-27.27sNow %u / Was %u","Directory Index", i, cfg.dir[i]->dirnum); - opt[n][0]=0; - uifc.helpbuf= - "`Directory Advanced Options:`\n" - "\n" - "This is the advanced options menu for the selected file directory.\n" - ; + case 16: + while(1) { + n=0; + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Extensions Allowed" + ,cfg.dir[i]->exts); + if(!cfg.dir[i]->data_dir[0]) + sprintf(str,"[%sdirs/]",cfg.data_dir); + else + strcpy(str,cfg.dir[i]->data_dir); + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Data Directory" + ,str); + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Upload Semaphore File" + ,cfg.dir[i]->upload_sem); + snprintf(opt[n++], MAX_OPLN, "%-27.27s%s","Sort Value and Direction" + ,file_sort_desc[cfg.dir[i]->sort]); + snprintf(opt[n++], MAX_OPLN, "%-27.27sNow %u / Was %u","Directory Index", i, cfg.dir[i]->dirnum); + opt[n][0]=0; + uifc.helpbuf= + "`Directory Advanced Options:`\n" + "\n" + "This is the advanced options menu for the selected file directory.\n" + ; n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,4,66,&adv_dflt,0 ,"Advanced Options",opt); if(n==-1) @@ -2174,7 +2201,7 @@ void dir_cfg(int libnum) break; } } - break; + break; } } } diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index c4df44680a5e8bdec05c51142e58b26fc33e0b06..b220d56142be26c0478160470b9f03939ce2f3aa 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -74,6 +74,7 @@ typedef struct { /* Transfer Directory Info */ char code[LEN_EXTCODE+1]; /* Internal code (with optional lib prefix) */ char code_suffix[LEN_CODE+1]; /* Eight character code suffix */ char vdir[LEN_SLNAME+1]; /* Virtual Directory name */ + char vpath[LEN_DIR+1]; /* Optional vpath (e.g. alias) */ char area_tag[FIDO_AREATAG_LEN+1]; char lname[LEN_SLNAME+1], /* Long name - used for listing */ sname[LEN_SSNAME+1], /* Short name - used for prompts */ @@ -113,7 +114,7 @@ typedef struct { /* Transfer Library Information */ ex_arstr[LEN_ARSTR+1], /* Exemption Requirements (credits) */ op_arstr[LEN_ARSTR+1], /* Operator Requirements */ code_prefix[LEN_CODE+1], /* Prefix for internal code */ - parent_path[48]; /* Parent for dir paths */ + parent_path[LEN_DIR+1]; /* Parent for dir paths */ uchar ar[LEN_ARSTR+1], ul_ar[LEN_ARSTR+1], dl_ar[LEN_ARSTR+1], diff --git a/src/sbbs3/scfglib.h b/src/sbbs3/scfglib.h index 51f02132f89c49fb1e353c645719170eb227a851..25dab3dba37fe94f2ca34a931f0bab08cc2c32dd 100644 --- a/src/sbbs3/scfglib.h +++ b/src/sbbs3/scfglib.h @@ -81,6 +81,7 @@ DLLEXPORT bool is_valid_xtrnsec(scfg_t*, int); DLLEXPORT char * sub_newsgroup_name(scfg_t*, sub_t*, char*, size_t); DLLEXPORT char * sub_area_tag(scfg_t*, sub_t*, char*, size_t); DLLEXPORT char * dir_area_tag(scfg_t*, dir_t*, char*, size_t); +DLLEXPORT char * dir_vpath(scfg_t*, dir_t* dir, char* path, size_t); uint nearest_sysfaddr_index(scfg_t*, faddr_t*); faddr_t* nearest_sysfaddr(scfg_t*, faddr_t*); diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index 1e2e4bf25f43e860ef91503cec3a113c439027fe..981865d0ceaca78097c16bb923d1fb5a12a60787 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -976,3 +976,16 @@ char* dir_area_tag(scfg_t* cfg, dir_t* dir, char* str, size_t size) strupr(str); return str; } + +/****************************************************************************/ +/* Returns virtual path for a file directory, without trailing slash */ +/****************************************************************************/ +char* dir_vpath(scfg_t* cfg, dir_t* dir, char* path, size_t size) +{ + if(dir->vpath[0] != '\0') + return dir->vpath; + else + safe_snprintf(path, size, "%s/%s" + ,cfg->lib[dir->lib]->vdir, dir->vdir); + return path; +} diff --git a/src/sbbs3/scfglib2.c b/src/sbbs3/scfglib2.c index 018ce12f2c0887ab0f202360234bbff3a33f7a42..ca6ac5ab88a577b8eeda46b7aadb5008d5f9e2e5 100644 --- a/src/sbbs3/scfglib2.c +++ b/src/sbbs3/scfglib2.c @@ -308,6 +308,7 @@ bool read_file_cfg(scfg_t* cfg, char* error, size_t maxerrlen) cfg->lib[cfg->dir[i]->lib]->offline_dir=i; init_vdir(cfg, cfg->dir[i]); + SAFECOPY(cfg->dir[i]->vpath, iniGetString(section, NULL, "vpath", "", value)); SAFECOPY(cfg->dir[i]->arstr, iniGetString(section, NULL, "ars", "", value)); SAFECOPY(cfg->dir[i]->ul_arstr, iniGetString(section, NULL, "upload_ars", "", value)); diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c index f1d6861fc9e4105c185dc3bdc68924a579d2ad64..a765101527040de6b2f27afaa85c866e71a20b9c 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -784,6 +784,7 @@ bool write_file_cfg(scfg_t* cfg) iniSetString(§ion, name, "area_tag", cfg->dir[i]->area_tag, &ini_style); backslash(cfg->dir[i]->path); iniSetString(§ion, name, "path", cfg->dir[i]->path, &ini_style); + iniSetString(§ion, name, "vpath", cfg->dir[i]->vpath, &ini_style); if (cfg->dir[i]->misc&DIR_FCHK) { SAFECOPY(path, cfg->dir[i]->path);