#include <stdio.h>
#include <errno.h>
#include <sys/file.h>
#include <sys/tape.h>

#define MAXPNAME 48                     /* Maximum logical device     */
                                        /* plus file name length.     */
#define MAXAPATH 256                    /* Maximum path name length.  */

   int IBM_taptyp;                      /* 0-3 unknown,reel,Exabyte,  */
                                        /* DAT                        */

ztpop2_(fcb, pname, mode, ierr)
/*--------------------------------------------------------------------*/
/*! open a tape device for double-buffer, asymchronous IO             */
/*# IO-basic Tape                                                     */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995, 2000                                         */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  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 of   */
/*;  the License, 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; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/*  Open a tape drive for "map" (double buffered, asynchronous) I/O.  */
/*  Inputs:                                                           */
/*     pname   C*48   Physical file name                              */
/*     mode    I      Mode indicator: 0 => read only                  */
/*                                    2 => read/write                 */
/*  Output:                                                           */
/*     fcb     I(*)   File control block for opened tape drive        */
/*     ierr    I      Error return code: 0 => no error                */
/*                             2 => no such logical device            */
/*                             3 => device not found                  */
/*                             6 => other open error                  */
/*  IBM version - synchronous I/O only, gets IBM type                 */
/*--------------------------------------------------------------------*/
int *fcb, *mode, *ierr;
char pname[MAXPNAME];
/*--------------------------------------------------------------------*/
{
                                        /* Offsets to entries in the  */
                                        /* file control blocks        */
   extern int Z_fcbfd, Z_fcbreq, Z_fcberr, Z_fcbxfr, Z_fcbsiz,
      Z_fcbsp1, Z_fcbsp2, Z_fcbsp3, Z_fcbsp4;
                                        /* # FTAB elements per map    */
                                        /* file control block         */
   extern int Z_mfcb;
   extern int errno;
   int llen, xlen, xlnb, jerr, fd, dupfd, ifd, n7 = 7;
   struct stchgp chgp;
   char msg[80];
   register int i, j;
   char lognam[MAXPNAME], pathname[MAXAPATH], cmd[256], *chptr;
   FILE *mpipe;
/*--------------------------------------------------------------------*/
   *ierr = 0;
                                        /* Extract logical device.    */
   for (i = 0; i < MAXPNAME && pname[i] != ':'; i++)
      lognam[i] = pname[i];
   lognam[i] = '\0';
                                        /* Translate logical device   */
                                        /* name and null terminate.   */
   llen = MAXPNAME;
   xlen = MAXAPATH;
   ztrlo2_ (&llen, lognam, &xlen, pathname, &xlnb, &jerr);
   if (jerr != 0) {
      *ierr = 3;
      }
   else {
      pathname[xlnb] = '\0';
      chptr = pathname + 5;
      sprintf (cmd, "/etc/lsdev -C -r type -l %s", chptr);
      for (i = 0; i < sizeof(cmd); i++) {
         if (cmd[i] == '.') {
            cmd[i] = '\0' ;
            break ;
            }
         }
      if  ((mpipe = popen (cmd, "r")) == NULL) {
         IBM_taptyp = 0;
         }
      else {
         fgets (cmd, sizeof(cmd), mpipe);
         pclose (mpipe);
         j = 99;
         for (i = 0; i < 20; i ++) {
            if (cmd[i] == '\0') break ;
            if (cmd[i] > ' ') j = i;
            if (cmd[i] < ' ') {
               cmd[i] = '\0';
               break ;
               }
            }
         cmd[j+1] = '\0';

/*                                        DEBUG                      */
/*       printf ("Device type returned = %s for tape\n", cmd);       */

         if (strcmp (cmd, "9trk") == 0) {
            IBM_taptyp = 1;
            }
         else if ((strcmp (cmd, "8mm") == 0) ||
		  (strcmp (cmd, "8mm5gb") == 0)) {
            IBM_taptyp = 2;
            sprintf (cmd, "/etc/lsattr -E -a extfm -F value -l %s", chptr);
            for (i = 0; i < sizeof(cmd); i++) {
               if (cmd[i] == '.') {
                  cmd[i] = '\0' ;
                  break ;
                  }
               }
            if ((mpipe = popen (cmd, "r")) == NULL) {
               }
            else {
               fgets (cmd, sizeof(cmd), mpipe);
               pclose (mpipe);
               j = 99;
               for (i = 0; i < 20; i ++) {
                  if (cmd[i] == '\0') break ;
                  if (cmd[i] > ' ') j = i;
                  if (cmd[i] < ' ') {
                     cmd[i] = '\0';
                     break ;
                     }
                  }
               cmd[j+1] = '\0';
               if (strcmp (cmd, "yes") != 0) {
                  sprintf (msg,
    "ZTPOP2: 8mm (8200) drive uses short EOFs - DOES NOT WORK IN AIPS");
                  zmsgwr_ (msg, &n7);
                  *ierr = 6;
                  }
               }
            }
         else if (strcmp (cmd, "150mb") == 0) {
            IBM_taptyp = 3;
            }
         else if (strcmp (cmd, "ost") == 0) {
            IBM_taptyp = 0;
            }
         else {
            IBM_taptyp = 0;
            }
         }
                                        /* Open the tape drive        */
                                        /* according to "mode".       */
                                        /* If this is Wes' on-line    */
                                        /* device, use special open   */
                                        /* & use fake file descriptor */
      errno = 0;
      if (!strncasecmp(pathname, "ON-LINE", 7)) {
         ifd = -99;
         fd = olopen_(&ifd, pathname, strlen(pathname));
/*         if ((fd == -1) && (errno == -1))
            ifd = -99;
            fprintf (stderr, "olopen errors = -1 --- retry\n");
            fd = olopen_(&ifd, pathname, strlen(pathname)); */
         }
      else {
         if (*ierr == 0) {
            fd = open (pathname, *mode);
            if (fd == -1) {
               *(fcb + Z_fcberr) = errno;
                                        /* Device doesn't exist.      */
               if (errno == ENOENT)
                  *ierr = 2;
                                        /* Some other open error.     */
               else
                  *ierr = 6;
               sprintf (msg,
                  "ZTPOP2 error opening tape errno %d",errno);
               zmsgwr_ (msg, &n7);
               sprintf (msg,
                  "ZTPOP2 mode %d name %s", *mode, pathname);
               zmsgwr_ (msg, &n7);               }
            }
         }
                                        /* Get duplicate file         */
                                        /* descriptor for 2nd buffer  */
                                        /* (this is only necessary    */
                                        /* for I/O wait servicing).   */
      if (*ierr == 0) {
         *(fcb + Z_fcbfd) = fd;
                                        /* Single buffered            */
         if (fd < 0)
            *(fcb + Z_mfcb + Z_fcbfd) = fd;
         else {
            dupfd = dup(fd);
            if (dupfd == -1) {
                                        /* Store 2nd buffer info in   */
                                        /* 1st buffer FCB for error   */
                                        /* processing (kludge).       */
               *(fcb + Z_mfcb + Z_fcbfd) = dupfd;
               for (i = 0; i < Z_mfcb; i++)
                  *(fcb + i) = *(fcb + Z_mfcb + i);
               *(fcb + Z_fcberr) = errno;
               close (fd);
               *ierr = 6;
               }
            else {
               *(fcb + Z_mfcb + Z_fcbfd) = dupfd;
                                        /* Enable asynchronous mode   */
                                        /* for both buffers here (not */
                                        /* implemented in this        */
                                        /* version).                  */
                                        /* Set blocksize 0 all tapes  */
               chgp.st_ecc = ST_NOECC ;
               chgp.st_blksize = 0;
               if (ioctl (fd, STIOCHGP, &chgp) == -1) {
                  sprintf (msg,
                     "ZTPOP2 error setting tape blocksize to 0");
                  zmsgwr_ (msg, &n7);
                  }
               }
            }
         }
      }

   return;
}
