Пример #1
0
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);
}
Пример #2
0
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);
}