cvs commit: apache/src/regex Makefile
ben 96/07/28 03:32:19 Modified:src Configuration.tmpl Makefile.tmpl src/regex Makefile Log: Make ranlib work, when it doesn't (as it were). Clean up regex inheritance of Apache flags. Revision ChangesPath 1.22 +6 -0 apache/src/Configuration.tmpl Index: Configuration.tmpl === RCS file: /export/home/cvs/apache/src/Configuration.tmpl,v retrieving revision 1.21 retrieving revision 1.22 diff -C3 -r1.21 -r1.22 *** Configuration.tmpl1996/07/16 22:22:08 1.21 --- Configuration.tmpl1996/07/28 10:32:17 1.22 *** *** 75,80 --- 75,85 # -lndbm is commonly required for DBM auth, if that is configured in. EXTRA_LIBS= + # Default to using ranlib on libraries (for regex). Set this to something else + # if ranlib kills your system (usually by setting it again in the OS specific + # section below) + RANLIB=ranlib + # AUX_CFLAGS are system-specific control flags. # NOTE: IF YOU DO NOT CHOOSE ONE OF THESE, EDIT httpd.h AND CHOOSE # SETTINGS FOR THE SYSTEM FLAGS. IF YOU DON'T, BAD THINGS WILL HAPPEN. *** *** 120,125 --- 125,131 #AUX_CFLAGS= -DSCO5 #AUX_LIBS=-lsocket -lmalloc -lprot #BROKEN_BPRINTF_FLAGS=-K noinline + #RANLIB=true # For SVR4 # Some SVR4 implementations will require SO_LINGER option to be set in order # to guarantee buffer flushes. Dell, Esix, and UnixWare are a few of these. 1.17 +1 -1 apache/src/Makefile.tmpl Index: Makefile.tmpl === RCS file: /export/home/cvs/apache/src/Makefile.tmpl,v retrieving revision 1.16 retrieving revision 1.17 diff -C3 -r1.16 -r1.17 *** Makefile.tmpl 1996/07/27 23:00:49 1.16 --- Makefile.tmpl 1996/07/28 10:32:17 1.17 *** *** 25,31 $(CC) $(LFLAGS) $(AUX_LFLAGS) -o httpd $(OBJS) $(LIBS) $(EXTRA_LIBS) $(AUX_LIBS) regex/libregex.a: ! cd regex; make lib CC=$(CC) CFLAGS="$(CFLAGS) $(AUX_CFLAGS) -I. -DPOSIX_MISTAKE" clean: rm -f httpd $(OBJS) *pure* --- 25,31 $(CC) $(LFLAGS) $(AUX_LFLAGS) -o httpd $(OBJS) $(LIBS) $(EXTRA_LIBS) $(AUX_LIBS) regex/libregex.a: ! cd regex; make lib CC=$(CC) AUX_CFLAGS="$(CFLAGS) $(AUX_CFLAGS)" RANLIB=$(RANLIB) clean: rm -f httpd $(OBJS) *pure* 1.4 +2 -2 apache/src/regex/Makefile Index: Makefile === RCS file: /export/home/cvs/apache/src/regex/Makefile,v retrieving revision 1.3 retrieving revision 1.4 diff -C3 -r1.3 -r1.4 *** Makefile 1996/07/27 04:25:42 1.3 --- Makefile 1996/07/28 10:32:19 1.4 *** *** 6,12 # Put -Dconst= in for a pre-ANSI compiler. # Do not take -DPOSIX_MISTAKE out. # REGCFLAGS isn't important to you (it's for my use in some special contexts). ! CFLAGS=-I. -DPOSIX_MISTAKE # If you have a pre-ANSI compiler, put -o into MKHFLAGS. If you want # the Berkeley __P macro, put -b in. --- 6,12 # Put -Dconst= in for a pre-ANSI compiler. # Do not take -DPOSIX_MISTAKE out. # REGCFLAGS isn't important to you (it's for my use in some special contexts). ! CFLAGS=-I. -DPOSIX_MISTAKE $(AUX_CFLAGS) # If you have a pre-ANSI compiler, put -o into MKHFLAGS. If you want # the Berkeley __P macro, put -b in. *** *** 40,46 lib:purge $(OBJPRODN) rm -f libregex.a ar crv libregex.a $(OBJPRODN) ! ranlib libregex.a purge: rm -f *.o --- 40,46 lib:purge $(OBJPRODN) rm -f libregex.a ar crv libregex.a $(OBJPRODN) ! $(RANLIB) libregex.a purge: rm -f *.o
cvs commit: apache/src buff.c buff.h http_config.h http_core.c http_protocol.c http_protocol.h http_request.c httpd.h mod_actions.c mod_alias.c mod_cgi.c mod_include.c mod_negotiation.c mod_proxy.c util.c
akosut 96/07/28 12:27:58 Modified:src buff.c buff.h http_config.h http_core.c http_protocol.c http_protocol.h http_request.c httpd.h mod_actions.c mod_alias.c mod_cgi.c mod_include.c mod_negotiation.c mod_proxy.c util.c Log: Make Apache unconditionally compliant with all HTTP/1.1 features and requirements, as of draft -06. Revision ChangesPath 1.5 +40 -4 apache/src/buff.c Index: buff.c === RCS file: /export/home/cvs/apache/src/buff.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C3 -r1.4 -r1.5 *** buff.c1996/07/25 19:32:26 1.4 --- buff.c1996/07/28 19:27:41 1.5 *** *** 1,3 --- 1,4 + /* * Copyright (c) 1996 The Apache Group. All rights reserved. * *** *** 173,178 --- 174,193 } /* + * Set a flag on (1) or off (0). Currently, these flags work + * as a function of the bcwrite() function, so we make sure to + * flush before setting them one way or the other; otherwise + * writes could end up with the wrong flag. + */ + int bsetflag(BUFF *fb, int flag, int value) + { + bflush(fb); + if (value) fb->flags |= flag; + else fb->flags &= ~flag; + return value; + } + + /* * Read up to nbyte bytes into buf. * If fewer than byte bytes are currently available, then return those. * Returns 0 for EOF, -1 for error. *** *** 410,415 --- 425,451 } /* + * A hook to write() that deals with chunking. This is really a protocol- + * level issue, but we deal with it here because it's simpler; this is + * an interim solution pending a complete rewrite of all this stuff in + * 2.0, using something like sfio stacked disciplines or BSD's funopen(). + */ + int bcwrite(BUFF *fb, const void *buf, int nbyte) { + int r; + + if (fb->flags & B_CHUNK) { + char chunksize[16]; /* Big enough for practically anything */ + + sprintf(chunksize, "%x\015\012", nbyte); + write(fb->fd, chunksize, strlen(chunksize)); + } + r = write(fb->fd, buf, nbyte); + if ((r > 0) && (fb->flags & B_CHUNK)) + write(fb->fd, "\015\012", 2); + return r; + } + + /* * Write nbyte bytes. * Only returns fewer than nbyte if an error ocurred. * Returns -1 if no bytes were written before the error ocurred. *** *** 425,431 if (!(fb->flags & B_WR)) { /* unbuffered write */ ! do i = write(fb->fd, buf, nbyte); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) --- 461,467 if (!(fb->flags & B_WR)) { /* unbuffered write */ ! do i = bcwrite(fb, buf, nbyte); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) *** *** 458,464 } /* the buffer must be full */ ! do i = write(fb->fd, fb->outbase, fb->bufsiz); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) --- 494,500 } /* the buffer must be full */ ! do i = bcwrite(fb, fb->outbase, fb->bufsiz); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) *** *** 494,500 */ while (nbyte > fb->bufsiz) { ! do i = write(fb->fd, buf, nbyte); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) --- 530,536 */ while (nbyte > fb->bufsiz) { ! do i = bcwrite(fb, buf, nbyte); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) *** *** 540,546 { /* the buffer must be full */ j = fb->outcnt; ! do i = write(fb->fd, fb->outbase, fb->outcnt); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) --- 576,582 { /* the buffer must be full */ j = fb->outcnt; ! do i = bcwrite(fb, fb->outbase, fb->outcnt); while (i == -1 && errno == EINTR); if (i > 0) fb->bytes_sent += i; if (i == 0) 1.5 +5 -0 apache/src/buff.h Index: buff.h === RCS file: /export/home/cvs/apache/src/buff.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C3 -r1.4 -r1.5 *** buff.h1996/05/27 21:08:27 1.4 --- buff.h1996/07/28 19:27:42 1.5 *** *** 66,71 --- 66,73 /* A write erro
cvs commit: apache/src mod_cookies.c
akosut 96/07/28 12:34:57 Modified:src mod_cookies.c Log: Add CookieExpires and CookieEnable directives. Reviewed by: Brian Behlendorf, Rob Hartill, Jim Jagielski Revision ChangesPath 1.11 +130 -7apache/src/mod_cookies.c Index: mod_cookies.c === RCS file: /export/home/cvs/apache/src/mod_cookies.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C3 -r1.10 -r1.11 *** mod_cookies.c 1996/07/04 13:01:59 1.10 --- mod_cookies.c 1996/07/28 19:34:56 1.11 *** *** 96,101 --- 96,102 * code from mod_log_agent.c. * 24.5.96 MJC Improved documentation after receiving comments from users * 4.7.96 MJC Bug, "else" missing since February caused logging twice + * 19.7.96 AEK Added CookieExpires and CookieEnable directives */ #include "httpd.h" *** *** 109,116 --- 110,123 char *fname; int log_fd; int always; + time_t expires; } cookie_log_state; + /* Define this to allow post-2000 cookies. Cookies use two-digit dates, + * so it might be dicey. (Netscape does it correctly, but others may not) + */ + #define MILLENIAL_COOKIES + /* Make Cookie: Now we have to generate something that is going to be * pretty unique. We can base it on the pid, time, hostip */ *** *** 118,138 void make_cookie(request_rec *r) { struct timeval tv; char new_cookie[100]; /* blurgh */ char *dot; const char *rname = pstrdup(r->pool, ! get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME)); struct timezone tz = { 0 , 0 }; if ((dot = strchr(rname,'.'))) *dot='\0'; /* First bit of hostname */ gettimeofday(&tv, &tz); ! sprintf(new_cookie,"%s%s%d%ld%d; path=/", ! COOKIE_NAME, rname, ! (int)getpid(), ! (long)tv.tv_sec, (int)tv.tv_usec/1000 ); table_set(r->headers_out,"Set-Cookie",new_cookie); return; --- 125,177 void make_cookie(request_rec *r) { + cookie_log_state *cls = get_module_config (r->server->module_config, +&cookies_module); struct timeval tv; char new_cookie[100]; /* blurgh */ char *dot; const char *rname = pstrdup(r->pool, ! get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME)); struct timezone tz = { 0 , 0 }; if ((dot = strchr(rname,'.'))) *dot='\0'; /* First bit of hostname */ gettimeofday(&tv, &tz); ! ! if (cls->expires) { ! static const char *const days[7]= ! {"Sun","Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; ! struct tm *tms; ! time_t when = time(NULL) + cls->expires; ! ! #ifndef MILLENIAL_COOKIES ! /* Only two-digit date string, so we can't trust "00" or more. !* Therefore, we knock it all back to just before midnight on !* 1/1/2000 (which is 946684799) !*/ ! ! if (when > 946684799) ! when = 946684799; ! #endif ! tms = gmtime(&when); ! ! ! ! /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ ! sprintf(new_cookie, !"%s%s%d%ld%d; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", ! COOKIE_NAME, rname, (int)getpid(), ! (long)tv.tv_sec, (int)tv.tv_usec/1000, days[tms->tm_wday], ! tms->tm_mday, month_snames[tms->tm_mon], ! (tms->tm_year >= 100) ? tms->tm_year - 100 : tms->tm_year, ! tms->tm_hour, tms->tm_min, tms->tm_sec); ! } ! else ! sprintf(new_cookie,"%s%s%d%ld%d; path=/", ! COOKIE_NAME, rname, ! (int)getpid(), ! (long)tv.tv_sec, (int)tv.tv_usec/1000 ); table_set(r->headers_out,"Set-Cookie",new_cookie); return; *** *** 140,147 --- 179,190 int spot_cookie(request_rec *r) { + int *disable = (int *)get_module_config(r->per_dir_config, + &cookies_module); char *cookie; + if (*disable) return DECLINED; + if ((cookie = table_get (r->headers_in, "Cookie"))) if (strstr(cookie,COOKIE_NAME)) return DECLINED; /* Theres already a cookie, no new one */ *** *** 165,174 --- 208,228 cls->fname = ""; cls->log_fd = -1; + cls->expires = 0; return (void *)cls; } + void *make_cookie_dir (pool *p, char *d) { + return
cvs commit: apache/src http_core.c
akosut 96/07/28 12:35:51 Modified:src http_core.c Log: Add section. Reviewed by: Brian Behlendorf, Jim Jagielski Revision ChangesPath 1.26 +36 -0 apache/src/http_core.c Index: http_core.c === RCS file: /export/home/cvs/apache/src/http_core.c,v retrieving revision 1.25 retrieving revision 1.26 diff -C3 -r1.25 -r1.26 *** http_core.c 1996/07/28 19:27:43 1.25 --- http_core.c 1996/07/28 19:35:49 1.26 *** *** 65,70 --- 65,72 #include "util_md5.h" #include "scoreboard.h" + extern char *module_names[]; + /* Server core module... This module provides support for really basic * server operations, including options and commands which control the * operation of other modules. Consider this the bureaucracy module. *** *** 670,675 --- 672,709 return NULL; } + char *end_ifmod (cmd_parms *cmd, void *dummy) { + return NULL; + } + + char *start_ifmod (cmd_parms *cmd, void *dummy, char *arg) + { + char *endp = strrchr (arg, '>'); + char l[MAX_STRING_LEN]; + int i, not = (arg[0] == '!'); + int found = 0; + int nest = 1; + + if (endp) *endp = '\0'; + if (not) arg++; + + for (i=0; module_names[i]; i++) + if (!strcasecmp(arg, module_names[i])) + found++; + + if ((!not && found) || (not && !found)) + return NULL; + + while (nest && !(cfg_getline (l, MAX_STRING_LEN, cmd->infile))) { + if (!strncasecmp(l, "")) + nest--; + } + + return NULL; + } + /* httpd.conf commands... beginning with the business */ char *end_virthost_magic = " out of place"; *** *** 1014,1019 --- 1048,1055 { "KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, TAKE1, "Keep-Alive timeout duration (sec)"}, { "KeepAlive", set_keep_alive, NULL, RSRC_CONF, TAKE1, "Maximum Keep-Alive requests per connection (0 to disable)" }, { "IdentityCheck", set_idcheck, NULL, RSRC_CONF|ACCESS_CONF, FLAG, NULL }, + { "", end_ifmod, NULL, OR_ALL, NO_ARGS, NULL }, { "ContentDigest", set_content_md5, NULL, RSRC_CONF|ACCESS_CONF|OR_AUTHCFG, FLAG, "whether or not to send a Content-MD5 header with each request" }, { "CacheNegotiatedDocs", }, { "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1, NULL },
cvs commit: apache/src CHANGES mod_proxy.c
chuck 96/07/28 15:17:55 Modified:src CHANGES mod_proxy.c Log: Submitted by: Chuck Murcko added NoCache * directive to enable proper operation w/o caching changed #tmp to tmp in temp file template, for broken link/unlink changed Expire to Expires in cache_update() added $Id$ Revision ChangesPath 1.45 +14 -0 apache/src/CHANGES Index: CHANGES === RCS file: /export/home/cvs/apache/src/CHANGES,v retrieving revision 1.44 retrieving revision 1.45 diff -C3 -r1.44 -r1.45 *** CHANGES 1996/07/17 23:20:47 1.44 --- CHANGES 1996/07/28 22:17:49 1.45 *** *** 1,5 --- 1,19 Changes with Apache 1.2b1: + *) Changes to mod_proxy since 1.1beta: + tested w/SOCKS proxy for http + fixed IP address formation in host2addr() + fixed SIGALRM on big cache cleanup + fixed temp files #tmp not removed + changed PF_INET to AF_INET in socket() calls + installed CONNECT code from Troy Morrison <[EMAIL PROTECTED]> for testing + added NoCache config directive to disallow caching for selected hosts + added NoCache * directive to enable proper operation w/o caching + changed #tmp to tmp in temp file template, for broken link/unlink + changed Expire to Expires in cache_update() + added appropriate #defines for Next compile + added $Id: CHANGES,v 1.45 1996/07/28 22:17:49 chuck Exp $ for RCS/CVS [Chuck Murcko] + *) Fix ErrorDocument handling. When ErrorDocument failed it used to display filename instead of error message. [Paul Sutton] 1.35 +20 -13apache/src/mod_proxy.c Index: mod_proxy.c === RCS file: /export/home/cvs/apache/src/mod_proxy.c,v retrieving revision 1.34 retrieving revision 1.35 diff -C3 -r1.34 -r1.35 *** mod_proxy.c 1996/07/28 19:27:49 1.34 --- mod_proxy.c 1996/07/28 22:17:51 1.35 *** *** 51,56 --- 51,60 */ /* + * $Id: mod_proxy.c,v 1.35 1996/07/28 22:17:51 chuck Exp $ + */ + + /* Note that the Explain() stuff is not yet complete. Also note numerous FIXMEs and CHECKMEs which should be eliminated. *** *** 71,87 Ben Laurie <[EMAIL PROTECTED]> 30 Mar 96 ! More changes: ! 0) tested w/SOCKS proxy for http ! 1) fixed IP address formation in host2addr() ! 2) fixed SIGALRM on big cache cleanup ! 3) fixed temp files #tmp not removed ! 4) changed PF_INET to AF_INET in socket() calls ! 5) installed CONNECT code from Troy Morrison <[EMAIL PROTECTED]> for testing ! 6) added NoCache config directive to disallow caching for selected hosts ! Chuck Murcko <[EMAIL PROTECTED]> 2 Jun 96 */ --- 75,93 Ben Laurie <[EMAIL PROTECTED]> 30 Mar 96 ! More things to do: ! ! 0. Massive code cleanup & break into multiple files; link as a lib ! ! 1. Check date routines ! ! 2. Get ftp working, add PASV mode ! ! 3. Add gopher & WAIS ! 4. Various other fixups to insure no NULL strings parsed, etc. ! Chuck Murcko <[EMAIL PROTECTED]> 28 Jul 96 */ *** *** 1413,1419 sprintf(filename, "%s%s", cachedir, ent->d_name); Explain1("GC Examining file %s",filename); /* is it a temporary file? */ ! if (strncmp(ent->d_name, "#tmp", 4) == 0) { /* then stat it to see how old it is; delete temporary files > 1 day old */ if (stat(filename, &buf) == -1) --- 1419,1425 sprintf(filename, "%s%s", cachedir, ent->d_name); Explain1("GC Examining file %s",filename); /* is it a temporary file? */ ! if (strncmp(ent->d_name, "tmp", 3) == 0) { /* then stat it to see how old it is; delete temporary files > 1 day old */ if (stat(filename, &buf) == -1) *** *** 1783,1789 /* read expiry date; if a bad date, then leave it so the client can * read it */ ! expire = get_header(resp_hdrs, "Expire"); if (expire != NULL) expc = parsedate(expire->value, NULL); else expc = -1; --- 1789,1795 /* read expiry date; if a bad date, then leave it so the client can * read it */ ! expire = get_header(resp_hdrs, "Expires"); if (expire != NULL) expc = parsedate(expire->value, NULL); else expc = -1; *** *** 1974,1980 buff[35] = ' '; /* open temporary file */ ! #define TMPFILESTR "/#tmpXX" c->tempfile=palloc(r->pool,strlen(conf->cache.root)+sizeof TMPFILESTR-1); strcpy(c->tempfile,conf->cache.root); /* --- 1980,1986 buff[35] = ' '; /* open temporary
cvs commit: apache/src mod_negotiation.c
chuck 96/07/28 15:40:56 Modified:src mod_negotiation.c Log: Reviewed by: Chuck Murcko Submitted by: Ralf S. Engelschall Prevent conflicts when ProxyRemote is in use Revision ChangesPath 1.11 +3 -0 apache/src/mod_negotiation.c Index: mod_negotiation.c === RCS file: /export/home/cvs/apache/src/mod_negotiation.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C3 -r1.10 -r1.11 *** mod_negotiation.c 1996/07/28 19:27:49 1.10 --- mod_negotiation.c 1996/07/28 22:40:55 1.11 *** *** 593,598 --- 593,601 if (!(filp = strrchr (r->filename, '/'))) return DECLINED; /* Weird... */ + if (strncmp(r->filename, "proxy:", 6) == 0) + return DECLINED; + ++filp; prefix_len = strlen (filp);
cvs commit: apache/src httpd.h util.c
akosut 96/07/28 19:32:36 Modified:src httpd.h util.c Log: Add pregsub() function, for use with regex. Revision ChangesPath 1.41 +3 -0 apache/src/httpd.h Index: httpd.h === RCS file: /export/home/cvs/apache/src/httpd.h,v retrieving revision 1.40 retrieving revision 1.41 diff -C3 -r1.40 -r1.41 *** httpd.h 1996/07/28 19:27:46 1.40 --- httpd.h 1996/07/29 02:32:33 1.41 *** *** 562,567 --- 562,570 int strcasecmp_match(char *str, char *exp); char *uudecode (pool *, char *); + char *pregsub(pool *p, const char *input, const char *source, + size_t nmatch, regmatch_t pmatch[]); + void str_tolower (char *); int ind (const char *, char); /* Sigh... */ int rind (const char *, char); 1.15 +78 -0 apache/src/util.c Index: util.c === RCS file: /export/home/cvs/apache/src/util.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C3 -r1.14 -r1.15 *** util.c1996/07/28 19:27:50 1.14 --- util.c1996/07/29 02:32:34 1.15 *** *** 227,232 --- 227,310 return 0; } + /* This function substitues for $0-$9, filling in regular expression + * submatches. Pass it the same nmatch and pmatch arguments that you + * passed regexec(). pmatch should not be greater than the maximum number + * of subexpressions - i.e. one more than the re_nsub member of regex_t. + * + * input should be the string with the $-expressions, source should be the + * string that was matched against. + * + * It returns the substituted string, or NULL on error. + * + * Parts of this code are based on Henry Spencer's regsub(), from his + * AT&T V8 regexp package. + */ + + char *pregsub(pool *p, const char *input, const char *source, + size_t nmatch, regmatch_t pmatch[]) { + const char *src = input; + char *dest, *dst; + char c; + int no, len; + + if (!source) return NULL; + if (!nmatch) return pstrdup(p, src); + + /* First pass, find the size */ + + len = 0; + + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '$' && isdigit(*src)) + no = *src++ - '0'; + else + no = -1; + + if (no < 0) { /* Ordinary character. */ + if (c == '\\' && (*src == '$' || *src == '&')) + c = *src++; + len++; + } else if (no <= nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { + len += pmatch[no].rm_eo - pmatch[no].rm_so; + } + + } + + dest = dst = pcalloc(p, len + 1); + + /* Now actually fill in the string */ + + src = input; + + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '$' && isdigit(*src)) + no = *src++ - '0'; + else + no = -1; + + if (no < 0) { /* Ordinary character. */ + if (c == '\\' && (*src == '$' || *src == '&')) + c = *src++; + *dst++ = c; + } else if (no <= nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { + len = pmatch[no].rm_eo - pmatch[no].rm_so; + strncpy(dst, source + pmatch[no].rm_so, len); + dst += len; + if (*(dst-1) == '\0') /* strncpy hit NULL. */ + return NULL; + } + + } + *dst = '\0'; + + return dest; + } + /* * Parse .. so we don't compromise security */