"Fossies" - the Fresh Open Source Software Archive

Member "s-nail-14.9.11/edit.c" (8 Aug 2018, 7403 Bytes) of package /linux/misc/s-nail-14.9.11.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.10_vs_14.9.11.

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