1 /* $OpenBSD: expand.c,v 1.11 2010/11/28 14:35:58 gilles Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Gilles Chehade <gilles@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/queue.h> 21 #include <sys/tree.h> 22 #include <sys/param.h> 23 #include <sys/socket.h> 24 25 #include <event.h> 26 #include <imsg.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 31 #include "smtpd.h" 32 #include "log.h" 33 34 struct expandnode * 35 expandtree_lookup(struct expandtree *expandtree, struct expandnode *node) 36 { 37 struct expandnode key; 38 39 key = *node; 40 return RB_FIND(expandtree, expandtree, &key); 41 } 42 43 void 44 expandtree_increment_node(struct expandtree *expandtree, struct expandnode *node) 45 { 46 struct expandnode *p; 47 48 p = expandtree_lookup(expandtree, node); 49 if (p == NULL) { 50 p = calloc(1, sizeof(struct expandnode)); 51 if (p == NULL) 52 fatal("calloc"); 53 *p = *node; 54 if (RB_INSERT(expandtree, expandtree, p)) 55 fatalx("expandtree_increment_node: node already exists"); 56 } 57 p->refcnt++; 58 } 59 60 void 61 expandtree_decrement_node(struct expandtree *expandtree, struct expandnode *node) 62 { 63 struct expandnode *p; 64 65 p = expandtree_lookup(expandtree, node); 66 if (p == NULL) 67 fatalx("expandtree_decrement_node: node doesn't exist."); 68 69 p->refcnt--; 70 } 71 72 void 73 expandtree_remove_node(struct expandtree *expandtree, struct expandnode *node) 74 { 75 struct expandnode *p; 76 77 p = expandtree_lookup(expandtree, node); 78 if (p == NULL) 79 fatalx("expandtree_remove: node doesn't exist."); 80 81 RB_REMOVE(expandtree, expandtree, p); 82 } 83 84 void 85 expandtree_free_nodes(struct expandtree *expandtree) 86 { 87 struct expandnode *p; 88 struct expandnode *nxt; 89 90 for (p = RB_MIN(expandtree, expandtree); p != NULL; p = nxt) { 91 nxt = RB_NEXT(expandtree, expandtree, p); 92 RB_REMOVE(expandtree, expandtree, p); 93 free(p); 94 } 95 } 96 97 int 98 expand_cmp(struct expandnode *e1, struct expandnode *e2) 99 { 100 if (e1->type < e2->type) 101 return -1; 102 103 if (e1->type > e2->type) 104 return 1; 105 106 return memcmp(&e1->u, &e2->u, sizeof(e1->u)); 107 } 108 109 RB_GENERATE(expandtree, expandnode, entry, expand_cmp); 110