1
0
Files
2022-09-29 17:59:04 +03:00

168 lines
3.1 KiB
C

/*
* fop -o mk|app|trun|ver [-vdf] [-b nblocks] filename
* -f fork a child to do the work
*
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/param.h> /* BBTOB */
int vflag;
int dflag;
int fflag;
char *progname;
mkfile(char *filename, int nblocks);
verify(char *filename);
appfile(char *filename, int nblocks);
main(int argc, char **argv)
{
int nblocks;
char *filename;
char *op;
int c;
extern int optind;
extern char *optarg;
progname = argv[0];
while ((c = getopt(argc, argv, "o:b:dvf")) != -1)
switch (c) {
case 'v': vflag = 1; break;
case 'd': dflag = 1; break;
case 'f': fflag = 1; break;
case 'o': op = optarg; break;
case 'b': nblocks = atoi(optarg); break;
default:
usage:
fprintf(stderr,
"usage: %s -o m|a|t|v [-dvf] [-b nblocks] file\n",
progname);
exit(1);
}
filename = argv[optind];
if (getenv("DEBUG"))
dflag = 1;
if (getenv("VERBOSE"))
vflag = 1;
if (fflag && fork())
exit(0);
switch ( *op ) {
case 'm': mkfile(filename, nblocks); break;
case 'a': appfile(filename, nblocks); break;
case 't': truncate(filename, BBTOB(nblocks)); break;
case 'v': verify(filename); break;
}
}
mkfile(char *filename, int nblocks)
{
int fd;
struct stat sb;
int t0;
fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644);
if (fd == -1) {
fprintf(stderr, "%s: open(%s): %s\n", progname, filename,
strerror(errno));
exit(1);
}
if (fstat(fd, &sb) == -1) {
fprintf(stderr, "%s: fstat(%s): %s\n", progname, filename,
strerror(errno));
exit(1);
}
for (t0 = 0; t0 < nblocks; t0++) {
char buf[64];
lseek(fd, BBTOB(t0), SEEK_SET);
sprintf(buf, "%15d %15d mkfile\n", t0, sb.st_ino);
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
if (errno != ENOSPC)
fprintf(stderr, "%s: write(%s): %s\n",
progname, filename, strerror(errno));
exit(1);
}
}
fsync(fd);
close(fd);
return 0;
}
verify(char *filename)
{
int fd;
struct stat sb;
char buf[32];
int offset, offval, ino;
fd = open(filename, O_RDONLY);
if (fd == -1) {
perror("open");
exit(1);
}
if (fstat(fd, &sb) == -1) {
perror("fstat");
exit(1);
}
for (offset=0; offset < sb.st_size; offset += BBSIZE) {
lseek(fd, offset, SEEK_SET);
if (read(fd, buf, 32) != 32) {
perror("read");
exit(1);
}
offval = atoi(buf);
ino = atoi(buf+15);
if (offval != offset/BBSIZE || ino != sb.st_ino) {
fprintf(stderr,
"verify: %s offset=%d (should=%d) ino=%d (should=%d)\n",
filename,
offval, offset/BBSIZE, ino, sb.st_ino);
exit(2);
}
}
return 0;
}
appfile(char *filename, int nblocks)
{
int fd;
struct stat statbuf;
int t0;
fd = open(filename, O_WRONLY, 0644);
if (fd == -1) {
/*perror("open");*/
exit(1);
}
if (fstat(fd, &statbuf) == -1) {
perror("stat");
exit(1);
}
nblocks = BTOBB(statbuf.st_size) + nblocks;
for (t0 = BTOBB(statbuf.st_size); t0 < nblocks; t0++) {
char buf[64];
lseek(fd, BBTOB(t0), SEEK_SET);
sprintf(buf, "%15d %15d appfile\n", t0, statbuf.st_ino);
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
if (errno != ENOSPC)
perror("write");
exit(1);
}
}
return 0;
}