strlen/Memcpy_s/strncasecmp

strlen

声明:size_t strlen(const char *str)
举例:

#include <stdio.h>
#include <string.h>

int main ()
{
   char str[50];
   int len;

   strcpy(str, "This is runoob.com");

   len = strlen(str);
   printf("|%s| 的长度是 |%d|\n", str, len);
   
   return(0);
}
让我们编译并运行上面的程序,这将产生以下结果:

|This is runoob.com| 的长度是 |18|

Memcpy_s

void *dest,
size_t numberOfElements,
const void *src,
size_t count
);
第一个参数为目标内存地址,第二个参数为目标内存缓冲大小,第三个参数为源内存地址,第四个为源内存缓冲的大小。返回值是一个错误码。

为什么这个返回值是错误码呢?因为这个版本中加入了基本的错误检测。如果源缓冲大小为0,即count为0,函数返回0,什么也不做。此函数没有对目标指针为NULL的情况,不做检查,所以你自己要注意检查。如果指针有值,但是是无效值,函数也没办法检查是否是有效内存,只是会搜集这些信息,在程序崩溃时提供调试需要的信息。

strncasecmp

举例:

#include <string.h>
main(){
    char *a = "aBcDeF";
    char *b = "AbCdEf";
    if(!strncasecmp(a, b, 3))    // 注意此处存在符号“!”
    {
        printf("%s =%s\n", a, b);
    }
}

定义
int strncasecmp(const char *s1, const char *s2, size_t n);

描述
strncasecmp()用来比较参数s1 和s2 字符串前n个字符,比较时会自动忽略大小写的差异。
若参数s1 和s2 字符串相同则返回0。s1 若大于s2 则返回大于0 的值,s1 若小于s2 则返回小于0 的值。

aarch64-openwrt-linux-musl-gcc -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math -fno-strict-aliasing -Wa,--noexecstack -D_XOPEN_SOURCE=700 -I./arch/aarch64 -I./arch/generic -Iobj/src/internal -I./src/include -I./src/internal -Iobj/include -I./include -g -O2 -fno-align-jumps -fno-align-functions -fno-align-loops -fno-align-labels -fira-region=one -fira-hoist-pressure -freorder-blocks-algorithm=simple -fno-prefetch-loop-arrays -fno-tree-ch -pipe -fno-unwind-tables -fno-asynchronous-unwind-tables -ffunction-sections -fdata-sections -Wno-pointer-to-int-cast -Werror=implicit-function-declaration -Werror=implicit-int -Werror=pointer-sign -Werror=pointer-arith -Werror=int-conversion -Werror=incompatible-pointer-types -Werror=discarded-qualifiers -Werror=discarded-array-qualifiers -Waddress -Warray-bounds -Wchar-subscripts -Wduplicate-decl-specifier -Winit-self -Wreturn-type -Wsequence-point -Wstrict-aliasing -Wunused-function -Wunused-label -Wunused-variable -pipe -mcpu=cortex-a53 -g3 -fno-caller-saves -fno-plt -fhonour-copts -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -Wl,-z,pack-relative-relocs -nostdlib -shared \ -Wl,-e,_dlstart -o lib/libc.so obj/src/aio/aio.lo obj/src/aio/aio_suspend.lo obj/src/aio/lio_listio.lo obj/src/complex/__cexp.lo obj/src/complex/__cexpf.lo obj/src/complex/cabs.lo obj/src/complex/cabsf.lo obj/src/complex/cabsl.lo obj/src/complex/cacos.lo obj/src/complex/cacosf.lo obj/src/complex/cacosh.lo obj/src/complex/cacoshf.lo obj/src/complex/cacoshl.lo obj/src/complex/cacosl.lo obj/src/complex/carg.lo obj/src/complex/cargf.lo obj/src/complex/cargl.lo obj/src/complex/casin.lo obj/src/complex/casinf.lo obj/src/complex/casinh.lo obj/src/complex/casinhf.lo obj/src/complex/casinhl.lo obj/src/complex/casinl.lo obj/src/complex/catan.lo obj/src/complex/catanf.lo obj/src/complex/catanh.lo obj/src/complex/catanhf.lo obj/src/complex/catanhl.lo obj/src/complex/catanl.lo obj/src/complex/ccos.lo obj/src/complex/ccosf.lo obj/src/complex/ccosh.lo obj/src/complex/ccoshf.lo obj/src/complex/ccoshl.lo obj/src/complex/ccosl.lo obj/src/complex/cexp.lo obj/src/complex/cexpf.lo obj/src/complex/cexpl.lo obj/src/complex/cimag.lo obj/src/complex/cimagf.lo obj/src/complex/cimagl.lo obj/src/complex/clog.lo obj/src/complex/clogf.lo obj/src/complex/clogl.lo obj/src/complex/conj.lo obj/src/complex/conjf.lo obj/src/complex/conjl.lo obj/src/complex/cpow.lo obj/src/complex/cpowf.lo obj/src/complex/cpowl.lo obj/src/complex/cproj.lo obj/src/complex/cprojf.lo obj/src/complex/cprojl.lo obj/src/complex/creal.lo obj/src/complex/crealf.lo obj/src/complex/creall.lo obj/src/complex/csin.lo obj/src/complex/csinf.lo obj/src/complex/csinh.lo obj/src/complex/csinhf.lo obj/src/complex/csinhl.lo obj/src/complex/csinl.lo obj/src/complex/csqrt.lo obj/src/complex/csqrtf.lo obj/src/complex/csqrtl.lo obj/src/complex/ctan.lo obj/src/complex/ctanf.lo obj/src/complex/ctanh.lo obj/src/complex/ctanhf.lo obj/src/complex/ctanhl.lo obj/src/complex/ctanl.lo obj/src/conf/confstr.lo obj/src/conf/fpathconf.lo obj/src/conf/legacy.lo obj/src/conf/pathconf.lo obj/src/conf/sysconf.lo obj/src/crypt/crypt.lo obj/src/crypt/crypt_blowfish.lo obj/src/crypt/crypt_des.lo obj/src/crypt/crypt_md5.lo obj/src/crypt/crypt_r.lo obj/src/crypt/crypt_sha256.lo obj/src/crypt/crypt_sha512.lo obj/src/crypt/encrypt.lo obj/src/ctype/__ctype_b_loc.lo obj/src/ctype/__ctype_get_mb_cur_max.lo obj/src/ctype/__ctype_tolower_loc.lo obj/src/ctype/__ctype_toupper_loc.lo obj/src/ctype/isalnum.lo obj/src/ctype/isalpha.lo obj/src/ctype/isascii.lo obj/src/ctype/isblank.lo obj/src/ctype/iscntrl.lo obj/src/ctype/isdigit.lo obj/src/ctype/isgraph.lo obj/src/ctype/islower.lo obj/src/ctype/isprint.lo obj/src/ctype/ispunct.lo obj/src/ctype/isspace.lo obj/src/ctype/isupper.lo obj/src/ctype/iswalnum.lo obj/src/ctype/iswalpha.lo obj/src/ctype/iswblank.lo obj/src/ctype/iswcntrl.lo obj/src/ctype/iswctype.lo obj/src/ctype/iswdigit.lo obj/src/ctype/iswgraph.lo obj/src/ctype/iswlower.lo obj/src/ctype/iswprint.lo obj/src/ctype/iswpunct.lo obj/src/ctype/iswspace.lo obj/src/ctype/iswupper.lo obj/src/ctype/iswxdigit.lo obj/src/ctype/isxdigit.lo obj/src/ctype/toascii.lo obj/src/ctype/tolower.lo obj/src/ctype/toupper.lo obj/src/ctype/towctrans.lo obj/src/ctype/wcswidth.lo obj/src/ctype/wctrans.lo obj/src/ctype/wcwidth.lo obj/src/dirent/alphasort.lo obj/src/dirent/closedir.lo obj/src/dirent/dirfd.lo obj/src/dirent/fdopendir.lo obj/src/dirent/opendir.lo obj/src/dirent/readdir.lo obj/src/dirent/readdir_r.lo obj/src/dirent/rewinddir.lo obj/src/dirent/scandir.lo obj/src/dirent/seekdir.lo obj/src/dirent/telldir.lo obj/src/dirent/versionsort.lo obj/src/env/__environ.lo obj/src/env/__init_tls.lo obj/src/env/__libc_start_main.lo obj/src/env/__reset_tls.lo obj/src/env/__stack_chk_fail.lo obj/src/env/clearenv.lo obj/src/env/getenv.lo obj/src/env/putenv.lo obj/src/env/secure_getenv.lo obj/src/env/setenv.lo obj/src/env/unsetenv.lo obj/src/errno/__errno_location.lo obj/src/errno/strerror.lo obj/src/exit/_Exit.lo obj/src/exit/abort.lo obj/src/exit/abort_lock.lo obj/src/exit/assert.lo obj/src/exit/at_quick_exit.lo obj/src/exit/atexit.lo obj/src/exit/exit.lo obj/src/exit/quick_exit.lo obj/src/fcntl/creat.lo obj/src/fcntl/fcntl.lo obj/src/fcntl/open.lo obj/src/fcntl/openat.lo obj/src/fcntl/posix_fadvise.lo obj/src/fcntl/posix_fallocate.lo obj/src/fenv/__flt_rounds.lo obj/src/fenv/aarch64/fenv.lo obj/src/fenv/fegetexceptflag.lo obj/src/fenv/feholdexcept.lo obj/src/fenv/fesetexceptflag.lo obj/src/fenv/fesetround.lo obj/src/fenv/feupdateenv.lo obj/src/internal/defsysinfo.lo obj/src/internal/emulate_wait4.lo obj/src/internal/floatscan.lo obj/src/internal/intscan.lo obj/src/internal/libc.lo obj/src/internal/procfdname.lo obj/src/internal/shgetc.lo obj/src/internal/syscall_ret.lo obj/src/internal/vdso.lo obj/src/internal/version.lo obj/src/ipc/ftok.lo obj/src/ipc/msgctl.lo obj/src/ipc/msgget.lo obj/src/ipc/msgrcv.lo obj/src/ipc/msgsnd.lo obj/src/ipc/semctl.lo obj/src/ipc/semget.lo obj/src/ipc/semop.lo obj/src/ipc/semtimedop.lo obj/src/ipc/shmat.lo obj/src/ipc/shmctl.lo obj/src/ipc/shmdt.lo obj/src/ipc/shmget.lo obj/src/ldso/__dlsym.lo obj/src/ldso/aarch64/dlsym.lo obj/src/ldso/aarch64/tlsdesc.lo obj/src/ldso/dl_iterate_phdr.lo obj/src/ldso/dladdr.lo obj/src/ldso/dlclose.lo obj/src/ldso/dlerror.lo obj/src/ldso/dlinfo.lo obj/src/ldso/dlopen.lo obj/src/legacy/cuserid.lo obj/src/legacy/daemon.lo obj/src/legacy/err.lo obj/src/legacy/euidaccess.lo obj/src/legacy/ftw.lo obj/src/legacy/futimes.lo obj/src/legacy/getdtablesize.lo obj/src/legacy/getloadavg.lo obj/src/legacy/getpagesize.lo obj/src/legacy/getpass.lo obj/src/legacy/getusershell.lo obj/src/legacy/isastream.lo obj/src/legacy/lutimes.lo obj/src/legacy/ulimit.lo obj/src/legacy/utmpx.lo obj/src/legacy/valloc.lo obj/src/linux/adjtime.lo obj/src/linux/adjtimex.lo obj/src/linux/arch_prctl.lo obj/src/linux/brk.lo obj/src/linux/cache.lo obj/src/linux/cap.lo obj/src/linux/chroot.lo obj/src/linux/clock_adjtime.lo obj/src/linux/clone.lo obj/src/linux/copy_file_range.lo obj/src/linux/epoll.lo obj/src/linux/eventfd.lo obj/src/linux/fallocate.lo obj/src/linux/fanotify.lo obj/src/linux/flock.lo obj/src/linux/getdents.lo obj/src/linux/getrandom.lo obj/src/linux/gettid.lo obj/src/linux/inotify.lo obj/src/linux/ioperm.lo obj/src/linux/iopl.lo obj/src/linux/klogctl.lo obj/src/linux/membarrier.lo obj/src/linux/memfd_create.lo obj/src/linux/mlock2.lo obj/src/linux/module.lo obj/src/linux/mount.lo obj/src/linux/name_to_handle_at.lo obj/src/linux/open_by_handle_at.lo obj/src/linux/personality.lo obj/src/linux/pivot_root.lo obj/src/linux/prctl.lo obj/src/linux/preadv2.lo obj/src/linux/prlimit.lo obj/src/linux/process_vm.lo obj/src/linux/ptrace.lo obj/src/linux/pwritev2.lo obj/src/linux/quotactl.lo obj/src/linux/readahead.lo obj/src/linux/reboot.lo obj/src/linux/remap_file_pages.lo obj/src/linux/renameat2.lo obj/src/linux/sbrk.lo obj/src/linux/sendfile.lo obj/src/linux/setfsgid.lo obj/src/linux/setfsuid.lo obj/src/linux/setgroups.lo obj/src/linux/sethostname.lo obj/src/linux/setns.lo obj/src/linux/settimeofday.lo obj/src/linux/signalfd.lo obj/src/linux/splice.lo obj/src/linux/statx.lo obj/src/linux/stime.lo obj/src/linux/swap.lo obj/src/linux/sync_file_range.lo obj/src/linux/syncfs.lo obj/src/linux/sysinfo.lo obj/src/linux/tee.lo obj/src/linux/timerfd.lo obj/src/linux/unshare.lo obj/src/linux/utimes.lo obj/src/linux/vhangup.lo obj/src/linux/vmsplice.lo obj/src/linux/wait3.lo obj/src/linux/wait4.lo obj/src/linux/xattr.lo obj/src/locale/__lctrans.lo obj/src/locale/__mo_lookup.lo obj/src/locale/bind_textdomain_codeset.lo obj/src/locale/c_locale.lo obj/src/locale/catclose.lo obj/src/locale/catgets.lo obj/src/locale/catopen.lo obj/src/locale/dcngettext.lo obj/src/locale/duplocale.lo obj/src/locale/freelocale.lo obj/src/locale/iconv.lo obj/src/locale/iconv_close.lo obj/src/locale/langinfo.lo obj/src/locale/locale_map.lo obj/src/locale/localeconv.lo obj/src/locale/newlocale.lo obj/src/locale/pleval.lo obj/src/locale/setlocale.lo obj/src/locale/strcoll.lo obj/src/locale/strfmon.lo obj/src/locale/strtod_l.lo obj/src/locale/strxfrm.lo obj/src/locale/textdomain.lo obj/src/locale/uselocale.lo obj/src/locale/wcscoll.lo obj/src/locale/wcsxfrm.lo obj/src/malloc/calloc.lo obj/src/malloc/free.lo obj/src/malloc/libc_calloc.lo obj/src/malloc/lite_malloc.lo obj/src/malloc/mallocng/aligned_alloc.lo obj/src/malloc/mallocng/donate.lo obj/src/malloc/mallocng/free.lo obj/src/malloc/mallocng/malloc.lo obj/src/malloc/mallocng/malloc_usable_size.lo obj/src/malloc/mallocng/realloc.lo obj/src/malloc/memalign.lo obj/src/malloc/posix_memalign.lo obj/src/malloc/realloc.lo obj/src/malloc/reallocarray.lo obj/src/malloc/replaced.lo obj/src/math/__cos.lo obj/src/math/__cosdf.lo obj/src/math/__cosl.lo obj/src/math/__expo2.lo obj/src/math/__expo2f.lo obj/src/math/__fpclassify.lo obj/src/math/__fpclassifyf.lo obj/src/math/__fpclassifyl.lo obj/src/math/__invtrigl.lo obj/src/math/__math_divzero.lo obj/src/math/__math_divzerof.lo obj/src/math/__math_invalid.lo obj/src/math/__math_invalidf.lo obj/src/math/__math_invalidl.lo obj/src/math/__math_oflow.lo obj/src/math/__math_oflowf.lo obj/src/math/__math_uflow.lo obj/src/math/__math_uflowf.lo obj/src/math/__math_xflow.lo obj/src/math/__math_xflowf.lo obj/src/math/__polevll.lo obj/src/math/__rem_pio2.lo obj/src/math/__rem_pio2_large.lo obj/src/math/__rem_pio2f.lo obj/src/math/__rem_pio2l.lo obj/src/math/__signbit.lo obj/src/math/__signbitf.lo obj/src/math/__signbitl.lo obj/src/math/__sin.lo obj/src/math/__sindf.lo obj/src/math/__sinl.lo obj/src/math/__tan.lo obj/src/math/__tandf.lo obj/src/math/__tanl.lo obj/src/math/aarch64/ceil.lo obj/src/math/aarch64/ceilf.lo obj/src/math/aarch64/fabs.lo obj/src/math/aarch64/fabsf.lo obj/src/math/aarch64/floor.lo obj/src/math/aarch64/floorf.lo obj/src/math/aarch64/fma.lo obj/src/math/aarch64/fmaf.lo obj/src/math/aarch64/fmax.lo obj/src/math/aarch64/fmaxf.lo obj/src/math/aarch64/fmin.lo obj/src/math/aarch64/fminf.lo obj/src/math/aarch64/llrint.lo obj/src/math/aarch64/llrintf.lo obj/src/math/aarch64/llround.lo obj/src/math/aarch64/llroundf.lo obj/src/math/aarch64/lrint.lo obj/src/math/aarch64/lrintf.lo obj/src/math/aarch64/lround.lo obj/src/math/aarch64/lroundf.lo obj/src/math/aarch64/nearbyint.lo obj/src/math/aarch64/nearbyintf.lo obj/src/math/aarch64/rint.lo obj/src/math/aarch64/rintf.lo obj/src/math/aarch64/round.lo obj/src/math/aarch64/roundf.lo obj/src/math/aarch64/sqrt.lo obj/src/math/aarch64/sqrtf.lo obj/src/math/aarch64/trunc.lo obj/src/math/aarch64/truncf.lo obj/src/math/acos.lo obj/src/math/acosf.lo obj/src/math/acosh.lo obj/src/math/acoshf.lo obj/src/math/acoshl.lo obj/src/math/acosl.lo obj/src/math/asin.lo obj/src/math/asinf.lo obj/src/math/asinh.lo obj/src/math/asinhf.lo obj/src/math/asinhl.lo obj/src/math/asinl.lo obj/src/math/atan.lo obj/src/math/atan2.lo obj/src/math/atan2f.lo obj/src/math/atan2l.lo obj/src/math/atanf.lo obj/src/math/atanh.lo obj/src/math/atanhf.lo obj/src/math/atanhl.lo obj/src/math/atanl.lo obj/src/math/cbrt.lo obj/src/math/cbrtf.lo obj/src/math/cbrtl.lo obj/src/math/ceill.lo obj/src/math/copysign.lo obj/src/math/copysignf.lo obj/src/math/copysignl.lo obj/src/math/cos.lo obj/src/math/cosf.lo obj/src/math/cosh.lo obj/src/math/coshf.lo obj/src/math/coshl.lo obj/src/math/cosl.lo obj/src/math/erf.lo obj/src/math/erff.lo obj/src/math/erfl.lo obj/src/math/exp.lo obj/src/math/exp10.lo obj/src/math/exp10f.lo obj/src/math/exp10l.lo obj/src/math/exp2.lo obj/src/math/exp2f.lo obj/src/math/exp2f_data.lo obj/src/math/exp2l.lo obj/src/math/exp_data.lo obj/src/math/expf.lo obj/src/math/expl.lo obj/src/math/expm1.lo obj/src/math/expm1f.lo obj/src/math/expm1l.lo obj/src/math/fabsl.lo obj/src/math/fdim.lo obj/src/math/fdimf.lo obj/src/math/fdiml.lo obj/src/math/finite.lo obj/src/math/finitef.lo obj/src/math/floorl.lo obj/src/math/fmal.lo obj/src/math/fmaxl.lo obj/src/math/fminl.lo obj/src/math/fmod.lo obj/src/math/fmodf.lo obj/src/math/fmodl.lo obj/src/math/frexp.lo obj/src/math/frexpf.lo obj/src/math/frexpl.lo obj/src/math/hypot.lo obj/src/math/hypotf.lo obj/src/math/hypotl.lo obj/src/math/ilogb.lo obj/src/math/ilogbf.lo obj/src/math/ilogbl.lo obj/src/math/j0.lo obj/src/math/j0f.lo obj/src/math/j1.lo obj/src/math/j1f.lo obj/src/math/jn.lo obj/src/math/jnf.lo obj/src/math/ldexp.lo obj/src/math/ldexpf.lo obj/src/math/ldexpl.lo obj/src/math/lgamma.lo obj/src/math/lgamma_r.lo obj/src/math/lgammaf.lo obj/src/math/lgammaf_r.lo obj/src/math/lgammal.lo obj/src/math/llrintl.lo obj/src/math/llroundl.lo obj/src/math/log.lo obj/src/math/log10.lo obj/src/math/log10f.lo obj/src/math/log10l.lo obj/src/math/log1p.lo obj/src/math/log1pf.lo obj/src/math/log1pl.lo obj/src/math/log2.lo obj/src/math/log2_data.lo obj/src/math/log2f.lo obj/src/math/log2f_data.lo obj/src/math/log2l.lo obj/src/math/log_data.lo obj/src/math/logb.lo obj/src/math/logbf.lo obj/src/math/logbl.lo obj/src/math/logf.lo obj/src/math/logf_data.lo obj/src/math/logl.lo obj/src/math/lrintl.lo obj/src/math/lroundl.lo obj/src/math/modf.lo obj/src/math/modff.lo obj/src/math/modfl.lo obj/src/math/nan.lo obj/src/math/nanf.lo obj/src/math/nanl.lo obj/src/math/nearbyintl.lo obj/src/math/nextafter.lo obj/src/math/nextafterf.lo obj/src/math/nextafterl.lo obj/src/math/nexttoward.lo obj/src/math/nexttowardf.lo obj/src/math/nexttowardl.lo obj/src/math/pow.lo obj/src/math/pow_data.lo obj/src/math/powf.lo obj/src/math/powf_data.lo obj/src/math/powl.lo obj/src/math/remainder.lo obj/src/math/remainderf.lo obj/src/math/remainderl.lo obj/src/math/remquo.lo obj/src/math/remquof.lo obj/src/math/remquol.lo obj/src/math/rintl.lo obj/src/math/roundl.lo obj/src/math/scalb.lo obj/src/math/scalbf.lo obj/src/math/scalbln.lo obj/src/math/scalblnf.lo obj/src/math/scalblnl.lo obj/src/math/scalbn.lo obj/src/math/scalbnf.lo obj/src/math/scalbnl.lo obj/src/math/signgam.lo obj/src/math/significand.lo obj/src/math/significandf.lo obj/src/math/sin.lo obj/src/math/sincos.lo obj/src/math/sincosf.lo obj/src/math/sincosl.lo obj/src/math/sinf.lo obj/src/math/sinh.lo obj/src/math/sinhf.lo obj/src/math/sinhl.lo obj/src/math/sinl.lo obj/src/math/sqrt_data.lo obj/src/math/sqrtl.lo obj/src/math/tan.lo obj/src/math/tanf.lo obj/src/math/tanh.lo obj/src/math/tanhf.lo obj/src/math/tanhl.lo obj/src/math/tanl.lo obj/src/math/tgamma.lo obj/src/math/tgammaf.lo obj/src/math/tgammal.lo obj/src/math/truncl.lo obj/src/misc/a64l.lo obj/src/misc/basename.lo obj/src/misc/dirname.lo obj/src/misc/ffs.lo obj/src/misc/ffsl.lo obj/src/misc/ffsll.lo obj/src/misc/fmtmsg.lo obj/src/misc/forkpty.lo obj/src/misc/get_current_dir_name.lo obj/src/misc/getauxval.lo obj/src/misc/getdomainname.lo obj/src/misc/getentropy.lo obj/src/misc/gethostid.lo obj/src/misc/getopt.lo obj/src/misc/getopt_long.lo obj/src/misc/getpriority.lo obj/src/misc/getresgid.lo obj/src/misc/getresuid.lo obj/src/misc/getrlimit.lo obj/src/misc/getrusage.lo obj/src/misc/getsubopt.lo obj/src/misc/initgroups.lo obj/src/misc/ioctl.lo obj/src/misc/issetugid.lo obj/src/misc/lockf.lo obj/src/misc/login_tty.lo obj/src/misc/mntent.lo obj/src/misc/nftw.lo obj/src/misc/openpty.lo obj/src/misc/ptsname.lo obj/src/misc/pty.lo obj/src/misc/realpath.lo obj/src/misc/setdomainname.lo obj/src/misc/setpriority.lo obj/src/misc/setrlimit.lo obj/src/misc/syscall.lo obj/src/misc/syslog.lo obj/src/misc/uname.lo obj/src/misc/wordexp.lo obj/src/mman/madvise.lo obj/src/mman/mincore.lo obj/src/mman/mlock.lo obj/src/mman/mlockall.lo obj/src/mman/mmap.lo obj/src/mman/mprotect.lo obj/src/mman/mremap.lo obj/src/mman/msync.lo obj/src/mman/munlock.lo obj/src/mman/munlockall.lo obj/src/mman/munmap.lo obj/src/mman/posix_madvise.lo obj/src/mman/shm_open.lo obj/src/mq/mq_close.lo obj/src/mq/mq_getattr.lo obj/src/mq/mq_notify.lo obj/src/mq/mq_open.lo obj/src/mq/mq_receive.lo obj/src/mq/mq_send.lo obj/src/mq/mq_setattr.lo obj/src/mq/mq_timedreceive.lo obj/src/mq/mq_timedsend.lo obj/src/mq/mq_unlink.lo obj/src/multibyte/btowc.lo obj/src/multibyte/c16rtomb.lo obj/src/multibyte/c32rtomb.lo obj/src/multibyte/internal.lo obj/src/multibyte/mblen.lo obj/src/multibyte/mbrlen.lo obj/src/multibyte/mbrtoc16.lo obj/src/multibyte/mbrtoc32.lo obj/src/multibyte/mbrtowc.lo obj/src/multibyte/mbsinit.lo obj/src/multibyte/mbsnrtowcs.lo obj/src/multibyte/mbsrtowcs.lo obj/src/multibyte/mbstowcs.lo obj/src/multibyte/mbtowc.lo obj/src/multibyte/wcrtomb.lo obj/src/multibyte/wcsnrtombs.lo obj/src/multibyte/wcsrtombs.lo obj/src/multibyte/wcstombs.lo obj/src/multibyte/wctob.lo obj/src/multibyte/wctomb.lo obj/src/network/accept.lo obj/src/network/accept4.lo obj/src/network/bind.lo obj/src/network/connect.lo obj/src/network/dn_comp.lo obj/src/network/dn_expand.lo obj/src/network/dn_skipname.lo obj/src/network/dns_parse.lo obj/src/network/ent.lo obj/src/network/ether.lo obj/src/network/freeaddrinfo.lo obj/src/network/gai_strerror.lo obj/src/network/getaddrinfo.lo obj/src/network/gethostbyaddr.lo obj/src/network/gethostbyaddr_r.lo obj/src/network/gethostbyname.lo obj/src/network/gethostbyname2.lo obj/src/network/gethostbyname2_r.lo obj/src/network/gethostbyname_r.lo obj/src/network/getifaddrs.lo obj/src/network/getnameinfo.lo obj/src/network/getpeername.lo obj/src/network/getservbyname.lo obj/src/network/getservbyname_r.lo obj/src/network/getservbyport.lo obj/src/network/getservbyport_r.lo obj/src/network/getsockname.lo obj/src/network/getsockopt.lo obj/src/network/h_errno.lo obj/src/network/herror.lo obj/src/network/hstrerror.lo obj/src/network/htonl.lo obj/src/network/htons.lo obj/src/network/if_freenameindex.lo obj/src/network/if_indextoname.lo obj/src/network/if_nameindex.lo obj/src/network/if_nametoindex.lo obj/src/network/in6addr_any.lo obj/src/network/in6addr_loopback.lo obj/src/network/inet_addr.lo obj/src/network/inet_aton.lo obj/src/network/inet_legacy.lo obj/src/network/inet_ntoa.lo obj/src/network/inet_ntop.lo obj/src/network/inet_pton.lo obj/src/network/listen.lo obj/src/network/lookup_ipliteral.lo obj/src/network/lookup_name.lo obj/src/network/lookup_serv.lo obj/src/network/netlink.lo obj/src/network/netname.lo obj/src/network/ns_parse.lo obj/src/network/ntohl.lo obj/src/network/ntohs.lo obj/src/network/proto.lo obj/src/network/recv.lo obj/src/network/recvfrom.lo obj/src/network/recvmmsg.lo obj/src/network/recvmsg.lo obj/src/network/res_init.lo obj/src/network/res_mkquery.lo obj/src/network/res_msend.lo obj/src/network/res_query.lo obj/src/network/res_querydomain.lo obj/src/network/res_send.lo obj/src/network/res_state.lo obj/src/network/resolvconf.lo obj/src/network/send.lo obj/src/network/sendmmsg.lo obj/src/network/sendmsg.lo obj/src/network/sendto.lo obj/src/network/serv.lo obj/src/network/setsockopt.lo obj/src/network/shutdown.lo obj/src/network/sockatmark.lo obj/src/network/socket.lo obj/src/network/socketpair.lo obj/src/passwd/fgetgrent.lo obj/src/passwd/fgetpwent.lo obj/src/passwd/fgetspent.lo obj/src/passwd/getgr_a.lo obj/src/passwd/getgr_r.lo obj/src/passwd/getgrent.lo obj/src/passwd/getgrent_a.lo obj/src/passwd/getgrouplist.lo obj/src/passwd/getpw_a.lo obj/src/passwd/getpw_r.lo obj/src/passwd/getpwent.lo obj/src/passwd/getpwent_a.lo obj/src/passwd/getspent.lo obj/src/passwd/getspnam.lo obj/src/passwd/getspnam_r.lo obj/src/passwd/lckpwdf.lo obj/src/passwd/nscd_query.lo obj/src/passwd/putgrent.lo obj/src/passwd/putpwent.lo obj/src/passwd/putspent.lo obj/src/prng/__rand48_step.lo obj/src/prng/__seed48.lo obj/src/prng/drand48.lo obj/src/prng/lcong48.lo obj/src/prng/lrand48.lo obj/src/prng/mrand48.lo obj/src/prng/rand.lo obj/src/prng/rand_r.lo obj/src/prng/random.lo obj/src/prng/seed48.lo obj/src/prng/srand48.lo obj/src/process/_Fork.lo obj/src/process/aarch64/vfork.lo obj/src/process/execl.lo obj/src/process/execle.lo obj/src/process/execlp.lo obj/src/process/execv.lo obj/src/process/execve.lo obj/src/process/execvp.lo obj/src/process/fexecve.lo obj/src/process/fork.lo obj/src/process/posix_spawn.lo obj/src/process/posix_spawn_file_actions_addchdir.lo obj/src/process/posix_spawn_file_actions_addclose.lo obj/src/process/posix_spawn_file_actions_adddup2.lo obj/src/process/posix_spawn_file_actions_addfchdir.lo obj/src/process/posix_spawn_file_actions_addopen.lo obj/src/process/posix_spawn_file_actions_destroy.lo obj/src/process/posix_spawn_file_actions_init.lo obj/src/process/posix_spawnattr_destroy.lo obj/src/process/posix_spawnattr_getflags.lo obj/src/process/posix_spawnattr_getpgroup.lo obj/src/process/posix_spawnattr_getsigdefault.lo obj/src/process/posix_spawnattr_getsigmask.lo obj/src/process/posix_spawnattr_init.lo obj/src/process/posix_spawnattr_sched.lo obj/src/process/posix_spawnattr_setflags.lo obj/src/process/posix_spawnattr_setpgroup.lo obj/src/process/posix_spawnattr_setsigdefault.lo obj/src/process/posix_spawnattr_setsigmask.lo obj/src/process/posix_spawnp.lo obj/src/process/system.lo obj/src/process/wait.lo obj/src/process/waitid.lo obj/src/process/waitpid.lo obj/src/regex/fnmatch.lo obj/src/regex/glob.lo obj/src/regex/regcomp.lo obj/src/regex/regerror.lo obj/src/regex/regexec.lo obj/src/regex/tre-mem.lo obj/src/sched/affinity.lo obj/src/sched/sched_cpucount.lo obj/src/sched/sched_get_priority_max.lo obj/src/sched/sched_getcpu.lo obj/src/sched/sched_getparam.lo obj/src/sched/sched_getscheduler.lo obj/src/sched/sched_rr_get_interval.lo obj/src/sched/sched_setparam.lo obj/src/sched/sched_setscheduler.lo obj/src/sched/sched_yield.lo obj/src/search/hsearch.lo obj/src/search/insque.lo obj/src/search/lsearch.lo obj/src/search/tdelete.lo obj/src/search/tdestroy.lo obj/src/search/tfind.lo obj/src/search/tsearch.lo obj/src/search/twalk.lo obj/src/select/poll.lo obj/src/select/ppoll.lo obj/src/select/pselect.lo obj/src/select/select.lo obj/src/setjmp/aarch64/longjmp.lo obj/src/setjmp/aarch64/setjmp.lo obj/src/signal/aarch64/restore.lo obj/src/signal/aarch64/sigsetjmp.lo obj/src/signal/block.lo obj/src/signal/getitimer.lo obj/src/signal/kill.lo obj/src/signal/killpg.lo obj/src/signal/psiginfo.lo obj/src/signal/psignal.lo obj/src/signal/raise.lo obj/src/signal/setitimer.lo obj/src/signal/sigaction.lo obj/src/signal/sigaddset.lo obj/src/signal/sigaltstack.lo obj/src/signal/sigandset.lo obj/src/signal/sigdelset.lo obj/src/signal/sigemptyset.lo obj/src/signal/sigfillset.lo obj/src/signal/sighold.lo obj/src/signal/sigignore.lo obj/src/signal/siginterrupt.lo obj/src/signal/sigisemptyset.lo obj/src/signal/sigismember.lo obj/src/signal/siglongjmp.lo obj/src/signal/signal.lo obj/src/signal/sigorset.lo obj/src/signal/sigpause.lo obj/src/signal/sigpending.lo obj/src/signal/sigprocmask.lo obj/src/signal/sigqueue.lo obj/src/signal/sigrelse.lo obj/src/signal/sigrtmax.lo obj/src/signal/sigrtmin.lo obj/src/signal/sigset.lo obj/src/signal/sigsetjmp_tail.lo obj/src/signal/sigsuspend.lo obj/src/signal/sigtimedwait.lo obj/src/signal/sigwait.lo obj/src/signal/sigwaitinfo.lo obj/src/stat/__xstat.lo obj/src/stat/chmod.lo obj/src/stat/fchmod.lo obj/src/stat/fchmodat.lo obj/src/stat/fstat.lo obj/src/stat/fstatat.lo obj/src/stat/futimens.lo obj/src/stat/futimesat.lo obj/src/stat/lchmod.lo obj/src/stat/lstat.lo obj/src/stat/mkdir.lo obj/src/stat/mkdirat.lo obj/src/stat/mkfifo.lo obj/src/stat/mkfifoat.lo obj/src/stat/mknod.lo obj/src/stat/mknodat.lo obj/src/stat/stat.lo obj/src/stat/statvfs.lo obj/src/stat/umask.lo obj/src/stat/utimensat.lo obj/src/stdio/__fclose_ca.lo obj/src/stdio/__fdopen.lo obj/src/stdio/__fmodeflags.lo obj/src/stdio/__fopen_rb_ca.lo obj/src/stdio/__lockfile.lo obj/src/stdio/__overflow.lo obj/src/stdio/__stdio_close.lo obj/src/stdio/__stdio_exit.lo obj/src/stdio/__stdio_read.lo obj/src/stdio/__stdio_seek.lo obj/src/stdio/__stdio_write.lo obj/src/stdio/__stdout_write.lo obj/src/stdio/__toread.lo obj/src/stdio/__towrite.lo obj/src/stdio/__uflow.lo obj/src/stdio/asprintf.lo obj/src/stdio/clearerr.lo obj/src/stdio/dprintf.lo obj/src/stdio/ext.lo obj/src/stdio/ext2.lo obj/src/stdio/fclose.lo obj/src/stdio/feof.lo obj/src/stdio/ferror.lo obj/src/stdio/fflush.lo obj/src/stdio/fgetc.lo obj/src/stdio/fgetln.lo obj/src/stdio/fgetpos.lo obj/src/stdio/fgets.lo obj/src/stdio/fgetwc.lo obj/src/stdio/fgetws.lo obj/src/stdio/fileno.lo obj/src/stdio/flockfile.lo obj/src/stdio/fmemopen.lo obj/src/stdio/fopen.lo obj/src/stdio/fopencookie.lo obj/src/stdio/fprintf.lo obj/src/stdio/fputc.lo obj/src/stdio/fputs.lo obj/src/stdio/fputwc.lo obj/src/stdio/fputws.lo obj/src/stdio/fread.lo obj/src/stdio/freopen.lo obj/src/stdio/fscanf.lo obj/src/stdio/fseek.lo obj/src/stdio/fsetpos.lo obj/src/stdio/ftell.lo obj/src/stdio/ftrylockfile.lo obj/src/stdio/funlockfile.lo obj/src/stdio/fwide.lo obj/src/stdio/fwprintf.lo obj/src/stdio/fwrite.lo obj/src/stdio/fwscanf.lo obj/src/stdio/getc.lo obj/src/stdio/getc_unlocked.lo obj/src/stdio/getchar.lo obj/src/stdio/getchar_unlocked.lo obj/src/stdio/getdelim.lo obj/src/stdio/getline.lo obj/src/stdio/gets.lo obj/src/stdio/getw.lo obj/src/stdio/getwc.lo obj/src/stdio/getwchar.lo obj/src/stdio/ofl.lo obj/src/stdio/ofl_add.lo obj/src/stdio/open_memstream.lo obj/src/stdio/open_wmemstream.lo obj/src/stdio/pclose.lo obj/src/stdio/perror.lo obj/src/stdio/popen.lo obj/src/stdio/printf.lo obj/src/stdio/putc.lo obj/src/stdio/putc_unlocked.lo obj/src/stdio/putchar.lo obj/src/stdio/putchar_unlocked.lo obj/src/stdio/puts.lo obj/src/stdio/putw.lo obj/src/stdio/putwc.lo obj/src/stdio/putwchar.lo obj/src/stdio/remove.lo obj/src/stdio/rename.lo obj/src/stdio/rewind.lo obj/src/stdio/scanf.lo obj/src/stdio/setbuf.lo obj/src/stdio/setbuffer.lo obj/src/stdio/setlinebuf.lo obj/src/stdio/setvbuf.lo obj/src/stdio/snprintf.lo obj/src/stdio/sprintf.lo obj/src/stdio/sscanf.lo obj/src/stdio/stderr.lo obj/src/stdio/stdin.lo obj/src/stdio/stdout.lo obj/src/stdio/swprintf.lo obj/src/stdio/swscanf.lo obj/src/stdio/tempnam.lo obj/src/stdio/tmpfile.lo obj/src/stdio/tmpnam.lo obj/src/stdio/ungetc.lo obj/src/stdio/ungetwc.lo obj/src/stdio/vasprintf.lo obj/src/stdio/vdprintf.lo obj/src/stdio/vfprintf.lo obj/src/stdio/vfscanf.lo obj/src/stdio/vfwprintf.lo obj/src/stdio/vfwscanf.lo obj/src/stdio/vprintf.lo obj/src/stdio/vscanf.lo obj/src/stdio/vsnprintf.lo obj/src/stdio/vsprintf.lo obj/src/stdio/vsscanf.lo obj/src/stdio/vswprintf.lo obj/src/stdio/vswscanf.lo obj/src/stdio/vwprintf.lo obj/src/stdio/vwscanf.lo obj/src/stdio/wprintf.lo obj/src/stdio/wscanf.lo obj/src/stdlib/abs.lo obj/src/stdlib/atof.lo obj/src/stdlib/atoi.lo obj/src/stdlib/atol.lo obj/src/stdlib/atoll.lo obj/src/stdlib/bsearch.lo obj/src/stdlib/div.lo obj/src/stdlib/ecvt.lo obj/src/stdlib/fcvt.lo obj/src/stdlib/gcvt.lo obj/src/stdlib/imaxabs.lo obj/src/stdlib/imaxdiv.lo obj/src/stdlib/labs.lo obj/src/stdlib/ldiv.lo obj/src/stdlib/llabs.lo obj/src/stdlib/lldiv.lo obj/src/stdlib/qsort.lo obj/src/stdlib/qsort_nr.lo obj/src/stdlib/strtod.lo obj/src/stdlib/strtol.lo obj/src/stdlib/wcstod.lo obj/src/stdlib/wcstol.lo obj/src/string/aarch64/memcpy.lo obj/src/string/aarch64/memset.lo obj/src/string/bcmp.lo obj/src/string/bcopy.lo obj/src/string/bzero.lo obj/src/string/explicit_bzero.lo obj/src/string/index.lo obj/src/string/memccpy.lo obj/src/string/memchr.lo obj/src/string/memcmp.lo obj/src/string/memmem.lo obj/src/string/memmove.lo obj/src/string/mempcpy.lo obj/src/string/memrchr.lo obj/src/string/rindex.lo obj/src/string/stpcpy.lo obj/src/string/stpncpy.lo obj/src/string/strcasecmp.lo obj/src/string/strcasestr.lo obj/src/string/strcat.lo obj/src/string/strchr.lo obj/src/string/strchrnul.lo obj/src/string/strcmp.lo obj/src/string/strcpy.lo obj/src/string/strcspn.lo obj/src/string/strdup.lo obj/src/string/strerror_r.lo obj/src/string/strlcat.lo obj/src/string/strlcpy.lo obj/src/string/strlen.lo obj/src/string/strncasecmp.lo obj/src/string/strncat.lo obj/src/string/strncmp.lo obj/src/string/strncpy.lo obj/src/string/strndup.lo obj/src/string/strnlen.lo obj/src/string/strpbrk.lo obj/src/string/strrchr.lo obj/src/string/strsep.lo obj/src/string/strsignal.lo obj/src/string/strspn.lo obj/src/string/strstr.lo obj/src/string/strtok.lo obj/src/string/strtok_r.lo obj/src/string/strverscmp.lo obj/src/string/swab.lo obj/src/string/wcpcpy.lo obj/src/string/wcpncpy.lo obj/src/string/wcscasecmp.lo obj/src/string/wcscasecmp_l.lo obj/src/string/wcscat.lo obj/src/string/wcschr.lo obj/src/string/wcscmp.lo obj/src/string/wcscpy.lo obj/src/string/wcscspn.lo obj/src/string/wcsdup.lo obj/src/string/wcslen.lo obj/src/string/wcsncasecmp.lo obj/src/string/wcsncasecmp_l.lo obj/src/string/wcsncat.lo obj/src/string/wcsncmp.lo obj/src/string/wcsncpy.lo obj/src/string/wcsnlen.lo obj/src/string/wcspbrk.lo obj/src/string/wcsrchr.lo obj/src/string/wcsspn.lo obj/src/string/wcsstr.lo obj/src/string/wcstok.lo obj/src/string/wcswcs.lo obj/src/string/wmemchr.lo obj/src/string/wmemcmp.lo obj/src/string/wmemcpy.lo obj/src/string/wmemmove.lo obj/src/string/wmemset.lo obj/src/temp/__randname.lo obj/src/temp/mkdtemp.lo obj/src/temp/mkostemp.lo obj/src/temp/mkostemps.lo obj/src/temp/mkstemp.lo obj/src/temp/mkstemps.lo obj/src/temp/mktemp.lo obj/src/termios/cfgetospeed.lo obj/src/termios/cfmakeraw.lo obj/src/termios/cfsetospeed.lo obj/src/termios/tcdrain.lo obj/src/termios/tcflow.lo obj/src/termios/tcflush.lo obj/src/termios/tcgetattr.lo obj/src/termios/tcgetsid.lo obj/src/termios/tcgetwinsize.lo obj/src/termios/tcsendbreak.lo obj/src/termios/tcsetattr.lo obj/src/termios/tcsetwinsize.lo obj/src/thread/__lock.lo obj/src/thread/__syscall_cp.lo obj/src/thread/__timedwait.lo obj/src/thread/__tls_get_addr.lo obj/src/thread/__wait.lo obj/src/thread/aarch64/__set_thread_area.lo obj/src/thread/aarch64/__unmapself.lo obj/src/thread/aarch64/clone.lo obj/src/thread/aarch64/syscall_cp.lo obj/src/thread/call_once.lo obj/src/thread/cnd_broadcast.lo obj/src/thread/cnd_destroy.lo obj/src/thread/cnd_init.lo obj/src/thread/cnd_signal.lo obj/src/thread/cnd_timedwait.lo obj/src/thread/cnd_wait.lo obj/src/thread/default_attr.lo obj/src/thread/lock_ptc.lo obj/src/thread/mtx_destroy.lo obj/src/thread/mtx_init.lo obj/src/thread/mtx_lock.lo obj/src/thread/mtx_timedlock.lo obj/src/thread/mtx_trylock.lo obj/src/thread/mtx_unlock.lo obj/src/thread/pthread_atfork.lo obj/src/thread/pthread_attr_destroy.lo obj/src/thread/pthread_attr_get.lo obj/src/thread/pthread_attr_init.lo obj/src/thread/pthread_attr_setdetachstate.lo obj/src/thread/pthread_attr_setguardsize.lo obj/src/thread/pthread_attr_setinheritsched.lo obj/src/thread/pthread_attr_setschedparam.lo obj/src/thread/pthread_attr_setschedpolicy.lo obj/src/thread/pthread_attr_setscope.lo obj/src/thread/pthread_attr_setstack.lo obj/src/thread/pthread_attr_setstacksize.lo obj/src/thread/pthread_barrier_destroy.lo obj/src/thread/pthread_barrier_init.lo obj/src/thread/pthread_barrier_wait.lo obj/src/thread/pthread_barrierattr_destroy.lo obj/src/thread/pthread_barrierattr_init.lo obj/src/thread/pthread_barrierattr_setpshared.lo obj/src/thread/pthread_cancel.lo obj/src/thread/pthread_cleanup_push.lo obj/src/thread/pthread_cond_broadcast.lo obj/src/thread/pthread_cond_destroy.lo obj/src/thread/pthread_cond_init.lo obj/src/thread/pthread_cond_signal.lo obj/src/thread/pthread_cond_timedwait.lo obj/src/thread/pthread_cond_wait.lo obj/src/thread/pthread_condattr_destroy.lo obj/src/thread/pthread_condattr_init.lo obj/src/thread/pthread_condattr_setclock.lo obj/src/thread/pthread_condattr_setpshared.lo obj/src/thread/pthread_create.lo obj/src/thread/pthread_detach.lo obj/src/thread/pthread_equal.lo obj/src/thread/pthread_getattr_np.lo obj/src/thread/pthread_getconcurrency.lo obj/src/thread/pthread_getcpuclockid.lo obj/src/thread/pthread_getname_np.lo obj/src/thread/pthread_getschedparam.lo obj/src/thread/pthread_getspecific.lo obj/src/thread/pthread_join.lo obj/src/thread/pthread_key_create.lo obj/src/thread/pthread_kill.lo obj/src/thread/pthread_mutex_consistent.lo obj/src/thread/pthread_mutex_destroy.lo obj/src/thread/pthread_mutex_getprioceiling.lo obj/src/thread/pthread_mutex_init.lo obj/src/thread/pthread_mutex_lock.lo obj/src/thread/pthread_mutex_setprioceiling.lo obj/src/thread/pthread_mutex_timedlock.lo obj/src/thread/pthread_mutex_trylock.lo obj/src/thread/pthread_mutex_unlock.lo obj/src/thread/pthread_mutexattr_destroy.lo obj/src/thread/pthread_mutexattr_init.lo obj/src/thread/pthread_mutexattr_setprotocol.lo obj/src/thread/pthread_mutexattr_setpshared.lo obj/src/thread/pthread_mutexattr_setrobust.lo obj/src/thread/pthread_mutexattr_settype.lo obj/src/thread/pthread_once.lo obj/src/thread/pthread_rwlock_destroy.lo obj/src/thread/pthread_rwlock_init.lo obj/src/thread/pthread_rwlock_rdlock.lo obj/src/thread/pthread_rwlock_timedrdlock.lo obj/src/thread/pthread_rwlock_timedwrlock.lo obj/src/thread/pthread_rwlock_tryrdlock.lo obj/src/thread/pthread_rwlock_trywrlock.lo obj/src/thread/pthread_rwlock_unlock.lo obj/src/thread/pthread_rwlock_wrlock.lo obj/src/thread/pthread_rwlockattr_destroy.lo obj/src/thread/pthread_rwlockattr_init.lo obj/src/thread/pthread_rwlockattr_setpshared.lo obj/src/thread/pthread_self.lo obj/src/thread/pthread_setattr_default_np.lo obj/src/thread/pthread_setcancelstate.lo obj/src/thread/pthread_setcanceltype.lo obj/src/thread/pthread_setconcurrency.lo obj/src/thread/pthread_setname_np.lo obj/src/thread/pthread_setschedparam.lo obj/src/thread/pthread_setschedprio.lo obj/src/thread/pthread_setspecific.lo obj/src/thread/pthread_sigmask.lo obj/src/thread/pthread_spin_destroy.lo obj/src/thread/pthread_spin_init.lo obj/src/thread/pthread_spin_lock.lo obj/src/thread/pthread_spin_trylock.lo obj/src/thread/pthread_spin_unlock.lo obj/src/thread/pthread_testcancel.lo obj/src/thread/sem_destroy.lo obj/src/thread/sem_getvalue.lo obj/src/thread/sem_init.lo obj/src/thread/sem_open.lo obj/src/thread/sem_post.lo obj/src/thread/sem_timedwait.lo obj/src/thread/sem_trywait.lo obj/src/thread/sem_unlink.lo obj/src/thread/sem_wait.lo obj/src/thread/synccall.lo obj/src/thread/thrd_create.lo obj/src/thread/thrd_exit.lo obj/src/thread/thrd_join.lo obj/src/thread/thrd_sleep.lo obj/src/thread/thrd_yield.lo obj/src/thread/tls.lo obj/src/thread/tss_create.lo obj/src/thread/tss_delete.lo obj/src/thread/tss_set.lo obj/src/thread/vmlock.lo obj/src/time/__map_file.lo obj/src/time/__month_to_secs.lo obj/src/time/__secs_to_tm.lo obj/src/time/__tm_to_secs.lo obj/src/time/__tz.lo obj/src/time/__year_to_secs.lo obj/src/time/asctime.lo obj/src/time/asctime_r.lo obj/src/time/clock.lo obj/src/time/clock_getcpuclockid.lo obj/src/time/clock_getres.lo obj/src/time/clock_gettime.lo obj/src/time/clock_nanosleep.lo obj/src/time/clock_settime.lo obj/src/time/ctime.lo obj/src/time/ctime_r.lo obj/src/time/difftime.lo obj/src/time/ftime.lo obj/src/time/getdate.lo obj/src/time/gettimeofday.lo obj/src/time/gmtime.lo obj/src/time/gmtime_r.lo obj/src/time/localtime.lo obj/src/time/localtime_r.lo obj/src/time/mktime.lo obj/src/time/nanosleep.lo obj/src/time/strftime.lo obj/src/time/strptime.lo obj/src/time/time.lo obj/src/time/timegm.lo obj/src/time/timer_create.lo obj/src/time/timer_delete.lo obj/src/time/timer_getoverrun.lo obj/src/time/timer_gettime.lo obj/src/time/timer_settime.lo obj/src/time/times.lo obj/src/time/timespec_get.lo obj/src/time/utime.lo obj/src/time/wcsftime.lo obj/src/unistd/_exit.lo obj/src/unistd/access.lo obj/src/unistd/acct.lo obj/src/unistd/alarm.lo obj/src/unistd/chdir.lo obj/src/unistd/chown.lo obj/src/unistd/close.lo obj/src/unistd/ctermid.lo obj/src/unistd/dup.lo obj/src/unistd/dup2.lo obj/src/unistd/dup3.lo obj/src/unistd/faccessat.lo obj/src/unistd/fchdir.lo obj/src/unistd/fchown.lo obj/src/unistd/fchownat.lo obj/src/unistd/fdatasync.lo obj/src/unistd/fsync.lo obj/src/unistd/ftruncate.lo obj/src/unistd/getcwd.lo obj/src/unistd/getegid.lo obj/src/unistd/geteuid.lo obj/src/unistd/getgid.lo obj/src/unistd/getgroups.lo obj/src/unistd/gethostname.lo obj/src/unistd/getlogin.lo obj/src/unistd/getlogin_r.lo obj/src/unistd/getpgid.lo obj/src/unistd/getpgrp.lo obj/src/unistd/getpid.lo obj/src/unistd/getppid.lo obj/src/unistd/getsid.lo obj/src/unistd/getuid.lo obj/src/unistd/isatty.lo obj/src/unistd/lchown.lo obj/src/unistd/link.lo obj/src/unistd/linkat.lo obj/src/unistd/lseek.lo obj/src/unistd/nice.lo obj/src/unistd/pause.lo obj/src/unistd/pipe.lo obj/src/unistd/pipe2.lo obj/src/unistd/posix_close.lo obj/src/unistd/pread.lo obj/src/unistd/preadv.lo obj/src/unistd/pwrite.lo obj/src/unistd/pwritev.lo obj/src/unistd/read.lo obj/src/unistd/readlink.lo obj/src/unistd/readlinkat.lo obj/src/unistd/readv.lo obj/src/unistd/renameat.lo obj/src/unistd/rmdir.lo obj/src/unistd/setegid.lo obj/src/unistd/seteuid.lo obj/src/unistd/setgid.lo obj/src/unistd/setpgid.lo obj/src/unistd/setpgrp.lo obj/src/unistd/setregid.lo obj/src/unistd/setresgid.lo obj/src/unistd/setresuid.lo obj/src/unistd/setreuid.lo obj/src/unistd/setsid.lo obj/src/unistd/setuid.lo obj/src/unistd/setxid.lo obj/src/unistd/sleep.lo obj/src/unistd/symlink.lo obj/src/unistd/symlinkat.lo obj/src/unistd/sync.lo obj/src/unistd/tcgetpgrp.lo obj/src/unistd/tcsetpgrp.lo obj/src/unistd/truncate.lo obj/src/unistd/ttyname.lo obj/src/unistd/ttyname_r.lo obj/src/unistd/ualarm.lo obj/src/unistd/unlink.lo obj/src/unistd/unlinkat.lo obj/src/unistd/usleep.lo obj/src/unistd/write.lo obj/src/unistd/writev.lo obj/ldso/dlstart.lo obj/ldso/dynlink.lo /home/soho/code/bn68/iplatform/board/model_mtk_mt798x/sdk/mtk798x/openwrt-26.0x/staging_dir/toolchain-aarch64_cortex-a53_gcc-14.3.0_musl/lib/gcc/aarch64-openwrt-linux-musl/14.3.0/libgcc.a /home/soho/code/bn68/iplatform/board/model_mtk_mt798x/sdk/mtk798x/openwrt-26.0x/staging_dir/toolchain-aarch64_cortex-a53_gcc-14.3.0_musl/lib/gcc/aarch64-openwrt-linux-musl/14.3.0/../../../../aarch64-openwrt-linux-musl/bin/ld:built in linker script:95: syntax error collect2: error: ld returned 1 exit status Makefile:164: recipe for target 'lib/libc.so' failed make[5]: *** [lib/libc.so] Error 1
最新发布
01-06
static int build_isp_bin() { char name_buf[1024] = { 0 }; char* isp_buf = calloc(1024 * 1024 * 5, 1); char* tmp_p = isp_buf; char default_isp_name[DEFAULT_ISP_NAME_LEN] = { 0 }; int ext_fw_file_len = 0, ret = 0, i = 0; int isp_all_len = 0; int isp_valid_len = 0; get_partition_size(target_isp_partition, &isp_all_len, &isp_valid_len); if (isp_buf == NULL) return -1; memcpy(gBlockIspHeader.magicNumber, blockHdrMagicNumber, BLOCK_MAGIC_NUMBER_LEN); gBlockIspHeader.num = htons(gBlockIspHeader.num); memcpy(isp_buf, &gBlockIspHeader, sizeof(BLOCK_NEW_HEADER)); isp_buf += sizeof(BLOCK_NEW_HEADER); for (i = 0; i < gExtFwBlockNum; i++) { if (gExtFwBlock[i].add && gExtFwBlock[i].blockType == DEFINE_EX_PACK(CONTENT_TYPE_ISP_CONFIG)) { ret = packExtFw(&gExtFwBlock[i], isp_buf, bin_extfw_path); if (ret) { ERR("packExtFw is not good"); goto out_free_buf; } /* upboot 的 extFw 头部和文件长度累加,需要使用文件对齐后的长度 */ ext_fw_file_len += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); isp_buf += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); } else continue; } snprintf(name_buf, sizeof(name_buf), "%s/build_fw_dir/isp_block.bin", bin_extfw_path); writeToBinFile(isp_buf - ext_fw_file_len - sizeof(BLOCK_NEW_HEADER), ext_fw_file_len + sizeof(BLOCK_NEW_HEADER), name_buf); isp_buf = tmp_p; for (i = 0; i < gExtFwBlockNum; i++) { /* 将 default extFw 写入 radio 分区,即往 flash.bin 写入 default isp_config 固件共板时会有多个flash.bin,对应不同的default isp_config*/ if (0 == strncasecmp(gExtFwBlock[i].deviceName, DEFAULT_EXT_FW_NAME, strlen(DEFAULT_EXT_FW_NAME)) && gExtFwBlock[i].blockType == DEFINE_EX_PACK(CONTENT_TYPE_ISP_CONFIG)) { printf("write default isp\n"); if (sizeof(EXT_FW_HEADER) + gExtFwBlock[i].fileInfo.fileSize > isp_all_len) { DBG("isp sector is not enough to write isp file [size 0x%lx]", sizeof(EXT_FW_HEADER) + gExtFwBlock[i].fileInfo.fileSize); ret = -1; goto out_free_buf; } ret = packExtFw(&gExtFwBlock[i], isp_buf, bin_extfw_path); if (ret) { ERR("packExtFw default not good"); goto out_free_buf; } #ifdef FIRMWARE_SUPPORT_MULTI_PRODUCT_BY_SENSOR snprintf(default_isp_name, sizeof(default_isp_name), "%s_isp.bin", gExtFwBlock[i].deviceName); update_fw_multi_name(gExtFwBlock[i].default_isp_name); #else snprintf(default_isp_name, sizeof(default_isp_name), "isp.bin"); #endif isp_buf += gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER); snprintf(name_buf, sizeof(name_buf), "%s/build_fw_dir/%s", bin_extfw_path, default_isp_name); writeToBinFile(isp_buf - gExtFwBlock[i].fileInfo.fileSize - sizeof(EXT_FW_HEADER), gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), name_buf); } } out_free_buf: free(tmp_p); return ret; } static int build_mcu_bin() { char name_buf[1024] = { 0 }; char* mcu_buf = calloc(1024 * 1024, 1); char* tmp_p = mcu_buf; int ext_fw_file_len = 0, ret = 0, i = 0; if (mcu_buf == NULL) return -1; memcpy(gBlockMcuHeader.magicNumber, blockHdrMagicNumber, BLOCK_MAGIC_NUMBER_LEN); gBlockMcuHeader.num = htons(gBlockMcuHeader.num); memcpy(mcu_buf, &gBlockMcuHeader, sizeof(BLOCK_NEW_HEADER)); mcu_buf += sizeof(BLOCK_NEW_HEADER); for (i = 0; i < gExtFwBlockNum; i++) { if (gExtFwBlock[i].add && gExtFwBlock[i].blockType == DEFINE_EX_PACK(CONTENT_TYPE_MCU_CONFIG)) { ret = packExtFw(&gExtFwBlock[i], mcu_buf, bin_extfw_path); if (ret) { ERR("packExtFw is not good"); goto out_free_buf; } /* upboot 的 extFw 头部和文件长度累加,需要使用文件对齐后的长度 */ ext_fw_file_len += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); mcu_buf += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); } else continue; } snprintf(name_buf, sizeof(name_buf), "%s/build_fw_dir/mcu_block.bin", bin_extfw_path); if (ext_fw_file_len > 0) writeToBinFile(mcu_buf - ext_fw_file_len - sizeof(BLOCK_NEW_HEADER), ext_fw_file_len + sizeof(BLOCK_NEW_HEADER), name_buf); out_free_buf: free(tmp_p); return ret; } static int build_lte_bin() { int ext_fw_file_len = 0, ret = 0, i = 0; char* lte_buf = calloc(1024 * 1024 * 80, 1); char name_buf[1024] = { 0 }; if (lte_buf == NULL) return -1; memcpy(gBlockLteHeader.magicNumber, blockHdrMagicNumber, BLOCK_MAGIC_NUMBER_LEN); gBlockLteHeader.num = htons(gBlockLteHeader.num); memcpy(lte_buf, &gBlockLteHeader, sizeof(BLOCK_NEW_HEADER)); lte_buf += sizeof(BLOCK_NEW_HEADER); for (i = 0; i < gExtFwBlockNum; i++) { if (gExtFwBlock[i].add && gExtFwBlock[i].blockType == DEFINE_EX_PACK(CONTENT_TYPE_LTE_CONFIG)) { ret = packExtFw(&gExtFwBlock[i], lte_buf, bin_extfw_path); if (ret) { ERR("packExtFw is not good"); goto out_free_buf; } /* upboot 的 extFw 头部和文件长度累加,需要使用文件对齐后的长度 */ #ifndef LTE_FW_QF_UPGRAD ext_fw_file_len += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); lte_buf += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER), 4); #else ext_fw_file_len += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER) + lte_ext_fw_header_expend_len, 4); lte_buf += ALIGN(gExtFwBlock[i].fileInfo.fileSize + sizeof(EXT_FW_HEADER) + lte_ext_fw_header_expend_len, 4); #endif } else continue; } snprintf(name_buf, sizeof(name_buf), "%s/build_fw_dir/lte_block.bin", bin_extfw_path); if (ext_fw_file_len > 0) { writeToBinFile(lte_buf - ext_fw_file_len - sizeof(BLOCK_NEW_HEADER), ext_fw_file_len + sizeof(BLOCK_NEW_HEADER), name_buf); } out_free_buf: free(lte_buf - ext_fw_file_len - sizeof(BLOCK_NEW_HEADER)); return ret; } 分析这三个函数的作用
10-15
该模块目前仅支持WS-UsernameToken认证,现在我要新增digest认证,目前已做的修改如下(onvif_proc_data_srv函数只修改了一半),请你补全剩下的修改(包括onvif_proc_data_srv函数以及其他需要修改的地方) #### 流程梳理 - 初始化认证状态:`digest_authenticated`=0,`wss_authenticated`=0。 - 检查Digest凭据: - 如果有,验证,成功则`digest_authenticated`=1;失败则返回401。 - 如果没有,继续。 - 解析SOAP消息(如果前面返回了,就无需解析)。 - 在解析SOAP之后,检查SOAP头中是否有`WSS`凭据: - 如果有,进行`WSS`验证(调用原有的`soap_usernametoken_auth`等函数): 成功:`wss_authenticated`=1 失败:构造`SOAP Fault`,设置上下文返回类型为`SOAP_FAULT`,然后返回错误。 - 如果没有,`wss_authenticated`保持0。 - 检查是否至少有一个认证通过:if (`digest_authenticated` || `wss_authenticated`) - 如果是,则继续后续处理(调用`soap_serve_request`)。 - 否则,返回401(带`WWW-Authenticate`头)。 **认证组合测试**: | 测试用例 | 预期结果 | | ------------------------ | -------------- | | 有效`Digest` + 无`WSS` | 200 OK | | 有效`Digest` + 有`效WSS` | 200 OK | | 有效`Digest` + 无效`WSS` | 400/SOAP Fault | | 无效`Digest` + 有效`WSS` | 401 | | 无效`Digest` + 无效`WSS` | 401 | | 无`Digest` + 有效`WSS` | 200 OK | | 无`Digest` + 无效`WSS` | 400/SOAP Fault | | 无`Digest` + 无`WSS` | 401 | #### 修改步骤 - 修改CONTEXT结构体,增加一些字段来存储Digest认证相关的信息。 - 对`http_parse.c`中解析HTTP头部的函数,增加对Authorization头的解析 - 实现Digest认证验证函数 - 生成nonce和管理nonce,比如设置nonce的过期时间,防止重放攻击 - 修改`onvif_proc_data_srv`函数(`onvif_srv.c`),在解析SOAP之前,先检查是否有Digest认证头并进行验证。 - 在401响应的HTTP报头添加`WWW-Authenticate`头。 #### HTTP解析流程 在`http_parser.c`中,HTTP报文的解析主要由`http_parser()`函数完成。该函数通过以下步骤将报文内容读入CONTEXT结构体: ##### 1. 初始化CONTEXT结构体 - 分配头部缓冲区(`context->head_buf`),大小为`HTTP_HEAD_BUF_SIZE`。 - 初始化CONTEXT中的各个字段,包括`head_end`(指向缓冲区当前写入位置)、`hbuf_data_end`(指向已接收数据的末尾)等。 - 设置套接字为非阻塞模式。 ##### 2. 解析HTTP头部 - 调用`http_parse_header(context)`函数解析HTTP头部。 - 读取请求行(第一行):调用`http_read_line`读取一行,然后通过`http_parse_method`解析HTTP方法(GET/POST等),`http_parse_url`解析URL(包括路径和查询参数),`http_parse_version`解析HTTP版本。 - 解析请求头字段:循环调用`http_read_line`读取每一行,直到遇到空行(表示头部结束)。每行按`key: value`格式解析,通过`http_parse_key`函数处理。该函数会调用注册的关键字解析器(如`http_parse_host`、`http_parse_content_type`等)将对应的值存入CONTEXT的字段中。 - 例如,Host字段的值会存入`context->host`。 ##### 3. 解析HTTP内容(Body) - 如果有内容(如POST请求),根据`Content-Length`或`Transfer-Encoding`处理: - 对于普通POST请求,调用`http_read_content`函数读取内容到`context->content_buf`。 - 对于文件上传(`multipart/form-data`),会处理`boundary`,并调整内容指针。 - 读取的内容会被存入`context->content_buf`,长度由`context->content_len`记录。 ##### 4. 后续处理 - 根据解析出的URL路径,确定服务组(如`ONVIF`或`HTTPD`),并调用对应的`data_srv`函数进行处理。 - 处理结果会被放入响应缓冲区,通过`http_make_response`或`http_make_file_response`发送。 #### **步骤一:修改CONTEXT结构体(httpd.h)** 在CONTEXT结构体中增加Digest认证相关的字段: ```c #define LEN_USERNAME 256 #define LEN_REALM 256 #define LEN_DIGEST_NONCE 256 #define LEN_URI 256 #define LEN_RESPONSE 256 #define LEN_ALGORITHM 64 #define LEN_QOP 64 #define LEN_NC 32 #define LEN_CNONCE 64 #define LEN_OPAQUE 256 typedef struct _CONTEXT { /* 现有字段... */ /* 新增Digest认证相关字段 */ BOOL digest_authenticated; /* Digest认证是否通过 */ BOOL wss_authenticated; /* Digest认证是否通过 */ char digest_username[LEN_USERNAME]; /* Digest认证用户名 */ char digest_realm[LEN_REALM]; /* Digest认证域 */ char digest_nonce[LEN_DIGEST_NONCE]; /* 服务器生成的nonce */ char digest_uri[LEN_URI]; /* 请求的URI */ char digest_response[LEN_RESPONSE]; /* 客户端计算的响应值 */ char digest_algorithm[LEN_ALGORITHM];/* 算法类型 */ char digest_qop[LEN_QOP]; /* 保护质量 */ char digest_nc[LEN_NC]; /* 随机数计数器 */ char digest_cnonce[LEN_CNONCE]; /* 客户端随机数 */ char digest_opaque[LEN_OPAQUE]; /* 服务器不透明数据 */ /* 其他现有字段... */ } CONTEXT; ``` #### 步骤二:解析Authorization头(`http_parser.c`) **添加Authorization头解析器** 在`http_parser_init()`函数中添加: ```c void http_parser_init() { /* 现有初始化代码... */ /* 添加Authorization头解析器 */ http_key_parser_add("Authorization", http_parse_authorization); /* ... */ } ``` **实现Authorization头解析函数** 参考`http`头格式: ```c GET/cgi-bin/checkout?a=b HTTP/1.1 Authorization: Digest username="Mufasa", realm="realm", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c0", uri="/xxxx/System/Register", response="6629fae49393a05397450978507c4ef1", algorithm=MD5, qop=auth, nc=00000001, cnonce="0a4f113b", /* opaque="5ccc069c403ebaf9f0171e9517f40e41" */ ``` 辅助函数:`trim_whitespace` - 去除键前后的空格,避免因空格导致匹配失败。 - 十六进制字符转数值 ```c /* 移除字符串两端的空格 */ void trim_whitespace(char *str) { char *end; /* 去除前导空格 */ while (isspace((unsigned char)*str)) str++; /* 全空格字符串处理 */ if (*str == 0) return; /* 去除尾部空格 */ end = str + strlen(str) - 1; while (end > str && isspace((unsigned char)*end)) end--; *(end + 1) = '\0'; } /* 十六进制字符转数值 */ int hex_val(char c) { return isdigit(c) ? c - '0' : tolower(c) - 'a' + 10; } ``` **`http_parse_authorization`:** 该函数假设各参数之间使用逗号分隔,且参数值中不包含逗号。 ```c LOCAL S32 http_parse_authorization(CONTEXT *context, char *value) { char *parse_ptr = value; char *token; int error_count = 0; /* 检查Digest认证类型 */ if (strncasecmp(parse_ptr, "Digest ", 7) != 0) { return OK; } parse_ptr += 7; /* 跳过前缀 */ char *saveptr; /* strtok_r上下文指针 */ token = strtok_r(parse_ptr, ",", &saveptr); while (token != NULL) { /* 分割键值对 */ char *eq = strchr(token, '='); if (!eq) { HTTPD_DEBUG("Invalid param format: %s", token); error_count++; token = strtok_r(NULL, ",", &saveptr); continue; } /* 分割键值 */ *eq = '\0'; char *key = token; char *val = eq + 1; /* 移除键值两端的空格 */ trim_whitespace(key); trim_whitespace(val); /* 处理引号包裹的值 */ size_t vlen = strlen(val); if (vlen >= 2 && val[0] == '"' && val[vlen-1] == '"') { val[vlen-1] = '\0'; /* 移除尾部引号 */ memmove(val, val+1, vlen-1); /* 移除头部引号 */ vlen -= 2; /* 更新长度 */ } /* 存储到CONTEXT字段 */ if (strcasecmp(key, "username") == 0) { strncpy(context->digest_username, val, LEN_USERNAME-1); } else if (strcasecmp(key, "realm") == 0) { strncpy(context->digest_realm, val, LEN_REALM-1); } else if (strcasecmp(key, "nonce") == 0) { strncpy(context->digest_nonce, val, LEN_DIGEST_NONCE-1); } else if (strcasecmp(key, "uri") == 0) { /* 规范化URI路径(移除查询参数)*/ char *query_start = strchr(val, '?'); if (query_start) *query_start = '\0'; strncpy(context->digest_uri, val, LEN_URI-1); } else if (strcasecmp(key, "response") == 0) { strncpy(context->digest_response, val, LEN_RESPONSE-1); } else if (strcasecmp(key, "algorithm") == 0) { strncpy(context->digest_algorithm, val, LEN_ALGORITHM-1); } else if (strcasecmp(key, "qop") == 0) { strncpy(context->digest_qop, val, LEN_QOP-1); } else if (strcasecmp(key, "nc") == 0) { strncpy(context->digest_nc, val, LEN_NC-1); } else if (strcasecmp(key, "cnonce") == 0) { strncpy(context->digest_cnonce, val, LEN_CNONCE-1); } else if (strcasecmp(key, "opaque") == 0) { strncpy(context->digest_opaque, val, LEN_OPAQUE-1); } else { HTTPD_DEBUG("Unknown Digest param: %s=%s", key, val); } token = strtok_r(NULL, ",", &saveptr); } /* 检查必需参数是否齐全 */ if (strlen(context->digest_response) == 0) { HTTPD_WARNING("Missing required response field"); return ERROR; } return (error_count > 3) ? ERROR : OK; } ``` #### 步骤三:生成响应Authorization头 `onvif_srv.c`文件,`onvif_make_response(CONTEXT *context)`函数会在状态码非200时调用`http_make_response()`函数发送HTTP错误响应。 ```c #define HTTP_UNAUTHORIZED 401 LOCAL S32 onvif_make_response(CONTEXT *context) { /* 其他字段... */ if (context->code == HTTP_REQ_OK) { if (soap->use_udp == FALSE && soap->xml_buf.start != NULL && soap->xml_buf.start != soap->xml_buf.last) { ONVIF_TRACE("Onvif_make_response return onvif_send_http_rsp_packet."); ret = onvif_send_http_rsp_packet(soap); goto out; } else { ONVIF_TRACE("Onvif_make_response return OK."); ret = OK; goto out; } } ONVIF_TRACE("Onvif_make_response return http_make_response."); ret = http_make_response(context); out: /* 清除content内容 */ http_reset_context(context); return ret; } ``` 在`http_make_response()`函数中,通过`http_send_rsp_header()`设置HTTP响应报文头部。因此,需要修改`http_send_rsp_header()`函数,使其能够在HTTP状态码为401时添加`WWW-Authenticate`头部。 ```c /* Location */ if (HTTP_MOVE_TEMPORARILY == context->code) { // ...原有Location代码... } /* ========== 新增Digest认证头 ========== */ if (HTTP_UNAUTHORIZED == context->code) { /* 必需字段: realm, nonce, qop */ context->digest_realm = “Restricted Area”; /* 生成带时效的nonce */ if (generate_digest_nonce(context) != OK) { return ERROR; } length = snprintf(context->head_end, (context->head_buf_end - context->head_end), "WWW-Authenticate: Digest realm=\"Restricted Area\", nonce=\"%s\", qop=\"auth\"", context->digest_nonce); /* 结束头部 */ length += snprintf(context->head_end + length, (context->head_buf_end - context->head_end - length), "\r\n"); context->head_end += length; context->header_len += length; } /* Access-Control-Allow-Origin */ if (context->origin == TRUE) { /* ...原有代码... */ } ``` #### 步骤四:nonce生成及过期管理: ```c #include <openssl/rand.h> #include <openssl/err.h> #include <time.h> #include <string.h> #define ERROR_CRYPTO_FAIL -1 #define ERROR_BUFFER_OVERFLOW -2 #define OK 0 S32 generate_digest_nonce(CONTEXT *context) { /* 数据源:时间戳+随机数 */ struct { time_t timestamp; /* 精确到秒的时间戳 */ time_t expiration_time; /* 过期时间 */ unsigned char rand_bytes[16]; /* 强随机数 */ } nonce_seed; /* 取当前时间戳 */ nonce_seed.timestamp = time(NULL); nonce_seed.expiration_time = nonce_seed.timestamp + NONCE_LIFETIME; /* 过期时间 */ /* 生成密码学强随机数 (使用OpenSSL RAND_bytes) */ if (RAND_bytes(nonce_seed.rand_bytes, sizeof(nonce_seed.rand_bytes)) != 1) { return ERROR_CRYPTO_FAIL; /* 随机数生成失败 */ } /* 转为十六进制字符串格式 */ char hex_buffer[2 * sizeof(nonce_seed) + 1]; const unsigned char *ptr = (const unsigned char *)&nonce_seed; for (size_t i = 0; i < sizeof(nonce_seed); i++) { snprintf(hex_buffer + 2*i, 3, "%02x", ptr[i]); } hex_buffer[2 * sizeof(nonce_seed)] = '\0'; /* 组合realm和hex_buffer生成nonce:realm:hex_buffer" */ int len = snprintf(context->digest_nonce, LEN_DIGEST_NONCE, "%s:%s", context->digest_realm, hex_buffer); if (len < 0 || len >= LEN_DIGEST_NONCE) { return ERROR_BUFFER_OVERFLOW; } return OK; } /* NONCE验证函数(应在认证流程中调用) */ int validate_nonce(const char *nonce_str) { /* 提取时间结构体部分(跳过realm前缀) */ const char *hex_seed = strchr(nonce_str, ':') + 1; size_t seed_len = strlen(hex_seed)/2; /* 将HEX转回二进制结构 */ struct { time_t timestamp; time_t expiration_time; unsigned char rand_bytes[16]; } seed; for (size_t i = 0; i < seed_len; i++) { sscanf(hex_seed + 2*i, "%2hhx", (unsigned char*)&seed + i); } /* 过期判断 */ time_t current_time = time(NULL); if (current_time > seed.expiration_time) { return 0; /* 过期 */ } return 1; /* 有效 */ } ``` #### 步骤五:修改`onvif_proc_data_srv`函数(`onvif_srv.c`)(待修改) 在`onvif_proc_data_srv`函数中,在解析SOAP之前,先检查是否有Digest认证头,并进行验证。 ```c S32 onvif_proc_data_srv(CONTEXT *context) { /* 现有代码... */ /* 在解析SOAP之前添加Digest认证检查 */ context->digest_authenticated = FALSE; /* 检查是否有Digest认证头 */ if (context->digest_username[0] != '\0') { /* 执行Digest认证 */ if (check_digest_auth(context) == OK) { context->digest_authenticated = TRUE; ONVIF_TRACE("Digest authentication successful"); } else { ONVIF_TRACE("Digest authentication failed"); /* 认证失败,返回401 */ context->code = HTTP_UNAUTHORIZED; return ERROR; } } /* 检查是否至少有一个认证通过 */ if (!context->digest_authenticated && !soap->wss_authenticated) { /* 没有提供任何认证凭据,返回401 */ context->code = HTTP_UNAUTHORIZED; return ERROR; } /* 继续原有处理逻辑... */ ``` #### 步骤六:实现Digest认证验证函数 实现一个函数,用于验证Digest认证的响应是否正确。 ```c S32 check_digest_auth(CONTEXT *context) { if (!context) return -1; /* 验证必要参数存在 */ if (strlen(context->digest_username) == 0 || strlen(context->digest_realm) == 0 || strlen(context->digest_nonce) == 0 || strlen(context->digest_uri) == 0 || strlen(context->digest_response) == 0) { ONVIF_WARN("Missing required Digest auth parameters"); return -1; } /* 获取用户对应的密码 */ char stored_pwd[USER_MANAGEMENT_PASSWD_MAX_STR_LEN + 1] = {0}; if (strcmp(context->digest_username, TP_ROOT_USER) == 0) { /* 管理员账户 */ char *plain_pwd = tpssl_rsa_decrypt(PRI_KEY_FILE_PATH, (U8 *)TP_DEFAULT_PSWD, (U32)strlen(TP_DEFAULT_PSWD)); if (!plain_pwd) return -1; strncpy(stored_pwd, plain_pwd, sizeof(stored_pwd)-1); ONVIF_FREE(plain_pwd); } else { /* 第三方账户 */ THIRD_ACCOUNT_USER_MANAGEMENT third_acct; if (0 == ds_read(THIRD_ACCOUNT_PATH, &third_acct, sizeof(third_acct))) { char *plain_pwd = tpssl_rsa_decrypt(PRI_KEY_FILE_PATH, (U8 *)third_acct.ciphertext, (U32)strlen(third_acct.ciphertext)); if (!plain_pwd) return -1; strncpy(stored_pwd, plain_pwd, sizeof(stored_pwd)-1); ONVIF_FREE(plain_pwd); } else { return -1; } } /* 计算HA1 = MD5(username:realm:password) */ char ha1_input[256]; snprintf(ha1_input, sizeof(ha1_input), "%s:%s:%s", context->digest_username, context->digest_realm, stored_pwd); char ha1[33]; tpssl_md5_hex(ha1_input, ha1); memset(stored_pwd, 0, sizeof(stored_pwd)); /* 立即清除密码 */ /* 计算HA2 = MD5(method:uri) */ char ha2_input[256]; snprintf(ha2_input, sizeof(ha2_input), "%s:%s", http_method_str(context->method), context->digest_uri); char ha2[33]; tpssl_md5_hex(ha2_input, ha2); /* 计算预期响应 = MD5(HA1:nonce:nc:cnonce:qop:HA2) */ char resp_input[512]; snprintf(resp_input, sizeof(resp_input), "%s:%s:%s:%s:%s:%s", ha1, context->digest_nonce, context->digest_nc, context->digest_cnonce, context->digest_qop, ha2); char expected_resp[33]; tpssl_md5_hex(resp_input, expected_resp); /* 验证响应值 */ if (strcasecmp(expected_resp, context->digest_response) == 0) { ONVIF_TRACE("Digest auth success for user: %s", context->digest_username); return 0; /* 认证成功 */ } ONVIF_WARN("Digest auth failed. Expected: %s, Received: %s", expected_resp, context->digest_response); return -1; /* 认证失败 */ } #include <openssl/md5.h> /* 计算字符串的MD5哈希值(十六进制格式) */ void tpssl_md5_hex(const char *input, char *output) { if (!input || !output) return; unsigned char digest[MD5_DIGEST_LENGTH]; MD5_CTX context; MD5_Init(&context); MD5_Update(&context, input, strlen(input)); MD5_Final(digest, &context); for (int i = 0; i < MD5_DIGEST_LENGTH; i++) { sprintf(output + (i * 2), "%02x", digest[i]); } output[32] = '\0'; /* MD5总是32字符 */ } /* 将HTTP方法枚举转换为字符串 */ const char *http_method_str(HTTP_METHOD method) { switch(method) { case HTTP_GET: return "GET"; case HTTP_POST: return "POST"; case HTTP_PUT: return "PUT"; case HTTP_DELETE: return "DELETE"; default: return "UNKNOWN"; } } ```
09-13
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值