Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ITS - Intelligent Transport Systems
ITS
Commits
1f88debd
Commit
1f88debd
authored
Mar 21, 2016
by
filatov
Browse files
Certificate generator updates
parent
8a3e80ed
Changes
10
Hide whitespace changes
Inline
Side-by-side
tools/itscertgen/checker/certinfo.c
View file @
1f88debd
...
...
@@ -49,7 +49,8 @@ typedef enum {
si_digest
,
si_certificate
,
si_certificate_chain
,
si_digest_with_other_algorithm
si_digest_with_other_algorithm
,
si_other
}
SignerInfoType
;
typedef
enum
{
...
...
@@ -117,7 +118,8 @@ static const char * _signer_types[] = {
"self"
,
"digest"
,
"certificate"
,
"chain"
,
"certificate_chain"
,
"other_digest"
,
"other"
,
};
...
...
@@ -252,19 +254,34 @@ int main(int argc, char ** argv)
cxml_handler_add_default_entities
(
NULL
);
if
(
*
p
>
1
){
fprintf
(
stderr
,
"Unsupported signer type: %s
\n
"
,
ENUMSTRING
(
*
p
,
_signer_types
));
return
-
1
;
}
fprintf
(
stdout
,
"
\t
<signer type =
\"
%s
\"
"
,
ENUMSTRING
(
*
p
,
_signer_types
));
if
(
*
p
==
1
){
if
(
*
p
==
si_digest
||
*
p
==
si_digest_with_other_algorithm
){
if
(
*
p
==
si_digest_with_other_algorithm
){
p
++
;
fprintf
(
stdout
,
" algorithm =
\"
%s
\"
"
,
ENUMSTRING
(
*
p
,
_pk_algorithms
));
}
p
++
;
fprintf
(
stdout
,
" digest=
\"
"
);
print_x
(
stdout
,
p
+
1
,
8
);
print_x
(
stdout
,
p
,
8
);
fprintf
(
stdout
,
"
\"
"
);
p
+=
8
;
fprintf
(
stdout
,
"/>
\n
"
);
}
else
{
fprintf
(
stdout
,
">
\n
"
);
if
(
*
p
==
si_certificate_chain
||
*
p
>=
si_other
){
const
char
*
b
=
++
p
;
length
=
(
uint32_t
)
cintx_read
(
&
p
,
e
,
NULL
);
print_x
(
stdout
,
b
,
length
);
p
+=
length
;
}
else
{
fprintf
(
stderr
,
"Unsupported signer type: %d
\n
"
,
ENUMSTRING
(
*
p
,
_signer_types
));
return
-
1
;
}
fprintf
(
stdout
,
"
\t
</signer>
\n
"
);
}
fprintf
(
stdout
,
"/>
\n
"
);
p
++
;
const
SubjectInfo
*
si
=
(
const
SubjectInfo
*
)
p
;
if
(
si
->
subject_type
>
crl_signer
){
fprintf
(
stderr
,
"Unsupported subject type: %d
\n
"
,
si
->
subject_type
);
...
...
@@ -736,6 +753,15 @@ static int print_validity(const char ** pp, const char * e)
}
}
break
;
default:
{
fprintf
(
stdout
,
"
\t\t\t
<region type=
\"
%d
\"
>
\n
"
,
rtype
);
int
size
=
(
int
)
cintx_read
(
&
p
,
e
,
&
rc
);
print_x
(
stdout
,
p
,
size
);
p
+=
size
;
fprintf
(
stdout
,
"
\n\t\t\t
</region>
\n
"
);
}
break
;
}
}
fprintf
(
stdout
,
"
\t\t
</restriction>
\n
"
);
...
...
tools/itscertgen/checker/itscertverify.vcxproj
View file @
1f88debd
...
...
@@ -36,14 +36,14 @@
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
true
</UseDebugLibraries>
<PlatformToolset>
v120
</PlatformToolset>
<CharacterSet>
Unicod
e
</CharacterSet>
<CharacterSet>
MultiByt
e
</CharacterSet>
</PropertyGroup>
<PropertyGroup
Condition=
"'$(Configuration)|$(Platform)'=='Release|Win32'"
Label=
"Configuration"
>
<ConfigurationType>
Application
</ConfigurationType>
<UseDebugLibraries>
false
</UseDebugLibraries>
<PlatformToolset>
v120
</PlatformToolset>
<WholeProgramOptimization>
true
</WholeProgramOptimization>
<CharacterSet>
Unicod
e
</CharacterSet>
<CharacterSet>
MultiByt
e
</CharacterSet>
</PropertyGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.props"
/>
<ImportGroup
Label=
"ExtensionSettings"
>
...
...
@@ -72,12 +72,12 @@
<WarningLevel>
Level3
</WarningLevel>
<Optimization>
Disabled
</Optimization>
<PreprocessorDefinitions>
WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
C:\OpenSSL
-
Win32\include;..
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>
C:\OpenSSL
\
Win32\include;..
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
Console
</SubSystem>
<GenerateDebugInformation>
true
</GenerateDebugInformation>
<AdditionalLibraryDirectories>
C:\OpenSSL
-
Win32\lib\VC\static
</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>
C:\OpenSSL
\
Win32\lib\VC\static
</AdditionalLibraryDirectories>
<AdditionalDependencies>
libeay32MDd.lib;ssleay32MDd.lib;%(AdditionalDependencies)
</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
...
...
@@ -90,14 +90,14 @@
<FunctionLevelLinking>
true
</FunctionLevelLinking>
<IntrinsicFunctions>
true
</IntrinsicFunctions>
<PreprocessorDefinitions>
WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)
</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
C:\OpenSSL
-
Win32\include;..
</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>
C:\OpenSSL
\
Win32\include;..
</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>
Console
</SubSystem>
<GenerateDebugInformation>
true
</GenerateDebugInformation>
<EnableCOMDATFolding>
true
</EnableCOMDATFolding>
<OptimizeReferences>
true
</OptimizeReferences>
<AdditionalLibraryDirectories>
C:\OpenSSL
-
Win32\lib\VC\static
</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>
C:\OpenSSL
\
Win32\lib\VC\static
</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import
Project=
"$(VCTargetsPath)\Microsoft.Cpp.targets"
/>
...
...
tools/itscertgen/checker/mkgmtime.c
0 → 100644
View file @
1f88debd
// Found in DeSmuME
// Alexis modified it a tad bit so it would compile as C (opposed to C++)
/* lib/mkgmtime.c
Copyright (C) 2010 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
//Taken from newlib 1.18.0 which is licensed under GPL 2 and modified for desmume
/*
* mktime.c
* Original Author: G. Haley
*
* Converts the broken-down time, expressed as local time, in the structure
* pointed to by tim_p into a calendar time value. The original values of the
* tm_wday and tm_yday fields of the structure are ignored, and the original
* values of the other fields have no restrictions. On successful completion
* the fields of the structure are set to represent the specified calendar
* time. Returns the specified calendar time. If the calendar time can not be
* represented, returns the value (time_t) -1.
*
* Modifications: Fixed tm_isdst usage - 27 August 2008 Craig Howland.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include
<stdlib.h>
#include
<time.h>
#include
<stdio.h>
#include
"mkgmtime.h"
#define _SEC_IN_MINUTE 60L
#define _SEC_IN_HOUR 3600L
#define _SEC_IN_DAY 86400L
static
const
int
DAYS_IN_MONTH
[
12
]
=
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
};
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
static
const
int
_DAYS_BEFORE_MONTH
[
12
]
=
{
0
,
31
,
59
,
90
,
120
,
151
,
181
,
212
,
243
,
273
,
304
,
334
};
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
static
void
validate_structure
(
struct
tm
*
tim_p
)
{
div_t
res
;
int
days_in_feb
=
28
;
/* calculate time & date to account for out of range values */
if
(
tim_p
->
tm_sec
<
0
||
tim_p
->
tm_sec
>
59
)
{
res
=
div
(
tim_p
->
tm_sec
,
60
);
tim_p
->
tm_min
+=
res
.
quot
;
if
((
tim_p
->
tm_sec
=
res
.
rem
)
<
0
)
{
tim_p
->
tm_sec
+=
60
;
--
tim_p
->
tm_min
;
}
}
if
(
tim_p
->
tm_min
<
0
||
tim_p
->
tm_min
>
59
)
{
res
=
div
(
tim_p
->
tm_min
,
60
);
tim_p
->
tm_hour
+=
res
.
quot
;
if
((
tim_p
->
tm_min
=
res
.
rem
)
<
0
)
{
tim_p
->
tm_min
+=
60
;
--
tim_p
->
tm_hour
;
}
}
if
(
tim_p
->
tm_hour
<
0
||
tim_p
->
tm_hour
>
23
)
{
res
=
div
(
tim_p
->
tm_hour
,
24
);
tim_p
->
tm_mday
+=
res
.
quot
;
if
((
tim_p
->
tm_hour
=
res
.
rem
)
<
0
)
{
tim_p
->
tm_hour
+=
24
;
--
tim_p
->
tm_mday
;
}
}
if
(
tim_p
->
tm_mon
>
11
)
{
res
=
div
(
tim_p
->
tm_mon
,
12
);
tim_p
->
tm_year
+=
res
.
quot
;
if
((
tim_p
->
tm_mon
=
res
.
rem
)
<
0
)
{
tim_p
->
tm_mon
+=
12
;
--
tim_p
->
tm_year
;
}
}
if
(
_DAYS_IN_YEAR
(
tim_p
->
tm_year
)
==
366
)
days_in_feb
=
29
;
if
(
tim_p
->
tm_mday
<=
0
)
{
while
(
tim_p
->
tm_mday
<=
0
)
{
if
(
--
tim_p
->
tm_mon
==
-
1
)
{
tim_p
->
tm_year
--
;
tim_p
->
tm_mon
=
11
;
days_in_feb
=
((
_DAYS_IN_YEAR
(
tim_p
->
tm_year
)
==
366
)
?
29
:
28
);
}
tim_p
->
tm_mday
+=
_DAYS_IN_MONTH
(
tim_p
->
tm_mon
);
}
}
else
{
while
(
tim_p
->
tm_mday
>
_DAYS_IN_MONTH
(
tim_p
->
tm_mon
))
{
tim_p
->
tm_mday
-=
_DAYS_IN_MONTH
(
tim_p
->
tm_mon
);
if
(
++
tim_p
->
tm_mon
==
12
)
{
tim_p
->
tm_year
++
;
tim_p
->
tm_mon
=
0
;
days_in_feb
=
((
_DAYS_IN_YEAR
(
tim_p
->
tm_year
)
==
366
)
?
29
:
28
);
}
}
}
}
static
const
unsigned
long
_leap_moments
[]
=
{
1136073600
,
1230768000
,
1341100800
,
1435708800
,
};
time_t
addleapseconds
(
time_t
t
)
{
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
_leap_moments
)
/
sizeof
(
_leap_moments
[
0
]);
i
++
){
if
(
t
<
_leap_moments
[
i
])
break
;
}
return
t
+
i
;
}
time_t
removeleapseconds
(
time_t
t
)
{
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
_leap_moments
)
/
sizeof
(
_leap_moments
[
0
]);
i
++
){
if
(
t
<
_leap_moments
[
i
])
break
;
t
--
;
}
return
t
;
}
#define ITS_UTC_EPOCH 1072915200
unsigned
long
mkitstime32
(
struct
tm
*
tim_p
)
{
time_t
ret
=
mktaitime
(
tim_p
);
if
(
ret
>
0
){
ret
-=
ITS_UTC_EPOCH
;
}
return
(
unsigned
long
)
ret
;
}
unsigned
long
long
mkitstime64
(
struct
tm
*
tim_p
)
{
unsigned
long
long
ret
=
mktaitime64
(
tim_p
);
if
(
ret
>
0
){
ret
-=
((
unsigned
long
long
)
ITS_UTC_EPOCH
)
*
1000
;
}
return
ret
;
}
time_t
mktaitime
(
struct
tm
*
tim_p
)
{
time_t
t
=
mkgmtime
(
tim_p
);
if
(
t
>=
0
){
t
=
addleapseconds
(
t
);
}
return
t
;
}
unsigned
long
long
mktaitime64
(
struct
tm
*
tim_p
)
{
time_t
t
=
mkgmtime
(
tim_p
);
if
(
t
>=
0
){
t
=
addleapseconds
(
t
);
}
return
((
unsigned
long
long
)
t
)
*
1000
;
}
unsigned
long
unix2itstime32
(
time_t
t
)
{
return
((
unsigned
long
)
addleapseconds
(
t
))
-
ITS_UTC_EPOCH
;
}
unsigned
long
long
unix2itstime64
(
time_t
t
)
{
return
(((
unsigned
long
long
)
addleapseconds
(
t
))
-
ITS_UTC_EPOCH
)
*
1000
;
}
static
char
_datebuf
[
8
][
16
];
static
int
_datebufidx
=
0
;
const
char
*
strgmtdate
(
time_t
t
)
{
struct
tm
*
tm
;
char
*
b
=
_datebuf
[
_datebufidx
];
_datebufidx
=
(
_datebufidx
+
1
)
&
7
;
tm
=
gmtime
(
&
t
);
sprintf
(
b
,
"%u-%02u-%02u"
,
1900
+
tm
->
tm_year
,
tm
->
tm_mon
+
1
,
tm
->
tm_mday
);
return
b
;
}
const
char
*
strtaidate
(
time_t
t
)
{
return
strgmtdate
(
removeleapseconds
(
t
));
}
const
char
*
stritsdate32
(
time_t
t
)
{
return
strtaidate
(
t
+
ITS_UTC_EPOCH
);
}
time_t
mkgmtime
(
struct
tm
*
tim_p
)
{
time_t
tim
=
0
;
long
days
=
0
;
int
year
,
isdst
,
tm_isdst
;
/* validate structure */
validate_structure
(
tim_p
);
/* compute hours, minutes, seconds */
tim
+=
tim_p
->
tm_sec
+
(
tim_p
->
tm_min
*
_SEC_IN_MINUTE
)
+
(
tim_p
->
tm_hour
*
_SEC_IN_HOUR
);
/* compute days in year */
days
+=
tim_p
->
tm_mday
-
1
;
days
+=
_DAYS_BEFORE_MONTH
[
tim_p
->
tm_mon
];
if
(
tim_p
->
tm_mon
>
1
&&
_DAYS_IN_YEAR
(
tim_p
->
tm_year
)
==
366
)
days
++
;
/* compute day of the year */
tim_p
->
tm_yday
=
days
;
if
(
tim_p
->
tm_year
>
10000
||
tim_p
->
tm_year
<
-
10000
)
{
return
(
time_t
)
-
1
;
}
/* compute days in other years */
if
(
tim_p
->
tm_year
>
70
)
{
for
(
year
=
70
;
year
<
tim_p
->
tm_year
;
year
++
)
days
+=
_DAYS_IN_YEAR
(
year
);
}
else
if
(
tim_p
->
tm_year
<
70
)
{
for
(
year
=
69
;
year
>
tim_p
->
tm_year
;
year
--
)
days
-=
_DAYS_IN_YEAR
(
year
);
days
-=
_DAYS_IN_YEAR
(
year
);
}
/* compute day of the week */
if
((
tim_p
->
tm_wday
=
(
days
+
4
)
%
7
)
<
0
)
tim_p
->
tm_wday
+=
7
;
/* compute total seconds */
tim
+=
(
days
*
_SEC_IN_DAY
);
/* Convert user positive into 1 */
tm_isdst
=
tim_p
->
tm_isdst
>
0
?
1
:
tim_p
->
tm_isdst
;
isdst
=
tm_isdst
;
//screw this!
// if (_daylight)
// {
// int y = tim_p->tm_year + YEAR_BASE;
// if (y == tz->__tzyear || __tzcalc_limits (y))
//{
// /* calculate start of dst in dst local time and
// start of std in both std local time and dst local time */
// time_t startdst_dst = tz->__tzrule[0].change
// - (time_t) tz->__tzrule[1].offset;
// time_t startstd_dst = tz->__tzrule[1].change
// - (time_t) tz->__tzrule[1].offset;
// time_t startstd_std = tz->__tzrule[1].change
// - (time_t) tz->__tzrule[0].offset;
// /* if the time is in the overlap between dst and std local times */
// if (tim >= startstd_std && tim < startstd_dst)
// ; /* we let user decide or leave as -1 */
// else
// {
// isdst = (tz->__tznorth
// ? (tim >= startdst_dst && tim < startstd_std)
// : (tim >= startdst_dst || tim < startstd_std));
// /* if user committed and was wrong, perform correction, but not
// * if the user has given a negative value (which
// * asks mktime() to determine if DST is in effect or not) */
// if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1)
// {
// /* we either subtract or add the difference between
// time zone offsets, depending on which way the user got it
// wrong. The diff is typically one hour, or 3600 seconds,
// and should fit in a 16-bit int, even though offset
// is a long to accomodate 12 hours. */
// int diff = (int) (tz->__tzrule[0].offset
// - tz->__tzrule[1].offset);
// if (!isdst)
// diff = -diff;
// tim_p->tm_sec += diff;
// validate_structure (tim_p);
// tim += diff; /* we also need to correct our current time calculation */
// }
// }
//}
// }
//screw this also
/* add appropriate offset to put time in gmt format */
//if (isdst == 1)
// tim += (time_t) tz->__tzrule[1].offset;
//else /* otherwise assume std time */
// tim += (time_t) tz->__tzrule[0].offset;
//and screw this too
/* reset isdst flag to what we have calculated */
tim_p
->
tm_isdst
=
isdst
;
return
tim
;
}
// vim: ts=2 sw=2 et
tools/itscertgen/checker/mkgmtime.h
0 → 100644
View file @
1f88debd
/* lib/mkgmtime.h
Copyright (C) 2010 DeSmuME team
This file is part of DeSmuME
DeSmuME is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
DeSmuME is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _MKGMTIME_H_
#define _MKGMTIME_H_
#include
<time.h>
#ifdef __cplusplus
extern
"C"
{
#endif
extern
time_t
mkgmtime
(
struct
tm
*
tim_p
);
extern
time_t
mktaitime
(
struct
tm
*
tim_p
);
extern
time_t
addleapseconds
(
time_t
t
);
#define mktaitime32(X) ((unsigned long)mktaitime(X))
extern
unsigned
long
mkitstime32
(
struct
tm
*
tim_p
);
extern
unsigned
long
unix2itstime32
(
time_t
t
);
extern
unsigned
long
long
mktaitime64
(
struct
tm
*
tim_p
);
extern
unsigned
long
long
mkitstime64
(
struct
tm
*
tim_p
);
extern
unsigned
long
long
unix2itstime64
(
time_t
t
);
extern
const
char
*
stritsdate32
(
time_t
t
);
extern
const
char
*
strtaidate
(
time_t
t
);
extern
const
char
*
strgmtdate
(
time_t
t
);
#ifdef __cplusplus
}
#endif
#endif
//_MKGMTIME_H_
tools/itscertgen/cshared/cstr.c
View file @
1f88debd
...
...
@@ -35,6 +35,22 @@ int cstrequal(const char * s1, const char * s2)
return
(
s1
==
s2
)
||
(
s1
&&
s2
&&
0
==
strcmp
(
s1
,
s2
));
}
char
*
cstrisprefix
(
const
char
*
str
,
const
char
*
prefix
)
{
int
len
;
if
(
str
==
prefix
){
return
(
char
*
)(
str
?
str
+
strlen
(
str
)
:
NULL
);
}
if
(
str
==
NULL
||
prefix
==
NULL
||
0
==
*
prefix
){
return
(
char
*
)
str
;
}
len
=
strlen
(
prefix
);
if
(
0
==
memcmp
(
str
,
prefix
,
len
)){
return
((
char
*
)
str
)
+
len
;
}
return
NULL
;
}
char
*
cstrcpy
(
char
*
dst
,
const
char
*
src
)
{
if
(
!
dst
)
return
(
char
*
)
0
;
...
...
@@ -52,22 +68,37 @@ char * cstrcpy(char * dst, const char * src)
/* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */
char
*
cstrncpy
(
char
*
dst
,
int
maxsize
,
const
char
*
src
)
{
if
(
!
dst
)
return
(
char
*
)
0
;
if
(
!
dst
)
return
(
char
*
)
0
;
unsigned
int
ms
=
maxsize
;
unsigned
int
len
=
0
;
if
(
src
&&
ms
>
0
){
if
(
src
&&
ms
>
0
){
len
=
strlen
(
src
);
if
(
len
>
ms
){
len
=
ms
;
}
if
(
len
){
if
(
len
){
memcpy
(
dst
,
src
,
len
);
}
}
dst
[
len
]
=
0
;
dst
[
len
]
=
0
;
return
dst
+
len
;
}
char
*
cmemcpy
(
char
*
dst
,
const
char
*
src
,
int
length
)
{
if
(
!
dst
)
return
(
char
*
)
0
;
if
(
length
){
if
(
src
){
memcpy
(
dst
,
src
,
length
);
}
else
{
memset
(
dst
,
0
,
length
);
}
}
dst
[
length
]
=
0
;
return
dst
+
length
;
}
/* copy up to maxsize characters from src to dst and return pointer to the next byte after the end */
char
*
cvstrncpy
(
char
*
dst
,
int
maxsize
,
const
char
*
ptr
,
...)
{
...
...
tools/itscertgen/cshared/cstr.h
View file @
1f88debd
...
...
@@ -17,9 +17,11 @@ extern "C" {
#define cisspace(X) isspace((int)(X))
#define cisdigit(X) isdigit((int)(X))
#define cisalnum(X) isalnum((int)(X))
int
cstrlen
(
const
char
*
str
);
int
cstrnlen
(
const
char
*
str
,
int<