home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckvcvt.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  15KB  |  598 lines

  1. /*
  2.  * ckvcvt - assorted outboard processing for C-Kermit/VMS labeled files
  3.  */
  4.  
  5. /* Revision History:
  6.  * T1.0-00 - 08-Apr-91 - tmk - Initial coding, sync w/ 5A(167) and ckvfio.c
  7.  *                   2.0-066.
  8.  * T1.0-01 - 14-Apr-91 - tmk - Fix errors in help output, show actual system
  9.  *                   message on RMS error.
  10.  * T1.0-02 - 15-Apr-91 - tmk - Redefine fab$b_journal as fab$b_rfm+1.
  11.  * T1.0-03 - 15-Apr-91 - tmk - ACL support, sync w/ 5A(169) and ckvfio.c 2.0-
  12.  *                   069.
  13.  * T1.0-04 - 16-Apr-91 - tmk - Fix _another_ journaling bug (whimper), handle
  14.  *                   missing semicolon in filespec gracefully.
  15.  * T1.0-05 - 04-Sep-92 - tmk - Implement ckvfio.c 087 fix.
  16.  * T1.0-06 - 08-Apr-93 - tmk - Implement ckvfio.c 097 fix.
  17.  * T1.0-07 - 24-Feb-95 - mpjz- Fix for DEC C on VAX.
  18.  * T1.0-08 - 06-Sep-95 - fdc - Get rid of nonportable memmove().
  19.  */
  20.  
  21. #ifdef WINTCP
  22. #include stdio
  23. #include stdlib
  24. #include ctype
  25. #include string
  26. #include rms
  27. #include ssdef
  28. #else
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <ctype.h>
  32. #include <string.h>
  33. #include <rms.h>
  34. #include <ssdef.h>
  35. #endif /* WINTCP */
  36. #define    VERSION    "T1.0-06"
  37.  
  38. #ifndef OLD_VMS
  39. #include <starlet.h>
  40. #endif /* OLD_VMS */
  41.  
  42. #define    R_MODE    "rb"
  43. #define    IO_ERROR    0
  44. #define IO_SUCCESS    1
  45.  
  46. /*
  47.  * Definitions for output file
  48.  */
  49.  
  50. static struct FAB fab_ofile;
  51. static struct RAB rab_ofile;
  52. static struct XABDAT xabdat_ofile;
  53. static struct XABFHC xabfhc_ofile;
  54. static struct XABPRO xabpro_ofile;
  55. static struct XABALL xaball_ofile;
  56. static struct XABRDT xabrdt_ofile;
  57. static short ofile_ffb;
  58. static int ofile_rec;
  59.  
  60. /*
  61.  * Common RMS items
  62.  */
  63.  
  64. static unsigned long int rms_sts;
  65.  
  66. /*
  67.  * Global varables
  68.  */
  69.  
  70. int    keepacl = 0;            /* Preserve ACL data? */
  71. int    backup    = 0;            /* Preserve file backup date? */
  72. int    debug    = 0;            /* Debug output? */
  73. int    notrim    = 0;            /* Don't trim names? */
  74. int    inquire = 0;            /* Testing if labeled? */
  75. int    owner    = 0;            /* Preserve file ownership? */
  76. int    strip    = 0;            /* Just stripping? */
  77. FILE    *infd    = NULL;            /* Input file descriptor */
  78. char    *infn    = NULL;            /* Input file name */
  79. char    *outfn    = NULL;            /* Special output file name */
  80. char    buffer[512];            /* Work buffer */
  81. char    label[99];            /* Label name */
  82. int    lblen    = 0;            /* Length of label */
  83. char    vmsname[255];            /* Stored name */
  84. char    vmsfile[70];            /* Stored file info */
  85. char    vmsacl[512];            /* Stored ACL data */
  86. int    acllen = 0;            /* Size of same */
  87. char    *filptr = vmsfile;        /* Attribute pointer */
  88. int    gotname    = 0;            /* Found name? */
  89. int    gotfile = 0;            /* Found file info? */
  90. int    gotacl = 0;            /* Found ACL info? */
  91. int    bail    = 0;            /* If we should bail out */
  92. char    revdat[8];            /* Revision date */
  93. unsigned short revnum;            /* Revision number */
  94. unsigned short jnlflg;            /* Journaling flags */
  95.  
  96. /*
  97.  * Function prototypes
  98.  */
  99.  
  100. extern int main(int, char **);
  101. void do_help();
  102. void barf(char *);
  103. void strip_file();
  104.  
  105. #if !defined(__DECC) && !defined(VAX)
  106. #define XABP char
  107. #else
  108. #define XABP void
  109. #endif
  110.  
  111. /* memmove() replacement */
  112.  
  113. void
  114. mymove(to, from, len) char * to; char * from; int len; {
  115.     char tmp[16384];
  116.     strncpy((char *)tmp,from,len);
  117.     strncpy(to,(char *)tmp,len);
  118. }
  119.  
  120. /*
  121.  * Ok, let's do it
  122.  */
  123.  
  124. int main(argc, argv)
  125. int argc;
  126. char *argv[];
  127. {
  128.     register char *ap;
  129.     int i, j;                    /* How original */
  130.  
  131.     if (argc < 2)                /* User say anything? */
  132.     do_help();                /* If not... */
  133.  
  134.     if (*argv[1] != '-') {
  135.     infn = argv[1];
  136.     if ((infd = fopen(argv[1], R_MODE)) == NULL) {
  137.         perror(argv[1]);
  138.         exit(IO_ERROR);
  139.     }
  140.     argc--;
  141.     argv++;
  142.     }
  143.     else
  144.     bail++;
  145.  
  146.     while (argc > 1) {
  147.     ap = argv[1];
  148.     if (*ap != '-') {
  149.         fprintf(stderr, "Unknown option '%s',", ap);
  150.         fprintf(stderr, " do CKVCVT -? for help.\n");
  151.     }
  152.     else for (ap++; *ap; ap++) {
  153.         switch (tolower(*ap)) {
  154.  
  155.         case 'a':                /* Preserve ACL's */
  156.         keepacl++;
  157.         break;
  158.  
  159.         case 'b':                /* Preserve backup date */
  160.         backup++;
  161.         break;
  162.  
  163.         case 'd':                /* Debug mode? */
  164.         debug++;
  165.         break;
  166.  
  167.         case 'f':                /* Name output file */
  168.         if (isgraph(ap[1]) != 0)
  169.             outfn = &ap[1];
  170.         else if (argc > 2) {
  171.             outfn = argv[2];
  172.             argc--;
  173.             argv++;
  174.         }
  175.         else {
  176.             break;
  177.         }
  178.         goto next_arg;
  179.  
  180.         case 'i':                /* Inquire if labeled */
  181.         inquire++;
  182.         strip++;
  183.         break;
  184.  
  185.         case 'o':                /* Preserve file ownership */
  186.         owner++;
  187.         break;
  188.  
  189.         case 's':                /* Just strip it */
  190.         strip++;
  191.         break;
  192.  
  193.         case 't':                /* Don't trim filenames */
  194.         notrim++;
  195.         break;
  196.  
  197.         case '?':                /* Emit help text */
  198.         case 'h':
  199.         do_help();
  200.         break;
  201.  
  202.         default:
  203.         fprintf(stderr, "?Unknown option '%c',", *ap);
  204.         fprintf(stderr, " do CKVCVT -? for help\n");
  205.         }
  206.     }
  207.     next_arg:
  208.     argc--;
  209.     argv++;
  210.     }
  211.  
  212.     if (bail != 0)
  213.     exit(IO_ERROR);
  214.  
  215.     fread(buffer, 20, 1, infd);
  216.     if (strncmp(buffer, "KERMIT LABELED FILE:", 20) != 0)
  217.     barf("not a Kermit labeled file");
  218.  
  219.     fread(buffer, 2, 1, infd);
  220.     buffer[2] = '\0';
  221.     lblen = atoi(buffer);
  222.     if (lblen != 2)
  223.     barf("");
  224.  
  225.     fread(buffer, lblen, 1, infd);
  226.  
  227.     if (strip != 0)                /* Stripping headers? */
  228.     strip_file();
  229.  
  230.     if (strncmp(buffer, "D7", 2) != 0)
  231.     barf("not from a VAX/VMS system");
  232.  
  233.     fread(buffer, 6, 1, infd);
  234.     if (strncmp(buffer, "04VERS", 6) != 0)
  235.     barf("");
  236.  
  237.     fread(buffer, 8, 1, infd);
  238.     buffer[8] = '\0';
  239.     lblen = atoi(buffer);
  240.  
  241.     fread(buffer, lblen, 1, infd);
  242.     buffer[lblen] = '\0';
  243.     if (debug)
  244.     fprintf(stderr, "File created under VAX/VMS %s\n", buffer);
  245.  
  246.     fread(buffer, 7, 1, infd);
  247.     if (strncmp(buffer, "05KVERS", 7) != 0)
  248.     barf("");
  249.  
  250.     fread(buffer, 8, 1, infd);
  251.     buffer[8] = '\0';
  252.     lblen = atoi(buffer);
  253.  
  254.     fread(buffer, lblen, 1, infd);
  255.     buffer[lblen] = '\0';
  256.     if (debug)
  257.     fprintf(stderr, "File created with C-Kermit/VMS %s\n", buffer);
  258.  
  259.     next_label:
  260.     fread(buffer, 2, 1, infd);
  261.     buffer[2] = '\0';
  262.     lblen = atoi(buffer);
  263.     if (lblen == 0)
  264.     barf("lost sync");
  265.  
  266.     fread(buffer, lblen, 1, infd);
  267.     buffer[lblen] = '\0';
  268.     if (strcmp(buffer, "VMSNAME") == 0) {
  269.     fread(buffer, 8, 1, infd);
  270.     buffer[8] = '\0';
  271.     lblen = atoi(buffer);
  272.     fread(vmsname, lblen, 1, infd);
  273.     vmsname[lblen] = '\0';
  274.     gotname++;
  275.     if (debug)
  276.         fprintf(stderr, "Loaded file name block as %s\n", vmsname);
  277.     i = (int)strstr(vmsname, "::");
  278.     if (i != (int)NULL) {
  279.         char temp[255];
  280.         i += 2;
  281.         mymove(vmsname, (char *)i, (int)strlen(vmsname));
  282.     }
  283.         if (!notrim) {
  284.         char temp[255];
  285.         i = (int)strrchr(vmsname, ':');
  286.         j = (int)strrchr(vmsname, ']');
  287.         if (j == (int)NULL)
  288.         j = (int)strrchr(vmsname, '>');
  289.         if (j > i)
  290.         i = j;
  291.         i++;
  292.         mymove(vmsname, (char *)i, (int) strlen(vmsname));
  293.     }
  294.     if (strchr(vmsname, ';') != NULL) {
  295.         for (j = strlen(vmsname); vmsname[j] != ';'; j--)
  296.         ;
  297.         vmsname[j] = '\0';
  298.     }
  299.     if (debug)
  300.         fprintf(stderr, "Resultant filespec: %s\n", vmsname);
  301.     goto next_label;
  302.     }
  303.     else if (strcmp(buffer, "VMSFILE") == 0) {
  304.     fread(buffer, 8, 1, infd);
  305.     buffer[8] = '\0';
  306.     lblen = atoi(buffer);
  307.     fread(vmsfile, lblen, 1, infd);
  308.     vmsfile[lblen] = '\0';
  309.     gotfile++;
  310.     if (debug)
  311.         fprintf(stderr, "Loaded file attribute block\n");
  312.     goto next_label;
  313.     }
  314.     else if (strcmp(buffer, "VMSACL") == 0) {
  315.     fread(buffer, 8, 1, infd);
  316.     buffer[8] = '\0';
  317.     acllen = atoi(buffer);
  318.     fread(vmsacl, acllen, 1, infd);
  319.     vmsacl[acllen] = '\0';
  320.     gotacl++;
  321.     if (debug)
  322.         fprintf(stderr, "Loaded file ACL block\n");
  323.     goto next_label;
  324.     }
  325.     else if (strcmp(buffer, "DATA") == 0) {
  326.     fread(buffer, 8, 1, infd);
  327.     buffer[8] = '\0';
  328.     lblen = atoi(buffer);
  329.     if (lblen != 0)
  330.         barf("");
  331.     if (debug)
  332.         fprintf(stderr, "Positioned at start of file data\n");
  333.     goto all_set;
  334.     }
  335.     else {
  336.     fprintf(stderr, "%s: unrecognized label '%s'\n", infn, buffer);
  337.     fread(buffer, 8, 1, infd);
  338.     buffer[8] = '\0';
  339.     lblen = atoi(buffer);
  340.     if (lblen > 512)
  341.         barf("unrecognized label too long to skip");
  342.     fread(vmsfile, lblen, 1, infd);
  343.     goto next_label;
  344.     }
  345.  
  346.     all_set:
  347.     if (gotfile != 1 || gotname != 1)
  348.     barf("missing required labels");
  349.  
  350. /*
  351.  * Prep the characteristics
  352.  */
  353.  
  354.     fab_ofile = cc$rms_fab;
  355.     fab_ofile.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
  356.     fab_ofile.fab$l_fop = FAB$M_MXV;
  357.     if (outfn == NULL) {
  358.     fab_ofile.fab$l_fna = vmsname;
  359.     fab_ofile.fab$b_fns = strlen(vmsname);
  360.     }
  361.     else {
  362.     fab_ofile.fab$l_fna = outfn;
  363.     fab_ofile.fab$b_fns = strlen(outfn);
  364.     }
  365.     fab_ofile.fab$l_xab = (XABP *)&xabdat_ofile;
  366.     rab_ofile = cc$rms_rab;
  367.     rab_ofile.rab$l_fab = &fab_ofile;
  368.     xabdat_ofile = cc$rms_xabdat;
  369.     xabdat_ofile.xab$l_nxt = (XABP *)&xabrdt_ofile;
  370.     xabrdt_ofile = cc$rms_xabrdt;
  371.     xabrdt_ofile.xab$l_nxt = (XABP *)&xabfhc_ofile;
  372.     xabfhc_ofile = cc$rms_xabfhc;
  373.     xabfhc_ofile.xab$l_nxt = (XABP *)&xabpro_ofile;
  374.     xabpro_ofile = cc$rms_xabpro;
  375.     xabpro_ofile.xab$l_nxt = (XABP *)&xaball_ofile;
  376.     xaball_ofile = cc$rms_xaball;
  377.  
  378. /*
  379.  * Load 'em up
  380.  */
  381.  
  382.     mymove(&xabpro_ofile.xab$w_pro, filptr, 2);
  383.     filptr += 2;
  384.     if (owner != 0)
  385.     mymove(&xabpro_ofile.xab$l_uic, filptr, 4);
  386.     filptr += 4;
  387.     mymove(&fab_ofile.fab$b_rfm, filptr, 1);
  388.     filptr += 1;
  389.     mymove(&fab_ofile.fab$b_org, filptr, 1);
  390.     filptr += 1;
  391.     mymove(&fab_ofile.fab$b_rat, filptr, 1);
  392.     filptr += 5;                /* 4 bytes reserved for char */
  393.     mymove(&fab_ofile.fab$b_fsz, filptr, 1);
  394.     filptr += 1;
  395.     mymove(&xabfhc_ofile.xab$w_lrl, filptr, 2);
  396.     filptr += 2;
  397.     mymove(&fab_ofile.fab$w_mrs, filptr, 2);
  398.     filptr += 2;
  399.     mymove(&xabfhc_ofile.xab$l_ebk, filptr, 4);
  400.     filptr += 4;
  401. /* preserve this as RMS won't remember it for us */
  402.     mymove(&ofile_ffb, filptr, 2);
  403.     filptr += 2;
  404.     mymove(&xaball_ofile.xab$l_alq, filptr, 4);
  405.     filptr += 4;
  406.     mymove(&xaball_ofile.xab$w_deq, filptr, 2);
  407.     filptr += 2;
  408. #ifdef COMMENT /* was: defined(VAX) && defined(__DECC) */
  409. /*
  410.    This is really annoying. The people from DEC changed xaball, but only on
  411.    VAX not AXP!  - mpjz
  412. */
  413.     mymove(&xaball_ofile.xaballdef$$_fill_7, filptr, 1);
  414. #else
  415.     mymove(&xaball_ofile.xab$b_bkz, filptr, 1);
  416. #endif /* COMMENT */
  417.     filptr += 1;
  418.     mymove(&fab_ofile.fab$w_gbc, filptr, 2);
  419.     filptr += 2;
  420.     mymove(&xabfhc_ofile.xab$w_verlimit, filptr, 2);
  421.     filptr += 2;
  422.     mymove(&jnlflg, filptr, 1);
  423.     if (jnlflg !=0)
  424.       printf(
  425.          "Original file was marked for RMS Journaling, this copy is not.\n"
  426.          );
  427.     filptr += 1;
  428.     mymove(&xabdat_ofile.xab$q_cdt, filptr, 8);
  429.     filptr += 8;
  430.     mymove(&revdat, filptr, 8);
  431.     filptr += 8;
  432.     mymove(&revnum, filptr, 2);
  433.     filptr += 2;
  434.     mymove(&xabdat_ofile.xab$q_edt, filptr, 8);
  435.     filptr += 8;
  436.     if (backup != 0)
  437.     mymove(&xabdat_ofile.xab$q_bdt, filptr, 8);
  438.     filptr += 8;
  439.  
  440. /*
  441.  * ACL's?
  442.  */
  443.  
  444.     if(keepacl != 0 && gotacl != 0) {
  445.     xabpro_ofile.xab$l_aclbuf = (XABP *)&vmsacl;
  446.     xabpro_ofile.xab$w_aclsiz = acllen;
  447.     }
  448.  
  449. /*
  450.  * Give it a quick whirl around the dance floor
  451.  */
  452.  
  453.     printf("Creating %s...\n", fab_ofile.fab$l_fna);
  454.     rms_sts = sys$create(&fab_ofile);
  455.     if (!(rms_sts & 1))
  456.     exit(rms_sts);
  457.  
  458.     if(keepacl != 0 && gotacl != 0) {
  459.     if (!(xabpro_ofile.xab$l_aclsts & 1))
  460.         exit(xabpro_ofile.xab$l_aclsts);
  461.     }
  462.  
  463.     rms_sts = sys$connect(&rab_ofile);
  464.     if (!(rms_sts & 1))
  465.     exit(rms_sts);
  466.  
  467.     ofile_rec = 1;
  468.     fread(buffer, 512, 1, infd);
  469.     while (!feof(infd)) {
  470.     rab_ofile.rab$l_rbf = buffer;
  471.     rab_ofile.rab$w_rsz = 512;
  472.     if (ofile_rec == xabfhc_ofile.xab$l_ebk) {
  473.         xabfhc_ofile.xab$w_ffb = ofile_ffb;
  474.         if (ofile_ffb)
  475.         rab_ofile.rab$w_rsz -= (512 - ofile_ffb);
  476.         if (debug) {
  477.         fprintf(stderr,"FFB (first free byte) = %d\n", ofile_ffb);
  478.         fprintf(stderr,"Last record size = %d\n", rab_ofile.rab$w_rsz);
  479.         }
  480.     }
  481.     rms_sts = sys$write(&rab_ofile);
  482.     if (!(rms_sts & 1))
  483.         exit(rms_sts);
  484.     fread(buffer, 512, 1, infd);
  485.     ofile_rec++;
  486.     }
  487.  
  488. /*
  489.  * Update the revision information
  490.  */
  491.  
  492.     mymove(&xabrdt_ofile.xab$q_rdt, revdat, 8);
  493.     mymove(&xabrdt_ofile.xab$w_rvn, &revnum, 2);
  494.  
  495.     rms_sts = sys$close(&fab_ofile);
  496.     if (!(rms_sts & 1))
  497.     exit(rms_sts);
  498.     printf("...done.\n");
  499.     exit(IO_SUCCESS);
  500. }
  501.  
  502. void do_help()
  503. {
  504.     printf("This is CKVCVT %s\n\n", VERSION);
  505.     printf("Usage: CKVCVT infile options\n\n");
  506.     printf("Options:\n");
  507.     printf("         -a     Preserve file ACL data (may require privs)\n");
  508.     printf("         -b     Preserve file backup date\n");
  509.     printf("         -d     Print debugging information\n");
  510.     printf("         -f fn  Name output file fn instead of default\n");
  511.     printf("         -i     Inquire if a file is labeled\n");
  512.     printf("         -o     Preserve file ownership (requires privs)\n");
  513.     printf("         -s     Strip one level of label information\n");
  514.     printf("         -t     Don't trim paths from output file name\n");
  515.     printf("         -?     Display this message\n\n");
  516.     exit(IO_SUCCESS);
  517. }
  518.  
  519. void barf(text)
  520. char *text;
  521. {
  522.     if (text == "")
  523.     fprintf(stderr, "%s: corrupted Kermit labeled file\n", infn);
  524.     else
  525.     fprintf(stderr, "%s: %s\n", infn, text);
  526.     exit(IO_ERROR);
  527. }
  528.  
  529. void strip_file()
  530. {
  531.     next_label:
  532.     fread(buffer, 2, 1, infd);            /* Get label length */
  533.     buffer[2] = '\0';
  534.     lblen = atoi(buffer);
  535.     if (lblen == 0)                /* Better not be zero! */
  536.     barf("lost sync");
  537.  
  538.     fread(label, lblen, 1, infd);        /* Get the label name */
  539.     label[lblen] = '\0';
  540.     fread(buffer, 8, 1, infd);            /* Get the contents length */
  541.     buffer[8] = '\0';
  542.     lblen = atoi(buffer);
  543.     if (strcmp(label, "DATA") == 0) {        /* If done... */
  544.     if (lblen != 0)
  545.         barf("");
  546.     if (debug)
  547.         fprintf(stderr, "Positioned at start of file data\n");
  548.     goto all_set;
  549.     }
  550.     fread(buffer, lblen, 1, infd);        /* Else skip contents */
  551.     goto next_label;                /* And loop */
  552.  
  553. /*
  554.  * We've skipped the first header, now do whatever task is needed
  555.  */
  556.  
  557.     all_set:
  558.     if (inquire != 0) {
  559.     printf("%s is a properly formatted Kermit labeled file\n", infn);
  560.     exit(IO_SUCCESS);
  561.     }
  562.  
  563.     fab_ofile = cc$rms_fab;
  564.     fab_ofile.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
  565.     fab_ofile.fab$l_fop = FAB$M_MXV;
  566.     fab_ofile.fab$l_fna = infn;
  567.     fab_ofile.fab$b_fns = strlen(infn);
  568.     fab_ofile.fab$b_rfm = FAB$C_FIX;
  569.     fab_ofile.fab$w_mrs = 512;
  570.     rab_ofile = cc$rms_rab;
  571.     rab_ofile.rab$l_fab = &fab_ofile;
  572.  
  573.     printf("Stripping %s...\n", fab_ofile.fab$l_fna);
  574.     rms_sts = sys$create(&fab_ofile);
  575.     if (!(rms_sts & 1))
  576.     exit(rms_sts);
  577.  
  578.     rms_sts = sys$connect(&rab_ofile);
  579.     if (!(rms_sts & 1))
  580.     exit(rms_sts);
  581.  
  582.     fread(buffer, 512, 1, infd);
  583.     while (!feof(infd)) {
  584.     rab_ofile.rab$l_rbf = buffer;
  585.     rab_ofile.rab$w_rsz = 512;
  586.     rms_sts = sys$write(&rab_ofile);
  587.     if (!(rms_sts & 1))
  588.         exit(rms_sts);
  589.     fread(buffer, 512, 1, infd);
  590.     }
  591.  
  592.     rms_sts = sys$close(&fab_ofile);
  593.     if (!(rms_sts & 1))
  594.     exit(rms_sts);
  595.     printf("...done.\n");
  596.     exit(IO_SUCCESS);
  597. }
  598.