blob: 70093667fa416950972b842495971c1091dde4f6 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * Regex and string management functions.
3 *
4 * Copyright 2000-2006 Willy Tarreau <w@1wt.eu>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <ctype.h>
14#include <stdlib.h>
15#include <string.h>
16
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020017#include <common/config.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020018#include <common/regex.h>
19#include <common/standard.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020020#include <proto/log.h>
21
22/* regex trash buffer used by various regex tests */
23regmatch_t pmatch[MAX_MATCH]; /* rm_so, rm_eo for regular expressions */
24
25
26
Willy Tarreaub17916e2006-10-15 15:17:57 +020027int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches)
Willy Tarreaubaaee002006-06-26 02:48:02 +020028{
29 char *old_dst = dst;
30
31 while (*str) {
32 if (*str == '\\') {
33 str++;
Willy Tarreau8f8e6452007-06-17 21:51:38 +020034 if (isdigit((unsigned char)*str)) {
Willy Tarreaubaaee002006-06-26 02:48:02 +020035 int len, num;
36
37 num = *str - '0';
38 str++;
39
40 if (matches[num].rm_eo > -1 && matches[num].rm_so > -1) {
41 len = matches[num].rm_eo - matches[num].rm_so;
42 memcpy(dst, src + matches[num].rm_so, len);
43 dst += len;
44 }
45
46 } else if (*str == 'x') {
47 unsigned char hex1, hex2;
48 str++;
49
50 hex1 = toupper(*str++) - '0';
51 hex2 = toupper(*str++) - '0';
52
53 if (hex1 > 9) hex1 -= 'A' - '9' - 1;
54 if (hex2 > 9) hex2 -= 'A' - '9' - 1;
55 *dst++ = (hex1<<4) + hex2;
56 } else {
57 *dst++ = *str++;
58 }
59 } else {
60 *dst++ = *str++;
61 }
62 }
63 *dst = '\0';
64 return dst - old_dst;
65}
66
67/* returns NULL if the replacement string <str> is valid, or the pointer to the first error */
Willy Tarreaub17916e2006-10-15 15:17:57 +020068const char *check_replace_string(const char *str)
Willy Tarreaubaaee002006-06-26 02:48:02 +020069{
Willy Tarreaub17916e2006-10-15 15:17:57 +020070 const char *err = NULL;
Willy Tarreaubaaee002006-06-26 02:48:02 +020071 while (*str) {
72 if (*str == '\\') {
73 err = str; /* in case of a backslash, we return the pointer to it */
74 str++;
75 if (!*str)
76 return err;
Willy Tarreau8f8e6452007-06-17 21:51:38 +020077 else if (isdigit((unsigned char)*str))
Willy Tarreaubaaee002006-06-26 02:48:02 +020078 err = NULL;
79 else if (*str == 'x') {
80 str++;
81 if (!ishex(*str))
82 return err;
83 str++;
84 if (!ishex(*str))
85 return err;
86 err = NULL;
87 }
88 else {
89 Warning("'\\%c' : deprecated use of a backslash before something not '\\','x' or a digit.\n", *str);
90 err = NULL;
91 }
92 }
93 str++;
94 }
95 return err;
96}
97
98
99/* returns the pointer to an error in the replacement string, or NULL if OK */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200100const char *chain_regex(struct hdr_exp **head, const regex_t *preg,
101 int action, const char *replace)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200102{
103 struct hdr_exp *exp;
104
105 if (replace != NULL) {
Willy Tarreaub17916e2006-10-15 15:17:57 +0200106 const char *err;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200107 err = check_replace_string(replace);
108 if (err)
109 return err;
110 }
111
112 while (*head != NULL)
113 head = &(*head)->next;
114
115 exp = calloc(1, sizeof(struct hdr_exp));
116
117 exp->preg = preg;
118 exp->replace = replace;
119 exp->action = action;
120 *head = exp;
121
122 return NULL;
123}
124
125
126
127/*
128 * Local variables:
129 * c-indent-level: 8
130 * c-basic-offset: 8
131 * End:
132 */