Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
John McEleney
/
mailutils
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit
7a0ce7e4
...
7a0ce7e43631803dea9ae197a13a695fd0c05752
authored
2003-01-15 17:28:06 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Implement "whatnow" shell
1 parent
a966942c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
568 additions
and
0 deletions
mh/mh_whatnow.c
mh/whatnow.c
mh/mh_whatnow.c
0 → 100644
View file @
7a0ce7e
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2003 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <mh.h>
/* Valid commands are:
``display'' to list the message being distributed/replied-to on
the terminal
``edit'' to re-edit using the same editor that was used on the
preceding round unless a profile entry
``edit <editor>'' to invoke <editor> for further editing
``list'' to list the draft on the terminal
``push'' to send the message in the background
``quit'' to terminate the session and preserve the draft
``quit -delete'' to terminate, then delete the draft
``refile +folder'' to refile the draft into the given folder
``send'' to send the message
``send -watch'' to cause the delivery process to be monitored
``whom'' to list the addresses that the message will go to
``whom -check'' to list the addresses and verify that they are
acceptable to the transport service */
typedef
int
(
*
handler_fp
)
__PMT
((
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
));
static
void
display_file
(
const
char
*
name
)
{
char
*
pager
=
mh_global_profile_get
(
"moreproc"
,
getenv
(
"PAGER"
));
if
(
pager
)
mh_spawnp
(
pager
,
name
);
else
{
stream_t
stream
;
int
rc
;
size_t
off
=
0
;
size_t
n
;
char
buffer
[
512
];
rc
=
file_stream_create
(
&
stream
,
name
,
MU_STREAM_READ
);
if
(
rc
)
{
mh_error
(
"file_stream_create: %s"
,
mu_errstring
(
rc
));
return
;
}
rc
=
stream_open
(
stream
);
if
(
rc
)
{
mh_error
(
"stream_open: %s"
,
mu_errstring
(
rc
));
return
;
}
while
(
stream_read
(
stream
,
buffer
,
sizeof
buffer
-
1
,
off
,
&
n
)
==
0
&&
n
!=
0
)
{
buffer
[
n
]
=
'\0'
;
printf
(
"%s"
,
buffer
);
off
+=
n
;
}
stream_destroy
(
&
stream
,
NULL
);
}
}
static
int
display
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
if
(
!
wh
->
msg
)
mh_error
(
_
(
"no alternate message to display"
));
else
display_file
(
wh
->
msg
);
return
0
;
}
static
int
edit
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
if
(
argc
==
1
)
{
char
*
editor
;
char
*
name
;
asprintf
(
&
name
,
"%s-next"
,
wh
->
editor
);
editor
=
mh_global_profile_get
(
name
,
wh
->
editor
);
free
(
name
);
mh_spawnp
(
editor
,
wh
->
file
);
}
else
{
int
i
,
rc
,
status
;
char
**
xargv
;
xargv
=
calloc
(
argc
+
1
,
sizeof
(
*
xargv
));
if
(
!
xargv
)
{
mh_error
(
_
(
"not enough memory"
));
return
0
;
}
for
(
i
=
1
;
i
<
argc
;
i
++
)
xargv
[
i
-
1
]
=
argv
[
i
];
xargv
[
i
++-
1
]
=
wh
->
file
;
xargv
[
i
++-
1
]
=
NULL
;
rc
=
mu_spawnvp
(
xargv
[
0
],
(
const
char
**
)
xargv
,
&
status
);
free
(
xargv
);
}
return
0
;
}
static
int
list
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
if
(
!
wh
->
file
)
mh_error
(
_
(
"no draft file to display"
));
else
display_file
(
wh
->
file
);
return
0
;
}
static
int
push
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
return
0
;
}
static
int
quit
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
*
status
=
0
;
return
1
;
}
static
int
refile
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
return
0
;
}
static
int
send
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
return
0
;
}
static
void
print_readable
(
char
*
email
)
{
for
(;
*
email
&&
*
email
!=
'@'
;
email
++
)
putchar
(
*
email
);
if
(
!*
email
)
return
;
printf
(
_
(
" at %s
\n
"
),
email
+
1
);
}
static
int
whom
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
if
(
!
wh
->
file
)
mh_error
(
_
(
"no draft file to display"
));
else
{
mh_context_t
*
ctx
;
ctx
=
mh_context_create
(
wh
->
file
,
1
);
if
(
mh_context_read
(
ctx
))
{
mh_error
(
_
(
"malformed message"
));
}
else
{
char
*
to
=
mh_context_get_value
(
ctx
,
MU_HEADER_TO
,
NULL
);
char
*
cc
=
mh_context_get_value
(
ctx
,
MU_HEADER_CC
,
NULL
);
char
*
bcc
=
mh_context_get_value
(
ctx
,
MU_HEADER_BCC
,
NULL
);
char
*
s
=
to
?
to
:
(
cc
?
cc
:
bcc
);
if
(
!
s
)
{
mh_error
(
_
(
"No recipients"
));
}
else
{
address_t
addr
;
size_t
i
,
count
;
address_create
(
&
addr
,
s
);
if
(
cc
)
{
address_t
a
;
address_create
(
&
a
,
cc
);
address_concatenate
(
addr
,
&
a
);
}
if
(
bcc
)
{
address_t
a
;
address_create
(
&
a
,
bcc
);
address_concatenate
(
addr
,
&
a
);
}
printf
(
" %s
\n
"
,
_
(
"-- Network Recipients --"
));
address_get_count
(
addr
,
&
count
);
for
(
i
=
1
;
i
<=
count
;
i
++
)
{
char
*
buf
;
int
rc
;
rc
=
address_aget_email
(
addr
,
i
,
&
buf
);
if
(
rc
)
{
mh_error
(
"address_aget_email: %s"
,
mu_errstring
(
rc
));
continue
;
}
printf
(
" "
);
print_readable
(
buf
);
free
(
buf
);
}
}
/* Cleanup everything. Note comment to mh_context_get_value! */
free
(
bcc
);
free
(
cc
);
free
(
to
);
}
free
(
ctx
);
}
return
0
;
}
struct
helpdata
{
char
*
name
;
char
*
descr
;
}
helpdata
[]
=
{
{
"display [<>]"
,
N_
(
"List the message being distributed/replied-to on the terminal."
)
},
{
"edit [<e <>]"
,
N_
(
"Edit the message. If EDITOR is omitted use the one that was used on"
" the preceeding round unless the profile entry
\"
LASTEDITOR-next
\"
"
" names an alternate editor."
)
},
{
"list [<>]"
,
N_
(
"List the draft on the terminal."
)
},
{
"push [<>]"
,
N_
(
"Send the message in the background."
)
},
{
"quit [-delete]"
,
N_
(
"Terminate the session. Preserve the draft, inless -delete flag is given."
)
},
{
"refile [<>] +"
,
N_
(
"Refile the draft into the given FOLDER."
)
},
{
"send [-watch] [<>]"
,
N_
(
"Send the message. The -watch flag causes the delivery process to be "
"monitored. SWITCHES are passed to send program verbatim."
)
},
{
"whom [-check] [<>]"
,
N_
(
"List the addresses and verify that they are acceptable to the "
"transport service."
)
},
{
NULL
},
};
#define OPT_DOC_COL 29
/* column in which option text starts */
#define RMARGIN 79
/* right margin used for wrapping */
static
int
print_short
(
const
char
*
str
)
{
int
n
;
char
*
s
;
for
(
n
=
0
;
*
str
;
str
++
,
n
++
)
{
switch
(
*
str
)
{
case
'+'
:
putchar
(
'+'
);
s
=
_
(
"FOLDER"
);
n
+=
printf
(
"%s"
,
s
);
break
;
case
'<'
:
switch
(
str
[
1
])
{
case
'>'
:
s
=
_
(
"SWITCHES"
);
n
+=
printf
(
"%s"
,
s
)
-
1
;
str
++
;
break
;
case
'e'
:
s
=
_
(
"EDITOR"
);
n
+=
printf
(
"%s"
,
s
)
-
1
;
str
++
;
break
;
default:
putchar
(
*
str
);
}
break
;
default:
putchar
(
*
str
);
}
}
return
n
;
}
static
void
print_descr
(
int
n
,
char
*
s
)
{
do
{
char
*
p
;
char
*
space
=
NULL
;
for
(;
n
<
OPT_DOC_COL
;
n
++
)
putchar
(
' '
);
for
(
p
=
s
;
*
p
&&
p
<
s
+
(
RMARGIN
-
OPT_DOC_COL
);
p
++
)
if
(
isspace
(
*
p
))
space
=
p
;
if
(
!
space
||
p
<
s
+
(
RMARGIN
-
OPT_DOC_COL
))
{
printf
(
"%s"
,
s
);
s
+=
strlen
(
s
);
}
else
{
for
(;
s
<
space
;
s
++
)
putchar
(
*
s
);
for
(;
*
s
&&
isspace
(
*
s
);
s
++
)
;
}
putchar
(
'\n'
);
n
=
1
;
}
while
(
*
s
);
}
static
int
help
(
struct
mh_whatnow_env
*
wh
,
int
argc
,
char
**
argv
,
int
*
status
)
{
struct
helpdata
*
p
;
printf
(
"%s
\n
"
,
_
(
"Options are:"
));
if
(
argc
==
0
||
argv
[
0
][
0
]
==
'?'
)
{
/* Short version */
for
(
p
=
helpdata
;
p
->
name
;
p
++
)
{
printf
(
" "
);
print_short
(
p
->
name
);
putchar
(
'\n'
);
}
}
else
{
for
(
p
=
helpdata
;
p
->
name
;
p
++
)
{
int
n
;
n
=
printf
(
" "
);
n
+=
print_short
(
p
->
name
);
print_descr
(
n
+
1
,
_
(
p
->
descr
));
}
}
return
0
;
}
static
handler_fp
func
(
const
char
*
name
)
{
static
struct
{
char
*
name
;
handler_fp
fp
;
}
tab
[]
=
{
{
"help"
,
help
},
{
"?"
,
help
},
{
"display"
,
display
},
{
"edit"
,
edit
},
{
"list"
,
list
},
{
"push"
,
push
},
{
"quit"
,
quit
},
{
"refile"
,
refile
},
{
"send"
,
send
},
{
"whom"
,
whom
},
},
*
p
;
int
len
;
if
(
!
name
)
return
help
;
len
=
strlen
(
name
);
for
(
p
=
tab
;
p
->
name
;
p
++
)
{
int
min
=
strlen
(
p
->
name
);
if
(
min
>
len
)
min
=
len
;
if
(
strncmp
(
p
->
name
,
name
,
min
)
==
0
)
return
p
->
fp
;
}
mh_error
(
_
(
"%s is unknown. Hit <CR> for help"
),
name
);
return
NULL
;
}
int
mh_whatnow
(
struct
mh_whatnow_env
*
wh
,
int
initial_edit
)
{
int
rc
,
status
=
0
;
if
(
!
wh
->
editor
)
wh
->
editor
=
mh_global_profile_get
(
"Editor"
,
"prompter"
);
if
(
initial_edit
)
mh_spawnp
(
wh
->
editor
,
wh
->
file
);
if
(
!
wh
->
prompt
)
wh
->
prompt
=
_
(
"What now?"
);
do
{
char
*
line
=
NULL
;
size_t
size
=
0
;
int
argc
;
char
**
argv
;
handler_fp
fun
;
printf
(
"%s "
,
wh
->
prompt
);
getline
(
&
line
,
&
size
,
stdin
);
if
(
!
line
)
continue
;
rc
=
argcv_get
(
line
,
""
,
"#"
,
&
argc
,
&
argv
);
free
(
line
);
if
(
rc
)
{
argcv_free
(
argc
,
argv
);
break
;
}
fun
=
func
(
argv
[
0
]);
if
(
fun
)
rc
=
fun
(
wh
,
argc
,
argv
,
&
status
);
else
rc
=
0
;
argcv_free
(
argc
,
argv
);
}
while
(
rc
==
0
);
return
status
;
}
mh/whatnow.c
0 → 100644
View file @
7a0ce7e
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2003 Free Software Foundation, Inc.
GNU Mailutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Mailutils is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Mailutils; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* MH whatnow command */
#include <mh.h>
const
char
*
argp_program_version
=
"whatnow ("
PACKAGE_STRING
")"
;
static
char
doc
[]
=
"GNU MH whatnow"
;
static
char
args_doc
[]
=
N_
(
"[FILE]"
);
#define ARG_NODRAFTFOLDER 1
#define ARG_NOEDIT 2
/* GNU options */
static
struct
argp_option
options
[]
=
{
{
"draftfolder"
,
'd'
,
N_
(
"FOLDER"
),
0
,
N_
(
"Specify the folder for message drafts"
)},
{
"nodraftfolder"
,
ARG_NODRAFTFOLDER
,
0
,
0
,
N_
(
"Undo the effect of the last --draftfolder option"
)},
{
"draftmessage"
,
'm'
,
N_
(
"MSG"
),
0
,
N_
(
"Invoke the draftmessage facility"
)},
{
"editor"
,
'e'
,
N_
(
"PROG"
),
0
,
N_
(
"Set the editor program to use"
)},
{
"noedit"
,
ARG_NOEDIT
,
0
,
0
,
N_
(
"Suppress the initial edit"
)},
{
"prompt"
,
'p'
,
N_
(
"STRING"
),
0
,
N_
(
"Set the prompt"
)},
{
NULL
}
};
/* Traditional MH options */
struct
mh_option
mh_option
[]
=
{
{
"draftfolder"
,
6
,
'd'
,
MH_OPT_ARG
,
"folder"
},
{
"nodraftfolder"
,
3
,
ARG_NODRAFTFOLDER
,
},
{
"draftmessage"
,
6
,
'm'
},
{
"editor"
,
1
,
'e'
,
MH_OPT_ARG
,
"program"
},
{
"noedit"
,
3
,
ARG_NOEDIT
,
},
{
"prompt"
,
1
,
'p'
},
{
0
}
};
struct
mh_whatnow_env
wh_env
=
{
0
};
static
int
initial_edit
=
1
;
static
int
opt_handler
(
int
key
,
char
*
arg
,
void
*
unused
)
{
switch
(
key
)
{
case
'd'
:
wh_env
.
draftfolder
=
arg
;
break
;
case
'e'
:
wh_env
.
editor
=
arg
;
break
;
case
ARG_NODRAFTFOLDER
:
wh_env
.
draftfolder
=
NULL
;
break
;
case
ARG_NOEDIT
:
initial_edit
=
0
;
break
;
case
'm'
:
wh_env
.
draftmessage
=
arg
;
break
;
case
'p'
:
wh_env
.
prompt
=
arg
;
break
;
default:
return
1
;
}
return
0
;
}
int
main
(
int
argc
,
char
**
argv
)
{
int
index
;
mu_init_nls
();
mh_argp_parse
(
argc
,
argv
,
options
,
mh_option
,
args_doc
,
doc
,
opt_handler
,
NULL
,
&
index
);
wh_env
.
msg
=
getenv
(
"mhaltmsg"
);
return
mh_whatnow
(
&
wh_env
,
initial_edit
);
}
Please
register
or
sign in
to post a comment