diff --git a/NOTES.md b/NOTES.md
index 3841447e3a86e55c17fdaf891918dfeee1df463e..ca0a0bb1812887cfe9f0ac05f7a5776ac9bedea4 100644
--- a/NOTES.md
+++ b/NOTES.md
@@ -21,23 +21,17 @@ Switch between MAIL and BULLETIN modes? MAIL commands are documented
## Things to do
* Run [godoc](http://localhost:6060/) and then review where the help text is lacking.
- * Missing [RESPOND] [MAIL] [SET PROMPT_EXPIRE] [SET NOREADNEW] [SET NOSHOWNEW] [SET NOPROMPT_EXPIRE] [SET READNEW] [SET SHOWNEW] [SHOW NEW]
* Run this.Skew.Safe() before... each command? each write?
- * Handle broadcast messages - create a broadcast table and add an expiration column.
* Database
* trigger to limit values for 'visibility'?
+ * trigger to limit values for 'alert'?
* Add commands:
* Commands for a local mail system?
* Commands to connect to Mattermost or mastodon?
* Make a spreadsheet for signups.
- * Pager:
- * Make "/" work for search.
- * Run [VACUUM](https://www.sqlite.org/lang_vacuum.html) on the expire run.
- * Notifications:
- * Figure out how SHOWNEW, NOTIFY, READNEW and BRIEF work.
* Permissions:
* Review permission requirements for each command.
- * Expire. This was created due to file storage limits.
+ * Expire. This was created due to file storage limits. Keep it?
* Code cleanup:
* Review sql queries and clean out the ones not used.
* Review sql queries and find duplicates.
diff --git a/batch/batch.go b/batch/batch.go
index a28d0bc1571f2ebfc03a09dd9d086e426286c935..e8b65b71372f38e8f5b21dd61c794475df607e31 100644
--- a/batch/batch.go
+++ b/batch/batch.go
@@ -45,6 +45,8 @@ func Expire() int {
rows, err := q.DeleteAllExpiredMessages(ctx)
ask.CheckErr(err)
+ _, err = store.ExecContext(ctx, "VACUUM")
+ ask.CheckErr(err)
fmt.Printf("Expired %d messages\n", rows)
return 0
}
diff --git a/folders/folders.go b/folders/folders.go
index b4b918425e877a0c389e38373e2b2088564ee4d2..436e71c8c5e795efc65b6d285eb5e4a240b10f94 100644
--- a/folders/folders.go
+++ b/folders/folders.go
@@ -19,9 +19,6 @@ func ValidFolder(folder string) (storage.Folder, error) {
return storage.Folder{}, errors.New("Unable to select the folder")
}
if !IsFolderReadable(correct.Name, this.User.Login) {
- // TODO: Should be:
- // WRITE(6,'('' You are not allowed to access folder.'')')
- // WRITE(6,'('' See '',A,'' if you wish to access folder.'')')
return storage.Folder{}, errors.New("Unable to select the folder")
}
return correct, nil
@@ -51,11 +48,9 @@ func CreateFolder(options storage.CreateFolderParams) error {
// ListFolder provides a list of folders that this.User has access to.
func ListFolder() ([]storage.ListFolderRow, error) {
- // TODO: need to check access.
ctx := storage.Context()
rows, err := this.Q.ListFolder(ctx)
if err != nil {
- // TODO: process this error a bit more to give a better error message.
return []storage.ListFolderRow{}, err
}
return rows, nil
diff --git a/pager/pager.go b/pager/pager.go
index ce7d0d4c83d54cd14057a1ad89d83637c8153e29..9ecd1dbe12e1f8ed5c0b6ee573f8ab44398f0e7a 100644
--- a/pager/pager.go
+++ b/pager/pager.go
@@ -79,9 +79,12 @@ func Pager(content string) bool {
return false
}
+ // TODO: get '/' to work for searching.
switch key {
case ' ': // page down
start += pageSize
+ case '\n', '\r': // line down
+ start++
case 'b': // page up
start -= pageSize
case 'q', 'Q': // quit
diff --git a/repl/command.go b/repl/command.go
index f8f59315049a50e6a232065735153b3c75c7f56a..3740e46cf11700afa029f8089064af2d4bc39f45 100644
--- a/repl/command.go
+++ b/repl/command.go
@@ -1134,14 +1134,66 @@ characteristics of the BULLETIN Utility.
The following options are available:
- ALWAYS BRIEF DEFAULT_EXPIRE EXPIRE_LIMIT
- FOLDER NOALWAYS NOBRIEF NONOTIFY
- NOPROMPT_EXPIRE NOREADNEW NOSHOWNEW NOSYSTEM
- NOTIFY PROMPT_EXPIRE READNEW SHOWNEW
- SYSTEM
+ ACCESS ALWAYS BRIEF DEFAULT_EXPIRE
+ EXPIRE_LIMIT FOLDER NOALWAYS NOBRIEF
+ NONOTIFY NOPROMPT_EXPIRE NOREADNEW NOSHOWNEW
+ NOSYSTEM NOTIFY PROMPT_EXPIRE READNEW
+ SHOWNEW SYSTEM
`,
Action: ActionSet,
Commands: dclish.Commands{
+ "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
+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
+command in AUTHORIZE to grant the id to users, and this will give those
+users access to the folder. This is preferred because of problems with
+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
+messages, and thus will not be able to set any login flags. (NOTE: If
+such a user selects such a folder and then uses SET ACCESS to grant him
+or herself access, the user must reselect the folder in order for the
+new access to take affect in order to be able to set login flags.)`,
+ Action: ActionSetAccess,
+ Flags: dclish.Flags{
+ "/ALL": {
+ Description: ` Specifies that access to the folder is granted to all users. If /READ
+ 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]`,
+ },
+ "/READ": {
+ Description: ` Specifies that access to the folder will be limited to being able to
+ read the messages.`,
+ },
+ },
+ },
+
"ALWAYS": {
Description: `Specifies that the selected folder has the ALWAYS attribute. This
causes messages in the folder to be displayed differently when logging
diff --git a/repl/folders.go b/repl/folders.go
index 3cd7d3586e6d53c6685de4b55912c88b94ad53a8..5b0631b375a7ba13c075c1f717e911ad83daade2 100644
--- a/repl/folders.go
+++ b/repl/folders.go
@@ -15,8 +15,27 @@ import (
)
// ActionIndex handles the `INDEX` command. This lists all the folders.
-func ActionIndex(_ *dclish.Command) error {
- // TODO: Handle flags!
+func ActionIndex(cmd *dclish.Command) error {
+
+ if cmd.Flags["/MARKED"].Set {
+ return errors.New("Not implemented yet")
+ }
+ if cmd.Flags["/NEW"].Set {
+ return errors.New("Not implemented yet")
+ }
+ if cmd.Flags["/RESTART"].Set {
+ return errors.New("Not implemented yet")
+ }
+ if cmd.Flags["/SEEN"].Set {
+ return errors.New("Not implemented yet")
+ }
+ if cmd.Flags["/UNMARKED"].Set {
+ return errors.New("Not implemented yet")
+ }
+ if cmd.Flags["/UNSEEN"].Set {
+ return errors.New("Not implemented yet")
+ }
+
rows, err := folders.ListFolder()
if err != nil {
return err
diff --git a/repl/show.go b/repl/show.go
index 4df2ec9d54a7e3985cd696d26834d8494a3eaa67..00de916bb5588c0a7c7dd39949e9187e16f38d6f 100644
--- a/repl/show.go
+++ b/repl/show.go
@@ -15,8 +15,8 @@ import (
)
// ActionShow handles the `SHOW` command.
-func ActionShow(_ *dclish.Command) error {
- this.ShowAlerts(false)
+func ActionShow(cmd *dclish.Command) error {
+ fmt.Println(cmd.Description)
return nil
}
@@ -96,7 +96,7 @@ func ActionShowFolder(cmd *dclish.Command) error {
// ActionShowNew handles the `SHOW NEW` command.
func ActionShowNew(_ *dclish.Command) error {
- fmt.Println("TODO: implement ActionShowNew.")
+ this.ShowAlerts(false)
return nil
}