[BACK]Return to main.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/main.c between version 1.264 and 1.273.2.3

version 1.264, 2016/04/13 12:26:25 version 1.273.2.3, 2017/01/09 02:27:58
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2012, 2014-2016 Ingo Schwarze <schwarze@openbsd.org>   * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>   * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
Line 30 
Line 30 
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <glob.h>  #include <glob.h>
   #if HAVE_SANDBOX_INIT
   #include <sandbox.h>
   #endif
 #include <signal.h>  #include <signal.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdint.h>  #include <stdint.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <time.h>
 #include <unistd.h>  #include <unistd.h>
   
 #include "mandoc_aux.h"  #include "mandoc_aux.h"
Line 47 
Line 51 
 #include "manconf.h"  #include "manconf.h"
 #include "mansearch.h"  #include "mansearch.h"
   
 #if !defined(__GNUC__) || (__GNUC__ < 2)  
 # if !defined(lint)  
 #  define __attribute__(x)  
 # endif  
 #endif /* !defined(__GNUC__) || (__GNUC__ < 2) */  
   
 enum    outmode {  enum    outmode {
         OUTMODE_DEF = 0,          OUTMODE_DEF = 0,
         OUTMODE_FLN,          OUTMODE_FLN,
Line 83  struct curparse {
Line 81  struct curparse {
         struct manoutput *outopts;      /* output options */          struct manoutput *outopts;      /* output options */
 };  };
   
   
   #if HAVE_SQLITE3
   int                       mandocdb(int, char *[]);
   #endif
   
 static  int               fs_lookup(const struct manpaths *,  static  int               fs_lookup(const struct manpaths *,
                                 size_t ipath, const char *,                                  size_t ipath, const char *,
                                 const char *, const char *,                                  const char *, const char *,
Line 91  static void    fs_search(const struct mansearch *,
Line 94  static void    fs_search(const struct mansearch *,
                                 const struct manpaths *, int, char**,                                  const struct manpaths *, int, char**,
                                 struct manpage **, size_t *);                                  struct manpage **, size_t *);
 static  int               koptions(int *, char *);  static  int               koptions(int *, char *);
 #if HAVE_SQLITE3  
 int                       mandocdb(int, char**);  
 #endif  
 static  int               moptions(int *, char *);  static  int               moptions(int *, char *);
 static  void              mmsg(enum mandocerr, enum mandoclevel,  static  void              mmsg(enum mandocerr, enum mandoclevel,
                                 const char *, int, int, const char *);                                  const char *, int, int, const char *);
   static  void              outdata_alloc(struct curparse *);
 static  void              parse(struct curparse *, int, const char *);  static  void              parse(struct curparse *, int, const char *);
 static  void              passthrough(const char *, int, int);  static  void              passthrough(const char *, int, int);
 static  pid_t             spawn_pager(struct tag_files *);  static  pid_t             spawn_pager(struct tag_files *);
Line 158  main(int argc, char *argv[])
Line 159  main(int argc, char *argv[])
                 err((int)MANDOCLEVEL_SYSERR, "pledge");                  err((int)MANDOCLEVEL_SYSERR, "pledge");
 #endif  #endif
   
   #if HAVE_SANDBOX_INIT
           if (sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, NULL) == -1)
                   errx((int)MANDOCLEVEL_SYSERR, "sandbox_init");
   #endif
   
         /* Search options. */          /* Search options. */
   
         memset(&conf, 0, sizeof(conf));          memset(&conf, 0, sizeof(conf));
Line 477  main(int argc, char *argv[])
Line 483  main(int argc, char *argv[])
                                 passthrough(resp->file, fd,                                  passthrough(resp->file, fd,
                                     conf.output.synopsisonly);                                      conf.output.synopsisonly);
   
                         if (argc > 1 && curp.outtype <= OUTT_UTF8)                          if (argc > 1 && curp.outtype <= OUTT_UTF8) {
                                 ascii_sepline(curp.outdata);                                  if (curp.outdata == NULL)
                                           outdata_alloc(&curp);
                                   terminal_sepline(curp.outdata);
                           }
                 } else if (rc < MANDOCLEVEL_ERROR)                  } else if (rc < MANDOCLEVEL_ERROR)
                         rc = MANDOCLEVEL_ERROR;                          rc = MANDOCLEVEL_ERROR;
   
Line 663  fs_lookup(const struct manpaths *paths, size_t ipath,
Line 672  fs_lookup(const struct manpaths *paths, size_t ipath,
   
 found:  found:
 #if HAVE_SQLITE3  #if HAVE_SQLITE3
         warnx("outdated mandoc.db lacks %s(%s) entry, run makewhatis %s",          warnx("outdated mandoc.db lacks %s(%s) entry, run %s %s",
             name, sec, paths->paths[ipath]);              name, sec, BINM_MAKEWHATIS, paths->paths[ipath]);
 #endif  #endif
         *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));          *res = mandoc_reallocarray(*res, ++*ressz, sizeof(struct manpage));
         page = *res + (*ressz - 1);          page = *res + (*ressz - 1);
Line 738  parse(struct curparse *curp, int fd, const char *file)
Line 747  parse(struct curparse *curp, int fd, const char *file)
         if (rctmp != MANDOCLEVEL_OK && curp->wstop)          if (rctmp != MANDOCLEVEL_OK && curp->wstop)
                 return;                  return;
   
         /* If unset, allocate output dev now (if applicable). */          if (curp->outdata == NULL)
                   outdata_alloc(curp);
   
         if (curp->outdata == NULL) {  
                 switch (curp->outtype) {  
                 case OUTT_HTML:  
                         curp->outdata = html_alloc(curp->outopts);  
                         break;  
                 case OUTT_UTF8:  
                         curp->outdata = utf8_alloc(curp->outopts);  
                         break;  
                 case OUTT_LOCALE:  
                         curp->outdata = locale_alloc(curp->outopts);  
                         break;  
                 case OUTT_ASCII:  
                         curp->outdata = ascii_alloc(curp->outopts);  
                         break;  
                 case OUTT_PDF:  
                         curp->outdata = pdf_alloc(curp->outopts);  
                         break;  
                 case OUTT_PS:  
                         curp->outdata = ps_alloc(curp->outopts);  
                         break;  
                 default:  
                         break;  
                 }  
         }  
   
         mparse_result(curp->mp, &man, NULL);          mparse_result(curp->mp, &man, NULL);
   
         /* Execute the out device, if it exists. */          /* Execute the out device, if it exists. */
Line 817  parse(struct curparse *curp, int fd, const char *file)
Line 802  parse(struct curparse *curp, int fd, const char *file)
                         break;                          break;
                 }                  }
         }          }
           mparse_updaterc(curp->mp, &rc);
 }  }
   
 static void  static void
   outdata_alloc(struct curparse *curp)
   {
           switch (curp->outtype) {
           case OUTT_HTML:
                   curp->outdata = html_alloc(curp->outopts);
                   break;
           case OUTT_UTF8:
                   curp->outdata = utf8_alloc(curp->outopts);
                   break;
           case OUTT_LOCALE:
                   curp->outdata = locale_alloc(curp->outopts);
                   break;
           case OUTT_ASCII:
                   curp->outdata = ascii_alloc(curp->outopts);
                   break;
           case OUTT_PDF:
                   curp->outdata = pdf_alloc(curp->outopts);
                   break;
           case OUTT_PS:
                   curp->outdata = ps_alloc(curp->outopts);
                   break;
           default:
                   break;
           }
   }
   
   static void
 passthrough(const char *file, int fd, int synopsis_only)  passthrough(const char *file, int fd, int synopsis_only)
 {  {
         const char       synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";          const char       synb[] = "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS";
Line 829  passthrough(const char *file, int fd, int synopsis_onl
Line 842  passthrough(const char *file, int fd, int synopsis_onl
         const char      *syscall;          const char      *syscall;
         char            *line, *cp;          char            *line, *cp;
         size_t           linesz;          size_t           linesz;
           ssize_t          len, written;
         int              print;          int              print;
   
         line = NULL;          line = NULL;
         linesz = 0;          linesz = 0;
   
           if (fflush(stdout) == EOF) {
                   syscall = "fflush";
                   goto fail;
           }
   
         if ((stream = fdopen(fd, "r")) == NULL) {          if ((stream = fdopen(fd, "r")) == NULL) {
                 close(fd);                  close(fd);
                 syscall = "fdopen";                  syscall = "fdopen";
Line 841  passthrough(const char *file, int fd, int synopsis_onl
Line 860  passthrough(const char *file, int fd, int synopsis_onl
         }          }
   
         print = 0;          print = 0;
         while (getline(&line, &linesz, stream) != -1) {          while ((len = getline(&line, &linesz, stream)) != -1) {
                 cp = line;                  cp = line;
                 if (synopsis_only) {                  if (synopsis_only) {
                         if (print) {                          if (print) {
                                 if ( ! isspace((unsigned char)*cp))                                  if ( ! isspace((unsigned char)*cp))
                                         goto done;                                          goto done;
                                 while (isspace((unsigned char)*cp))                                  while (isspace((unsigned char)*cp)) {
                                         cp++;                                          cp++;
                                           len--;
                                   }
                         } else {                          } else {
                                 if (strcmp(cp, synb) == 0 ||                                  if (strcmp(cp, synb) == 0 ||
                                     strcmp(cp, synr) == 0)                                      strcmp(cp, synr) == 0)
Line 856  passthrough(const char *file, int fd, int synopsis_onl
Line 877  passthrough(const char *file, int fd, int synopsis_onl
                                 continue;                                  continue;
                         }                          }
                 }                  }
                 if (fputs(cp, stdout)) {                  for (; len > 0; len -= written) {
                           if ((written = write(STDOUT_FILENO, cp, len)) != -1)
                                   continue;
                         fclose(stream);                          fclose(stream);
                         syscall = "fputs";                          syscall = "write";
                         goto fail;                          goto fail;
                 }                  }
         }          }
Line 969  woptions(struct curparse *curp, char *arg)
Line 992  woptions(struct curparse *curp, char *arg)
   
         while (*arg) {          while (*arg) {
                 o = arg;                  o = arg;
                 switch (getsubopt(&arg, UNCONST(toks), &v)) {                  switch (getsubopt(&arg, (char * const *)toks, &v)) {
                 case 0:                  case 0:
                         curp->wstop = 1;                          curp->wstop = 1;
                         break;                          break;
Line 1001  mmsg(enum mandocerr t, enum mandoclevel lvl,
Line 1024  mmsg(enum mandocerr t, enum mandoclevel lvl,
 {  {
         const char      *mparse_msg;          const char      *mparse_msg;
   
         fprintf(stderr, "%s: %s:", getprogname(), file);          fprintf(stderr, "%s: %s:", getprogname(),
               file == NULL ? "<stdin>" : file);
   
         if (line)          if (line)
                 fprintf(stderr, "%d:%d:", line, col + 1);                  fprintf(stderr, "%d:%d:", line, col + 1);
Line 1020  mmsg(enum mandocerr t, enum mandoclevel lvl,
Line 1044  mmsg(enum mandocerr t, enum mandoclevel lvl,
 static pid_t  static pid_t
 spawn_pager(struct tag_files *tag_files)  spawn_pager(struct tag_files *tag_files)
 {  {
           const struct timespec timeout = { 0, 100000000 };  /* 0.1s */
 #define MAX_PAGER_ARGS 16  #define MAX_PAGER_ARGS 16
         char            *argv[MAX_PAGER_ARGS];          char            *argv[MAX_PAGER_ARGS];
         const char      *pager;          const char      *pager;
Line 1053  spawn_pager(struct tag_files *tag_files)
Line 1078  spawn_pager(struct tag_files *tag_files)
                         break;                          break;
         }          }
   
         /* For more(1) and less(1), use the tag file. */          /* For less(1), use the tag file. */
   
         if ((cmdlen = strlen(argv[0])) >= 4) {          if ((cmdlen = strlen(argv[0])) >= 4) {
                 cp = argv[0] + cmdlen - 4;                  cp = argv[0] + cmdlen - 4;
                 if (strcmp(cp, "less") == 0 || strcmp(cp, "more") == 0) {                  if (strcmp(cp, "less") == 0) {
                         argv[argc++] = mandoc_strdup("-T");                          argv[argc++] = mandoc_strdup("-T");
                         argv[argc++] = tag_files->tfn;                          argv[argc++] = tag_files->tfn;
                 }                  }
Line 1069  spawn_pager(struct tag_files *tag_files)
Line 1094  spawn_pager(struct tag_files *tag_files)
         case -1:          case -1:
                 err((int)MANDOCLEVEL_SYSERR, "fork");                  err((int)MANDOCLEVEL_SYSERR, "fork");
         case 0:          case 0:
                 /* Set pgrp in both parent and child to avoid racing exec. */  
                 (void)setpgid(0, 0);  
                 break;                  break;
         default:          default:
                 (void)setpgid(pager_pid, 0);                  (void)setpgid(pager_pid, 0);
Line 1089  spawn_pager(struct tag_files *tag_files)
Line 1112  spawn_pager(struct tag_files *tag_files)
                 err((int)MANDOCLEVEL_SYSERR, "pager stdout");                  err((int)MANDOCLEVEL_SYSERR, "pager stdout");
         close(tag_files->ofd);          close(tag_files->ofd);
         close(tag_files->tfd);          close(tag_files->tfd);
   
           /* Do not start the pager before controlling the terminal. */
   
           while (tcgetpgrp(STDIN_FILENO) != getpid())
                   nanosleep(&timeout, NULL);
   
         execvp(argv[0], argv);          execvp(argv[0], argv);
         err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]);          err((int)MANDOCLEVEL_SYSERR, "exec %s", argv[0]);
 }  }

Legend:
Removed from v.1.264  
changed lines
  Added in v.1.273.2.3

CVSweb