static char *sccsid
= "@(#)misc.c 1.4 (Berkeley) 3/8/86";
* open_valid_art -- determine if a given article name is valid;
* if it is, return a file pointer to the open article,
* along with a unique id of the article.
* Parameters: "artname" is a string containing the
* "id" is space for us to put the article
* Returns: File pointer to the open article if the
* article is valid; NULL otherwise
open_valid_art(artname
, id
)
static char crnt_art_id
[MAX_STRLEN
];
if (crnt_art_num
== atoi(artname
)) {
if (fseek(art_fp
, (long) 0, 0) < 0)
(void) strcpy(id
, crnt_art_id
);
art_fp
= fopen(artname
, "r");
if (fstat(fd
, (struct stat
*) &statbuf
) < 0) {
if ((statbuf
.st_mode
& S_IFREG
) != S_IFREG
) {
(void) strcpy(crnt_art_id
, id
);
crnt_art_num
= atoi(artname
);
* openartbyid -- open an article by message-id.
* Parameters: "msg_id" is the message ID of the
* article, enclosed in <>'s.
* Returns: A file pointer to the open article,
* or NULL if the article doesn't exist.
* Side effects: Displays article, opens dbm database
* (only once, keeps it open after that).
* Converts "msg_id" to lower case.
char line
[MAX_STRLEN
], path
[MAX_STRLEN
];
static DBM
*db
; /* History file, dbm version */
static FILE *hfp
; /* history file, text version */
if (dbminit(HISTORY_FILE
) < 0) {
syslog(LOG_ERR
, "nntpd: openartbyid: dbminit %s: %m\n",
db
= dbm_open(HISTORY_FILE
, O_RDONLY
, 0);
syslog(LOG_ERR
, "nntpd: openartbyid: dbm_open %s: %m\n",
for (cp
= msg_id
; *cp
!= '\0'; ++cp
)
key
.dsize
= strlen(msg_id
) + 1;
content
= dbm_fetch(db
, key
);
if (content
.dptr
== NULL
)
hfp
= fopen(HISTORY_FILE
, "r");
syslog(LOG_ERR
, "nntpd: message: fopen %s: %m\n",
if (fseek(hfp
, (long) *(int *)content
.dptr
, 0) < 0) {
syslog(LOG_ERR
, "nntpd: message: fseek: %m\n");
(void) fgets(line
, sizeof(line
), hfp
);
if ((cp
= index(line
, '\n')) != NULL
)
"nntpd: message: malformed line in history file (%d bytes)\n",
(int) *(int *)content
.dptr
);
if ((cp
= index(tmp
, ' ')) != NULL
)
while ((cp
= index(tmp
, '.')) != NULL
)
(void) strcpy(path
, homedir
);
(void) strcat(path
, "/");
(void) strcat(path
, tmp
);
art_fp
= fopen(path
, "r");
* spew -- spew out the contents of a file to stdout, doing
* the necessary cr-lf additions at the end. Finish with
* a "." on a line by itself, and an fflush(stdout).
* Parameters: "how" tells what part of the file we
* ARTICLE The entire thing.
* HEAD Just the first part.
* BODY Just the second part.
* "fp" is the open file to spew from.
* Side effects: Changes current position in file.
while (fgets(line
, sizeof(line
)-6, fp
) != NULL
&& *line
!= '\n') {
if (how
== BODY
) /* We need to skip this anyway */
if ((fgets(line
, sizeof(line
)-6, fp
) == NULL
)
|| (index(line
, '\n') != NULL
))
} else if (how
== ARTICLE
) {
while (fgets(line
, sizeof(line
)-6, fp
) != NULL
) {
if ((fgets(line
, sizeof(line
)-6, fp
) == NULL
)
|| (index(line
, '\n') != NULL
))
* get_id -- get the message id of the current article.
* Parameters: "art_fp" is a pointer to the open file.
* "id" is space for the message ID.
* Side effects: Seeks and rewinds on "art_fp".
* Changes space pointed to by "id".
while (fgets(line
, sizeof(line
), art_fp
) != NULL
) {
if ((cp
= index(line
, '\n')) != NULL
)
if ((cp
= index(line
, ' ')) != NULL
) {
if (streql(line
, "Message-ID:")) {
(void) strcpy(id
, cp
+ 1);
(void) strcpy(id
, "<0>");
* close_crnt -- close the current article file pointer, if it's
* Side effects: Closes "art_fp" if it's open; sets "art_fp" to NULL.
* findart -- find an article number in the article array.
* Parameters: "artname" is a string containing
* the name of the article.
* Returns: An index into "art_array",
* or -1 if "artname" isn't in "art_array".
* Improvement: Replace this linear search with a binary one.
for (i
= 0; i
< num_arts
; ++i
)
if (art_array
[i
] == artnum
)
* get_distlist -- return a nicely set up array of distribution groups
* along with a count, when given an NNTP-spec distribution list
* in the form <dist1,dist2,...,distn>.
* Parameters: "array" is storage for our array,
* set to point at some static data.
* "list" is the NNTP distribution list.
* Returns: Number of distributions found.
* Side effects: Changes static data area.
get_distlist(array
, list
)
static char **dist_list
= (char **) NULL
;
cp
= index(list
+ 1, '>');
for (cp
= list
+ 1; *cp
!= '\0'; ++cp
)
distcount
= parsit(list
+ 1, &dist_list
);
* spawn -- create a child process with the input from the client
* Parameters: "path" is the path of the program to invoke.
* "name" is the name to call the program.
* "flag" is a single flag to be passed to the program.
* "cont_code" is the response code to transmit
* "err_code" is the response code to transmit when
* Returns: -1 on non-zero return from child,
* 0 on error before fork/exec,
* Side effects: Creates and removes temporary file;
* accepts input from client; forks and execs.
spawn(path
, name
, flag
, cont_code
, err_code
)
char tempfile
[256], line
[MAX_STRLEN
];
(void) strcpy(tempfile
, "/tmp/rpostXXXXXX");
fp
= fopen(tempfile
, "w");
printf("%d Cannot create temporary file.\r\n", err_code
);
printf("%d Enter news, period on a line by itself to end.\r\n",
while (fgets(line
, sizeof(line
), stdin
) != NULL
) {
if ((cp
= index(line
, '\r')) != NULL
)
else if ((cp
= index(line
, '\n')) != NULL
)
if (strcmp(line
, ".") == 0)
fprintf(fp
, "%s\n", line
+1);
fprintf(fp
, "%s\n", line
);
* Ok, now we have the article in "tempfile". We
* should be able to fork off, close fd's 0 to 31 (or
* whatever), open "tempfile" for input, thus making
* it stdin, and then execl the inews. We think.
if (fork() == 0) { /* We're in child */
(void) setuid(uid_poster
);
(void) setgid(gid_poster
);
for (i
= 0; i
< nds
; ++i
)
fd
= open(tempfile
, O_RDONLY
);
fd
= open("/", O_RDONLY
);
execl(path
, name
, flag
, (char *) NULL
);
while (wait(&status
) > 0)
exit_status
= status
.w_T
.w_Retcode
;
return (exit_status
? -1 : 1);
* streql -- determine if two strings are equal, ignoring case.
* Parameters: "a" and "b" are the pointers
* to characters to be compared.
* Returns: 1 if the strings are equal, 0 otherwise.
while (lower(*a
) == lower(*b
)) {
* lower -- convert a character to lower case, if it's
* Parameters: "c" is the character to be
* Returns: "c" if the character is not
* upper case, otherwise the lower
if (isascii(c
) && isupper(c
))