11590Srgrimes/*
21590Srgrimes * Copyright (c) 1980, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 4. Neither the name of the University nor the names of its contributors
141590Srgrimes *    may be used to endorse or promote products derived from this software
151590Srgrimes *    without specific prior written permission.
161590Srgrimes *
171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271590Srgrimes * SUCH DAMAGE.
281590Srgrimes */
291590Srgrimes
301590Srgrimes#ifndef lint
3174769Smikeh#if 0
321590Srgrimesstatic char sccsid[] = "@(#)strings.c	8.1 (Berkeley) 6/6/93";
3374769Smikeh#endif
341590Srgrimes#endif /* not lint */
3599112Sobrien#include <sys/cdefs.h>
3699112Sobrien__FBSDID("$FreeBSD$");
371590Srgrimes
381590Srgrimes/*
391590Srgrimes * Mail -- a mail program
401590Srgrimes *
411590Srgrimes * String allocation routines.
421590Srgrimes * Strings handed out here are reclaimed at the top of the command
431590Srgrimes * loop each time, so they need not be freed.
441590Srgrimes */
451590Srgrimes
461590Srgrimes#include "rcv.h"
471590Srgrimes#include "extern.h"
481590Srgrimes
491590Srgrimes/*
501590Srgrimes * Allocate size more bytes of space and return the address of the
511590Srgrimes * first byte to the caller.  An even number of bytes are always
521590Srgrimes * allocated so that the space will always be on a word boundary.
531590Srgrimes * The string spaces are of exponentially increasing size, to satisfy
541590Srgrimes * the occasional user with enormous string size requests.
551590Srgrimes */
561590Srgrimes
571590Srgrimeschar *
58216564Scharniersalloc(int size)
591590Srgrimes{
6077274Smikeh	char *t;
6177274Smikeh	int s, index;
6277274Smikeh	struct strings *sp;
631590Srgrimes
641590Srgrimes	s = size;
6577274Smikeh	s += (sizeof(char *) - 1);
6677274Smikeh	s &= ~(sizeof(char *) - 1);
671590Srgrimes	index = 0;
681590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
6977274Smikeh		if (sp->s_topFree == NULL && (STRINGSIZE << index) >= s)
701590Srgrimes			break;
711590Srgrimes		if (sp->s_nleft >= s)
721590Srgrimes			break;
731590Srgrimes		index++;
741590Srgrimes	}
751590Srgrimes	if (sp >= &stringdope[NSPACE])
7674769Smikeh		errx(1, "String too large");
7777274Smikeh	if (sp->s_topFree == NULL) {
781590Srgrimes		index = sp - &stringdope[0];
7977274Smikeh		if ((sp->s_topFree = malloc(STRINGSIZE << index)) == NULL)
8074769Smikeh			err(1, "No room for space %d", index);
811590Srgrimes		sp->s_nextFree = sp->s_topFree;
821590Srgrimes		sp->s_nleft = STRINGSIZE << index;
831590Srgrimes	}
841590Srgrimes	sp->s_nleft -= s;
851590Srgrimes	t = sp->s_nextFree;
861590Srgrimes	sp->s_nextFree += s;
8777274Smikeh	return (t);
881590Srgrimes}
891590Srgrimes
901590Srgrimes/*
911590Srgrimes * Reset the string area to be empty.
921590Srgrimes * Called to free all strings allocated
931590Srgrimes * since last reset.
941590Srgrimes */
951590Srgrimesvoid
96216564Scharniersreset(void)
971590Srgrimes{
9877274Smikeh	struct strings *sp;
9977274Smikeh	int index;
1001590Srgrimes
1011590Srgrimes	if (noreset)
1021590Srgrimes		return;
1031590Srgrimes	index = 0;
1041590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
10577274Smikeh		if (sp->s_topFree == NULL)
1061590Srgrimes			continue;
1071590Srgrimes		sp->s_nextFree = sp->s_topFree;
1081590Srgrimes		sp->s_nleft = STRINGSIZE << index;
1091590Srgrimes		index++;
1101590Srgrimes	}
1111590Srgrimes}
1121590Srgrimes
1131590Srgrimes/*
1141590Srgrimes * Make the string area permanent.
1151590Srgrimes * Meant to be called in main, after initialization.
1161590Srgrimes */
1171590Srgrimesvoid
118216564Scharnierspreserve(void)
1191590Srgrimes{
12077274Smikeh	struct strings *sp;
1211590Srgrimes
1221590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++)
12377274Smikeh		sp->s_topFree = NULL;
1241590Srgrimes}
125