/**************************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020--2024 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.TPAX. */ /**************************************************************/ #include #include #include #include #include #include "tpax_driver_impl.h" static int tpax_backref_idx(const char c) { return ((c >= '1') && (c <= '9')) ? c - '0' : 0; } int tpax_util_path_replstr( char * dstpath, const char * srcpath, const char * replstr, const regex_t * regex, size_t buflen, int flags) { int ret; int idx; regoff_t ro; const char * ch; char * dst; size_t explen; regmatch_t pmatch[11]; /* attempt to match */ switch (regexec(regex,srcpath,11,pmatch,0)) { case 0: break; case REG_NOMATCH: return 0; default: return -1; } /* copy bytes leading up to match */ if (buflen <= (explen = pmatch[0].rm_so)) { errno = ENOBUFS; return -1; } for (ro=0,dst=dstpath; ro stands for the entire matched string */ if (ch[0] == '&') { idx = 0; /* back-reference semantics: a matched subexpression or an empty string */ } else if ((ch[0] == '\\') && (idx = tpax_backref_idx(ch[1]))) { if (pmatch[idx].rm_so < 0) idx = -1; ch++; /* all other escaped characters */ } else if (ch[0] == '\\') { *dst++ = *++ch; idx = -1; buflen--; /* all other characters */ } else { *dst++ = *ch; idx = -1; buflen--; } /* copy matched string or matched subexpression, if any */ if (idx >= 0) { if (buflen <= (explen = (pmatch[idx].rm_eo - pmatch[idx].rm_so))) { errno = ENOBUFS; return -1; } for (ro=pmatch[idx].rm_so; ro