* Copyright (c) 1980 Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)list.c 5.16 (Berkeley) %G%";
* Convert the user string of message numbers and
* store the numbers into vector.
* Returns the count of messages picked up or -1 on error.
getmsglist(buf
, vector
, flags
)
register struct message
*mp
;
if (markall(buf
, flags
) < 0)
for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
*ip
++ = mp
- &message
[0] + 1;
* Mark all messages that the user wanted from the command
* line in the message structure. Return 0 on success, -1
* Bit values for colon modifiers.
#define CMNEW 01 /* New messages */
#define CMOLD 02 /* Old messages */
#define CMUNREAD 04 /* Unread messages */
#define CMDELETED 010 /* Deleted messages */
#define CMREAD 020 /* Read messages */
* The following table describes the letters which can follow
* the colon and gives the corresponding modifier bit.
char co_char
; /* What to find past : */
int co_bit
; /* Associated modifier bit */
int co_mask
; /* m_status bits to mask */
int co_equal
; /* ... must equal this */
'd', CMDELETED
, MDELETED
, MDELETED
,
'r', CMREAD
, MREAD
, MREAD
,
register struct message
*mp
;
char *namelist
[NMLSIZE
], *bufp
;
int tok
, beg
, mc
, star
, other
, valdot
, colmod
, colresult
;
valdot
= dot
- &message
[0] + 1;
for (i
= 1; i
<= msgCount
; i
++)
printf("No numbers mixed with *\n");
for (i
= beg
; i
<= lexnumber
; i
++)
if (f
== MDELETED
|| (message
[i
- 1].m_flag
& MDELETED
) == 0)
printf("Non-numeric second argument\n");
printf("Referencing beyond EOF\n");
} while ((message
[i
- 1].m_flag
& MDELETED
) != f
);
printf("Referencing before 1\n");
} while ((message
[i
- 1].m_flag
& MDELETED
) != f
);
printf("Non-numeric second argument\n");
if (lexstring
[0] == ':') {
colresult
= evalcol(lexstring
[1]);
printf("Unknown colon modifier \"%s\"\n",
*np
++ = savestr(lexstring
);
lexnumber
= metamess(lexstring
[0], f
);
printf("Can't mix \"*\" with anything\n");
for (i
= 0; i
< msgCount
; i
++)
if ((message
[i
].m_flag
& MDELETED
) == f
) {
printf("No applicable messages.\n");
* If no numbers were given, mark all of the messages,
* so that we can unmark any whose sender was not selected
* if any user names were given.
if ((np
> namelist
|| colmod
!= 0) && mc
== 0)
for (i
= 1; i
<= msgCount
; i
++)
if ((message
[i
-1].m_flag
& MDELETED
) == f
)
* If any names were given, go through and eliminate any
* messages whose senders were not requested.
for (i
= 1; i
<= msgCount
; i
++) {
for (mc
= 0, np
= &namelist
[0]; *np
!= NOSTR
; np
++)
if (matchsender(*np
, i
)) {
* Make sure we got some decent messages.
for (i
= 1; i
<= msgCount
; i
++)
if (message
[i
-1].m_flag
& MMARK
) {
printf("No applicable messages from {%s",
for (np
= &namelist
[1]; *np
!= NOSTR
; np
++)
* If any colon modifiers were given, go through and
* unmark any messages which do not satisfy the modifiers.
for (i
= 1; i
<= msgCount
; i
++) {
register struct coltab
*colp
;
for (colp
= &coltab
[0]; colp
->co_char
; colp
++)
if (colp
->co_bit
& colmod
)
if ((mp
->m_flag
& colp
->co_mask
)
for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
if (mp
>= &message
[msgCount
]) {
register struct coltab
*colp
;
printf("No messages satisfy");
for (colp
= &coltab
[0]; colp
->co_char
; colp
++)
if (colp
->co_bit
& colmod
)
printf(" :%c", colp
->co_char
);
* Turn the character after a colon modifier into a bit
register struct coltab
*colp
;
for (colp
= &coltab
[0]; colp
->co_char
; colp
++)
if (colp
->co_char
== col
)
* Check the passed message number for legality and proper flags.
* If f is MDELETED, then either kind will do. Otherwise, the message
register struct message
*mp
;
if (mesg
< 1 || mesg
> msgCount
) {
printf("%d: Invalid message number\n", mesg
);
if (f
!= MDELETED
&& (mp
->m_flag
& MDELETED
) != 0) {
printf("%d: Inappropriate message\n", mesg
);
* Scan out the list of string arguments, shell style
getrawlist(line
, argv
, argc
)
register char c
, *cp
, *cp2
, quotec
;
for (; *cp
== ' ' || *cp
== '\t'; cp
++)
"Too many elements in the list; excess discarded.\n");
while ((c
= *cp
) != '\0') {
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
if (*cp
>= '0' && *cp
<= '7')
if (*cp
>= '0' && *cp
<= '7')
/* null doesn't show up anyway */
else if (c
>= 'A' && c
<= '_' ||
} else if (c
== '"' || c
== '\'')
else if (c
== ' ' || c
== '\t')
argv
[argn
++] = savestr(linebuf
);
* scan out a single lexical item and return its token number,
* updating the string pointer passed **p. Also, store the value
* of the number or string scanned in lexnumber or lexstring as
* appropriate. In any event, store the scanned `thing' in lexstring.
strcpy(lexstring
, string_stack
[regretp
]);
lexnumber
= numberstack
[regretp
];
return(regretstack
[regretp
--]);
* strip away leading white space.
while (c
== ' ' || c
== '\t')
* If no characters remain, we are at end of line,
* If the leading character is a digit, scan
* the number and convert it on the fly.
* Return TNUMBER when done.
lexnumber
= lexnumber
*10 + c
- '0';
* Check for single character tokens; return such
for (lp
= &singles
[0]; lp
->l_char
!= 0; lp
++)
* We've got a string! Copy all the characters
* of the string into lexstring, until we see
* If the lead character is a " or ', save it
* and scan until you get another.
if (c
== '\'' || c
== '"') {
if (quotec
== 0 && (c
== ' ' || c
== '\t'))
if (cp2
- lexstring
< STRINGLEN
-1)
fprintf(stderr
, "Missing %c\n", quotec
);
* Unscan the named token by pushing it onto the regret stack.
panic("Too many regrets");
regretstack
[regretp
] = token
;
lexstring
[STRINGLEN
-1] = '\0';
string_stack
[regretp
] = savestr(lexstring
);
numberstack
[regretp
] = lexnumber
;
* Reset all the scanner global variables.
* Find the first message whose flags & m == f and return
register struct message
*mp
;
for (mp
= dot
; mp
< &message
[msgCount
]; mp
++)
if ((mp
->m_flag
& m
) == f
)
for (mp
= dot
-1; mp
>= &message
[0]; mp
--)
if ((mp
->m_flag
& m
) == f
)
* See if the passed name sent the passed message number. Return true
register char *cp
, *cp2
, *backup
;
if (!*str
) /* null string matches nothing instead of everything */
backup
= cp2
= nameof(&message
[mesg
- 1], 0);
if (raise(*cp
++) != raise(*cp2
++)) {
* See if the given string matches inside the subject field of the
* given message. For the purpose of the scan, we ignore case differences.
* If it does, return true. The string search argument is assumed to
* have the form "/search-string." If it is of the form "/," we use the
* previous search string.
register struct message
*mp
;
register char *cp
, *cp2
, *backup
;
* Now look, ignoring case, for the word in the string.
if (value("searchheaders") && (cp
= index(str
, ':'))) {
cp2
= hfield("subject", mp
);
if (raise(*cp
++) != raise(*cp2
++)) {
* Mark the named message by setting its mark bit.
if (i
< 1 || i
> msgCount
)
panic("Bad message number to mark");
message
[i
-1].m_flag
|= MMARK
;
* Unmark the named message.
if (i
< 1 || i
> msgCount
)
panic("Bad message number to unmark");
message
[i
-1].m_flag
&= ~MMARK
;
* Return the message number corresponding to the passed meta character.
register struct message
*mp
;
* First 'good' message left.
for (mp
= &message
[0]; mp
< &message
[msgCount
]; mp
++)
if ((mp
->m_flag
& MDELETED
) == f
)
return(mp
- &message
[0] + 1);
printf("No applicable messages\n");
* Last 'good message left.
for (mp
= &message
[msgCount
-1]; mp
>= &message
[0]; mp
--)
if ((mp
->m_flag
& MDELETED
) == f
)
return(mp
- &message
[0] + 1);
printf("No applicable messages\n");
m
= dot
- &message
[0] + 1;
if ((dot
->m_flag
& MDELETED
) != f
) {
printf("%d: Inappropriate message\n", m
);
printf("Unknown metachar (%c)\n", c
);