1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31
32 /*
33 * University Copyright- Copyright (c) 1982, 1986, 1988
34 * The Regents of the University of California
35 * All Rights Reserved
36 *
37 * University Acknowledgment- Portions of this document are derived from
38 * software developed by the University of California, Berkeley, and its
39 * contributors.
40 */
41
42 /*
43 * mailx -- a modified version of a University of California at Berkeley
44 * mail program
45 *
46 * Memory allocation routines.
47 * Memory handed out here are reclaimed at the top of the command
48 * loop each time, so they need not be freed.
49 */
50
51 #include "rcv.h"
52 #include <locale.h>
53
54 static void *lastptr; /* addr of last buffer allocated */
55 static struct strings *lastsp; /* last string space allocated from */
56
57 /*
58 * Allocate size more bytes of space and return the address of the
59 * first byte to the caller. An even number of bytes are always
60 * allocated so that the space will always be on a word boundary.
61 * The string spaces are of exponentially increasing size, to satisfy
62 * the occasional user with enormous string size requests.
63 */
64
65 void *
salloc(unsigned size)66 salloc(unsigned size)
67 {
68 register char *t;
69 register unsigned s;
70 register struct strings *sp;
71 int index;
72
73 s = size;
74 #if defined(u3b) || defined(sparc)
75 s += 3; /* needs alignment on quad boundary */
76 s &= ~03;
77 #elif defined(i386)
78 s++;
79 s &= ~01;
80 #else
81 #error Unknown architecture!
82 #endif
83 index = 0;
84 for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
85 if (sp->s_topFree == NOSTR && (STRINGSIZE << index) >= s)
86 break;
87 if (sp->s_nleft >= s)
88 break;
89 index++;
90 }
91 if (sp >= &stringdope[NSPACE])
92 panic("String too large");
93 if (sp->s_topFree == NOSTR) {
94 index = sp - &stringdope[0];
95 sp->s_topFree = (char *) calloc(STRINGSIZE << index,
96 (unsigned) 1);
97 if (sp->s_topFree == NOSTR) {
98 fprintf(stderr, gettext("No room for space %d\n"),
99 index);
100 panic("Internal error");
101 }
102 sp->s_nextFree = sp->s_topFree;
103 sp->s_nleft = STRINGSIZE << index;
104 }
105 sp->s_nleft -= s;
106 t = sp->s_nextFree;
107 sp->s_nextFree += s;
108 lastptr = t;
109 lastsp = sp;
110 return(t);
111 }
112
113 /*
114 * Reallocate size bytes of space and return the address of the
115 * first byte to the caller. The old data is copied into the new area.
116 */
117
118 void *
srealloc(void * optr,unsigned size)119 srealloc(void *optr, unsigned size)
120 {
121 void *nptr;
122
123 /* if we just want to expand the last allocation, that's easy */
124 if (optr == lastptr) {
125 register unsigned s, delta;
126 register struct strings *sp = lastsp;
127
128 s = size;
129 #if defined(u3b) || defined(sparc)
130 s += 3; /* needs alignment on quad boundary */
131 s &= ~03;
132 #elif defined(i386)
133 s++;
134 s &= ~01;
135 #else
136 #error Unknown architecture!
137 #endif /* defined(u3b) || defined(sparc) */
138 delta = s - (sp->s_nextFree - (char *)optr);
139 if (delta <= sp->s_nleft) {
140 sp->s_nextFree += delta;
141 sp->s_nleft -= delta;
142 return (optr);
143 }
144 }
145 nptr = salloc(size);
146 if (nptr)
147 memcpy(nptr, optr, size); /* XXX - copying too much */
148 return nptr;
149 }
150
151 /*
152 * Reset the string area to be empty.
153 * Called to free all strings allocated
154 * since last reset.
155 */
156 void
sreset(void)157 sreset(void)
158 {
159 register struct strings *sp;
160 register int index;
161
162 if (noreset)
163 return;
164 minit();
165 index = 0;
166 for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
167 if (sp->s_topFree == NOSTR)
168 continue;
169 sp->s_nextFree = sp->s_topFree;
170 sp->s_nleft = STRINGSIZE << index;
171 index++;
172 }
173 lastptr = NULL;
174 lastsp = NULL;
175 }
176