home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
old
/
ckermit5a190
/
ckvcvt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-20
|
14KB
|
565 lines
/*
* ckvcvt - assorted outboard processing for C-Kermit/VMS labeled files
*/
/* Revision History:
* T1.0-00 - 08-Apr-91 - tmk - Initial coding, sync w/ 5A(167) and ckvfio.c
* 2.0-066.
* T1.0-01 - 14-Apr-91 - tmk - Fix errors in help output, show actual system
* message on RMS error.
* T1.0-02 - 15-Apr-91 - tmk - Redefine fab$b_journal as fab$b_rfm+1.
* T1.0-03 - 15-Apr-91 - tmk - ACL support, sync w/ 5A(169) and ckvfio.c 2.0-
* 069.
* T1.0-04 - 16-Apr-91 - tmk - Fix _another_ journaling bug (whimper), handle
* missing semicolon in filespec gracefully.
* T1.0-05 - 04-Sep-92 - tmk - Implement ckvfio.c 087 fix.
* T1.0-06 - 08-Apr-93 - tmk - Implement ckvfio.c 097 fix.
*/
#ifdef WINTCP
#include stdio
#include stdlib
#include ctype
#include string
#include rms
#include ssdef
#else
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <rms.h>
#include <ssdef.h>
#endif /* WINTCP */
#define VERSION "T1.0-06"
#define R_MODE "rb"
#define IO_ERROR 0
#define IO_SUCCESS 1
/*
* Definitions for output file
*/
static struct FAB fab_ofile;
static struct RAB rab_ofile;
static struct XABDAT xabdat_ofile;
static struct XABFHC xabfhc_ofile;
static struct XABPRO xabpro_ofile;
static struct XABALL xaball_ofile;
static struct XABRDT xabrdt_ofile;
static short ofile_ffb;
static int ofile_rec;
/*
* Common RMS items
*/
static unsigned long int rms_sts;
/*
* Global varables
*/
int keepacl = 0; /* Preserve ACL data? */
int backup = 0; /* Preserve file backup date? */
int debug = 0; /* Debug output? */
int notrim = 0; /* Don't trim names? */
int inquire = 0; /* Testing if labeled? */
int owner = 0; /* Preserve file ownership? */
int strip = 0; /* Just stripping? */
FILE *infd = NULL; /* Input file descriptor */
char *infn = NULL; /* Input file name */
char *outfn = NULL; /* Special output file name */
char buffer[512]; /* Work buffer */
char label[99]; /* Label name */
int lblen = 0; /* Length of label */
char vmsname[255]; /* Stored name */
char vmsfile[70]; /* Stored file info */
char vmsacl[512]; /* Stored ACL data */
int acllen = 0; /* Size of same */
char *filptr = vmsfile; /* Attribute pointer */
int gotname = 0; /* Found name? */
int gotfile = 0; /* Found file info? */
int gotacl = 0; /* Found ACL info? */
int bail = 0; /* If we should bail out */
char revdat[8]; /* Revision date */
unsigned short revnum; /* Revision number */
unsigned short jnlflg; /* Journaling flags */
/*
* Function prototypes
*/
extern int main(int, char **);
void do_help();
void barf(char *);
void strip_file();
/*
* Ok, let's do it
*/
int main(argc, argv)
int argc;
char *argv[];
{
register char *ap;
int i, j; /* How original */
if (argc < 2) /* User say anything? */
do_help(); /* If not... */
if (*argv[1] != '-') {
infn = argv[1];
if ((infd = fopen(argv[1], R_MODE)) == NULL) {
perror(argv[1]);
exit(IO_ERROR);
}
argc--;
argv++;
}
else
bail++;
while (argc > 1) {
ap = argv[1];
if (*ap != '-') {
fprintf(stderr, "Unknown option '%s',", ap);
fprintf(stderr, " do CKVCVT -? for help.\n");
}
else for (ap++; *ap; ap++) {
switch (tolower(*ap)) {
case 'a': /* Preserve ACL's */
keepacl++;
break;
case 'b': /* Preserve backup date */
backup++;
break;
case 'd': /* Debug mode? */
debug++;
break;
case 'f': /* Name output file */
if (isgraph(ap[1]) != 0)
outfn = &ap[1];
else if (argc > 2) {
outfn = argv[2];
argc--;
argv++;
}
else {
break;
}
goto next_arg;
case 'i': /* Inquire if labeled */
inquire++;
strip++;
break;
case 'o': /* Preserve file ownership */
owner++;
break;
case 's': /* Just strip it */
strip++;
break;
case 't': /* Don't trim filenames */
notrim++;
break;
case '?': /* Emit help text */
case 'h':
do_help();
break;
default:
fprintf(stderr, "?Unknown option '%c',", *ap);
fprintf(stderr, " do CKVCVT -? for help\n");
}
}
next_arg:
argc--;
argv++;
}
if (bail != 0)
exit(IO_ERROR);
fread(buffer, 20, 1, infd);
if (strncmp(buffer, "KERMIT LABELED FILE:", 20) != 0)
barf("not a Kermit labeled file");
fread(buffer, 2, 1, infd);
buffer[2] = '\0';
lblen = atoi(buffer);
if (lblen != 2)
barf("");
fread(buffer, lblen, 1, infd);
if (strip != 0) /* Stripping headers? */
strip_file();
if (strncmp(buffer, "D7", 2) != 0)
barf("not from a VAX/VMS system");
fread(buffer, 6, 1, infd);
if (strncmp(buffer, "04VERS", 6) != 0)
barf("");
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
fread(buffer, lblen, 1, infd);
buffer[lblen] = '\0';
if (debug)
fprintf(stderr, "File created under VAX/VMS %s\n", buffer);
fread(buffer, 7, 1, infd);
if (strncmp(buffer, "05KVERS", 7) != 0)
barf("");
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
fread(buffer, lblen, 1, infd);
buffer[lblen] = '\0';
if (debug)
fprintf(stderr, "File created with C-Kermit/VMS %s\n", buffer);
next_label:
fread(buffer, 2, 1, infd);
buffer[2] = '\0';
lblen = atoi(buffer);
if (lblen == 0)
barf("lost sync");
fread(buffer, lblen, 1, infd);
buffer[lblen] = '\0';
if (strcmp(buffer, "VMSNAME") == 0) {
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
fread(vmsname, lblen, 1, infd);
vmsname[lblen] = '\0';
gotname++;
if (debug)
fprintf(stderr, "Loaded file name block as %s\n", vmsname);
i = strstr(vmsname, "::");
if (i != NULL) {
i += 2;
memmove(vmsname, i, strlen(vmsname));
}
if (!notrim) {
i = strrchr(vmsname, ':');
j = strrchr(vmsname, ']');
if (j == NULL)
j = strrchr(vmsname, '>');
if (j > i)
i = j;
i++;
memmove(vmsname, i, strlen(vmsname));
}
if (strchr(vmsname, ';') != NULL) {
for (j = strlen(vmsname); vmsname[j] != ';'; j--)
;
vmsname[j] = '\0';
}
if (debug)
fprintf(stderr, "Resultant filespec: %s\n", vmsname);
goto next_label;
}
else if (strcmp(buffer, "VMSFILE") == 0) {
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
fread(vmsfile, lblen, 1, infd);
vmsfile[lblen] = '\0';
gotfile++;
if (debug)
fprintf(stderr, "Loaded file attribute block\n");
goto next_label;
}
else if (strcmp(buffer, "VMSACL") == 0) {
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
acllen = atoi(buffer);
fread(vmsacl, acllen, 1, infd);
vmsacl[acllen] = '\0';
gotacl++;
if (debug)
fprintf(stderr, "Loaded file ACL block\n");
goto next_label;
}
else if (strcmp(buffer, "DATA") == 0) {
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
if (lblen != 0)
barf("");
if (debug)
fprintf(stderr, "Positioned at start of file data\n");
goto all_set;
}
else {
fprintf(stderr, "%s: unrecognized label '%s'\n", infn, buffer);
fread(buffer, 8, 1, infd);
buffer[8] = '\0';
lblen = atoi(buffer);
if (lblen > 512)
barf("unrecognized label too long to skip");
fread(vmsfile, lblen, 1, infd);
goto next_label;
}
all_set:
if (gotfile != 1 || gotname != 1)
barf("missing required labels");
/*
* Prep the characteristics
*/
fab_ofile = cc$rms_fab;
fab_ofile.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
fab_ofile.fab$l_fop = FAB$M_MXV;
if (outfn == NULL) {
fab_ofile.fab$l_fna = vmsname;
fab_ofile.fab$b_fns = strlen(vmsname);
}
else {
fab_ofile.fab$l_fna = outfn;
fab_ofile.fab$b_fns = strlen(outfn);
}
fab_ofile.fab$l_xab = &xabdat_ofile;
rab_ofile = cc$rms_rab;
rab_ofile.rab$l_fab = &fab_ofile;
xabdat_ofile = cc$rms_xabdat;
xabdat_ofile.xab$l_nxt = &xabrdt_ofile;
xabrdt_ofile = cc$rms_xabrdt;
xabrdt_ofile.xab$l_nxt = &xabfhc_ofile;
xabfhc_ofile = cc$rms_xabfhc;
xabfhc_ofile.xab$l_nxt = &xabpro_ofile;
xabpro_ofile = cc$rms_xabpro;
xabpro_ofile.xab$l_nxt = &xaball_ofile;
xaball_ofile = cc$rms_xaball;
/*
* Load 'em up
*/
memmove(&xabpro_ofile.xab$w_pro, filptr, 2);
filptr += 2;
if (owner != 0)
memmove(&xabpro_ofile.xab$l_uic, filptr, 4);
filptr += 4;
memmove(&fab_ofile.fab$b_rfm, filptr, 1);
filptr += 1;
memmove(&fab_ofile.fab$b_org, filptr, 1);
filptr += 1;
memmove(&fab_ofile.fab$b_rat, filptr, 1);
filptr += 5; /* 4 bytes reserved for char */
memmove(&fab_ofile.fab$b_fsz, filptr, 1);
filptr += 1;
memmove(&xabfhc_ofile.xab$w_lrl, filptr, 2);
filptr += 2;
memmove(&fab_ofile.fab$w_mrs, filptr, 2);
filptr += 2;
memmove(&xabfhc_ofile.xab$l_ebk, filptr, 4);
filptr += 4;
/* preserve this as RMS won't remember it for us */
memmove(&ofile_ffb, filptr, 2);
filptr += 2;
memmove(&xaball_ofile.xab$l_alq, filptr, 4);
filptr += 4;
memmove(&xaball_ofile.xab$w_deq, filptr, 2);
filptr += 2;
memmove(&xaball_ofile.xab$b_bkz, filptr, 1);
filptr += 1;
memmove(&fab_ofile.fab$w_gbc, filptr, 2);
filptr += 2;
memmove(&xabfhc_ofile.xab$w_verlimit, filptr, 2);
filptr += 2;
memmove(&jnlflg, filptr, 1);
if (jnlflg !=0)
printf("Original file was marked for RMS Journaling, this copy is not.\n");
filptr += 1;
memmove(&xabdat_ofile.xab$q_cdt, filptr, 8);
filptr += 8;
memmove(&revdat, filptr, 8);
filptr += 8;
memmove(&revnum, filptr, 2);
filptr += 2;
memmove(&xabdat_ofile.xab$q_edt, filptr, 8);
filptr += 8;
if (backup != 0)
memmove(&xabdat_ofile.xab$q_bdt, filptr, 8);
filptr += 8;
/*
* ACL's?
*/
if(keepacl != 0 && gotacl != 0) {
xabpro_ofile.xab$l_aclbuf = &vmsacl;
xabpro_ofile.xab$w_aclsiz = acllen;
}
/*
* Give it a quick whirl around the dance floor
*/
printf("Creating %s...\n", fab_ofile.fab$l_fna);
rms_sts = sys$create(&fab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
if(keepacl != 0 && gotacl != 0) {
if (!(xabpro_ofile.xab$l_aclsts & 1))
exit(xabpro_ofile.xab$l_aclsts);
}
rms_sts = sys$connect(&rab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
ofile_rec = 1;
fread(buffer, 512, 1, infd);
while (!feof(infd)) {
rab_ofile.rab$l_rbf = buffer;
rab_ofile.rab$w_rsz = 512;
if (ofile_rec == xabfhc_ofile.xab$l_ebk) {
xabfhc_ofile.xab$w_ffb = ofile_ffb;
if (ofile_ffb)
rab_ofile.rab$w_rsz -= (512 - ofile_ffb);
if (debug) {
fprintf(stderr, "FFB (first free byte) = %d\n", ofile_ffb);
fprintf(stderr, "Last record size = %d\n", rab_ofile.rab$w_rsz);
}
}
rms_sts = sys$write(&rab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
fread(buffer, 512, 1, infd);
ofile_rec++;
}
/*
* Update the revision information
*/
memmove(&xabrdt_ofile.xab$q_rdt, revdat, 8);
memmove(&xabrdt_ofile.xab$w_rvn, &revnum, 2);
rms_sts = sys$close(&fab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
printf("...done.\n");
exit(IO_SUCCESS);
}
void do_help()
{
printf("This is CKVCVT %s\n\n", VERSION);
printf("Usage: CKVCVT infile options\n\n");
printf("Options:\n");
printf(" -a Preserve file ACL data (may require privs)\n");
printf(" -b Preserve file backup date\n");
printf(" -d Print debugging information\n");
printf(" -f fn Name output file fn instead of default\n");
printf(" -i Inquire if a file is labeled\n");
printf(" -o Preserve file ownership (requires privs)\n");
printf(" -s Strip one level of label information\n");
printf(" -t Don't trim paths from output file name\n");
printf(" -? Display this message\n\n");
exit(IO_SUCCESS);
}
void barf(text)
char *text;
{
if (text == "")
fprintf(stderr, "%s: corrupted Kermit labeled file\n", infn);
else
fprintf(stderr, "%s: %s\n", infn, text);
exit(IO_ERROR);
}
void strip_file()
{
next_label:
fread(buffer, 2, 1, infd); /* Get label length */
buffer[2] = '\0';
lblen = atoi(buffer);
if (lblen == 0) /* Better not be zero! */
barf("lost sync");
fread(label, lblen, 1, infd); /* Get the label name */
label[lblen] = '\0';
fread(buffer, 8, 1, infd); /* Get the contents length */
buffer[8] = '\0';
lblen = atoi(buffer);
if (strcmp(label, "DATA") == 0) { /* If done... */
if (lblen != 0)
barf("");
if (debug)
fprintf(stderr, "Positioned at start of file data\n");
goto all_set;
}
fread(buffer, lblen, 1, infd); /* Else skip contents */
goto next_label; /* And loop */
/*
* We've skipped the first header, now do whatever task is needed
*/
all_set:
if (inquire != 0) {
printf("%s is a properly formatted Kermit labeled file\n", infn);
exit(IO_SUCCESS);
}
fab_ofile = cc$rms_fab;
fab_ofile.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
fab_ofile.fab$l_fop = FAB$M_MXV;
fab_ofile.fab$l_fna = infn;
fab_ofile.fab$b_fns = strlen(infn);
fab_ofile.fab$b_rfm = FAB$C_FIX;
fab_ofile.fab$w_mrs = 512;
rab_ofile = cc$rms_rab;
rab_ofile.rab$l_fab = &fab_ofile;
printf("Stripping %s...\n", fab_ofile.fab$l_fna);
rms_sts = sys$create(&fab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
rms_sts = sys$connect(&rab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
fread(buffer, 512, 1, infd);
while (!feof(infd)) {
rab_ofile.rab$l_rbf = buffer;
rab_ofile.rab$w_rsz = 512;
rms_sts = sys$write(&rab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
fread(buffer, 512, 1, infd);
}
rms_sts = sys$close(&fab_ofile);
if (!(rms_sts & 1))
exit(rms_sts);
printf("...done.\n");
exit(IO_SUCCESS);
}