mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-11-18 19:09:31 +00:00
313 lines
7.2 KiB
C
313 lines
7.2 KiB
C
/*
|
|
* getvers version 2.0 for Apple IIGS
|
|
*
|
|
* Written by Dave Tribby for GNO/ME 2.0.6 * April 1998
|
|
* Original getvers written by Ian Schmidt (Copyright 1993 Two Meg Software)
|
|
*
|
|
* NOTE: I started in recoding getvers in C, but shifted to assembly language
|
|
* and completed the implementation. This version has a couple of
|
|
* deficiencies (e.g. the resources should be locked after being
|
|
* loaded). It's included just in case someone must translate getvers
|
|
* to C and needs a resonable starting point.
|
|
*
|
|
* $Id
|
|
*/
|
|
|
|
|
|
#include <err.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <Types.h>
|
|
#include <Resources.h>
|
|
#include <GSOS.h>
|
|
#include <orca.h>
|
|
#include <misctool.h>
|
|
|
|
#include <gno/gno.h>
|
|
|
|
int rval=0; /* Returned status */
|
|
int bflag=0; /* Command line -b option flag */
|
|
int cflag=0; /* Command line -c option flag */
|
|
|
|
static void usage __P((void));
|
|
static void ReadResources __P((char *));
|
|
|
|
|
|
int
|
|
main(int argc,
|
|
char *argv[])
|
|
{
|
|
int ch;
|
|
char *fn;
|
|
|
|
/* Report stack usage at end if compile option is set */
|
|
__REPORT_STACK();
|
|
|
|
/* Parse the command-line options */
|
|
while ((ch = getopt(argc, argv, "bc")) != -1)
|
|
switch (ch) {
|
|
case 'c':
|
|
cflag = 1;
|
|
break;
|
|
case 'b':
|
|
bflag = 1;
|
|
break;
|
|
case '?':
|
|
default:
|
|
usage();
|
|
}
|
|
argc -= optind;
|
|
argv = argv + optind;
|
|
|
|
if (!*argv)
|
|
usage();
|
|
else {
|
|
|
|
/* Start up the resource manager */
|
|
ResourceStartUp(userid());
|
|
|
|
/* Parse the command-line filenames */
|
|
while (*argv) {
|
|
fn = *argv++;
|
|
ReadResources(fn);
|
|
if (*argv && !bflag) (void)printf("\n");
|
|
}
|
|
|
|
/* Shut down the resource manager */
|
|
/* (which closes open resource files) */
|
|
ResourceShutDown();
|
|
}
|
|
exit(rval);
|
|
}
|
|
|
|
/*
|
|
* Perform malloc memory allocation + error checking
|
|
*/
|
|
static void *
|
|
malloc_c(size_t size)
|
|
{
|
|
void *rtn_value;
|
|
if ((rtn_value = malloc(size)) == NULL) {
|
|
(void)fprintf(stderr, "\nERROR: cannot allocate %ld bytes\n",
|
|
size);
|
|
exit(1);
|
|
}
|
|
return rtn_value;
|
|
}
|
|
|
|
|
|
typedef struct rVersType {
|
|
Long version;
|
|
unsigned short country;
|
|
Str255 product;
|
|
} rVersType, *rVersPtr;
|
|
|
|
/*
|
|
* Translate 8-bit text and print on stdout
|
|
*/
|
|
void
|
|
Print8bitText(ptr raw_text, Word raw_len)
|
|
{
|
|
Word Xlate_len;
|
|
ResultBuf255Ptr Xlate_buf;
|
|
LongWord Xresult;
|
|
int Xprint_len;
|
|
|
|
/* Translated buffer could need up to 4 characters per input char. */
|
|
/* It also needs two length words preceeding the characters. */
|
|
Xlate_len = raw_len*4+4;
|
|
|
|
/* Allocate an extra byte so C-string can be terminated with null */
|
|
Xlate_buf = (ResultBuf255Ptr)malloc_c(Xlate_len*4+1);
|
|
Xlate_buf->bufSize = Xlate_len;
|
|
|
|
Xresult = StringToText(fAllowLongerSubs, raw_text,
|
|
raw_len, (Ptr)Xlate_buf);
|
|
|
|
/* Add null character to terminate characters */
|
|
Xprint_len = Xresult & 0xFFFF;
|
|
Xlate_buf->bufString.text[Xprint_len] = 0;
|
|
|
|
/* Print the translated text */
|
|
(void)fputs(Xlate_buf->bufString.text, stdout);
|
|
|
|
/* All done with the translation buffer */
|
|
free(Xlate_buf);
|
|
}
|
|
|
|
static void
|
|
PrintPString(ptr ps)
|
|
{
|
|
int len;
|
|
len = *ps++;
|
|
while (len--) putchar(*ps++);
|
|
}
|
|
|
|
/*
|
|
* Translate 8-bit characters that might be embedded in
|
|
* the p-string parameter and print on stdout
|
|
*/
|
|
static void
|
|
Print8bitString(ptr ps)
|
|
{
|
|
/* Length of input string */
|
|
Print8bitText((ptr)(ps+1), *ps);
|
|
}
|
|
|
|
|
|
|
|
#define NUM_COUNTRY 55
|
|
char *countryTbl[NUM_COUNTRY]={"United States", "France", "Britain",
|
|
"Germany", "Italy", "Netherlands", "Belgium/Luxembourg",
|
|
"Sweden", "Spain", "Denmark", "Portugal", "French Canadian",
|
|
"Norway", "Israel", "Japan", "Australia", "Arabia", "Finland",
|
|
"French Swiss", "German Swiss", "Greece", "Iceland", "Malta",
|
|
"Cyprus", "Turkey", "Bosnia/Herzegovena/Yugoslavia/Croatia",
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
"India", "Pakistan",
|
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
"Lithuania", "Poland", "Hungary", "Estonia", "Latvia",
|
|
"Lapland", "Faeroe Islands", "Iran", "Russia", "Ireland",
|
|
"Korea", "China", "Taiwan", "Thailand"};
|
|
|
|
/*
|
|
* Print information related to the rVersion resource
|
|
* passed as a parameter.
|
|
*/
|
|
static void
|
|
PrintVersionResource(ptr rezPtr)
|
|
{
|
|
rVersPtr rVers_addr;
|
|
String(9) string_version;
|
|
unsigned long moreInfo;
|
|
int country_num;
|
|
char *country;
|
|
|
|
/* Translate version from raw number to string */
|
|
rVers_addr = (rVersPtr)rezPtr;
|
|
VersionString(0, rVers_addr->version, (Ptr)&string_version);
|
|
|
|
/* Print product name and string version */
|
|
Print8bitString((ptr) &(rVers_addr->product));
|
|
putchar(' ');
|
|
PrintPString((ptr) &string_version);
|
|
putchar('\n');
|
|
|
|
/* All done if -b (brief) option was specified */
|
|
if ( bflag ) return;
|
|
|
|
/* The "moreInfo" p-string follows the product p-string */
|
|
moreInfo = (unsigned long)&(rVers_addr->product) +
|
|
rVers_addr->product.textLength + 1;
|
|
Print8bitString((Ptr)moreInfo);
|
|
putchar('\n');
|
|
|
|
/* Print the country information */
|
|
if ( (country_num=rVers_addr->country) < NUM_COUNTRY)
|
|
country = countryTbl[country_num];
|
|
if (country_num >= NUM_COUNTRY || country == NULL )
|
|
(void)printf("Country: %d unknown to this version of getvers\n",
|
|
country_num);
|
|
else
|
|
(void)printf("Country: %s\n", country);
|
|
}
|
|
|
|
|
|
/*
|
|
* Print the rVersion comment passed as a parameter.
|
|
*/
|
|
static void
|
|
PrintCommentResource(ptr rezPtr)
|
|
{
|
|
LongWord rez_len;
|
|
rez_len = GetResourceSize(0x802A,1);
|
|
Print8bitText(rezPtr, rez_len);
|
|
putchar('\n');
|
|
}
|
|
|
|
|
|
/*
|
|
* Read the version (and, optionally, comment) resources from the
|
|
* indicated file
|
|
*/
|
|
static void
|
|
ReadResources(char *path_str)
|
|
{
|
|
#define noPreload 0x8000
|
|
Word new_file_id;
|
|
Word old_file_id;
|
|
Word old_depth;
|
|
GSString255Ptr path_ptr;
|
|
Handle rVer_handle, rCom_handle;
|
|
int error;
|
|
|
|
/* Let user know what file we're working on */
|
|
(void)printf("%s: ",path_str);
|
|
|
|
/* Convert C string into GSString */
|
|
path_ptr = malloc_c(strlen(path_str)+2);
|
|
path_ptr->length = strlen(path_str);
|
|
strcpy(path_ptr->text, path_str);
|
|
|
|
/* Open the resource fork of the file */
|
|
new_file_id = OpenResourceFile(noPreload+readEnable,
|
|
NULL, (Pointer)path_ptr);
|
|
if ((error = toolerror()) != noError) {
|
|
if (error == 0x0046)
|
|
(void)printf("File not found\n");
|
|
else if (error == 0x0063)
|
|
(void)printf("No resource fork\n");
|
|
else
|
|
(void)printf("Error $%04X opening resource fork\n",
|
|
error);
|
|
rval = 1;
|
|
}
|
|
else {
|
|
/* Set up to search only this resource file, remembering */
|
|
/* previous setting so it can be restored when closing file */
|
|
old_file_id = GetCurResourceFile();
|
|
SetCurResourceFile(new_file_id);
|
|
old_depth = SetResourceFileDepth(1);
|
|
|
|
/* Read the version resource */
|
|
rVer_handle = LoadResource(0x8029,1);
|
|
if ((error = toolerror()) != noError) {
|
|
if (error == 0x1E06)
|
|
(void)printf("No version resource\n");
|
|
else
|
|
(void)printf(
|
|
"Error $%04X getting version resource\n",
|
|
error);
|
|
rval = 1;
|
|
}
|
|
else {
|
|
PrintVersionResource(*rVer_handle);
|
|
}
|
|
|
|
/* Read the comment resource, if requested */
|
|
if ( cflag ) {
|
|
rCom_handle = LoadResource(0x802A,1);
|
|
if ((error = toolerror()) == noError) {
|
|
PrintCommentResource(*rCom_handle);
|
|
}
|
|
}
|
|
|
|
/* Close the resource file and restore original search values */
|
|
CloseResourceFile(new_file_id);
|
|
SetCurResourceFile(old_file_id);
|
|
SetResourceFileDepth(old_depth);
|
|
}
|
|
/* Free the memory allocated for the path name */
|
|
free(path_ptr);
|
|
}
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
(void)fprintf(stderr, "usage: getvers [-b] [-c] file ...\n");
|
|
exit(1);
|
|
}
|