"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/misc.c" between
tin-2.4.3.tar.xz and tin-2.4.4.tar.xz

About: TIN is a threaded NNTP and spool based UseNet newsreader.

misc.c  (tin-2.4.3.tar.xz):misc.c  (tin-2.4.4.tar.xz)
/* /*
* Project : tin - a Usenet reader * Project : tin - a Usenet reader
* Module : misc.c * Module : misc.c
* Author : I. Lea & R. Skrenta * Author : I. Lea & R. Skrenta
* Created : 1991-04-01 * Created : 1991-04-01
* Updated : 2018-11-23 * Updated : 2019-09-19
* Notes : * Notes :
* *
* Copyright (c) 1991-2019 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pb m.com> * Copyright (c) 1991-2020 Iain Lea <iain@bricbrac.de>, Rich Skrenta <skrenta@pb m.com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * 3. Neither the name of the copyright holder nor the names of its
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * contributors may be used to endorse or promote products derived from
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * this software without specific prior written permission.
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY *
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef TIN_H #ifndef TIN_H
# include "tin.h" # include "tin.h"
#endif /* !TIN_H */ #endif /* !TIN_H */
#ifndef VERSION_H #ifndef VERSION_H
# include "version.h" # include "version.h"
#endif /* !VERSION_H */ #endif /* !VERSION_H */
#ifndef TCURSES_H #ifndef TCURSES_H
# include "tcurses.h" # include "tcurses.h"
skipping to change at line 243 skipping to change at line 246
fclose(fp_out); fclose(fp_out);
fclose(fp_in); fclose(fp_in);
return ret; return ret;
} }
/* /*
* copy the body of articles with given file pointers, * copy the body of articles with given file pointers,
* prefix (= quote_chars), initials of the articles author * prefix (= quote_chars), initials of the articles author
* with_sig is set if the signature should be quoted * with_sig is set if the signature should be quoted
* *
* TODO: rewrite from scratch, the code is awful * TODO: rewrite from scratch, the code is awful.
*/ */
void void
copy_body( copy_body(
FILE *fp_ip, FILE *fp_ip,
FILE *fp_op, FILE *fp_op,
char *prefix, char *prefix,
char *initl, char *initl,
t_bool raw_data) t_bool raw_data)
{ {
char buf[8192]; char buf[8192];
char buf2[8192]; char buf2[8192];
char prefixbuf[256]; char prefixbuf[256];
char *p = prefixbuf;
char *q = prefix;
int i; int i;
int retcode; int retcode;
size_t maxlen = sizeof(prefixbuf) - 1;
size_t ilen = strlen(initl);
t_bool initials = FALSE;
t_bool status_char; t_bool status_char;
t_bool status_space; t_bool status_space;
/* This is a shortcut for speed reasons: if no prefix (= quote_chars) is given just copy */ /* This is a shortcut for speed reasons: if no prefix (= quote_chars) is given just copy */
if (!prefix || !*prefix) { if (!prefix || !*prefix) {
copy_fp(fp_ip, fp_op); copy_fp(fp_ip, fp_op);
return; return;
} }
if (strlen(prefix) > 240) /* truncate and terminate */ while(maxlen > 0 && *q) {
prefix[240] = '\0'; if (*q == '%' && *(q + 1) == 'I') {
if (maxlen < ilen) /* not enough space left for %I expans
ion */
break;
/* convert %S to %s, for compatibility reasons only */ strcpy(p, initl);
if (strstr(prefix, "%S")) { maxlen -= ilen;
status_char = FALSE; p += ilen;
for (i = 0; prefix[i]; i++) { q += 2; /* skip over "%I" */
if ((status_char) && (prefix[i] == 'S')) initials = TRUE;
prefix[i] = 's'; } else {
status_char = (prefix[i] == '%'); *p++ = *q++;
maxlen--;
} }
} }
*p = '\0';
/* /* no QUOTE_COMPRESS with initials */
* strip trailing space if tinrc.quote_style doesn't have its if ((tinrc.quote_style & QUOTE_COMPRESS) && !initials) {
* QUOTE_COMPRESS flag set if (prefixbuf[strlen(prefixbuf) - 1] == ' ')
*/ prefixbuf[strlen(prefixbuf) - 1] = '\0';
if (tinrc.quote_style & QUOTE_COMPRESS) { }
if (strstr(prefix, "%s"))
snprintf(prefixbuf, sizeof(prefixbuf), prefix, initl);
else {
/* strip tailing space from quote-char for quoting quoted
lines */
strcpy(prefixbuf, prefix);
if (prefixbuf[strlen(prefixbuf) - 1] == ' ')
prefixbuf[strlen(prefixbuf) - 1] = '\0';
}
} else
snprintf(prefixbuf, sizeof(prefixbuf), prefix, initl);
/* /*
* if raw_data is true, the signature is exceptionally quoted, even if * if raw_data is true, the signature is exceptionally quoted, even if
* tinrc tells us not to do so. This extraordinary behavior occurs when * tinrc tells us not to do so. This extraordinary behavior occurs when
* replying or following up with the 'raw' message shown. * replying or following up with the 'raw' message shown.
*/ */
while (fgets(buf, (int) sizeof(buf), fp_ip) != NULL) { while (fgets(buf, (int) sizeof(buf), fp_ip) != NULL) {
if (!(tinrc.quote_style & QUOTE_SIGS) && !strcmp(buf, SIGDASHES) && !raw_data) if (!(tinrc.quote_style & QUOTE_SIGS) && !strcmp(buf, SIGDASHES) && !raw_data)
break; break;
if (strstr(prefix, "%s")) { /* initials wanted */
if (initials) { /* initials wanted */
if (buf[0] != '\n') { /* line is not empty */ if (buf[0] != '\n') { /* line is not empty */
if (strchr(buf, '>')) { if (strchr(buf, '>')) {
status_space = FALSE; status_space = FALSE;
status_char = TRUE; status_char = TRUE;
for (i = 0; buf[i] && (buf[i] != '>'); i+ +) { for (i = 0; buf[i] && (buf[i] != '>'); i+ +) {
buf2[i] = buf[i]; buf2[i] = buf[i];
if (buf[i] != ' ') if (buf[i] != ' ')
status_space = TRUE; status_space = TRUE;
if ((status_space) && !(isalpha(( int)(unsigned char) buf[i]) || buf[i] == '>')) if ((status_space) && !(isalpha(( int)(unsigned char) buf[i]) || buf[i] == '>'))
status_char = FALSE; status_char = FALSE;
skipping to change at line 421 skipping to change at line 423
if (group && group->attribute->ispell != NULL) if (group && group->attribute->ispell != NULL)
STRCPY(ispell, group->attribute->ispell); STRCPY(ispell, group->attribute->ispell);
else else
STRCPY(ispell, get_val("ISPELL", PATH_ISPELL)); STRCPY(ispell, get_val("ISPELL", PATH_ISPELL));
/* /*
* Now separating the header and body in two different files so that * Now separating the header and body in two different files so that
* the header is not checked by ispell * the header is not checked by ispell
*/ */
#ifdef HAVE_LONG_FILE_NAMES # ifdef HAVE_LONG_FILE_NAMES
snprintf(nam_body, sizeof(nam_body), "%s%s", nam, ".body"); snprintf(nam_body, sizeof(nam_body), "%s%s", nam, ".body");
snprintf(nam_head, sizeof(nam_head), "%s%s", nam, ".head"); snprintf(nam_head, sizeof(nam_head), "%s%s", nam, ".head");
#else # else
snprintf(nam_body, sizeof(nam_body), "%s%s", nam, ".b"); snprintf(nam_body, sizeof(nam_body), "%s%s", nam, ".b");
snprintf(nam_head, sizeof(nam_head), "%s%s", nam, ".h"); snprintf(nam_head, sizeof(nam_head), "%s%s", nam, ".h");
#endif /* HAVE_LONG_FILE_NAMES */ # endif /* HAVE_LONG_FILE_NAMES */
if ((fp_all = fopen(nam, "r")) == NULL) { if ((fp_all = fopen(nam, "r")) == NULL) {
perror_message(_(txt_cannot_open), nam); perror_message(_(txt_cannot_open), nam);
return FALSE; return FALSE;
} }
if ((fp_head = fopen(nam_head, "w")) == NULL) { if ((fp_head = fopen(nam_head, "w")) == NULL) {
perror_message(_(txt_cannot_open), nam_head); perror_message(_(txt_cannot_open), nam_head);
fclose(fp_all); fclose(fp_all);
return FALSE; return FALSE;
skipping to change at line 598 skipping to change at line 600
/* /*
* Save the newsrc file. If it fails for some reason, give the user a * Save the newsrc file. If it fails for some reason, give the user a
* chance to try again * chance to try again
*/ */
if (!no_write) { if (!no_write) {
i = 3; /* max retries */ i = 3; /* max retries */
while (i--) { while (i--) {
wrote_newsrc_lines = write_newsrc(); wrote_newsrc_lines = write_newsrc();
if ((wrote_newsrc_lines >= 0L) && (wrote_newsrc_lines >= read_newsrc_lines)) { if ((wrote_newsrc_lines >= 0L) && (wrote_newsrc_lines >= read_newsrc_lines)) {
if (!batch_mode || verbose) if (/* !batch_mode || */ verbose)
wait_message(0, _(txt_newsrc_saved)); wait_message(0, _(txt_newsrc_saved));
break; break;
} }
if (wrote_newsrc_lines < read_newsrc_lines) { if (wrote_newsrc_lines < read_newsrc_lines) {
/* FIXME: prompt for retry? (i.e. remove break) * / /* FIXME: prompt for retry? (i.e. remove break) * /
wait_message(0, _(txt_warn_newsrc), newsrc, wait_message(0, _(txt_warn_newsrc), newsrc,
(read_newsrc_lines - wrote_newsrc_lines), (read_newsrc_lines - wrote_newsrc_lines),
PLURAL(read_newsrc_lines - wrote_newsrc_l ines, txt_group), PLURAL(read_newsrc_lines - wrote_newsrc_l ines, txt_group),
OLDNEWSRC_FILE); OLDNEWSRC_FILE);
skipping to change at line 632 skipping to change at line 634
#ifdef HAVE_MH_MAIL_HANDLING #ifdef HAVE_MH_MAIL_HANDLING
write_mail_active_file(); write_mail_active_file();
#endif /* HAVE_MH_MAIL_HANDLING */ #endif /* HAVE_MH_MAIL_HANDLING */
} }
#ifdef XFACE_ABLE #ifdef XFACE_ABLE
slrnface_stop(); slrnface_stop();
#endif /* XFACE_ABLE */ #endif /* XFACE_ABLE */
/* Do this sometime after we save the newsrc in case this hangs up for an y reason */ /* Do this sometime after we save the newsrc in case this hangs up for an y reason */
if (ret != NNTP_ERROR_EXIT) nntp_close((ret == NNTP_ERROR_EXIT)); /* disconnect fro
nntp_close(); /* disconnect from NNTP server */ m NNTP server */
free_all_arrays(); free_all_arrays();
/* TODO: why do we make this exception here? */ /* TODO: why do we make this exception here? */
#ifdef SIGUSR1 #ifdef SIGUSR1
if (ret != -SIGUSR1) { if (ret != -SIGUSR1) {
#endif /* SIGUSR1 */ #endif /* SIGUSR1 */
#ifdef HAVE_COLOR #ifdef HAVE_COLOR
# ifndef USE_CURSES # ifndef USE_CURSES
reset_screen_attr(); reset_screen_attr();
skipping to change at line 715 skipping to change at line 716
# else # else
return 0; /* chmod via system() like for mkdir? */ return 0; /* chmod via system() like for mkdir? */
# endif /* HAVE_CHMOD */ # endif /* HAVE_CHMOD */
} else } else
return -1; return -1;
#else #else
return mkdir(path, mode); return mkdir(path, mode);
#endif /* !HAVE_MKDIR */ #endif /* !HAVE_MKDIR */
} }
#ifdef M_UNIX
void void
rename_file( rename_file(
const char *old_filename, const char *old_filename,
const char *new_filename) const char *new_filename)
{ {
FILE *fp_old, *fp_new; FILE *fp_old, *fp_new;
int fd; int fd;
mode_t mode = (mode_t) (S_IRUSR|S_IWUSR); mode_t mode = (mode_t) (S_IRUSR|S_IWUSR);
struct stat statbuf; struct stat statbuf;
unlink(new_filename); unlink(new_filename);
# ifdef HAVE_LINK #ifdef HAVE_LINK
if (link(old_filename, new_filename) == -1) if (link(old_filename, new_filename) == -1)
# else #else
if (rename(old_filename, new_filename) < 0) if (rename(old_filename, new_filename) < 0)
# endif /* HAVE_LINK */ #endif /* HAVE_LINK */
{ {
if (errno == EXDEV) { /* create & copy file across filesystem * / if (errno == EXDEV) { /* create & copy file across filesystem * /
if ((fp_old = fopen(old_filename, "r")) == NULL) { if ((fp_old = fopen(old_filename, "r")) == NULL) {
perror_message(_(txt_cannot_open), old_filename); perror_message(_(txt_cannot_open), old_filename);
return; return;
} }
if ((fp_new = fopen(new_filename, "w")) == NULL) { if ((fp_new = fopen(new_filename, "w")) == NULL) {
perror_message(_(txt_cannot_open), new_filename); perror_message(_(txt_cannot_open), new_filename);
fclose(fp_old); fclose(fp_old);
return; return;
skipping to change at line 763 skipping to change at line 763
fchmod(fd, mode); fchmod(fd, mode);
fclose(fp_new); fclose(fp_new);
fclose(fp_old); fclose(fp_old);
errno = 0; errno = 0;
} else { } else {
perror_message(_(txt_rename_error), old_filename, new_fil ename); perror_message(_(txt_rename_error), old_filename, new_fil ename);
return; return;
} }
} }
# ifdef HAVE_LINK #ifdef HAVE_LINK
if (unlink(old_filename) == -1) { if (unlink(old_filename) == -1) {
perror_message(_(txt_rename_error), old_filename, new_filename); perror_message(_(txt_rename_error), old_filename, new_filename);
return; return;
} }
# endif /* HAVE_LINK */ #endif /* HAVE_LINK */
} }
#endif /* M_UNIX */
/* /*
* Note that we exit screen/curses mode when invoking * Note that we exit screen/curses mode when invoking
* external commands * external commands
*/ */
t_bool t_bool
invoke_cmd( invoke_cmd(
const char *nam) const char *nam)
{ {
int ret; int ret;
t_bool save_cmd_line = cmd_line; t_bool save_cmd_line = cmd_line;
#ifndef IGNORE_SYSTEM_STATUS #ifndef IGNORE_SYSTEM_STATUS
t_bool success; t_bool success;
#endif /* IGNORE_SYSTEM_STATUS */ #endif /* !IGNORE_SYSTEM_STATUS */
if (!save_cmd_line) { if (!save_cmd_line) {
EndWin(); EndWin();
Raw(FALSE); Raw(FALSE);
} }
set_signal_catcher(FALSE); set_signal_catcher(FALSE);
TRACE(("called system(%s)", _nc_visbuf(nam))); TRACE(("called system(%s)", _nc_visbuf(nam)));
ret = system(nam); ret = system(nam);
#ifndef USE_SYSTEM_STATUS #ifndef USE_SYSTEM_STATUS
skipping to change at line 888 skipping to change at line 887
base_name(d, f); base_name(d, f);
if ((p = strrstr(d, f)) != NULL) if ((p = strrstr(d, f)) != NULL)
*p = '\0'; *p = '\0';
strcpy(dir, d); strcpy(dir, d);
free(f); free(f);
free(d); free(d);
} }
/* /*
* Return TRUE if new mail has arrived * Return TRUE if new mail has arrived
*
* TODO: why not cache the mailbox_name?
*/ */
#define MAILDIR_NEW "new" #define MAILDIR_NEW "new"
t_bool t_bool
mail_check( mail_check(
void) const char *mailbox_name)
{ {
const char *mailbox_name;
struct stat buf; struct stat buf;
mailbox_name = get_val("MAIL", mailbox);
if (mailbox_name != NULL && stat(mailbox_name, &buf) >= 0) { if (mailbox_name != NULL && stat(mailbox_name, &buf) >= 0) {
if ((int) (buf.st_mode & S_IFMT) == (int) S_IFDIR) { /* maildir s etup */ if ((int) (buf.st_mode & S_IFMT) == (int) S_IFDIR) { /* maildir s etup */
char *maildir_box; char *maildir_box;
size_t maildir_box_len = strlen(mailbox_name) + strlen(MA ILDIR_NEW) + 2; size_t maildir_box_len = strlen(mailbox_name) + strlen(MA ILDIR_NEW) + 2;
DIR *dirp; DIR *dirp;
DIR_BUF *dp; DIR_BUF *dp;
maildir_box = my_malloc(maildir_box_len); maildir_box = my_malloc(maildir_box_len);
joinpath(maildir_box, maildir_box_len, mailbox_name, MAIL DIR_NEW); joinpath(maildir_box, maildir_box_len, mailbox_name, MAIL DIR_NEW);
skipping to change at line 1435 skipping to change at line 1429
str[0] = '\0'; str[0] = '\0';
return NULL; return NULL;
} }
} }
return str; return str;
} }
/* /*
* strfpath - produce formatted pathname expansion. Handles following forms: * strfpath - produce formatted pathname expansion. Handles following forms:
* ~/News -> $HOME/News * ~/News -> $HOME/News
* ~abc/News -> /usr/abc/News * ~abc/News -> /home/abc/News
* $var/News -> /env/var/News * $var/News -> /env/var/News
* =file -> $HOME/Mail/file * =file -> $HOME/Mail/file
* = -> $HOME/Mail/group.name * = -> $HOME/Mail/group.name (shorthand for =%G)
* +file -> savedir/group.name/file * +file -> savedir/group.name/file
* * %G -> group.name (group.name is a file )
* Interestingly, %G is not documented as such and apparently unused * %G/file -> group.name/file (group.name is a dir)
* ~/News/%G -> $HOME/News/group.name * %P -> group/name (name is a file)
* %P/file -> group/name/file (name is a dir)
* *
* Inputs: * Inputs:
* format The string to be converted * format The string to be converted
* str Return buffer * str Return buffer
* maxsize Size of str * maxsize Size of str
* group ptr to current group * group ptr to current group
* expand_all true if '+' and '=' should be expanded * expand_all true if '+' and '=' should be expanded
* Returns: * Returns:
* 0 on error * 0 on error
* 1 if generated pathname is a mailbox * 1 if generated pathname is a mailbox
* 2 success * 2 success
*
* TODO: add %X (Article number), %M (Message-ID)?
*/ */
static int static int
_strfpath( _strfpath(
const char *format, const char *format,
char *str, char *str,
size_t maxsize, size_t maxsize,
struct t_group *group, struct t_group *group,
t_bool expand_all) t_bool expand_all)
{ {
char *endp; char *endp;
skipping to change at line 1521 skipping to change at line 1514
sprintf(tbuf, "%s/", pwd- >pw_dir); sprintf(tbuf, "%s/", pwd- >pw_dir);
break; break;
} }
if ((str = strfpath_cp(str, tbuf, endp)) == NULL) if ((str = strfpath_cp(str, tbuf, endp)) == NULL)
return 0; return 0;
break; break;
case '$': /* Read the envvar and use its value */ case '$': /* Read the envvar and use its value */
i = 0; i = 0;
format++; format++;
if (*format && *format == '{') { if (*format == '{') {
format++; format++;
while (*format && !(strchr("}-", *format) )) while (*format && !(strchr("}-", *format) ))
tbuf[i++] = *format++; tbuf[i++] = *format++;
tbuf[i] = '\0'; tbuf[i] = '\0';
i = 0; i = 0;
if (*format && *format == '-') { if (*format == '-') {
format++; format++;
while (*format && *format != '}') while (*format && *format != '}')
defbuf[i++] = *format++; defbuf[i++] = *format++;
} }
defbuf[i] = '\0'; defbuf[i] = '\0';
} else { } else {
while (*format && *format != '/') while (*format && *format != '/')
tbuf[i++] = *format++; tbuf[i++] = *format++;
tbuf[i] = '\0'; tbuf[i] = '\0';
format--; format--;
skipping to change at line 1616 skipping to change at line 1609
} else { } else {
str[0] = '\0'; str[0] = '\0';
return 0; return 0;
} }
} else /* Wasn't the first char in format */ } else /* Wasn't the first char in format */
*str++ = *format; *str++ = *format;
break; break;
case '%': /* Different forms of parsing cmds */ case '%': /* Different forms of parsing cmds */
format++; format++;
if (*format && *format == 'G' && group != NULL) { if (group != NULL && *format == 'G') {
memset(tbuf, 0, sizeof(tbuf)); memset(tbuf, 0, sizeof(tbuf));
STRCPY(tbuf, group->name); STRCPY(tbuf, group->name);
i = strlen(tbuf); i = strlen(tbuf);
if (((str + i) < (endp - 1)) && (i > 0)) { if (((str + i) < (endp - 1)) && (i > 0)) {
strcpy(str, tbuf); strcpy(str, tbuf);
str += i; str += i;
break;
} else { } else {
str[0] = '\0'; str[0] = '\0';
return 0; return 0;
} }
} else break;
*str++ = *format; }
if (group != NULL && *format == 'P') {
char *pbuf = my_malloc(strlen(group->name
) + 2); /* trailing "/\0" */
make_group_path(group->name, pbuf);
if ((i = strlen(pbuf)))
pbuf[i--] = '\0'; /* remove trail
ing '/' */
else {
str[0] = '\0';
free(pbuf);
return 0;
}
if (((str + i) < (endp - 1)) && (i > 0))
{
strcpy(str, pbuf);
free(pbuf);
str += i;
} else {
str[0] = '\0';
free(pbuf);
return 0;
}
break;
}
*str++ = *format;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
break; break;
} }
} }
if (str < endp && *format == '\0') { if (str < endp && *format == '\0') {
*str = '\0'; *str = '\0';
if (is_mailbox) if (is_mailbox)
return 1; return 1;
skipping to change at line 2018 skipping to change at line 2033
/* /*
* Convert a newsgroup name to a newsspool path * Convert a newsgroup name to a newsspool path
* No effect when reading via NNTP * No effect when reading via NNTP
*/ */
void void
make_group_path( make_group_path(
const char *name, const char *name,
char *path) char *path)
{ {
while (*name) { while (*name) {
*path = ((*name == '.') ? '/' : *name); *path++ = ((*name == '.') ? '/' : *name);
name++; name++;
path++;
} }
*path++ = '/'; *path++ = '/';
*path = '\0'; *path = '\0';
} }
/* /*
* Given a base pathname & a newsgroup name build an absolute pathname. * Given a base pathname & a newsgroup name build an absolute pathname.
* base_dir = /usr/spool/news * base_dir = /usr/spool/news
* group_name = alt.sources * group_name = alt.sources
* group_path = /usr/spool/news/alt/sources * group_path = /usr/spool/news/alt/sources
*/ */
void void
make_base_group_path( make_base_group_path(
const char *base_dir, const char *base_dir,
const char *group_name, const char *group_name,
char *group_path, char *group_path,
size_t group_path_len) size_t group_path_len)
{ {
char buf[LEN]; char *buf = my_malloc(strlen(group_name) + 2); /* trailing "/\0" */
make_group_path(group_name, buf); make_group_path(group_name, buf);
joinpath(group_path, group_path_len, base_dir, buf); joinpath(group_path, group_path_len, base_dir, buf);
free(buf);
} }
/* /*
* Delete index lock * Delete index lock
*/ */
void void
cleanup_tmp_files( cleanup_tmp_files(
void) void)
{ {
/* /*
* only required if update_index == TRUE, but update_index is * only required if update_index == TRUE, but update_index is
* unknown here * unknown here
*/ */
if (batch_mode) if (batch_mode)
unlink(lock_file); unlink(lock_file);
} }
#ifndef M_UNIX
void
make_post_process_cmd(
char *cmd,
char *dir,
char *file)
{
char buf[LEN];
char currentdir[PATH_LEN];
get_cwd(currentdir);
chdir(dir);
sh_format(buf, sizeof(buf), cmd, file);
invoke_cmd(buf);
chdir(currentdir);
}
#endif /* !M_UNIX */
/* /*
* returns filesize in bytes * returns filesize in bytes
* -1 in case of an error (file not found, or !S_IFREG) * -1 in case of an error (file not found, or !S_IFREG)
*/ */
long /* we use long here as off_t might be unsigned on some systems */ long /* we use long here as off_t might be unsigned on some systems */
file_size( file_size(
const char *file) const char *file)
{ {
struct stat statbuf; struct stat statbuf;
skipping to change at line 2105 skipping to change at line 2102
long /* we use long (not time_t) here */ long /* we use long (not time_t) here */
file_mtime( file_mtime(
const char *file) const char *file)
{ {
struct stat statbuf; struct stat statbuf;
return (stat(file, &statbuf) == -1 ? -1L : (S_ISREG(statbuf.st_mode)) ? ( long) statbuf.st_mtime : -1L); return (stat(file, &statbuf) == -1 ? -1L : (S_ISREG(statbuf.st_mode)) ? ( long) statbuf.st_mtime : -1L);
} }
/* /*
* TODO: this seems to be unix specific, avoid !M_UNIX calls or * TODO: this feature isn't documented anywhere
* add code for other OS
* this feature also isn't documented anywhere
*/ */
char * char *
random_organization( random_organization(
char *in_org) char *in_org)
{ {
FILE *orgfp; FILE *orgfp;
int nool = 0, sol; int nool = 0, sol;
static char selorg[512]; static char selorg[512];
*selorg = '\0'; *selorg = '\0';
if (*in_org != '/') /* M_UNIXism?! */ if (*in_org != '/')
return in_org; return in_org;
srand((unsigned int) time(NULL)); srand((unsigned int) time(NULL));
if ((orgfp = fopen(in_org, "r")) == NULL) if ((orgfp = fopen(in_org, "r")) == NULL)
return selorg; return selorg;
/* count lines */ /* count lines */
while (fgets(selorg, (int) sizeof(selorg), orgfp)) while (fgets(selorg, (int) sizeof(selorg), orgfp))
nool++; nool++;
skipping to change at line 2366 skipping to change at line 2361
(void) utf8_valid(*line); (void) utf8_valid(*line);
/* /*
* TODO: hardcode unknown_ucs4 (0x00 0x00 0x00 0x3f) * TODO: hardcode unknown_ucs4 (0x00 0x00 0x00 0x3f)
* instead of converting it? * instead of converting it?
*/ */
cd0 = iconv_open("UCS-4", "US-ASCII"); cd0 = iconv_open("UCS-4", "US-ASCII");
cd1 = iconv_open("UCS-4", network_charset); cd1 = iconv_open("UCS-4", network_charset);
cd2 = iconv_open(clocal_charset, "UCS-4"); cd2 = iconv_open(clocal_charset, "UCS-4");
if (cd0 != (iconv_t) (-1) && cd1 != (iconv_t) (-1) && cd2 != (iconv_t) (-1)) { if (cd0 != (iconv_t) (-1) && cd1 != (iconv_t) (-1) && cd2 != (iconv_t) (-1)) {
ICONV_CONST char *inbuf;
char unknown = '?'; char unknown = '?';
ICONV_CONST char *unknown_ascii = &unknown;
char *unknown_buf; char *unknown_buf;
char unknown_ucs4[4]; char unknown_ucs4[4];
char *obuf, *outbuf; char *obuf, *outbuf;
char *tmpbuf, *tbuf; char *tmpbuf, *tbuf;
ICONV_CONST char *inbuf;
ICONV_CONST char *unknown_ascii = &unknown;
ICONV_CONST char *cur_inbuf; ICONV_CONST char *cur_inbuf;
int used; int used;
size_t inbytesleft = 1; size_t inbytesleft = 1;
size_t unknown_bytesleft = 4; size_t unknown_bytesleft = 4;
size_t tmpbytesleft, tsize; size_t tmpbytesleft, tsize;
size_t outbytesleft, osize; size_t outbytesleft, osize;
size_t cur_obl, cur_ibl; size_t cur_obl, cur_ibl;
size_t result; size_t result;
unknown_buf = unknown_ucs4; unknown_buf = unknown_ucs4;
skipping to change at line 3438 skipping to change at line 3433
char *realname) char *realname)
{ {
char *addr_begin; char *addr_begin;
char decoded[HEADER_LEN]; char decoded[HEADER_LEN];
int result, code, addrtype; int result, code, addrtype;
decoded[0] = '\0'; decoded[0] = '\0';
#ifdef DEBUG #ifdef DEBUG
if (debug & DEBUG_MISC) if (debug & DEBUG_MISC)
wait_message(0, "From:=[%s]", from); debug_print_file("GNKSA", "From:=[%s]", from);
#endif /* DEBUG */ #endif /* DEBUG */
/* split from */ /* split from */
code = gnksa_split_from(from, address, realname, &addrtype); code = gnksa_split_from(from, address, realname, &addrtype);
if (*address == '\0') /* address missing or not extractable */ if (*address == '\0') /* address missing or not extractable */
return code; return code;
#ifdef DEBUG #ifdef DEBUG
if (debug & DEBUG_MISC) if (debug & DEBUG_MISC)
wait_message(0, "address=[%s]", address); debug_print_file("GNKSA", "address=[%s]", address);
#endif /* DEBUG */ #endif /* DEBUG */
/* parse address */ /* parse address */
addr_begin = strrchr(address, '@'); addr_begin = strrchr(address, '@');
if (addr_begin != NULL) { if (addr_begin != NULL) {
/* temporarily terminate string at separator position */ /* temporarily terminate string at separator position */
*addr_begin++ = '\0'; *addr_begin++ = '\0';
#ifdef DEBUG #ifdef DEBUG
if (debug & DEBUG_MISC) if (debug & DEBUG_MISC)
wait_message(0, "FQDN=[%s]", addr_begin); debug_print_file("GNKSA", "FQDN=[%s]", addr_begin);
#endif /* DEBUG */ #endif /* DEBUG */
/* convert FQDN part to lowercase */ /* convert FQDN part to lowercase */
str_lwr(addr_begin); str_lwr(addr_begin);
#ifdef DEBUG
if (debug & DEBUG_MISC)
debug_print_file("GNKSA", "str_lwr(FQDN)=[%s]", addr_begi
n);
#endif /* DEBUG */
if ((result = gnksa_check_domain(addr_begin)) != GNKSA_OK if ((result = gnksa_check_domain(addr_begin)) != GNKSA_OK
&& (code == GNKSA_OK)) /* error detected */ && (code == GNKSA_OK)) /* error detected */
code = result; code = result;
if ((result = gnksa_check_localpart(address)) != GNKSA_OK if ((result = gnksa_check_localpart(address)) != GNKSA_OK
&& (code == GNKSA_OK)) /* error detected */ && (code == GNKSA_OK)) /* error detected */
code = result; code = result;
/* restore separator character */ /* restore separator character */
*--addr_begin = '@'; *--addr_begin = '@';
} }
#ifdef DEBUG #ifdef DEBUG
if (debug & DEBUG_MISC) if (debug & DEBUG_MISC)
wait_message(0, "realname=[%s]", realname); debug_print_file("GNKSA", "realname=[%s]", realname);
#endif /* DEBUG */ #endif /* DEBUG */
/* check realname */ /* check realname */
if ((result = gnksa_dequote_plainphrase(realname, decoded, addrtype)) != GNKSA_OK) { if ((result = gnksa_dequote_plainphrase(realname, decoded, addrtype)) != GNKSA_OK) {
if (code == GNKSA_OK) /* error detected */ if (code == GNKSA_OK) /* error detected */
code = result; code = result;
} else /* copy dequoted realname to result variable */ } else /* copy dequoted realname to result variable */
strcpy(realname, decoded); strcpy(realname, decoded);
#ifdef DEBUG #ifdef DEBUG
if (debug & DEBUG_MISC) { /* TODO: dump to a file instead of wait_message () */ if (debug & DEBUG_MISC) { /* TODO: dump to a file instead of wait_message () */
if (code != GNKSA_OK) if (code != GNKSA_OK)
wait_message(2, "From:=[%s], GNKSA=[%d]", from, code); debug_print_file("GNKSA", "From:=[%s], GNKSA=[%d]", from, code);
else else
wait_message(0, "GNKSA=[%d]", code); debug_print_file("GNKSA", "GNKSA=[%d]", code);
} }
#endif /* DEBUG */ #endif /* DEBUG */
return code; return code;
} }
/* /*
* check given address * check given address
*/ */
int int
skipping to change at line 3703 skipping to change at line 3703
/* decoding needed? */ /* decoding needed? */
if (!strstr(in, "xn--")) if (!strstr(in, "xn--"))
return out; return out;
#if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE) #if defined(MULTIBYTE_ABLE) && !defined(NO_LOCALE)
/* IDNA 2008 */ /* IDNA 2008 */
# if defined(HAVE_LIBIDNKIT) && defined(HAVE_IDN_DECODENAME) # if defined(HAVE_LIBIDNKIT) && defined(HAVE_IDN_DECODENAME)
{ {
idn_result_t res; idn_result_t res;
char *q, *r = NULL; char *q, *r;
if ((q = strrchr(out, '@'))) { if ((q = strrchr(out, '@'))) {
q++; q++;
r = strrchr(in, '@'); r = strrchr(in, '@');
r++; r++;
} else { } else {
r = in; r = in;
q = out; q = out;
} }
if ((res = idn_decodename(IDN_DECODE_LOOKUP, r, q, out + strlen(o ut) - q + 1)) == idn_success) if ((res = idn_decodename(IDN_DECODE_LOOKUP, r, q, out + strlen(o ut) - q + 1)) == idn_success)
skipping to change at line 3733 skipping to change at line 3733
} }
# endif /* HAVE_LIBIDNKIT && HAVE_IDN_DECODENAME */ # endif /* HAVE_LIBIDNKIT && HAVE_IDN_DECODENAME */
/* IDNA 2003 */ /* IDNA 2003 */
# ifdef HAVE_LIBICUUC # ifdef HAVE_LIBICUUC
{ {
UChar *src; UChar *src;
UChar dest[1024]; UChar dest[1024];
UErrorCode err = U_ZERO_ERROR; UErrorCode err = U_ZERO_ERROR;
char *s; char *s;
#ifdef HAVE_LIBICUUC_46_API # ifdef HAVE_LIBICUUC_46_API
UIDNA *uts46; UIDNA *uts46;
UIDNAInfo info = UIDNA_INFO_INITIALIZER; UIDNAInfo info = UIDNA_INFO_INITIALIZER;
#endif /* HAVE_LIBICUUC_46_API */ # endif /* HAVE_LIBICUUC_46_API */
if ((s = strrchr(out, '@'))) if ((s = strrchr(out, '@')))
s++; s++;
else else
s = out; s = out;
src = char2UChar(s); src = char2UChar(s);
#ifndef HAVE_LIBICUUC_46_API # ifndef HAVE_LIBICUUC_46_API
uidna_IDNToUnicode(src, -1, dest, 1023, UIDNA_USE_STD3_RULES, NUL L, &err); uidna_IDNToUnicode(src, -1, dest, 1023, UIDNA_USE_STD3_RULES, NUL L, &err);
#else # else
uts46 = uidna_openUTS46(UIDNA_USE_STD3_RULES, &err); uts46 = uidna_openUTS46(UIDNA_USE_STD3_RULES, &err);
uidna_nameToUnicode(uts46, src, u_strlen(src), dest, 1023, &info, &err); uidna_nameToUnicode(uts46, src, u_strlen(src), dest, 1023, &info, &err);
uidna_close(uts46); uidna_close(uts46);
#endif /* !HAVE_LIBICUUC_46_API */ # endif /* !HAVE_LIBICUUC_46_API */
free(src); free(src);
if (!(U_FAILURE(err))) { if (!(U_FAILURE(err))) {
char *t; char *t;
*s = '\0'; /* cut off domainpart */ *s = '\0'; /* cut off domainpart */
if ((s = UChar2char(dest)) != NULL) { /* convert domainpa rt */ if ((s = UChar2char(dest)) != NULL) { /* convert domainpa rt */
t = my_malloc(strlen(out) + strlen(s) + 1); t = my_malloc(strlen(out) + strlen(s) + 1);
sprintf(t, "%s%s", out, s); sprintf(t, "%s%s", out, s);
free(s); free(s);
free(out); free(out);
 End of changes. 63 change blocks. 
118 lines changed or deleted 123 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)