Tacsiazuma
Tacsiazuma A letscode.hu alapitója, több, mint egy évtized fejlesztői tapasztalattal. Neovim függő hobbi pilóta.

Ha nem értesz a COBOL

Ha nem értesz a COBOL

Aki mostanság figyeli a híreket, az biztos hallhatott róla, hogy az egyébként is kihalófélben lévő kobaltbányászokból COBOL fejlesztőkből mégtöbbre van szükség, mert az USA munkaügyi segélyeket ellátó rendszere - ami történetesen COBOLban íródott és mainframeken fut -, a hirtelen megnövekedett munkanélküliség miatti terhelést képtelen kezelni. Na de mégis mit lehet tudni erről az ősöreg nyelvről?

Leginkább azt, hogy habár ősrégi (1959-ben készült el az első COBOL 60 névre hallgató verziója) és azok az emberek, akik értenek hozzá tényleg kihalófélben vannak (átlagéletkoruk jóval 50 felett van), még mind a mai napig rengeteg helyen fut (97-ben készült becslés alapján 200 milliárd sor kód fut aktívan), így nem fogunk tőle egyhamar megszabadulni (mert ugyanezen becslések szerint évi 5 milliárd sor sarat kódot tapasztanak a már meglévőhöz), ugyanis ezt a kódot más modernebb nyelvekre átírni sem egyszerű.

Apropó modern: a COBOL nyelvet aktívan fejlesztik, a legújabb specifikáció a COBOL 2014! Sőt, 2002 óta objektumorientált programozást is támogat. Habár jobban ügyelnek a visszafele kompatibilitásra, mint a WordPress, annyira, hogy pl. a COBOL 80-as sztenderdet vissza is dobta a piac, mert túl sokba került volna átírni a kódbázist a 74-es verzió után. 5 évet váratott magára a legközelebbi 85-ös kiadás.

Na de hogy tudunk nekiállni fejleszteni benne? Ez annyira nem egyszerű, ugyanis a COBOL fordítók zöme fizetős (és lévén enterprise grade, ezért nem is kicsit), vagy csak mainframeken fut.

Ha nagyon gyorsan bele akarunk ugrani a dologba, akkor létezik egy majdnem 100%-ban jó megoldás, mégpedig a GnuCobol (korábban OpenCOBOL), ami körül szaglászva még magyar nevek is felbukkannak, pl. itt. Ez igazából C-re fordítja először és utána a C fordító segítségével jön létre a futtatható állományunk. Ez a két lépés alapesetben egyben fut le, de megállíthatjuk, hogy megnézzük milyen C kódot is köp ki magából. A készítői amúgy semmiféle garanciát nem vállalnak, hogy követik a sztenderdet, habár a tesztek alapján 99.79%-ban megfelel és még a 2014-es specifikációt is implementálja. Akit érdekel, az innen tudja letölteni.

Debian rendszereken a

1
sudo apt install open-cobol

paranccsal tudjuk magunkévá tenni a compilert, amit ki is próbáltam egy egyszerű hello world programmal

1
2
3
4
5
6
7
8
000100* HELLO.COB GnuCOBOL example
000200 IDENTIFICATION DIVISION.
000300 PROGRAM-ID. hello.
000400 PROCEDURE DIVISION.
000500 DISPLAY "Hello, world!".
000600 STOP RUN.

gobc -x stuff.cob

De a gond ott van, hogy ez túl egyszerű. Miért is ne mennénk egy lépéssel közelebb a valódi COBOL futtatókörnyezethez?

Először is letöltjük a hercules emulátort. Ez egy open source implementációja a System/370 és ESA/390 mainframe architektúráknak, aminek a segítségével tudjuk majd futtatni a programjainkat.

Én ezt linuxon próbáltam, amihez az első lépés, hogy letöltsük a forráskódot innen.

Ezután kitömörítettem és az util mappában futtattam a misztikus nevű toolt, ami ellenőrzi, hogy a buildhez minden szükséges függőség megvan-e:

1
./util/bldlvlck

Ez szépen kiírja nekünk, hogyha valami hiányzik, vagy épp megvan, a verziókkal együtt:

``` This utility will check the level of various utilities needed to build hercules. Checking is done against versions that are KNOWN to work. This doesn't mean a build will NOT succeed with older versions of the utilities, but will give a hint as to what package may need an upgrade if the build ever fails with some odd reason. OK autoconf requires 2.5, found 2.69 OK automake requires 1.9, found 1.16.1 OK gawk requires 3.0, found 4.2.1 OK gcc requires 3, found 9.2.1 OK grep requires 1, found 3.3 OK libiconv requires 1.8, found 2.30.0 OK m4 requires 1.4.6, found 1.4.18 OK make requires 3.79, found 4.2.1 OK perl requires 5.6, found 5.28.1 OK sed requires 3.02, found 4.7 ```

Ezután jött egy szokásos konfigurálás:

1
./configure

Buildelés (ami a világ összes warningját elémdobta)

1
make

Telepítés:

1
sudo make install

Ezután elindítjuk, hogy lássuk tényleg minden klappol:

1
hercules

Ha minden jól megy, akkor valami hasonló fogad bennünket:

![](assets/uploads/2020/04/10185139/image-2-1024x596.png)

Viszont ez még önmagában üres, nem fut rajta semmi olyan, ami nekünk jó lenne, így állítsuk is le. Rakjunk fel rá valami mainframekre szabott operációs rendszert. Itt már vigyáznunk kell, mert a legtöbb ilyen operációs rendszer bizony nem futtatható ingyenesen, de akad pár kivétel. Egyik ilyen kivétel lesz az MVS, azaz Multiple Virtual Storage, ami egy IBM által fejlesztett, igen elterjedt operációs rendszer volt az System/370-esekre még régen.

Ezt innen tudjuk letölteni. Kicsomagoljuk, belenavigálunk és utána átállítjuk, hogy console módban menjen, így látjuk majd mi is történik:

1
<pre class="wp-block-preformatted">cd unattended<br></br>./set_console_mode

Ezután pedig a mappa gyökeréből elindítjuk az mvs-t:

1
./mvs

Beletelik egy kis időbe, míg elindul, mert a herculest is elindítja, de a végére valami hasonló fogad minket:

![](assets/uploads/2020/04/11235908/image-6.png)

Ezt kb. úgy képzelhetjük el, mintha futna egy virtuális gép a gépünkön. Mondhatnánk, hogy nincs más hátra, SSH-zzunk be, nem? Na igen, a helyzet az, hogy ezekkel a gépekkel még nem így kommunikáltak, hanem az IBM 3270-es protokoll segítségével. De mégis hogy oldom ezt meg? Hát 3270-es terminál segítségével!

![https://upload.wikimedia.org/wikipedia/commons/a/a8/IBM-3279.jpg](https://upload.wikimedia.org/wikipedia/commons/a/a8/IBM-3279.jpg)
Az IBM 3270-es terminál

Igen, szerencsénkre a TCP felé épülő protokollt sok más helyen is megvalósították, így elég egy programot telepítenünk, amivel rá tudunk csatlakozni a herculesre. Én Ubuntun a következő paranccsal telepítettem, de minden más operációs rendszerre elérhető:

1
sudo apt install c3270

Ezután pedig csatlakozunk (a portot külön fel kell venni, mert nem ez az alapértelmezett portja):

1
c3270 localhost -port 3270

Itt ugye az első dolgunk az lesz, hogy bejelentkezünk:

![](assets/uploads/2020/04/12001319/image-7.png)
A csatlakozás pillanata

A felhasználó amit használni fogunk: HERC01, a default jelszó pedig CUL8TR (see you later). Itt fontos lesz megjegyezni, hogy ez a fajta terminál minden utasítás végére entert vár, ehhez kicsit szokni kell majd. Ráadásul az se mindegy, hogy mit hova írunk be, mert el tudunk vándorolni a kurzorral. A menürendszerben visszafele az F3 lenyomásával tudunk haladni.

![](assets/uploads/2020/04/11005334/image-4.png)
Belépés után ez a képernyő fogad bennünket

Most, hogy már beléptünk, akkor csináljunk is valamit, nemde? Keressünk meg valami COBOL fájlt és futtassuk le! Ehhez először az RFE (review front end)-t kell kijelölnünk, tehát írjunk be egy egyest és enter:

![](assets/uploads/2020/04/12003714/image-8.png)
Az RFE, azaz review front end menüpont

Itt jöhet a következő lépés. A TRK4- egy pár olyan scripttel kerül szállításra, amit már rögtön le tudunk futtatni, így megkeressük azokat és egy jobot fogunk submitolni, ami lévén nem interaktív batch job, ezért rögtön lefut és mi már csak a kimenetét fogjuk tudni megnézni. A mainframeken nem fájlokat tartanak nyilván, hanem ún. dataseteket, amiket nem könyvtárakba rendeznek, hanem a nevezéktanjuk által vannak rendszerezve. Ez a nevezéktan pontok mentén osztja fel őket. Ahhoz, hogy tudjunk böngészni köztük, üssük le a 3-ast és egy entert, hogy a utilities alá kerüljünk:

![](assets/uploads/2020/04/12121455/image-9.png)
Utilities, itt tudunk mindenféle műveletet végrehajtani a datasetekkel

Itt pedig a 4-es menüpont, mert listázni akarjuk a dataseteket. Azon belül a sys2 prefixűekre leszünk kiváncsiak:

![](assets/uploads/2020/04/12121605/image-10.png)
A sys2 prefixű dataseteket akarjuk listázni

A nyilak segítségével navigáljunk le a második piros vonalra és írjuk be a szöveget, majd üssünk egy entert.

A következő oldalról a navigáció már egy kicsit trükkösebb. Ha elakadunk, akkor a más rendszerekből is megszokott F1 lesz a segítségünkre:

![](assets/uploads/2020/04/12122743/image-11.png)
A listázáshoz szükséges súgó. Itt felsorolja az egyes kódokat, amiket a listaelemek első oszlopába írva tudunk tovább navigálni.

A súgóból az F3 segítségével tudunk visszajutni az előző képernyőre, ahol a SYS2.JCLLIB elé tegyünk egy b betűt és üssük le az entert. Ez a b, mint browse, azaz a prefixen belüli tartalmat akarjuk böngészni.

![](assets/uploads/2020/04/12123051/image-12.png)
A JCLLIB prefix van kijelölve böngészésre.

A JCL, azaz Job Control Language egy leírás arról a batch jobról, amit épp le akarunk futtatni. Ki akarja futtatni, azonosítója és hasonlók. Na de nézzük meg miket is találunk itt!

![](assets/uploads/2020/04/12123439/image-13.png)
A SYS2.JCLLIB prefix tartalmának első oldala. Itt már nem elég a nyilakkal navigáljunk, a következő lapokat is elő kell csalni.

Itt lesznek majd azok a bizonyos cobol minta jobok, amiket mi keresünk, de sajnos nem az első oldalon. Ha megindulunk a nyilakkal lefele, akkor szomorúan tapasztaljuk, hogy körbe körbe járunk velük, tehát a lapozást máshogy kell intézni. Mégpedig igen könnyen. A command utáni promptba írjunk + vagy - jelet attól függően, hogy előre vagy hátra akarunk lapozni. Amire mi vágyunk, az a második oldalon lesz, mégpedig egy prímszám kereső kis cobol job, a PRIMCOB1. Navigáljunk mellé és az első cellába írjuk be az e, azaz edit parancs kódját, majd újra enter.

![](assets/uploads/2020/04/12124137/image-14.png)
A SYS2.JCLLIB prefix tartalmának második oldala

Na és most jutottunk végre el oda, hogy lássunk valami kódot is!

![](assets/uploads/2020/04/12124538/image-15.png)
A SYS2.JCCLIB.PRIMCOB1 dataset tartalma, ami igazából egy JCL job

Akkor kicsit nézzük át, hogy mi is zajlik itt. Bele is kell írjunk a szövegbe majd, amit mint egy sima editorral, úgy tudunk megtenni. Az első amit át kell írnunk az a futtató neve, ez legyen a saját felhasználónk neve, azaz HERC01.

A CLASS itt azt jelenti, hogy mennyire sürgős a feladat végrehajtása, ugyanis itt minden job átmegy a JES2-n ( Job Entry Subsystem) és kell egy prioritás, az A jelentése, hogy azonnal hajtsuk végre. A jobok kimenetét alapból kinyomtatnánk, ezt a MSGCLASS értéke szabályozza, ahol az A-B-C, stb. különféle nyomtatókat jelent rákötve a rendszerre. Mi most nem akarjuk kinyomtatni, hanem H, azaz held output opciót választjuk. Ez azt jelenti, hogy a gépen meg tudjuk még nézni, hogy mi is lett a kimenete a feladatnak. A többi //-el kezdődő sor nem annyira fontos, talán még az EXEC COBUCG, ami egy lépésben lefordítja és futtatja a kapott COBOL kódot, a PARM.COB pedig a compilernek átadott paramétereket tartalmazza. Ez a program alapból 2000-ig gyűjti össze a prímszámokat, kiírja azokat és a végén pedig kiírja mennyit talált. A 2000 egyébként paraméterként van átadva a fájl legvégén, itt is a +,- segítségével tudunk navigálni.

![](assets/uploads/2020/04/12131235/image-16.png)
A paramétere a cobol jobnak

Na most ha átírtuk az azonosítót PRIMCOB1-ről HERC01-re, na meg a MSGCLASS-t, akkor mentsük el a változtatásokat, a command sorba írjuk be, hogy save, azután pedig submit. Ekkor kér tőlünk egy karaktert, amit a HERC01 végére fog biggyeszteni, így könnyebben beazonosítható majd, ha keressük. Ezt megadva már el is küldtük a JES-nek, kapunk egy azonosítót is hozzá, nézzük meg a kimenetét! Ehhez vissza kell navigálni az F3 nyomogatásával a data set utilitiesig, ahol a 8-as, azaz outlistet kell kiválasztani. Itt vannak felsorolva a jobok kimenetei. Itt elvileg megtaláljuk azt a job azonosítót, amit az imént kaptunk! Keressük meg a miénket, rakjunk elé egy s-t, majd enter és ezzel ki is választjuk azt.

![](assets/uploads/2020/04/12131914/image-17.png)

Itt aztán mindenfélét látunk majd, JES2 kimenetet, COBOL compiler és futtatás eredményét, valamint a programunk kimenetét.

![](assets/uploads/2020/04/12132411/image-18.png)
Az első oldala a job kimenetének. Kevesebb, mint egy másodpercig tartott, ha megnézzük a második és hatodik sorban levő időt

A + segítségével lapozzunk lentebb. A harmadik oldalon találtunk érdekes információkat a fordításról és a futtatásról, ha pedig lentebb megyünk, akkor a kimenetet is látjuk:

![](assets/uploads/2020/04/12132639/image-19.png)
A COB stepname a compiler, a GO stepname pedig a futtatás. Látjuk, hogy mindkettő századmásodpercek alatt végzett.
![](assets/uploads/2020/04/12132833/image-20.png)
A programunk 303 prímszámot talált 0-2000 között.

Ezzel a végére is értünk annak, hogy egy emulátorban futó COBOL kódot lefordítsunk és lefuttassunk, majd megnézzük annak az eredményét. Most nem álltunk neki saját kódot írni, de aki örömét leli a szenvedésemben, az szóljon és megnézzük mi a helyzet, ha szeretnénk Db2-t is elérni valahogy!

comments powered by Disqus