strings.c revision 77274
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 * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
3574769Smikeh#if 0
361590Srgrimesstatic char sccsid[] = "@(#)strings.c	8.1 (Berkeley) 6/6/93";
3774769Smikeh#endif
3874769Smikehstatic const char rcsid[] =
3974769Smikeh  "$FreeBSD: head/usr.bin/mail/strings.c 77274 2001-05-27 20:26:22Z mikeh $";
401590Srgrimes#endif /* not lint */
411590Srgrimes
421590Srgrimes/*
431590Srgrimes * Mail -- a mail program
441590Srgrimes *
451590Srgrimes * String allocation routines.
461590Srgrimes * Strings handed out here are reclaimed at the top of the command
471590Srgrimes * loop each time, so they need not be freed.
481590Srgrimes */
491590Srgrimes
501590Srgrimes#include "rcv.h"
511590Srgrimes#include "extern.h"
521590Srgrimes
531590Srgrimes/*
541590Srgrimes * Allocate size more bytes of space and return the address of the
551590Srgrimes * first byte to the caller.  An even number of bytes are always
561590Srgrimes * allocated so that the space will always be on a word boundary.
571590Srgrimes * The string spaces are of exponentially increasing size, to satisfy
581590Srgrimes * the occasional user with enormous string size requests.
591590Srgrimes */
601590Srgrimes
611590Srgrimeschar *
621590Srgrimessalloc(size)
631590Srgrimes	int size;
641590Srgrimes{
6577274Smikeh	char *t;
6677274Smikeh	int s, index;
6777274Smikeh	struct strings *sp;
681590Srgrimes
691590Srgrimes	s = size;
7077274Smikeh	s += (sizeof(char *) - 1);
7177274Smikeh	s &= ~(sizeof(char *) - 1);
721590Srgrimes	index = 0;
731590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
7477274Smikeh		if (sp->s_topFree == NULL && (STRINGSIZE << index) >= s)
751590Srgrimes			break;
761590Srgrimes		if (sp->s_nleft >= s)
771590Srgrimes			break;
781590Srgrimes		index++;
791590Srgrimes	}
801590Srgrimes	if (sp >= &stringdope[NSPACE])
8174769Smikeh		errx(1, "String too large");
8277274Smikeh	if (sp->s_topFree == NULL) {
831590Srgrimes		index = sp - &stringdope[0];
8477274Smikeh		if ((sp->s_topFree = malloc(STRINGSIZE << index)) == NULL)
8574769Smikeh			err(1, "No room for space %d", index);
861590Srgrimes		sp->s_nextFree = sp->s_topFree;
871590Srgrimes		sp->s_nleft = STRINGSIZE << index;
881590Srgrimes	}
891590Srgrimes	sp->s_nleft -= s;
901590Srgrimes	t = sp->s_nextFree;
911590Srgrimes	sp->s_nextFree += s;
9277274Smikeh	return (t);
931590Srgrimes}
941590Srgrimes
951590Srgrimes/*
961590Srgrimes * Reset the string area to be empty.
971590Srgrimes * Called to free all strings allocated
981590Srgrimes * since last reset.
991590Srgrimes */
1001590Srgrimesvoid
1011590Srgrimessreset()
1021590Srgrimes{
10377274Smikeh	struct strings *sp;
10477274Smikeh	int index;
1051590Srgrimes
1061590Srgrimes	if (noreset)
1071590Srgrimes		return;
1081590Srgrimes	index = 0;
1091590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) {
11077274Smikeh		if (sp->s_topFree == NULL)
1111590Srgrimes			continue;
1121590Srgrimes		sp->s_nextFree = sp->s_topFree;
1131590Srgrimes		sp->s_nleft = STRINGSIZE << index;
1141590Srgrimes		index++;
1151590Srgrimes	}
1161590Srgrimes}
1171590Srgrimes
1181590Srgrimes/*
1191590Srgrimes * Make the string area permanent.
1201590Srgrimes * Meant to be called in main, after initialization.
1211590Srgrimes */
1221590Srgrimesvoid
1231590Srgrimesspreserve()
1241590Srgrimes{
12577274Smikeh	struct strings *sp;
1261590Srgrimes
1271590Srgrimes	for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++)
12877274Smikeh		sp->s_topFree = NULL;
1291590Srgrimes}
130