mirror of
https://github.com/moparisthebest/curl
synced 2025-03-11 07:39:50 -04:00
moved the dynamicly set pointers to the connectdata struct
This commit is contained in:
parent
1c6f6f6972
commit
584dbffe60
@ -493,7 +493,7 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
|
if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
|
||||||
(data->maxdownload != *ftp->bytecountp)) {
|
(conn->maxdownload != *ftp->bytecountp)) {
|
||||||
failf(data, "Received only partial file");
|
failf(data, "Received only partial file");
|
||||||
return CURLE_PARTIAL_FILE;
|
return CURLE_PARTIAL_FILE;
|
||||||
}
|
}
|
||||||
@ -1393,16 +1393,16 @@ again:;
|
|||||||
else if(from < 0) {
|
else if(from < 0) {
|
||||||
/* -Y */
|
/* -Y */
|
||||||
totalsize = -from;
|
totalsize = -from;
|
||||||
data->maxdownload = -from;
|
conn->maxdownload = -from;
|
||||||
data->resume_from = from;
|
data->resume_from = from;
|
||||||
infof(data, "FTP RANGE the last %d bytes\n", totalsize);
|
infof(data, "FTP RANGE the last %d bytes\n", totalsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* X-Y */
|
/* X-Y */
|
||||||
totalsize = to-from;
|
totalsize = to-from;
|
||||||
data->maxdownload = totalsize+1; /* include the last mentioned byte */
|
conn->maxdownload = totalsize+1; /* include the last mentioned byte */
|
||||||
data->resume_from = from;
|
data->resume_from = from;
|
||||||
infof(data, "FTP RANGE from %d getting %d bytes\n", from, data->maxdownload);
|
infof(data, "FTP RANGE from %d getting %d bytes\n", from, conn->maxdownload);
|
||||||
}
|
}
|
||||||
infof(data, "range-download from %d to %d, totally %d bytes\n",
|
infof(data, "range-download from %d to %d, totally %d bytes\n",
|
||||||
from, to, totalsize);
|
from, to, totalsize);
|
||||||
|
57
lib/http.c
57
lib/http.c
@ -282,8 +282,8 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
"%s"
|
"%s"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
hostname, remote_port,
|
hostname, remote_port,
|
||||||
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
(data->bits.proxy_user_passwd)?conn->allocptr.proxyuserpwd:"",
|
||||||
(data->useragent?data->ptr_uagent:"")
|
(data->useragent?conn->allocptr.uagent:"")
|
||||||
);
|
);
|
||||||
|
|
||||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
||||||
@ -405,9 +405,9 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
have been used in the proxy connect, but if we have got a header with
|
have been used in the proxy connect, but if we have got a header with
|
||||||
the user-agent string specified, we erase the previously made string
|
the user-agent string specified, we erase the previously made string
|
||||||
here. */
|
here. */
|
||||||
if(checkheaders(data, "User-Agent:") && data->ptr_uagent) {
|
if(checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
|
||||||
free(data->ptr_uagent);
|
free(conn->allocptr.uagent);
|
||||||
data->ptr_uagent=NULL;
|
conn->allocptr.uagent=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
|
if((data->bits.user_passwd) && !checkheaders(data, "Authorization:")) {
|
||||||
@ -421,23 +421,23 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
sprintf(data->buffer, "%s:%s", data->user, data->passwd);
|
sprintf(data->buffer, "%s:%s", data->user, data->passwd);
|
||||||
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
|
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
|
||||||
&authorization) >= 0) {
|
&authorization) >= 0) {
|
||||||
if(data->ptr_userpwd)
|
if(conn->allocptr.userpwd)
|
||||||
free(data->ptr_userpwd);
|
free(conn->allocptr.userpwd);
|
||||||
data->ptr_userpwd = aprintf( "Authorization: Basic %s\015\012",
|
conn->allocptr.userpwd = aprintf( "Authorization: Basic %s\015\012",
|
||||||
authorization);
|
authorization);
|
||||||
free(authorization);
|
free(authorization);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
|
if((data->bits.http_set_referer) && !checkheaders(data, "Referer:")) {
|
||||||
if(data->ptr_ref)
|
if(conn->allocptr.ref)
|
||||||
free(data->ptr_ref);
|
free(conn->allocptr.ref);
|
||||||
data->ptr_ref = aprintf("Referer: %s\015\012", data->referer);
|
conn->allocptr.ref = aprintf("Referer: %s\015\012", data->referer);
|
||||||
}
|
}
|
||||||
if(data->cookie && !checkheaders(data, "Cookie:")) {
|
if(data->cookie && !checkheaders(data, "Cookie:")) {
|
||||||
if(data->ptr_cookie)
|
if(conn->allocptr.cookie)
|
||||||
free(data->ptr_cookie);
|
free(conn->allocptr.cookie);
|
||||||
data->ptr_cookie = aprintf("Cookie: %s\015\012", data->cookie);
|
conn->allocptr.cookie = aprintf("Cookie: %s\015\012", data->cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->cookies) {
|
if(data->cookies) {
|
||||||
@ -457,7 +457,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!checkheaders(data, "Host:") &&
|
if(!checkheaders(data, "Host:") &&
|
||||||
!data->ptr_host) {
|
!conn->allocptr.host) {
|
||||||
/* if ptr_host is already set, it is OK since we only re-use connections
|
/* if ptr_host is already set, it is OK since we only re-use connections
|
||||||
to the very same host and port */
|
to the very same host and port */
|
||||||
|
|
||||||
@ -465,9 +465,10 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
(!(conn->protocol&PROT_HTTPS) && (data->remote_port == PORT_HTTP)) )
|
(!(conn->protocol&PROT_HTTPS) && (data->remote_port == PORT_HTTP)) )
|
||||||
/* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
|
/* If (HTTPS on port 443) OR (non-HTTPS on port 80) then don't include
|
||||||
the port number in the host string */
|
the port number in the host string */
|
||||||
data->ptr_host = aprintf("Host: %s\r\n", host);
|
conn->allocptr.host = aprintf("Host: %s\r\n", host);
|
||||||
else
|
else
|
||||||
data->ptr_host = aprintf("Host: %s:%d\r\n", host, data->remote_port);
|
conn->allocptr.host = aprintf("Host: %s:%d\r\n", host,
|
||||||
|
data->remote_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!checkheaders(data, "Pragma:"))
|
if(!checkheaders(data, "Pragma:"))
|
||||||
@ -541,7 +542,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
*/
|
*/
|
||||||
if((data->httpreq == HTTPREQ_GET) &&
|
if((data->httpreq == HTTPREQ_GET) &&
|
||||||
!checkheaders(data, "Range:")) {
|
!checkheaders(data, "Range:")) {
|
||||||
data->ptr_rangeline = aprintf("Range: bytes=%s\r\n", data->range);
|
conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", data->range);
|
||||||
}
|
}
|
||||||
else if((data->httpreq != HTTPREQ_GET) &&
|
else if((data->httpreq != HTTPREQ_GET) &&
|
||||||
!checkheaders(data, "Content-Range:")) {
|
!checkheaders(data, "Content-Range:")) {
|
||||||
@ -549,14 +550,14 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
if(data->resume_from) {
|
if(data->resume_from) {
|
||||||
/* This is because "resume" was selected */
|
/* This is because "resume" was selected */
|
||||||
long total_expected_size= data->resume_from + data->infilesize;
|
long total_expected_size= data->resume_from + data->infilesize;
|
||||||
data->ptr_rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
|
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s%ld/%ld\r\n",
|
||||||
data->range, total_expected_size-1,
|
data->range, total_expected_size-1,
|
||||||
total_expected_size);
|
total_expected_size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Range was selected and then we just pass the incoming range and
|
/* Range was selected and then we just pass the incoming range and
|
||||||
append total size */
|
append total size */
|
||||||
data->ptr_rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
|
conn->allocptr.rangeline = aprintf("Content-Range: bytes %s/%d\r\n",
|
||||||
data->range, data->infilesize);
|
data->range, data->infilesize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -572,7 +573,7 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
/* add the main request stuff */
|
/* add the main request stuff */
|
||||||
add_bufferf(req_buffer,
|
add_bufferf(req_buffer,
|
||||||
"%s " /* GET/HEAD/POST/PUT */
|
"%s " /* GET/HEAD/POST/PUT */
|
||||||
"%s HTTP/1.0\r\n" /* path */
|
"%s HTTP/1.1\r\n" /* path */
|
||||||
"%s" /* proxyuserpwd */
|
"%s" /* proxyuserpwd */
|
||||||
"%s" /* userpwd */
|
"%s" /* userpwd */
|
||||||
"%s" /* range */
|
"%s" /* range */
|
||||||
@ -588,15 +589,15 @@ CURLcode Curl_http(struct connectdata *conn)
|
|||||||
(data->bits.http_post || data->bits.http_formpost)?"POST":
|
(data->bits.http_post || data->bits.http_formpost)?"POST":
|
||||||
(data->bits.http_put)?"PUT":"GET"),
|
(data->bits.http_put)?"PUT":"GET"),
|
||||||
ppath,
|
ppath,
|
||||||
(data->bits.proxy_user_passwd && data->ptr_proxyuserpwd)?data->ptr_proxyuserpwd:"",
|
(data->bits.proxy_user_passwd && conn->allocptr.proxyuserpwd)?conn->allocptr.proxyuserpwd:"",
|
||||||
(data->bits.user_passwd && data->ptr_userpwd)?data->ptr_userpwd:"",
|
(data->bits.user_passwd && conn->allocptr.userpwd)?conn->allocptr.userpwd:"",
|
||||||
(data->bits.set_range && data->ptr_rangeline)?data->ptr_rangeline:"",
|
(data->bits.set_range && conn->allocptr.rangeline)?conn->allocptr.rangeline:"",
|
||||||
(data->useragent && *data->useragent && data->ptr_uagent)?data->ptr_uagent:"",
|
(data->useragent && *data->useragent && conn->allocptr.uagent)?conn->allocptr.uagent:"",
|
||||||
(data->ptr_cookie?data->ptr_cookie:""), /* Cookie: <data> */
|
(conn->allocptr.cookie?conn->allocptr.cookie:""), /* Cookie: <data> */
|
||||||
(data->ptr_host?data->ptr_host:""), /* Host: host */
|
(conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
|
||||||
http->p_pragma?http->p_pragma:"",
|
http->p_pragma?http->p_pragma:"",
|
||||||
http->p_accept?http->p_accept:"",
|
http->p_accept?http->p_accept:"",
|
||||||
(data->bits.http_set_referer && data->ptr_ref)?data->ptr_ref:"" /* Referer: <data> <CRLF> */
|
(data->bits.http_set_referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> <CRLF> */
|
||||||
);
|
);
|
||||||
|
|
||||||
if(co) {
|
if(co) {
|
||||||
|
63
lib/url.c
63
lib/url.c
@ -158,35 +158,6 @@ CURLcode curl_close(CURL *curl)
|
|||||||
data->bits.rangestringalloc=0; /* free now */
|
data->bits.rangestringalloc=0; /* free now */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data->ptr_proxyuserpwd) {
|
|
||||||
free(data->ptr_proxyuserpwd);
|
|
||||||
data->ptr_proxyuserpwd=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_uagent) {
|
|
||||||
free(data->ptr_uagent);
|
|
||||||
data->ptr_uagent=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_userpwd) {
|
|
||||||
free(data->ptr_userpwd);
|
|
||||||
data->ptr_userpwd=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_rangeline) {
|
|
||||||
free(data->ptr_rangeline);
|
|
||||||
data->ptr_rangeline=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_ref) {
|
|
||||||
free(data->ptr_ref);
|
|
||||||
data->ptr_ref=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_cookie) {
|
|
||||||
free(data->ptr_cookie);
|
|
||||||
data->ptr_cookie=NULL;
|
|
||||||
}
|
|
||||||
if(data->ptr_host) {
|
|
||||||
free(data->ptr_host);
|
|
||||||
data->ptr_host=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for allocated [URL] memory to free: */
|
/* check for allocated [URL] memory to free: */
|
||||||
if(data->freethis)
|
if(data->freethis)
|
||||||
free(data->freethis);
|
free(data->freethis);
|
||||||
@ -577,13 +548,26 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
|
|||||||
/* close possibly still open sockets */
|
/* close possibly still open sockets */
|
||||||
if(-1 != conn->secondarysocket) {
|
if(-1 != conn->secondarysocket) {
|
||||||
sclose(conn->secondarysocket);
|
sclose(conn->secondarysocket);
|
||||||
conn->secondarysocket = -1;
|
|
||||||
}
|
}
|
||||||
if(-1 != conn->firstsocket) {
|
if(-1 != conn->firstsocket) {
|
||||||
sclose(conn->firstsocket);
|
sclose(conn->firstsocket);
|
||||||
conn->firstsocket=-1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(conn->allocptr.proxyuserpwd)
|
||||||
|
free(conn->allocptr.proxyuserpwd);
|
||||||
|
if(conn->allocptr.uagent)
|
||||||
|
free(conn->allocptr.uagent);
|
||||||
|
if(conn->allocptr.userpwd)
|
||||||
|
free(conn->allocptr.userpwd);
|
||||||
|
if(conn->allocptr.rangeline)
|
||||||
|
free(conn->allocptr.rangeline);
|
||||||
|
if(conn->allocptr.ref)
|
||||||
|
free(conn->allocptr.ref);
|
||||||
|
if(conn->allocptr.cookie)
|
||||||
|
free(conn->allocptr.cookie);
|
||||||
|
if(conn->allocptr.host)
|
||||||
|
free(conn->allocptr.host);
|
||||||
|
|
||||||
free(conn); /* free all the connection oriented data */
|
free(conn); /* free all the connection oriented data */
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@ -1544,6 +1528,11 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
free(conn->path); /* free the previous path pointer */
|
free(conn->path); /* free the previous path pointer */
|
||||||
conn->path = path; /* use this one */
|
conn->path = path; /* use this one */
|
||||||
conn->ppath = path; /* set this too */
|
conn->ppath = path; /* set this too */
|
||||||
|
|
||||||
|
/* re-use init */
|
||||||
|
conn->maxdownload = 0; /* might have been used previously! */
|
||||||
|
|
||||||
|
infof(data, "Re-using existing connection! (#%d)\n", conn->connectindex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
@ -1653,9 +1642,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
data->proxyuser, data->proxypasswd);
|
data->proxyuser, data->proxypasswd);
|
||||||
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
|
if(Curl_base64_encode(data->buffer, strlen(data->buffer),
|
||||||
&authorization) >= 0) {
|
&authorization) >= 0) {
|
||||||
if(data->ptr_proxyuserpwd)
|
if(conn->allocptr.proxyuserpwd)
|
||||||
free(data->ptr_proxyuserpwd);
|
free(conn->allocptr.proxyuserpwd);
|
||||||
data->ptr_proxyuserpwd =
|
conn->allocptr.proxyuserpwd =
|
||||||
aprintf("Proxy-authorization: Basic %s\015\012", authorization);
|
aprintf("Proxy-authorization: Basic %s\015\012", authorization);
|
||||||
free(authorization);
|
free(authorization);
|
||||||
}
|
}
|
||||||
@ -1667,9 +1656,9 @@ static CURLcode _connect(CURL *curl, CURLconnect **in_connect)
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
|
if((conn->protocol&PROT_HTTP) || data->bits.httpproxy) {
|
||||||
if(data->useragent) {
|
if(data->useragent) {
|
||||||
if(data->ptr_uagent)
|
if(conn->allocptr.uagent)
|
||||||
free(data->ptr_uagent);
|
free(conn->allocptr.uagent);
|
||||||
data->ptr_uagent =
|
conn->allocptr.uagent =
|
||||||
aprintf("User-Agent: %s\015\012", data->useragent);
|
aprintf("User-Agent: %s\015\012", data->useragent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,6 +242,9 @@ struct connectdata {
|
|||||||
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
|
long upload_bufsize; /* adjust as you see fit, never bigger than BUFSIZE
|
||||||
never smaller than UPLOAD_BUFSIZE */
|
never smaller than UPLOAD_BUFSIZE */
|
||||||
|
|
||||||
|
long maxdownload; /* in bytes, the maximum amount of data to fetch, 0
|
||||||
|
means unlimited */
|
||||||
|
|
||||||
struct ssl_connect_data ssl; /* this is for ssl-stuff */
|
struct ssl_connect_data ssl; /* this is for ssl-stuff */
|
||||||
|
|
||||||
struct ConnectBits bits; /* various state-flags for this connection */
|
struct ConnectBits bits; /* various state-flags for this connection */
|
||||||
@ -274,6 +277,17 @@ struct connectdata {
|
|||||||
the same we read from. -1 disables */
|
the same we read from. -1 disables */
|
||||||
long *writebytecountp; /* return number of bytes written or NULL */
|
long *writebytecountp; /* return number of bytes written or NULL */
|
||||||
|
|
||||||
|
/** Dynamicly allocated strings, may need to be freed before this **/
|
||||||
|
/** struct is killed. **/
|
||||||
|
struct dynamically_allocated_data {
|
||||||
|
char *proxyuserpwd; /* free later if not NULL! */
|
||||||
|
char *uagent; /* free later if not NULL! */
|
||||||
|
char *userpwd; /* free later if not NULL! */
|
||||||
|
char *rangeline; /* free later if not NULL! */
|
||||||
|
char *ref; /* free later if not NULL! */
|
||||||
|
char *cookie; /* free later if not NULL! */
|
||||||
|
char *host; /* free later if not NULL */
|
||||||
|
} allocptr;
|
||||||
|
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
|
|
||||||
@ -411,11 +425,15 @@ typedef enum {
|
|||||||
*
|
*
|
||||||
* (Request)
|
* (Request)
|
||||||
* 3 - Request-specific. Variables that are of interest for this particular
|
* 3 - Request-specific. Variables that are of interest for this particular
|
||||||
* transfer being made right now.
|
* transfer being made right now. THIS IS WRONG STRUCT FOR THOSE.
|
||||||
*
|
*
|
||||||
* In Febrary 2001, this is being done stricter. The 'connectdata' struct
|
* In Febrary 2001, this is being done stricter. The 'connectdata' struct
|
||||||
* MUST have all the connection oriented stuff as we may now have several
|
* MUST have all the connection oriented stuff as we may now have several
|
||||||
* simultaneous connections and connection structs in memory.
|
* simultaneous connections and connection structs in memory.
|
||||||
|
*
|
||||||
|
* From now on, the 'UrlData' must only contain data that is set once to go
|
||||||
|
* for many (perhaps) independent connections. Values that are generated or
|
||||||
|
* calculated internally MUST NOT be a part of this struct.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct UrlData {
|
struct UrlData {
|
||||||
@ -488,9 +506,6 @@ struct UrlData {
|
|||||||
long timeout; /* in seconds, 0 means no timeout */
|
long timeout; /* in seconds, 0 means no timeout */
|
||||||
long infilesize; /* size of file to upload, -1 means unknown */
|
long infilesize; /* size of file to upload, -1 means unknown */
|
||||||
|
|
||||||
long maxdownload; /* in bytes, the maximum amount of data to fetch, 0
|
|
||||||
means unlimited */
|
|
||||||
|
|
||||||
char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
|
char buffer[BUFSIZE+1]; /* buffer with size BUFSIZE */
|
||||||
|
|
||||||
double current_speed; /* the ProgressShow() funcion sets this */
|
double current_speed; /* the ProgressShow() funcion sets this */
|
||||||
@ -546,15 +561,6 @@ struct UrlData {
|
|||||||
char proxyuser[MAX_CURL_USER_LENGTH];
|
char proxyuser[MAX_CURL_USER_LENGTH];
|
||||||
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
|
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
|
||||||
|
|
||||||
/**** Dynamicly allocated strings, may need to be freed on return ****/
|
|
||||||
char *ptr_proxyuserpwd; /* free later if not NULL! */
|
|
||||||
char *ptr_uagent; /* free later if not NULL! */
|
|
||||||
char *ptr_userpwd; /* free later if not NULL! */
|
|
||||||
char *ptr_rangeline; /* free later if not NULL! */
|
|
||||||
char *ptr_ref; /* free later if not NULL! */
|
|
||||||
char *ptr_cookie; /* free later if not NULL! */
|
|
||||||
char *ptr_host; /* free later if not NULL */
|
|
||||||
|
|
||||||
char *krb4_level; /* what security level */
|
char *krb4_level; /* what security level */
|
||||||
#ifdef KRB4
|
#ifdef KRB4
|
||||||
FILE *cmdchannel;
|
FILE *cmdchannel;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user