Node.js

Node.js

Node.js

 View Only

Tagging files with Node.js on z/OS using mvsutils

By Wayne Zhang posted 08/05/21 07:20 PM

  
When working with files on z/OS, it is often necessary to tag files appropriate to their encoding. This article will demonstrate how you can use IBM SDK for Node.js - z/OS to tag your files on z/OS by leveraging the mvsutils Node.js module.

Step 1: Getting Started

Download IBM SDK for Node.js - z/OS and follow the IBM Documentation installation instructions to install Node.js.

Step 2: Start a New Project

We need to start by creating a project directory. For this tutorial, we will simply call our project my-app.

$ mkdir my-app
$ cd my-app

Now that we changed our working directory to the project directory, we will initialize our working directory as a new "npm package". This will allow us to install the mvsutils node module as a dependency later. The following command will create a package.json file which describes our application, and contains information about our application's dependencies:

$ npm init --yes

Next, we will install mvsutils as a dependency.

$ npm install mvsutils

Once mvsutils has finished installing, we are ready to begin writing our application.

Step 3: Checking the Tag of an Existing File

Often times, we may want to check if a file is tagged before deciding what to do with it. Every file has a coded character set identifier (CCSID), which is a number that identifies the encoding a file is tagged as. We can use the GetFileCcsid() function from mvsutils to check both the CCSID and text mode of a file. For demonstration purposes, we will first manually create file.txt via the command line.

$ touch file.txt

Since we created our file.txt via the touch command, file.txt will be an untagged file with CCSID of 0 and text mode set to off. We can verify that this is the case using the ls command. By using the -T option, we can check the tag of each file listed.

$ ls -T
- untagged    T=off file.txt
t ISO8859-1   T=on  check.js
                    node_modules
t ISO8859-1   T=on  package-lock.json
t ISO8859-1   T=on  package.json

Now, let's begin writing our Node.js application. We will create check.js where we'll write the code to check the tag of file.txt. Open check.js in an editor of your choosing and input the following:

const fs = require('fs');
const mvsutils = require('mvsutils');

fs.open('file.txt', 'r', (err, fd) => {
  let attr = mvsutils.GetFileCcsid(fd);
  console.log('file text mode', attr.text, ' file ccsid', attr.ccsid);
  fs.close(fd);
});

Our code will print out the text mode of file.txt, as well as the ccsid of file.txt. Since file.txt is an untagged file, when we execute our code we should see the following output:

$ node check.js
file text mode 0  file ccsid 0


Step 4: Tagging an Existing File

Now that we are able to verify that file.txt is not tagged, we can use the SetFileCcsid() function from mvsutils to tag it. For this tutorial, we will tag it as ASCII. The CCSID of ASCII is 819, and the text mode needs to be set to on.

Let's amend our code from the previous step, and create tag.js where we'll input our new code:

const fs = require('fs');
const mvsutils = require('mvsutils');

fs.open('file.txt', 'r', (err, fd) => {
  let attr = mvsutils.GetFileCcsid(fd);

  // ASCII is CCSID 819.
  if (!attr.text || attr.ccsid != 819) {
    // To set text mode to "on", put 1 for the second parameter.
    let result = mvsutils.SetFileCcsid(fd, 1, 819);

    if (result.rc == 0) {
      console.log('success');
    } else {
      console.log('failed');
    }
  } else {
    console.log('already tagged');
  }

  fs.close(fd);
});

Our code will first use GetFileCcsid() as seen in the previous step to check the CCSID and text mode of file.txt. It will then tag file.txt as ASCII only if the file isn't tagged as such already. We can now execute our code, and if everything works correctly, we should see it output "success":

$ node tag.js
success

We can either use the ls command, or check.js from the previous step to verify that file.txt is correctly tagged as ASCII:

$ ls -T
t ISO8859-1   T=on  check.js
t ISO8859-1   T=on  file.txt
                    node_modules
t ISO8859-1   T=on  package-lock.json
t ISO8859-1   T=on  package.json
t ISO8859-1   T=on  tag.js
$ node check.js
file text mode 1  file ccsid 819


Step 5: Tagging a New File

So far, we have seen how an existing file can be tagged. Sometimes, it may be necessary to tag a file that is created at runtime. When Node.js creates a new file, it will automatically be tagged as ASCII by default. But what if we need to write an EBCDIC file so that it can be consumed by z/OS services? We can once again use the SetFileCcsid() function from mvsutils in a manner similar to the previous step.

For the purpose of this tutorial, let's say we have an application new.js that creates EBCDIC files:

const fs = require('fs');

let buffer = Buffer.from([0xC8, 0x85, 0x93, 0x93, 0x96, 0x6B, 0x40,
                          0xE6, 0x96, 0x99, 0x93, 0x84, 0x5A, 0x15]);

fs.open('hello.ebcdic', 'wx', (err, fd) => {
  if (err) throw err;

  fs.write(fd, buffer, (err) => {
    if (err) throw err;

    console.log('written');
    fs.close(fd);
  });
});

This application will create a new file named hello.ebcdic, and write Hello, World!\n to it in EBCDIC. However, since Node.js will tag this file as ASCII, this file will be unreadable. Here is where we can use mvsutils to amend our application by tagging the file as EBCDIC after it is written:

const fs = require('fs');
const mvsutils = require('mvsutils');

let buffer = Buffer.from([0xC8, 0x85, 0x93, 0x93, 0x96, 0x6B, 0x40,
                          0xE6, 0x96, 0x99, 0x93, 0x84, 0x5A, 0x15]);

fs.open('hello.ebcdic', 'wx', (err, fd) => {
  if (err) throw err;

  fs.write(fd, buffer, (err) => {
    if (err) throw err;

    console.log('written');

    // CCSID of EBCDIC is 1047.
    let result = mvsutils.SetFileCcsid(fd, 1, 1047);

    if (result.rc === 0) {
      console.log('success');
    } else {
      console.log('failure');
    }

    fs.close(fd);
  });
});

With our changes to new.js, it will now tag the hello.ebcdic file as EBCDIC right after it is created. We can verify that this worked with the ls command:

$ ls -T
t ISO8859-1   T=on  check.js
t ISO8859-1   T=on  file.txt
t IBM-1047    T=on  hello.ebcdic
t ISO8859-1   T=on  new.js
                    node_modules
t ISO8859-1   T=on  package-lock.json
t ISO8859-1   T=on  package.json
t ISO8859-1   T=on  tag.js

And we will now be able to read hello.ebcdic with the cat command:

$ cat hello.ebcdic
Hello, World!


Additional Resources

See https://github.com/ibmruntimes/mvsutils for more examples on using the mvsutils package.
0 comments
38 views

Permalink