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 (1)
......@@ -440,7 +440,9 @@ static uint32_t color_value(uint32_t col)
{
if (col & 0x80000000)
return col;
return (0xff << 24) | (palette[col].red << 16) | (palette[col].green << 8) | palette[col].blue;
if (col < sizeof(palette) / sizeof(palette[0]))
return (0xff << 24) | (palette[col].red << 16) | (palette[col].green << 8) | palette[col].blue;
fprintf(stderr, "Invalid colour value: %08x\n", col);
}
static struct rectlist *get_full_rectangle_locked(struct bitmap_screen *screen)
......
......@@ -189,12 +189,15 @@ int sortorder[sizeof(sort_order)/sizeof(struct sort_order_info)];
char *screen_modes[]={ "Current", "80x25", "80x28", "80x30", "80x43", "80x50", "80x60", "132x37 (16:9)", "132x52 (5:4)", "132x25", "132x28", "132x30", "132x34", "132x43", "132x50", "132x60", "C64", "C128 (40col)", "C128 (80col)", "Atari", "Atari XEP80", "Custom", "EGA 80x25", NULL};
static char *screen_modes_enum[]={"Current", "80x25", "80x28", "80x30", "80x43", "80x50", "80x60", "132x37", "132x52", "132x25", "132x28", "132x30", "132x34", "132x43", "132x50", "132x60", "C64", "C128-40col", "C128-80col", "Atari", "Atari-XEP80", "Custom", "EGA80x25", NULL};
char *log_levels[]={"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Info", "Debug", NULL};
static char *log_level_desc[]={"None", "Alerts", "Critical Errors", "Errors", "Warnings", "Notices", "Normal", "All (Debug)", NULL};
char *rate_names[]={"300", "600", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "76800", "115200", "Current", NULL};
int rates[]={300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 0};
static char *rip_versions[] = {"Off", "RIPv1", "RIPv3"};
static char *fc_names[] = {"RTS/CTS", "XON/XOFF", "RTS/CTS and XON/XOFF", "None", NULL};
static char *fc_enum[] = {"RTSCTS", "XONXOFF", "RTSCTS_XONXOFF", "None", NULL};
......@@ -687,7 +690,7 @@ void read_item(str_list_t listfile, struct bbslist *entry, char *bbsname, int id
entry->screen_mode=iniGetEnum(section,NULL,"ScreenMode",screen_modes_enum,SCREEN_MODE_CURRENT);
entry->nostatus=iniGetBool(section,NULL,"NoStatus",FALSE);
entry->hidepopups=iniGetBool(section,NULL,"HidePopups",FALSE);
entry->rip=iniGetBool(section,NULL,"RIP",FALSE);
entry->rip=iniGetEnum(section,NULL,"RIP",rip_versions,RIP_VERSION_NONE);
iniGetString(section,NULL,"DownloadPath",home,entry->dldir);
iniGetString(section,NULL,"UploadPath",home,entry->uldir);
......@@ -909,6 +912,28 @@ void configure_log(struct bbslist *item, const char *itemname, str_list_t inifil
}
}
static int
get_rip_version(int oldver, int *changed)
{
int cur = oldver;
int bar = 0;
uifc.helpbuf= "`RIP Version`\n\n"
"RIP v1 requires EGA mode while RIP v3\n"
"works in any screen mode.";
switch(uifc.list(WIN_SAV,0,0,0,&cur,&bar,"RIP Mode",rip_versions)) {
case -1:
check_exit(FALSE);
break;
case RIP_VERSION_NONE:
case RIP_VERSION_1:
case RIP_VERSION_3:
if (cur != oldver)
*changed = 1;
}
return cur;
}
int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isdefault)
{
char opt[19][69]; /* 21=Holds number of menu items, 80=Number of columns */
......@@ -994,7 +1019,7 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd
sprintf(opt[i++], "Address Family %s",address_family_names[item->address_family]);
sprintf(opt[i++], "Font %s",item->font);
sprintf(opt[i++], "Hide Popups %s",item->hidepopups?"Yes":"No");
sprintf(opt[i++], "RIP %s",item->rip?"Yes":"No");
sprintf(opt[i++], "RIP %s",rip_versions[item->rip]);
opt[i][0]=0;
uifc.changes=0;
......@@ -1282,9 +1307,9 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd
break;
default:
iniSetEnum(&inifile,itemname,"ScreenMode",screen_modes_enum,item->screen_mode,&ini_style);
if (item->rip && item->screen_mode != SCREEN_MODE_EGA_80X25 && item->screen_mode != SCREEN_MODE_80X43) {
item->rip = FALSE;
iniSetBool(&inifile,itemname,"RIP",item->rip,&ini_style);
if (item->rip == RIP_VERSION_1 && item->screen_mode != SCREEN_MODE_EGA_80X25 && item->screen_mode != SCREEN_MODE_80X43) {
item->rip = RIP_VERSION_3;
iniSetEnum(&inifile,itemname,"RIP",rip_versions,item->rip,&ini_style);
}
if(item->screen_mode == SCREEN_MODE_C64) {
SAFECOPY(item->font,font_names[33]);
......@@ -1411,13 +1436,12 @@ int edit_list(struct bbslist **list, struct bbslist *item,char *listpath,int isd
iniSetBool(&inifile,itemname,"HidePopups",item->hidepopups,&ini_style);
break;
case 17:
item->rip = !item->rip;
changed = 1;
if (item->rip) {
item->rip = get_rip_version(item->rip, &changed);
if (item->rip == RIP_VERSION_1) {
item->screen_mode = 4;
iniSetEnum(&inifile,itemname,"ScreenMode",screen_modes_enum,item->screen_mode,&ini_style);
}
iniSetBool(&inifile,itemname,"RIP",item->rip,&ini_style);
iniSetEnum(&inifile,itemname,"RIP",rip_versions,item->rip,&ini_style);
}
if(uifc.changes)
changed=1;
......@@ -1467,7 +1491,7 @@ void add_bbs(char *listpath, struct bbslist *bbs)
iniSetEnum(&inifile, bbs->name, "AddressFamily", address_families, bbs->address_family, &ini_style);
iniSetString(&inifile,bbs->name,"Font",bbs->font,&ini_style);
iniSetBool(&inifile,bbs->name,"HidePopups",bbs->hidepopups,&ini_style);
iniSetBool(&inifile,bbs->name,"RIP",bbs->rip,&ini_style);
iniSetEnum(&inifile,bbs->name,"RIP",rip_versions,bbs->rip,&ini_style);
iniSetString(&inifile,bbs->name,"Comment",bbs->comment,&ini_style);
if((listfile=fopen(listpath,"w"))!=NULL) {
iniWriteFile(listfile,inifile);
......
......@@ -66,6 +66,12 @@ enum {
,ADDRESS_FAMILY_INET6
};
enum {
RIP_VERSION_NONE
,RIP_VERSION_1
,RIP_VERSION_3
};
/* NOTE: changing this may require updating sort_order in bbslist.c */
struct bbslist {
char name[LIST_NAME_MAX+1];
......
......@@ -226,6 +226,7 @@ static struct {
enum rip_state state;
enum rip_state newstate;
bool enabled;
int version;
int x;
int y;
struct {
......@@ -270,6 +271,7 @@ static struct {
RIP_STATE_BOL,
RIP_STATE_FLUSHING,
true,
3,
0,
0,
{0, 0, 639, 349},
......@@ -7177,7 +7179,7 @@ static void do_rip_string(const char *buf, size_t len);
static bool handle_rip_line(BYTE *buf, unsigned *blen, unsigned *pos, size_t *rip_start, unsigned maxlen, enum rip_state ns);
static void unrip_line(BYTE *buf, unsigned *blen, unsigned *pos, size_t *rip_start, unsigned maxlen);
static void write_text(const char *str);
static char * rv_static(const char * const var, const void * const data);
static char * rv_version(const char * const var, const void * const data);
static char * rv_date(const char * const var, const void * const data);
static char * rv_time(const char * const var, const void * const data);
static char * rv_sound(const char * const var, const void * const data);
......@@ -7197,11 +7199,10 @@ static void kill_mouse_fields(void);
static void shadow_palette(void);
static void normal_palette(void);
static void draw_line(int x1, int y1, int x2, int y2);
static void reinit_screen(enum text_modes mode, uint8_t *font, int fontx, int fonty);
static void reinit_screen(uint8_t *font, int fontx, int fonty);
static bool no_viewport(void);
//static const char ripver[] = "RIPSCRIP015410";
static const char ripver[] = "RIPSCRIP030001";
static const char *ripver[] = {"", "RIPSCRIP015410", "RIPSCRIP030001"};
#define RIP_MOUSE_EVENT_NONE 0
#define RIP_MOUSE_EVENT_TEXT 1
......@@ -7274,7 +7275,7 @@ static const struct builtin_rip_variable builtins[] = {
{"RESTORE9", rv_restore, NULL},
{"RESTOREALL", rv_restore, NULL},
{"REVPHASER", rv_sound, NULL},
{"RIPVER", rv_static, ripver},// RIPscrip version
{"RIPVER", rv_version, NULL},// RIPscrip version
{"RMF", rv_restore, NULL},
{"RTW", rv_restore, NULL},
{"SAVE", rv_save, NULL},
......@@ -7358,9 +7359,9 @@ get_text_variable(const char * const var)
}
static char *
rv_static(const char * const var, const void * const data)
rv_version(const char * const var, const void * const data)
{
return strdup(data);
return strdup(ripver[rip.version]);
}
static char *
......@@ -7614,7 +7615,7 @@ rv_reset(const char * const var, const void * const data)
rip.text_disabled = false;
rip.ansi_state = ANSI_STATE_NONE;
_setcursortype(rip.curstype);
reinit_screen(C80X43, NULL, 8, 8);
reinit_screen((uint8_t*)conio_fontdata[0].eight_by_eight, 8, 8);
memcpy(&curr_ega_palette, &default_ega_palette, sizeof(curr_ega_palette));
set_ega_palette();
cterm->left_margin = 1;
......@@ -7764,7 +7765,7 @@ map_rip_y(int y)
static void
scale_setpixel(int x, int y, uint32_t color)
{
if (!(color & 0x80000000) && color < 256)
if (!(color & 0x80000000))
color = map_rip_color(color);
setpixel(map_rip_x(x), map_rip_y(y), color);
}
......@@ -7846,6 +7847,8 @@ rv_termset(const char * const var, const void * const data)
if (cterm->left_margin == 1 && cterm->right_margin == 1 &&
cterm->top_margin == 1 && cterm->bottom_margin == 1)
return strdup("NO");
if (rip.text_disabled)
return strdup("NO");
if (rip.curstype == _NOCURSOR)
return strdup("NO");
return strdup("YES");
......@@ -7871,20 +7874,30 @@ rv_termset(const char * const var, const void * const data)
return NULL;
}
break;
case 'S':
case 'S': {
void *font;
int width;
int height;
pthread_mutex_lock(&vstatlock);
font = vstat.forced_font;
width = vstat.charwidth;
height = vstat.charheight;
pthread_mutex_unlock(&vstatlock);
switch(var[5]) {
case 'F':
gettextinfo(&ti);
term.nostatus = TRUE;
reinit_screen(ti.currmode, vstat.forced_font, vstat.charwidth, vstat.charheight);
reinit_screen(font, width, height);
return NULL;
case 'N':
gettextinfo(&ti);
term.nostatus = FALSE;
reinit_screen(ti.currmode, vstat.forced_font, vstat.charwidth, vstat.charheight);
reinit_screen(font, width, height);
return NULL;
}
break;
}
case 'V':
switch(var[6]) {
case 'F':
......@@ -9369,47 +9382,52 @@ kill_mouse_fields(void)
// TODO: this currently doesn't seem to work (shocker!)
static void
reinit_screen(enum text_modes mode, uint8_t *font, int fx, int fy)
reinit_screen(uint8_t *font, int fx, int fy)
{
// TODO: Mystery rows in 8x8 mode...
struct ciolib_pixels *pix = getpixels(0, 0, rip.x_max - 1, rip.y_max - 1, false);
struct cterminal oldcterm = *cterm;
int old_hold = hold_update;
int cols = 80;
int rows = 43;
void *nvmem;
hold_update = 0;
cterm_end(cterm);
normal_palette();
// First, switch to the new mode...
textmode(mode);
// TODO: You know this is insane right?
// Patch vstat font, font size, and cols
pthread_mutex_lock(&vstatlock);
vstat.forced_font = font;
vstat.charwidth = fx;
vstat.charheight = fy;
if (font == ripfnt7x8)
cols = 91;
if (font == ripfnt7x14)
cols = 91;
if (font == ripfnt16x14)
cols = 40;
vstat.cols = cols;
// We need to update gettextinfo() results as well...
cio_textinfo.screenwidth = cols;
// And this crappy thing.
term.width = cols;
// Now, make the vmem array large enough for the new bits...
nvmem = realloc(vstat.vmem->vmem, vstat.cols * vstat.rows * sizeof(vstat.vmem->vmem[0]));
// And use it.
vstat.vmem->vmem = nvmem;
pthread_mutex_lock(&vstatlock);
rows = vstat.scrnheight / fy;
if (font != vstat.forced_font || fx != vstat.charwidth || fy != vstat.charheight) {
vstat.forced_font = font;
vstat.charwidth = fx;
vstat.charheight = fy;
vstat.cols = cols;
vstat.rows = rows;
// We need to update gettextinfo() results as well...
cio_textinfo.screenwidth = cols;
cio_textinfo.screenheight = rows;
// And this crappy thing.
term.width = cols;
term.height = rows;
// Now, make the vmem array large enough for the new bits...
nvmem = realloc(vstat.vmem->vmem, vstat.cols * vstat.rows * sizeof(vstat.vmem->vmem[0]));
// And use it.
vstat.vmem->vmem = nvmem;
}
pthread_mutex_unlock(&vstatlock);
// Initialize it...
clrscr();
get_term_win_size(&term.width, &term.height, &term.nostatus);
term.width = cols;
cterm = cterm_init((mode == C80X43 ? 43 : 25) + (term.nostatus ? 0 : -1), vstat.cols, oldcterm.x, oldcterm.y, oldcterm.backlines, oldcterm.backwidth, oldcterm.scrollback, oldcterm.emulation);
cterm = cterm_init(rows + (term.nostatus ? 0 : -1), cols, oldcterm.x, oldcterm.y, oldcterm.backlines, oldcterm.backwidth, oldcterm.scrollback, oldcterm.emulation);
cterm->apc_handler = oldcterm.apc_handler;
cterm->apc_handler_data = oldcterm.apc_handler_data;
cterm->mouse_state_change = oldcterm.mouse_state_change;
......@@ -9928,11 +9946,16 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
GET_XY();
arg1 = parse_mega(&args[4], 2);
pthread_mutex_lock(&vstatlock);
// This seems to be
arg3 = (arg1 * 7750 / 10000);
if (vstat.scale_numerator == 729 && vstat.scale_denominator == 1000) {
// Detect EGA mode and use the same value as RIPterm did.
arg3 = (arg1 * 7750 / 10000);
}
else {
arg3 = arg1 * vstat.scale_numerator / vstat.scale_denominator;
}
pthread_mutex_unlock(&vstatlock);
if (arg1 == 1)
arg3 = 1;
pthread_mutex_unlock(&vstatlock);
full_ellipse(x1, y1, arg1, arg3, false);
break;
case 'E': // RIP_ERASE_VIEW !|E
......@@ -10427,6 +10450,13 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
GET_XY();
rip.x_dim = x1;
rip.y_dim = y1;
pthread_mutex_lock(&vstatlock);
rip.x_max = vstat.scrnwidth;
if (rip.x_max > rip.x_dim)
rip.x_max = rip.x_dim;
rip.y_max = vstat.scrnheight;
if (rip.y_max > rip.y_dim)
rip.y_max = rip.y_dim;
// TODO: Hack... we should likely scale both directions...
rip.viewport.sx = 0;
rip.viewport.sy = 0;
......@@ -10436,6 +10466,7 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
FREE_AND_NULL(rip.ymap);
FREE_AND_NULL(rip.xunmap);
FREE_AND_NULL(rip.yunmap);
pthread_mutex_unlock(&vstatlock);
break;
case 'g': // RIP_GOTOXY !|g <x> <y>
/* This command sets the position of the text cursor in the TTY Text
......@@ -10807,32 +10838,33 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
break;
struct text_info ti;
gettextinfo(&ti);
arg3 = vstat.charwidth;
if (arg1)
cterm->extattr |= CTERM_EXTATTR_AUTOWRAP;
else
cterm->extattr &= ~CTERM_EXTATTR_AUTOWRAP;
pthread_mutex_lock(&vstatlock);
if (x1 == cterm->left_margin - 1 && x2 == cterm->right_margin - 1
&& y1 == cterm->top_margin - 1 && y2 == cterm->bottom_margin - 1
&& arg2 == vstat.charwidth) {
pthread_mutex_unlock(&vstatlock);
break;
}
pthread_mutex_unlock(&vstatlock);
switch(arg2) {
case 0:
if (ti.currmode == C80X43 && arg3 == 8)
break;
reinit_screen(C80X43, NULL, 8, 8);
reinit_screen((uint8_t*)conio_fontdata[0].eight_by_eight, 8, 8);
break;
case 1:
if (ti.currmode == C80X43 && arg3 == 7)
break;
reinit_screen(C80X43, ripfnt7x8, 7, 8);
reinit_screen(ripfnt7x8, 7, 8);
break;
case 2:
if (ti.currmode == EGA80X25 && arg3 == 8)
break;
reinit_screen(EGA80X25, NULL, 8, 14);
reinit_screen((uint8_t*)conio_fontdata[0].eight_by_fourteen, 8, 14);
break;
case 3:
if (ti.currmode == EGA80X25 && arg3 == 7)
break;
reinit_screen(EGA80X25, ripfnt7x14, 7, 14);
reinit_screen(ripfnt7x14, 7, 14);
break;
case 4:
if (ti.currmode == EGA80X25 && arg3 == 16)
break;
reinit_screen(EGA80X25, ripfnt16x14, 16, 14);
reinit_screen(ripfnt16x14, 16, 14);
break;
}
arg3 = 0;
......@@ -10855,10 +10887,6 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
cterm->bottom_margin = y2 + 1;
cterm->extattr |= CTERM_EXTATTR_ORIGINMODE;
if (arg1)
cterm->extattr |= CTERM_EXTATTR_AUTOWRAP;
else
cterm->extattr &= ~CTERM_EXTATTR_AUTOWRAP;
if (arg3) {
setwindow(cterm);
arg3 = hold_update;
......@@ -12064,8 +12092,10 @@ do_rip_command(int level, int sublevel, int cmd, const char *rawargs)
gettextinfo(&ti);
int bline = y1 + rip.viewport.sy + rip.clipboard->height - 1;
pthread_mutex_lock(&vstatlock);
if (bline >= vstat.scrnheight)
bline = vstat.scrnheight - 1;
pthread_mutex_unlock(&vstatlock);
if (x1 + rip.viewport.sx + rip.clipboard->width - 1 > rip.viewport.ex)
break;
switch(arg1) {
......@@ -13042,20 +13072,20 @@ handle_rip_line(BYTE *buf, unsigned *blen, unsigned *pos, size_t *rip_start, uns
fwrite(pending, 1, pending_len, cterm->logfile);
if (strcmp(pending, "\x1b[!") == 0) {
gettextinfo(&ti);
if (ti.currmode == C80X43 || ti.currmode == EGA80X25)
conn_send(ripver, 14, 1000);
if (rip.version)
conn_send(ripver[rip.version], 14, 1000);
}
else if (strcmp(pending, "\x1b[0!") == 0) {
gettextinfo(&ti);
if (ti.currmode == C80X43 || ti.currmode == EGA80X25)
conn_send(ripver, 14, 1000);
if (rip.version)
conn_send(ripver[rip.version], 14, 1000);
}
else if (strcmp(pending, "\x1b[1!") == 0) {
rip.enabled = false;
}
else if (strcmp(pending, "\x1b[2!") == 0) {
gettextinfo(&ti);
if (ti.currmode == C80X43 || ti.currmode == EGA80X25)
if (rip.version)
rip.enabled = true;
}
else if (pending[0] == '\x1b' && pending[1] == '[') {
......@@ -13514,7 +13544,8 @@ init_rip(int enabled)
memset(&rip, 0, sizeof(rip));
rip.state = RIP_STATE_BOL;
rip.newstate = RIP_STATE_FLUSHING;
rip.enabled = enabled;
rip.enabled = version != RIP_VERSION_NONE;
rip.version = version;
rip.x = 0;
rip.y = 0;
rip.viewport.sx = 0;
......@@ -13531,9 +13562,15 @@ init_rip(int enabled)
rip.line_pattern = 0xffff;
rip.line_width = 1;
rip.x_dim = 640;
rip.x_max = 640;
pthread_mutex_lock(&vstatlock);
rip.x_max = vstat.scrnwidth;
if (rip.x_max > rip.x_dim)
rip.x_max = rip.x_dim;
rip.y_dim = 350;
rip.y_max = 350;
rip.y_max = vstat.scrnheight;
if (rip.y_max > rip.y_dim)
rip.y_max = rip.y_dim;
pthread_mutex_unlock(&vstatlock);
pending_len = 0;
if (pending)
......@@ -13541,7 +13578,7 @@ init_rip(int enabled)
moredata_len = 0;
if (moredata)
moredata[0] = 0;
if (enabled) {
if (version) {
memcpy(&curr_ega_palette, &default_ega_palette, sizeof(curr_ega_palette));
set_ega_palette();
}
......
......@@ -45,7 +45,6 @@ void rlogin_input_thread(void *args)
#endif
void rlogin_output_thread(void *args)
{
fd_set wds;
int wr;
int ret;
int sent;
......
......@@ -2251,7 +2251,7 @@ static void apc_handler(char *strbuf, size_t slen, void *apcd)
MD5_calc(digest, buf, rc);
}
fclose(f);
MD5_hex((BYTE *)buf, digest);
MD5_hex(buf, digest);
conn_send(buf, strlen(buf), 0);
}
conn_send("\n", 1, 0);
......