Update first part of zmodem sources
This commit is contained in:
parent
cb2d964597
commit
706d0fcfe7
250
mbsebbs/zmmisc.c
250
mbsebbs/zmmisc.c
@ -53,15 +53,16 @@
|
||||
static void zputhex(int);
|
||||
static void zsbh32(int,char*,int,int);
|
||||
static void zsda32(char*,int,int);
|
||||
static int zrdat32(char*,int);
|
||||
static int noxrd7(void);
|
||||
static int zrbhd32(char*);
|
||||
static int zrbhdr(char*);
|
||||
static int zrhhdr(char*);
|
||||
static int zgethex(void);
|
||||
static int zgeth1(void);
|
||||
static int zrdat32(char*,int);
|
||||
static int noxrd7(void);
|
||||
static int zrbhd32(char*);
|
||||
static int zrbhdr(char*);
|
||||
static int zrhhdr(char*);
|
||||
static int zgethex(void);
|
||||
static int zgeth1(void);
|
||||
static void garbitch(void);
|
||||
|
||||
|
||||
#include "../config.h"
|
||||
#include "../lib/mbselib.h"
|
||||
#include "../lib/nodelist.h"
|
||||
@ -163,16 +164,16 @@ static int frame_length = 0;
|
||||
|
||||
void get_frame_buffer(void)
|
||||
{
|
||||
if (frame_buffer == NULL)
|
||||
frame_buffer = malloc(FRAME_BUFFER_SIZE);
|
||||
if (frame_buffer == NULL)
|
||||
frame_buffer = malloc(FRAME_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
|
||||
void free_frame_buffer(void)
|
||||
{
|
||||
if (frame_buffer)
|
||||
free(frame_buffer);
|
||||
frame_buffer = NULL;
|
||||
if (frame_buffer)
|
||||
free(frame_buffer);
|
||||
frame_buffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -182,45 +183,43 @@ void free_frame_buffer(void)
|
||||
*/
|
||||
void zsbhdr(int len, int type, register char *shdr)
|
||||
{
|
||||
register int n;
|
||||
register unsigned short crc;
|
||||
register int n;
|
||||
register unsigned short crc;
|
||||
|
||||
Syslog('z', "zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
|
||||
Syslog('z', "zsbhdr: %c %d %s %lx", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
|
||||
|
||||
BUFFER_CLEAR();
|
||||
BUFFER_CLEAR();
|
||||
|
||||
if (type == ZDATA)
|
||||
for (n = Znulls; --n >=0; )
|
||||
BUFFER_BYTE(0);
|
||||
if (type == ZDATA)
|
||||
for (n = Znulls; --n >=0; )
|
||||
BUFFER_BYTE(0);
|
||||
|
||||
BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZDLE);
|
||||
BUFFER_BYTE(ZPAD); BUFFER_BYTE(ZDLE);
|
||||
|
||||
switch (Crc32t=Txfcs32) {
|
||||
case 2:
|
||||
zsbh32(len, shdr, type, Usevhdrs?ZVBINR32:ZBINR32);
|
||||
BUFFER_FLUSH(); break;
|
||||
case 1:
|
||||
zsbh32(len, shdr, type, Usevhdrs?ZVBIN32:ZBIN32); break;
|
||||
default:
|
||||
if (Usevhdrs) {
|
||||
switch (Crc32t=Txfcs32) {
|
||||
case 2: zsbh32(len, shdr, type, Usevhdrs?ZVBINR32:ZBINR32);
|
||||
BUFFER_FLUSH();
|
||||
break;
|
||||
case 1: zsbh32(len, shdr, type, Usevhdrs?ZVBIN32:ZBIN32);
|
||||
break;
|
||||
default: if (Usevhdrs) {
|
||||
BUFFER_BYTE(ZVBIN);
|
||||
zsendline(len);
|
||||
}
|
||||
else
|
||||
} else
|
||||
BUFFER_BYTE(ZBIN);
|
||||
zsendline(type);
|
||||
crc = updcrc16(type, 0);
|
||||
zsendline(type);
|
||||
crc = updcrc16(type, 0);
|
||||
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
zsendline(*shdr);
|
||||
crc = updcrc16((0377& *shdr), crc);
|
||||
}
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zsendline(((int)(crc>>8)));
|
||||
zsendline(crc);
|
||||
}
|
||||
}
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zsendline(((int)(crc>>8)));
|
||||
zsendline(crc);
|
||||
}
|
||||
|
||||
BUFFER_FLUSH();
|
||||
BUFFER_FLUSH();
|
||||
}
|
||||
|
||||
|
||||
@ -230,24 +229,24 @@ void zsbhdr(int len, int type, register char *shdr)
|
||||
*/
|
||||
void zsbh32(int len, register char *shdr, int type, int flavour)
|
||||
{
|
||||
register int n;
|
||||
register unsigned long crc;
|
||||
register int n;
|
||||
register unsigned long crc;
|
||||
|
||||
BUFFER_BYTE(flavour);
|
||||
if (Usevhdrs)
|
||||
zsendline(len);
|
||||
zsendline(type);
|
||||
crc = 0xFFFFFFFFL; crc = updcrc32(type, crc);
|
||||
BUFFER_BYTE(flavour);
|
||||
if (Usevhdrs)
|
||||
zsendline(len);
|
||||
zsendline(type);
|
||||
crc = 0xFFFFFFFFL; crc = updcrc32(type, crc);
|
||||
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
crc = updcrc32((0377 & *shdr), crc);
|
||||
zsendline(*shdr);
|
||||
}
|
||||
crc = ~crc;
|
||||
for (n=4; --n >= 0;) {
|
||||
zsendline((int)crc);
|
||||
crc >>= 8;
|
||||
}
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
crc = updcrc32((0377 & *shdr), crc);
|
||||
zsendline(*shdr);
|
||||
}
|
||||
crc = ~crc;
|
||||
for (n=4; --n >= 0;) {
|
||||
zsendline((int)crc);
|
||||
crc >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -257,45 +256,44 @@ void zsbh32(int len, register char *shdr, int type, int flavour)
|
||||
*/
|
||||
void zshhdr(int len, int type, register char *shdr)
|
||||
{
|
||||
register int n;
|
||||
register unsigned short crc;
|
||||
register int n;
|
||||
register unsigned short crc;
|
||||
|
||||
Syslog('z', "zshhdr: %c %d %s %ld", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
|
||||
Syslog('z', "zshhdr: %c %d %s %ld", Usevhdrs?'v':'f', len, frametypes[type+FTOFFSET], rclhdr(shdr));
|
||||
|
||||
BUFFER_CLEAR();
|
||||
BUFFER_CLEAR();
|
||||
|
||||
BUFFER_BYTE(ZPAD);
|
||||
BUFFER_BYTE(ZPAD);
|
||||
BUFFER_BYTE(ZDLE);
|
||||
if (Usevhdrs) {
|
||||
BUFFER_BYTE(ZVHEX);
|
||||
zputhex(len);
|
||||
}
|
||||
else
|
||||
BUFFER_BYTE(ZHEX);
|
||||
zputhex(type);
|
||||
Crc32t = 0;
|
||||
BUFFER_BYTE(ZPAD);
|
||||
BUFFER_BYTE(ZPAD);
|
||||
BUFFER_BYTE(ZDLE);
|
||||
if (Usevhdrs) {
|
||||
BUFFER_BYTE(ZVHEX);
|
||||
zputhex(len);
|
||||
} else
|
||||
BUFFER_BYTE(ZHEX);
|
||||
zputhex(type);
|
||||
Crc32t = 0;
|
||||
|
||||
crc = updcrc16(type, 0);
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
zputhex(*shdr); crc = updcrc16((0377 & *shdr), crc);
|
||||
}
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zputhex(((int)(crc>>8))); zputhex(crc);
|
||||
crc = updcrc16(type, 0);
|
||||
for (n=len; --n >= 0; ++shdr) {
|
||||
zputhex(*shdr); crc = updcrc16((0377 & *shdr), crc);
|
||||
}
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zputhex(((int)(crc>>8))); zputhex(crc);
|
||||
|
||||
/*
|
||||
* Make it printable on remote machine
|
||||
*/
|
||||
BUFFER_BYTE(015);
|
||||
BUFFER_BYTE(0212);
|
||||
/*
|
||||
* Make it printable on remote machine
|
||||
*/
|
||||
BUFFER_BYTE(015);
|
||||
BUFFER_BYTE(0212);
|
||||
|
||||
/*
|
||||
* Uncork the remote in case a fake XOFF has stopped data flow
|
||||
*/
|
||||
if (type != ZFIN && type != ZACK)
|
||||
BUFFER_BYTE(021);
|
||||
/*
|
||||
* Uncork the remote in case a fake XOFF has stopped data flow
|
||||
*/
|
||||
if (type != ZFIN && type != ZACK)
|
||||
BUFFER_BYTE(021);
|
||||
|
||||
BUFFER_FLUSH();
|
||||
BUFFER_FLUSH();
|
||||
}
|
||||
|
||||
|
||||
@ -306,58 +304,58 @@ void zshhdr(int len, int type, register char *shdr)
|
||||
char *Zendnames[] = {(char *)"ZCRCE",(char *)"ZCRCG",(char *)"ZCRCQ",(char *)"ZCRCW"};
|
||||
void zsdata(register char *buf, int length, int frameend)
|
||||
{
|
||||
register unsigned short crc;
|
||||
register unsigned short crc;
|
||||
|
||||
Syslog('z', "zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]);
|
||||
Syslog('z', "zsdata: %d %s", length, Zendnames[(frameend-ZCRCE)&3]);
|
||||
|
||||
BUFFER_CLEAR();
|
||||
BUFFER_CLEAR();
|
||||
|
||||
switch (Crc32t) {
|
||||
case 1:
|
||||
zsda32(buf, length, frameend); break;
|
||||
case 2:
|
||||
zsdar32(buf, length, frameend); break;
|
||||
default:
|
||||
crc = 0;
|
||||
for (;--length >= 0; ++buf) {
|
||||
switch (Crc32t) {
|
||||
case 1: zsda32(buf, length, frameend);
|
||||
break;
|
||||
case 2: zsdar32(buf, length, frameend);
|
||||
break;
|
||||
default: crc = 0;
|
||||
for (;--length >= 0; ++buf) {
|
||||
zsendline(*buf); crc = updcrc16((0377 & *buf), crc);
|
||||
}
|
||||
BUFFER_BYTE(ZDLE); BUFFER_BYTE(frameend);
|
||||
crc = updcrc16(frameend, crc);
|
||||
}
|
||||
BUFFER_BYTE(ZDLE);
|
||||
BUFFER_BYTE(frameend);
|
||||
crc = updcrc16(frameend, crc);
|
||||
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zsendline(((int)(crc>>8))); zsendline(crc);
|
||||
}
|
||||
if (frameend == ZCRCW)
|
||||
BUFFER_BYTE(XON);
|
||||
crc = updcrc16(0,updcrc16(0,crc));
|
||||
zsendline(((int)(crc>>8))); zsendline(crc);
|
||||
}
|
||||
if (frameend == ZCRCW)
|
||||
BUFFER_BYTE(XON);
|
||||
|
||||
BUFFER_FLUSH();
|
||||
BUFFER_FLUSH();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void zsda32(register char *buf, int length, int frameend)
|
||||
{
|
||||
register int c;
|
||||
register unsigned long crc;
|
||||
register int c;
|
||||
register unsigned long crc;
|
||||
|
||||
crc = 0xFFFFFFFFL;
|
||||
for (;--length >= 0; ++buf) {
|
||||
c = *buf & 0377;
|
||||
if (c & 0140)
|
||||
BUFFER_BYTE(lastsent = c);
|
||||
else
|
||||
zsendline(c);
|
||||
crc = updcrc32(c, crc);
|
||||
}
|
||||
BUFFER_BYTE(ZDLE);
|
||||
BUFFER_BYTE(frameend);
|
||||
crc = updcrc32(frameend, crc);
|
||||
crc = 0xFFFFFFFFL;
|
||||
for (;--length >= 0; ++buf) {
|
||||
c = *buf & 0377;
|
||||
if (c & 0140)
|
||||
BUFFER_BYTE(lastsent = c);
|
||||
else
|
||||
zsendline(c);
|
||||
crc = updcrc32(c, crc);
|
||||
}
|
||||
BUFFER_BYTE(ZDLE);
|
||||
BUFFER_BYTE(frameend);
|
||||
crc = updcrc32(frameend, crc);
|
||||
|
||||
crc = ~crc;
|
||||
for (c=4; --c >= 0;) {
|
||||
zsendline((int)crc); crc >>= 8;
|
||||
}
|
||||
crc = ~crc;
|
||||
for (c=4; --c >= 0;) {
|
||||
zsendline((int)crc); crc >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -491,7 +489,7 @@ crcfoo:
|
||||
|
||||
void garbitch(void)
|
||||
{
|
||||
Syslog('+', "Zmodem: Garbled data subpacket");
|
||||
Syslog('+', "Zmodem: Garbled data subpacket");
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,23 +6,14 @@
|
||||
void get_frame_buffer(void);
|
||||
void free_frame_buffer(void);
|
||||
void zsbhdr(int, int, register char *);
|
||||
void zsbh32(int, register char *, int, int);
|
||||
void zshhdr(int, int, register char *);
|
||||
void zsdata(register char *, int, int);
|
||||
void zsda32(register char *, int, int);
|
||||
int zrdata(register char *, int);
|
||||
int zrdat32(register char *, int);
|
||||
void garbitch(void);
|
||||
int zgethdr(char *);
|
||||
int zrbhdr(register char *);
|
||||
int zrbhd32(register char *);
|
||||
int zrhhdr(char *);
|
||||
void zputhex(register int);
|
||||
void zsendline(int);
|
||||
int zgethex(void);
|
||||
int zgeth1(void);
|
||||
int zdlread(void);
|
||||
int noxrd7(void);
|
||||
void stohdr(long);
|
||||
long rclhdr(register char *);
|
||||
|
||||
|
179
mbsebbs/zmrle.c
179
mbsebbs/zmrle.c
@ -51,58 +51,54 @@
|
||||
*/
|
||||
void zsdar32(char *buf, int length, int frameend)
|
||||
{
|
||||
register int c, l, n;
|
||||
register unsigned long crc;
|
||||
register int c, l, n;
|
||||
register unsigned long crc;
|
||||
|
||||
crc = 0xFFFFFFFFL; l = *buf++ & 0377;
|
||||
if (length == 1) {
|
||||
zsendline(l); crc = updcrc32(l, crc);
|
||||
if (l == ZRESC) {
|
||||
zsendline(1); crc = updcrc32(1, crc);
|
||||
}
|
||||
} else {
|
||||
for (n = 0; --length >= 0; ++buf) {
|
||||
if ((c = *buf & 0377) == l && n < 126 && length>0) {
|
||||
++n; continue;
|
||||
}
|
||||
switch (n) {
|
||||
case 0:
|
||||
zsendline(l);
|
||||
crc = 0xFFFFFFFFL; l = *buf++ & 0377;
|
||||
if (length == 1) {
|
||||
zsendline(l); crc = updcrc32(l, crc);
|
||||
if (l == ZRESC) {
|
||||
zsendline(1); crc = updcrc32(1, crc);
|
||||
}
|
||||
} else {
|
||||
for (n = 0; --length >= 0; ++buf) {
|
||||
if ((c = *buf & 0377) == l && n < 126 && length>0) {
|
||||
++n; continue;
|
||||
}
|
||||
switch (n) {
|
||||
case 0: zsendline(l);
|
||||
crc = updcrc32(l, crc);
|
||||
if (l == ZRESC) {
|
||||
zsendline(0100); crc = updcrc32(0100, crc);
|
||||
}
|
||||
l = c; break;
|
||||
case 1: if (l != ZRESC) {
|
||||
zsendline(l); zsendline(l);
|
||||
crc = updcrc32(l, crc);
|
||||
crc = updcrc32(l, crc);
|
||||
if (l == ZRESC) {
|
||||
zsendline(0100); crc = updcrc32(0100, crc);
|
||||
}
|
||||
l = c; break;
|
||||
case 1:
|
||||
if (l != ZRESC) {
|
||||
zsendline(l); zsendline(l);
|
||||
crc = updcrc32(l, crc);
|
||||
crc = updcrc32(l, crc);
|
||||
n = 0; l = c; break;
|
||||
}
|
||||
/* **** FALL THRU TO **** */
|
||||
default:
|
||||
zsendline(ZRESC); crc = updcrc32(ZRESC, crc);
|
||||
if (l == 040 && n < 34) {
|
||||
n += 036;
|
||||
zsendline(n); crc = updcrc32(n, crc);
|
||||
}
|
||||
else {
|
||||
n += 0101;
|
||||
zsendline(n); crc = updcrc32(n, crc);
|
||||
zsendline(l); crc = updcrc32(l, crc);
|
||||
}
|
||||
n = 0; l = c; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* **** FALL THRU TO **** */
|
||||
default: zsendline(ZRESC); crc = updcrc32(ZRESC, crc);
|
||||
if (l == 040 && n < 34) {
|
||||
n += 036;
|
||||
zsendline(n); crc = updcrc32(n, crc);
|
||||
} else {
|
||||
n += 0101;
|
||||
zsendline(n); crc = updcrc32(n, crc);
|
||||
zsendline(l); crc = updcrc32(l, crc);
|
||||
}
|
||||
n = 0; l = c; break;
|
||||
}
|
||||
}
|
||||
PUTCHAR(ZDLE); PUTCHAR(frameend);
|
||||
crc = updcrc32(frameend, crc);
|
||||
}
|
||||
PUTCHAR(ZDLE); PUTCHAR(frameend);
|
||||
crc = updcrc32(frameend, crc);
|
||||
|
||||
crc = ~crc;
|
||||
for (length=4; --length >= 0;) {
|
||||
zsendline((int)crc); crc >>= 8;
|
||||
}
|
||||
crc = ~crc;
|
||||
for (length=4; --length >= 0;) {
|
||||
zsendline((int)crc); crc >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -111,86 +107,79 @@ void zsdar32(char *buf, int length, int frameend)
|
||||
*/
|
||||
int zrdatr32(register char *buf, int length)
|
||||
{
|
||||
register int c;
|
||||
register unsigned long crc;
|
||||
register char *end;
|
||||
register int d;
|
||||
register int c;
|
||||
register unsigned long crc;
|
||||
register char *end;
|
||||
register int d;
|
||||
|
||||
crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
|
||||
d = 0; /* Use for RLE decoder state */
|
||||
while (buf <= end) {
|
||||
if ((c = zdlread()) & ~0377) {
|
||||
crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
|
||||
d = 0; /* Use for RLE decoder state */
|
||||
while (buf <= end) {
|
||||
if ((c = zdlread()) & ~0377) {
|
||||
crcfoo:
|
||||
switch (c) {
|
||||
case GOTCRCE:
|
||||
case GOTCRCG:
|
||||
case GOTCRCQ:
|
||||
case GOTCRCW:
|
||||
d = c; c &= 0377;
|
||||
switch (c) {
|
||||
case GOTCRCE:
|
||||
case GOTCRCG:
|
||||
case GOTCRCQ:
|
||||
case GOTCRCW: d = c; c &= 0377;
|
||||
crc = updcrc32(c, crc);
|
||||
if ((c = zdlread()) & ~0377)
|
||||
goto crcfoo;
|
||||
goto crcfoo;
|
||||
crc = updcrc32(c, crc);
|
||||
if ((c = zdlread()) & ~0377)
|
||||
goto crcfoo;
|
||||
goto crcfoo;
|
||||
crc = updcrc32(c, crc);
|
||||
if ((c = zdlread()) & ~0377)
|
||||
goto crcfoo;
|
||||
goto crcfoo;
|
||||
crc = updcrc32(c, crc);
|
||||
if ((c = zdlread()) & ~0377)
|
||||
goto crcfoo;
|
||||
goto crcfoo;
|
||||
crc = updcrc32(c, crc);
|
||||
if (crc != 0xDEBB20E3) {
|
||||
Syslog('+', "Zmodem zrdatr32: Bad CRC");
|
||||
return TERROR;
|
||||
Syslog('+', "Zmodem zrdatr32: Bad CRC");
|
||||
return TERROR;
|
||||
}
|
||||
Rxcount = length - (end - buf);
|
||||
|
||||
Syslog('z', "zrdatr32: %d %s", Rxcount,
|
||||
Zendnames[(d-GOTCRCE)&3]);
|
||||
Syslog('z', "zrdatr32: %d %s", Rxcount, Zendnames[(d-GOTCRCE)&3]);
|
||||
|
||||
return d;
|
||||
case GOTCAN:
|
||||
Syslog('+', "Zmodem: Sender Canceled");
|
||||
case GOTCAN: Syslog('+', "Zmodem: Sender Canceled");
|
||||
return ZCAN;
|
||||
case TIMEOUT:
|
||||
Syslog('+', "Zmodem: TIMEOUT");
|
||||
case TIMEOUT: Syslog('+', "Zmodem: TIMEOUT");
|
||||
return c;
|
||||
default:
|
||||
Syslog('+', "Zmodem: Bad data subpacket");
|
||||
default: Syslog('+', "Zmodem: Bad data subpacket");
|
||||
return c;
|
||||
}
|
||||
}
|
||||
crc = updcrc32(c, crc);
|
||||
switch (d) {
|
||||
case 0:
|
||||
if (c == ZRESC) {
|
||||
d = -1; continue;
|
||||
}
|
||||
}
|
||||
crc = updcrc32(c, crc);
|
||||
switch (d) {
|
||||
case 0: if (c == ZRESC) {
|
||||
d = -1; continue;
|
||||
}
|
||||
*buf++ = c; continue;
|
||||
case -1:
|
||||
if (c >= 040 && c < 0100) {
|
||||
d = c - 035; c = 040; goto spaces;
|
||||
case -1: if (c >= 040 && c < 0100) {
|
||||
d = c - 035; c = 040; goto spaces;
|
||||
}
|
||||
if (c == 0100) {
|
||||
d = 0;
|
||||
*buf++ = ZRESC; continue;
|
||||
d = 0;
|
||||
*buf++ = ZRESC; continue;
|
||||
}
|
||||
d = c; continue;
|
||||
default:
|
||||
d -= 0100;
|
||||
default: d -= 0100;
|
||||
if (d < 1)
|
||||
goto badpkt;
|
||||
goto badpkt;
|
||||
spaces:
|
||||
if ((buf + d) > end)
|
||||
goto badpkt;
|
||||
goto badpkt;
|
||||
while ( --d >= 0)
|
||||
*buf++ = c;
|
||||
*buf++ = c;
|
||||
d = 0; continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
badpkt:
|
||||
Syslog('+', "Zmodem: Data subpacket too long");
|
||||
return TERROR;
|
||||
Syslog('+', "Zmodem: Data subpacket too long");
|
||||
return TERROR;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user