--- /dev/null
+/* For allocMem(), freeMem() */
+#include <hadesstd.h>
+
+/* For msglog() */
+#include <hadesstd.h>
+#include <errno.h>
+
+/* For sscanf() */
+#include <stdio.h>
+
+/* For open() */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* For read(), write(), close() */
+#include <unistd.h>
+
+/* For st */
+#include <sys/ioctl.h>
+#include <sys/mtio.h>
+
+#include "ansiTapeLabel.h"
+#include "ansiTape.h"
+
+AnsiTape *openAnsiTape(const char* filename) {
+ int tape;
+ int fileSeqNum = 0;
+ int stat;
+ int i = 0;
+
+ char *vol;
+ char *label;
+
+ AnsiTape *thisAnsiTape;
+ struct mtop mtoperS, *mtoper = &mtoperS;
+
+ thisAnsiTape = allocMem(sizeof(AnsiTape));
+
+ tape = open("/dev/tape", O_RDWR);
+ if(tape == -1) {
+ msglog(LOG_ERR, "Could not open tape!\n");
+ exit(-2);
+ }
+
+ mtoper->mt_op = MTEOM;
+ mtoper->mt_count = 1;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not go to the eom of the tape!\n");
+ exit(-2);
+ }
+
+ mtoper->mt_op = MTBSF;
+ mtoper->mt_count = 3;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+
+ mtoper->mt_op = MTREW;
+ mtoper->mt_count = 1;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not rewind tape!\n");
+ exit(-2);
+ }
+
+ vol = readVolumeLabel(tape);
+
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not rewind tape!\n");
+ exit(-2);
+ }
+
+ if (vol == 0) {
+ writeNewVolumeLabel("HADAQ ", " ", tape);
+ } else {
+ writeVolumeLabel(vol, tape);
+ }
+
+ fileSeqNum = 1;
+ } else {
+ mtoper->mt_op = MTFSF;
+ mtoper->mt_count = 1;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not jump over the filemark!\n");
+ exit(-2);
+ }
+ label = allocMem(80*sizeof(char));
+ do {
+ stat = read(tape, label, 80);
+ if (i == 0) {
+ sscanf(label, "%*31c%4d", &fileSeqNum);
+ fileSeqNum++;
+ }
+ i++;
+ } while (stat != -1);
+ freeMem(label);
+ }
+
+#if 0
+ mtoper->mt_op = MTSETBLK;
+ mtoper->mt_count = 80;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not set blocksize to 80!\n");
+ exit(-2);
+ }
+#endif
+
+ writeHeader(tape, fileSeqNum, filename);
+
+ mtoper->mt_op = MTWEOF;
+ mtoper->mt_count = 1;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not write filemark!\n");
+ exit(-2);
+ }
+
+#if 0
+ mtoper->mt_op = MTSETBLK;
+ mtoper->mt_count = BLOCKSIZE;
+ stat = ioctl(tape, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not set the correct blocksize!\n");
+ exit(-2);
+ }
+#endif
+
+ thisAnsiTape->fd = tape;
+
+ thisAnsiTape->bytesWritten = 0;
+ thisAnsiTape->bufferFull = 0;
+
+ thisAnsiTape->filename = filename;
+ thisAnsiTape->fileSeqNum = fileSeqNum;
+
+ return thisAnsiTape;
+}
+
+int writeAnsiTape(AnsiTape *openTape, const char *src, size_t size) {
+ int returnValue = 0;
+ while(size >= BLOCKSIZE - openTape->bufferFull) {
+ if (openTape->bufferFull < BLOCKSIZE) {
+ memcpy(openTape->buf + openTape->bufferFull, src, BLOCKSIZE - openTape->bufferFull);
+ src += (BLOCKSIZE - openTape->bufferFull);
+ returnValue += (BLOCKSIZE - openTape->bufferFull);
+ openTape->bytesWritten += (BLOCKSIZE - openTape->bufferFull);
+ size -= (BLOCKSIZE - openTape->bufferFull);
+ }
+ write(openTape->fd, openTape->buf, BLOCKSIZE);
+ openTape->bufferFull = 0;
+ }
+ if (size > 0) {
+ memcpy(openTape->buf + openTape->bufferFull, src, size);
+ openTape->bytesWritten += size;
+ openTape->bufferFull += size;
+ returnValue += size;
+ }
+ return returnValue;
+}
+
+int closeAnsiTape(AnsiTape *openTape) {
+ int stat;
+ struct mtop mtoperS, *mtoper = &mtoperS;
+ if(openTape->bufferFull != 0) {
+ write(openTape->fd, openTape->buf, BLOCKSIZE);
+ }
+
+ mtoper->mt_op = MTWEOF;
+ mtoper->mt_count = 1;
+ stat = ioctl(openTape->fd, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not write filemark!\n");
+ exit(-2);
+ }
+
+#if 0
+ mtoper->mt_op = MTSETBLK;
+ mtoper->mt_count = 80;
+ stat = ioctl(openTape->fd, MTIOCTOP, mtoper);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not set blocksize to 80!\n");
+ exit(-2);
+ }
+#endif
+
+ writeTrailer(openTape->fd, openTape->fileSeqNum, openTape->bytesWritten, openTape->filename);
+
+ stat = close(openTape->fd);
+ if (stat == -1) {
+ msglog(LOG_ERR, "Could not close file on tape!\n");
+ exit(-2);
+ freeMem(openTape);
+ }
+
+ return 0;
+}
+
--- /dev/null
+#ifndef ANSITAPE_H
+#define ANSITAPE_H
+
+#define BLOCKSIZE 8192
+
+typedef struct AnsiTapeS {
+ int fd;
+
+ unsigned int bufferFull;
+ unsigned long bytesWritten;
+ char buf[8192];
+
+ const char *filename;
+ int fileSeqNum;
+} AnsiTape;
+
+AnsiTape *openAnsiTape(const char *);
+
+int writeAnsiTape(AnsiTape *, const char *, size_t);
+
+int closeAnsiTape(AnsiTape *);
+
+#endif
+
--- /dev/null
+#include <hadesstd.h>
+
+#include "ansiTapeChar.h"
+
+char *ansichar(char *s, int length) {
+ int i, end = 0;
+ for(i=0 ; i<length ; i++) {
+ if (end == 0) {
+ if(isupper(s[i]) || isdigit(s[i])) {
+ } else if(islower(s[i])) {
+ s[i] = toupper(s[i]);
+ } else {
+ switch (s[i]) {
+ case (' '):
+ case ('!'):
+ case ('"'):
+ case ('%'):
+ case ('&'):
+ case ('\''):
+ case ('('):
+ case (')'):
+ case ('*'):
+ case ('+'):
+ case (','):
+ case ('-'):
+ case ('_'):
+ case ('.'):
+ case ('/'):
+ case (':'):
+ case (';'):
+ case ('<'):
+ case ('='):
+ case ('>'):
+ case ('?'):
+ break;
+ case ('\0'):
+ s[i] = ' ';
+ end = 1;
+ break;
+ default:
+ s[i] = 'Z';
+ break;
+ }
+ }
+ } else {
+ s[i] = ' ';
+ }
+ }
+ s[length] = '\0';
+
+ return s;
+}
+
+char *unixchar(char *s, int length) {
+ int i, end = 0;
+ for(i=0 ; i<length ; i++) {
+ if (end == 0) {
+ if(s[i] == '\0') {
+ s[i] = ' ';
+ end = 1;
+ }
+ } else {
+ s[i] = ' ';
+ }
+ }
+ s[length] = '\0';
+
+ return s;
+}
+
--- /dev/null
+#ifndef ANSITAPECHAR_H
+#define ANSITAPECHAR_H
+
+char *ansichar(char *, int);
+char *unixchar(char *, int);
+
+#endif
+
--- /dev/null
+/* For msglog() */
+#include <hadesstd.h>
+#include <errno.h>
+/* For allocMem(), freeMem() */
+#include <hadesstd.h>
+/* For memcpy() */
+#include <string.h>
+
+/* For read(), write(), gethostname() */
+#include <unistd.h>
+
+/* For time() */
+#include <time.h>
+/* For getpwent() */
+#include <pwd.h>
+#include <sys/types.h>
+/* For getuid() */
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "ansiTapeChar.h"
+#include "ansiTapeLabel.h"
+
+/* Functions concerning the volume label */
+
+char *readVolumeLabel(int tape) {
+ char *vol;
+ int stat;
+ vol = allocMem(80*sizeof(char));
+ stat = read(tape, vol, 80);
+ if(stat == -1) {
+ vol = 0;
+ }
+
+ return vol;
+ freeMem(vol);
+}
+
+int writeVolumeLabel(const char *vol, int tape) {
+ char *v;
+ int stat;
+ v = allocMem(80*sizeof(char));
+ memcpy(v, vol, 80);
+ stat = write(tape, v, 80);
+ if(stat == -1) {
+ msglog(LOG_ERR, "Could not write volume label to tape!\n");
+ exit(-3);
+ }
+
+ freeMem(v);
+ return 0;
+}
+
+int writeNewVolumeLabel(const char *volId, const char *ownerId, int tape) {
+ char *vol, *oid;
+ int stat;
+
+#ifdef LINUX
+ const char *impId = "LINUXHADAQ023";
+#endif
+#ifdef UNIX
+ const char *impId = "UNIXHADAQ0023";
+#endif
+#ifndef LINUX
+#ifndef UNIX
+ const char *impId = " HADAQ0023";
+#endif
+#endif
+
+ vol = allocMem(80*sizeof(char));
+
+ oid = allocMem(15*sizeof(char));
+ if (80 != sprintf(vol, "VOL1HADAQ %s%s 4", impId, ansichar(oid, 14))) {
+ msglog(LOG_ERR, "LabelV not 80 char!\n");
+ exit(-3);
+ }
+ freeMem(oid);
+
+ stat = write(tape, vol, 80);
+ if(stat == -1) {
+ msglog(LOG_ERR, "Could not write volume label to tape!\n");
+ exit(-3);
+ }
+
+ freeMem(vol);
+ return 0;
+}
+
+/* Functions concerning the hdr-label and the eof-label */
+
+int writeLabel(const char *hdreof, int tape, int fileSeqNum, int bytes, const char *filename) {
+ int stat;
+ int i;
+ int blockSize = BLOCKSIZE;
+ char hostname[21];
+ char *creaCent;
+ char label[81];
+ char fn[37];
+#ifdef LINUX
+ const char *impId = "LINUXHADAQ023";
+#endif
+#ifdef UNIX
+ const char *impId = "UNIXHADAQ0023";
+#endif
+#ifndef LINUX
+ #ifndef UNIX
+ const char *impId = " HADAQ0023";
+ #endif
+#endif
+ uid_t uid;
+ char *user;
+ time_t tim;
+ struct passwd pwentryS, *pwentry = &pwentryS;
+ struct tm cdS, *cd = &cdS;
+
+ tim = time(0);
+ cd = gmtime(&tim);
+ if ((cd->tm_year)/100 == 19) {
+ creaCent = " ";
+ } else {
+ creaCent = "0";
+ }
+
+ strcpy(fn, filename);
+ if (80 != sprintf(label, "%-3s%1d%-17s%06d%04d%04d%04d%02d%1s%02d%03d%6d%1s%06d%-13s%-7s",
+ hdreof,
+ 1,
+ ansichar(fn, 17),
+ 1,
+ 1,
+ fileSeqNum,
+ 1,
+ 0,
+ creaCent, (cd->tm_year)%100, cd->tm_yday,
+ 99366,
+ " ",
+ (bytes + BLOCKSIZE -1) / BLOCKSIZE,
+ impId,
+ "")
+ ) {
+ msglog(LOG_ERR, "Label1 not 80 char!\n");
+ exit(-3);
+ }
+
+ stat = write(tape, label, 80);
+ if(stat == -1) {
+ msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
+ exit(-3);
+ }
+
+ if (80 != sprintf(label, "%-3s%1d%1s%05d%05d%-21s%1s%010d%-3s%02d%28s",
+ hdreof,
+ 2,
+ "F",
+ blockSize,
+ blockSize,
+ "",
+ "M",
+ bytes,
+ "",
+ 0,
+ "")
+ ) {
+ msglog(LOG_ERR, "Label2 not 80 char!\n");
+ exit(-3);
+ }
+ stat = write(tape, label, 80);
+ if(stat == -1) {
+ msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
+ exit(-3);
+ }
+
+ uid = getuid();
+ while (NULL != (pwentry = getpwent()) && pwentry->pw_uid != uid) {
+ }
+
+ if (NULL != pwentry) {
+ user = pwentry->pw_name;
+ } else {
+ user = "hades";
+ }
+
+ gethostname(hostname, 20);
+
+ if (80 != sprintf(label, "%-3s%1d%010d%-10s%-20s%-36s",
+ hdreof,
+ 3,
+ tim,
+ user,
+ hostname,
+ filename)
+ ) {
+ msglog(LOG_ERR, "Label3 not 80 char!\n");
+ exit(-3);
+ }
+
+ stat = write(tape, label, 80);
+ if(stat == -1) {
+ msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
+ exit(-3);
+ }
+ return 0;
+}
+
+int writeHeader(int tape, int fileSeqNum, const char *filename) {
+ return writeLabel("HDR", tape, fileSeqNum, 0, filename);
+}
+
+int writeTrailer(int tape, int fileSeqNum, unsigned long numBytes, const char *filename) {
+ return writeLabel("EOF", tape, fileSeqNum, numBytes, filename);
+}
--- /dev/null
+#ifndef ANSITAPELABEL_H
+#define ANSITAPELABEL_H
+
+#define BLOCKSIZE 8192
+
+char *readVolumeLabel(int);
+int writeVolumeLabel(const char *, int);
+int writeNewVolumeLabel(const char *, const char *, int);
+
+int writeHeader(int, int, const char *);
+int writeTrailer(int, int, unsigned long, const char *);
+
+#endif
+