[w3m-dev 03676] cleanup for pipe
* etc.c (open_pipe_rw): added * file.c (uncompress_stream): rewrite using open_pipe_rw * image.c (openImgdisplay): rewrite using open_pipe_rw * local.c (localcgi_popen_rw): deleted (localcgi_post): rewrite using open_pipe_rw * proto.h (open_pipe_rw): added * search.c (migemor): initialized to NULL (migemow): initialized to NULL (migemo_pid): initialized to 0 (open_migemo): rewrite using open_pipe_rw From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
This commit is contained in:
@@ -1,3 +1,17 @@
|
|||||||
|
2003-01-23 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
|
* [w3m-dev 03676] cleanup for pipe
|
||||||
|
* etc.c (open_pipe_rw): added
|
||||||
|
* file.c (uncompress_stream): rewrite using open_pipe_rw
|
||||||
|
* image.c (openImgdisplay): rewrite using open_pipe_rw
|
||||||
|
* local.c (localcgi_popen_rw): deleted
|
||||||
|
(localcgi_post): rewrite using open_pipe_rw
|
||||||
|
* proto.h (open_pipe_rw): added
|
||||||
|
* search.c (migemor): initialized to NULL
|
||||||
|
(migemow): initialized to NULL
|
||||||
|
(migemo_pid): initialized to 0
|
||||||
|
(open_migemo): rewrite using open_pipe_rw
|
||||||
|
|
||||||
2003-01-23 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
2003-01-23 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>
|
||||||
|
|
||||||
* [w3m-dev 03675] x-face
|
* [w3m-dev 03675] x-face
|
||||||
@@ -6686,4 +6700,4 @@ a * [w3m-dev 03276] compile error on EWS4800
|
|||||||
* release-0-2-1
|
* release-0-2-1
|
||||||
* import w3m-0.2.1
|
* import w3m-0.2.1
|
||||||
|
|
||||||
$Id: ChangeLog,v 1.702 2003/01/22 16:01:16 ukai Exp $
|
$Id: ChangeLog,v 1.703 2003/01/22 16:10:27 ukai Exp $
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: etc.c,v 1.52 2003/01/17 17:06:57 ukai Exp $ */
|
/* $Id: etc.c,v 1.53 2003/01/22 16:10:28 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include "myctype.h"
|
#include "myctype.h"
|
||||||
@@ -1339,6 +1339,58 @@ setup_child(int child, int i, int f)
|
|||||||
fmInitialized = FALSE;
|
fmInitialized = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
open_pipe_rw(FILE **fr, FILE **fw)
|
||||||
|
{
|
||||||
|
int fdr[2];
|
||||||
|
int fdw[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (fr && pipe(fdr) < 0)
|
||||||
|
goto err0;
|
||||||
|
if (fw && pipe(fdw) < 0)
|
||||||
|
goto err1;
|
||||||
|
|
||||||
|
flush_tty();
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0)
|
||||||
|
goto err2;
|
||||||
|
if (pid == 0) {
|
||||||
|
/* child */
|
||||||
|
if (fr) {
|
||||||
|
close(fdr[0]);
|
||||||
|
dup2(fdr[1], 1);
|
||||||
|
}
|
||||||
|
if (fw) {
|
||||||
|
close(fdw[1]);
|
||||||
|
dup2(fdw[0], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (fr) {
|
||||||
|
close(fdr[1]);
|
||||||
|
*fr = fdopen(fdr[0], "r");
|
||||||
|
}
|
||||||
|
if (fw) {
|
||||||
|
close(fdw[0]);
|
||||||
|
*fw = fdopen(fdw[1], "w");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pid;
|
||||||
|
err2:
|
||||||
|
if (fw) {
|
||||||
|
close(fdw[0]);
|
||||||
|
close(fdw[1]);
|
||||||
|
}
|
||||||
|
err1:
|
||||||
|
if (fr) {
|
||||||
|
close(fdr[0]);
|
||||||
|
close(fdr[1]);
|
||||||
|
}
|
||||||
|
err0:
|
||||||
|
return (pid_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
myExec(char *command)
|
myExec(char *command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: file.c,v 1.197 2003/01/22 16:01:17 ukai Exp $ */
|
/* $Id: file.c,v 1.198 2003/01/22 16:10:28 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "myctype.h"
|
#include "myctype.h"
|
||||||
@@ -7723,8 +7723,8 @@ inputAnswer(char *prompt)
|
|||||||
static void
|
static void
|
||||||
uncompress_stream(URLFile *uf, char **src)
|
uncompress_stream(URLFile *uf, char **src)
|
||||||
{
|
{
|
||||||
int pid1;
|
pid_t pid1;
|
||||||
int fd1[2];
|
FILE *f1;
|
||||||
char *expand_cmd = GUNZIP_CMDNAME;
|
char *expand_cmd = GUNZIP_CMDNAME;
|
||||||
char *expand_name = GUNZIP_NAME;
|
char *expand_name = GUNZIP_NAME;
|
||||||
char *tmpf = NULL;
|
char *tmpf = NULL;
|
||||||
@@ -7748,82 +7748,58 @@ uncompress_stream(URLFile *uf, char **src)
|
|||||||
}
|
}
|
||||||
uf->compression = CMP_NOCOMPRESS;
|
uf->compression = CMP_NOCOMPRESS;
|
||||||
|
|
||||||
if (pipe(fd1) < 0) {
|
|
||||||
UFclose(uf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uf->scheme != SCM_LOCAL
|
if (uf->scheme != SCM_LOCAL
|
||||||
#ifdef USE_IMAGE
|
#ifdef USE_IMAGE
|
||||||
&& !image_source
|
&& !image_source
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
tmpf = tmpfname(TMPF_DFL, ext)->ptr;
|
tmpf = tmpfname(TMPF_DFL, ext)->ptr;
|
||||||
if (save2tmp(*uf, tmpf) < 0) {
|
}
|
||||||
|
|
||||||
|
pid1 = open_pipe_rw(&f1, NULL);
|
||||||
|
if (pid1 < 0) {
|
||||||
|
UFclose(uf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pid1 == 0) {
|
||||||
|
/* child */
|
||||||
|
pid_t pid2;
|
||||||
|
FILE *f2;
|
||||||
|
dup2(1, 2); /* stderr>&stdout */
|
||||||
|
setup_child(TRUE, -1, UFfileno(uf));
|
||||||
|
pid2 = open_pipe_rw(NULL, &f2);
|
||||||
|
if (pid2 < 0) {
|
||||||
UFclose(uf);
|
UFclose(uf);
|
||||||
return;
|
exit(1);
|
||||||
}
|
}
|
||||||
#if 0
|
if (pid2 > 0) {
|
||||||
if (uf->scheme != SCM_FTP)
|
Str buf = Strnew_size(SAVE_BUF_SIZE);
|
||||||
#endif
|
FILE *f = NULL;
|
||||||
UFclose(uf);
|
if (tmpf)
|
||||||
|
f = fopen(tmpf, "wb");
|
||||||
|
while (UFread(uf, buf, SAVE_BUF_SIZE)) {
|
||||||
|
if (Strfputs(buf, f2) < 0)
|
||||||
|
break;
|
||||||
|
if (f)
|
||||||
|
Strfputs(buf, f);
|
||||||
|
}
|
||||||
|
fclose(f2);
|
||||||
|
if (f)
|
||||||
|
fclose(f);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
/* child */
|
||||||
|
execlp(expand_cmd, expand_name, NULL);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (tmpf) {
|
||||||
if (src)
|
if (src)
|
||||||
*src = tmpf;
|
*src = tmpf;
|
||||||
else
|
else
|
||||||
uf->scheme = SCM_LOCAL;
|
uf->scheme = SCM_LOCAL;
|
||||||
}
|
}
|
||||||
|
UFhalfclose(uf);
|
||||||
flush_tty();
|
uf->stream = newFileStream(f1, (void (*)())fclose);
|
||||||
/* fd1[0]: read, fd1[1]: write */
|
|
||||||
if ((pid1 = fork()) == 0) {
|
|
||||||
close(fd1[0]);
|
|
||||||
dup2(fd1[1], 1);
|
|
||||||
dup2(fd1[1], 2);
|
|
||||||
setup_child(TRUE, -1, UFfileno(uf));
|
|
||||||
if (tmpf) {
|
|
||||||
#ifdef USE_BINMODE_STREAM
|
|
||||||
int tmpfd = open(tmpf, O_RDONLY | O_BINARY);
|
|
||||||
#else
|
|
||||||
int tmpfd = open(tmpf, O_RDONLY);
|
|
||||||
#endif
|
|
||||||
if (tmpfd < 0) {
|
|
||||||
close(fd1[1]);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
dup2(tmpfd, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* child */
|
|
||||||
int pid2;
|
|
||||||
int fd2[2];
|
|
||||||
if (pipe(fd2) < 0) {
|
|
||||||
close(fd1[1]);
|
|
||||||
UFclose(uf);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if ((pid2 = fork()) == 0) {
|
|
||||||
/* child */
|
|
||||||
Str buf = Strnew_size(SAVE_BUF_SIZE);
|
|
||||||
close(fd2[0]);
|
|
||||||
while (UFread(uf, buf, SAVE_BUF_SIZE)) {
|
|
||||||
if (write(fd2[1], buf->ptr, buf->length) < 0) {
|
|
||||||
close(fd2[1]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd2[1]);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
close(fd2[1]);
|
|
||||||
dup2(fd2[0], 0);
|
|
||||||
}
|
|
||||||
execlp(expand_cmd, expand_name, NULL);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
close(fd1[1]);
|
|
||||||
if (tmpf == NULL)
|
|
||||||
UFclose(uf);
|
|
||||||
uf->stream = newFileStream(fdopen(fd1[0], "rb"), (void (*)())pclose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *
|
static FILE *
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: image.c,v 1.26 2003/01/17 16:57:19 ukai Exp $ */
|
/* $Id: image.c,v 1.27 2003/01/22 16:10:28 ukai Exp $ */
|
||||||
|
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -89,24 +89,12 @@ termImage()
|
|||||||
static int
|
static int
|
||||||
openImgdisplay()
|
openImgdisplay()
|
||||||
{
|
{
|
||||||
int fdr[2], fdw[2];
|
Imgdisplay_pid = open_pipe_rw(&Imgdisplay_rf, &Imgdisplay_wf);
|
||||||
char *cmd;
|
|
||||||
|
|
||||||
if (pipe(fdr) < 0)
|
|
||||||
goto err0;
|
|
||||||
if (pipe(fdw) < 0)
|
|
||||||
goto err1;
|
|
||||||
|
|
||||||
flush_tty();
|
|
||||||
Imgdisplay_pid = fork();
|
|
||||||
if (Imgdisplay_pid < 0)
|
if (Imgdisplay_pid < 0)
|
||||||
goto err2;
|
goto err0;
|
||||||
if (Imgdisplay_pid == 0) {
|
if (Imgdisplay_pid == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
close(fdr[0]);
|
char *cmd;
|
||||||
close(fdw[1]);
|
|
||||||
dup2(fdw[0], 0);
|
|
||||||
dup2(fdr[1], 1);
|
|
||||||
setup_child(FALSE, 2, -1);
|
setup_child(FALSE, 2, -1);
|
||||||
set_environ("W3M_TTY", ttyname_tty());
|
set_environ("W3M_TTY", ttyname_tty());
|
||||||
if (!strchr(Imgdisplay, '/'))
|
if (!strchr(Imgdisplay, '/'))
|
||||||
@@ -116,21 +104,9 @@ openImgdisplay()
|
|||||||
myExec(cmd);
|
myExec(cmd);
|
||||||
/* XXX: ifdef __EMX__, use start /f ? */
|
/* XXX: ifdef __EMX__, use start /f ? */
|
||||||
}
|
}
|
||||||
close(fdr[1]);
|
|
||||||
close(fdw[0]);
|
|
||||||
Imgdisplay_rf = fdopen(fdr[0], "r");
|
|
||||||
Imgdisplay_wf = fdopen(fdw[1], "w");
|
|
||||||
activeImage = TRUE;
|
activeImage = TRUE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
err2:
|
|
||||||
close(fdw[0]);
|
|
||||||
close(fdw[1]);
|
|
||||||
err1:
|
|
||||||
close(fdr[0]);
|
|
||||||
close(fdr[1]);
|
|
||||||
err0:
|
err0:
|
||||||
Imgdisplay_rf = NULL;
|
|
||||||
Imgdisplay_wf = NULL;
|
|
||||||
Imgdisplay_pid = 0;
|
Imgdisplay_pid = 0;
|
||||||
activeImage = FALSE;
|
activeImage = FALSE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: local.c,v 1.24 2003/01/17 17:07:00 ukai Exp $ */
|
/* $Id: local.c,v 1.25 2003/01/22 16:10:28 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -355,60 +355,10 @@ cgi_filename(char *fn, int *status)
|
|||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static pid_t
|
|
||||||
localcgi_popen_rw(int *p_fdr, int *p_fdw)
|
|
||||||
{
|
|
||||||
int fdr[2], fdw[2];
|
|
||||||
pid_t pid;
|
|
||||||
Str emsg;
|
|
||||||
|
|
||||||
if (pipe(fdr) < 0) {
|
|
||||||
emsg = Sprintf("localcgi_popen_rw: pipe: %s", strerror(errno));
|
|
||||||
goto pipe_err0;
|
|
||||||
}
|
|
||||||
if (p_fdw && pipe(fdw) < 0) {
|
|
||||||
emsg = Sprintf("localcgi_popen_rw: pipe: %s", strerror(errno));
|
|
||||||
goto pipe_err1;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_tty();
|
|
||||||
if ((pid = fork()) < 0) {
|
|
||||||
emsg = Sprintf("localcgi_popen_rw: fork: %s", strerror(errno));
|
|
||||||
goto pipe_err2;
|
|
||||||
}
|
|
||||||
else if (!pid) {
|
|
||||||
close(fdr[0]);
|
|
||||||
dup2(fdr[1], 1);
|
|
||||||
if (p_fdw) {
|
|
||||||
close(fdw[1]);
|
|
||||||
dup2(fdw[0], 0);
|
|
||||||
}
|
|
||||||
setup_child(TRUE, 2, -1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
close(fdr[1]);
|
|
||||||
*p_fdr = fdr[0];
|
|
||||||
if (p_fdw) {
|
|
||||||
close(fdw[0]);
|
|
||||||
*p_fdw = fdw[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pid;
|
|
||||||
pipe_err2:
|
|
||||||
close(fdw[0]);
|
|
||||||
close(fdw[1]);
|
|
||||||
pipe_err1:
|
|
||||||
close(fdr[0]);
|
|
||||||
close(fdr[1]);
|
|
||||||
pipe_err0:
|
|
||||||
disp_err_message(emsg->ptr, FALSE);
|
|
||||||
return (pid_t) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *
|
FILE *
|
||||||
localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
|
localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
|
||||||
{
|
{
|
||||||
int fdr, fdw = -1;
|
FILE *fr = NULL, *fw = NULL;
|
||||||
int status;
|
int status;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
char *file;
|
char *file;
|
||||||
@@ -418,18 +368,19 @@ localcgi_post(char *uri, char *qstr, FormList *request, char *referer)
|
|||||||
return NULL;
|
return NULL;
|
||||||
writeLocalCookie();
|
writeLocalCookie();
|
||||||
if (request && request->enctype != FORM_ENCTYPE_MULTIPART)
|
if (request && request->enctype != FORM_ENCTYPE_MULTIPART)
|
||||||
pid = localcgi_popen_rw(&fdr, &fdw);
|
pid = open_pipe_rw(&fr, &fw);
|
||||||
else
|
else
|
||||||
pid = localcgi_popen_rw(&fdr, NULL);
|
pid = open_pipe_rw(&fr, NULL);
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (pid) {
|
else if (pid) {
|
||||||
if (fdw > 0) {
|
if (fw) {
|
||||||
write(fdw, request->body, request->length);
|
fwrite(request->body, sizeof(char), request->length, fw);
|
||||||
close(fdw);
|
fclose(fw);
|
||||||
}
|
}
|
||||||
return fdopen(fdr, "r");
|
return fr;
|
||||||
}
|
}
|
||||||
|
setup_child(TRUE, 2, -1);
|
||||||
|
|
||||||
if (qstr == NULL)
|
if (qstr == NULL)
|
||||||
set_cgi_environ(uri, file, uri);
|
set_cgi_environ(uri, file, uri);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: proto.h,v 1.82 2003/01/20 15:54:11 ukai Exp $ */
|
/* $Id: proto.h,v 1.83 2003/01/22 16:10:28 ukai Exp $ */
|
||||||
/*
|
/*
|
||||||
* This file was automatically generated by version 1.7 of cextract.
|
* This file was automatically generated by version 1.7 of cextract.
|
||||||
* Manual editing not recommended.
|
* Manual editing not recommended.
|
||||||
@@ -416,6 +416,7 @@ extern void set_int(void);
|
|||||||
extern void getTCstr(void);
|
extern void getTCstr(void);
|
||||||
extern void setlinescols(void);
|
extern void setlinescols(void);
|
||||||
extern void setupscreen(void);
|
extern void setupscreen(void);
|
||||||
|
extern pid_t open_pipe_rw(FILE **fr, FILE **fw);
|
||||||
extern int initscr(void);
|
extern int initscr(void);
|
||||||
extern int write1(char c);
|
extern int write1(char c);
|
||||||
extern void endline(void);
|
extern void endline(void);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $Id: search.c,v 1.24 2003/01/17 16:57:20 ukai Exp $ */
|
/* $Id: search.c,v 1.25 2003/01/22 16:10:29 ukai Exp $ */
|
||||||
#include "fm.h"
|
#include "fm.h"
|
||||||
#include "regex.h"
|
#include "regex.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -14,9 +14,9 @@ set_mark(Line *l, int pos, int epos)
|
|||||||
|
|
||||||
#ifdef USE_MIGEMO
|
#ifdef USE_MIGEMO
|
||||||
/* Migemo: romaji --> kana+kanji in regexp */
|
/* Migemo: romaji --> kana+kanji in regexp */
|
||||||
static FILE *migemor, *migemow;
|
static FILE *migemor = NULL, *migemow = NULL;
|
||||||
static int migemo_running;
|
static int migemo_running;
|
||||||
static int migemo_pid;
|
static int migemo_pid = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
init_migemo()
|
init_migemo()
|
||||||
@@ -35,41 +35,18 @@ init_migemo()
|
|||||||
static int
|
static int
|
||||||
open_migemo(char *migemo_command)
|
open_migemo(char *migemo_command)
|
||||||
{
|
{
|
||||||
int fdr[2];
|
migemo_pid = open_pipe_rw(&migemor, &migemow);
|
||||||
int fdw[2];
|
|
||||||
|
|
||||||
if (pipe(fdr) < 0)
|
|
||||||
goto err0;
|
|
||||||
if (pipe(fdw) < 0)
|
|
||||||
goto err1;
|
|
||||||
|
|
||||||
flush_tty();
|
|
||||||
/* migemow:fdw[1] -|-> fdw[0]=0 {migemo} fdr[1]=1 -|-> fdr[0]:migemor */
|
|
||||||
migemo_pid = fork();
|
|
||||||
if (migemo_pid < 0)
|
if (migemo_pid < 0)
|
||||||
goto err2;
|
goto err0;
|
||||||
if (migemo_pid == 0) {
|
if (migemo_pid == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
close(fdr[0]);
|
|
||||||
close(fdw[1]);
|
|
||||||
dup2(fdw[0], 0);
|
|
||||||
dup2(fdr[1], 1);
|
|
||||||
setup_child(FALSE, 2, -1);
|
setup_child(FALSE, 2, -1);
|
||||||
myExec(migemo_command);
|
myExec(migemo_command);
|
||||||
/* XXX: ifdef __EMX__, use start /f ? */
|
/* XXX: ifdef __EMX__, use start /f ? */
|
||||||
}
|
}
|
||||||
close(fdr[1]);
|
|
||||||
close(fdw[0]);
|
|
||||||
migemor = fdopen(fdr[0], "r");
|
|
||||||
migemow = fdopen(fdw[1], "w");
|
|
||||||
return 1;
|
return 1;
|
||||||
err2:
|
|
||||||
close(fdw[0]);
|
|
||||||
close(fdw[1]);
|
|
||||||
err1:
|
|
||||||
close(fdr[0]);
|
|
||||||
close(fdr[1]);
|
|
||||||
err0:
|
err0:
|
||||||
|
migemo_pid = 0;
|
||||||
migemo_active = migemo_running = 0;
|
migemo_active = migemo_running = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user