* some of our "standard" functions in external programs, too.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "lib.h"
+extern short Umask;
+
void mutt_nocurses_error (const char *fmt, ...)
{
va_list ap;
return (p);
}
+char *safe_strcat (char *d, size_t l, const char *s)
+{
+ char *p = d;
+
+ if (!l)
+ return d;
+
+ l--; /* Space for the trailing '\0'. */
+
+ for (; *d && l; l--)
+ d++;
+ for (; *s && l; l--)
+ *d++ = *s++;
+
+ *d = '\0';
+
+ return p;
+}
+
+char *safe_strncat (char *d, size_t l, const char *s, size_t sl)
+{
+ char *p = d;
+
+ if (!l)
+ return d;
+
+ l--; /* Space for the trailing '\0'. */
+
+ for (; *d && l; l--)
+ d++;
+ for (; *s && l && sl; l--, sl--)
+ *d++ = *s++;
+
+ *d = '\0';
+
+ return p;
+}
+
+
void mutt_str_replace (char **p, const char *s)
{
FREE (p);
void mutt_unlink (const char *s)
{
+ int fd;
+ int flags;
FILE *f;
- struct stat sb;
+ struct stat sb, sb2;
char buf[2048];
+
+ /* Defend against symlink attacks */
+
+#ifdef O_NOFOLLOW
+ flags = O_RDWR | O_NOFOLLOW;
+#else
+ flags = O_RDWR;
+#endif
- if (stat (s, &sb) == 0)
+ if (lstat (s, &sb) == 0 && S_ISREG(sb.st_mode))
{
- if ((f = fopen (s, "r+")))
+ if ((fd = open (s, flags)) < 0)
+ return;
+
+ if ((fstat (fd, &sb2) != 0) || !S_ISREG (sb2.st_mode)
+ || (sb.st_dev != sb2.st_dev) || (sb.st_ino != sb2.st_ino))
+ {
+ close (fd);
+ return;
+ }
+
+ if ((f = fdopen (fd, "r+")))
{
unlink (s);
memset (buf, 0, sizeof (buf));
struct stat osb, nsb;
int fd;
- if ((fd = open (path, flags, 0600)) < 0)
+ umask(Umask);
+ if ((fd = open (path, flags, 0666)) < 0)
return fd;
/* make sure the file is not symlink */
*/
FILE *safe_fopen (const char *path, const char *mode)
{
+ /* first set the current umask */
+ umask(Umask);
if (mode[0] == 'w')
{
int fd;