Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
2f5a2b24
Commit
2f5a2b24
authored
Mar 01, 2007
by
lars/lthalmann@mysql.com/dl145j.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.0
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge
parents
c0e985cd
87e7afe5
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
115 additions
and
33 deletions
+115
-33
client/mysql_upgrade.c
client/mysql_upgrade.c
+20
-9
client/mysqltest.c
client/mysqltest.c
+2
-2
cmd-line-utils/readline/xmalloc.c
cmd-line-utils/readline/xmalloc.c
+3
-4
include/my_dbug.h
include/my_dbug.h
+2
-0
sql/field.cc
sql/field.cc
+3
-3
sql/ha_archive.cc
sql/ha_archive.cc
+2
-0
sql/ha_berkeley.cc
sql/ha_berkeley.cc
+3
-3
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.cc
+22
-7
sql/log.cc
sql/log.cc
+2
-2
support-files/compiler_warnings.supp
support-files/compiler_warnings.supp
+56
-3
No files found.
client/mysql_upgrade.c
View file @
2f5a2b24
...
...
@@ -171,7 +171,7 @@ void set_extra_default(int id, const struct my_option *opt)
}
d
=
(
extra_default_t
*
)
my_malloc
(
sizeof
(
extra_default_t
),
MYF
(
MY_FAE
|
MY_ZEROFILL
));
MYF
(
MY_FAE
|
MY_ZEROFILL
));
d
->
id
=
id
;
d
->
name
=
opt
->
name
;
d
->
n_len
=
strlen
(
opt
->
name
);
...
...
@@ -345,15 +345,17 @@ static int create_defaults_file(const char *path, const char *forced_path)
}
dynstr_set
(
&
buf
,
NULL
);
}
if
(
dynstr_append_mem
(
&
buf
,
"
\n
"
,
1
)
||
dynstr_append_mem
(
&
buf
,
d
->
name
,
d
->
n_len
)
||
(
d
->
v_len
&&
(
dynstr_append_mem
(
&
buf
,
"="
,
1
)
||
dynstr_append_mem
(
&
buf
,
d
->
value
,
d
->
v_len
))))
if
(
dynstr_append_mem
(
&
buf
,
"
\n
"
,
1
)
||
dynstr_append_mem
(
&
buf
,
d
->
name
,
d
->
n_len
)
||
(
d
->
v_len
&&
(
dynstr_append_mem
(
&
buf
,
"="
,
1
)
||
dynstr_append_mem
(
&
buf
,
d
->
value
,
d
->
v_len
))))
{
ret
=
1
;
goto
error
;
}
my_delete
((
gptr
)
d
,
MYF
(
0
));
my_free
((
gptr
)
d
,
MYF
(
0
));
list_pop
(
extra_defaults
);
/* pop off the head */
}
if
(
my_write
(
defaults_file
,
buf
.
str
,
buf
.
length
,
MYF
(
MY_FNABP
|
MY_WME
)))
...
...
@@ -451,10 +453,10 @@ int main(int argc, char **argv)
char
*
forced_extra_defaults
;
char
*
local_defaults_group_suffix
;
const
char
*
script_line
;
char
*
upgrade_defaults_path
;
char
*
upgrade_defaults_path
=
NULL
;
char
*
defaults_to_use
=
NULL
;
int
upgrade_defaults_created
=
0
;
int
no_defaults
;
char
path
[
FN_REFLEN
];
DYNAMIC_STRING
cmdline
;
...
...
@@ -464,6 +466,10 @@ int main(int argc, char **argv)
#endif
/* Check if we are forced to use specific defaults */
no_defaults
=
0
;
if
(
argc
>=
2
&&
!
strcmp
(
argv
[
1
],
"--no-defaults"
))
no_defaults
=
1
;
get_defaults_options
(
argc
,
argv
,
&
forced_defaults_file
,
&
forced_extra_defaults
,
&
local_defaults_group_suffix
);
...
...
@@ -578,7 +584,9 @@ int main(int argc, char **argv)
if
(
defaults_to_use
)
{
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append_os_quoted
(
&
cmdline
,
"--defaults-extra-file="
,
dynstr_append_os_quoted
(
&
cmdline
,
(
no_defaults
?
"--defaults-file="
:
"--defaults-extra-file="
),
defaults_to_use
,
NullS
);
}
...
...
@@ -652,7 +660,9 @@ int main(int argc, char **argv)
if
(
defaults_to_use
)
{
dynstr_append
(
&
cmdline
,
" "
);
dynstr_append_os_quoted
(
&
cmdline
,
"--defaults-extra-file="
,
dynstr_append_os_quoted
(
&
cmdline
,
(
no_defaults
?
"--defaults-file="
:
"--defaults-extra-file="
),
defaults_to_use
,
NullS
);
}
dynstr_append
(
&
cmdline
,
" "
);
...
...
@@ -684,6 +694,7 @@ int main(int argc, char **argv)
if
(
upgrade_defaults_created
)
my_delete
(
upgrade_defaults_path
,
MYF
(
0
));
my_free
(
upgrade_defaults_path
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_end
(
info_flag
?
MY_CHECK_ERROR
|
MY_GIVE_INFO
:
0
);
return
ret
;
}
...
...
client/mysqltest.c
View file @
2f5a2b24
...
...
@@ -6726,11 +6726,11 @@ int reg_replace(char** buf_p, int* buf_len_p, char *pattern,
if
(
back_ref_num
>=
0
&&
back_ref_num
<=
(
int
)
r
.
re_nsub
)
{
int
start_off
,
end_off
;
regoff_t
start_off
,
end_off
;
if
((
start_off
=
subs
[
back_ref_num
].
rm_so
)
>
-
1
&&
(
end_off
=
subs
[
back_ref_num
].
rm_eo
)
>
-
1
)
{
int
block_len
=
end_off
-
start_off
;
int
block_len
=
(
int
)
(
end_off
-
start_off
)
;
memcpy
(
res_p
,
str_p
+
start_off
,
block_len
);
res_p
+=
block_len
;
}
...
...
cmd-line-utils/readline/xmalloc.c
View file @
2f5a2b24
...
...
@@ -39,8 +39,7 @@
/* **************************************************************** */
static
void
memory_error_and_abort
(
fname
)
char
*
fname
;
memory_error_and_abort
(
const
char
*
fname
)
{
fprintf
(
stderr
,
"%s: out of virtual memory
\n
"
,
fname
);
exit
(
2
);
...
...
@@ -57,7 +56,7 @@ xmalloc (bytes)
temp
=
malloc
(
bytes
);
if
(
temp
==
0
)
memory_error_and_abort
((
char
*
)
"xmalloc"
);
memory_error_and_abort
(
"xmalloc"
);
return
(
temp
);
}
...
...
@@ -71,7 +70,7 @@ xrealloc (pointer, bytes)
temp
=
pointer
?
realloc
(
pointer
,
bytes
)
:
malloc
(
bytes
);
if
(
temp
==
0
)
memory_error_and_abort
((
char
*
)
"xrealloc"
);
memory_error_and_abort
(
"xrealloc"
);
return
(
temp
);
}
...
...
include/my_dbug.h
View file @
2f5a2b24
...
...
@@ -74,6 +74,7 @@ extern void _db_unlock_file(void);
#define DBUG_ASSERT(A) assert(A)
#define DBUG_EXECUTE_IF(keyword,a1) \
{if (_db_on_) {if (_db_strict_keyword_ (keyword)) { a1 }}}
#define IF_DBUG(A) A
#else
/* No debugger */
#define DBUG_ENTER(a1)
...
...
@@ -98,6 +99,7 @@ extern void _db_unlock_file(void);
#define DBUG_OUTPUT(A)
#define DBUG_ASSERT(A) {}
#define DBUG_LEAVE
#define IF_DBUG(A)
#endif
#ifdef __cplusplus
}
...
...
sql/field.cc
View file @
2f5a2b24
...
...
@@ -6144,7 +6144,7 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr)
void
Field_string
::
sort_string
(
char
*
to
,
uint
length
)
{
uint
tmp
=
my_strnxfrm
(
field_charset
,
IF_DBUG
(
uint
tmp
=
)
my_strnxfrm
(
field_charset
,
(
unsigned
char
*
)
to
,
length
,
(
unsigned
char
*
)
ptr
,
field_length
);
DBUG_ASSERT
(
tmp
==
length
);
...
...
sql/ha_archive.cc
View file @
2f5a2b24
...
...
@@ -749,10 +749,12 @@ int ha_archive::write_row(byte *buf)
DBUG_PRINT
(
"archive"
,(
"MyPack is %d
\n
"
,
(
*
field
)
->
data_length
((
char
*
)
buf
+
(
*
field
)
->
offset
())));
if
((
*
field
)
->
real_type
()
==
MYSQL_TYPE_VARCHAR
)
{
#ifndef DBUG_OFF
uint
actual_length
=
(
*
field
)
->
data_length
((
char
*
)
buf
+
(
*
field
)
->
offset
());
uint
offset
=
(
*
field
)
->
offset
()
+
actual_length
+
(
actual_length
>
255
?
2
:
1
);
DBUG_PRINT
(
"archive"
,(
"Offset is %d -> %d
\n
"
,
actual_length
,
offset
));
#endif
/*
if ((*field)->pack_length() + (*field)->offset() != offset)
bzero(buf + offset, (size_t)((*field)->pack_length() + (actual_length > 255 ? 2 : 1) - (*field)->data_length));
...
...
sql/ha_berkeley.cc
View file @
2f5a2b24
...
...
@@ -807,7 +807,7 @@ int ha_berkeley::pack_row(DBT *row, const byte *record, bool new_row)
ptr
+=
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
}
row
->
data
=
rec_buff
;
row
->
size
=
(
size
_t
)
(
ptr
-
rec_buff
);
row
->
size
=
(
u_int32
_t
)
(
ptr
-
rec_buff
);
return
0
;
}
...
...
@@ -902,7 +902,7 @@ DBT *ha_berkeley::create_key(DBT *key, uint keynr, char *buff,
key_part
->
length
);
key_length
-=
key_part
->
length
;
}
key
->
size
=
(
buff
-
(
char
*
)
key
->
data
);
key
->
size
=
(
u_int32_t
)
(
buff
-
(
char
*
)
key
->
data
);
DBUG_DUMP
(
"key"
,(
char
*
)
key
->
data
,
key
->
size
);
DBUG_RETURN
(
key
);
}
...
...
@@ -946,7 +946,7 @@ DBT *ha_berkeley::pack_key(DBT *key, uint keynr, char *buff,
key_ptr
+=
key_part
->
store_length
;
key_length
-=
key_part
->
store_length
;
}
key
->
size
=
(
buff
-
(
char
*
)
key
->
data
);
key
->
size
=
(
u_int32_t
)
(
buff
-
(
char
*
)
key
->
data
);
DBUG_DUMP
(
"key"
,(
char
*
)
key
->
data
,
key
->
size
);
DBUG_RETURN
(
key
);
}
...
...
sql/ha_ndbcluster.cc
View file @
2f5a2b24
...
...
@@ -2331,10 +2331,12 @@ int ha_ndbcluster::write_row(byte *record)
{
Ndb
*
ndb
=
get_ndb
();
Uint64
next_val
=
(
Uint64
)
table
->
next_number_field
->
val_int
()
+
1
;
#ifndef DBUG_OFF
char
buff
[
22
];
DBUG_PRINT
(
"info"
,
(
"Trying to set next auto increment value to %s"
,
llstr
(
next_val
,
buff
)));
#endif
if
(
ndb
->
setAutoIncrementValue
((
const
NDBTAB
*
)
m_table
,
next_val
,
TRUE
)
==
-
1
)
ERR_RETURN
(
ndb
->
getNdbError
());
...
...
@@ -3490,7 +3492,7 @@ int ha_ndbcluster::end_bulk_insert()
}
else
{
int
res
=
trans
->
restart
();
IF_DBUG
(
int
res
=
)
trans
->
restart
();
DBUG_ASSERT
(
res
==
0
);
}
}
...
...
@@ -4257,7 +4259,9 @@ static int create_ndb_column(NDBCOL &col,
// Set autoincrement
if
(
field
->
flags
&
AUTO_INCREMENT_FLAG
)
{
#ifndef DBUG_OFF
char
buff
[
22
];
#endif
col
.
setAutoIncrement
(
TRUE
);
ulonglong
value
=
info
->
auto_increment_value
?
info
->
auto_increment_value
:
(
ulonglong
)
1
;
...
...
@@ -5680,7 +5684,9 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
if
(
share
->
commit_count
!=
0
)
{
*
commit_count
=
share
->
commit_count
;
#ifndef DBUG_OFF
char
buff
[
22
];
#endif
DBUG_PRINT
(
"info"
,
(
"Getting commit_count: %s from share"
,
llstr
(
share
->
commit_count
,
buff
)));
pthread_mutex_unlock
(
&
share
->
mutex
);
...
...
@@ -5706,7 +5712,9 @@ uint ndb_get_commitcount(THD *thd, char *dbname, char *tabname,
pthread_mutex_lock
(
&
share
->
mutex
);
if
(
share
->
commit_count_lock
==
lock
)
{
#ifndef DBUG_OFF
char
buff
[
22
];
#endif
DBUG_PRINT
(
"info"
,
(
"Setting commit_count to %s"
,
llstr
(
stat
.
commit_count
,
buff
)));
share
->
commit_count
=
stat
.
commit_count
;
...
...
@@ -5762,7 +5770,9 @@ ndbcluster_cache_retrieval_allowed(THD *thd,
bool
is_autocommit
=
!
(
thd
->
options
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
));
char
*
dbname
=
full_name
;
char
*
tabname
=
dbname
+
strlen
(
dbname
)
+
1
;
#ifndef DBUG_OFF
char
buff
[
22
],
buff2
[
22
];
#endif
DBUG_ENTER
(
"ndbcluster_cache_retrieval_allowed"
);
DBUG_PRINT
(
"enter"
,
(
"dbname: %s, tabname: %s, is_autocommit: %d"
,
dbname
,
tabname
,
is_autocommit
));
...
...
@@ -5829,7 +5839,9 @@ ha_ndbcluster::register_query_cache_table(THD *thd,
ulonglong
*
engine_data
)
{
Uint64
commit_count
;
#ifndef DBUG_OFF
char
buff
[
22
];
#endif
bool
is_autocommit
=
!
(
thd
->
options
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
));
DBUG_ENTER
(
"ha_ndbcluster::register_query_cache_table"
);
DBUG_PRINT
(
"enter"
,(
"dbname: %s, tabname: %s, is_autocommit: %d"
,
...
...
@@ -6036,7 +6048,9 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb,
int
retries
=
10
;
int
reterr
=
0
;
int
retry_sleep
=
30
*
1000
;
/* 30 milliseconds */
#ifndef DBUG_OFF
char
buff
[
22
],
buff2
[
22
],
buff3
[
22
],
buff4
[
22
];
#endif
DBUG_ENTER
(
"ndb_get_table_statistics"
);
DBUG_PRINT
(
"enter"
,
(
"table: %s"
,
table
));
...
...
@@ -6725,7 +6739,9 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
if
(
ndb_get_table_statistics
(
NULL
,
false
,
ndb
,
tabname
,
&
stat
)
==
0
)
{
#ifndef DBUG_OFF
char
buff
[
22
],
buff2
[
22
];
#endif
DBUG_PRINT
(
"ndb_util_thread"
,
(
"Table: %s commit_count: %s rows: %s"
,
share
->
table_name
,
...
...
@@ -7565,8 +7581,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
DBUG_PRINT
(
"info"
,
(
"INT_ITEM"
));
if
(
context
->
expecting
(
Item
::
INT_ITEM
))
{
Item_int
*
int_item
=
(
Item_int
*
)
item
;
DBUG_PRINT
(
"info"
,
(
"value %ld"
,
(
long
)
int_item
->
value
));
DBUG_PRINT
(
"info"
,
(
"value %ld"
,
(
long
)
((
Item_int
*
)
item
)
->
value
));
NDB_ITEM_QUALIFICATION
q
;
q
.
value_type
=
Item
::
INT_ITEM
;
curr_cond
->
ndb_item
=
new
Ndb_item
(
NDB_VALUE
,
q
,
item
);
...
...
@@ -7592,8 +7608,7 @@ void ndb_serialize_cond(const Item *item, void *arg)
DBUG_PRINT
(
"info"
,
(
"REAL_ITEM"
));
if
(
context
->
expecting
(
Item
::
REAL_ITEM
))
{
Item_float
*
float_item
=
(
Item_float
*
)
item
;
DBUG_PRINT
(
"info"
,
(
"value %f"
,
float_item
->
value
));
DBUG_PRINT
(
"info"
,
(
"value %f"
,
((
Item_float
*
)
item
)
->
value
));
NDB_ITEM_QUALIFICATION
q
;
q
.
value_type
=
Item
::
REAL_ITEM
;
curr_cond
->
ndb_item
=
new
Ndb_item
(
NDB_VALUE
,
q
,
item
);
...
...
@@ -7640,8 +7655,8 @@ void ndb_serialize_cond(const Item *item, void *arg)
DBUG_PRINT
(
"info"
,
(
"DECIMAL_ITEM"
));
if
(
context
->
expecting
(
Item
::
DECIMAL_ITEM
))
{
Item_decimal
*
decimal_item
=
(
Item_decimal
*
)
item
;
DBUG_PRINT
(
"info"
,
(
"value %f"
,
decimal_item
->
val_real
()));
DBUG_PRINT
(
"info"
,
(
"value %f"
,
((
Item_decimal
*
)
item
)
->
val_real
()));
NDB_ITEM_QUALIFICATION
q
;
q
.
value_type
=
Item
::
DECIMAL_ITEM
;
curr_cond
->
ndb_item
=
new
Ndb_item
(
NDB_VALUE
,
q
,
item
);
...
...
sql/log.cc
View file @
2f5a2b24
...
...
@@ -304,7 +304,7 @@ void setup_windows_event_source()
/* Register EventMessageFile */
dwError
=
RegSetValueEx
(
hRegKey
,
"EventMessageFile"
,
0
,
REG_EXPAND_SZ
,
(
PBYTE
)
szPath
,
strlen
(
szPath
)
+
1
);
(
PBYTE
)
szPath
,
(
DWORD
)
(
strlen
(
szPath
)
+
1
)
);
/* Register supported event types */
dwTypes
=
(
EVENTLOG_ERROR_TYPE
|
EVENTLOG_WARNING_TYPE
|
...
...
@@ -1784,7 +1784,7 @@ void MYSQL_LOG::rotate_and_purge(uint flags)
#ifdef HAVE_REPLICATION
if
(
expire_logs_days
)
{
long
purge_time
=
time
(
0
)
-
expire_logs_days
*
24
*
60
*
60
;
long
purge_time
=
(
long
)
(
time
(
0
)
-
expire_logs_days
*
24
*
60
*
60
)
;
if
(
purge_time
>=
0
)
purge_logs_before_date
(
purge_time
);
}
...
...
support-files/compiler_warnings.supp
View file @
2f5a2b24
integer.cpp: .*control reaches end of non-void function.*: 1288-1427
DictTabInfo.cpp : .*invalid access to non-static.*
DictTabInfo.cpp : .*macro was used incorrectly.*
DbdihMain.cpp : .*unused variable.* : 6666-
6705
DbdihMain.cpp : .*unused variable.* : 6666-
7013
DbtupExecQuery.cpp : .*unused variable.* : 1448-1449
kernel_types.h : .*only defines private constructors and has no friends.* : 51
Dbtup.hpp: .*only defines private constructors and has no friends.*
diskpage.hpp: .*only defines private constructors and has no friends.*
tuppage.hpp: .*only defines private constructors and has no friends.*
NdbScanOperation.cpp: .*unused variable '__align'.* : 1190-1200
sql_yacc.cc : .*label 'yyerrlab1' defined but not used.*
kernel_types.h : .*'struct Local_key' only defines private constructors and has no friends.*
lgman.hpp : .*'struct Lgman::Buffer_idx' only defines private constructors and has no friends.*
SchemaFile.hpp : .*'struct SchemaFile::TableEntry' only defines private constructors and has no friends.*
sql_yacc.cc : .*switch statement contains 'default' but no 'case' labels.*
#
# Things that can be ignored in InnoDB
#
pars0grm.tab.c: .*'yyerrorlab' : unreferenced label.*
_flex_tmp.c: .*not enough actual parameters for macro 'yywrap'.*
pars0lex.l: .*conversion from 'ulint' to 'int', possible loss of data.*
#
# bdb is not critical to keep up to date
#
...
...
@@ -11,16 +28,52 @@ sql_yacc.cc : .*switch statement contains 'default' but no 'case' labels.*
.*/bdb/.* : .*unused parameter.*
.*/bdb/.* : .*may be used uninitialized.*
.*/bdb/.* : .*empty body in an if-statement.*
.*/bdb/.* : .*conversion from 'u?lint' to 'int', possible loss of data.*
db_vrfy.c : .*comparison is always false due to limited range of data type.*
dbm.c : .*'item.dsize' is used uninitialized in this function.*
#
# Ignore all conversion warnings on windows 64
# (Is safe as we are not yet supporting strings >= 2G)
#
.* : conversion from 'size_t' to .*int'.*
.* : conversion from '__int64' to .*int'.*
.* : conversion from '__int64' to 'uint8'.*
.* : conversion from '__int64' to 'uint32'.*
.* : conversion from '__int64' to 'u.*long'.*
.* : conversion from '__int64' to 'long'.*
.* : conversion from '__int64' to 'off_t'.*
.* : conversion from '.*size_t' to .*int'.*
.* : conversion from '.*size_t' to 'TaoCrypt::word32'.*
.* : conversion from '.*size_t' to 'u.*long'.*
.* : conversion from '.*size_t' to 'uint32'.*
.* : conversion from '.*size_t' to 'off_t'.*
.* : conversion from '.*size_t' to 'size_s'.*
.* : conversion from 'u?lint' to 'int'.*
ha_berkeley.cc : .*conversion from 'ulonglong' to 'char'.*
#
# The following should be fixed by the ndb team
#
.*/ndb/.* : .*used uninitialized in this function.*
.*/ndb/.* : .*unused variable.*
.*/ndb/.* : .*defined but not used.*
#
# Unexplanable (?) stuff
#
listener.cc : .*conversion from 'SOCKET' to 'int'.*
net_serv.cc : .*conversion from 'SOCKET' to 'int'.*
mi_packrec.c : .*result of 32-bit shift implicitly converted to 64 bits.* : 567
#
# Wrong compiler warnings
#
.* : .*no matching operator delete found; memory will not be freed if initialization throws an exception.*
#
# Viossl warnings - fixed in 5.1, disabled in 5.0. Too large to be changed
# in 5.0. Please do not merge upwards.
#
socket_wrapper.cpp : .*truncation of constant value.*
socket_wrapper.hpp : .*truncation of constant value.*
viossl.c : .*conversion from 'SOCKET' to 'socket_t'.*
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment