133965Sjdp/* $NetBSD: type_regex.c,v 1.8 2021/04/13 13:13:04 christos Exp $ */ 278828Sobrien 3130561Sobrien/*- 433965Sjdp * Copyright (c) 1998-1999 Brett Lymn 533965Sjdp * (blymn@baea.com.au, brett_lymn@yahoo.com.au) 633965Sjdp * All rights reserved. 733965Sjdp * 833965Sjdp * This code has been donated to The NetBSD Foundation by the Author. 933965Sjdp * 1033965Sjdp * Redistribution and use in source and binary forms, with or without 1133965Sjdp * modification, are permitted provided that the following conditions 1233965Sjdp * are met: 1333965Sjdp * 1. Redistributions of source code must retain the above copyright 1433965Sjdp * notice, this list of conditions and the following disclaimer. 1533965Sjdp * 2. The name of the author may not be used to endorse or promote products 1633965Sjdp * derived from this software without specific prior written permission 1733965Sjdp * 1833965Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1933965Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2033965Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2133965Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2233965Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23130561Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2433965Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2533965Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2633965Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2733965Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2833965Sjdp * 2933965Sjdp * 30130561Sobrien */ 3133965Sjdp 3233965Sjdp#include <sys/cdefs.h> 3333965Sjdp__RCSID("$NetBSD: type_regex.c,v 1.8 2021/04/13 13:13:04 christos Exp $"); 3433965Sjdp 3533965Sjdp#include <stdlib.h> 3633965Sjdp#include <sys/types.h> 3733965Sjdp#include <regex.h> 3860484Sobrien#include "form.h" 3933965Sjdp#include "internals.h" 4033965Sjdp 4133965Sjdp/* 4233965Sjdp * The regex type handling. 4333965Sjdp */ 4433965Sjdp 4533965Sjdptypedef struct 4633965Sjdp{ 47104834Sobrien regex_t compiled; 48104834Sobrien unsigned references; 49104834Sobrien} regex_args; 5033965Sjdp 5160484Sobrien/* 5277298Sobrien * Create the regex arguments structure from the given args. Return NULL 5360484Sobrien * if the call fails, otherwise return a pointer to the structure allocated. 5460484Sobrien */ 5560484Sobrienstatic char * 5660484Sobriencreate_regex_args(va_list *args) 5760484Sobrien{ 5833965Sjdp regex_args *new; 5933965Sjdp char *expression; 6033965Sjdp 6133965Sjdp new = malloc(sizeof(*new)); 6233965Sjdp 6333965Sjdp if (new != NULL) { 6433965Sjdp new->references = 1; 6533965Sjdp expression = va_arg(*args, char *); 6633965Sjdp if ((regcomp(&new->compiled, expression, 6733965Sjdp (REG_EXTENDED | REG_NOSUB | REG_NEWLINE))) != 0) { 6833965Sjdp free(new); 6933965Sjdp return NULL; 7033965Sjdp } 7133965Sjdp } 7238889Sjdp 7338889Sjdp return (void *) new; 7438889Sjdp} 7538889Sjdp 7660484Sobrien/* 7760484Sobrien * Copy the regex argument structure. 7860484Sobrien */ 7938889Sjdpstatic char * 8038889Sjdpcopy_regex_args(char *args) 8189857Sobrien{ 8233965Sjdp ((regex_args *) (void *) args)->references++; 8333965Sjdp 8433965Sjdp return (void *) args; 8589857Sobrien} 8633965Sjdp 8733965Sjdp/* 8833965Sjdp * Free the allocated storage associated with the type arguments. 8933965Sjdp */ 90130561Sobrienstatic void 9133965Sjdpfree_regex_args(char *args) 9233965Sjdp{ 9333965Sjdp if (args != NULL) { 9477298Sobrien ((regex_args *) (void *) args)->references--; 9533965Sjdp if (((regex_args *) (void *) args)->references == 0) 9677298Sobrien free(args); 97130561Sobrien } 9833965Sjdp} 9933965Sjdp 10060484Sobrien/* 10133965Sjdp * Check the contents of the field buffer match the regex. 10233965Sjdp */ 10333965Sjdpstatic int 10438889Sjdpregex_check_field(FIELD *field, char *args) 10533965Sjdp{ 10633965Sjdp if ((args != NULL) && 10733965Sjdp (regexec(&((regex_args *) (void *) field->args)->compiled, 10860484Sobrien args, (size_t) 0, NULL, 0) == 0)) 10960484Sobrien return TRUE; 11060484Sobrien 11133965Sjdp return FALSE; 11260484Sobrien} 11333965Sjdp 11433965Sjdpstatic FIELDTYPE builtin_regex = { 11533965Sjdp _TYPE_HAS_ARGS | _TYPE_IS_BUILTIN, /* flags */ 11660484Sobrien 0, /* refcount */ 117130561Sobrien NULL, /* link */ 11833965Sjdp create_regex_args, /* make_args */ 11933965Sjdp copy_regex_args, /* copy_args */ 12033965Sjdp free_regex_args, /* free_args */ 12133965Sjdp regex_check_field, /* field_check */ 12233965Sjdp NULL, /* char_check */ 12333965Sjdp NULL, /* next_choice */ 12433965Sjdp NULL /* prev_choice */ 12533965Sjdp}; 12633965Sjdp 12733965SjdpFIELDTYPE *TYPE_REGEXP = &builtin_regex; 12833965Sjdp 12933965Sjdp 13033965Sjdp