Coverity fixes, etc from Nelson
[sxemacs] / lib-src / movemail.c
index 219bced..ba22f92 100644 (file)
@@ -1,7 +1,7 @@
 /* movemail foo bar -- move file foo to file bar,
    locking file foo.
    Copyright (C) 1986, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
-   
+
    Copyright (C) 2005 Johann "Myrkraverk" Oskarsson <johann@myrkraverk.com>
 
 This file is part of SXEmacs.
@@ -45,11 +45,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * form "po:username".  This will cause movemail to open a connection
  * to a pop server running on $MAILHOST (environment variable).
  * Movemail must be setuid to root in order to work with POP.
- * 
+ *
  * New module: popmail.c
  * Modified routines:
  *     main - added code within #ifdef MAIL_USE_POP; added setuid
- *             (getuid ()) after POP code. 
+ *             (getuid ()) after POP code.
  * New routines in movemail.c:
  *     get_errmsg - return pointer to system error message
  *
@@ -80,6 +80,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "../src/regex.h"
 #endif
 
+#include <assert.h>
+
 extern char *optarg;
 extern int optind, opterr;
 
@@ -167,12 +169,12 @@ struct option longopts[] = {
        {"verbose", no_argument, NULL, 'v'},
        {0}
 };
-#endif 
+#endif
 
 #define DOTLOCKING     0
-#define FLOCKING       1
+#define FLOCKING       1
 #define LOCKFING       2
-#define MMDF                   3
+#define MMDF           3
 #define LOCKING         4
 
 #if defined(MAIL_LOCK_FLOCK) && defined(HAVE_FLOCK)
@@ -196,7 +198,10 @@ static char *unparse_lock_method(int);
 
 int main(int argc, char *argv[])
 {
-       char *inname = 0, *outname = 0, *poppass = 0;
+       char *inname = 0, *outname = 0;
+#if defined MAIL_USE_POP
+       char *poppass = 0;
+#endif /* MAIL_USE_POP */
 #ifndef DISABLE_DIRECT_ACCESS
        int indesc, outdesc;
        int nread;
@@ -234,12 +239,15 @@ int main(int argc, char *argv[])
                case 0:
                        break;
                case 1: /* one of the standard arguments seen */
-                       if (!inname)
+                       if (!inname) {
                                inname = optarg;
-                       else if (!outname)
+                       } else if (!outname) {
                                outname = optarg;
-                       else
+#if defined MAIL_USE_POP
+                       } else {
                                poppass = optarg;
+#endif /* MAIL_USE_POP */
+                       }
                        break;
 
                case 'i':       /* infile */
@@ -283,12 +291,15 @@ int main(int argc, char *argv[])
        }
 
        while (optind < argc) {
-               if (!inname)
+               if (!inname) {
                        inname = argv[optind];
-               else if (!outname)
+               } else if (!outname) {
                        outname = argv[optind];
-               else
+#if defined MAIL_USE_POP
+               } else {
                        poppass = argv[optind];
+#endif /* MAIL_USE_POP */
+               }
                optind++;
        }
 
@@ -304,11 +315,6 @@ int main(int argc, char *argv[])
        if (*outname == 0)
                fatal("Destination file name is empty", 0);
 
-       VERBOSE(("checking access to output file\n"));
-       /* Check access to output file.  */
-       if (access(outname, F_OK) == 0 && access(outname, W_OK) != 0)
-               pfatal_with_name(outname);
-
        /* Also check that outname's directory is writable to the real uid.  */
        {
                char *buf = (char *)xmalloc(strlen(outname) + 1);
@@ -334,9 +340,6 @@ int main(int argc, char *argv[])
 
 #ifndef DISABLE_DIRECT_ACCESS
 
-       /* Check access to input file.  */
-       if (access(inname, R_OK | W_OK) != 0)
-               pfatal_with_name(inname);
 
        if (fork() == 0) {
                setuid(getuid());
@@ -416,16 +419,16 @@ int main(int argc, char *argv[])
 
                {
                        char buf[1024];
-
                        while (1) {
                                nread = read(indesc, buf, sizeof buf);
-                               if (nread != write(outdesc, buf, nread)) {
+                               if (nread < 0 ||
+                                   nread != write(outdesc, buf, nread)) {
                                        int saved_errno = errno;
                                        unlink(outname);
                                        errno = saved_errno;
                                        pfatal_with_name(outname);
                                }
-                               if (nread < (int)sizeof buf)
+                               if (nread < (int)sizeof(buf))
                                        break;
                        }
                }
@@ -446,7 +449,8 @@ int main(int argc, char *argv[])
                case FLOCKING:
                case LOCKING:
 #ifdef HAVE_FTRUNCATE
-                       ftruncate(indesc, 0L);
+                       if(ftruncate(indesc, 0L)!=0)
+                               pfatal_and_delete(inname);
 #else
                        close(open(inname, O_CREAT | O_TRUNC | O_RDWR, 0666));
 #endif
@@ -587,16 +591,20 @@ static void lock_dot(char *filename)
                /* Give up if cannot do that.  */
 
 #ifdef HAVE_MKSTEMP
+               /* Remove all group and other permissions.. */
+               umask(S_IRWXG|S_IRWXO);
                desc = mkstemp(tempname);
 #else
                desc = open(tempname, O_WRONLY | O_CREAT | O_EXCL, 0666);
 #endif
 
                if (desc < 0) {
-                       char *message = (char *)xmalloc(strlen(tempname) + 50);
-                       sprintf(message,
-                               "%s--see source file lib-src/movemail.c",
-                               tempname);
+                       int msz = strlen(tempname) + 50;
+                       char *message = (char *)xmalloc(msz);
+                       int sz = snprintf(message, msz,
+                                         "%s--see source file lib-src/movemail.c",
+                                         tempname);
+                       assert(sz>=0 && sz < msz);
                        pfatal_with_name(message);
                }
                close(desc);
@@ -618,6 +626,7 @@ static void lock_dot(char *filename)
                }
        }
        strcpy(dotlock_filename, filename);
+       free(tempname);
 }
 #endif                         /* not DISABLE_DIRECT_ACCESS */
 
@@ -671,10 +680,10 @@ static char *concat(char *s1, char *s2, char *s3)
        int len1 = strlen(s1), len2 = strlen(s2), len3 = strlen(s3);
        char *result = (char *)xmalloc(len1 + len2 + len3 + 1);
 
-       strcpy(result, s1);
-       strcpy(result + len1, s2);
-       strcpy(result + len1 + len2, s3);
-       *(result + len1 + len2 + len3) = 0;
+       strncpy(result, s1, len1+1);
+       strncpy(result + len1, s2, len2+1);
+       strncpy(result + len1 + len2, s3, len3+1);
+       *(result + len1 + len2 + len3) = '\0';
 
        return result;
 }
@@ -699,7 +708,7 @@ static long *xmalloc(unsigned int size)
 #include <stdio.h>
 #include "../src/syspwd.h"
 
-#define POP_ERROR      (-1)
+#define POP_ERROR      (-1)
 #define POP_RETRIEVED (0)
 #define POP_DONE (1)