diff --git a/NOTES.md b/NOTES.md
index 4ef9374b1949fecde9c9b0f8ff1aa4d8c061a6c2..2f659b47aa42988161dd84a33f85e094d2988096 100644
--- a/NOTES.md
+++ b/NOTES.md
@@ -19,6 +19,8 @@ Look up how to run migrations on the db from embedded files.
Figure out readline completion. Case sensitive - issue? Building from
repl.commands?
+sqlite trigger tracing: `.trace stdout --row --profile --stmt --expanded --plain --close`
+
## Things to do
* Implement a better dclish parser.
diff --git a/accounts/accounts.go b/accounts/accounts.go
index e69a617b817dfa6a7a501f12884cea1fa46b47d0..186a1c9f08947cb6dd81c809edac64c1bc8205e0 100644
--- a/accounts/accounts.go
+++ b/accounts/accounts.go
@@ -2,15 +2,11 @@
package accounts
import (
- "database/sql"
"errors"
"fmt"
- "os"
- "path"
"strings"
"git.lyda.ie/kevin/bulletin/folders"
- "github.com/adrg/xdg"
_ "modernc.org/sqlite" // Loads sqlite driver.
)
@@ -19,7 +15,6 @@ import (
type UserData struct {
Account string
FullName string
- pref *sql.DB
Folders *folders.Store
CurrentFolder string
CurrentMessage int
@@ -49,18 +44,7 @@ func Open(acc string) error {
Account: acc,
}
- prefdir := path.Join(xdg.ConfigHome, "BULLETIN")
- err = os.MkdirAll(prefdir, 0700)
- if err != nil {
- return errors.New("account preference directory problem")
- }
- User.pref, err = sql.Open("sqlite", path.Join(prefdir, fmt.Sprintf("%s.%s", acc, ".db")))
- if err != nil {
- return errors.New("account preference database problem")
- }
- // TODO: run prefs migration - move this to a storage module.
-
- User.Folders, err = folders.Open()
+ User.Folders, err = folders.Open(acc)
if err != nil {
return err
}
@@ -70,7 +54,6 @@ func Open(acc string) error {
// Close closes the resources open for the account.
func (u *UserData) Close() {
- u.pref.Close()
u.Folders.Close()
}
diff --git a/decus/vax91b/bulletin/bulletin6.for b/decus/vax91b/bulletin/bulletin6.for
index 7dc073d2b387b5cfc00ef4b9e3b788fcd5d421c0..55abcadcb941c99332f2c11194a742e6f4338023 100644
--- a/decus/vax91b/bulletin/bulletin6.for
+++ b/decus/vax91b/bulletin/bulletin6.for
@@ -18,122 +18,122 @@ C
C FUNCTION: To close out the bulletin files and enable CTRL-C & -Y
C
DATA LUN /0/
-
+
ENTRY CLOSE_BULLINF
LUN = LUN + 1 ! Unit = 9
-
+
ENTRY CLOSE_SYSUAF
LUN = LUN + 1 ! Unit = 8
-
+
ENTRY CLOSE_BULLNEWS
ENTRY CLOSE_BULLFOLDER
LUN = LUN + 3 ! Unit = 7
-
+
ENTRY CLOSE_BULLUSER
LUN = LUN + 2 ! Unit = 4
-
+
ENTRY CLOSE_BULLDIR
LUN = LUN + 1 ! Unit = 2
-
+
ENTRY CLOSE_BULLFIL
LUN = LUN + 1 ! Unit = 1
-
+
CALL ENABLE_CTRL
-
+
CLOSE (UNIT=LUN)
-
+
LUN = 0
-
+
RETURN
END
-
-
+
+
SUBROUTINE CLOSE_FILE_DELETE
-
+
IMPLICIT INTEGER (A-Z)
-
+
DATA LUN /0/
-
+
ENTRY CLOSE_BULLDIR_DELETE
LUN = LUN + 1 ! Unit = 2
-
+
ENTRY CLOSE_BULLFIL_DELETE
LUN = LUN + 1 ! Unit = 1
-
+
CALL ENABLE_CTRL
-
+
CLOSE (UNIT=LUN,STATUS='DELETE')
-
+
LUN = 0
-
+
RETURN
END
-
-
+
+
SUBROUTINE OPEN_FILE(UNIT)
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLFILES.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLUSER.INC'
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE '($FORIOSDEF)'
-
+
INCLUDE '($PRVDEF)'
-
+
COMMON /REMOTE_FOLDER/ REMOTE_SET,REMOTE_UNIT
-
+
COMMON /DIR_POSITION/ DIR_NUM
-
+
COMMON /NEWS_OPEN/ NEWS_OPEN
-
+
DATA LUN /0/
-
+
LUN = UNIT - 14 ! 14 gets added to LUN
-
+
ENTRY OPEN_BULLNEWS
LUN = LUN + 5 ! Unit = 14
-
+
ENTRY OPEN_BULLINF
LUN = LUN + 1 ! Unit = 9
-
+
ENTRY OPEN_SYSUAF
LUN = LUN + 1 ! Unit = 8
-
+
ENTRY OPEN_BULLFOLDER
LUN = LUN + 3 ! Unit = 7
-
+
ENTRY OPEN_BULLUSER
LUN = LUN + 2 ! Unit = 4
-
+
ENTRY OPEN_BULLDIR
LUN = LUN + 1 ! Unit = 2
-
+
ENTRY OPEN_BULLFIL
LUN = LUN + 1 ! Unit = 1
-
+
IER = 0
-
+
NTRIES = 0
-
+
CALL SET_PROTECTION
-
+
CALL DISABLE_CTRL ! No breaks while file is open
-
+
IF (LUN.EQ.2.AND..NOT.REMOTE_SET) THEN
DO WHILE (FILE_LOCK(IER,IER1))
-
+
OPEN (UNIT=2,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='OLD',FORM='UNFORMATTED',
& RECORDTYPE='FIXED',RECORDSIZE=DIR_RECORD_LENGTH/4,
& ORGANIZATION='INDEXED',IOSTAT=IER,
& KEY=(9:12:INTEGER,1:8:CHARACTER),ACCESS='KEYED')
-
+
IF (IER.EQ.FOR$IOS_FILNOTFOU) THEN
OPEN (UNIT=2,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='NEW',FORM='UNFORMATTED',
@@ -158,7 +158,7 @@ C
END DO
DIR_NUM = -1
END IF
-
+
IF (LUN.EQ.1.AND..NOT.REMOTE_SET) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=1,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
@@ -174,7 +174,7 @@ C
IF (NTRIES.GT.30) CALL TIMER_ERR(LUN)
END DO
END IF
-
+
IF (LUN.EQ.4) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=4,FILE=BULLUSER_FILE,STATUS='OLD',
@@ -200,7 +200,7 @@ C
IF (NTRIES.GT.30) CALL TIMER_ERR(LUN)
END DO
END IF
-
+
IF (LUN.EQ.7) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=7,FILE=BULLFOLDER_FILE,STATUS='OLD',
@@ -232,7 +232,7 @@ C
END DO
IF (IER.EQ.0) NEWS_OPEN = .FALSE.
END IF
-
+
IF (LUN.EQ.14) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=7,FILE=BULLNEWS_FILE,STATUS='OLD',
@@ -253,7 +253,7 @@ C
END DO
IF (IER.EQ.0) NEWS_OPEN = .TRUE.
END IF
-
+
IF (LUN.EQ.9) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=9,FILE=BULLINF_FILE,STATUS='UNKNOWN',
@@ -269,7 +269,7 @@ C
IF (NTRIES.GT.30) CALL TIMER_ERR(LUN)
END DO
END IF
-
+
IF (IER.NE.0) THEN
WRITE (6,'(
& '' Cannot open file in OPEN_FILE, unit = '',I)') LUN
@@ -281,108 +281,108 @@ C
END IF
CALL ENABLE_CTRL_EXIT ! Enable CTRL-Y & -C & EXIT
END IF
-
+
LUN = 0
-
+
CALL RESET_PROTECTION
-
+
RETURN
END
-
-
-
+
+
+
SUBROUTINE TIMER_ERR(UNIT)
-
+
IMPLICIT INTEGER (A-Z)
-
+
CHARACTER*14 NAMES(6)
DATA NAMES/'directory','message','BULLUSER.DAT','BULLFOLDER.DAT',
& 'BULLINF.DAT','BULLNEWS.DAT'/
INTEGER NAME(14)
DATA NAME/1,2,0,3,0,0,4,0,5,0,0,0,0,6/
-
+
IF (TEST_BULLCP().NE.2) THEN ! If BULLCP process, don't log error
WRITE(6,'('' ERROR: Unable to open '',A,
& '' file after 30 secs.'')')
& NAMES(NAME(UNIT))(:TRIM(NAMES(NAME(UNIT))))
WRITE (6,'('' Please try again later.'')')
END IF
-
+
CALL ENABLE_CTRL_EXIT ! No breaks while file is open
END
-
-
-
+
+
+
SUBROUTINE OPEN_FILE_SHARED
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE '($FORIOSDEF)'
-
+
INCLUDE 'BULLFILES.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLUSER.INC'
-
+
INCLUDE 'BULLDIR.INC'
-
+
COMMON /POINT/ BULL_POINT
-
+
COMMON /REMOTE_FOLDER/ REMOTE_SET,REMOTE_UNIT
-
+
COMMON /DIR_POSITION/ DIR_NUM
-
+
COMMON /NEWS_OPEN/ NEWS_OPEN
-
+
EXTERNAL LNM_MODE_EXEC,ENABLE_CTRL_EXIT
C
C The following 2 files were used prior to V1.1.
C
CHARACTER*80 BULLDIR_FILE /'BULL_DIR:BULLDIR.DAT'/
CHARACTER*80 BULLETIN_FILE /'BULL_DIR:BULLETIN.DAT'/
-
+
CHARACTER*25 SAVE_FOLDER
DATA SAVE_BLOCK/-1/
-
+
CHARACTER*14 NAMES(6)
DATA NAMES/'directory','message','BULLUSER.DAT','BULLFOLDER.DAT',
& 'BULLINF.DAT','BULLNEWS.DAT'/
INTEGER NAME(14)
DATA NAME/1,2,0,3,0,0,4,0,5,0,0,0,0,6/
-
+
DATA LUN /0/
-
+
ENTRY OPEN_BULLNEWS_SHARED
LUN = LUN + 5 ! Unit = 14
-
+
ENTRY OPEN_BULLINF_SHARED
LUN = LUN + 1 ! Unit = 9
-
+
ENTRY OPEN_SYSUAF_SHARED
LUN = LUN + 1 ! Unit = 8
-
+
ENTRY OPEN_BULLFOLDER_SHARED
LUN = LUN + 3 ! Unit = 7
-
+
ENTRY OPEN_BULLUSER_SHARED
LUN = LUN + 2 ! Unit = 4
-
+
ENTRY OPEN_BULLDIR_SHARED
LUN = LUN + 1 ! Unit = 2
-
+
ENTRY OPEN_BULLFIL_SHARED
LUN = LUN + 1 ! Unit = 1
-
+
IER = 0
-
+
NTRIES = 0
-
+
CALL DISABLE_CTRL
-
+
IF (LUN.EQ.2.AND..NOT.REMOTE_SET) THEN
DO WHILE (FILE_LOCK(IER,IER1))
-
+
OPEN (UNIT=2,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='OLD',FORM='UNFORMATTED',
& RECORDTYPE='FIXED',RECORDSIZE=DIR_RECORD_LENGTH/4,
@@ -411,7 +411,7 @@ C
END DO
DIR_NUM = -1
END IF
-
+
IF (LUN.EQ.1.AND.REMOTE_SET.AND.(SAVE_BLOCK.NE.BLOCK.OR.
& SAVE_FOLDER.NE.FOLDER)) THEN
CALL REMOTE_READ_MESSAGE(BULL_POINT,IER)
@@ -439,7 +439,7 @@ C
IF (NTRIES.GT.30) CALL ENABLE_CTRL_EXIT
END DO
END IF
-
+
IF (LUN.EQ.4) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=4,FILE=BULLUSER_FILE,STATUS='OLD',
@@ -455,14 +455,14 @@ C
IF (NTRIES.GT.30) CALL ENABLE_CTRL_EXIT
END DO
END IF
-
+
IF (LUN.EQ.7) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=7,FILE=BULLFOLDER_FILE,STATUS='OLD',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& IOSTAT=IER,ORGANIZATION='INDEXED',SHARED,
& KEY=(1:25:CHARACTER,26:29:INTEGER))
-
+
IF (IER.EQ.0) THEN
INQUIRE(UNIT=7,RECORDSIZE=ASK_SIZE)
IF (ASK_SIZE.NE.FOLDER_RECORD/4) THEN
@@ -477,20 +477,20 @@ C
END DO
IF (IER.EQ.0) NEWS_OPEN = .FALSE.
END IF
-
+
IF (LUN.EQ.14) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=7,FILE=BULLNEWS_FILE,STATUS='OLD',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& IOSTAT=IER,ORGANIZATION='INDEXED',SHARED,
& KEY=(1:25:CHARACTER,26:29:INTEGER))
-
+
NTRIES = NTRIES + 1
IF (NTRIES.GT.30) CALL ENABLE_CTRL_EXIT
END DO
IF (IER.EQ.0) NEWS_OPEN = .TRUE.
END IF
-
+
IF (LUN.EQ.8) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=8,FILE='SYSUAF',DEFAULTFILE='SYS$SYSTEM:SYSUAF.DAT',
@@ -499,7 +499,7 @@ C
& USEROPEN=LNM_MODE_EXEC)
END DO
END IF
-
+
IF (LUN.EQ.9) THEN
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=9,FILE=BULLINF_FILE,STATUS='OLD',
@@ -516,7 +516,7 @@ C
IF (NTRIES.GT.30) CALL ENABLE_CTRL_EXIT
END DO
END IF
-
+
IF (IER.EQ.FOR$IOS_FILNOTFOU.AND.LUN.NE.8) THEN
CALL OPEN_FILE(LUN)
ELSE IF (IER.NE.0) THEN
@@ -530,46 +530,46 @@ C
END IF
CALL ENABLE_CTRL_EXIT
END IF
-
+
LUN = 0
-
+
RETURN
END
-
-
+
+
SUBROUTINE RESET_PROTECTION
-
+
IMPLICIT INTEGER (A-Z)
-
+
DATA PROT_LEVEL /0/
-
+
PROT_LEVEL = PROT_LEVEL - 1
IF (PROT_LEVEL.GT.0) RETURN
-
+
CALL SYS$SETDFPROT(CUR_DEF_PROT,) ! Reset default protection
-
+
RETURN
-
+
ENTRY SET_PROTECTION
-
+
PROT_LEVEL = PROT_LEVEL + 1
IF (PROT_LEVEL.GT.1) RETURN
-
+
CALL SYS$SETDFPROT('FF00'X,CUR_DEF_PROT)
! Set protection to (SYSTEM:RWED,OWNER:RWED,WORLD,GROUP)
-
+
RETURN
END
-
-
-
-
+
+
+
+
SUBROUTINE FOLDER_TO_NEWS
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
NEWS_FOLDER = FOLDER
NEWS_FOLDER_NUMBER = FOLDER_NUMBER
NEWS_FOLDER_DESCRIP = FOLDER_DESCRIP(
@@ -578,11 +578,11 @@ C
NEWS_F_NBULL = F_NBULL
NEWS_F_NEWEST_BTIM(1) = F_NEWEST_BTIM(1)
NEWS_F_NEWEST_BTIM(2) = F_NEWEST_BTIM(2)
-
+
RETURN
-
+
ENTRY FOLDER1_TO_NEWS
-
+
NEWS_FOLDER1 = FOLDER1
NEWS_FOLDER1_NUMBER = FOLDER1_NUMBER
NEWS_FOLDER1_DESCRIP = FOLDER1_DESCRIP(
@@ -591,11 +591,11 @@ C
NEWS_F1_NBULL = F1_NBULL
NEWS_F1_NEWEST_BTIM(1) = F1_NEWEST_BTIM(1)
NEWS_F1_NEWEST_BTIM(2) = F1_NEWEST_BTIM(2)
-
+
RETURN
-
+
ENTRY NEWS_TO_FOLDER
-
+
FOLDER = NEWS_FOLDER
FOLDER_NUMBER = NEWS_FOLDER_NUMBER
FOLDER_DESCRIP = NEWS_FOLDER(:TRIM(NEWS_FOLDER))
@@ -605,11 +605,11 @@ C
F_NEWEST_BTIM(1) = NEWS_F_NEWEST_BTIM(1)
F_NEWEST_BTIM(2) = NEWS_F_NEWEST_BTIM(2)
FOLDER_FLAG = 0
-
+
RETURN
-
+
ENTRY NEWS_TO_FOLDER1
-
+
FOLDER1 = NEWS_FOLDER1
FOLDER1_NUMBER = NEWS_FOLDER1_NUMBER
FOLDER1_DESCRIP = NEWS_FOLDER1(:TRIM(NEWS_FOLDER1))
@@ -619,49 +619,49 @@ C
F1_NEWEST_BTIM(1) = NEWS_F1_NEWEST_BTIM(1)
F1_NEWEST_BTIM(2) = NEWS_F1_NEWEST_BTIM(2)
FOLDER1_FLAG = 0
-
+
RETURN
-
+
END
-
-
-
-
+
+
+
+
SUBROUTINE CONVERT_BULLDIRS
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLFILES.INC'
-
+
CHARACTER BUFFER*115
-
+
WRITE (6,'('' Converting data files to new format. Please wait.'')')
-
+
CALL SET_PROTECTION
-
+
OPEN (UNIT=2,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='OLD',FORM='UNFORMATTED',
& RECORDTYPE='FIXED',ACCESS='DIRECT',
& ORGANIZATION='RELATIVE',DISPOSE='KEEP',
& IOSTAT=IER)
-
+
IF (IER.NE.0) GO TO 900 ! No BULLDIR file found.
-
+
READ (2'1,IOSTAT=IER1) BUFFER
-
+
CALL LIB$MOVC3(4,%REF(BUFFER(39:)),NBULL)
-
+
OPEN (UNIT=9,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='NEW',FORM='UNFORMATTED',
& RECORDTYPE='FIXED',RECORDSIZE=DIR_RECORD_LENGTH/4,
& ORGANIZATION='INDEXED',IOSTAT=IER,DISPOSE='DELETE',
& KEY=(9:12:INTEGER,1:8:CHARACTER),ACCESS='KEYED',
& INITIALSIZE=(((NBULL+1)*DIR_RECORD_LENGTH)/512)+5 )
-
+
IF (IER.NE.0) THEN
OPEN (UNIT=9,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='NEW',FORM='UNFORMATTED',
@@ -669,16 +669,16 @@ C
& ORGANIZATION='INDEXED',IOSTAT=IER,DISPOSE='DELETE',
& KEY=(9:12:INTEGER,1:8:CHARACTER),ACCESS='KEYED')
END IF
-
+
IF (IER1.NE.0) GO TO 800
-
+
CALL SYS_BINTIM(BUFFER(1:11)//' '//BUFFER(12:19),NEWEST_EXBTIM)
CALL SYS_BINTIM(BUFFER(20:30)//' '//BUFFER(31:38),NEWEST_MSGBTIM)
BULLDIR_HEADER(29:40) = BUFFER(39:)
CALL SYS_BINTIM(BUFFER(51:61)//' '//BUFFER(62:69),SHUTDOWN_BTIM)
BULLDIR_HEADER(49:52) = BUFFER(70:)
IF (IER.EQ.0) WRITE (9,IOSTAT=IER) BULLDIR_HEADER
-
+
ICOUNT = 2
DO WHILE (IER.EQ.0)
READ (2'ICOUNT,IOSTAT=IER) BUFFER
@@ -695,18 +695,18 @@ C
ICOUNT = ICOUNT + 1
END IF
END DO
-
+
800 CLOSE (UNIT=9,DISPOSE='KEEP')
CLOSE (UNIT=2)
-
+
900 CALL RESET_PROTECTION
-
+
RETURN
-
+
END
-
-
-
+
+
+
SUBROUTINE CONVERT_BULLFILES
C
C SUBROUTINE CONVERT_BULLFILES
@@ -716,54 +716,54 @@ C Add expiration time to directory file, add extra byte to bulletin
C file to show where each bulletin starts (for redunancy sake in
C case crash occurs).
C
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLFILES.INC'
-
+
CHARACTER*81 BUFFER
-
+
WRITE (6,'('' Converting data files to new format. Please wait.'')')
-
+
OPEN (UNIT=9,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='OLD',
& RECORDTYPE='FIXED',RECORDSIZE=107,ACCESS='DIRECT',
& ORGANIZATION='RELATIVE',DISPOSE='KEEP',FORM='FORMATTED',
& SHARED,READONLY,IOSTAT=IER)
-
+
IF (IER.NE.0) CALL ERROR_AND_EXIT ! Error. Why?
-
+
OPEN (UNIT=10,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLFIL',STATUS='OLD',
& RECORDTYPE='FIXED',RECORDSIZE=80,
& FORM='FORMATTED',IOSTAT=IER,SHARED,READONLY)
-
+
IF (IER.NE.0) CALL ERROR_AND_EXIT ! Error. Why?
-
+
CALL SET_PROTECTION
-
+
OPEN (UNIT=1,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLFIL',STATUS='NEW',IOSTAT=IER,
& ACCESS='DIRECT',RECORDTYPE='FIXED',RECORDSIZE=81,
& FORM='FORMATTED')
-
+
OPEN (UNIT=2,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLDIR',STATUS='NEW',FORM='UNFORMATTED',
& RECORDTYPE='FIXED',RECORDSIZE=DIR_RECORD_LENGTH/4,
& ORGANIZATION='INDEXED',IOSTAT=IER,DISPOSE='KEEP',
& KEY=(9:12:INTEGER,1:8:CHARACTER),ACCESS='KEYED')
-
+
NEWEST_EXTIME = '00:00:00.00'
- READ (9'1,1000,IOSTAT=IER)
+ READ (9'1,1000,IOSTAT=IER)
& NEWEST_EXDATE,NEWEST_DATE,NEWEST_TIME(:8),
& NBULL,NBLOCK,SHUTDOWN,SHUTDOWN_DATE,SHUTDOWN_TIME(:8)
NEMPTY = 0
IF (IER.EQ.0) CALL WRITEDIR(0,IER1)
-
+
EXTIME = '00:00:00.00'
ICOUNT = 2
DO WHILE (IER.EQ.0)
@@ -780,20 +780,20 @@ C
ICOUNT = ICOUNT + 1
END IF
END DO
-
+
CLOSE (UNIT=9)
CLOSE (UNIT=2)
CLOSE (UNIT=10)
CLOSE (UNIT=1)
-
+
CALL RESET_PROTECTION
RETURN
-
+
1000 FORMAT(A11,A11,A8,A4,A4,A4,A11,A8)
1010 FORMAT(A53,A12,A11,A8,A4,A11,A4,A4)
-
+
END
-
+
SUBROUTINE CONVERT_BULLFILE
C
C SUBROUTINE CONVERT_BULLFILE
@@ -803,29 +803,29 @@ C
C NOTE: CONVERT_BULLFILES converts from 80 to 81 byte length.
C This converts from 81 byte length to 128 compressed format.
C
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLFILES.INC'
-
+
CHARACTER*80 BUFFER,NEW_FILE
-
+
WRITE (6,'('' Converting data files to new format. Please wait.'')')
-
+
CALL CLOSE_BULLDIR
-
+
CALL SET_PROTECTION
-
+
CALL OPEN_BULLFOLDER
-
+
100 READ (7,FMT=FOLDER_FMT,ERR=200)
& FOLDER,FOLDER_NUMBER,FOLDER_OWNER,FOLDER_DESCRIP
& ,FOLDER_BBOARD,FOLDER_BBEXPIRE,USERB,GROUPB,ACCOUNTB
-
+
FOLDER_FILE = FOLDER_DIRECTORY(:TRIM(FOLDER_DIRECTORY))
& //FOLDER(:TRIM(FOLDER))
NEW_FILE = FOLDER_FILE(:TRIM(FOLDER_FILE))//'.BULLFILOLD'
@@ -833,20 +833,20 @@ C
& ,STATUS='OLD',
& RECORDTYPE='FIXED',RECORDSIZE=81,ACCESS='DIRECT',
& FORM='FORMATTED',IOSTAT=IER,SHARED,READONLY)
-
+
IF (IER.NE.0) CALL ERROR_AND_EXIT ! Error. Why?
-
+
OPEN (UNIT=1,FILE=FOLDER_FILE(1:TRIM(FOLDER_FILE))
& //'.BULLFIL',STATUS='NEW',IOSTAT=IER,
& ACCESS='DIRECT',RECORDTYPE='FIXED',RECORDSIZE=32,
& FORM='UNFORMATTED')
IER = LIB$RENAME_FILE(FOLDER_FILE(:TRIM(FOLDER_FILE))
& //'.BULLFIL;-1',NEW_FILE)
-
+
CALL OPEN_BULLDIR
-
+
CALL READDIR(0,IER)
-
+
IF (IER.EQ.1) THEN
NBLOCK = 0
DO I=1,NBULL
@@ -864,27 +864,27 @@ C
BLOCK = SBLOCK
CALL WRITEDIR(I,IER)
END DO
-
+
NEMPTY = 0
CALL WRITEDIR(0,IER)
END IF
-
+
CLOSE (UNIT=10)
CLOSE (UNIT=1)
-
+
CALL CLOSE_BULLDIR
GOTO 100
-
+
200 CALL OPEN_BULLDIR_SHARED
-
+
CALL RESET_PROTECTION
-
+
RETURN
-
+
END
-
-
-
+
+
+
SUBROUTINE CONVERT_BULLFOLDER(FILENAME,ASK_SIZE)
C
C SUBROUTINE CONVERT_BULLFOLDER
@@ -892,46 +892,46 @@ C
C FUNCTION: Converts bulletin folder file to new format.
C
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
INCLUDE 'BULLFILES.INC'
-
+
INCLUDE '($SSDEF)'
-
+
INCLUDE '($FORIOSDEF)'
-
+
CHARACTER*(*) FILENAME
-
+
CHARACTER*80 NEW_FILE
-
+
WRITE (6,'('' Converting data files to new format. Please wait.'')')
-
+
CALL SET_PROTECTION
-
+
EODIR = MAX(INDEX(FILENAME,':'),INDEX(FILENAME,']'))
SUFFIX = INDEX(FILENAME(EODIR:),'.') + EODIR - 1
NEW_FILE = FILENAME(:SUFFIX)//'OLD'
-
+
DO WHILE (FILE_LOCK(IER,IER1))
OPEN (UNIT=7,FILE=FILENAME,STATUS='OLD',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& FORM='FORMATTED',ORGANIZATION='INDEXED',IOSTAT=IER,
& KEY=(1:25:CHARACTER,26:29:INTEGER))
END DO
-
+
IF (IER.NE.0) CALL ERROR_AND_EXIT ! Error. Why?
-
+
OPEN (UNIT=19,FILE=NEW_FILE,STATUS='NEW',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& RECORDSIZE=FOLDER_RECORD,
& FORM='FORMATTED',ORGANIZATION='INDEXED',IOSTAT=IER,
& KEY=(1:25:CHARACTER,26:29:INTEGER),DISPOSE='DELETE')
-
+
IF (IER.NE.0) CALL ERROR_AND_EXIT ! Error. Why?
-
+
IF (ASK_SIZE.EQ.173/4) THEN
F_NUMBER = 0
DO WHILE (IER.EQ.0)
@@ -1001,52 +1001,52 @@ C
END IF
END DO
END IF
-
+
CLOSE (UNIT=7)
CLOSE (UNIT=19,STATUS='SAVE')
-
+
IER = LIB$RENAME_FILE(NEW_FILE,FILENAME)
IER = LIB$RENAME_FILE(BULLFOLDER_FILE//';-1',NEW_FILE)
-
+
CALL RESET_PROTECTION
-
+
IER = LIB$DELETE_FILE(BBOARD_DIRECTORY(:TRIM(BBOARD_DIRECTORY))
& //'BOARD.COM;*') ! BULLETIN$ is referenced in old file
-
+
RETURN
END
-
+
SUBROUTINE CONVERT_USERFILE
C
C SUBROUTINE CONVERT_USERFILE
C
C FUNCTION: Converts user file to new format which has 8 bytes added.
C
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLFILES.INC'
-
+
INCLUDE 'BULLUSER.INC'
-
+
CHARACTER BUFFER*74,NEW_FILE*80
-
+
CHARACTER*11 LOGIN_DATE,READ_DATE
CHARACTER*8 LOGIN_TIME,READ_TIME
-
+
WRITE (6,'('' Converting data files to new format. Please wait.'')')
-
+
EODIR = MAX(INDEX(BULLUSER_FILE,':'),INDEX(BULLUSER_FILE,']'))
SUFFIX = INDEX(BULLUSER_FILE(EODIR:),'.') + EODIR - 1
NEW_FILE = BULLUSER_FILE(:SUFFIX)//'OLD'
IER = LIB$RENAME_FILE(BULLUSER_FILE,NEW_FILE)
-
+
OPEN (UNIT=9,FILE=NEW_FILE,STATUS='OLD',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& FORM='FORMATTED',ORGANIZATION='INDEXED',IOSTAT=IER,
& KEY=(1:12:CHARACTER))
INQUIRE (UNIT=9,RECORDSIZE=RECL)
-
+
IF ((RECL-28)/16.GT.FLONG) THEN
WRITE (6,'('' ERROR: Old data files have more folders'',
& '' than was specified with BULLUSER.INC.'')')
@@ -1059,7 +1059,7 @@ C
CALL EXIT
END IF
END IF
-
+
IF (IER.EQ.0) THEN
CALL SET_PROTECTION
OPEN (UNIT=4,FILE=BULLUSER_FILE,STATUS='NEW',
@@ -1067,7 +1067,7 @@ C
& FORM='FORMATTED',ORGANIZATION='INDEXED',IOSTAT=IER,
& KEY=(1:12:CHARACTER))
END IF
-
+
IF (IER.NE.0) THEN
WRITE (6,'('' Cannot convert user file.'')')
IF (IER1.EQ.0) CALL ERRSNS(IDUMMY,IER1)
@@ -1075,14 +1075,14 @@ C
CALL RESET_PROTECTION
CALL ENABLE_CTRL_EXIT
END IF
-
+
DO I=1,FLONG
NEW_FLAG(I) = 'FFFFFFFF'X
NOTIFY_FLAG(I) = 0
BRIEF_FLAG(I) = 0
SET_FLAG(I) = 0
END DO
-
+
IF (RECL.EQ.42.OR.RECL.EQ.50.OR.RECL.EQ.58.OR.RECL.EQ.66.OR.
& RECL.EQ.74) THEN ! Old format
IF (RECL.LE.58) RECL = 50
@@ -1118,7 +1118,7 @@ C
ELSE ! Folder maxmimum increase
OFLONG = (RECL - 28) / 16 ! Old #longwords/flag
DO WHILE (IER.EQ.0)
- READ (9,FMT='(A12,<4+OFLONG*4>A4)',IOSTAT=IER)
+ READ (9,FMT='(A12,<4+OFLONG*4>A4)',IOSTAT=IER)
& TEMP_USER,LOGIN_BTIM,READ_BTIM,
& (NEW_FLAG(I),I=1,OFLONG),(SET_FLAG(I),I=1,OFLONG),
& (BRIEF_FLAG(I),I=1,OFLONG),(NOTIFY_FLAG(I),I=1,OFLONG)
@@ -1128,18 +1128,18 @@ C
END IF
END DO
END IF
-
+
IER = 0
-
+
CLOSE (UNIT=9)
CLOSE (UNIT=4)
-
+
CALL RESET_PROTECTION
-
+
RETURN
END
-
-
+
+
SUBROUTINE READDIR(BULLETIN_NUM,ICOUNT)
C
C SUBROUTINE READDIR
@@ -1154,24 +1154,24 @@ C number of blocks in bulletin file, etc.
C OUTPUTS:
C ICOUNT - The last record read by this routine.
C
-
+
IMPLICIT INTEGER (A - Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
INCLUDE 'BULLFOLDER.INC'
-
+
COMMON /PROMPT/ COMMAND_PROMPT
CHARACTER*39 COMMAND_PROMPT
-
+
COMMON /REMOTE_FOLDER/ REMOTE_SET,REMOTE_UNIT
-
+
COMMON /DIR_POSITION/ DIR_NUM
-
+
CHARACTER*3 CFOLDER_NUMBER
-
+
ICOUNT = BULLETIN_NUM
-
+
IF (ICOUNT.EQ.0) THEN
IF (.NOT.REMOTE_SET) THEN
DO WHILE (REC_LOCK(IER))
@@ -1230,19 +1230,19 @@ C
RETURN
END IF
END IF
-
+
IF (IER.EQ.0) ICOUNT = ICOUNT + 1
-
+
UNLOCK 2
-
+
RETURN
-
+
END
-
-
-
-
-
+
+
+
+
+
SUBROUTINE READDIR_KEYGE(IER)
C
C SUBROUTINE READDIR_KEYGE
@@ -1255,15 +1255,15 @@ C MSG_KEY - Message key (passed via BULLDIR.INC common block).
C OUTPUTS:
C IER - If not 0, no entry found. Else contains message number.
C
-
+
IMPLICIT INTEGER (A - Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
COMMON /REMOTE_FOLDER/ REMOTE_SET,REMOTE_UNIT
-
+
COMMON /DIR_POSITION/ DIR_NUM
-
+
IF (.NOT.REMOTE_SET) THEN
DO WHILE (REC_LOCK(IER))
READ(2,KEYID=1,KEYGT=MSG_KEY,IOSTAT=IER) BULLDIR_ENTRY
@@ -1281,66 +1281,66 @@ C
ELSE
CALL REMOTE_GET_HEADER(DUMMY,-1,IER)
END IF
-
+
RETURN
-
+
END
-
-
-
+
+
+
SUBROUTINE CONVERT_HEADER_FROMBIN
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
CHARACTER*23 DATETIME
-
+
CALL SYS$ASCTIM(,DATETIME,NEWEST_EXBTIM,)
-
+
NEWEST_EXDATE = DATETIME
NEWEST_EXTIME = DATETIME(13:)
-
+
CALL SYS$ASCTIM(,DATETIME,NEWEST_MSGBTIM,)
-
+
NEWEST_DATE = DATETIME
NEWEST_TIME = DATETIME(13:)
-
+
CALL SYS$ASCTIM(,DATETIME,SHUTDOWN_BTIM,)
-
+
SHUTDOWN_DATE = DATETIME
SHUTDOWN_TIME = DATETIME(13:)
-
+
RETURN
END
-
-
-
+
+
+
SUBROUTINE CONVERT_ENTRY_FROMBIN
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
CHARACTER*23 DATETIME
-
+
CALL SYS$ASCTIM(,DATETIME,EX_BTIM,)
-
+
EXDATE = DATETIME
EXTIME = DATETIME(13:)
-
+
CALL SYS$ASCTIM(,DATETIME,MSG_BTIM,)
-
+
DATE = DATETIME
TIME = DATETIME(13:)
-
+
RETURN
END
-
-
-
-
-
+
+
+
+
+
SUBROUTINE WRITEDIR(BULLETIN_NUM,IER)
C
C SUBROUTINE WRITEDIR
@@ -1354,23 +1354,23 @@ C If 0, write the header of the directory file.
C OUTPUTS:
C IER - Error status from WRITE.
C
-
+
IMPLICIT INTEGER (A - Z)
-
+
COMMON /REMOTE_FOLDER/ REMOTE_SET,REMOTE_UNIT
-
+
COMMON /DIR_POSITION/ DIR_NUM
-
+
INCLUDE 'BULLDIR.INC'
-
+
CONV = .TRUE.
-
+
GO TO 10
-
+
ENTRY WRITEDIR_NOCONV(BULLETIN_NUM,IER)
-
+
CONV = .FALSE.
-
+
10 IF (BULLETIN_NUM.EQ.0) THEN
IF (CONV) CALL CONVERT_HEADER_TOBIN
IF (REMOTE_SET) THEN
@@ -1410,52 +1410,52 @@ C
END IF
END IF
END IF
-
+
IF (REMOTE_SET.AND.IER.GT.0) CALL ERROR_AND_EXIT
-
+
DIR_NUM = -1
-
+
RETURN
-
+
END
-
-
-
+
+
+
SUBROUTINE CONVERT_HEADER_TOBIN
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
CALL SYS_BINTIM(NEWEST_EXDATE//' '//NEWEST_EXTIME,NEWEST_EXBTIM)
-
+
CALL SYS_BINTIM(NEWEST_DATE//' '//NEWEST_TIME,NEWEST_MSGBTIM)
-
+
CALL SYS_BINTIM(SHUTDOWN_DATE//' '//SHUTDOWN_TIME,SHUTDOWN_BTIM)
-
+
RETURN
END
-
-
-
+
+
+
SUBROUTINE CONVERT_ENTRY_TOBIN
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLDIR.INC'
-
+
CALL SYS_BINTIM(EXDATE//' '//EXTIME,EX_BTIM)
-
+
CALL SYS_BINTIM(DATE//' '//TIME,MSG_BTIM)
-
+
CALL GET_MSGKEY(MSG_BTIM,MSG_KEY)
-
+
RETURN
END
-
-
-
-
+
+
+
+
SUBROUTINE READACL(FILENAME,ACLENT,ACLLENGTH)
C
C SUBROUTINE READACL
@@ -1467,26 +1467,26 @@ C FILENAME - Name of file to check.
C ACLENT - String which will be large enough to hold ACL information.
C
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLFILES.INC'
-
+
INCLUDE '($ACLDEF)'
-
+
CHARACTER ACLENT*(*),OUTPUT*80,ACLSTR*255,FILENAME*(*)
-
+
CALL INIT_ITMLST ! Initialize item list
CALL ADD_2_ITMLST(ACLLENGTH,ACL$C_READACL,%LOC(ACLENT))
CALL END_ITMLST(ACL_ITMLST) ! Get address of itemlist
-
+
IER = SYS$CHANGE_ACL(,ACL$C_FILE,FILENAME,%VAL(ACL_ITMLST),,,)
-
+
BIG = .NOT.IER
IF (BIG) THEN
IER = SYS$PARSE_ACL('(ID=*,ACCESS=NONE)',ACLENT,,)
ACLLENGTH = ACL$S_ADDACLENT
CTXT = 0
END IF
-
+
DO ACC_TYPE=1,2
POINT = 1
OUTLEN = 0
@@ -1554,7 +1554,7 @@ C
OUTPUT = ACLSTR(START_ID:END_ID)//','
OUTLEN = IDLEN + 2
ELSE IF (OUTLEN+IDLEN-1.EQ.80) THEN
- WRITE (6,'(1X,A)')
+ WRITE (6,'(1X,A)')
& OUTPUT(:OUTLEN-1)//ACLSTR(START_ID:END_ID)
OUTLEN = 1
ELSE
@@ -1566,28 +1566,28 @@ C
END DO
IF (OUTLEN.GT.1) WRITE (6,'(1X,A)') OUTPUT(:OUTLEN-2)
END DO
-
+
RETURN
END
-
-
-
-
+
+
+
+
SUBROUTINE CONVERT_INFFILE
-
+
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE 'BULLUSER.INC'
-
+
INCLUDE 'BULLFILES.INC'
-
+
OPEN (UNIT=10,FILE=BULLINF_FILE,STATUS='OLD',
& ACCESS='KEYED',RECORDTYPE='FIXED',
& IOSTAT=IER,ORGANIZATION='INDEXED',
& KEY=(1:12:CHARACTER))
-
+
INQUIRE (UNIT=10,RECORDSIZE=RECL)
-
+
IF ((RECL-28)/16.GT.FLONG) THEN
WRITE (6,'('' ERROR: Old data files have more folders'',
& '' than was specified with BULLUSER.INC.'')')
@@ -1599,42 +1599,42 @@ C
CALL EXIT
END IF
END IF
-
+
RECL = RECL/8
-
+
OPEN (UNIT=9,FILE=BULLINF_FILE,STATUS='NEW',
& ACCESS='KEYED',RECORDTYPE='FIXED',RECORDSIZE=FOLDER_MAX*2+3,
& IOSTAT=IER,ORGANIZATION='INDEXED',
& KEY=(1:12:CHARACTER))
-
+
DO WHILE (IER.EQ.0)
READ (10,IOSTAT=IER) TEMP_USER,((LAST_READ_BTIM(J,I),J=1,2),I=1,RECL)
IF (IER.EQ.0) WRITE (9) TEMP_USER,
& ((LAST_READ_BTIM(J,I),J=1,2),I=1,FOLDER_MAX)
END DO
-
+
CLOSE (UNIT=10,STATUS='DELETE')
-
+
CLOSE (UNIT=9)
-
+
RETURN
END
-
-
+
+
SUBROUTINE ERROR_AND_EXIT
-
+
IMPLICIT INTEGER (A-Z)
-
+
CALL ERRSNS(IDUMMY,IER)
CALL SYS_GETMSG(IER)
CALL ENABLE_CTRL_EXIT
-
+
RETURN
END
-
-
-
-
+
+
+
+
SUBROUTINE COPY_ACL(INFILE,OUTFILE)
C
C SUBROUTINE COPY_ACL
@@ -1643,29 +1643,29 @@ C FUNCTION:
C Copy ACLs from one file to another file
C
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE '($ACLDEF)'
-
+
CHARACTER*(*) INFILE,OUTFILE
-
+
CALL INIT_ITMLST ! Initialize item list
CALL ADD_2_ITMLST(4,ACL$C_ACLLENGTH,%LOC(ACLLENGTH))
! Get length needed to store acl output
CALL END_ITMLST(ACL_ITMLST) ! Get address of itemlist
-
+
IER = SYS$CHANGE_ACL(,ACL$C_FILE,INFILE,%VAL(ACL_ITMLST),,,,,)
-
+
CALL LIB$GET_VM(ACLLENGTH+8,ACLSTR) ! Create character string to
CALL MAKE_CHAR(%VAL(ACLSTR),ACLLENGTH,ACLLENGTH) ! store acl
-
+
CALL COPY_ACL1(INFILE,OUTFILE,%VAL(ACLSTR),ACLLENGTH)
! Pass location of string
CALL LIB$FREE_VM(ACLLENGTH+8,ACLSTR)
-
+
RETURN
END
-
-
+
+
SUBROUTINE COPY_ACL1(INFILE,OUTFILE,ACLENT,ACLLENGTH)
C
C SUBROUTINE COPY_ACL1
@@ -1674,17 +1674,17 @@ C FUNCTION: Called by COPY_ACL to actually do the copy. Need 2 routines
C since must convert location of string into a character string.
C
IMPLICIT INTEGER (A-Z)
-
+
INCLUDE '($ACLDEF)'
-
+
CHARACTER ACLENT*(*),INFILE*(*),OUTFILE*(*)
-
+
CALL INIT_ITMLST ! Initialize item list
CALL ADD_2_ITMLST(ACLLENGTH,ACL$C_READACL,%LOC(ACLENT))
CALL END_ITMLST(ACL_ITMLST) ! Get address of itemlist
IER = SYS$CHANGE_ACL(,ACL$C_FILE,INFILE,%VAL(ACL_ITMLST),,,,,)
! Read input file acl
-
+
IF (.NOT.IER) THEN
IER = SYS$PARSE_ACL('(ID=*,ACCESS=NONE)',ACLENT,,)
IF (.NOT.IER) RETURN
@@ -1697,7 +1697,7 @@ C
CALL END_ITMLST(ACL1_ITMLST) ! Get address of itemlist
IER = SYS$CHANGE_ACL
& (,ACL$C_FILE,OUTFILE,%VAL(ACL1_ITMLST),,,)
-
+
CALL INIT_ITMLST ! Initialize item list
CALL ADD_2_ITMLST(ACLLENGTH,ACL$C_FNDACETYP,%LOC(ACLENT))
CALL END_ITMLST(ACL_ITMLST) ! Get address of itemlist
@@ -1709,18 +1709,18 @@ C
END DO
RETURN
END IF
-
+
CALL INIT_ITMLST ! Initialize item list
-
+
POINT = 1
DO WHILE (POINT.LT.ACLLENGTH) ! Transfer all acls to output file
CALL ADD_2_ITMLST(ICHAR(ACLENT(POINT:POINT)),ACL$C_ADDACLENT,
& %LOC(ACLENT(POINT:)))
POINT = POINT + ICHAR(ACLENT(POINT:POINT))
END DO
-
+
CALL END_ITMLST(ACL_ITMLST) ! Get address of itemlist
IER = SYS$CHANGE_ACL(,ACL$C_FILE,OUTFILE,%VAL(ACL_ITMLST),,,)
-
+
RETURN
END
diff --git a/folders/folders.go b/folders/folders.go
index 9f4c8fa4303e78c65412b1efedbb3e67f425191c..2fd334bf4aad947db4f3fdce6adaa8cba8a31e51 100644
--- a/folders/folders.go
+++ b/folders/folders.go
@@ -5,7 +5,6 @@ import (
"database/sql"
"embed"
"errors"
- "log"
"os"
"path"
@@ -23,11 +22,12 @@ var fs embed.FS
// Store is the store for folders.
type Store struct {
- db *sql.DB
+ user string
+ db *sql.DB
}
// Open opens the folders database.
-func Open() (*Store, error) {
+func Open(user string) (*Store, error) {
fdir := path.Join(xdg.DataHome, "BULLETIN")
err := os.MkdirAll(fdir, 0700)
if err != nil {
@@ -39,18 +39,18 @@ func Open() (*Store, error) {
if err != nil {
return nil, err
}
- m, err := migrate.NewWithSourceInstance("iofs", sqldir, "sqlite://"+fdb)
+ m, err := migrate.NewWithSourceInstance("iofs", sqldir, "sqlite://"+fdb+"?_pragma=foreign_keys(1)")
if err != nil {
- log.Fatal(err)
+ return nil, err
}
err = m.Up()
- if err != nil {
+ if err != nil && err != migrate.ErrNoChange {
return nil, err
}
m.Close()
- store := &Store{}
- store.db, err = sql.Open("sqlite", fdb)
+ store := &Store{user: user}
+ store.db, err = sql.Open("sqlite", "file://"+fdb+"?_pragma=foreign_keys(1)")
if err != nil {
return nil, errors.New("bulletin database problem")
}
diff --git a/folders/sql/1_create_table.down.sql b/folders/sql/1_create_table.down.sql
index df3837bed721d8c7b22e2eaf5ded9a401202c71f..4070921fe631b62d42878b713da994824eacb233 100644
--- a/folders/sql/1_create_table.down.sql
+++ b/folders/sql/1_create_table.down.sql
@@ -1 +1,14 @@
+--- Dropped in reverse order to deal with foreign keys.
+DROP TRIGGER co_owners_after_update_update_at;
+DROP TABLE co_owners;
+
+DROP TRIGGER folders_before_delete_protect;
+DROP TRIGGER folders_after_update_update_at;
+DROP TRIGGER folders_before_update_validate;
+DROP TRIGGER folders_before_insert_validate;
DROP TABLE folders;
+
+DROP TRIGGER users_before_delete_protect;
+DROP TRIGGER users_before_update_protect;
+DROP TRIGGER users_after_update_update_at;
+DROP TABLE users;
diff --git a/folders/sql/1_create_table.up.sql b/folders/sql/1_create_table.up.sql
index 232fd99f8a09a6d1edd860f6aecd5e56ec7d6d55..6094a1cdb7c4f74ebb93615ae3e20e45ec1e146e 100644
--- a/folders/sql/1_create_table.up.sql
+++ b/folders/sql/1_create_table.up.sql
@@ -1,18 +1,101 @@
+CREATE TABLE users (
+ login VARCHAR(25) NOT NULL PRIMARY KEY,
+ name VARCHAR(53) NOT NULL,
+ admin INT DEFAULT 0,
+ create_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ update_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
+) WITHOUT ROWID;
+
+CREATE TRIGGER users_after_update_update_at
+ AFTER UPDATE ON users FOR EACH ROW
+ WHEN NEW.update_at = OLD.update_at --- avoid infinite loop
+BEGIN
+ UPDATE users SET update_at=CURRENT_TIMESTAMP WHERE login=NEW.login;
+END;
+
+INSERT INTO users (login, name, admin)
+ VALUES ('SYSTEM', 'System User', 1);
+
+CREATE TRIGGER users_before_update_protect
+ AFTER UPDATE ON users FOR EACH ROW
+ WHEN OLD.login = 'SYSTEM' AND (NEW.login != OLD.login OR NEW.admin != 1)
+BEGIN
+ SELECT RAISE (ABORT, 'SYSTEM user is protected');
+END;
+
+CREATE TRIGGER users_before_delete_protect
+ BEFORE DELETE on users FOR EACH ROW
+ WHEN OLD.login = 'SYSTEM'
+BEGIN
+ SELECT RAISE (ABORT, 'SYSTEM user is protected');
+END;
+
CREATE TABLE folders (
- name VARCHAR(25) NOT NULL UNIQUE,
+ name VARCHAR(25) NOT NULL PRIMARY KEY,
always INT DEFAULT 0,
brief INT DEFAULT 0,
- description VARCHAR(53),
- co_owners TEXT,
+ description VARCHAR(53) NOT NULL,
notify INT DEFAULT 0,
- owner TEXT,
+ owner VARCHAR(25) REFERENCES users(login) ON UPDATE CASCADE,
readnew INT DEFAULT 0,
shownew INT DEFAULT 0,
system INT DEFAULT 0,
expire INT DEFAULT 14,
- visibility TEXT DEFAULT "public"
-);
+ visibility TEXT DEFAULT 'public',
+ create_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ update_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
+) WITHOUT ROWID;
+
+CREATE TRIGGER folders_before_insert_validate
+ BEFORE INSERT on folders
+BEGIN
+ SELECT
+ CASE
+ WHEN NEW.name != UPPER(NEW.name) OR NEW.name GLOB '*[^A-Z0-9_-]*' THEN
+ RAISE (ABORT, 'Invalid folder name')
+ END;
+END;
+
+CREATE TRIGGER folders_before_update_validate
+ BEFORE UPDATE on folders
+BEGIN
+ SELECT
+ CASE
+ WHEN NEW.name != UPPER(NEW.name) OR NEW.name GLOB '*[^A-Z0-9_-]*' THEN
+ RAISE (ABORT, 'Invalid folder name')
+ WHEN OLD.name = 'GENERAL' AND OLD.name != NEW.name THEN
+ RAISE (ABORT, 'GENERAL folder is protected')
+ END;
+END;
+
+CREATE TRIGGER folders_after_update_update_at
+ AFTER UPDATE ON folders FOR EACH ROW
+ WHEN NEW.update_at = OLD.update_at --- avoid infinite loop
+BEGIN
+ UPDATE folders SET update_at=CURRENT_TIMESTAMP WHERE name=NEW.name;
+END;
+
+CREATE TRIGGER folders_before_delete_protect
+ BEFORE DELETE on folders FOR EACH ROW
+ WHEN OLD.name = 'GENERAL'
+BEGIN
+ SELECT RAISE (ABORT, 'GENERAL folder is protected');
+END;
INSERT INTO folders (name, description, system, shownew, owner)
- VALUES ("GENERAL", "Default general bulletin folder.", 1, 1, "SYSTEM");
+ VALUES ('GENERAL', 'Default general bulletin folder.', 1, 1, 'SYSTEM');
+
+CREATE TABLE co_owners (
+ folder VARCHAR(25) REFERENCES folders(name) ON UPDATE CASCADE,
+ owner VARCHAR(25) REFERENCES users(login) ON UPDATE CASCADE,
+ create_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ update_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ PRIMARY KEY (folder, owner)
+) WITHOUT ROWID;
+CREATE TRIGGER co_owners_after_update_update_at
+ AFTER UPDATE ON co_owners FOR EACH ROW
+ WHEN NEW.update_at = OLD.update_at --- avoid infinite loop
+BEGIN
+ UPDATE co_owners SET update_at=CURRENT_TIMESTAMP WHERE folder=NEW.folder AND owner=NEW.owner;
+END;
diff --git a/repl/command.go b/repl/command.go
index 378d46a922cf2ea6a93dd799b97ff66bb3f67696..77f5d1bf9a2d8ea90ad86092bd3a1de5b084fe1d 100644
--- a/repl/command.go
+++ b/repl/command.go
@@ -9,7 +9,7 @@ var commands = dclish.Commands{
contains the message. Otherwise, BULLETIN will prompt for the text.
BULLETIN will ask for an expiration date and a header to contain the
topic of the message.
-
+
Format:
ADD [file-name]`,
MaxArgs: 1,
@@ -20,8 +20,8 @@ with the /BROADCAST qualifier. If specified, all terminals are sent the
message. Otherwise, only users are sent the message.`,
},
"/BELL": {
- Description: `This option is restricted to privileged users. It is used in conjunction
-with the /BROADCAST qualifier. If specified, the bell is rung on the
+ Description: `This option is restricted to privileged users. It is used in conjunction
+with the /BROADCAST qualifier. If specified, the bell is rung on the
terminals when the message is broadcasted.`,
},
"/BROADCAST": {
@@ -31,12 +31,12 @@ in at the time. If the folder is remote, a message will be broadcast on
all nodes which are connected to that folder, unless /LOCAL is specified.
A node which does not have BULLCP running cannot have a message
broadcasted to it, (even though it is able to create a remote folder).
-
+
See also /ALL and /BELL.`,
},
"/CLUSTER": {
Description: `/[NO]CLUSTER
-
+
This option specifies that broadcasted messages should be sent to all
nodes in the cluster. /CLUSTER is the default.`,
},
@@ -48,7 +48,7 @@ BULLETIN command line.`,
},
"/EXPIRATION": {
Description: `/EXPIRATION=time
-
+
Specifies the time at which the message is to expire. Either absolute
time: [dd-mmm-yyyy] hh:mm:ss, or delta time: dddd [hh:mm:ss] can be
used.`,
@@ -62,7 +62,7 @@ suppressed with /NOINDENT.`,
},
"/FOLDER": {
Description: `/FOLDER=(foldername,[...])
-
+
Specifies the foldername into which the message is to be added. Does
not change the current selected folder. Folders can be either local or
remote folders. Thus, a nodename can precede the foldername (this
@@ -74,11 +74,11 @@ Specifying remote nodes is only possible if that remote node is running
a special BULLCP process. If it isn't, the only way to add messages to
that remote node is via the /NODE command. However, /FOLDER is a much
quicker method, and much more versatile.
-
+
You can specify logical names which translate to one or more folder
names. I.e. $ DEFINE ALL_FOLDERS "VAX1,VAX2,VAX3", and then specify
ALL_FOLDERS after /FOLDER=. Note that the quotation marks are required.
-
+
When using /FOLDER for remote nodes, proxy logins are used to determine
if privileged options are allowed. If they are not allowed, the message
will still be added, but without the privileged settings.`,
@@ -89,7 +89,7 @@ message is broadcasted ONLY on the local node.`,
},
"/NODES": {
Description: `/NODES=(nodes[,...])
-
+
Specifies to send the message to the listed DECNET nodes. The BULLETIN
utility must be installed properly on the other nodes. (See
installation notes). You can specify a different username to use at the
@@ -97,11 +97,11 @@ other nodes by either using the USERNAME qualifier, or by specifying the
nodename with 2 semi-colons followed by the username, i.e.
nodename::username. If you specify a username, you will be prompted for
the password of the account on the other nodes.
-
+
Additionally, you can specify logical names which translate to one or
more node names. I.e. $ DEFINE ALL_NODES "VAX1,VAX2,VAX3", and then
specify /NODES=ALL_NODES. Note that the quotation marks are required.
-
+
NOTE: It is preferable to use /FOLDER instead of /NODE if possible,
since adding messages via /FOLDER is much quicker.`,
},
@@ -120,7 +120,7 @@ user has privileges.`,
},
"/SUBJECT": {
Description: `/SUBJECT=description
-
+
Specifies the subject of the message to be added.`,
},
"/SHUTDOWN": {
@@ -128,12 +128,12 @@ Specifies the subject of the message to be added.`,
This option is restricted to privileged users. If specified, message
will be automatically deleted after a computer shutdown has occurred.
This option is restricted to SYSTEM folders.
-
+
If the bulletin files are shared between cluster nodes, the message
will be deleted after the node on which the message was submitted from
is rebooted. If you wish the message to be deleted after a different
node reboots, you have the option of specifying that node name.
-
+
NOTE: If the folder is a remote folder, the message will be deleted
after the remote node reboots, not the node from which the message was
added. The nodename cannot be specified with a remote folder.`,
@@ -160,7 +160,7 @@ useful for scanning a long message.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Specifies that if a message header exists, the header will be shown.
If /HEADER or /NOHEADER is specified, the setting will apply for all
further reads in the selected folder. The default is /HEADER.`,
@@ -185,7 +185,7 @@ are to be changed. If the text of the message is to be changed, a file can
be specified which contains the text. If the editor is used for changing
the text, the old message text will be extracted. This can be suppressed
by the qualifier /NEW.
-
+
Format:
CHANGE [file-name]`,
MaxArgs: 1,
@@ -203,7 +203,7 @@ added /EDIT to your BULLETIN command line.`,
},
"/EXPIRATION": {
Description: `/EXPIRATION[=time]
-
+
Specifies the time at which the message is to expire. Either absolute
time: [dd-mmm-yyyy] hh:mm:ss, or delta time: dddd [hh:mm:ss] can be
used. If no time is specified, you will be prompted for the time.`,
@@ -223,12 +223,12 @@ new text is to be read in.`,
},
"/NUMBER": {
Description: `/NUMBER=message_number[-message_number1]
-
-Specifies the message or messages to be replaced. If this qualifier is
+
+Specifies the message or messages to be replaced. If this qualifier is
omitted, the message that is presently being read will be replaced.
A range of messages can be specified, i.e. /NUMBER=1-5. Only the expiration
date and message headers can be changed if a range is specified.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
},
@@ -241,7 +241,7 @@ shutdown. This option is restricted to SYSTEM folders.`,
},
"/SUBJECT": {
Description: `/SUBJECT=description
-
+
Specifies the subject of the message to be added.`,
},
"/SYSTEM": {
@@ -256,15 +256,15 @@ privileged command and is restricted to SYSTEM folders.`,
"COPY": {
Description: `Copies a message to another folder without deleting it from the
current folder.
-
+
Format:
-
+
COPY folder-name [message_number][-message_number1]
-
+
The folder-name is the name of the folder to which the message is to be
copied to. Optionally, a range of messages which are to be copied can be
specified following the folder name, i.e. COPY NEWFOLDER 2-5.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
MinArgs: 1,
@@ -275,14 +275,14 @@ in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Valid only if destination folder is a news group. Specifies that header
of message is to be included with the text when the text is copied.
The default is /NOHEADER.`,
},
"/MERGE": {
Description: `Specifies that the original date and time of the copied messages are
-saved and that the messages are placed in correct chronological order
+saved and that the messages are placed in correct chronological order
in the new folder. This operation is lengthy if the new folder is large.`,
},
"/ORIGINAL": {
@@ -300,14 +300,14 @@ to specified users. Once created, that message is automatically
selected (see information on SELECT command). The commands that can be
used to modify the folder's characteristics are: MODIFY, REMOVE, SET
ACCESS, SET BBOARD, SET NODE, and SET SYSTEM.
-
+
Format:
CREATE folder-name
-
+
The folder-name is limited to 25 letters and must not include spaces or
characters that are also invalid in filenames (this is because the
folder is stored in a file name created with the folder name).
-
+
NOTE: Creation of folders may be a restricted command if the installer
has elected to install it as such. This is done by modifying
BULLCOM.CLD.`,
@@ -332,26 +332,26 @@ more information.)`,
},
"/DESCRIPTION": {
Description: `/DESCRIPTION=description
-
+
Specifies the description of the folder, which is displayed using the
SHOW FOLDER command. If omitted, you are prompted for a description.
-
+
If this folder is to receive messages from a network mailing list
via the BBOARD feature, and you wish to use the POST and RESPOND/LIST
commands, the address of the mailing list should be included in the
description. This is done by enclosing the address using <> and
placing it at the end of the description, i.e.
-
+
INFOVAX MAILING LIST <INFO-VAX@KL.SRI.COM>
-
+
If a mailer protocol is needs to be added to the network address in
order for it to be sent by VMS MAIL, i.e. protocol%"address", the
appropriate protocol can be specified by either hardcoding it into the
file BULLNEWS.INC before compiling BULLETIN, or by defining the system
logical name BULL_NEWS_MAILER (it is the same protocol used by the NEWS
feature in order to respond to NEWS messages). The default protocol is
-IN%. If desired, you can specify the protocol with the address, i.e.
-
+IN%. If desired, you can specify the protocol with the address, i.e.
+
INFOVAX MAILING LIST <IN%"INFO-VAX@KL.SRI.COM">`,
},
"/ID": {
@@ -360,12 +360,12 @@ identifier. The creator's process must have the identifier presently
assigned to it. Any process which has that identifier assigned to it
will be able to control the folder as if it were the folder's owner.
This is used to allow more than one use to control a folder.
-
+
Note: This feature will not work during remote access to the folder.`,
},
"/NODE": {
Description: `/NODE=node
-
+
Specifies that the folder is a remote folder at the specified node.
A remote folder is a folder in which the messages are actually stored
on a folder at a remote DECNET node. The specified node is checked to
@@ -379,7 +379,7 @@ between more than one node. This capability is only present if the BULLCP
process is running on the remote node via the BULL/STARTUP command.
If the remote folder name is different from the local folder name, the
remote folder name is specified using the /REMOTENAME qualifier.
-
+
NOTE: If a message is added to a remote node, the message is stored
immediately. However, a user logging into another node might not be
immediately alerted that the message is present. That information is
@@ -433,7 +433,7 @@ respect to adding or modifying messages. All users can read the folder.`,
Description: `Specifies that the folder is a SYSTEM folder. A SYSTEM folder is
allowed to have SYSTEM and SHUTDOWN messages added to it. By default,
the GENERAL folder is a SYSTEM folder. This is a privileged command.
-
+
If this is a remote folder, /SYSTEM cannot be specified unless the
folder at the other node is also a SYSTEM folder.`,
},
@@ -443,9 +443,9 @@ folder at the other node is also a SYSTEM folder.`,
Description: `Displays the beginning of the message you are currently reading. If
you are reading a long message and want to display the first part
of the message again, you can enter the CURRENT command.
-
+
Format:
-
+
CURRENT`,
Flags: dclish.Flags{
"/EDIT": {
@@ -454,7 +454,7 @@ useful for scanning a long message.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Specifies that if a message header exists, the header will be shown.
If /HEADER or /NOHEADER is specified, the setting will apply for all
further reads in the selected folder. The default is /HEADER.`,
@@ -468,15 +468,15 @@ delete a message. Note that the message is not deleted immediately, but
its expiration is set 15 minutes in the future. This is to allow a user
to recover the message using the UNDELETE command. If you want the
message deleted immediately, use the /IMMEDIATE qualifier.
-
+
Format:
DELETE [message_number][-message_number1]
-
+
The message's relative number is found by the DIRECTORY command. It is
possible to delete a range of messages by specifying two numbers
separated by a dash, i.e. DELETE 1-5. However, a range cannot be
specified if the folder is remote.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
MaxArgs: 1,
@@ -491,7 +491,7 @@ remote folder at a time.`,
},
"/NODES": {
Description: `/NODES=(nodes[,...])
-
+
Specifies to delete the message at the listed DECNET nodes. The BULLETIN
utility must be installed properly on the other nodes. You can specify
a different username to use at the other nodes by either using the
@@ -500,14 +500,14 @@ followed by the username, i.e. nodename::username. If you specify a
username, you will be prompted for the password of the account on the
other nodes. The /SUBJECT must be specified to identify the specific
message that is to be deleted.
-
+
Additionally, you can specify logical names which translate to one or
more node names. I.e. $ DEFINE ALL_NODES "VAX1,VAX2,VAX3", and then
specify /NODES=ALL_NODES. Note that the quotation marks are required.`,
},
"/SUBJECT": {
Description: `/SUBJECT=subject
-
+
Specifies the subject of the bulletin to be deleted at a remote DECNET
node. The DECNET node must be specified with the /NODE qualifier.
The specified subject need not be the exact subject of the message.
@@ -524,11 +524,11 @@ on other DECNET nodes via the /NODE qualifier.`,
"DIRECTORY": {
Description: `Lists a summary of the messages. The message number, submitter's name,
date, and subject of each message is displayed.
-
+
Format:
-
+
DIRECTORY [folder]
-
+
If a folder is specified, that folder is selected before the directory
is listed. Unless otherwise specified, listing starts with the first
newest message. If there are no new messages, listing will start at the
@@ -550,7 +550,7 @@ folder.`,
},
"/END": {
Description: `/END=message_number
-
+
Indicates the last message number you want to display.`,
},
"/FOLDERS": {
@@ -572,7 +572,7 @@ to be read. To see all messages, use either /ALL, or reselect the
folder.`,
},
"/SEEN": {
- Description: `Lists messages that have been seen (indicated by a greater than sign).
+ Description: `Lists messages that have been seen (indicated by a greater than sign).
Using /SEEN is equivalent to selecting the folder with /SEEN, i.e. only
seen messages will be shown and be able to be read. To see all
messages, use either /ALL, or reselect the folder.`,
@@ -600,27 +600,27 @@ are to be displayed. This cannot be used in conjunction with /MARKED.`,
},
"/SEARCH": {
Description: `/SEARCH=[string]
-
+
Specifies that only messages which contain the specified string are
to be displayed. This cannot be used in conjunction with /MARKED.
If no string is specified, the previously specified string is used.`,
},
"/SINCE": {
Description: `/SINCE=date
-
+
Displays a listing of all the messages created on or after the
specified date. If no date is specified, the default is TODAY.`,
},
"/START": {
Description: `/START=message_number
-
+
Indicates the first message number you want to display. For example,
to display all the messages beginning with number three, enter the
command line DIRECTORY/START=3. Not valid with /FOLDER.`,
},
"/SUBJECT": {
Description: `/SUBJECT=[string]
-
+
Specifies that only messages which contain the specified string in it's
subject header are to be displayed. This cannot be used in conjunction
with /MARKED. If no string is specified, the previously specified string
@@ -639,13 +639,13 @@ is used.`,
Description: `Copies the current message to the named file. The file-name parameter
is required. If the file exists, the message is appended to the file,
unless the /NEW qualifier is specified.
-
+
Format:
FILE filename [message_number][-message_number1],[...]
-
+
A range of messages to be copied can optionally be specified, i.e.
FILE 2-5.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
MinArgs: 1,
@@ -659,8 +659,8 @@ in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
-Controls whether a header containing the owner, subject, and date of the
+
+Controls whether a header containing the owner, subject, and date of the
message is written in the file. The default is to write the header.`,
},
"/NEW": {
@@ -677,8 +677,10 @@ file exists, the file would be appended to that file.`,
},
"HELP": {
Description: `To obtain help on any topic, type:
-
- HELP topic`,
+
+ HELP topic
+
+Type "HELP Topics" to get a list of topics.`,
MaxArgs: 1,
Action: ActionHelp,
},
@@ -688,7 +690,7 @@ INDEX command is re-entered while the listing is in progress, the listing
will skip to the next folder. This is useful for skipping a particular
folder. It also can be used to continue the listing from where one left
off after one has read a message.
-
+
Format:
INDEX`,
Action: ActionIndex,
@@ -705,7 +707,7 @@ with /UNMARKED, i.e. only unmarked messages will be shown and be able
to be read.`,
},
"/SEEN": {
- Description: `Lists messages that have been seen (indicated by a greater than sign).
+ Description: `Lists messages that have been seen (indicated by a greater than sign).
Using /SEEN is equivalent to selecting the folder with /SEEN, i.e. only
seen messages will be shown and be able to be read.`,
},
@@ -755,7 +757,7 @@ first folder.`,
},
"LAST": {
Description: `Displays the last message in the current folder.
-
+
Format:
LAST`,
Flags: dclish.Flags{
@@ -765,7 +767,7 @@ useful for scanning a long message.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Specifies that if a message header exists, the header will be shown.
If /HEADER or /NOHEADER is specified, the setting will apply for all
further reads in the selected folder. The default is /HEADER.`,
@@ -775,11 +777,11 @@ further reads in the selected folder. The default is /HEADER.`,
"MAIL": {
Description: `Invokes the VAX/VMS Personal Mail Utility (MAIL) to send the message
which you are reading to the specified recipients.
-
+
Format:
-
+
MAIL recipient-name[s]
-
+
The input for the recipient name is exactly the same format as used by
the MAIL command at DCL level. Note that this means when specifying an
address that has quotes, in order to pass the quotes you must specify
@@ -794,16 +796,16 @@ mailing it.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
-Controls whether a header containing the owner, subject, and date of the
+
+Controls whether a header containing the owner, subject, and date of the
message is written in the mail. The default is to write the header.`,
},
"/SUBJECT": {
Description: `/SUBJECT=text
-
+
Specifies the subject of the mail message. If the text consists of more
than one word, enclose the text in quotation marks (").
-
+
If you omit this qualifier, the description of the message will be used
as the subject.`,
},
@@ -815,12 +817,12 @@ displayed with an asterisk in the left hand column of the directory
listing. A marked message can serve as a reminder of important
information. The UNMARK command sets the current or message-id message
as unmarked.
-
+
Format:
-
+
MARK [message-number or numbers]
UNMARK [message-number or numbers]
-
+
NOTE: The list of marked messages are stored in a file username.BULLMARK.
The files are created in the directory pointed to by the logical name
BULL_MARK. If BULL_MARK is not defined, SYS$LOGIN will be used.`,
@@ -832,12 +834,12 @@ displayed with an asterisk in the left hand column of the directory
listing. A marked message can serve as a reminder of important
information. The UNMARK command sets the current or message-id message
as unmarked.
-
+
Format:
-
+
MARK [message-number or numbers]
UNMARK [message-number or numbers]
-
+
NOTE: The list of marked messages are stored in a file username.BULLMARK.
The files are created in the directory pointed to by the logical name
BULL_MARK. If BULL_MARK is not defined, SYS$LOGIN will be used.`,
@@ -845,23 +847,23 @@ BULL_MARK. If BULL_MARK is not defined, SYS$LOGIN will be used.`,
},
"MODIFY": {
Description: `Modifies the database information for the current folder. Only the
-owner of the folder or a user with privileges can use this command.
-
+owner of the folder or a user with privileges can use this command.
+
Format:
-
+
MODIFY`,
Action: ActionModify,
Flags: dclish.Flags{
"/DESCRIPTION": {
Description: `Specifies a new description for the folder. You will be prompted for
the text of the description.
-
+
NOTE: If this folder is to receive messages from a network mailing list
via the BBOARD feature, and you wish to use the POST and RESPOND/LIST
commands, the address of the mailing list should be included in the
description. This is done by enclosing the address using <> and
placing it at the end of the description, i.e.
-
+
INFOVAX MAILING LIST <IN%"INFO-VAX@KL.SRI.COM">`,
},
"/ID": {
@@ -870,17 +872,17 @@ identifier. The creator's process must have the identifier presently
assigned to it. Any process which has that identifier assigned to it
will be able to control the folder as if it were the folder's owner.
This is used to allow more than one use to control a folder.
-
+
Note: This feature will not work during remote access to the folder.`,
},
"/NAME": {
Description: `/NAME=foldername
-
+
Specifies a new name for the folder.`,
},
"/OWNER": {
Description: `/OWNER=username
-
+
Specifies a new owner for the folder. If the owner does not have
privileges, BULLETIN will prompt for the password of the new owner
account in order to okay the modification. See also /ID.`,
@@ -890,17 +892,17 @@ account in order to okay the modification. See also /ID.`,
"MOVE": {
Description: `Moves a message to another folder and deletes it from the current
folder.
-
+
Format:
-
+
MOVE folder-name [message_number][-message_number1]
-
+
The folder-name is the name of the folder to which the message is to be
be moved to. Optionally, a range of messages which are to be moved can be
specified following the folder name, i.e. COPY NEWFOLDER 2-5. However,
if the old folder is remote, they will be copied but not deleted, as
only one message can be delted from a remote folder at a time.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.`,
MinArgs: 1,
@@ -913,7 +915,7 @@ message can be deleted from a remote folder at a time.`,
},
"/MERGE": {
Description: `Specifies that the original date and time of the moved messages are
-saved and that the messages are placed in correct chronological order
+saved and that the messages are placed in correct chronological order
in the new folder. This operation is lengthy if the new folder is large.`,
},
"/ORIGINAL": {
@@ -934,7 +936,7 @@ useful for scanning a long message.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Specifies that if a message header exists, the header will be shown.
If /HEADER or /NOHEADER is specified, the setting will apply for all
further reads in the selected folder. The default is /HEADER.`,
@@ -942,22 +944,22 @@ further reads in the selected folder. The default is /HEADER.`,
},
},
"PRINT": {
- Description: `Queues a copy of the message you are currently reading (or have
+ Description: `Queues a copy of the message you are currently reading (or have
just read) for printing. The file created by the PRINT command
is not released to the print queue until you exit, unless you add
the qualifier /NOW or change one of the print job's qualifiers.
Multiple messages are concatenated into one print job.
-
+
Format:
-
+
PRINT [message_number][-message_number1],[...]
-
+
A range of messages to be printed can optionally be specified, i.e.
PRINT 2-5.
-
+
The key words CURRENT and LAST can also be specified in the range,
in place of an actual number, i.e. CURRENT-LAST, 1-CURRENT, etc.
-
+
NOTE: The qualifier /PRINT is present on the DIRECTORY command. This
provides more flexibility than is present with the PRINT command. For
example, if you want to print all messages with a particular string in
@@ -983,13 +985,13 @@ queue specifying the new form type as the mounted form.)`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
-Controls whether a header containing the owner, subject, and date of the
+
+Controls whether a header containing the owner, subject, and date of the
message is printed at the beginning. The default is to write the header.`,
},
"/NOTIFY": {
Description: `/[NO]NOTIFY
-
+
Indicates that you will be notified by a broadcast message when the
file or files have been printed. If /NONOTIFY is specified, there
is no notification. The default is /NOTIFY.`,
@@ -1000,7 +1002,7 @@ command during this session to the printer.`,
},
"/QUEUE": {
Description: `/QUEUE=queue_name
-
+
The name of the queue to which a message is to be sent. If the /QUEUE
qualifier is not specified, the message is queued to SYS$PRINT.`,
},
@@ -1012,18 +1014,18 @@ the first time you enter the command, the first message in the folder
will be displayed. However, if there are new messages, the first new
message will be displayed. Each time you enter the command, the next
page, or if there are no more pages, the next message will be displayed.
-
+
Format:
READ [message-number]
-
+
The message's relative number is found by the DIRECTORY command.
If you specify a number greater than the number of messages in the
folder, the last message in the folder will be displayed.
-
+
NOTE: The READ command can be abbreviated by omitting the READ command,
i.e. typing the command "2" is equivalent to "READ 2", and simply
-hitting the <RETURN> key is equivalent to "READ".
-
+hitting the <RETURN> key is equivalent to "READ".
+
BULLETIN normally stores only the latest message that has been read per
folder. It can optionally store and display which messages have been
read in a folder on a per message basis. For information on this, see
@@ -1040,7 +1042,7 @@ useful for scanning a long message.`,
},
"/HEADER": {
Description: `/[NO]HEADER
-
+
Specifies that if a message header exists, the header will be shown.
If /HEADER or /NOHEADER is specified, the setting will apply for all
further reads in the selected folder. The default is /HEADER.`,
@@ -1077,7 +1079,7 @@ reselect the folder.`,
},
"/PAGE": {
Description: `/[NO]PAGE
-
+
Specifies that the display of the message will pause when it reaches the
end of the page. If /NOPAGE is specified, the whole message will be
displayed. This is useful for terminals that can store more than one
@@ -1086,7 +1088,7 @@ the contents of the terminal's memory.`,
},
"/SINCE": {
Description: `/SINCE=date
-
+
Specifies to read the first message created on or after the specified
date. If no date is specified, the default is TODAY.`,
},
@@ -1095,7 +1097,7 @@ date. If no date is specified, the default is TODAY.`,
"REMOVE": {
Description: `Removes a folder. Only the owner of a folder or a privileged user can
remove the folder.
-
+
Format:
REMOVE folder-name`,
MinArgs: 1,
@@ -1105,7 +1107,7 @@ remove the folder.
Description: `Adds message with subject of message being the subject of the currently
read message with "RE:" preceeding it. Format and qualifiers is exactly
the same as the ADD command except for /NOINDENT and /EXTRACT.
-
+
Format:
REPLY [file-name]`,
MaxArgs: 1,
@@ -1124,10 +1126,10 @@ This can be suppressed with /NOINDENT.`,
"RESPOND": {
Description: `Invokes the VAX/VMS Personal Mail Utility (MAIL) to send a reply mail
message to the owner of the currently read message.
-
+
Format:
RESPOND [file-name]
-
+
If you wish to use another method for sending the mail, define BULL_MAILER
to point to a command procedure. This procedure will then be executed in
place of MAIL, and the parameters passed to it are the username and subject
@@ -1164,10 +1166,10 @@ See the help topic POST Signature_file for signature information.`,
},
"/SUBJECT": {
Description: `/SUBJECT=text
-
+
Specifies the subject of the mail message. If the text consists of more
than one word, enclose the text in quotation marks (").
-
+
If you omit this qualifier, the description of the message will be used
as the subject preceeded by "RE: ".`,
},
@@ -1180,11 +1182,11 @@ as the subject preceeded by "RE: ".`,
"SEARCH": {
Description: `Searches the currently selected folder for the message containing the
first occurrence of the specified text string.
-
+
Format:
-
+
SEARCH [search-string]
-
+
The search starts from the first message in the current folder. The
search includes both the text of the message, and the description header.
If a "search-string" is not specified, a search is made using the
@@ -1199,7 +1201,7 @@ search can be aborted by typing a CTRL-C.`,
},
"/FOLDER": {
Description: `/FOLDER=(folder,[...])
-
+
Specifies a list of folders to be searched. The search will start by
selecting the first folder in the list and searching the messages for
a match. If, during a search, no more matches or messages are found,
@@ -1219,7 +1221,7 @@ message.`,
},
"/START": {
Description: `/START=message_number
-
+
Specifies the message number to start the search at.`,
},
"/SUBJECT": {
@@ -1233,17 +1235,17 @@ track of messages on a per message basis. Seen messages are displayed
with a greater than sign in the left hand column of the directory
listing. Once you have used the SEEN command once, messages will be
automatically be set as being SEEN when they are read. The UNSEEN
-command sets the current or message-id message as unseen.
-
+command sets the current or message-id message as unseen.
+
Format:
-
+
SEEN [message-number or numbers]
UNSEEN [message-number or numbers]
-
+
If you have used the SEEN command and wish to disable the automatic
marking of messages in regular folders as SEEN when they are read, type
the command SEEN/NOREAD. To reenable, simply use the SEEN command again.
-
+
NOTE: The list of SEEN messages are stored in a
file username.BULLMARK. NEWSMARK. The files are created in the directory
pointed to by the logical name BULL_MARK. If BULL_MARK is not defined,
@@ -1257,17 +1259,17 @@ track of messages on a per message basis. Seen messages are displayed
with a greater than sign in the left hand column of the directory
listing. Once you have used the SEEN command once, messages will be
automatically be set as being SEEN when they are read. The UNSEEN
-command sets the current or message-id message as unseen.
-
+command sets the current or message-id message as unseen.
+
Format:
-
+
SEEN [message-number or numbers]
UNSEEN [message-number or numbers]
-
+
If you have used the SEEN command and wish to disable the automatic
marking of messages in regular folders as SEEN when they are read, type
the command SEEN/NOREAD. To reenable, simply use the SEEN command again.
-
+
NOTE: The list of SEEN messages are stored in a
file username.BULLMARK. NEWSMARK. The files are created in the directory
pointed to by the logical name BULL_MARK. If BULL_MARK is not defined,
@@ -1281,19 +1283,19 @@ folder. Once a folder has been selected, all commands, i.e. DIRECTORY,
READ, etc. will apply only to those messages. Use the CREATE command to
create a folder. Use the DIRECTORY/FOLDER command to see the list of
folders that have been created.
-
+
Format:
-
+
SELECT [node-name::][folder-name]
-
+
The complete folder name need not be specified. BULLETIN will try to
find the closest matching name. I.e. INFOV can be used for INFOVAX.
-
+
Omitting the folder name will select the default general messages.
-
+
The node name can be specified only if the remote node has the special
BULLCP process running (invoked by BULLETIN/STARTUP command.)
-
+
After selecting a folder, the user will notified of the number of unread
messages, and the message pointer will be placed at the first unread
message.`,
@@ -1310,20 +1312,20 @@ to be reselected.`,
"SET": {
Description: `The SET command is used with other commands to define or change
characteristics of the BULLETIN Utility.
-
+
Format:
-
+
SET option`,
Flags: dclish.Flags{
"ACCESS": {
Description: `Controls access to a private folder. A private folder can only be
selected by users who have been granted access. Only the owner of that
folder is allowed to grant access.
-
+
Format:
-
+
SET [NO]ACCESS id-name [folder-name]
-
+
The id-name can be one or more ids from the system Rights Database for
which access is being modified. It can also be a file name which
contains a list of ids. For more information concerning usage of
@@ -1331,7 +1333,7 @@ private folders, see HELP CREATE /PRIVATE. NOTE: Access is created via
ACLs. If a user's process privileges are set to override ACLs, that
user will be able to access the folder even if access has not been
granted.
-
+
It is suggested that if you plan on granting access to many users, that
you create an id using the AUTHORIZE utility and then use the SET ACCESS
command to grant access to that id. Then, you can use the GRANT/ID
@@ -1341,7 +1343,7 @@ running into system quota when checking for acls on a file with a large
amount of acls. It is also means that you don't have to remember to
remove the access for that user from a folder if that user is removed
from the system.
-
+
A user with BULLETIN privileges (see HELP SET PRIV) will be able to
select a protected folder regardless of the access settings. However, a
user without explicit access will not receive login notifications of new
@@ -1357,7 +1359,7 @@ comma must be enclosed in quotes. UICs can contain wildcards, i.e.
id SYS$NODE_nodename, where nodename is the decnet nodename. Thus, by
specifing this id, a folder can be restricted to a specific node, which
is useful when the folder is shared among nodes in a cluster.
-
+
Alternatively, the id-name can be a filename which contains a list of
ids. The filename should be preceeded by a "@". If the suffix is not
specified, it will be assumed that the suffix is ".DIS" .
@@ -1367,9 +1369,9 @@ is not specified, the folder will no longer be private. If /READ is
specified, all users will have read access, but only privileged users
will have write access (of course non-privileged users can gain access
via a later SET ACCESS command.)
-
+
Format:
-
+
SET ACCESS /ALL [folder-name]
3 /READ
Specifies that access to the folder will be limited to being able to
@@ -1394,9 +1396,9 @@ than just once. Non-SYSTEM message will also be displayed every time
the user actually reads that message (or a later one). This feature is
meant for messages which are very important, and thus you want to make
sure they are read.
-
+
Format:
-
+
SET [NO]ALWAYS`,
},
"BBOARD": {
@@ -1413,19 +1415,19 @@ which is spawned to read the mail. The parameters and the suggested
values are: PQL_DPGFLQUOTA = 10000, PQL_DWSQUOTA = 500, and PQL_DFILLM
= 30. If you are not using the BULLCP process, the subprocess limit for
users must be at least 2.
-
+
Format:
-
+
SET BBOARD [username]
-
+
BBOARD cannot be set for remote folders. See also the command SET
DIGEST for options on formatting BBOARD messages.
-
+
If BULLCP is running, BBOARD is updated every 15 minutes. If you want
to length this period, define BULL_BBOARD_UPDATE to be the number of
minutes, between updates. I.e. DEFINE/SYSTEM BULL_BBOARD_UPDATE "30"
will cause the updates to be don every 30 minutes.
-
+
NOTE: If you want to control the expiration date on a per message basis,
you can do so by adding a special header line to the message. The form
is Expires: or X-Expires: followed by the date in the form DD MMM YYYY.
@@ -1433,12 +1435,12 @@ The time will always be 00:00, even if the time is specified on the line.
3 /EXPIRATION
/EXPIRATION=days
/NOEXPIRATION
-
+
Specifies the number of days the message created by the BBOARD is to be
retained. The default is 14 days. The highest limit that can be
specified is 30 days. This can be overridden by a user with privileges.
If /NOEXPIRATION is specified, messages will become permanent.
-
+
NOTE: This value is the same value as specified by SET DEFAULT_EXPIRE.
If one is changed, the other will change also.
3 /SPECIAL
@@ -1461,37 +1463,37 @@ This problem is solved by placing the word LISTSERV in the folder
description line. Then, messages sent to the mailing list by the POST
command will be sent from the BBOARD account rather than from the user's
account. For example, the folder description might be:
-
+
FAKE MAILING LIST <FAKELIST@FAKENODE.BITNET> LISTSERV.
-
+
If you have PMDF or MX installed, the corresponding logical name
PMDF_REPLY_TO or MX_REPLY_TO will be temporarily defined in order to add
a REPLY-TO: line to the message header to display the real user's
address.
-
+
Users who use the method described in HELP SET BBOARD MORE_INFORMATION
should note the following: When using this LISTSERV feature, the BBOARD
account must be a real account, not simply a VMS MAIL forwarding entry.
Mail can only be sent from a real account. However, if mail forwarding
is set for that the account, the account does not need a real directory
or a unique uic, since it will not need space to store mail.
-
+
In order to be able to send LISTSERV commands from the BBOARD account
without having to actually login to the BBOARD account, there is a
utility included with BULLETIN called SETUSER. This requires privileges
to use. After compiling it, use the link command:
-
+
LINK SETUSER,SYS$SYSTEM:SYS.STB/SELECT
-
+
When you run it, it will prompt for a username. After verifying that
the given username is a valid account, it will then change your
process's username. You can then send mail from that account.
-
+
If you are using PMDF or MX, and wish to use this feature, you can still
do so by setting BBOARD. As long as the BBOARD account is not a real
account, it will work properly, even though the mail feed is not really
coming from the BBOARD account.
-
+
In order to find out if the LISTSERV mailing list will accept posts only
from subscribed users, send the command 'REV listname'. This will
retrieve the file listname.LIST. It begins with a list of keywords. If
@@ -1501,16 +1503,16 @@ of the keywords and the meaning of their settings, send any LISTSERV the
command 'INFO KEY'. Note that the 'listname.LIST' files include a list
of owners and subscribers. If 'send' is set to 'owners', then neither
the public nor the subscribers can post to the list.
-
+
3 More_information
If more than one folder is to have a BBOARD setting, only one of the
BBOARD names need be a real account. All other names could be names
whose mail is forwarded to the real account. BULLETIN will then
determine from the mail header which folder the mail is to be sent to.
Forwarding can be enabled for any name within MAIL by the command:
-
+
MAIL> SET FORWARD/USER=from_name to_name
-
+
Any mail sent to FROM_NAME will be forwarded to TO_NAME. Thus, only
TO_NAME need be a real account. For example, if you have INFOVAX and
LASER-LOVERS folders, you need create only a INFOVAX account, and then
@@ -1523,7 +1525,7 @@ the /SPECIAL set on their BBOARD accounts cannot have their mail
forwarded to BBOARD accounts that don't have /SPECIAL set. Folders of
the same type, i.e. that use the same /SPECIAL command procedure, must
be grouped separately.
-
+
The BBOARD account must match the mailing list name. If you prefer not
to have them match, then you must include the actual address of the
mailing list in the folder description in the format described under
@@ -1537,9 +1539,9 @@ BULLETIN. Note the difference between BRIEF and READNEW. The latter
causes a listing of the description of the new messages to be displayed
and prompts the user to read the messages. Setting BRIEF will clear a
READNEW setting (and visa versa).
-
+
Format:
-
+
SET [NO]BRIEF
3 /ALL
Specifies that the SET [NO]BRIEF option is the default for all users for
@@ -1550,12 +1552,12 @@ folder. This is a privileged qualifier. It will only affect brand new
users (or those that have never logged in). Use /ALL to modify all users.
3 /FOLDER
/FOLDER=foldername
-
+
Specifies the folder for which the option is to modified. If not
specified, the selected folder is modified. Valid only with NOBRIEF.
3 /PERMANENT
/[NO]PERMANENT
-
+
Specifies that BRIEF is a permanent flag and cannot be changed by the
individual, except if changing to SHOWNEW or READNEW. This is a
privileged qualifier.`,
@@ -1566,11 +1568,11 @@ the notification message "there are new messages" will be displayed every
time when logging in, until the new messages are read. Normally, the
BRIEF setting causes notification only at the first time that new messages
are detected.
-
+
Format:
-
+
SET [NO]CONTINUOUS_BRIEF
-
+
NOTE: Both SET GENERIC and SET CONTINUOUS_BRIEF cannot be set for the
same user.`,
},
@@ -1579,21 +1581,21 @@ same user.`,
PMDF path) is to be retained. The default is 14 days. The highest
limit that can be specified is 30 days. This can be overridden by a
user with privileges.
-
+
This also specifies the default expiration date when adding a message.
If no expiration date is entered when prompted for a date, or if
prompting has been disabled via SET NOPROMPT_EXPIRE, this value will be
used.
-
+
Format:
-
+
SET DEFAULT_EXPIRE days
-
+
If -1 is specified, messages will become permanent. If 0 is specified,
no default expiration date will be present. The latter should never be
specified for a folder with a BBOARD, or else the messages will
disappear.
-
+
NOTE: This value is the same value that SET BBOARD/EXPIRATION specifies.
If one is changed, the other will change also.`,
},
@@ -1603,11 +1605,11 @@ written directly from a network mailing program (i.e. PMDF). Several
mailing lists use digest format to send their messages, i.e. the
messages are concatenated into one long message. If DIGEST is set, the
messages will be separated into individual BULLETIN messages.
-
+
Format:
-
+
SET [NO]DIGEST
-
+
The command SHOW FOLDER/FULL will show if DIGEST has been set.
`,
},
@@ -1615,11 +1617,11 @@ The command SHOW FOLDER/FULL will show if DIGEST has been set.
Description: `Specifies that messages deleted from the selected folder are written
into a dump (or log) file. The name of the log file is foldername.LOG,
and it is located in the folder directory.
-
+
Format:
-
+
SET [NO]DUMP
-
+
The command SHOW FOLDER/FULL will show if dump has been set. (NOTE:
SHOW FOLDER/FULL is a privileged command.)`,
},
@@ -1627,18 +1629,18 @@ SHOW FOLDER/FULL is a privileged command.)`,
Description: `Specifies expiration limit that is allowed for messages. Non-privileged
users cannot specify an expiration that exceeds the number of days
specified. Privileged users can exceed the limit.
-
+
SET [NO]EXPIRE_LIMIT [days]
-
+
The command SHOW FOLDER/FULL will show the expiration limit, if one
exists. (NOTE: SHOW FOLDER/FULL is a privileged command.)`,
},
"FOLDER": {
Description: `Select a folder of messages. Identical to the SELECT command. See help
on that command for more information.
-
+
Format:
-
+
SET FOLDER [node-name::][folder-name]
3 /MARKED
Selects messages that have been marked (indicated by an asterisk).
@@ -1652,16 +1654,16 @@ many different people. If an account is specified as GENERIC, new
messages placed in the GENERAL folder will be displayed upon logging in
for a specific number of days, rather than only once. The default
period is 7 days. This command is a privileged command.
-
+
Format:
-
+
SET [NO]GENERIC username
-
+
NOTE: Both SET GENERIC and SET CONTINUOUS_BRIEF cannot be set for the
same user.
3 /DAYS
/DAYS=number_of_days
-
+
Specifies the number days that new GENERAL messages will be displayed
for upon logging in.
`,
@@ -1671,9 +1673,9 @@ for upon logging in.
keypad correspond to command definitions. These definitions can be seen
via the SHOW KEYPAD command. The default is NOKEYPAD unless the /KEYPAD
qualifier has been added to the BULLETIN command line.
-
+
Format:
-
+
SET [NO]KEYPAD
`,
},
@@ -1686,9 +1688,9 @@ occur if DISMAIL is set for an old account. Additionally, removing the
DISMAIL flag will not automatically enable LOGIN. (The reason for the
above was to avoid extra overhead for constant checking for the DISMAIL
flag.) This command is a privileged command.
-
+
Format:
-
+
SET [NO]LOGIN username
`,
},
@@ -1702,18 +1704,18 @@ the local folder. When the command is executed, the selected folder
will then point to the remote folder. If there were messages in the
local folder, they will be deleted. This feature is present only if the
BULLCP process is running on the remote node.
-
+
Format:
SET NODE nodename [remotename]
SET NONODE
-
+
NOTE: If one node adds a message to a remote node, other nodes connected
to the same folder will not immediately be aware of the new message.
This info is updated every 15 minutes, or if a user accesses that
folder.
3 /FOLDER
/FOLDER=foldername
-
+
Specifies the folder for which the node information is to modified.
If not specified, the selected folder is modified.
`,
@@ -1721,11 +1723,11 @@ If not specified, the selected folder is modified.
"NOTIFY": {
Description: `Specifies whether you will be notified via a broadcast message when a
message is added to the selected folder.
-
+
Format:
-
+
SET [NO]NOTIFY
-
+
In a cluster, if the logical name MAIL$SYSTEM_FLAGS is defined so that
bit 1 is set, users will be notified no matter which node they are logged
in to. If you wish to disable this, you should define BULL_SYSTEM_FLAGS
@@ -1739,12 +1741,12 @@ folder. This is a privileged qualifier. It will only affect brand new
users (or those that have never logged in). Use /ALL to modify all users.
3 /FOLDER
/FOLDER=foldername
-
+
Specifies the folder for which the option is to modified. If not
specified, the selected folder is modified. Valid only with NONOTIFY.
3 /PERMANENT
/[NO]PERMANENT
-
+
Specifies that NOTIFY is a permanent flag and cannot be changed by the
individual. /DEFAULT must be specified. This is a privileged qualifier.
`,
@@ -1756,9 +1758,9 @@ useful for terminals that can store more than one screenful at a time,
and that have a remote printer that can then print the contents of the
terminal's memory. The default is PAGE, unless the default was changed
by specifying /NOPAGE on the command line to invoke BULLETIN.
-
+
Format:
-
+
SET [NO]PAGE
`,
},
@@ -1766,17 +1768,17 @@ by specifying /NOPAGE on the command line to invoke BULLETIN.
Description: `Specifies either process privileges or rights identifiers that are
necessary to use privileged commands. Use the SHOW PRIVILEGES command
to see what is presently set. This is a privileged command.
-
+
Format:
-
+
SET PRIVILEGES parameters
-
+
The parameters are one or more privileges separated by commas. To
remove a privilege, specify the privilege preceeded by "NO". If /ID is
specified, the parameters are rights identifiers.
3 /ID
/[NO]ID
-
+
If specified, then the rights identifier which is specified as the
parameter will allow users holding that rights identifier to execute
privileged commands. If /NOID is specified, the identifier is removed.
@@ -1791,9 +1793,9 @@ greater than the expiration limit, and the user does not have
privileges, then the expiration limit will be used as the default
expiration. (If there is no expiration limit, and the user doesn't have
privileges, then an error will result.) PROMPT_EXPIRE is the default.
-
+
Format:
-
+
SET [NO]PROMPT_EXPIRE
`,
},
@@ -1803,14 +1805,14 @@ read new non-system or folder messages (if any exist). A new message is
defined as one that has been added since the last login, or since
accessing BULLETIN. The default setting for READNEW is dependent on how
the folder was created by the owner.
-
+
In order to apply this to a specific folder, first select the folder
(using the SELECT command), and then enter the SET READNEW command.
-
+
Format:
-
+
SET [NO]READNEW
-
+
NOTE: If you have several folders with READNEW enabled, each folder's
messages will be displayed separately. However, if you EXIT the READNEW
mode before all the folders have been displayed, you will not be alerted
@@ -1831,12 +1833,12 @@ folder. This is a privileged qualifier. It will only affect brand new
users (or those that have never logged in). Use /ALL to modify all users.
3 /FOLDER
/FOLDER=foldername
-
+
Specifies the folder for which the option is to modified. If not
specified, the selected folder is modified. Valid only with NOREADNEW.
3 /PERMANENT
/[NO]PERMANENT
-
+
Specifies that READNEW is a permanent flag and cannot be changed by the
individual. This is a privileged qualifier.
`,
@@ -1848,12 +1850,12 @@ except you will not be prompted to read the messages. The default is
dependent on how the folder was created by the owner. A new message is
defined as one that has been added since the last login, or since
accessing BULLETIN.
-
+
In order to apply this to a specific folder, first select the folder
(using the SELECT command), and then enter the SET SHOWNEW command.
-
+
Format:
-
+
SET [NO]SHOWNEW
3 /ALL
Specifies that the SET [NO]SHOWNEW option is the default for all users for
@@ -1866,12 +1868,12 @@ folder. This is a privileged qualifier. It will only affect brand new
users (or those that have never logged in). Use /ALL to modify all users.
3 /FOLDER
/FOLDER=foldername
-
+
Specifies the folder for which the option is to modified. If not
specified, the selected folder is modified. Valid only with NOSHOWNEW.
3 /PERMANENT
/[NO]PERMANENT
-
+
Specifies that SHOWNEW is a permanent flag and cannot be changed by the
individual, except if changing to READNEW. This is a privileged qualifier.
`,
@@ -1880,14 +1882,14 @@ individual, except if changing to READNEW. This is a privileged qualifier.
Description: `Specifies that the selected folder is a SYSTEM folder. A SYSTEM folder
is allowed to have SYSTEM and SHUTDOWN messages added to it. This is a
privileged command.
-
+
Format:
-
+
SET [NO]SYSTEM
-
+
By default, the GENERAL folder is a SYSTEM folder, and the setting for
that folder cannot be removed.
-
+
If the selected folder is remote, /SYSTEM cannot be specified unless the
folder at the other node is also a SYSTEM folder.
`,
@@ -1907,9 +1909,9 @@ currently selected folder.
Description: `Shows information about a folder of messages. Owner and description are
shown. If the folder name is omitted, and a folder has been selected via
the SELECT command, information about that folder is shown.
-
+
Format:
-
+
SHOW FOLDER [folder-name]
3 /FULL
Control whether all information of the folder is displayed. This
@@ -1920,10 +1922,10 @@ have access to that folder.
},
"KEYPAD": {
Description: `Displays the keypad command definitions. If the keypad has been enabled
-by either the SET KEYPAD COMMAND, or /KEYPAD is specified on the command
+by either the SET KEYPAD COMMAND, or /KEYPAD is specified on the command
line, the keypad keys will be defined as commands. SHOW KEYPAD is the
equivalent of HELP KEYPAD.
-
+
NOTE: If the keypad is not enabled, PF2 is defined to be SET KEYPAD.
3 /PRINT
Prints the keypad definitions on the default printer (SYS$PRINT).
@@ -1948,13 +1950,13 @@ the latest message which a user has read in the folder. If NOLOGIN is
set for a user, this information will be displayed. This is a
privileged command. Non-privileged users will only be able to display
the information for their own account.
-
+
Format:
SHOW USER [username]
-
+
The username is optional. If omitted, the process's username is used.
The username should not be included if /ALL or /[NO]LOGIN is specified.
-
+
NOTE: The last logged in time displayed is that which is stored when the
BULLETIN/LOGIN command is executed, not that which VMS stores. Some
sites make BULLETIN/LOGIN an optional command for users to store in
@@ -1965,27 +1967,27 @@ Specifies that information for all users is to be displayed. This is a
privileged command.
3 /LOGIN
/[NO]LOGIN
-
+
Specifies that only those users which do not have NOLOGIN set are to be
displayed. If negated, only those users with NOLOGIN set are displayed.
This is a privileged command. The qualifier /ALL need not be specified.
3 /FOLDER
/FOLDER=[foldername]
-
+
Specifies to display the latest message that was read by the user(s) for
the specified foldername. A newsgroup can be specified, but the info
can only be shown if the user has subscribed to the newsgroup. If the
foldername is not specified, the selected folder will be used.
3 /SINCE
/SINCE=[date]
-
+
Specifies to display only those users whose latest read message date is
the same date or later than the specified date. If no date is
specified, the date of the current message is used. Only valid for
folders or with /LOGIN. Use /START for newsgroups.
3 /START
/START=[number]
-
+
Specifies to display only those users whose latest read message number
is equal to or greather than the specified number. If no number is
specified, the message number of the current message is used. Only
@@ -2006,7 +2008,7 @@ their expiration date set to 15 minutes in the future and are deleted
then. Undeleting the message will reset the expiration date back to its
original value. Deleted messages will be indicated as such by the
string (DELETED) when either reading or doing a directory listing.
-
+
Format:
UNDELETE [message-number]
`,