"Fossies" - the Fresh Open Source Software Archive

Member "s-nail-14.9.7/edit.c" (16 Feb 2018, 6805 Bytes) of package /linux/misc/s-nail-14.9.7.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "edit.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 14.9.6_vs_14.9.7.

    1 /*@ S-nail - a mail user agent derived from Berkeley Mail.
    2  *@ Perform message editing functions.
    3  *
    4  * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
    5  * Copyright (c) 2012 - 2018 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
    6  */
    7 /*
    8  * Copyright (c) 1980, 1993
    9  *      The Regents of the University of California.  All rights reserved.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  */
   35 #undef n_FILE
   36 #define n_FILE edit
   37 
   38 #ifndef HAVE_AMALGAMATION
   39 # include "nail.h"
   40 #endif
   41 
   42 /* Edit a message by writing the message into a funnily-named file (which
   43  * should not exist) and forking an editor on it */
   44 static int edit1(int *msgvec, int viored);
   45 
   46 static int
   47 edit1(int *msgvec, int viored)
   48 {
   49    int c, i;
   50    FILE *fp = NULL;
   51    struct message *mp;
   52    off_t size;
   53    bool_t wb, lastnl;
   54    NYD_ENTER;
   55 
   56    wb = ok_blook(writebackedited);
   57 
   58    /* Deal with each message to be edited... */
   59    for (i = 0; msgvec[i] != 0 && i < msgCount; ++i) {
   60       sighandler_type sigint;
   61 
   62       if(i > 0){
   63          char prompt[64];
   64 
   65          snprintf(prompt, sizeof prompt, _("Edit message %d"), msgvec[i]);
   66          if(!getapproval(prompt, FAL0))
   67             continue;
   68       }
   69 
   70       mp = message + msgvec[i] - 1;
   71       setdot(mp);
   72       n_pstate |= n_PS_DID_PRINT_DOT;
   73       touch(mp);
   74 
   75       sigint = safe_signal(SIGINT, SIG_IGN);
   76 
   77       --mp->m_size; /* Strip final NL.. TODO MAILVFS->MESSAGE->length() */
   78       fp = run_editor(fp, -1/*mp->m_size TODO */, viored,
   79             ((mb.mb_perm & MB_EDIT) == 0 || !wb), NULL, mp,
   80             (wb ? SEND_MBOX : SEND_TODISP_ALL), sigint);
   81       ++mp->m_size; /* And readd it TODO */
   82 
   83       if (fp != NULL) {
   84          fseek(mb.mb_otf, 0L, SEEK_END);
   85          size = ftell(mb.mb_otf);
   86          mp->m_block = mailx_blockof(size);
   87          mp->m_offset = mailx_offsetof(size);
   88          mp->m_lines = 0;
   89          mp->m_flag |= MODIFY;
   90          rewind(fp);
   91          lastnl = 0;
   92          size = 0;
   93          while ((c = getc(fp)) != EOF) {
   94             if ((lastnl = (c == '\n')))
   95                ++mp->m_lines;
   96             if (putc(c, mb.mb_otf) == EOF)
   97                break;
   98             ++size;
   99          }
  100          if (!lastnl && putc('\n', mb.mb_otf) != EOF)
  101             ++size;
  102          if (putc('\n', mb.mb_otf) != EOF)
  103             ++size;
  104          mp->m_size = (size_t)size;
  105          if (ferror(mb.mb_otf))
  106             n_perr(_("/tmp"), 0);
  107          Fclose(fp);
  108       }
  109 
  110       safe_signal(SIGINT, sigint);
  111    }
  112    NYD_LEAVE;
  113    return 0;
  114 }
  115 
  116 FL int
  117 c_editor(void *v)
  118 {
  119    int *msgvec = v, rv;
  120    NYD_ENTER;
  121 
  122    rv = edit1(msgvec, 'e');
  123    NYD_LEAVE;
  124    return rv;
  125 }
  126 
  127 FL int
  128 c_visual(void *v)
  129 {
  130    int *msgvec = v, rv;
  131    NYD_ENTER;
  132 
  133    rv = edit1(msgvec, 'v');
  134    NYD_LEAVE;
  135    return rv;
  136 }
  137 
  138 FL FILE *
  139 run_editor(FILE *fp, off_t size, int viored, int readonly, struct header *hp,
  140    struct message *mp, enum sendaction action, sighandler_type oldint)
  141 {
  142    struct stat statb;
  143    sigset_t cset;
  144    FILE *nf = NULL;
  145    int t, ws;
  146    time_t modtime;
  147    off_t modsize;
  148    char *tempEdit;
  149    NYD_ENTER;
  150 
  151    if ((nf = Ftmp(&tempEdit, "runed", OF_WRONLY | OF_REGISTER)) == NULL) {
  152       n_perr(_("temporary mail edit file"), 0);
  153       goto jleave;
  154    }
  155 
  156    if (hp != NULL) {
  157       assert(mp == NULL);
  158       t = GTO | GSUBJECT | GCC | GBCC | GNL | GCOMMA;
  159       if ((hp->h_from != NULL || myaddrs(hp) != NULL) ||
  160             (hp->h_sender != NULL || ok_vlook(sender) != NULL) ||
  161             (hp->h_reply_to != NULL || ok_vlook(reply_to) != NULL) ||
  162                ok_vlook(replyto) != NULL /* v15compat, OBSOLETE */ ||
  163             hp->h_list_post != NULL || (hp->h_flags & HF_LIST_REPLY))
  164          t |= GIDENT;
  165       puthead(TRUM1, hp, nf, t, SEND_TODISP, CONV_NONE, NULL, NULL);
  166    }
  167 
  168    if (mp != NULL) {
  169       if (sendmp(mp, nf, NULL, NULL, action, NULL) < 0) {
  170          n_err(_("Failed to prepare editable message\n"));
  171          goto jleave;
  172       }
  173    } else {
  174       if (size >= 0)
  175          while (--size >= 0 && (t = getc(fp)) != EOF)
  176             putc(t, nf);
  177       else
  178          while ((t = getc(fp)) != EOF)
  179             putc(t, nf);
  180    }
  181 
  182    fflush(nf);
  183    if ((t = ferror(nf)) == 0) {
  184       if (fstat(fileno(nf), &statb) == -1)
  185          modtime = 0, modsize = 0;
  186       else
  187          modtime = statb.st_mtime, modsize = statb.st_size;
  188 
  189       if (readonly)
  190          t = (fchmod(fileno(nf), S_IRUSR) != 0);
  191    }
  192 
  193    if (Fclose(nf) < 0 || t != 0) {
  194       n_perr(tempEdit, 0);
  195       t = 1;
  196    }
  197    nf = NULL;
  198    if (t != 0)
  199       goto jleave;
  200 
  201    sigemptyset(&cset);
  202    if (n_child_run((viored == 'e' ? ok_vlook(EDITOR) : ok_vlook(VISUAL)),
  203             (oldint != SIG_IGN ? &cset : NULL),
  204             n_CHILD_FD_PASS, n_CHILD_FD_PASS, tempEdit, NULL, NULL, NULL, &ws
  205          ) < 0 || WEXITSTATUS(ws) != 0)
  206       goto jleave;
  207 
  208    /* If in read only mode or file unchanged, just remove the editor temporary
  209     * and return.  Otherwise switch to new file */
  210    if (readonly)
  211       goto jleave;
  212    if (stat(tempEdit, &statb) == -1) {
  213       n_perr(tempEdit, 0);
  214       goto jleave;
  215    }
  216 
  217    if ((modtime != statb.st_mtime || modsize != statb.st_size) &&
  218          (nf = Fopen(tempEdit, "r+")) == NULL)
  219       n_perr(tempEdit, 0);
  220 jleave:
  221    if (tempEdit != NULL) { /* TODO i'd rather do more signal handling */
  222       unlink(tempEdit);    /* TODO in here */
  223       Ftmp_free(&tempEdit);
  224    }
  225    NYD_LEAVE;
  226    return nf;
  227 }
  228 
  229 /* s-it-mode */