/* * Copyright (c) 2001-2007 Hypertriton, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * Routines for reading and writing signature and version information * from archive data. */ #include #include #include /* Read Agar archive version information. */ int AG_ReadVersion(AG_DataSource *ds, const char *name, const AG_Version *ver, AG_Version *rver) { char nbuf[AG_VERSION_NAME_MAX]; size_t nlen; Uint32 major, minor; nlen = strlen(name); if (AG_Read(ds, nbuf, sizeof(nbuf), 1) != 0 || strncmp(nbuf, name, nlen) != 0) { AG_SetError("%s: Bad magic (\"%s\")", name, nbuf); return (-1); } if (AG_ReadUint32v(ds, &major) == -1 || AG_ReadUint32v(ds, &minor) == -1) { AG_SetError("Reading version numbers: %s", AG_GetError()); return (-1); } if (rver != NULL) { rver->major = major; rver->minor = minor; } if (major != ver->major) { AG_SetError(_("%s: Major differs: v%d.%d != %d.%d"), name, major, minor, ver->major, ver->minor); return (-1); } if (minor != ver->minor) { Verbose(_("Warning: %s: Minor differs: v%d.%d != %d.%d\n"), name, major, minor, ver->major, ver->minor); } return (0); } /* Write Agar archive version information. */ int AG_WriteVersion(AG_DataSource *ds, const char *name, const AG_Version *ver) { char nbuf[AG_VERSION_NAME_MAX]; int i; for (i = 0; i < sizeof(nbuf); i += 4) { nbuf[i ] = 'a'; nbuf[i+1] = 'g'; nbuf[i+2] = 'a'; nbuf[i+3] = 'r'; } Strlcpy(nbuf, name, sizeof(nbuf)); if (AG_Write(ds, nbuf, sizeof(nbuf), 1) != 0) { AG_SetError("Writing magic: %s", AG_GetError()); return (-1); } if (AG_WriteUint32v(ds, &ver->major) == -1 || AG_WriteUint32v(ds, &ver->minor) == -1) { AG_SetError("Writing version numbers: %s", AG_GetError()); return (-1); } return (0); } int AG_ReadObjectVersion(AG_DataSource *ds, void *p, AG_Version *pver) { AG_ObjectClass *cl = OBJECT(p)->cls; return AG_ReadVersion(ds, cl->name, &cl->ver, pver); } void AG_WriteObjectVersion(AG_DataSource *ds, void *p) { AG_ObjectClass *cl = OBJECT(p)->cls; AG_WriteVersion(ds, cl->name, &cl->ver); }