home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
f
/
ftp-102.zip
/
ftape-1.02
/
qic
/
volume.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-12
|
5KB
|
190 lines
/* Manipulate the volume header.
Copyright (C) 1992 David L. Brown, Jr.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <alloca.h>
#include "qic.h"
#include "header.h"
/* The volume table. */
struct vt_entry *vt;
/* Table entries. */
int vt_size;
/* Table size in bytes. */
int vt_byte_size;
/* From date.c */
extern long current_qic_time (void);
void
create_vt (void)
{
int size;
size = count_space (current_header.data_first);
vt_size = size * BLOCK_SIZE / sizeof (struct vt_entry);
vt_byte_size = (vt_size
* sizeof (struct vt_entry));
vt = ((struct vt_entry *)
xmalloc (vt_byte_size));
bzero (vt, vt_byte_size);
}
void
read_vt (void)
{
struct memory_segment data;
data.data = alloca (BLOCK_SIZE * BLOCKS_PER_SEGMENT);
data.blocks = BLOCKS_PER_SEGMENT;
data.marked_bad = current_header.bad_sectors[current_header.data_first];
if (!read_good_segment (&data, current_header.data_first))
error (1, 0, "Cannot read volume table");
vt_size = (count_space (current_header.data_first)
* BLOCK_SIZE / sizeof (struct vt_entry));
vt_byte_size = (vt_size * sizeof (struct vt_entry));
vt = (struct vt_entry *) xmalloc (vt_byte_size);
bcopy (data.data, vt, vt_byte_size);
}
void
write_vt (void)
{
struct memory_segment data;
data.data = alloca (BLOCK_SIZE * BLOCKS_PER_SEGMENT);
/* Not quite right. */
data.blocks = count_space (current_header.data_first) + 3;
data.marked_bad = current_header.bad_sectors[current_header.data_first];
bcopy (vt, data.data, vt_byte_size);
write_good_segment (&data, current_header.data_first);
}
int
valid_vt (struct vt_entry *v)
{
return (v->signature[0] == 'V'
&& v->signature[1] == 'T'
&& v->signature[2] == 'B'
&& v->signature[3] == 'L');
}
/* Append an entry to the vt. */
void
append_vt (char *name, int start, int last, int bytes,
int continued, int sequence)
{
int i;
int first = current_header.data_first + 1;
for (i = 0; i < vt_size && valid_vt (&vt[i]); i++)
{
first = vt[i].last_segment + 1;
}
/* !!!!! This should be checked before the data is written. */
if (i >= vt_size)
error (1, 0, "Volume table is full.");
vt[i].signature[0] = 'V';
vt[i].signature[1] = 'T';
vt[i].signature[2] = 'B';
vt[i].signature[3] = 'L';
vt[i].start_segment = start;
vt[i].last_segment = last;
strncpy (vt[i].description, name, 44);
LLONG_SET (vt[i].time, current_qic_time ());
vt[i].flags = (continued ? 2 : 0);
vt[i].sequence = sequence;
vt[i].password[0] = 0;
LLONG_SET (vt[i].directory_size, 0);
LLONG_SET (vt[i].data_size, bytes);
vt[i].os_version = 0x0403;
vt[i].volume_label[0] = 0;
vt[i].logical_origin = ' ';
vt[i].physical_origin = 0;
vt[i].compression_type = 0;
}
/* Delete entries past a numbered entry. */
void
delete_vt (int from)
{
int i;
for (i = from; i < vt_size; i++)
{
bzero (&vt[i], sizeof (struct vt_entry));
}
}
/* Produce a listing of the vt. */
void
list_vt ()
{
int i;
char name[45];
for (i = 0; i < vt_size && valid_vt (&vt[i]); i++)
{
name[44] = 0;
strncpy (name, vt[i].description, 44);
#if 0
fprintf (stderr, "%d, %d\n", vt[i].start_segment, vt[i].last_segment);
#endif
fprintf (stdout, "%3d %c%8d (%5.fk) %s %s\n",
i,
(vt[i].flags & 2) ? '*' : ' ',
LLONG (vt[i].data_size),
((BLOCK_SIZE
* count_spaces (vt[i].start_segment, vt[i].last_segment))
/ 1024.0),
qic_to_text_time (LLONG(vt[i].time)),
name);
if (vt[i].sequence > 1)
fprintf (stdout, " Volume %d\n", vt[i].sequence);
}
}
/* Find first free segment on tape. */
int
first_free (void)
{
int i;
int first = current_header.data_first + 1;
for (i = 0; i < vt_size && valid_vt (&vt[i]); i++)
{
first = vt[i].last_segment + 1;
}
return (first);
}