/* * [] = "@(#)strings.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = "$FreeBSD: src/usr.bin/mail/strings.c,v 1.5 2002/06/30 05:25:06 obrien Exp $"; #endif /* not lint */ #include <sys/cdefs.h> /* * Mail -- a mail program * * String allocation routines. * Strings handed out here are reclaimed at the top of the command * loop each time, so they need not be freed. */ #include "rcv.h" #include "extern.h" /* * Allocate size more bytes of space and return the address of the * first byte to the caller. An even number of bytes are always * allocated so that the space will always be on a word boundary. * The string spaces are of exponentially increasing size, to satisfy * the occasional user with enormous string size requests. */ char * salloc(size) int size; { char *t; int s, index; struct strings *sp; s = size; s += (sizeof(char *) - 1); s &= ~(sizeof(char *) - 1); index = 0; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { if (sp->s_topFree == NULL && (STRINGSIZE << index) >= s) break; if (sp->s_nleft >= s) break; index++; } if (sp >= &stringdope[NSPACE]) errx(1, "String too large"); if (sp->s_topFree == NULL) { index = sp - &stringdope[0]; if ((sp->s_topFree = malloc(STRINGSIZE << index)) == NULL) err(1, "No room for space %d", index); sp->s_nextFree = sp->s_topFree; sp->s_nleft = STRINGSIZE << index; } sp->s_nleft -= s; t = sp->s_nextFree; sp->s_nextFree += s; return (t); } /* * Reset the string area to be empty. * Called to free all strings allocated * since last reset. */ void sreset() { struct strings *sp; int index; if (noreset) return; index = 0; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { if (sp->s_topFree == NULL) continue; sp->s_nextFree = sp->s_topFree; sp->s_nleft = STRINGSIZE << index; index++; } } /* * Make the string area permanent. * Meant to be called in main, after initialization. */ void spreserve() { struct strings *sp; for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) sp->s_topFree = NULL; }