Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (9)
......@@ -125,9 +125,9 @@ bool get_file_diz(file_t* f, char* ext, size_t maxlen)
return false;
}
printf("Parsing DIZ: %s\n", diz_fpath);
str_list_t lines = read_diz(diz_fpath);
format_diz(lines, ext, maxlen, /* allow_ansi: */false);
strListFree(&lines);
char* lines = read_diz(diz_fpath, NULL);
format_diz(lines, ext, maxlen, 0, false);
free(lines);
remove(diz_fpath);
if(mode&ASCII_ONLY)
......
......@@ -174,6 +174,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
......
/* ans2asc.c */
/* Convert ANSI messages to Synchronet .asc (Ctrl-A code) format */
/* $Id: ans2asc.c,v 1.16 2020/05/09 23:17:43 rswindell Exp $ */
/* Convert ANSI messages to Synchronet Ctrl-A code format */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
......@@ -17,28 +13,18 @@
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> /* isdigit */
#include <string.h> /* strcmp */
#include "sauce.h"
#include "git_branch.h"
#include "git_hash.h"
#ifndef CTRL_Z
#define CTRL_Z 0x1a
......@@ -46,20 +32,20 @@
static void print_usage(const char* prog)
{
char revision[16];
sscanf("$Revision: 1.16 $", "%*s %s", revision);
fprintf(stderr,"\nSynchronet ANSI-Terminal-Sequence to Ctrl-A-Code Conversion Utility v%s\n",revision);
fprintf(stderr,"\nSynchronet ANSI-Terminal-Sequence to Ctrl-A-Code Conversion Utility %s/%s\n"
,GIT_BRANCH
,GIT_HASH
);
fprintf(stderr,"\nusage: %s infile.ans [outfile.asc | outfile.msg] [[option] [...]]\n",prog);
fprintf(stderr,"\noptions:\n\n");
fprintf(stderr,"-ice treat blink as bright-background (iCE colors)\n");
fprintf(stderr,"-<columns> insert conditional-newlines to force wrap (e.g. -80)\n");
fprintf(stderr,"-newline append a newline (CRLF) sequence to output file\n");
fprintf(stderr,"-clear insert a clear screen code at beginning of output file\n");
fprintf(stderr,"-pause append a pause (hit a key) code to end of output file\n");
fprintf(stderr,"-space use space characters for cursor-right movement/alignment\n");
fprintf(stderr,"-delay <interval> insert a 1/10th second delay code at output byte interval\n");
fprintf(stderr," -ice treat blink as bright-background (iCE colors)\n");
fprintf(stderr," -<columns> insert conditional-newlines to force wrap (e.g. -80)\n");
fprintf(stderr," -normal use 'save/normal/restore' attributes for conditional new-lines\n");
fprintf(stderr," -newline append a newline (CRLF) sequence to output file\n");
fprintf(stderr," -clear insert a clear screen code at beginning of output file\n");
fprintf(stderr," -pause append a pause (hit a key) code to end of output file\n");
fprintf(stderr," -space use space characters for cursor-right movement/alignment\n");
fprintf(stderr," -delay <int> insert a 1/10th second delay code at output byte interval\n");
fprintf(stderr," (lower interval values result in more delays, slower display)\n");
}
......@@ -69,7 +55,8 @@ int main(int argc, char **argv)
int i,ch,ni;
FILE *in=stdin;
FILE *out=stdout;
int ice=0;
bool ice=false;
bool normal=false;
int cols=0;
int column=0;
int delay=0;
......@@ -96,16 +83,18 @@ int main(int argc, char **argv)
}
}
else if(strcmp(argv[i], "-ice") == 0)
ice = 1;
ice = true;
else if(strcmp(argv[i], "-clear") == 0)
clear = 1;
else if(strcmp(argv[i], "-pause") == 0)
pause = 1;
else if(strcmp(argv[i], "-space") == 0)
space = 1;
else if(strcmp(argv[i], "-normal") == 0)
normal = true;
else if(strcmp(argv[i], "-newline") == 0)
newline++;
else if(isdigit(argv[i][1]))
else if(IS_DIGIT(argv[i][1]))
cols = atoi(argv[i] + 1);
else {
print_usage(argv[0]);
......@@ -124,26 +113,40 @@ int main(int argc, char **argv)
}
}
if(in != stdin && cols < 1) {
struct sauce_charinfo info;
if(sauce_fread_charinfo(in, /* type: */NULL, &info)) {
cols = info.width;
ice = info.ice_color;
}
}
const char* cond_newline = normal ? "\1+\1N\1/\1-" : "\1/";
if(clear)
fprintf(out,"\1N\1L");
esc=0;
while((ch=fgetc(in))!=EOF && ch != CTRL_Z) {
if(ch=='[' && esc) { /* ANSI escape sequence */
if(cols && column >= cols) {
fprintf(out, cond_newline); // Conditional-newline
column = 0;
}
ni=0; /* zero number index */
memset(n,1,sizeof(n));
while((ch=fgetc(in))!=EOF) {
if(isdigit(ch)) { /* 1 digit */
if(IS_DIGIT(ch)) { /* 1 digit */
n[ni]=ch&0xf;
ch=fgetc(in);
if(ch==EOF)
break;
if(isdigit(ch)) { /* 2 digits */
if(IS_DIGIT(ch)) { /* 2 digits */
n[ni]*=10;
n[ni]+=ch&0xf;
ch=fgetc(in);
if(ch==EOF)
break;
if(isdigit(ch)) { /* 3 digits */
if(IS_DIGIT(ch)) { /* 3 digits */
n[ni]*=10;
n[ni]+=ch&0xf;
ch=fgetc(in);
......@@ -157,9 +160,9 @@ int main(int argc, char **argv)
case '=':
case '?':
ch=fgetc(in); /* First digit */
if(isdigit(ch)) ch=fgetc(in); /* l or h ? */
if(isdigit(ch)) ch=fgetc(in);
if(isdigit(ch)) fgetc(in);
if(IS_DIGIT(ch)) ch=fgetc(in); /* l or h ? */
if(IS_DIGIT(ch)) ch=fgetc(in);
if(IS_DIGIT(ch)) fgetc(in);
break;
case 'f':
case 'H':
......@@ -294,7 +297,7 @@ int main(int argc, char **argv)
break;
default:
if(cols && column >= cols) {
fprintf(out, "\1/"); // Conditional-newline
fprintf(out, cond_newline); // Conditional-newline
column = 0;
}
fputc(ch,out);
......
......@@ -32,6 +32,7 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="..\xpdev\xpdev.props" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\build\target_ia32.props" />
</ImportGroup>
......@@ -40,6 +41,7 @@
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
<Import Project="..\build\undeprecate.props" />
<Import Project="..\build\target_ia32.props" />
<Import Project="..\xpdev\xpdev.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
......@@ -70,8 +72,7 @@
<ProgramDataBaseFileName>.\msvc.win32.release\ans2asc/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
......@@ -110,8 +111,7 @@
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
......@@ -138,6 +138,12 @@
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\xpdev\xpdev.vcxproj">
<Project>{7428a1e8-56b7-4868-9c0e-29d031689feb}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -702,7 +702,6 @@ int sbbs_t::outchar(char ch)
if(lncntr || lastlinelen)
lncntr++;
lbuflen=0;
column=0;
break;
case FF: // 12
lncntr=0;
......
......@@ -162,6 +162,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c" />
</ItemGroup>
<ItemGroup>
......
......@@ -162,6 +162,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c" />
</ItemGroup>
<ItemGroup>
......
......@@ -30,6 +30,7 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
char tmp[512];
char tmp2[64];
char path[MAX_PATH+1];
bool is_op = dir_op(f->dir);
current_file = f;
getfilepath(&cfg, f, path);
......@@ -63,9 +64,21 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
bprintf(P_TRUNCATE, text[FiDescription],f->desc);
if(f->tags && f->tags[0])
bprintf(P_TRUNCATE, text[FiTags], f->tags);
if(f->author)
bprintf(P_TRUNCATE, text[FiAuthor], f->author);
if(f->author_org)
bprintf(P_TRUNCATE, text[FiGroup], f->author_org);
char* p = f->hdr.attr&MSG_ANONYMOUS ? text[UNKNOWN_USER] : f->from;
if(p != NULL && *p != '\0')
bprintf(P_TRUNCATE, text[FiUploadedBy], p);
if(is_op) {
if(f->from_ip != NULL)
bprintf(P_TRUNCATE, text[FiUploadedBy], f->from_ip);
if(f->from_host != NULL)
bprintf(P_TRUNCATE, text[FiUploadedBy], f->from_host);
if(f->from_prot != NULL)
bprintf(P_TRUNCATE, text[FiUploadedBy], f->from_prot);
}
if(f->to_list != NULL && *f->to_list != '\0')
bprintf(P_TRUNCATE, text[FiUploadedTo], f->to_list);
bprintf(P_TRUNCATE, text[FiDateUled],timestr(f->hdr.when_imported.time));
......@@ -81,10 +94,7 @@ void sbbs_t::showfileinfo(file_t* f, bool show_extdesc)
char* p = f->extdesc;
SKIP_CRLF(p);
truncsp(p);
long p_mode = P_NOATCODES;
if(!(console&CON_RAW_IN))
p_mode |= P_WORDWRAP;
putmsg(p, p_mode);
putmsg(p, P_NOATCODES | P_CPM_EOF);
newline();
}
if(f->size == -1) {
......
......@@ -28,6 +28,7 @@
#include "smblib.h"
#include "load_cfg.h" // smb_open_dir()
#include "scfglib.h"
#include "sauce.h"
/* libarchive: */
#include <archive.h>
......@@ -606,6 +607,25 @@ int file_client_hfields(file_t* f, client_t* client)
return SMB_SUCCESS;
}
int file_sauce_hfields(file_t* f, struct sauce_charinfo* info)
{
int i;
if(info == NULL)
return -1;
if(*info->author && (i = smb_hfield_str(f, SMB_AUTHOR, info->author)) != SMB_SUCCESS)
return i;
if(*info->group && (i = smb_hfield_str(f, SMB_AUTHOR_ORG, info->group)) != SMB_SUCCESS)
return i;
if(f->desc == NULL && *info->title && (i = smb_hfield_str(f, SMB_FILEDESC, info->title)) != SMB_SUCCESS)
return i;
return SMB_SUCCESS;
}
bool addfile(scfg_t* cfg, uint dirnum, file_t* f, const char* extdesc, client_t* client)
{
char fpath[MAX_PATH + 1];
......@@ -892,7 +912,7 @@ bool extract_diz(scfg_t* cfg, file_t* f, str_list_t diz_fnames, char* path, size
{
int i;
char archive[MAX_PATH + 1];
char* default_diz_fnames[] = { "FILE_ID.DIZ", "DESC.SDI", NULL };
char* default_diz_fnames[] = { "FILE_ID.ANS", "FILE_ID.DIZ", "DESC.SDI", NULL };
getfilepath(cfg, f, archive);
if(diz_fnames == NULL)
......@@ -945,39 +965,56 @@ bool extract_diz(scfg_t* cfg, file_t* f, str_list_t diz_fnames, char* path, size
return false;
}
str_list_t read_diz(const char* path)
char* read_diz(const char* path, struct sauce_charinfo* sauce)
{
FILE* fp = fopen(path, "r");
if(sauce != NULL)
memset(sauce, 0, sizeof(*sauce));
off_t len = flength(path);
FILE* fp = fopen(path, "rb");
if(fp == NULL)
return NULL;
str_list_t lines = strListReadFile(fp, NULL, /* max_line_len: */255);
if(sauce != NULL)
sauce_fread_charinfo(fp, /* type: */NULL, sauce);
if(len > LEN_EXTDESC)
len = LEN_EXTDESC;
char* buf = calloc((size_t)len + 1, 1);
if(buf != NULL)
fread(buf, (size_t)len, 1, fp);
fclose(fp);
return lines;
char* eof = strchr(buf, CTRL_Z); // CP/M EOF
if(eof != NULL)
*eof = '\0';
return buf;
}
char* format_diz(str_list_t lines, char* str, size_t maxlen, bool allow_ansi)
char* format_diz(const char* src, char* dest, size_t maxlen, int width, bool ice)
{
if(lines == NULL) {
*str = '\0';
return NULL;
}
strListTruncateTrailingWhitespaces(lines);
if(!allow_ansi) {
for(size_t i = 0; lines[i] != NULL; i++) {
strip_ansi(lines[i]);
strip_ctrl(lines[i], lines[i]);
}
if(src == NULL) {
*dest = '\0';
return dest;
}
strListFastDeleteBlanks(lines);
return strListCombine(lines, str, maxlen, "\r\n");
convert_ansi(src, dest, maxlen - 1, width, ice);
return dest;
}
// Take a verbose extended description (e.g. FILE_ID.DIZ)
// and convert to suitable short description
char* prep_file_desc(const char *src, char* dest)
char* prep_file_desc(const char* ext, char* dest)
{
int out;
char* src;
char* buf = strdup(ext);
if(buf == NULL)
src = (char*)ext;
else {
src = buf;
strip_ctrl(src, src);
}
FIND_ALPHANUMERIC(src);
for(out = 0; *src != '\0' && out < LEN_FDESC; src++) {
......@@ -995,6 +1032,7 @@ char* prep_file_desc(const char *src, char* dest)
dest[out++] = *src;
}
dest[out] = '\0';
free(buf);
return dest;
}
......
......@@ -57,10 +57,11 @@ DLLEXPORT bool addfile(scfg_t*, uint dirnum, file_t*, const char* extdesc, cli
DLLEXPORT bool removefile(scfg_t*, uint dirnum, const char* filename);
DLLEXPORT char* format_filename(const char* fname, char* buf, size_t, bool pad);
DLLEXPORT bool extract_diz(scfg_t*, file_t*, str_list_t diz_fname, char* path, size_t);
DLLEXPORT str_list_t read_diz(const char* path);
DLLEXPORT char* format_diz(str_list_t lines, char*, size_t maxlen, bool allow_ansi);
DLLEXPORT char* read_diz(const char* path, struct sauce_charinfo*);
DLLEXPORT char* format_diz(const char* src, char* dest, size_t maxlen, int width, bool ice_color);
DLLEXPORT char* prep_file_desc(const char *src, char* dst);
DLLEXPORT int file_client_hfields(file_t*, client_t*);
DLLEXPORT int file_sauce_hfields(file_t*, struct sauce_charinfo*);
DLLEXPORT str_list_t directory(const char* path);
DLLEXPORT long create_archive(const char* archive, const char* format
......
......@@ -170,6 +170,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="userdat.c" />
</ItemGroup>
<ItemGroup>
......
......@@ -42,6 +42,7 @@
#include "cryptlib.h"
#include "xpprintf.h" // vasprintf
#include "md5.h"
#include "sauce.h"
#include "git_branch.h"
#include "git_hash.h"
......@@ -1074,19 +1075,22 @@ static void receive_thread(void* arg)
if(scfg.dir[f.dir]->misc&DIR_DIZ) {
lprintf(LOG_DEBUG,"%04d <%s> DATA Extracting DIZ from: %s",xfer.ctrl_sock, xfer.user->alias,xfer.filename);
if(extract_diz(&scfg, &f, /* diz_fnames */NULL, tmp, sizeof(tmp))) {
struct sauce_charinfo sauce;
lprintf(LOG_DEBUG,"%04d <%s> DATA Parsing DIZ: %s",xfer.ctrl_sock, xfer.user->alias,tmp);
str_list_t lines = read_diz(tmp);
format_diz(lines, extdesc, sizeof(extdesc), /* allow_ansi: */false);
strListFree(&lines);
char* lines = read_diz(tmp, &sauce);
format_diz(lines, extdesc, sizeof(extdesc), sauce.width, sauce.ice_color);
free(lines);
if(!fdesc[0]) { /* use for normal description */
prep_file_desc(extdesc, fdesc); /* strip control chars and dupe chars */
}
file_sauce_hfields(&f, &sauce);
ftp_remove(xfer.ctrl_sock, __LINE__, tmp, xfer.user->alias);
} else
lprintf(LOG_DEBUG,"%04d <%s> DATA DIZ does not exist in: %s",xfer.ctrl_sock, xfer.user->alias ,xfer.filename);
} /* FILE_ID.DIZ support */
smb_hfield_str(&f, SMB_FILEDESC, fdesc);
if(f.desc == NULL)
smb_new_hfield_str(&f, SMB_FILEDESC, fdesc);
if(filedat) {
if(!updatefile(&scfg, &f))
lprintf(LOG_ERR,"%04d <%s> !DATA ERROR updating file (%s) in database"
......
......@@ -20,6 +20,7 @@
****************************************************************************/
#include "sbbs.h"
#include "sauce.h"
#include "filedat.h"
#include "js_request.h"
#include <stdbool.h>
......@@ -205,6 +206,16 @@ set_file_properties(JSContext *cx, JSObject* obj, file_t* f, enum file_detail de
|| !JS_DefineProperty(cx, obj, "from_port", STRING_TO_JSVAL(js_str), NULL, NULL, flags)))
return false;
if(((f->author != NULL && *f->author != '\0') || detail > file_detail_extdesc)
&& ((js_str = JS_NewStringCopyZ(cx, f->author)) == NULL
|| !JS_DefineProperty(cx, obj, "author", STRING_TO_JSVAL(js_str), NULL, NULL, flags)))
return false;
if(((f->author_org != NULL && *f->author_org != '\0') || detail > file_detail_extdesc)
&& ((js_str = JS_NewStringCopyZ(cx, f->author_org)) == NULL
|| !JS_DefineProperty(cx, obj, "author_org", STRING_TO_JSVAL(js_str), NULL, NULL, flags)))
return false;
if(((f->to_list != NULL && *f->to_list != '\0') || detail > file_detail_extdesc)
&& ((js_str = JS_NewStringCopyZ(cx, f->to_list)) == NULL
|| !JS_DefineProperty(cx, obj, "to_list", STRING_TO_JSVAL(js_str), NULL, NULL, flags)))
......@@ -464,6 +475,36 @@ parse_file_properties(JSContext *cx, JSObject* obj, file_t* file, char** extdesc
}
}
prop_name = "author";
if(JS_GetProperty(cx, obj, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
if(cp == NULL) {
JS_ReportError(cx, "Invalid '%s' string in file object", prop_name);
return SMB_FAILURE;
}
if(smb_hfield_str(file, SMB_AUTHOR, cp) != SMB_SUCCESS) {
free(cp);
JS_ReportError(cx, "Error %d adding '%s' property to file object", result, prop_name);
return result;
}
}
prop_name = "author_org";
if(JS_GetProperty(cx, obj, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
HANDLE_PENDING(cx, cp);
if(cp == NULL) {
JS_ReportError(cx, "Invalid '%s' string in file object", prop_name);
return SMB_FAILURE;
}
if(smb_hfield_str(file, SMB_AUTHOR_ORG, cp) != SMB_SUCCESS) {
free(cp);
JS_ReportError(cx, "Error %d adding '%s' property to file object", result, prop_name);
return result;
}
}
prop_name = "desc";
if(JS_GetProperty(cx, obj, prop_name, &val) && !JSVAL_NULL_OR_VOID(val)) {
JSVALUE_TO_RASTRING(cx, val, cp, &cp_sz, NULL);
......@@ -1049,12 +1090,14 @@ static void get_diz(scfg_t* scfg, file_t* file, char** extdesc)
char diz_fpath[MAX_PATH + 1];
if(extract_diz(scfg, file, /* diz_fnames: */NULL, diz_fpath, sizeof(diz_fpath))) {
char extbuf[LEN_EXTDESC + 1] = "";
str_list_t lines = read_diz(diz_fpath);
struct sauce_charinfo sauce;
char* lines = read_diz(diz_fpath, &sauce);
if(lines != NULL) {
format_diz(lines, extbuf, sizeof(extbuf), /* allow_ansi: */false);
strListFree(&lines);
format_diz(lines, extbuf, sizeof(extbuf), sauce.width, sauce.ice_color);
free(lines);
free(*extdesc);
*extdesc = strdup(extbuf);
file_sauce_hfields(file, &sauce);
if(file->desc == NULL)
smb_new_hfield_str(file, SMB_FILEDESC, prep_file_desc(extbuf, extbuf));
}
......
......@@ -45,6 +45,7 @@ int sbbs_t::listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode
file_t* bf[BF_MAX]; /* bf is batch flagged files */
smb_t smb;
ulong file_row[26];
size_t longest = 0;
if(!smb_init_dir(&cfg, &smb, dirnum))
return 0;
......@@ -69,6 +70,12 @@ int sbbs_t::listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode
return 0;
}
for(i = 0; i < file_count; i++) {
size_t len = strlen(file_list[i].name);
if(len > longest)
longest = len;
}
if(!tofile) {
action=NODE_LFIL;
getnodedat(cfg.node_num,&thisnode,0);
......@@ -263,9 +270,9 @@ int sbbs_t::listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode
else if(tofile)
listfiletofile(f, tofile);
else if(mode&FL_FINDDESC)
disp=listfile(f, dirnum, filespec, letter);
disp=listfile(f, dirnum, filespec, letter, longest);
else
disp=listfile(f, dirnum, nulstr, letter);
disp=listfile(f, dirnum, nulstr, letter, longest);
if(!disp && letter>'A') {
next=m-1;
letter--;
......@@ -340,9 +347,9 @@ int sbbs_t::listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode
/* Prints one file's information on a single line */
/* Return 1 if displayed, 0 otherwise */
/****************************************************************************/
bool sbbs_t::listfile(file_t* f, uint dirnum, const char *search, const char letter)
bool sbbs_t::listfile(file_t* f, uint dirnum, const char *search, const char letter, size_t namelen)
{
char *ptr,*cr,*lf;
char *ptr;
bool exist = true;
char* ext=NULL;
char path[MAX_PATH+1];
......@@ -356,9 +363,14 @@ bool sbbs_t::listfile(file_t* f, uint dirnum, const char *search, const char let
return false;
}
cond_newline();
attr(cfg.color[clr_filename]);
char fname[13]; /* This is one of the only 8.3 filename formats left! (used for display purposes only) */
bprintf("%-*s", (int)sizeof(fname)-1, format_filename(f->name, fname, sizeof(fname)-1, /* pad: */TRUE));
char fname[SMB_FILEIDX_NAMELEN + 1];
if(namelen < 12 || cols < 132)
namelen = 12;
else if(namelen > sizeof(fname) - 1)
namelen = sizeof(fname) - 1;
bprintf("%-*s", namelen, format_filename(f->name, fname, namelen, /* pad: */TRUE));
getfilepath(&cfg, f, path);
if(f->extdesc != NULL && *f->extdesc && !(useron.misc&EXTDESC))
......@@ -427,35 +439,13 @@ bool sbbs_t::listfile(file_t* f, uint dirnum, const char *search, const char let
}
CRLF;
} else {
char* ext_desc = strdup((char*)ext);
truncsp(ext_desc);
ptr=(char*)ext_desc;
SKIP_CRLF(ptr);
while(ptr && *ptr && !msgabort()) {
cr=strchr(ptr,CR);
lf=strchr(ptr,LF);
if(lf && (lf<cr || !cr)) cr=lf;
if(cr>ptr+LEN_FDESC)
cr=ptr+LEN_FDESC;
else if(cr)
*cr=0;
char str[256];
sprintf(str,"%.*s\r\n",LEN_FDESC,ptr);
putmsg(str,P_NOATCODES|P_SAVEATR);
if(!cr) {
if(strlen(ptr)>LEN_FDESC)
cr=ptr+LEN_FDESC;
else
break;
}
if(!(*(cr+1)) || !(*(cr+2)))
break;
bprintf("%21s",nulstr);
ptr=cr;
if(!(*ptr)) ptr++;
while(*ptr==LF || *ptr==CR) ptr++;
}
free(ext_desc);
truncsp(ext);
while(strncmp(ext, "\r\n", 2) == 0
|| strnicmp(ext, "\001N", 2) == 0
|| strnicmp(ext, "\0010", 2) == 0
|| strnicmp(ext, "\001W", 2) == 0)
ext += 2;
putmsg(ext, P_INDENT | P_NOATCODES | P_CPM_EOF | P_TRUNCATE);
}
return true;
}
......@@ -642,8 +632,8 @@ int sbbs_t::batchflagprompt(smb_t* smb, file_t** bf, ulong* row, uint total
remcdt = TRUE;
remfile = TRUE;
if(dir_op(smb->dirnum)) {
remcdt=!noyes(text[RemoveCreditsQ]);
remfile=!noyes(text[DeleteFileQ]);
remcdt=!noyes(text[RemoveCreditsQ]);
}
}
else if(ch=='M') {
......
......@@ -1747,15 +1747,15 @@ static void pop3_thread(void* arg)
update_clients();
client_off(socket);
SOCKET sock = socket;
mail_close_socket(&socket, &session);
/* Must be last */
{
int32_t remain = thread_down();
if(startup->options&MAIL_OPT_DEBUG_POP3)
lprintf(LOG_DEBUG,"%04d %s [%s] session thread terminated (%u threads remain, %lu clients served)"
,socket, client.protocol, host_ip, remain, ++stats.pop3_served);
,sock, client.protocol, host_ip, remain, ++stats.pop3_served);
}
/* Must be last */
mail_close_socket(&socket, &session);
}
static ulong rblchk(SOCKET sock, const char* prot, union xp_sockaddr *addr, const char* rbl_addr)
......@@ -5028,22 +5028,22 @@ static void smtp_thread(void* arg)
update_clients();
client_off(socket);
{
int32_t remain = thread_down();
lprintf(LOG_INFO,"%04d %s %s Session thread terminated (%u threads remain, %lu clients served)"
,socket, client.protocol, client_id, remain, ++stats.smtp_served);
}
free(mailproc_to_match);
#ifdef _WIN32
if(relay_user.number) {
if(startup->sound.logout[0] && !sound_muted(&scfg))
PlaySound(startup->sound.logout, NULL, SND_ASYNC|SND_FILENAME);
}
#endif
SOCKET sock = socket;
mail_close_socket(&socket, &session);
/* Must be last */
mail_close_socket(&socket, &session);
{
int32_t remain = thread_down();
lprintf(LOG_INFO,"%04d %s %s Session thread terminated (%u threads remain, %lu clients served)"
,sock, client.protocol, client_id, remain, ++stats.smtp_served);
}
free(mailproc_to_match);
}
BOOL bounce(SOCKET sock, smb_t* smb, smbmsg_t* msg, char* err, BOOL immediate)
......
......@@ -91,6 +91,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
uchar exatr=0;
char mark = '\0';
int i;
long col = column;
ulong l=0;
uint lines_printed = 0;
struct mouse_hotspot hot_spot = {0};
......@@ -143,7 +144,9 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
}
// fallthrough
default: // printing char
if(((*mode)&P_TRUNCATE) && column >= (cols - 1)) {
if(((*mode) & P_INDENT) && column < col)
cursor_right(col - column);
else if(((*mode)&P_TRUNCATE) && column >= (cols - 1)) {
l++;
continue;
} else if((*mode)&P_WRAP) {
......
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sauce.h"
#include "genwrap.h"
#include "filewrap.h"
// Saves and restores current file position
// Note: Does not support comments
bool sauce_fread_record(FILE* fp, sauce_record_t* record)
{
off_t offset = ftello(fp);
if(offset == -1)
return false;
if(fseeko(fp, -(int)sizeof(*record), SEEK_END) != 0)
return false;
bool result = fread(record, sizeof(*record), 1, fp) == 1
&& memcmp(record->id, SAUCE_ID, SAUCE_LEN_ID) == 0
&& memcmp(record->ver, SAUCE_VERSION, SAUCE_LEN_VERSION) == 0;
fseeko(fp, offset, SEEK_SET);
return result;
}
// Get 'type' and/or 'info' from SAUCE record of open file (fp) of DataType 'Character'
bool sauce_fread_charinfo(FILE* fp, enum sauce_char_filetype* type, struct sauce_charinfo* info)
{
sauce_record_t record;
if(!sauce_fread_record(fp, &record))
return false;
if(record.datatype != sauce_datatype_char)
return false;
if(type != NULL)
*type = record.filetype;
if(info != NULL) {
memset(info, 0, sizeof(*info));
SAFECOPY(info->title, record.title), truncsp(info->title);
SAFECOPY(info->author, record.author), truncsp(info->author);
SAFECOPY(info->group, record.group), truncsp(info->group);
SAFECOPY(info->date, record.date), truncsp(info->date);
info->width = record.tinfo1;
info->height = record.tinfo2;
switch(record.filetype) {
case sauce_char_filetype_ascii:
case sauce_char_filetype_ansi:
case sauce_char_filetype_ansimation:
if(record.tflags & sauce_ansiflag_nonblink)
info->ice_color = true;
break;
}
}
return true;
}
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#ifndef SAUCE_H_
#define SAUCE_H_
#include <stdio.h>
#include <stdbool.h>
#include "saucedefs.h"
struct sauce_charinfo {
char title[SAUCE_LEN_TITLE + 1];
char author[SAUCE_LEN_AUTHOR + 1];
char group[SAUCE_LEN_GROUP + 1];
char date[SAUCE_LEN_DATE + 1];
int height;
int width;
bool ice_color;
};
#ifdef __cplusplus
extern "C" {
#endif
// Note: Does not support comments
bool sauce_fread_record(FILE*, sauce_record_t*);
bool sauce_fread_charinfo(FILE*, enum sauce_char_filetype*, struct sauce_charinfo*);
#ifdef __cplusplus
}
#endif
#endif /* Don't add anything after this line */
......@@ -1049,7 +1049,7 @@ public:
long delfiles(const char *inpath, const char *spec, size_t keep = 0);
/* listfile.cpp */
bool listfile(file_t*, uint dirnum, const char *search, const char letter);
bool listfile(file_t*, uint dirnum, const char *search, const char letter, size_t namelen);
int listfiles(uint dirnum, const char *filespec, FILE* tofile, long mode);
int listfileinfo(uint dirnum, const char *filespec, long mode);
void listfiletofile(file_t*, FILE*);
......
......@@ -646,6 +646,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="scandirs.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
......
......@@ -753,6 +753,7 @@ typedef enum { /* Values for xtrn_t.event */
#define P_MARKUP (1<<16) /* Support StyleCodes/Rich/StructuredText */
#define P_HIDEMARKS (1<<17) /* Hide the mark-up characters */
#define P_REMOTE (1<<18) /* Only print when online == ON_REMOTE */
#define P_INDENT (1<<19) /* Indent lines to current cursor column */
/* Bits in 'mode' for listfiles */
#define FL_ULTIME (1<<0) /* List files by upload time */
......
......@@ -177,6 +177,7 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="sauce.c" />
<ClCompile Include="sbbsecho.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
......
......@@ -94,6 +94,114 @@ char* strip_ansi(char* str)
return str;
}
// Sort of a stripped down version of ANS2ASC
char* convert_ansi(const char* src, char* dest, size_t len, int width, BOOL ice_color)
{
const char* s = src;
char* d = dest;
char* p;
ulong n[10];
size_t nc;
int column = 0;
while(*s != '\0' && d < dest + len) {
if(*s == ESC && *(s + 1) == '[') {
s += 2;
nc = 0;
do {
n[nc] = strtoul(s, &p, 10);
if(p == s || p == NULL)
break;
nc++;
s = p;
if(*s != ';')
break;
s++;
} while(nc < sizeof(n) / sizeof(n[0]));
while(*s != '\0' && (*s < '@' || *s > '~'))
s++;
if(*s == 'C') { // Cursor right
if(n[0] < 1)
n[0] = 1;
while(n[0] >= 1 && d < dest + len) {
*(d++) = ' ';
n[0]--;
column++;
}
} else if(*s == 'm') { // Color / Attributes
for(size_t i = 0; i < nc && d < dest + len; i++) {
*(d++) = CTRL_A;
switch(n[i]) {
case 0:
case 2:
*(d++) = 'N';
break;
case 1:
*(d++) = 'H';
break;
case 3:
case 4:
case 5: /* blink */
case 6:
case 7:
*(d++) = ice_color ? 'E': 'I';
break;
case 30:
*(d++) = 'K';
break;
case 31:
*(d++) = 'R';
break;
case 32:
*(d++) = 'G';
break;
case 33:
*(d++) = 'Y';
break;
case 34:
*(d++) = 'B';
break;
case 35:
*(d++) = 'M';
break;
case 36:
*(d++) = 'C';
break;
case 37:
*(d++) = 'W';
break;
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
*(d++) = '0' + ((int)n[i] - 40);
break;
}
}
}
if(*s != '\0') // Skip "final byte"
s++;
} else {
if(*s == '\r' || *s == '\n') {
*(d++) = *(s++);
column = 0;
} else {
if(width && column >= width) {
d += sprintf(d, "\1+\1N\1/\1-"); // Save, normal, cond-newline, restore
column = 0;
}
*(d++) = *(s++);
column++;
}
}
}
*d = '\0';
return dest;
}
char* strip_exascii(const char *str, char* dest)
{
int i,j;
......
......@@ -52,6 +52,7 @@ DLLEXPORT str_list_t findstr_list(const char* fname);
DLLEXPORT BOOL trashcan(scfg_t* cfg, const char *insearch, const char *name);
DLLEXPORT char * trashcan_fname(scfg_t* cfg, const char *name, char* fname, size_t);
DLLEXPORT str_list_t trashcan_list(scfg_t* cfg, const char* name);
DLLEXPORT char * convert_ansi(const char* src, char* dest, size_t, int width, BOOL ice_color);
DLLEXPORT char * strip_ansi(char* str);
DLLEXPORT char * strip_exascii(const char *str, char* dest);
DLLEXPORT char * strip_space(const char *str, char* dest);
......
......@@ -311,8 +311,8 @@ enum {
,TagFilePrompt
,Unused299
,Unused300
,Unused301
,Unused302
,FiAuthor
,FiGroup
,FileAlreadyInQueue
,FileIsNotOnline
,FileAddedToBatDlQueue
......
......@@ -479,8 +479,8 @@ const char * const text_defaults[TOTAL_TEXT]={
"\x3a\x20" // 298 TagFilePrompt
,"\x55\x4e\x55\x53\x45\x44\x32\x39\x39" // 299 Unused299
,"\x55\x4e\x55\x53\x45\x44\x33\x30\x30" // 300 Unused300
,"\x55\x4e\x55\x53\x45\x44\x33\x30\x31" // 301 Unused301
,"\x55\x4e\x55\x53\x45\x44\x33\x30\x32" // 302 Unused302
,"\x0d\x0a\x01\x6e\x01\x67\x41\x75\x74\x68\x6f\x72\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3a\x01\x68\x20\x25\x73" // 301 FiAuthor
,"\x0d\x0a\x01\x6e\x01\x67\x47\x72\x6f\x75\x70\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3a\x01\x68\x20\x25\x73" // 302 FiGroup
,"\x01\x77\x01\x68\x0d\x0a\x25\x73\x20\x69\x73\x20\x61\x6c\x72\x65\x61\x64\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x71\x75\x65\x75\x65"
"\x2e\x0d\x0a" // 303 FileAlreadyInQueue
,"\x01\x77\x01\x68\x01\x2f\x46\x69\x6c\x65\x20\x69\x73\x20\x6e\x6f\x74\x20\x6f\x6e\x6c\x69\x6e\x65\x2e\x0d\x0a" // 304 FileIsNotOnline
......
......@@ -94,6 +94,7 @@
<ItemGroup>
<ClCompile Include="dat_rec.c" />
<ClCompile Include="filedat.c" />
<ClCompile Include="sauce.c" />
<ClCompile Include="upgrade_to_v319.c" />
<ClCompile Include="userdat.c" />
</ItemGroup>
......
......@@ -20,6 +20,7 @@
****************************************************************************/
#include "sbbs.h"
#include "sauce.h"
#include "filedat.h"
/****************************************************************************/
......@@ -152,15 +153,17 @@ bool sbbs_t::uploadfile(file_t* f)
if(cfg.dir[f->dir]->misc&DIR_DIZ) {
lprintf(LOG_DEBUG, "Extracting DIZ from: %s", path);
if(extract_diz(&cfg, f, /* diz_fnames: */NULL, str, sizeof(str))) {
struct sauce_charinfo sauce;
lprintf(LOG_DEBUG, "Parsing DIZ: %s", str);
str_list_t lines = read_diz(str);
char* lines = read_diz(str, &sauce);
if(lines != NULL)
format_diz(lines, ext, sizeof(ext), /* allow_ansi: */false);
strListFree(&lines);
format_diz(lines, ext, sizeof(ext), sauce.width, sauce.ice_color);
free(lines);
file_sauce_hfields(f, &sauce);
if(f->desc == NULL || f->desc[0] == 0) {
char desc[LEN_FDESC];
char desc[LEN_FDESC + 1];
SAFECOPY(desc, (char*)ext);
strip_exascii(desc, desc);
prep_file_desc(desc, desc);
......@@ -169,7 +172,7 @@ bool sbbs_t::uploadfile(file_t* f)
break;
if(desc[i] == '\0')
i = 0;
smb_hfield_str(f, SMB_FILEDESC, desc + i);
smb_new_hfield_str(f, SMB_FILEDESC, desc + i);
}
remove(str);
} else
......@@ -537,7 +540,6 @@ bool sbbs_t::bulkupload(uint dirnum)
smb_freemsgmem(&f);
smb_hfield_str(&f, SMB_FILENAME, dirent->d_name);
uint32_t cdt = (uint32_t)flength(str);
smb_hfield_bin(&f, SMB_COST, cdt);
bprintf(text[BulkUploadDescPrompt], format_filename(f.name, fname, 12, /* pad: */FALSE), cdt/1024);
if(strcmp(f.name, fname) != 0)
SAFECOPY(desc, f.name);
......
......@@ -168,6 +168,9 @@
#define SENDERTIME 0x0d /* authentication/connection time */
#define SENDERSERVER 0x0e /* server hostname that authenticated user */
#define SMB_AUTHOR 0x10
#define SMB_AUTHOR_ORG 0x16
#define REPLYTO 0x20 /* Name only */
#define REPLYTOAGENT 0x21
#define REPLYTONETTYPE 0x22
......@@ -597,6 +600,8 @@ typedef struct { /* Message or File */
*from_host, /* From host name */
*from_prot, /* From protocol (e.g. "Telnet", "NNTP", "HTTP", etc.) */
*from_port, /* From TCP/UDP port number */
*author, /* Author */
*author_org, /* Author's organization */
*replyto, /* Reply-to name */
*replyto_ext, /* Reply-to extension */
*replyto_list, /* Comma-separated list of mailboxes, RFC822-style */
......
......@@ -158,8 +158,6 @@ str_list_t smb_msghdr_str_list(smbmsg_t* msg)
tt=msg->expiration;
strListAppendFormat(&list, HFIELD_NAME_FMT "%.24s", "expiration", ctime_r(&tt, tmp));
}
if(msg->cost)
strListAppendFormat(&list, HFIELD_NAME_FMT "%u", "cost", msg->cost);
/* data fields */
strListAppendFormat(&list, HFIELD_NAME_FMT "%06"PRIX32"h" ,"data_offset" ,msg->hdr.offset);
......
......@@ -776,6 +776,12 @@ static void set_convenience_ptr(smbmsg_t* msg, uint16_t hfield_type, void* hfiel
case SENDERPORT:
msg->from_port=(char*)hfield_dat;
break;
case SMB_AUTHOR:
msg->author=(char*)hfield_dat;
break;
case SMB_AUTHOR_ORG:
msg->author_org=(char*)hfield_dat;
break;
case REPLYTO:
msg->replyto=(char*)hfield_dat;
break;
......@@ -926,6 +932,8 @@ static void clear_convenience_ptrs(smbmsg_t* msg)
msg->to_list=NULL;
memset(&msg->to_net,0,sizeof(net_t));
msg->author=NULL;
msg->author_org=NULL;
msg->cc_list=NULL;
msg->subj=NULL;
msg->summary=NULL;
......
......@@ -43,6 +43,9 @@ char* smb_hfieldtype(uint16_t type)
case SENDERTIME: return("SenderTime");
case SENDERSERVER: return("SenderServer");
case SMB_AUTHOR: return("Author");
case SMB_AUTHOR_ORG: return("AuthorOrg");
case REPLYTO: return("Reply-To"); /* RFC-compliant */
case REPLYTOAGENT: return("Reply-ToAgent");
case REPLYTONETTYPE: return("Reply-ToNetType");
......