10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 22*18Srobbin 23*18Srobbin /* 24*18Srobbin * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 25*18Srobbin * Use is subject to license terms. 26*18Srobbin */ 27*18Srobbin 280Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 290Sstevel@tonic-gate /* All Rights Reserved */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate 320Sstevel@tonic-gate /* 330Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 340Sstevel@tonic-gate * The Regents of the University of California 350Sstevel@tonic-gate * All Rights Reserved 360Sstevel@tonic-gate * 370Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 380Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 390Sstevel@tonic-gate * contributors. 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate 420Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 460Sstevel@tonic-gate * mail program 470Sstevel@tonic-gate * 480Sstevel@tonic-gate * Memory allocation routines. 490Sstevel@tonic-gate * Memory handed out here are reclaimed at the top of the command 500Sstevel@tonic-gate * loop each time, so they need not be freed. 510Sstevel@tonic-gate */ 520Sstevel@tonic-gate 530Sstevel@tonic-gate #include "rcv.h" 540Sstevel@tonic-gate #include <locale.h> 550Sstevel@tonic-gate 560Sstevel@tonic-gate static void *lastptr; /* addr of last buffer allocated */ 570Sstevel@tonic-gate static struct strings *lastsp; /* last string space allocated from */ 580Sstevel@tonic-gate 590Sstevel@tonic-gate /* 600Sstevel@tonic-gate * Allocate size more bytes of space and return the address of the 610Sstevel@tonic-gate * first byte to the caller. An even number of bytes are always 620Sstevel@tonic-gate * allocated so that the space will always be on a word boundary. 630Sstevel@tonic-gate * The string spaces are of exponentially increasing size, to satisfy 640Sstevel@tonic-gate * the occasional user with enormous string size requests. 650Sstevel@tonic-gate */ 660Sstevel@tonic-gate 670Sstevel@tonic-gate void * 680Sstevel@tonic-gate salloc(unsigned size) 690Sstevel@tonic-gate { 700Sstevel@tonic-gate register char *t; 710Sstevel@tonic-gate register unsigned s; 720Sstevel@tonic-gate register struct strings *sp; 730Sstevel@tonic-gate int index; 740Sstevel@tonic-gate 750Sstevel@tonic-gate s = size; 760Sstevel@tonic-gate #if defined(u3b) || defined(sparc) 770Sstevel@tonic-gate s += 3; /* needs alignment on quad boundary */ 780Sstevel@tonic-gate s &= ~03; 790Sstevel@tonic-gate #elif defined(i386) 800Sstevel@tonic-gate s++; 810Sstevel@tonic-gate s &= ~01; 820Sstevel@tonic-gate #else 830Sstevel@tonic-gate #error Unknown architecture! 840Sstevel@tonic-gate #endif 850Sstevel@tonic-gate index = 0; 860Sstevel@tonic-gate for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { 870Sstevel@tonic-gate if (sp->s_topFree == NOSTR && (STRINGSIZE << index) >= s) 880Sstevel@tonic-gate break; 890Sstevel@tonic-gate if (sp->s_nleft >= s) 900Sstevel@tonic-gate break; 910Sstevel@tonic-gate index++; 920Sstevel@tonic-gate } 930Sstevel@tonic-gate if (sp >= &stringdope[NSPACE]) 940Sstevel@tonic-gate panic("String too large"); 950Sstevel@tonic-gate if (sp->s_topFree == NOSTR) { 960Sstevel@tonic-gate index = sp - &stringdope[0]; 970Sstevel@tonic-gate sp->s_topFree = (char *) calloc(STRINGSIZE << index, 980Sstevel@tonic-gate (unsigned) 1); 990Sstevel@tonic-gate if (sp->s_topFree == NOSTR) { 1000Sstevel@tonic-gate fprintf(stderr, gettext("No room for space %d\n"), 1010Sstevel@tonic-gate index); 1020Sstevel@tonic-gate panic("Internal error"); 1030Sstevel@tonic-gate } 1040Sstevel@tonic-gate sp->s_nextFree = sp->s_topFree; 1050Sstevel@tonic-gate sp->s_nleft = STRINGSIZE << index; 1060Sstevel@tonic-gate } 1070Sstevel@tonic-gate sp->s_nleft -= s; 1080Sstevel@tonic-gate t = sp->s_nextFree; 1090Sstevel@tonic-gate sp->s_nextFree += s; 1100Sstevel@tonic-gate lastptr = t; 1110Sstevel@tonic-gate lastsp = sp; 1120Sstevel@tonic-gate return(t); 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate 1150Sstevel@tonic-gate /* 1160Sstevel@tonic-gate * Reallocate size bytes of space and return the address of the 1170Sstevel@tonic-gate * first byte to the caller. The old data is copied into the new area. 1180Sstevel@tonic-gate */ 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate void * 1210Sstevel@tonic-gate srealloc(void *optr, unsigned size) 1220Sstevel@tonic-gate { 1230Sstevel@tonic-gate void *nptr; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate /* if we just want to expand the last allocation, that's easy */ 1260Sstevel@tonic-gate if (optr == lastptr) { 1270Sstevel@tonic-gate register unsigned s, delta; 1280Sstevel@tonic-gate register struct strings *sp = lastsp; 1290Sstevel@tonic-gate 1300Sstevel@tonic-gate s = size; 1310Sstevel@tonic-gate #if defined(u3b) || defined(sparc) 1320Sstevel@tonic-gate s += 3; /* needs alignment on quad boundary */ 1330Sstevel@tonic-gate s &= ~03; 1340Sstevel@tonic-gate #elif defined(i386) 1350Sstevel@tonic-gate s++; 1360Sstevel@tonic-gate s &= ~01; 1370Sstevel@tonic-gate #else 1380Sstevel@tonic-gate #error Unknown architecture! 139*18Srobbin #endif /* defined(u3b) || defined(sparc) */ 1400Sstevel@tonic-gate delta = s - (sp->s_nextFree - (char *)optr); 1410Sstevel@tonic-gate if (delta <= sp->s_nleft) { 1420Sstevel@tonic-gate sp->s_nextFree += delta; 1430Sstevel@tonic-gate sp->s_nleft -= delta; 1440Sstevel@tonic-gate return (optr); 1450Sstevel@tonic-gate } 1460Sstevel@tonic-gate } 1470Sstevel@tonic-gate nptr = salloc(size); 1480Sstevel@tonic-gate if (nptr) 1490Sstevel@tonic-gate memcpy(nptr, optr, size); /* XXX - copying too much */ 1500Sstevel@tonic-gate return nptr; 1510Sstevel@tonic-gate } 1520Sstevel@tonic-gate 1530Sstevel@tonic-gate /* 1540Sstevel@tonic-gate * Reset the string area to be empty. 1550Sstevel@tonic-gate * Called to free all strings allocated 1560Sstevel@tonic-gate * since last reset. 1570Sstevel@tonic-gate */ 1580Sstevel@tonic-gate void 1590Sstevel@tonic-gate sreset(void) 1600Sstevel@tonic-gate { 1610Sstevel@tonic-gate register struct strings *sp; 1620Sstevel@tonic-gate register int index; 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate if (noreset) 1650Sstevel@tonic-gate return; 1660Sstevel@tonic-gate minit(); 1670Sstevel@tonic-gate index = 0; 1680Sstevel@tonic-gate for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { 1690Sstevel@tonic-gate if (sp->s_topFree == NOSTR) 1700Sstevel@tonic-gate continue; 1710Sstevel@tonic-gate sp->s_nextFree = sp->s_topFree; 1720Sstevel@tonic-gate sp->s_nleft = STRINGSIZE << index; 1730Sstevel@tonic-gate index++; 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate lastptr = NULL; 1760Sstevel@tonic-gate lastsp = NULL; 1770Sstevel@tonic-gate } 178