2026년 1월 30일 금요일

[Linux] Postfix에 PostScreen 설정

 

1단계: master.cf 수정 (서비스 활성화)

/etc/postfix/master.cf 파일을 열어 기존의 smtp 서비스를 비활성화하고, postscreen을 활성화해야 합니다.

  1. 기존 smtp 주석 처리:
    기존에 25번 포트를 열고 있던 줄을 찾아 앞에 #을 붙여 비활성화합니다.

    #smtp      inet  n       -       y       -       -       smtpd
  2. Postscreen 및 관련 서비스 활성화:
    아래 내용의 주석(#)을 해제하거나 새로 추가합니다.

    • smtp: 이제 Postscreen이 25번 포트를 담당합니다.
    • smtpd: Postscreen을 통과한 접속을 처리할 내부 서비스입니다.
    • dnsblog: DNS 블랙리스트 조회를 비동기로 처리합니다.
    • tlsproxy: Postscreen 단계에서 STARTTLS 지원을 위해 필요합니다.
    # Postscreen이 25번 포트 수신
    smtp      inet  n       -       y       -       1       postscreen
    
    # Postscreen 검사를 통과한 연결을 넘겨받을 smtpd
    smtpd     pass  -       -       y       -       -       smtpd
    
    # DNS 조회 및 TLS 처리를 위한 보조 서비스
    dnsblog   unix  -       -       y       -       0       dnsblog
    tlsproxy  unix  -       -       y       -       0       tlsproxy

2단계: main.cf 수정 (정책 설정)

/etc/postfix/main.cf 파일을 열어 Postscreen이 어떤 테스트를 수행하고 어떻게 차단할지 설정합니다.

아래 설정을 파일 하단에 추가합니다.

1. 기본 설정 및 화이트리스트

# === Postscreen 설정 ===

# 내 네트워크(mynetworks)는 검사에서 제외 (즉시 통과)
postscreen_access_list = permit_mynetworks

# 캐시 유지 시간 (검증된 IP를 기억하는 시간)
postscreen_cache_map = proxymap:btree:$data_directory/postscreen_cache
postscreen_cache_cleanup_interval = 12h

2. 좀비 PC 탐지 (Pre-greet, Protocol)

스팸 봇들이 자주 하는 "인사 먼저 하기(Pre-greet)"나 "명령어 쏟아붓기(Pipelining)"를 차단합니다. enforce는 차단을 의미합니다.

# 서버 인삿말(Banner)을 보내기도 전에 떠드는 놈 차단
postscreen_greet_action = enforce

# SMTP 프로토콜 위반 검사 (Pipelining, Non-SMTP command 등)
postscreen_pipelining_enable = yes
postscreen_pipelining_action = enforce

postscreen_non_smtp_command_enable = yes
postscreen_non_smtp_command_action = drop

postscreen_bare_newline_enable = yes
postscreen_bare_newline_action = enforce

3. DNSBL (DNS 블랙리스트) 설정 (가장 중요)

접속한 IP가 스팸 리스트에 있는지 확인합니다. 점수제를 사용하여 오탐을 줄입니다.

# DNSBL 사이트 설정 (예시: Zen Spamhaus, Barracuda)
# 이름=IP주소*가중치 형식입니다.
# 주의: Spamhaus 등은 상업적 이용 시 유료일 수 있으므로 라이선스 확인 필요
postscreen_dnsbl_threshold = 2
postscreen_dnsbl_sites = 
    zen.spamhaus.org*2
    b.barracudacentral.org*1
    bl.spamcop.net*1

# 블랙리스트에 걸렸을 때 동작 (enforce: 거부 응답 보냄 / drop: 연결 끊음)
postscreen_dnsbl_action = enforce

3단계: 적용 및 확인

  1. 설정 검사:
    오타가 없는지 확인합니다.

    postfix check
  2. Postfix 재시작:

    service postfix reload
    # 또는
    systemctl reload postfix
  3. 로그 확인:
    /var/log/mail.log (또는 /var/log/maillog)를 실시간으로 확인하여 작동 여부를 봅니다.

    tail -f /var/log/mail.log
    • PASS: 검사를 통과하여 smtpd로 넘겨진 경우 (PASS OLD는 캐시된 IP, PASS NEW는 새로 검증된 IP).
    • NOQUEUE: Postscreen에 의해 차단된 경우 (예: protocol violation, DNSBL rank ...).

팁 (주의사항)

  • 초기 적용 시: 처음에는 action 값들을 enforce 대신 **ignore**로 설정하여 며칠간 로그만 모니터링하는 것이 좋습니다. 정상적인 메일 서버가 차단되는지 확인한 후 enforce로 바꾸는 것이 안전합니다.
  • DNSBL 사용: zen.spamhaus.org는 매우 강력하지만, 무료 사용량 제한이 있거나 특정 DNS 서버(Google 8.8.8.8 등)를 통해 조회하면 차단될 수 있습니다. 본인의 환경에 맞는 DNSBL을 사용하세요.

2026년 1월 14일 수요일

[ABAP]_인터널 테이블을 가변 필드로 사용하기

  FIELD-SYMBOLS<FS_TABLE> TYPE STANDARD TABLE,
                 <FS_WA>    TYPE ANY,
                 <FS_FIELD> TYPE ANY.

  DATA LO_STRUCTDESCR  TYPE REF TO CL_ABAP_STRUCTDESCR,
         LO_TABLEDESCR   TYPE REF TO CL_ABAP_TABLEDESCR,
         LT_COMP         TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE,
         LS_COMP         TYPE CL_ABAP_STRUCTDESCR=>COMPONENT,
         LT_DATA         TYPE REF TO DATA,
         LS_DATA         TYPE REF TO DATA.

  DATA BEGIN OF LT_MARA OCCURS 0,
         MATNR      LIKE MARA-MATNR,
         MAKTX      LIKE MAKT-MAKTX,
         GROES      LIKE MARA-GROES,
         MEINS      LIKE MARA-MEINS,
         END OF LT_MARA.

*  "사용될 필드를 선언
  LS_COMP-NAME 'MATNR'.
  LS_COMP-TYPE CL_ABAP_ELEMDESCR=>GET_C18 ).
  APPEND LS_COMP TO LT_COMP.

  LS_COMP-NAME 'MAKTX'.
  LS_COMP-TYPE CL_ABAP_ELEMDESCR=>GET_C18 ).
  APPEND LS_COMP TO LT_COMP.

  LS_COMP-NAME 'GROES'.
  LS_COMP-TYPE CL_ABAP_ELEMDESCR=>GET_C18 ).
  APPEND LS_COMP TO LT_COMP.

  LS_COMP-NAME 'MEINS'.
  LS_COMP-TYPE CL_ABAP_ELEMDESCR=>GET_C18 ).
  APPEND LS_COMP TO LT_COMP.

  SELECT A~MATNR A~GROES A~MEINS B~MAKTX
    INTO CORRESPONDING FIELDS OF TABLE LT_MARA
    FROM MARA AS A
    JOIN MAKT AS B
      ON A~MATNR EQ B~MATNR
     AND B~SPRAS EQ 'E'
    UP TO 200 ROWS.

" 3. 구조 타입 및 테이블 타입 생성
  LO_STRUCTDESCR CL_ABAP_STRUCTDESCR=>CREATELT_COMP ).
  LO_TABLEDESCR  CL_ABAP_TABLEDESCR=>CREATEP_LINE_TYPE LO_STRUCTDESCR ).

*"선언된 구조체를 LT_DATA에 ASSIGN 처리
  CREATE DATA LT_DATA TYPE HANDLE LO_TABLEDESCR.
  ASSIGN LT_DATA->TO <FS_TABLE>.

  LOOP AT LT_MARA.
    CREATE DATA LS_DATA TYPE HANDLE LO_STRUCTDESCR.
    ASSIGN LS_DATA->TO <FS_WA>.

*   "LT_DATA에 ASSIGN된 필드를 찾아 데이터를 입력 처리함.
    ASSIGN COMPONENT 'MATNR' OF STRUCTURE <FS_WA> TO <FS_FIELD>.
    <FS_FIELD> LT_MARA-MATNR.

    ASSIGN COMPONENT 'MAKTX' OF STRUCTURE <FS_WA> TO <FS_FIELD>.
    <FS_FIELD> LT_MARA-MAKTX.

    ASSIGN COMPONENT 'GROES' OF STRUCTURE <FS_WA> TO <FS_FIELD>.
    <FS_FIELD> LT_MARA-GROES.

    ASSIGN COMPONENT 'MEINS' OF STRUCTURE <FS_WA> TO <FS_FIELD>.
    <FS_FIELD> LT_MARA-MEINS.

    APPEND <FS_WA> TO <FS_TABLE>.
  ENDLOOP.

  BREAK-POINT.
 

실행으로 생성된 인터널 테이블 구조


 

2026년 1월 12일 월요일

[AIX] sftp 자동 접속 스크립터

AIX에서 sftp 자동 접속 스크립터 

 

# cat sftp.sh
expect << EOF

set timeout 120
spawn sftp -oport=22 $2@$1

expect {
"yes/no" { send "yes\r"; exp_continue}
"password:" { send "$3\r" }
}

    expect "sftp>" { send "cd $4\r"}
    expect "sftp>" { send "put $5$6\r"}
    expect "sftp>" { send "ls -l $6\r"}
    expect "sftp>" { send "!ls -l $5$6\r"}
    expect "sftp>" { send "bye\r"}
    expect eof

EOF
 

2025년 12월 18일 목요일

[ABAP] Selection Screen에서 TABSTRIP 사용하기

 

 탭을 TAB_BLK로 선언(2개의 TAB(TAB1/TAB2))

SELECTION-SCREEN BEGIN OF TABBED BLOCK TAB_BLK FOR 10 LINES.
  SELECTION-SCREEN TAB (20TAB1 USER-COMMAND TAB1
    DEFAULT SCREEN 1001.
  SELECTION-SCREEN TAB (20TAB2 USER-COMMAND TAB2
    DEFAULT SCREEN 1002.
SELECTION-SCREEN END OF BLOCK TAB_BLK.

 

개별 TAB에 대한 조회 조건 선언 

SELECTION-SCREEN BEGIN OF SCREEN 1001 AS SUBSCREEN.
  SELECT-OPTIONS S_LIFNR  FOR EINA-LIFNR,
                   S_MATNR  FOR EINA-MATNR,
                   S_EKORG  FOR EINE-EKORG,
                   S_WERKS  FOR EINE-WERKS,
                   S_ESOKZ  FOR EINE-ESOKZ.

 SELECTION-SCREEN END OF SCREEN 1001.

SELECTION-SCREEN BEGIN OF SCREEN 1002 AS SUBSCREEN.
  PARAMETERS     P_DATUM  TYPE SY-DATUM.
SELECTION-SCREEN END OF SCREEN 1002.

 

 개별 탭에 대한 이름 선언

INITIALIZATION.
  TAB1 'Inforecord'.
  TAB2 'Others'.

선택된 탭에 따른 실행 프로그램 선언 

START-OF-SELECTION. 

  IF TAB_BLK-ACTIVETAB EQ 'TAB1'.
    PERFORM SELECT_DATA1.
  ELSE.
    
PERFORM SELECT_DATA2.
  ENDIF.

 실행결과


 

2025년 6월 23일 월요일

[Linux] Rocky9에 Openldap 설치 및 조직 설정

 

1. 관련 프로그램 설치 

기본 레파지토리에는 openldap-servers가 존재하지 않으므로 레피지토리에 추가

#  dnf config-manager --set-enabled plus

# dnf repolist 





# dnf update

# dnf -y install openldap openldap-servers openldap-clients

# systemctl enable slapd

# systemctl start slapd

# firewall-cmd --permanent --add-service={ldap,ldaps}

# firewall-cmd --reload

 

2. 관리자 패스워드 설정 

#  slappasswd

New password : *******

Re-enter new password : *******  

 {SSHA}***********************************  <--복사필요

# vi admin_pass.ldif 

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}***********************************  <--위화면 패스워드 붙여넣기

# ldapadd -Y EXTERNAL -H ldapi:/// -f admin_pass.ldif   <--루트 패스워드를 변경함.




 

3. Base DN을 설정 

# vi base_structure.ldif 

 # base_structure.ldif
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=example,dc=com

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=admin,dc=example,dc=com

# ldapadd -Y EXTERNAL -H ldapi:/// -f base_structure.ldif <--적용 

 

4. 기본 스키마 로드 

# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif


 

5. 기본 조직 설정

# vi initial_org.ldif

# 조직의 루트 DIT(Directory Information Tree) 항목 정의
# dc=example,dc=com은 설치 시 설정한 기본 도메인에 맞춰 변경해야 합니다.
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: My Company
description: My Company's main LDAP directory

# 사용자들을 위한 조직 구성 단위(OU) 정의
dn: ou=users,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: users
description: All user accounts in My Company

# 그룹들을 위한 조직 구성 단위(OU) 정의
dn: ou=groups,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: groups
description: All user groups in My Company

# 부서들을 위한 조직 구성 단위(OU) 정의
dn: ou=departments,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: departments
description: Departments within My Company

# IT 부서 OU 정의 (부서 OU 아래에 위치)
dn: ou=IT,ou=departments,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: IT
description: Information Technology Department

# HR 부서 OU 정의 (부서 OU 아래에 위치)
dn: ou=HR,ou=departments,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: HR
description: Human Resources Department

 

ldapadd -x -W -D "cn=admin,dc=example,dc=com" -f initial_org.ldif 


※ 패스워드는 이전에 설정한 관리자 패스워드를 입력 

 

 

6. Base Dn : cn=admin,dc=example,dc=com  , 관리자 패스워드 사용하여 관리 가능

 -  사용자 추가(HR 부서의 홍길동)

# slappassword  <--사용할 패스워드의 해시값으로 변환

New password: 홍길동
Re-enter new password: 홍길동
{SSHA}48cA5xSMTaz61+xo46Ek17DC07rapLtJ   <-- 해시값 복사

 # vi add_hong.ldif

 dn: uid=honggildong,ou=HR,ou=departments,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: 홍길동
sn: 홍
givenName: 길동
mail: hong.gildong@example.com  
uid: honggildong
userPassword: {SSHA}48cA5xSMTaz61+xo46Ek17DC07rapLtJ

 

ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f add_hong.ldif  



- Apache Directory Studio 프로그램에서 보면 정상적으로 추가되었음을 볼 수 있음.


 

만약 HR부서에 속한 인원을 조회시

# ldapsearch -x -b  "ou=HR,ou=departments,dc=example,dc=com" "(objectClass=person)" cn

인증이 필요한 경우

#  ldapsearch -x -D "cn=admin,dc=example,dc=com" -W -b "ou=IT,dc=example,dc=com" "(objectClass=person)" cn

  -x : 간편 인증 / -W 비밀번호 묻기

  -b : 검색 기준(Base DN)

  -D : Bind DN 로그인 계정 주소 

  (objectClass=Person) : 인원객체를 검색(추가 검색 조건 추가가능

   ex>이름(cn)이 홍길동일 경우 (&(objectClass=Person)(cn=홍길동))

  cn : 조회결과 속성

 

메일링 그룹을 만들시 goupofNames 또는  groupOfUniqueNames 객체를 사용하여 구성

 # vi group.ldif

dn: cn=all-users,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupOfNames
cn: all-users
description: All Users Mailing List
member: cn=John Doe,ou=IT,dc=example,dc=com
member: cn=Jane Smith,ou=HR,dc=example,dc=com
member: cn=Alice Kim,ou=Finance,dc=example,dc=com 

# ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f group.ldif

그룹 멤버 추가 방법

1. 매뉴얼로 수정 처리하는 방법

 - 스크립터로 구성 가능 

 ldapsearch -x -b "dc=example,dc=com" "(objectClass=person)" dn | grep "^dn:" | awk '{print "member: "$2}''

실행시 멤버 대상으로 생성되며 이를  LDIF로 만들어 생성할 수 있음.

 

2. 특정 그룹에 포함된 모든 대상자를 자동 포함시

- 추가 스키마가 필요하므로 추가 

# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/dyngroup.ldif

 -  vi group.ldif

dn: cn=all-users,ou=Groups,dc=example,dc=com
objectClass: groupOfURLs
cn: all-users
memberURL: ldap:///dc=example,dc=com??sub?(objectClass=person)
description: All Users Mailing List 

# ldapadd -x -D "cn=admin,dc=example,dc=com" -W -f group.ldif 


Postfix와 연동시

 /etc/postfix/ldap-groups.cf 

server_host = ldap://localhost
search_base = ou=Groups,dc=example,dc=com
query_filter = (cn=%s)
result_attribute = member
bind = yes
bind_dn = cn=admin,dc=example,dc=com
bind_pw = yourpassword 

 

 main.cf에 적용

virtual_alias_maps = ldap:/etc/postfix/ldap-groups.cf 

a11-user@example.com으로 이메일 전송시 해당 멤버에게 자동으로 이메일 전송됨. 

2025년 4월 25일 금요일

[SAP]_SMARTFORMS에 QR 바코드 추가하기

 [출처 : SAP COMMUNITY ]

 

Tcode SE73에서 System Bar Code 신규 설치 진행

만약  바코드 QR Code 2005가 나오지 않는다면 SAP Note 2029824를 먼저 설치하세요.


















설정이 완료되면 해당 폰트에서 실행시켜 테스트가 가능함.

정상 표시될 경우 Smartforms에서 폰트로 등록하여 사용하면 됨.


 




[SAP]_QR 바코드 설정

 

Tcode : SPAD 

1. 새 디바이스를 추가







디바이스명과 Parameters 파일을 다운받아 지정 후 실행














2. 동일 Tcode에서 신규 출력 Device를 생성


 






















테스트 프로그램으로 실행 후 출력 디바이스를 신규 추가한 디바이스로 진행

*&---------------------------------------------------------------------*
*& Report  ZJQR
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
*Robert Russell
*BWIPP in SAP
*created 2009 updated 2010
*contact me at rob.roosky@yahoo.com for more info
REPORT  ZQR_PRINT.

DATA: PARAMS LIKE PRI_PARAMS,
      VALID    TYPE C,
       iloop type string.

new-page print on.



skip 2.

WRITE:/ 'Testing BWIPP: QR codes in SAP'.

skip 2.

write:  'Normal position:  qr code for http://bit.ly/robrscn'.
*leave gap for qr code
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.


skip 2.

write:  'Shift Left:      qr code for http://bit.ly/robrscn'.
*leave gap for qr code
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZLT50'.
PRINT-CONTROL FUNCTION 'ZLT10'.
PRINT-CONTROL FUNCTION 'ZLT01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.

skip 2.
write:  'Shift Right:     qr code for http://bit.ly/robrscn'.
*leave gap for qr code
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZRT50'.
PRINT-CONTROL FUNCTION 'ZRT10'.
PRINT-CONTROL FUNCTION 'ZRT01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.


skip 2.
write:  'Scale X axis:     qr code for http://bit.ly/robrscn'.
*leave gap for qr code
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.


skip 2.
write:  'Scale y axis:     qr code for http://bit.ly/robrscn'.
*leave gap for qr code - y axis so the gap is bigger
skip 8.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.

*page breaks need to be controlled.
   NEW-PAGE.


skip 2.
write:  'Scale x/y axis:   qr code for http://bit.ly/robrscn'.
*leave gap for qr code - y axis so the gap is bigger
skip 8.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSY01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
PRINT-CONTROL FUNCTION 'ZSX01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.

skip 6.

skip 2.
write:  'Use option parse -ascii value for "g":   qr code for http://www.^103oogle.com'.
*leave gap for qr code -
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZOP01'.
WRITE: 'http://www.^103oogle.com' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.

skip 6.

skip 2.
write:  'Rotate 45 degress:   qr code for http://bit.ly/robrscn'.
*leave gap for qr code - rotating the qr code so the gap is bigger
skip 8.
PRINT-CONTROL FUNCTION 'ZBW01'.
PRINT-CONTROL FUNCTION 'ZRO01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.

skip 6.

*page breaks added for testing
   NEW-PAGE.
   WRITE: 'skip page' NO-GAP.

   NEW-PAGE.
   WRITE: 'skip page' NO-GAP.


   NEW-PAGE.
   WRITE: 'skip page' NO-GAP.


   NEW-PAGE.
   WRITE: 'skip page' NO-GAP.


   NEW-PAGE.

   WRITE: 'skip page' NO-GAP.

NEW-PAGE.

write:  'Back to normal:  qr code for http://bit.ly/robrscn'.
*leave gap for qr code
skip 6.
PRINT-CONTROL FUNCTION 'ZBW01'.
WRITE: 'http://bit.ly/robrscn' NO-GAP.
PRINT-CONTROL FUNCTION 'ZBW02'.
write: /'123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'.

write: /'end'.

WRITE:/.