/* For msglog() */
 #include <hadesstd.h>
 #include <errno.h>
+#include <error.h>
 
 /* For fdopen(), fclose(), sscanf(), printf() */
 #include <stdio.h>
  
 /* For st */
 #include <sys/ioctl.h>
-#include <sys/mtio.h>                                                           
+#include <sys/mtio.h>
 
 #include "tapelabel.h"
 #include "tape.h"
 
-static FILE *openTape(const char* filename) {
+FILE *openTape(const char* filename) {
        int tape;
        int fileSeqNum;
        int stat;
 
        FILE *outFile;
 
-       struct mtop *eom, *sbm, *rewind, *setblck;
+       struct mtop mtoperS, *mtoper = &mtoperS;
 
-       tape = open(filename, O_RDWR);
+       tape = open("/dev/tape", O_RDWR);
        if(tape == -1) {
                msglog(LOG_ERR, "Could not open tape!\n");
                exit(-2);
        }
 
-       eom->mt_op = MTEOM;
-       eom->mt_count = 1;
-       stat = ioctl(tape, MTIOCTOP, &eom);
+       mtoper->mt_op = MTEOM;
+       mtoper->mt_count = 1;
+       stat = ioctl(tape, MTIOCTOP, mtoper);
        if (stat == -1) {
                        msglog(LOG_ERR, "Could not go to the eon of the tape!\n");
+                       perror("What went wrong going to the EOM via ioctl?");
                exit(-2);
        }
 
-       sbm->mt_op = MTBSF;
-       sbm->mt_count = 2;
-       stat = ioctl(tape, MTIOCTOP, &sbm);
+       mtoper->mt_op = MTBSF;
+       mtoper->mt_count = 3;
+       stat = ioctl(tape, MTIOCTOP, mtoper);
        if (stat == -1) {
 
-               rewind->mt_op = MTREW;
-               rewind->mt_count = 1;
-               stat = ioctl(tape, MTIOCTOP, &rewind);
+               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, &rewind);
+               stat = ioctl(tape, MTIOCTOP, mtoper);
                if (stat == -1) {
                        msglog(LOG_ERR, "Could not rewind tape!\n");
                        exit(-2);
                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);
                } while (stat != -1);
                freeMem(label);
        }
+       msglog(LOG_INFO, "Been after all the tape moving operations, now trying to write the Header.\n");
 
        writeHeader(tape, fileSeqNum, filename);
+       msglog(LOG_INFO, "Wrote Header.\n");
 
-       setblck->mt_op = MTSETBLK;
-       setblck->mt_count = BLOCKSIZE;
-       stat = ioctl(tape, MTIOCTOP, &setblck);
+       mtoper->mt_op = MTSETBLK;
+       mtoper->mt_count = BLOCKSIZE;
+       stat = ioctl(tape, MTIOCTOP, mtoper);
        if (stat == -1) {
                        msglog(LOG_ERR, "Could not go to the eon of the tape!\n");
                exit(-2);
 
        outFile = fdopen(tape, "wb");
        setvbuf(outFile, 0, _IOFBF, BLOCKSIZE);
+
+       return outFile;
 }
 
 int closeTape(FILE *openTape, unsigned long numBytes, const char *filename) {
 
                msglog(LOG_ERR, "Could not read volume label from tape!\n");
                exit(-3);
        }
+
        return vol;
        freeMem(vol);
 }
                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;
+       char *vol, *oid;
        int stat;
 
 #ifdef LINUX
 
        vol = allocMem(80*sizeof(char));
 
-       sprintf(vol, "VOL1HADAQ               %s%s                            4", impId, ansichar(ownerId, 14));
+       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);
 
+       freeMem(vol);
        return 0;
 }
 
 /* Functions concerning the hdr-label and the eof-label */
 
-int writeHeader(int tape, int fileSeqNum, const char *filename) {
+int writeLabel(const char *hdreof, int tape, int fileSeqNum, int bytes, const char *filename) {
        int stat;
        int i;
        int blockSize = BLOCKSIZE;
-       char *hostname;
+       char hostname[21];
        char *creaCent;
-       char *label;
+       char label[81];
+       char fn[37];
 #ifdef LINUX
        const char *impId = "LINUXHADAQ023";
 #endif
        const char *impId = "    HADAQ0023";
   #endif
 #endif
-       uid_t uid, first_uid;
+       uid_t uid;
+       char *user;
        time_t tim;
-       struct passwd *pwentry;
-       struct tm *cd;
-
-       gethostname(hostname, 20);
+       struct passwd pwentryS, *pwentry = &pwentryS;
+       struct tm cdS, *cd = &cdS;
 
        tim = time(0);
        cd = gmtime(&tim);
        if ((cd->tm_year)/100 == 19) {
-               *creaCent = ' ';
+               creaCent = " ";
        } else {
-               *creaCent = '0';
+               creaCent = "0";
        }
 
-       label = allocMem(80*sizeof(char));
-
-       sprintf(label, "HDR1                 %s0000010001%04d000100%s%02d%03d 99366 000000%s       ", ansichar(filename, 17), fileSeqNum, creaCent, (cd->tm_year)%100, cd->tm_yday, impId);
-       stat = write(tape, label, 80);
-       if(stat == -1) {
-               msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
+       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);
        }
 
-       sprintf(label, "HDR2F%05d%05d010664            bin           33000                            ", blockSize, blockSize);
        stat = write(tape, label, 80);
        if(stat == -1) {
                msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
                exit(-3);
        }
 
-       uid = getuid();
-       pwentry = getpwent();
-       first_uid = pwentry->pw_uid;
-       do {
-               pwentry = getpwent();
-       } while (pwentry->pw_uid != uid && pwentry->pw_uid != first_uid);
-
-       if (pwentry->pw_name == "root") {
-               pwentry->pw_name = "hades";
+       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);
        }
-
-       sprintf(label, "HDR3%010d%s%s%s", tim, unixchar(pwentry->pw_name, 10), unixchar(hostname, 20), unixchar(filename, 36));
        stat = write(tape, label, 80);
        if(stat == -1) {
                msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
                exit(-3);
        }
 
-       freeMem(label);
-       return 0;
-}
-
-
-int writeTrailer(int tape, int fileSeqNum, unsigned long numBytes, const char *filename) {
-       int stat;
-       int i;
-       int blockSize = BLOCKSIZE;
-       char *hostname;
-       char *creaCent;
-       char *label;
-#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, first_uid;
-       time_t tim;
-       struct passwd *pwentry;
-       struct tm *cd;
-
-       gethostname(hostname, 20);
+       uid = getuid();
+       while (NULL != (pwentry = getpwent()) && pwentry->pw_uid != uid) {
+       }
 
-       tim = time(0);
-       cd = gmtime(&tim);
-       if ((cd->tm_year)/100 == 19) {
-               *creaCent = ' ';
+       if (NULL != pwentry) {
+               user = pwentry->pw_name;
        } else {
-               *creaCent = '0';
+               user = "hades";
        }
 
-       label = allocMem(80*sizeof(char));
-
-       sprintf(label, "EOF1                 %s0000010001%04d000100%s%02d%03d 99366 %06d%s       ", ansichar(filename, 17), fileSeqNum, creaCent, (cd->tm_year)%100, cd->tm_yday, (numBytes + BLOCKSIZE - 1)/BLOCKSIZE, impId);
-       stat = write(tape, label, 80);
-       if(stat == -1) {
-               msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
-               exit(-3);
-       }
+       gethostname(hostname, 20);
 
-       sprintf(label, "EOF2F%05d%05d010664            bin %010d33000                            ", blockSize, blockSize, numBytes);
-       stat = write(tape, label, 80);
-       if(stat == -1) {
-               msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
+       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);
        }
 
-       uid = getuid();
-       pwentry = getpwent();
-       first_uid = pwentry->pw_uid;
-       do {
-               pwentry = getpwent();
-       } while (pwentry->pw_uid != uid && pwentry->pw_uid != first_uid);
-
-       if (pwentry->pw_name == "root") {
-               pwentry->pw_name = "hades";
-       }
-
-       sprintf(label, "EOF3%010d%s%s%s", tim, unixchar(pwentry->pw_name, 10), unixchar(hostname, 20), unixchar(filename, 36));
        stat = write(tape, label, 80);
        if(stat == -1) {
                msglog(LOG_ERR, "Could not write ANSI label on tape!\n");
                exit(-3);
        }
-
-       freeMem(label);
        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);
+}