static int rep_name(char *name, int *nlen, int prnt) { REPLACE *pt; char *inpt; char *outpt; char *endpt; char *rpt; int found = 0; int res; # ifndef NET2_REGEX regmatch_t pm[MAXSUBEXP]; # endif char nname[PAXPATHLEN+1]; /* final result of all replacements */ char buf1[PAXPATHLEN+1]; /* where we work on the name */ /* * copy the name into buf1, where we will work on it. We need to keep * the orig string around so we can print out the result of the final * replacement. We build up the final result in nname. inpt points at * the string we apply the regular expression to. prnt is used to * suppress printing when we handle replacements on the link field * (the user already saw that substitution go by) */ pt = rephead; (void)strcpy(buf1, name); inpt = buf1; outpt = nname; endpt = outpt + PAXPATHLEN; /* * try each replacement string in order */ while (pt != NULL) { do { /* * check for a successful substitution, if not go to * the next pattern, or cleanup if we were global */ # ifdef NET2_REGEX if (regexec(pt->rcmp, inpt) == 0) # else if (regexec(&(pt->rcmp), inpt, MAXSUBEXP, pm, 0) != 0) # endif break; /* * ok we found one. We have three parts, the prefix * which did not match, the section that did and the * tail (that also did not match). Copy the prefix to * the final output buffer (watching to make sure we * do not create a string too long). */ found = 1; # ifdef NET2_REGEX rpt = pt->rcmp->startp[0]; # else rpt = inpt + pm[0].rm_so; # endif while ((inpt < rpt) && (outpt < endpt)) *outpt++ = *inpt++; if (outpt == endpt) break; /* * for the second part (which matched the regular * expression) apply the substitution using the * replacement string and place it the prefix in the * final output. If we have problems, skip it. */ # ifdef NET2_REGEX if ((res = resub(pt->rcmp,pt->nstr,outpt,endpt)) < 0) { # else if ((res = resub(&(pt->rcmp),pm,pt->nstr,outpt,endpt)) < 0) { # endif if (prnt) paxwarn(1, "Replacement name error %s", name); return(1); } outpt += res; /* * we set up to look again starting at the first * character in the tail (of the input string right * after the last character matched by the regular * expression (inpt always points at the first char in * the string to process). If we are not doing a global * substitution, we will use inpt to copy the tail to * the final result. Make sure we do not overrun the * output buffer */ # ifdef NET2_REGEX inpt = pt->rcmp->endp[0]; # else inpt += pm[0].rm_eo - pm[0].rm_so; # endif if ((outpt == endpt) || (*inpt == '\0')) break; /* * if the user wants global we keep trying to * substitute until it fails, then we are done. */ } while (pt->flgs & GLOB); if (found) break; /* * a successful substitution did NOT occur, try the next one */ pt = pt->fow; } if (found) { /* * we had a substitution, copy the last tail piece (if there is * room) to the final result */ while ((outpt < endpt) && (*inpt != '\0')) *outpt++ = *inpt++; *outpt = '\0'; if ((outpt == endpt) && (*inpt != '\0')) { if (prnt) paxwarn(1,"Replacement name too long %s >> %s", name, nname); return(1); } /* * inform the user of the result if wanted */ if (prnt && (pt->flgs & PRNT)) { if (*nname == '\0') (void)fprintf(stderr,"%s >> <empty string>\n", name); else (void)fprintf(stderr,"%s >> %s\n", name, nname); } /* * if empty inform the caller this file is to be skipped * otherwise copy the new name over the orig name and return */ if (*nname == '\0') return(1); *nlen = l_strncpy(name, nname, PAXPATHLEN + 1); name[PAXPATHLEN] = '\0'; } return(0); } #ifdef NET2_REGEX /* * resub() * apply the replacement to the matched expression. expand out the old * style ed(1) subexpression expansion. * Return: * -1 if error, or the number of characters added to the destination. */ static int resub(regexp *prog, char *src, char *dest, char *destend) { char *spt; char *dpt; char c; int no; int len; spt = src; dpt = dest; while ((dpt < destend) && ((c = *spt++) != '\0')) { if (c == '&') no = 0; else if ((c == '\\') && (*spt >= '0') && (*spt <= '9')) no = *spt++ - '0'; else { if ((c == '\\') && ((*spt == '\\') || (*spt == '&'))) c = *spt++; *dpt++ = c; continue; } if ((prog->startp[no] == NULL) || (prog->endp[no] == NULL) || ((len = prog->endp[no] - prog->startp[no]) <= 0)) continue; /* * copy the subexpression to the destination. * fail if we run out of space or the match string is damaged */ if (len > (destend - dpt)) len = destend - dpt; if (l_strncpy(dpt, prog->startp[no], len) != len) return(-1); dpt += len; } return(dpt - dest); }
static int rep_name(char *name, size_t nsize, int *nlen, int prnt) { REPLACE *pt; char *inpt; char *outpt; char *endpt; char *rpt; int found = 0; int res; regmatch_t pm[MAXSUBEXP]; char nname[PAXPATHLEN+1]; /* final result of all replacements */ char buf1[PAXPATHLEN+1]; /* where we work on the name */ /* * copy the name into buf1, where we will work on it. We need to keep * the orig string around so we can print out the result of the final * replacement. We build up the final result in nname. inpt points at * the string we apply the regular expression to. prnt is used to * suppress printing when we handle replacements on the link field * (the user already saw that substitution go by) */ pt = rephead; (void)strlcpy(buf1, name, sizeof(buf1)); inpt = buf1; outpt = nname; endpt = outpt + PAXPATHLEN; /* * try each replacement string in order */ while (pt != NULL) { do { char *oinpt = inpt; /* * check for a successful substitution, if not go to * the next pattern, or cleanup if we were global */ if (regexec(&(pt->rcmp), inpt, MAXSUBEXP, pm, 0) != 0) break; /* * ok we found one. We have three parts, the prefix * which did not match, the section that did and the * tail (that also did not match). Copy the prefix to * the final output buffer (watching to make sure we * do not create a string too long). */ found = 1; rpt = inpt + pm[0].rm_so; while ((inpt < rpt) && (outpt < endpt)) *outpt++ = *inpt++; if (outpt == endpt) break; /* * for the second part (which matched the regular * expression) apply the substitution using the * replacement string and place it the prefix in the * final output. If we have problems, skip it. */ if ((res = resub(&(pt->rcmp),pm,pt->nstr,oinpt,outpt,endpt)) < 0) { if (prnt) paxwarn(1, "Replacement name error %s", name); return(1); } outpt += res; /* * we set up to look again starting at the first * character in the tail (of the input string right * after the last character matched by the regular * expression (inpt always points at the first char in * the string to process). If we are not doing a global * substitution, we will use inpt to copy the tail to * the final result. Make sure we do not overrun the * output buffer */ inpt += pm[0].rm_eo - pm[0].rm_so; if ((outpt == endpt) || (*inpt == '\0')) break; /* * if the user wants global we keep trying to * substitute until it fails, then we are done. */ } while (pt->flgs & GLOB); if (found) break; /* * a successful substitution did NOT occur, try the next one */ pt = pt->fow; } if (found) { /* * we had a substitution, copy the last tail piece (if there is * room) to the final result */ while ((outpt < endpt) && (*inpt != '\0')) *outpt++ = *inpt++; *outpt = '\0'; if ((outpt == endpt) && (*inpt != '\0')) { if (prnt) paxwarn(1,"Replacement name too long %s >> %s", name, nname); return(1); } /* * inform the user of the result if wanted */ if (prnt && (pt->flgs & PRNT)) { if (*nname == '\0') (void)fprintf(stderr,"%s >> <empty string>\n", name); else (void)fprintf(stderr,"%s >> %s\n", name, nname); } /* * if empty inform the caller this file is to be skipped * otherwise copy the new name over the orig name and return */ if (*nname == '\0') return(1); *nlen = strlcpy(name, nname, nsize); } return(0); }