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
0beef50e
...
0beef50e329d8cfe8c68103e4d7d6dc579f4855f
authored
2001-11-11 18:45:49 +0000
by
Sergey Poznyakoff
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
User-defined actions for comsat.
1 parent
1a6af882
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
357 additions
and
0 deletions
comsat/action.c
comsat/action.c
0 → 100644
View file @
0beef50
/* GNU mailutils - a suite of utilities for electronic mail
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "comsat.h"
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
#include <obstack.h>
/* This module implements user-configurable actions for comsat. The
actions are kept in file .biffrc in the user's home directory and
are executed in sequence. Possible actions:
beep -- Produce audible signal
echo STRING -- Output STRING to the user's tty
exec PROG ARGS... -- Execute given program (not yet implemented)
Following metacharacters are accepted in strings:
$u -- Expands to username
$h -- Expands to hostname
$H{name} -- Expands to value of message header `name'
$B(C,L) -- Expands to message body. C and L give maximum
number of characters and line in the expansion.
When omitted, they default to 400, 5. */
int
act_getline
(
FILE
*
fp
,
char
**
sptr
,
size_t
*
size
)
{
char
buf
[
256
];
int
cont
=
1
;
size_t
used
=
0
;
while
(
cont
&&
fgets
(
buf
,
sizeof
buf
,
fp
))
{
int
len
=
strlen
(
buf
);
if
(
buf
[
len
-
1
]
==
'\n'
)
{
buf
[
--
len
]
=
0
;
if
(
buf
[
len
-
1
]
==
'\\'
)
{
buf
[
--
len
]
=
0
;
cont
=
1
;
}
else
cont
=
0
;
}
else
cont
=
1
;
if
(
len
+
used
+
1
>
*
size
)
{
*
sptr
=
realloc
(
*
sptr
,
len
+
used
+
1
);
if
(
!*
sptr
)
return
-
1
;
*
size
=
len
+
used
+
1
;
}
memcpy
(
*
sptr
+
used
,
buf
,
len
);
used
+=
len
;
}
if
(
*
sptr
)
(
*
sptr
)[
used
]
=
0
;
return
used
;
}
/* Convert second character of a backslash sequence to its ASCII
value: */
int
backslash
(
int
c
)
{
static
char
transtab
[]
=
"a
\a
b
\b
f
\f
n
\n
r
\r
t
\t
"
;
char
*
p
;
for
(
p
=
transtab
;
*
p
;
p
+=
2
)
{
if
(
*
p
==
c
)
return
p
[
1
];
}
return
c
;
}
int
expand_escape
(
char
**
pp
,
message_t
msg
,
struct
obstack
*
stk
)
{
char
*
p
=
*
pp
;
char
*
start
,
*
sval
,
*
namep
;
int
len
;
header_t
hdr
;
body_t
body
;
stream_t
stream
;
int
rc
=
1
;
size_t
size
,
lncount
;
switch
(
*++
p
)
/* skip past $ */
{
case
'u'
:
len
=
strlen
(
username
);
obstack_grow
(
stk
,
username
,
len
);
*
pp
=
p
;
rc
=
0
;
break
;
case
'h'
:
len
=
strlen
(
hostname
);
obstack_grow
(
stk
,
hostname
,
len
);
*
pp
=
p
;
rc
=
0
;
break
;
case
'H'
:
/* Header field */
if
(
*++
p
!=
'{'
)
break
;
start
=
++
p
;
p
=
strchr
(
p
,
'}'
);
if
(
!
p
)
break
;
len
=
p
-
start
;
if
(
len
==
0
||
(
namep
=
malloc
(
len
+
1
))
==
NULL
)
break
;
memcpy
(
namep
,
start
,
len
);
namep
[
len
]
=
0
;
if
(
message_get_header
(
msg
,
&
hdr
)
==
0
&&
header_aget_value
(
hdr
,
namep
,
&
sval
)
==
0
)
{
len
=
strlen
(
sval
);
obstack_grow
(
stk
,
sval
,
len
);
}
free
(
namep
);
*
pp
=
p
;
rc
=
0
;
break
;
case
'B'
:
/* Message body */
if
(
*++
p
==
'('
)
{
size
=
strtoul
(
p
+
1
,
&
p
,
0
);
if
(
*
p
==
','
)
lncount
=
strtoul
(
p
+
1
,
&
p
,
0
);
if
(
*
p
!=
')'
)
break
;
p
++
;
}
if
(
size
==
0
)
size
=
400
;
if
(
lncount
==
0
)
lncount
=
5
;
if
(
message_get_body
(
msg
,
&
body
)
==
0
&&
body_get_stream
(
body
,
&
stream
)
==
0
)
{
size_t
nread
;
char
*
buf
=
malloc
(
size
+
1
);
if
(
!
buf
)
break
;
if
(
stream_read
(
stream
,
buf
,
size
,
0
,
&
nread
)
==
0
)
{
char
*
q
;
buf
[
nread
]
=
0
;
q
=
buf
;
size
=
0
;
while
(
lncount
--
)
{
char
*
s
=
strchr
(
q
,
'\n'
);
if
(
!
q
)
break
;
size
+=
s
-
q
+
1
;
q
=
s
+
1
;
}
obstack_grow
(
stk
,
buf
,
size
);
}
free
(
buf
);
}
*
pp
=
p
;
rc
=
0
;
}
return
rc
;
}
char
*
expand_line
(
char
*
str
,
char
*
cr
,
message_t
msg
)
{
char
*
p
;
int
i
,
c
,
len
;
size_t
size
;
struct
obstack
stk
;
if
(
!*
str
)
return
NULL
;
obstack_init
(
&
stk
);
for
(
p
=
str
;
*
p
;
p
++
)
{
switch
(
*
p
)
{
case
'\n'
:
len
=
strlen
(
cr
);
obstack_grow
(
&
stk
,
cr
,
len
);
break
;
case
'\\'
:
p
++
;
switch
(
*
p
)
{
case
0
:
obstack_1grow
(
&
stk
,
c
);
break
;
case
'n'
:
len
=
strlen
(
cr
);
obstack_grow
(
&
stk
,
cr
,
len
);
break
;
default:
c
=
backslash
(
*
p
);
obstack_1grow
(
&
stk
,
c
);
}
break
;
case
'$'
:
if
(
expand_escape
(
&
p
,
msg
,
&
stk
)
==
0
)
break
;
/*FALLTHRU*/
default:
obstack_1grow
(
&
stk
,
*
p
);
}
}
obstack_1grow
(
&
stk
,
0
);
str
=
strdup
(
obstack_finish
(
&
stk
));
obstack_free
(
&
stk
,
NULL
);
return
str
;
}
char
*
default_action
=
"Mail to
\a
$u@$h
\a
---
\n
"
"From: $H{from}
\n
"
"Subject: $H{Subject}
\n
"
"---
\n
"
"$B(,5)
\n
"
"---
\n
"
;
/* Take care to clear eighth bit, so we won't upset some stupid terminals */
#define LB(c) ((c)&0x7f)
void
action_beep
(
FILE
*
tty
)
{
fprintf
(
tty
,
"
\a\a
"
);
}
void
action_echo
(
FILE
*
tty
,
char
*
str
)
{
char
*
p
;
if
(
!
str
)
return
;
for
(
p
=
str
;
*
p
;
p
++
)
*
p
=
LB
(
*
p
);
fprintf
(
tty
,
"%s"
,
str
);
}
FILE
*
open_rc
(
char
*
filename
,
FILE
*
tty
)
{
struct
stat
stb
;
struct
passwd
*
pw
=
getpwnam
(
username
);
if
(
stat
(
filename
,
&
stb
)
==
0
)
{
if
(
stb
.
st_uid
!=
pw
->
pw_uid
)
{
syslog
(
LOG_NOTICE
,
"%s's %s is not owned by %s"
,
username
,
filename
,
username
);
return
NULL
;
}
if
((
stb
.
st_mode
&
0777
)
!=
0600
)
{
fprintf
(
tty
,
"Warning: your .biffrc has wrong permissions
\r\n
"
);
syslog
(
LOG_NOTICE
,
"%s's %s has wrong permissions"
,
username
,
filename
);
return
NULL
;
}
}
return
fopen
(
filename
,
"r"
);
}
void
run_user_action
(
FILE
*
tty
,
char
*
cr
,
message_t
msg
)
{
FILE
*
fp
;
int
nact
=
0
;
char
*
stmt
=
NULL
;
size_t
size
=
0
;
fp
=
open_rc
(
BIFF_RC
,
tty
);
if
(
fp
)
{
int
line
=
0
;
while
(
act_getline
(
fp
,
&
stmt
,
&
size
))
{
char
*
str
;
int
argc
;
char
**
argv
;
line
++
;
str
=
expand_line
(
stmt
,
cr
,
msg
);
if
(
!
str
)
continue
;
if
(
argcv_get
(
str
,
""
,
&
argc
,
&
argv
)
||
argc
==
0
||
argv
[
0
][
0
]
==
'#'
)
{
free
(
str
);
argcv_free
(
argc
,
argv
);
continue
;
}
if
(
strcmp
(
argv
[
0
],
"beep"
)
==
0
)
{
action_beep
(
tty
);
nact
++
;
}
else
if
(
strcmp
(
argv
[
0
],
"echo"
)
==
0
)
{
action_echo
(
tty
,
argv
[
1
]);
nact
++
;
}
else
{
syslog
(
LOG_ERR
,
"%s:.biffrc:%d: unknown keyword %s"
,
username
,
line
,
argv
[
0
]);
break
;
}
}
fclose
(
fp
);
}
if
(
nact
==
0
)
{
char
*
str
=
expand_line
(
default_action
,
cr
,
msg
);
action_echo
(
tty
,
str
);
}
}
Please
register
or
sign in
to post a comment