2 * S-nail - a mail user agent derived from Berkeley Mail.
4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
5 * Copyright (c) 2012 Steffen "Daode" Nurpmeso.
8 * Copyright (c) 1980, 1993
9 * The Regents of the University of California. All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * Mail -- a mail program
43 * String allocation routines and support routines that build on top of them.
44 * Strings handed out here are reclaimed at the top of the command
45 * loop each time, so they need not be freed.
54 * Allocate size more bytes of space and return the address of the
55 * first byte to the caller. An even number of bytes are always
56 * allocated so that the space will always be on a word boundary.
57 * The string spaces are of exponentially increasing size, to satisfy
58 * the occasional user with enormous string size requests.
69 s
+= (sizeof (char *) - 1);
70 s
&= ~(sizeof (char *) - 1);
72 for (sp
= &stringdope
[0]; sp
< &stringdope
[NSPACE
]; sp
++) {
73 if (sp
->s_topFree
== NULL
&& (STRINGSIZE
<< string_index
) >= s
)
79 if (sp
>= &stringdope
[NSPACE
])
80 panic(tr(195, "String too large"));
81 if (sp
->s_topFree
== NULL
) {
82 string_index
= sp
- &stringdope
[0];
83 sp
->s_topFree
= smalloc(STRINGSIZE
<< string_index
);
84 sp
->s_nextFree
= sp
->s_topFree
;
85 sp
->s_nleft
= STRINGSIZE
<< string_index
;
94 csalloc(size_t nmemb
, size_t size
)
98 vp
= salloc(nmemb
* size
);
99 memset(vp
, 0, nmemb
* size
);
104 * Reset the string area to be empty.
105 * Called to free all strings allocated
117 for (sp
= &stringdope
[0]; sp
< &stringdope
[NSPACE
]; sp
++) {
118 if (sp
->s_topFree
== NULL
)
120 sp
->s_nextFree
= sp
->s_topFree
;
121 sp
->s_nleft
= STRINGSIZE
<< string_index
;
127 * Make the string area permanent.
128 * Meant to be called in main, after initialization.
135 for (sp
= &stringdope
[0]; sp
< &stringdope
[NSPACE
]; sp
++)
136 sp
->s_topFree
= NULL
;
140 * Return a pointer to a dynamic copy of the argument.
143 savestr(const char *str
)
146 int size
= strlen(str
) + 1;
148 if ((news
= salloc(size
)) != NULL
)
149 memcpy(news
, str
, size
);
154 * Return new string copy of a non-terminated argument.
157 savestrbuf(const char *sbuf
, size_t sbuf_len
)
161 if ((news
= salloc(sbuf_len
+ 1)) != NULL
) {
162 memcpy(news
, sbuf
, sbuf_len
);
169 * Make a copy of new argument incorporating old one.
172 save2str(const char *str
, const char *old
)
175 int newsize
= strlen(str
) + 1;
176 int oldsize
= old
? strlen(old
) + 1 : 0;
178 if ((news
= salloc(newsize
+ oldsize
)) != NULL
) {
180 memcpy(news
, old
, oldsize
);
181 news
[oldsize
- 1] = ' ';
183 memcpy(news
+ oldsize
, str
, newsize
);
189 savecat(const char *s1
, const char *s2
)
194 np
= ns
= salloc(strlen(s1
) + strlen(s2
) + 1);
195 for (cp
= s1
; *cp
; cp
++)
197 for (cp
= s2
; *cp
; cp
++)
204 str_concat_csvl(struct str
*self
, ...)
211 for (l
= 0; (cs
= va_arg(vl
, char const*)) != NULL
;)
216 self
->s
= salloc(l
+ 1);
219 for (l
= 0; (cs
= va_arg(vl
, char const*)) != NULL
;) {
220 size_t i
= strlen(cs
);
221 memcpy(self
->s
+ l
, cs
, i
);