mirror of
https://github.com/chatmail/core.git
synced 2026-05-16 21:36:30 +03:00
run rustfmt
This commit is contained in:
433
src/dc_qr.rs
433
src/dc_qr.rs
@@ -54,249 +54,246 @@ pub unsafe fn dc_check_qr(context: &Context, qr: *const libc::c_char) -> *mut dc
|
|||||||
return cleanup();
|
return cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(context, 0, "Scanned QR code: {}", as_str(qr),);
|
info!(context, 0, "Scanned QR code: {}", as_str(qr),);
|
||||||
/* split parameters from the qr code
|
/* split parameters from the qr code
|
||||||
------------------------------------ */
|
------------------------------------ */
|
||||||
if strncasecmp(
|
if strncasecmp(
|
||||||
qr,
|
qr,
|
||||||
b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char,
|
b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char,
|
||||||
strlen(b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char),
|
strlen(b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char),
|
||||||
) == 0i32
|
) == 0i32
|
||||||
{
|
{
|
||||||
payload =
|
payload = dc_strdup(
|
||||||
dc_strdup(&*qr.offset(strlen(
|
&*qr.offset(strlen(b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char) as isize),
|
||||||
b"OPENPGP4FPR:\x00" as *const u8 as *const libc::c_char,
|
);
|
||||||
) as isize));
|
let mut fragment: *mut libc::c_char = strchr(payload, '#' as i32);
|
||||||
let mut fragment: *mut libc::c_char = strchr(payload, '#' as i32);
|
if !fragment.is_null() {
|
||||||
if !fragment.is_null() {
|
*fragment = 0i32 as libc::c_char;
|
||||||
*fragment = 0i32 as libc::c_char;
|
fragment = fragment.offset(1isize);
|
||||||
fragment = fragment.offset(1isize);
|
let param: *mut dc_param_t = dc_param_new();
|
||||||
let param: *mut dc_param_t = dc_param_new();
|
dc_param_set_urlencoded(param, fragment);
|
||||||
dc_param_set_urlencoded(param, fragment);
|
addr = dc_param_get(param, DC_PARAM_FORWARDED as i32, 0 as *const libc::c_char);
|
||||||
addr = dc_param_get(param, DC_PARAM_FORWARDED as i32, 0 as *const libc::c_char);
|
if !addr.is_null() {
|
||||||
if !addr.is_null() {
|
let mut urlencoded: *mut libc::c_char = dc_param_get(
|
||||||
let mut urlencoded: *mut libc::c_char = dc_param_get(
|
param,
|
||||||
param,
|
DC_PARAM_SET_LONGITUDE as i32,
|
||||||
DC_PARAM_SET_LONGITUDE as i32,
|
0 as *const libc::c_char,
|
||||||
0 as *const libc::c_char,
|
);
|
||||||
);
|
if !urlencoded.is_null() {
|
||||||
|
name = dc_urldecode(urlencoded);
|
||||||
|
dc_normalize_name(name);
|
||||||
|
free(urlencoded as *mut libc::c_void);
|
||||||
|
}
|
||||||
|
invitenumber = dc_param_get(
|
||||||
|
param,
|
||||||
|
DC_PARAM_PROFILE_IMAGE as i32,
|
||||||
|
0 as *const libc::c_char,
|
||||||
|
);
|
||||||
|
auth = dc_param_get(param, 's' as i32, 0 as *const libc::c_char);
|
||||||
|
grpid = dc_param_get(param, 'x' as i32, 0 as *const libc::c_char);
|
||||||
|
if !grpid.is_null() {
|
||||||
|
urlencoded = dc_param_get(param, 'g' as i32, 0 as *const libc::c_char);
|
||||||
if !urlencoded.is_null() {
|
if !urlencoded.is_null() {
|
||||||
name = dc_urldecode(urlencoded);
|
grpname = dc_urldecode(urlencoded);
|
||||||
dc_normalize_name(name);
|
|
||||||
free(urlencoded as *mut libc::c_void);
|
free(urlencoded as *mut libc::c_void);
|
||||||
}
|
}
|
||||||
invitenumber = dc_param_get(
|
|
||||||
param,
|
|
||||||
DC_PARAM_PROFILE_IMAGE as i32,
|
|
||||||
0 as *const libc::c_char,
|
|
||||||
);
|
|
||||||
auth = dc_param_get(param, 's' as i32, 0 as *const libc::c_char);
|
|
||||||
grpid = dc_param_get(param, 'x' as i32, 0 as *const libc::c_char);
|
|
||||||
if !grpid.is_null() {
|
|
||||||
urlencoded = dc_param_get(param, 'g' as i32, 0 as *const libc::c_char);
|
|
||||||
if !urlencoded.is_null() {
|
|
||||||
grpname = dc_urldecode(urlencoded);
|
|
||||||
free(urlencoded as *mut libc::c_void);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dc_param_unref(param);
|
|
||||||
}
|
}
|
||||||
fingerprint = dc_normalize_fingerprint_c(payload);
|
dc_param_unref(param);
|
||||||
} else if strncasecmp(
|
}
|
||||||
qr,
|
fingerprint = dc_normalize_fingerprint_c(payload);
|
||||||
b"mailto:\x00" as *const u8 as *const libc::c_char,
|
} else if strncasecmp(
|
||||||
strlen(b"mailto:\x00" as *const u8 as *const libc::c_char),
|
qr,
|
||||||
) == 0i32
|
b"mailto:\x00" as *const u8 as *const libc::c_char,
|
||||||
{
|
strlen(b"mailto:\x00" as *const u8 as *const libc::c_char),
|
||||||
payload = dc_strdup(
|
) == 0i32
|
||||||
&*qr.offset(strlen(b"mailto:\x00" as *const u8 as *const libc::c_char) as isize),
|
{
|
||||||
);
|
payload = dc_strdup(
|
||||||
let query: *mut libc::c_char = strchr(payload, '?' as i32);
|
&*qr.offset(strlen(b"mailto:\x00" as *const u8 as *const libc::c_char) as isize),
|
||||||
if !query.is_null() {
|
);
|
||||||
*query = 0i32 as libc::c_char
|
let query: *mut libc::c_char = strchr(payload, '?' as i32);
|
||||||
}
|
if !query.is_null() {
|
||||||
addr = dc_strdup(payload);
|
*query = 0i32 as libc::c_char
|
||||||
} else if strncasecmp(
|
}
|
||||||
qr,
|
addr = dc_strdup(payload);
|
||||||
b"SMTP:\x00" as *const u8 as *const libc::c_char,
|
} else if strncasecmp(
|
||||||
strlen(b"SMTP:\x00" as *const u8 as *const libc::c_char),
|
qr,
|
||||||
) == 0i32
|
b"SMTP:\x00" as *const u8 as *const libc::c_char,
|
||||||
{
|
strlen(b"SMTP:\x00" as *const u8 as *const libc::c_char),
|
||||||
payload = dc_strdup(
|
) == 0i32
|
||||||
&*qr.offset(strlen(b"SMTP:\x00" as *const u8 as *const libc::c_char) as isize),
|
{
|
||||||
);
|
payload = dc_strdup(
|
||||||
let colon: *mut libc::c_char = strchr(payload, ':' as i32);
|
&*qr.offset(strlen(b"SMTP:\x00" as *const u8 as *const libc::c_char) as isize),
|
||||||
if !colon.is_null() {
|
);
|
||||||
*colon = 0i32 as libc::c_char
|
let colon: *mut libc::c_char = strchr(payload, ':' as i32);
|
||||||
}
|
if !colon.is_null() {
|
||||||
addr = dc_strdup(payload);
|
*colon = 0i32 as libc::c_char
|
||||||
} else if strncasecmp(
|
}
|
||||||
qr,
|
addr = dc_strdup(payload);
|
||||||
b"MATMSG:\x00" as *const u8 as *const libc::c_char,
|
} else if strncasecmp(
|
||||||
strlen(b"MATMSG:\x00" as *const u8 as *const libc::c_char),
|
qr,
|
||||||
) == 0i32
|
b"MATMSG:\x00" as *const u8 as *const libc::c_char,
|
||||||
{
|
strlen(b"MATMSG:\x00" as *const u8 as *const libc::c_char),
|
||||||
/* scheme: `MATMSG:TO:addr...;SUB:subject...;BODY:body...;` - there may or may not be linebreaks after the fields */
|
) == 0i32
|
||||||
/* does not work when the text `TO:` is used in subject/body _and_ TO: is not the first field. we ignore this case. */
|
{
|
||||||
let to: *mut libc::c_char = strstr(qr, b"TO:\x00" as *const u8 as *const libc::c_char);
|
/* scheme: `MATMSG:TO:addr...;SUB:subject...;BODY:body...;` - there may or may not be linebreaks after the fields */
|
||||||
if !to.is_null() {
|
/* does not work when the text `TO:` is used in subject/body _and_ TO: is not the first field. we ignore this case. */
|
||||||
addr = dc_strdup(&mut *to.offset(3isize));
|
let to: *mut libc::c_char = strstr(qr, b"TO:\x00" as *const u8 as *const libc::c_char);
|
||||||
let semicolon: *mut libc::c_char = strchr(addr, ';' as i32);
|
if !to.is_null() {
|
||||||
if !semicolon.is_null() {
|
addr = dc_strdup(&mut *to.offset(3isize));
|
||||||
*semicolon = 0i32 as libc::c_char
|
let semicolon: *mut libc::c_char = strchr(addr, ';' as i32);
|
||||||
}
|
if !semicolon.is_null() {
|
||||||
} else {
|
*semicolon = 0i32 as libc::c_char
|
||||||
(*qr_parsed).state = 400i32;
|
|
||||||
(*qr_parsed).text1 =
|
|
||||||
dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char);
|
|
||||||
return cleanup();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if strncasecmp(
|
(*qr_parsed).state = 400i32;
|
||||||
qr,
|
(*qr_parsed).text1 =
|
||||||
b"BEGIN:VCARD\x00" as *const u8 as *const libc::c_char,
|
dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char);
|
||||||
strlen(b"BEGIN:VCARD\x00" as *const u8 as *const libc::c_char),
|
return cleanup();
|
||||||
) == 0i32
|
}
|
||||||
{
|
} else {
|
||||||
let lines: *mut carray = dc_split_into_lines(qr);
|
if strncasecmp(
|
||||||
let mut i: libc::c_int = 0i32;
|
qr,
|
||||||
while (i as libc::c_uint) < carray_count(lines) {
|
b"BEGIN:VCARD\x00" as *const u8 as *const libc::c_char,
|
||||||
let key: *mut libc::c_char =
|
strlen(b"BEGIN:VCARD\x00" as *const u8 as *const libc::c_char),
|
||||||
carray_get(lines, i as libc::c_uint) as *mut libc::c_char;
|
) == 0i32
|
||||||
dc_trim(key);
|
{
|
||||||
let mut value: *mut libc::c_char = strchr(key, ':' as i32);
|
let lines: *mut carray = dc_split_into_lines(qr);
|
||||||
if !value.is_null() {
|
let mut i: libc::c_int = 0i32;
|
||||||
*value = 0i32 as libc::c_char;
|
while (i as libc::c_uint) < carray_count(lines) {
|
||||||
value = value.offset(1isize);
|
let key: *mut libc::c_char =
|
||||||
let mut semicolon_0: *mut libc::c_char = strchr(key, ';' as i32);
|
carray_get(lines, i as libc::c_uint) as *mut libc::c_char;
|
||||||
|
dc_trim(key);
|
||||||
|
let mut value: *mut libc::c_char = strchr(key, ':' as i32);
|
||||||
|
if !value.is_null() {
|
||||||
|
*value = 0i32 as libc::c_char;
|
||||||
|
value = value.offset(1isize);
|
||||||
|
let mut semicolon_0: *mut libc::c_char = strchr(key, ';' as i32);
|
||||||
|
if !semicolon_0.is_null() {
|
||||||
|
*semicolon_0 = 0i32 as libc::c_char
|
||||||
|
}
|
||||||
|
if strcasecmp(key, b"EMAIL\x00" as *const u8 as *const libc::c_char) == 0i32 {
|
||||||
|
semicolon_0 = strchr(value, ';' as i32);
|
||||||
if !semicolon_0.is_null() {
|
if !semicolon_0.is_null() {
|
||||||
*semicolon_0 = 0i32 as libc::c_char
|
*semicolon_0 = 0i32 as libc::c_char
|
||||||
}
|
}
|
||||||
if strcasecmp(key, b"EMAIL\x00" as *const u8 as *const libc::c_char) == 0i32
|
addr = dc_strdup(value)
|
||||||
{
|
} else if strcasecmp(key, b"N\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||||
semicolon_0 = strchr(value, ';' as i32);
|
{
|
||||||
|
semicolon_0 = strchr(value, ';' as i32);
|
||||||
|
if !semicolon_0.is_null() {
|
||||||
|
semicolon_0 = strchr(semicolon_0.offset(1isize), ';' as i32);
|
||||||
if !semicolon_0.is_null() {
|
if !semicolon_0.is_null() {
|
||||||
*semicolon_0 = 0i32 as libc::c_char
|
*semicolon_0 = 0i32 as libc::c_char
|
||||||
}
|
}
|
||||||
addr = dc_strdup(value)
|
|
||||||
} else if strcasecmp(key, b"N\x00" as *const u8 as *const libc::c_char)
|
|
||||||
== 0i32
|
|
||||||
{
|
|
||||||
semicolon_0 = strchr(value, ';' as i32);
|
|
||||||
if !semicolon_0.is_null() {
|
|
||||||
semicolon_0 = strchr(semicolon_0.offset(1isize), ';' as i32);
|
|
||||||
if !semicolon_0.is_null() {
|
|
||||||
*semicolon_0 = 0i32 as libc::c_char
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name = dc_strdup(value);
|
|
||||||
dc_str_replace(
|
|
||||||
&mut name,
|
|
||||||
b";\x00" as *const u8 as *const libc::c_char,
|
|
||||||
b",\x00" as *const u8 as *const libc::c_char,
|
|
||||||
);
|
|
||||||
dc_normalize_name(name);
|
|
||||||
}
|
}
|
||||||
|
name = dc_strdup(value);
|
||||||
|
dc_str_replace(
|
||||||
|
&mut name,
|
||||||
|
b";\x00" as *const u8 as *const libc::c_char,
|
||||||
|
b",\x00" as *const u8 as *const libc::c_char,
|
||||||
|
);
|
||||||
|
dc_normalize_name(name);
|
||||||
}
|
}
|
||||||
i += 1
|
|
||||||
}
|
}
|
||||||
dc_free_splitted_lines(lines);
|
i += 1
|
||||||
}
|
}
|
||||||
|
dc_free_splitted_lines(lines);
|
||||||
}
|
}
|
||||||
/* check the parameters
|
}
|
||||||
---------------------- */
|
/* check the parameters
|
||||||
if !addr.is_null() {
|
---------------------- */
|
||||||
/* urldecoding is needed at least for OPENPGP4FPR but should not hurt in the other cases */
|
if !addr.is_null() {
|
||||||
let mut temp: *mut libc::c_char = dc_urldecode(addr);
|
/* urldecoding is needed at least for OPENPGP4FPR but should not hurt in the other cases */
|
||||||
free(addr as *mut libc::c_void);
|
let mut temp: *mut libc::c_char = dc_urldecode(addr);
|
||||||
addr = temp;
|
free(addr as *mut libc::c_void);
|
||||||
temp = dc_addr_normalize(addr);
|
addr = temp;
|
||||||
free(addr as *mut libc::c_void);
|
temp = dc_addr_normalize(addr);
|
||||||
addr = temp;
|
free(addr as *mut libc::c_void);
|
||||||
if !dc_may_be_valid_addr(addr) {
|
addr = temp;
|
||||||
(*qr_parsed).state = 400i32;
|
if !dc_may_be_valid_addr(addr) {
|
||||||
(*qr_parsed).text1 =
|
(*qr_parsed).state = 400i32;
|
||||||
dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char);
|
(*qr_parsed).text1 =
|
||||||
return cleanup();
|
dc_strdup(b"Bad e-mail address.\x00" as *const u8 as *const libc::c_char);
|
||||||
}
|
return cleanup();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !fingerprint.is_null() {
|
if !fingerprint.is_null() {
|
||||||
if strlen(fingerprint) != 40 {
|
if strlen(fingerprint) != 40 {
|
||||||
(*qr_parsed).state = 400i32;
|
(*qr_parsed).state = 400i32;
|
||||||
(*qr_parsed).text1 = dc_strdup(
|
(*qr_parsed).text1 = dc_strdup(
|
||||||
b"Bad fingerprint length in QR code.\x00" as *const u8 as *const libc::c_char,
|
b"Bad fingerprint length in QR code.\x00" as *const u8 as *const libc::c_char,
|
||||||
|
);
|
||||||
|
return cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !fingerprint.is_null() {
|
||||||
|
let peerstate = Peerstate::from_fingerprint(context, &context.sql, as_str(fingerprint));
|
||||||
|
if addr.is_null() || invitenumber.is_null() || auth.is_null() {
|
||||||
|
if let Some(peerstate) = peerstate {
|
||||||
|
(*qr_parsed).state = 210i32;
|
||||||
|
let addr_ptr = if let Some(ref addr) = peerstate.addr {
|
||||||
|
to_cstring(addr)
|
||||||
|
} else {
|
||||||
|
std::ptr::null()
|
||||||
|
};
|
||||||
|
(*qr_parsed).id = dc_add_or_lookup_contact(
|
||||||
|
context,
|
||||||
|
0 as *const libc::c_char,
|
||||||
|
addr_ptr,
|
||||||
|
0x80i32,
|
||||||
|
0 as *mut libc::c_int,
|
||||||
);
|
);
|
||||||
return cleanup();
|
free(addr_ptr as *mut _);
|
||||||
}
|
dc_create_or_lookup_nchat_by_contact_id(
|
||||||
}
|
context,
|
||||||
|
(*qr_parsed).id,
|
||||||
if !fingerprint.is_null() {
|
2i32,
|
||||||
let peerstate = Peerstate::from_fingerprint(context, &context.sql, as_str(fingerprint));
|
&mut chat_id,
|
||||||
if addr.is_null() || invitenumber.is_null() || auth.is_null() {
|
0 as *mut libc::c_int,
|
||||||
if let Some(peerstate) = peerstate {
|
);
|
||||||
(*qr_parsed).state = 210i32;
|
device_msg = dc_mprintf(
|
||||||
let addr_ptr = if let Some(ref addr) = peerstate.addr {
|
b"%s verified.\x00" as *const u8 as *const libc::c_char,
|
||||||
to_cstring(addr)
|
peerstate.addr,
|
||||||
} else {
|
)
|
||||||
std::ptr::null()
|
|
||||||
};
|
|
||||||
(*qr_parsed).id = dc_add_or_lookup_contact(
|
|
||||||
context,
|
|
||||||
0 as *const libc::c_char,
|
|
||||||
addr_ptr,
|
|
||||||
0x80i32,
|
|
||||||
0 as *mut libc::c_int,
|
|
||||||
);
|
|
||||||
free(addr_ptr as *mut _);
|
|
||||||
dc_create_or_lookup_nchat_by_contact_id(
|
|
||||||
context,
|
|
||||||
(*qr_parsed).id,
|
|
||||||
2i32,
|
|
||||||
&mut chat_id,
|
|
||||||
0 as *mut libc::c_int,
|
|
||||||
);
|
|
||||||
device_msg = dc_mprintf(
|
|
||||||
b"%s verified.\x00" as *const u8 as *const libc::c_char,
|
|
||||||
peerstate.addr,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(*qr_parsed).text1 = dc_format_fingerprint_c(fingerprint);
|
|
||||||
(*qr_parsed).state = 230i32
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if !grpid.is_null() && !grpname.is_null() {
|
(*qr_parsed).text1 = dc_format_fingerprint_c(fingerprint);
|
||||||
(*qr_parsed).state = 202i32;
|
(*qr_parsed).state = 230i32
|
||||||
(*qr_parsed).text1 = dc_strdup(grpname);
|
|
||||||
(*qr_parsed).text2 = dc_strdup(grpid)
|
|
||||||
} else {
|
|
||||||
(*qr_parsed).state = 200i32
|
|
||||||
}
|
|
||||||
(*qr_parsed).id =
|
|
||||||
dc_add_or_lookup_contact(context, name, addr, 0x80i32, 0 as *mut libc::c_int);
|
|
||||||
(*qr_parsed).fingerprint = dc_strdup(fingerprint);
|
|
||||||
(*qr_parsed).invitenumber = dc_strdup(invitenumber);
|
|
||||||
(*qr_parsed).auth = dc_strdup(auth)
|
|
||||||
}
|
}
|
||||||
} else if !addr.is_null() {
|
|
||||||
(*qr_parsed).state = 320i32;
|
|
||||||
(*qr_parsed).id =
|
|
||||||
dc_add_or_lookup_contact(context, name, addr, 0x80i32, 0 as *mut libc::c_int)
|
|
||||||
} else if strstr(qr, b"http://\x00" as *const u8 as *const libc::c_char)
|
|
||||||
== qr as *mut libc::c_char
|
|
||||||
|| strstr(qr, b"https://\x00" as *const u8 as *const libc::c_char)
|
|
||||||
== qr as *mut libc::c_char
|
|
||||||
{
|
|
||||||
(*qr_parsed).state = 332i32;
|
|
||||||
(*qr_parsed).text1 = dc_strdup(qr)
|
|
||||||
} else {
|
} else {
|
||||||
(*qr_parsed).state = 330i32;
|
if !grpid.is_null() && !grpname.is_null() {
|
||||||
(*qr_parsed).text1 = dc_strdup(qr)
|
(*qr_parsed).state = 202i32;
|
||||||
}
|
(*qr_parsed).text1 = dc_strdup(grpname);
|
||||||
if !device_msg.is_null() {
|
(*qr_parsed).text2 = dc_strdup(grpid)
|
||||||
dc_add_device_msg(context, chat_id, device_msg);
|
} else {
|
||||||
|
(*qr_parsed).state = 200i32
|
||||||
|
}
|
||||||
|
(*qr_parsed).id =
|
||||||
|
dc_add_or_lookup_contact(context, name, addr, 0x80i32, 0 as *mut libc::c_int);
|
||||||
|
(*qr_parsed).fingerprint = dc_strdup(fingerprint);
|
||||||
|
(*qr_parsed).invitenumber = dc_strdup(invitenumber);
|
||||||
|
(*qr_parsed).auth = dc_strdup(auth)
|
||||||
}
|
}
|
||||||
|
} else if !addr.is_null() {
|
||||||
|
(*qr_parsed).state = 320i32;
|
||||||
|
(*qr_parsed).id =
|
||||||
|
dc_add_or_lookup_contact(context, name, addr, 0x80i32, 0 as *mut libc::c_int)
|
||||||
|
} else if strstr(qr, b"http://\x00" as *const u8 as *const libc::c_char)
|
||||||
|
== qr as *mut libc::c_char
|
||||||
|
|| strstr(qr, b"https://\x00" as *const u8 as *const libc::c_char)
|
||||||
|
== qr as *mut libc::c_char
|
||||||
|
{
|
||||||
|
(*qr_parsed).state = 332i32;
|
||||||
|
(*qr_parsed).text1 = dc_strdup(qr)
|
||||||
|
} else {
|
||||||
|
(*qr_parsed).state = 330i32;
|
||||||
|
(*qr_parsed).text1 = dc_strdup(qr)
|
||||||
|
}
|
||||||
|
if !device_msg.is_null() {
|
||||||
|
dc_add_device_msg(context, chat_id, device_msg);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup()
|
cleanup()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user