version 1.9, 2000/04/26 15:47:30 |
version 1.10, 2001/11/21 15:26:39 |
|
|
|
|
#ifndef lint |
#ifndef lint |
#if 0 |
#if 0 |
static char sccsid[] = "@(#)cmd2.c 8.1 (Berkeley) 6/6/93"; |
static const char sccsid[] = "@(#)cmd2.c 8.1 (Berkeley) 6/6/93"; |
#else |
#else |
static char rcsid[] = "$OpenBSD$"; |
static const char rcsid[] = "$OpenBSD$"; |
#endif |
#endif |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
|
|
* |
* |
* More user commands. |
* More user commands. |
*/ |
*/ |
static int igcomp __P((const void *, const void *)); |
static int igcomp(const void *, const void *); |
|
|
/* |
/* |
* If any arguments were given, go to the next applicable argument |
* If any arguments were given, go to the next applicable argument |
|
|
* If given as first command with no arguments, print first message. |
* If given as first command with no arguments, print first message. |
*/ |
*/ |
int |
int |
next(v) |
next(void *v) |
void *v; |
|
{ |
{ |
struct message *mp; |
struct message *mp; |
int *msgvec = v; |
int *msgvec = v; |
int *ip, *ip2, list[2], mdot; |
int *ip, *ip2, list[2], mdot; |
|
|
if (*msgvec != NULL) { |
if (*msgvec != NULL) { |
|
|
/* |
/* |
* If some messages were supplied, find the |
* If some messages were supplied, find the |
* first applicable one following dot using |
* first applicable one following dot using |
* wrap around. |
* wrap around. |
*/ |
*/ |
|
|
mdot = dot - &message[0] + 1; |
mdot = dot - &message[0] + 1; |
|
|
/* |
/* |
* Find the first message in the supplied |
* Find the first message in the supplied |
* message list which follows dot. |
* message list which follows dot. |
*/ |
*/ |
|
|
for (ip = msgvec; *ip != NULL; ip++) |
for (ip = msgvec; *ip != NULL; ip++) |
if (*ip > mdot) |
if (*ip > mdot) |
break; |
break; |
|
|
* If this is the first command, select message 1. |
* If this is the first command, select message 1. |
* Note that this must exist for us to get here at all. |
* Note that this must exist for us to get here at all. |
*/ |
*/ |
|
|
if (!sawcom) |
if (!sawcom) |
goto hitit; |
goto hitit; |
|
|
|
|
* Just find the next good message after dot, no |
* Just find the next good message after dot, no |
* wraparound. |
* wraparound. |
*/ |
*/ |
|
|
for (mp = dot+1; mp < &message[msgCount]; mp++) |
for (mp = dot+1; mp < &message[msgCount]; mp++) |
if ((mp->m_flag & (MDELETED|MSAVED)) == 0) |
if ((mp->m_flag & (MDELETED|MSAVED)) == 0) |
break; |
break; |
|
|
/* |
/* |
* Print dot. |
* Print dot. |
*/ |
*/ |
|
|
list[0] = dot - &message[0] + 1; |
list[0] = dot - &message[0] + 1; |
list[1] = NULL; |
list[1] = NULL; |
return(type(list)); |
return(type(list)); |
|
|
* so we can discard when the user quits. |
* so we can discard when the user quits. |
*/ |
*/ |
int |
int |
save(v) |
save(void *v) |
void *v; |
|
{ |
{ |
char *str = v; |
char *str = v; |
|
|
|
|
* Copy a message to a file without affected its saved-ness |
* Copy a message to a file without affected its saved-ness |
*/ |
*/ |
int |
int |
copycmd(v) |
copycmd(void *v) |
void *v; |
|
{ |
{ |
char *str = v; |
char *str = v; |
|
|
|
|
* If mark is true, mark the message "saved." |
* If mark is true, mark the message "saved." |
*/ |
*/ |
int |
int |
save1(str, mark, cmd, ignore) |
save1(char *str, int mark, char *cmd, struct ignoretab *ignore) |
char str[]; |
|
int mark; |
|
char *cmd; |
|
struct ignoretab *ignore; |
|
{ |
{ |
struct message *mp; |
struct message *mp; |
char *file, *disp; |
char *file, *disp; |
|
|
* file name, minus header and trailing blank line. |
* file name, minus header and trailing blank line. |
*/ |
*/ |
int |
int |
swrite(v) |
swrite(void *v) |
void *v; |
|
{ |
{ |
char *str = v; |
char *str = v; |
|
|
|
|
* unless the file name is the only thing on the line, in |
* unless the file name is the only thing on the line, in |
* which case, return 0 in the reference flag variable. |
* which case, return 0 in the reference flag variable. |
*/ |
*/ |
|
|
char * |
char * |
snarf(linebuf, flag) |
snarf(char *linebuf, int *flag) |
char linebuf[]; |
|
int *flag; |
|
{ |
{ |
char *cp; |
char *cp; |
|
|
|
|
/* |
/* |
* Strip away trailing blanks. |
* Strip away trailing blanks. |
*/ |
*/ |
|
|
while (cp > linebuf && isspace(*cp)) |
while (cp > linebuf && isspace(*cp)) |
cp--; |
cp--; |
*++cp = 0; |
*++cp = 0; |
|
|
/* |
/* |
* Now search for the beginning of the file name. |
* Now search for the beginning of the file name. |
*/ |
*/ |
|
|
while (cp > linebuf && !isspace(*cp)) |
while (cp > linebuf && !isspace(*cp)) |
cp--; |
cp--; |
if (*cp == '\0') { |
if (*cp == '\0') { |
|
|
* Delete messages. |
* Delete messages. |
*/ |
*/ |
int |
int |
delete(v) |
delete(void *v) |
void *v; |
|
{ |
{ |
int *msgvec = v; |
int *msgvec = v; |
|
|
delm(msgvec); |
delm(msgvec); |
return(0); |
return(0); |
} |
} |
|
|
* Delete messages, then type the new dot. |
* Delete messages, then type the new dot. |
*/ |
*/ |
int |
int |
deltype(v) |
deltype(void *v) |
void *v; |
|
{ |
{ |
int *msgvec = v; |
int *msgvec = v; |
int list[2]; |
int list[2]; |
|
|
* Internal interface. |
* Internal interface. |
*/ |
*/ |
int |
int |
delm(msgvec) |
delm(int *msgvec) |
int *msgvec; |
|
{ |
{ |
struct message *mp; |
struct message *mp; |
int *ip, last; |
int *ip, last; |
|
|
/* |
/* |
* Following can't happen -- it keeps lint happy |
* Following can't happen -- it keeps lint happy |
*/ |
*/ |
|
|
return(-1); |
return(-1); |
} |
} |
|
|
|
|
* Undelete the indicated messages. |
* Undelete the indicated messages. |
*/ |
*/ |
int |
int |
undeletecmd(v) |
undeletecmd(void *v) |
void *v; |
|
{ |
{ |
int *msgvec = v; |
int *msgvec = v; |
int *ip; |
int *ip; |
|
|
* Interactively dump core on "core" |
* Interactively dump core on "core" |
*/ |
*/ |
int |
int |
core(v) |
core(void *v) |
void *v; |
|
{ |
{ |
int pid; |
pid_t pid; |
extern int wait_status; |
extern int wait_status; |
|
|
switch (pid = vfork()) { |
switch (pid = vfork()) { |
|
|
* Clobber as many bytes of stack as the user requests. |
* Clobber as many bytes of stack as the user requests. |
*/ |
*/ |
int |
int |
clobber(v) |
clobber(void *v) |
void *v; |
|
{ |
{ |
char **argv = v; |
char **argv = v; |
int times; |
int times; |
|
|
* If no arguments, print the current list of retained fields. |
* If no arguments, print the current list of retained fields. |
*/ |
*/ |
int |
int |
retfield(v) |
retfield(void *v) |
void *v; |
|
{ |
{ |
char **list = v; |
char **list = v; |
|
|
|
|
* If no arguments, print the current list of ignored fields. |
* If no arguments, print the current list of ignored fields. |
*/ |
*/ |
int |
int |
igfield(v) |
igfield(void *v) |
void *v; |
|
{ |
{ |
char **list = v; |
char **list = v; |
|
|
|
|
} |
} |
|
|
int |
int |
saveretfield(v) |
saveretfield(void *v) |
void *v; |
|
{ |
{ |
char **list = v; |
char **list = v; |
|
|
|
|
} |
} |
|
|
int |
int |
saveigfield(v) |
saveigfield(void *v) |
void *v; |
|
{ |
{ |
char **list = v; |
char **list = v; |
|
|
|
|
} |
} |
|
|
int |
int |
ignore1(list, tab, which) |
ignore1(char **list, struct ignoretab *tab, char *which) |
char *list[]; |
|
struct ignoretab *tab; |
|
char *which; |
|
{ |
{ |
char field[LINESIZE]; |
char field[LINESIZE]; |
char **ap; |
char **ap; |
|
|
if (*list == NULL) |
if (*list == NULL) |
return(igshow(tab, which)); |
return(igshow(tab, which)); |
for (ap = list; *ap != 0; ap++) { |
for (ap = list; *ap != 0; ap++) { |
istrncpy(field, *ap, sizeof(field)); |
istrlcpy(field, *ap, sizeof(field)); |
if (member(field, tab)) |
if (member(field, tab)) |
continue; |
continue; |
h = hash(field); |
h = hash(field); |
|
|
* Print out all currently retained fields. |
* Print out all currently retained fields. |
*/ |
*/ |
int |
int |
igshow(tab, which) |
igshow(struct ignoretab *tab, char *which) |
struct ignoretab *tab; |
|
char *which; |
|
{ |
{ |
int h; |
int h; |
struct ignore *igp; |
struct ignore *igp; |
|
|
* Compare two names for sorting ignored field list. |
* Compare two names for sorting ignored field list. |
*/ |
*/ |
static int |
static int |
igcomp(l, r) |
igcomp(const void *l, const void *r) |
const void *l, *r; |
|
{ |
{ |
|
|
return(strcmp(*(char **)l, *(char **)r)); |
return(strcmp(*(char **)l, *(char **)r)); |
} |
} |