Commit c86adbc8 c86adbc879c201f691ccaa4b87fa55ce3238e45f by Sergey Poznyakoff

(mh_install_help, mh_real_install,mh_install): New functions.

(mh_open_msg_file): Rewritten.
1 parent e92c860e
Showing 1 changed file with 269 additions and 41 deletions
...@@ -251,10 +251,8 @@ mh_audit_open (char *name, mailbox_t mbox) ...@@ -251,10 +251,8 @@ mh_audit_open (char *name, mailbox_t mbox)
251 if (strchr (namep, '/') == NULL) 251 if (strchr (namep, '/') == NULL)
252 { 252 {
253 char *p = NULL; 253 char *p = NULL;
254 char *home;
255 254
256 asprintf (&p, "%s/Mail/%s", home = mu_get_homedir (), namep); 255 asprintf (&p, "%s/%s", mu_path_folder_dir, namep);
257 free (home);
258 if (!p) 256 if (!p)
259 { 257 {
260 mh_error (_("low memory")); 258 mh_error (_("low memory"));
...@@ -507,16 +505,107 @@ mh_file_copy (const char *from, const char *to) ...@@ -507,16 +505,107 @@ mh_file_copy (const char *from, const char *to)
507 return rc; 505 return rc;
508 } 506 }
509 507
508 static int
509 _mh_delim (char *str)
510 {
511 if (str[0] == '-')
512 {
513 for (; *str == '-'; str++)
514 ;
515 for (; *str == ' ' || *str == '\t'; str++)
516 ;
517 }
518 return str[0] == '\n';
519 }
520
521 char *
522 skipws (char *p, size_t off)
523 {
524 int len;
525 for (p += off; *p && isspace (*p); p++)
526 ;
527 len = strlen (p);
528 if (len > 0 && p[len-1] == '\n')
529 p[len-1] = 0;
530 return p;
531 }
532
533 static int
534 restore_envelope (stream_t str, char **pptr)
535 {
536 size_t offset = 0;
537 char *from = NULL;
538 char *env_from = NULL;
539 char *env_date = NULL;
540 int rc;
541 char buffer[80];
542 size_t len;
543
544 while ((rc = stream_readline (str, buffer, sizeof buffer, offset, &len)) == 0
545 && len > 0)
546 {
547 if (_mh_delim (buffer))
548 break;
549 buffer[len] = 0;
550 offset += len;
551 if (strncasecmp (buffer, MU_HEADER_FROM,
552 sizeof (MU_HEADER_FROM) - 1) == 0)
553 from = strdup (skipws (buffer, sizeof (MU_HEADER_FROM)));
554 else if (strncasecmp (buffer, MU_HEADER_ENV_SENDER,
555 sizeof (MU_HEADER_ENV_SENDER) - 1) == 0)
556 env_from = strdup (skipws (buffer, sizeof (MU_HEADER_ENV_SENDER)));
557 else if (strncasecmp (buffer, MU_HEADER_ENV_DATE,
558 sizeof (MU_HEADER_ENV_DATE) - 1) == 0)
559 env_date = strdup (skipws (buffer, sizeof (MU_HEADER_ENV_DATE)));
560 }
561
562 if (!env_from)
563 {
564 if (from)
565 {
566 address_t addr;
567
568 address_create (&addr, from);
569 if (!addr
570 || address_aget_email (addr, 1, &env_from))
571 env_from = strdup ("GNU-MH");
572 address_destroy (&addr);
573 }
574 else
575 env_from = strdup ("GNU-MH");
576 }
577
578 if (!env_date)
579 {
580 struct tm *tm;
581 time_t t;
582 char date[80];
583
584 time(&t);
585 tm = gmtime(&t);
586 strftime (date, sizeof (date), "%a %b %e %H:%M:%S %Y", tm);
587 env_date = strdup (date);
588 }
589
590 asprintf (pptr, "From %s %s\n", env_from, env_date);
591 free (env_from);
592 free (env_date);
593 free (from);
594 return 0;
595 }
596
510 mailbox_t 597 mailbox_t
511 mh_open_msg_file (char *file_name) 598 mh_open_msg_file (char *folder, char *file_name)
512 { 599 {
513 struct stat st; 600 struct stat st;
514 char *buffer; 601 char buffer[512];
515 int fd;
516 size_t len = 0; 602 size_t len = 0;
517 mailbox_t tmp; 603 mailbox_t tmp;
518 stream_t stream; 604 stream_t stream, instream;
519 char *p; 605 int rc, headers;
606
607 if (folder)
608 file_name = mh_expand_name (folder, file_name, 0);
520 609
521 if (stat (file_name, &st) < 0) 610 if (stat (file_name, &st) < 0)
522 { 611 {
...@@ -524,56 +613,77 @@ mh_open_msg_file (char *file_name) ...@@ -524,56 +613,77 @@ mh_open_msg_file (char *file_name)
524 return NULL; 613 return NULL;
525 } 614 }
526 615
527 buffer = xmalloc (st.st_size+1); 616 if ((rc = file_stream_create (&instream, file_name, MU_STREAM_READ)))
528 fd = open (file_name, O_RDONLY);
529 if (fd == -1)
530 { 617 {
531 mh_error (_("can't open file %s: %s"), file_name, strerror (errno)); 618 mh_error (_("can't create input stream (file %s): %s"),
619 file_name, mu_strerror (rc));
532 return NULL; 620 return NULL;
533 } 621 }
534 622
535 if (read (fd, buffer, st.st_size) != st.st_size) 623 if ((rc = stream_open (instream)))
624 {
625 mh_error (_("can't open input stream (file %s): %s"),
626 file_name, mu_strerror (rc));
627 stream_destroy (&instream, stream_get_owner (instream));
628 return NULL;
629 }
630
631 if (memory_stream_create (&stream, 0, MU_STREAM_RDWR)
632 || stream_open (stream))
536 { 633 {
537 mh_error (_("error reading file %s: %s"), file_name, strerror (errno)); 634 mh_error (_("can't create temporary stream"));
635 stream_destroy (&instream, stream_get_owner (instream));
538 return NULL; 636 return NULL;
539 } 637 }
540 638
541 buffer[st.st_size] = 0; 639 stream_readline (instream, buffer, sizeof buffer, 0, NULL);
542 close (fd); 640 if (strncmp (buffer, "From ", 5))
641 {
642 char *envstr;
643 restore_envelope (instream, &envstr);
644 stream_sequential_write (stream, envstr, strlen (envstr));
645 free (envstr);
646 }
543 647
544 if (mailbox_create (&tmp, "/dev/null") 648 headers = 1;
545 || mailbox_open (tmp, MU_STREAM_READ) != 0) 649 while ((rc = stream_sequential_readline (instream,
650 buffer, sizeof buffer, &len)) == 0
651 && len > 0)
546 { 652 {
547 mh_error (_("can't create temporary mailbox")); 653 buffer[len] = 0;
548 return NULL; 654 if (headers && _mh_delim (buffer))
655 {
656 headers = 0;
657 buffer[0] = '\n';
658 buffer[1] = 0;
659 len = 1;
660 }
661 rc = stream_sequential_write (stream, buffer, len);
662 if (rc)
663 {
664 mh_error (_("write error: %s"), mu_strerror (rc));
665 stream_destroy (&instream, stream_get_owner (instream));
666 stream_destroy (&stream, stream_get_owner (stream));
667 return NULL;
668 }
549 } 669 }
550 670
551 if (memory_stream_create (&stream, 0, MU_STREAM_RDWR) 671 stream_destroy (&instream, stream_get_owner (instream));
552 || stream_open (stream)) 672 if (rc)
553 { 673 {
554 mailbox_close (tmp); 674 mh_error (_("error reading file %s: %s"), file_name, mu_strerror (rc));
555 mh_error (_("can't create temporary stream")); 675 stream_destroy (&stream, stream_get_owner (stream));
556 return NULL; 676 return NULL;
557 } 677 }
558 678
559 for (p = buffer; *p && isspace (*p); p++) 679 if (mailbox_create (&tmp, "/dev/null")
560 ; 680 || mailbox_open (tmp, MU_STREAM_READ) != 0)
561
562 if (strncmp (p, "From ", 5))
563 { 681 {
564 struct tm *tm; 682 mh_error (_("can't create temporary mailbox"));
565 time_t t; 683 return NULL;
566 char date[80]; 684 }
567 685
568 time(&t);
569 tm = gmtime(&t);
570 strftime (date, sizeof (date),
571 "From GNU-MH-refile %a %b %e %H:%M:%S %Y%n",
572 tm);
573 stream_write (stream, date, strlen (date), 0, &len);
574 }
575 686
576 stream_write (stream, p, strlen (p), len, &len);
577 mailbox_set_stream (tmp, stream); 687 mailbox_set_stream (tmp, stream);
578 if (mailbox_messages_count (tmp, &len) 688 if (mailbox_messages_count (tmp, &len)
579 || len < 1) 689 || len < 1)
...@@ -589,6 +699,124 @@ mh_open_msg_file (char *file_name) ...@@ -589,6 +699,124 @@ mh_open_msg_file (char *file_name)
589 (unsigned long) len); 699 (unsigned long) len);
590 return NULL; 700 return NULL;
591 } 701 }
592 free (buffer);
593 return tmp; 702 return tmp;
594 } 703 }
704
705 void
706 mh_install_help (char *mhdir)
707 {
708 static char *text = N_(
709 "Prior to using MH, it is necessary to have a file in your login\n"
710 "directory (%s) named .mh_profile which contains information\n"
711 "to direct certain MH operations. The only item which is required\n"
712 "is the path to use for all MH folder operations. The suggested MH\n"
713 "path for you is %s...\n");
714
715 printf (_(text), mu_get_homedir (), mhdir);
716 }
717
718 void
719 mh_real_install (char *name, int automode)
720 {
721 char *home = mu_get_homedir ();
722 char *mhdir;
723 char *ctx;
724 FILE *fp;
725
726 asprintf (&mhdir, "%s/%s", home, "Mail");
727
728 if (!automode)
729 {
730 size_t n = 0;
731
732 if (mh_getyn (_("Do you need help")))
733 mh_install_help (mhdir);
734
735 if (!mh_getyn (_("Do you want the standard MH path \"%s\""), mhdir))
736 {
737 int local;
738 char *p;
739
740 local = mh_getyn (_("Do you want a path below your login directory"));
741 if (local)
742 printf (_("What is the path?"));
743 else
744 printf (_("What is the full path?"));
745 if (getline (&p, &n, stdin) <= 0)
746 exit (1);
747
748 n = strlen (p);
749 if (n == 0)
750 exit (1);
751
752 if (p[n-1] == '\n')
753 p[n-1] = 0;
754
755 free (mhdir);
756 if (local)
757 {
758 asprintf (&mhdir, "%s/%s", home, p);
759 free (p);
760 }
761 else
762 mhdir = p;
763 }
764 }
765
766 if (mh_check_folder (mhdir, !automode))
767 exit (1);
768
769 fp = fopen (name, "w");
770 if (!fp)
771 {
772 mu_error (_("cannot open file %s: %s"), name, mu_strerror (errno));
773 exit (1);
774 }
775 fprintf (fp, "Path: %s\n", mhdir);
776 fclose (fp);
777
778 asprintf (&ctx, "%s/%s", mhdir, MH_CONTEXT_FILE);
779 fp = fopen (ctx, "w");
780 if (fp)
781 {
782 fprintf (fp, "Current-Folder: inbox\n");
783 fclose (fp);
784 }
785 free (ctx);
786 free (mhdir);
787 /* FIXME: create inbox? */
788 }
789
790 void
791 mh_install (char *name, int automode)
792 {
793 struct stat st;
794
795 if (stat(name, &st))
796 {
797 if (errno == ENOENT)
798 {
799 if (automode)
800 printf(_("I'm going to create the standard MH path for you.\n"));
801 mh_real_install (name, automode);
802 }
803 else
804 {
805 mh_error(_("cannot stat %s: %s"), name, mu_strerror (errno));
806 exit (1);
807 }
808 }
809 else if ((st.st_mode & S_IFREG) || (st.st_mode & S_IFLNK))
810 {
811 mu_error(_("You already have an MH profile, use an editor to modify it"));
812 exit (0);
813 }
814 else
815 {
816 mu_error(_("You already have file %s which is not a regular file or a symbolic link.\n"
817 "Please remove it and try again"));
818 exit (1);
819 }
820 }
821
822
......