1/* buffer.c 2 Manipulate buffers used to hold strings. 3 4 Copyright (C) 1992, 1993, 2002 Ian Lance Taylor 5 6 This file is part of Taylor UUCP. 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public License 10 as published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Library General Public License for more details. 17 18 You should have received a copy of the GNU Library General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucp.h" 26 27#include "uudefs.h" 28 29/* Define MALLOC_BUFFERS when compiling this file in order to more 30 effectively use a debugging malloc library. */ 31 32#ifndef MALLOC_BUFFERS 33 34/* We keep a linked list of buffers. The union is a hack because the 35 default definition of offsetof, in uucp.h, takes the address of the 36 field, and some C compilers will not let you take the address of an 37 array. */ 38 39struct sbuf 40{ 41 struct sbuf *qnext; 42 size_t c; 43 union 44 { 45 char ab[4]; 46 char bdummy; 47 } 48 u; 49}; 50 51static struct sbuf *qBlist; 52 53/* Get a buffer of a given size. The buffer is returned with the 54 ubuffree function. */ 55 56char * 57zbufalc (c) 58 size_t c; 59{ 60 register struct sbuf *q; 61 62 if (qBlist == NULL) 63 { 64 q = (struct sbuf *) xmalloc (sizeof (struct sbuf) + c - 4); 65 q->c = c; 66 } 67 else 68 { 69 q = qBlist; 70 qBlist = q->qnext; 71 if (q->c < c) 72 { 73 q = (struct sbuf *) xrealloc ((pointer) q, 74 sizeof (struct sbuf) + c - 4); 75 q->c = c; 76 } 77 } 78 return q->u.ab; 79} 80 81/* Free up a buffer back onto the linked list. */ 82 83void 84ubuffree (z) 85 char *z; 86{ 87 struct sbuf *q; 88 /* The type of ioff should be size_t, but making it int avoids a bug 89 in some versions of the HP/UX compiler, and will always work. */ 90 int ioff; 91 92 if (z == NULL) 93 return; 94 ioff = offsetof (struct sbuf, u); 95 q = (struct sbuf *) (pointer) (z - ioff); 96 97#ifdef DEBUG_BUFFER 98 { 99 struct sbuf *qlook; 100 101 for (qlook = qBlist; qlook != NULL; qlook = qlook->qnext) 102 { 103 if (qlook == q) 104 { 105 ulog (LOG_ERROR, "ubuffree: Attempt to free buffer twice"); 106 abort (); 107 } 108 } 109 } 110#endif 111 112 q->qnext = qBlist; 113 qBlist = q; 114} 115 116#else /* MALLOC_BUFFERS */ 117 118char * 119zbufalc (c) 120 size_t c; 121{ 122 return (char *) xmalloc (c); 123} 124 125/* Free up a buffer back onto the linked list. */ 126 127void 128ubuffree (z) 129 char *z; 130{ 131 free (z); 132} 133 134#endif /* MALLOC_BUFFERS */ 135 136/* Get a buffer holding a given string. */ 137 138char * 139zbufcpy (z) 140 const char *z; 141{ 142 size_t csize; 143 char *zret; 144 145 if (z == NULL) 146 return NULL; 147 csize = strlen (z) + 1; 148 zret = zbufalc (csize); 149 memcpy (zret, z, csize); 150 return zret; 151} 152