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

Diff for /mandoc/catman.c between version 1.17 and 1.26

version 1.17, 2017/02/09 18:46:44 version 1.26, 2025/06/29 23:51:40
Line 1 
Line 1 
 /*      $Id$ */  /* $Id$ */
 /*  /*
    * Copyright (c) 2017, 2025 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>   * Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
  * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>  
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 17 
Line 17 
  */   */
 #include "config.h"  #include "config.h"
   
 #if HAVE_CMSG_XPG42  #if NEED_XPG4_2
 #define _XPG4_2  #define _XPG4_2
 #endif  #endif
   
Line 41 
Line 41 
 #include <time.h>  #include <time.h>
 #include <unistd.h>  #include <unistd.h>
   
 #ifndef O_DIRECTORY  int             verbose_flag = 0;
 #define O_DIRECTORY 0  
 #endif  
   
 int      process_manpage(int, int, const char *);  int      process_manpage(int, int, const char *);
 int      process_tree(int, int);  int      process_tree(int, int);
 void     run_mandocd(int, const char *, const char *)  void     run_mandocd(int, const char *, const char *)
                 __attribute__((noreturn));                  __attribute__((__noreturn__));
 ssize_t  sock_fd_write(int, int, int, int);  ssize_t  sock_fd_write(int, int, int, int);
 void     usage(void) __attribute__((noreturn));  void     usage(void) __attribute__((__noreturn__));
   
   
 void  void
 run_mandocd(int sockfd, const char *outtype, const char* defos)  run_mandocd(int sockfd, const char *outtype, const char* defos)
 {  {
         char     sockfdstr[10];          char     sockfdstr[10];
           int      len;
   
         if (snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd) == -1)          len = snprintf(sockfdstr, sizeof(sockfdstr), "%d", sockfd);
           if (len >= (int)sizeof(sockfdstr)) {
                   errno = EOVERFLOW;
                   len = -1;
           }
           if (len < 0)
                 err(1, "snprintf");                  err(1, "snprintf");
         if (defos == NULL)          if (defos == NULL)
                 execlp("mandocd", "mandocd", "-T", outtype, sockfdstr, NULL);                  execlp("mandocd", "mandocd", "-T", outtype,
                       sockfdstr, (char *)NULL);
         else          else
                 execlp("mandocd", "mandocd", "-T", outtype,                  execlp("mandocd", "mandocd", "-T", outtype,
                     "-I", defos, sockfdstr, NULL);                      "-I", defos, sockfdstr, (char *)NULL);
         err(1, "exec");          err(1, "exec(mandocd)");
 }  }
   
 ssize_t  ssize_t
Line 112  sock_fd_write(int fd, int fd0, int fd1, int fd2)
Line 117  sock_fd_write(int fd, int fd0, int fd1, int fd2)
          * to neither cause more than a handful of retries           * to neither cause more than a handful of retries
          * in normal operation nor unnecessary delays.           * in normal operation nor unnecessary delays.
          */           */
         for (;;) {          while ((sz = sendmsg(fd, &msg, 0)) == -1) {
                 if ((sz = sendmsg(fd, &msg, 0)) != -1 ||                  if (errno != EAGAIN) {
                     errno != EAGAIN)                          warn("FATAL: sendmsg");
                         break;                          break;
                   }
                 nanosleep(&timeout, NULL);                  nanosleep(&timeout, NULL);
         }          }
         return sz;          return sz;
Line 128  process_manpage(int srv_fd, int dstdir_fd, const char 
Line 134  process_manpage(int srv_fd, int dstdir_fd, const char 
         int      irc;          int      irc;
   
         if ((in_fd = open(path, O_RDONLY)) == -1) {          if ((in_fd = open(path, O_RDONLY)) == -1) {
                 warn("open(%s)", path);                  warn("open %s for reading", path);
                   fflush(stderr);
                 return 0;                  return 0;
         }          }
   
         if ((out_fd = openat(dstdir_fd, path,          if ((out_fd = openat(dstdir_fd, path,
             O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,              O_WRONLY | O_NOFOLLOW | O_CREAT | O_TRUNC,
             S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {              S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) {
                 warn("openat(%s)", path);                  warn("openat %s for writing", path);
                   fflush(stderr);
                 close(in_fd);                  close(in_fd);
                 return 0;                  return 0;
         }          }
Line 145  process_manpage(int srv_fd, int dstdir_fd, const char 
Line 153  process_manpage(int srv_fd, int dstdir_fd, const char 
         close(in_fd);          close(in_fd);
         close(out_fd);          close(out_fd);
   
         if (irc < 0) {          return irc;
                 warn("sendmsg");  
                 return -1;  
         }  
         return 0;  
 }  }
   
 int  int
Line 159  process_tree(int srv_fd, int dstdir_fd)
Line 163  process_tree(int srv_fd, int dstdir_fd)
         FTSENT          *entry;          FTSENT          *entry;
         const char      *argv[2];          const char      *argv[2];
         const char      *path;          const char      *path;
           int              fatal;
           int              gooddirs, baddirs, goodfiles, badfiles;
   
         argv[0] = ".";          argv[0] = ".";
         argv[1] = (char *)NULL;          argv[1] = (char *)NULL;
Line 169  process_tree(int srv_fd, int dstdir_fd)
Line 175  process_tree(int srv_fd, int dstdir_fd)
                 return -1;                  return -1;
         }          }
   
         while ((entry = fts_read(ftsp)) != NULL) {          fatal = 0;
           gooddirs = baddirs = goodfiles = badfiles = 0;
           while (fatal == 0 && (entry = fts_read(ftsp)) != NULL) {
                 path = entry->fts_path + 2;                  path = entry->fts_path + 2;
                 switch (entry->fts_info) {                  switch (entry->fts_info) {
                 case FTS_F:                  case FTS_F:
                         if (process_manpage(srv_fd, dstdir_fd, path) == -1) {                          switch (process_manpage(srv_fd, dstdir_fd, path)) {
                                 fts_close(ftsp);                          case -1:
                                 return -1;                                  fatal = errno;
                                   break;
                           case 0:
                                   badfiles++;
                                   break;
                           default:
                                   goodfiles++;
                                   break;
                         }                          }
                         break;                          break;
                 case FTS_D:                  case FTS_D:
Line 183  process_tree(int srv_fd, int dstdir_fd)
Line 198  process_tree(int srv_fd, int dstdir_fd)
                             mkdirat(dstdir_fd, path, S_IRWXU | S_IRGRP |                              mkdirat(dstdir_fd, path, S_IRWXU | S_IRGRP |
                               S_IXGRP | S_IROTH | S_IXOTH) == -1 &&                                S_IXGRP | S_IROTH | S_IXOTH) == -1 &&
                             errno != EEXIST) {                              errno != EEXIST) {
                                 warn("mkdirat(%s)", path);                                  warn("mkdirat %s", path);
                                   fflush(stderr);
                                 (void)fts_set(ftsp, entry, FTS_SKIP);                                  (void)fts_set(ftsp, entry, FTS_SKIP);
                         }                                  baddirs++;
                           } else
                                   gooddirs++;
                         break;                          break;
                 case FTS_DP:                  case FTS_DP:
                         break;                          break;
                   case FTS_DNR:
                           warnx("directory %s unreadable: %s",
                               path, strerror(entry->fts_errno));
                           fflush(stderr);
                           baddirs++;
                           break;
                   case FTS_DC:
                           warnx("directory %s causes cycle", path);
                           fflush(stderr);
                           baddirs++;
                           break;
                   case FTS_ERR:
                   case FTS_NS:
                           warnx("file %s: %s",
                               path, strerror(entry->fts_errno));
                           fflush(stderr);
                           badfiles++;
                           break;
                 default:                  default:
                         warnx("%s: not a regular file", path);                          warnx("file %s: not a regular file", path);
                           fflush(stderr);
                           badfiles++;
                         break;                          break;
                 }                  }
         }          }
           if (fatal == 0 && (fatal = errno) != 0)
                   warn("FATAL: fts_read");
   
         fts_close(ftsp);          fts_close(ftsp);
           if (verbose_flag)
                   warnx("processed %d files in %d directories",
                       goodfiles, gooddirs);
           if (baddirs > 0)
                   warnx("skipped %d %s due to errors", baddirs,
                       baddirs == 1 ? "directory" : "directories");
           if (badfiles > 0)
                   warnx("skipped %d %s due to errors", badfiles,
                       badfiles == 1 ? "file" : "files");
           if (fatal != 0) {
                   warnx("processing aborted due to fatal error, "
                       "results are probably incomplete");
           }
         return 0;          return 0;
 }  }
   
Line 210  main(int argc, char **argv)
Line 263  main(int argc, char **argv)
   
         defos = NULL;          defos = NULL;
         outtype = "ascii";          outtype = "ascii";
         while ((opt = getopt(argc, argv, "I:T:")) != -1) {          while ((opt = getopt(argc, argv, "I:T:v")) != -1) {
                 switch (opt) {                  switch (opt) {
                 case 'I':                  case 'I':
                         defos = optarg;                          defos = optarg;
Line 218  main(int argc, char **argv)
Line 271  main(int argc, char **argv)
                 case 'T':                  case 'T':
                         outtype = optarg;                          outtype = optarg;
                         break;                          break;
                   case 'v':
                           verbose_flag = 1;
                           break;
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 227  main(int argc, char **argv)
Line 283  main(int argc, char **argv)
                 argc -= optind;                  argc -= optind;
                 argv += optind;                  argv += optind;
         }          }
         if (argc != 2)          if (argc != 2) {
                   switch (argc) {
                   case 0:
                           warnx("missing arguments: srcdir and dstdir");
                           break;
                   case 1:
                           warnx("missing argument: dstdir");
                           break;
                   default:
                           warnx("too many arguments: %s", argv[2]);
                           break;
                   }
                 usage();                  usage();
           }
   
         if (socketpair(AF_LOCAL, SOCK_STREAM, AF_UNSPEC, srv_fds) == -1)          if (socketpair(AF_LOCAL, SOCK_STREAM, AF_UNSPEC, srv_fds) == -1)
                 err(1, "socketpair");                  err(1, "socketpair");
Line 246  main(int argc, char **argv)
Line 314  main(int argc, char **argv)
         close(srv_fds[1]);          close(srv_fds[1]);
   
         if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)          if ((dstdir_fd = open(argv[1], O_RDONLY | O_DIRECTORY)) == -1)
                 err(1, "open(%s)", argv[1]);                  err(1, "open destination %s", argv[1]);
   
         if (chdir(argv[0]) == -1)          if (chdir(argv[0]) == -1)
                 err(1, "chdir(%s)", argv[0]);                  err(1, "chdir to source %s", argv[0]);
   
         return process_tree(srv_fds[0], dstdir_fd) == -1 ? 1 : 0;          return process_tree(srv_fds[0], dstdir_fd) == -1 ? 1 : 0;
 }  }
Line 257  main(int argc, char **argv)
Line 325  main(int argc, char **argv)
 void  void
 usage(void)  usage(void)
 {  {
         fprintf(stderr, "usage: catman [-I os=name] [-T output] "          fprintf(stderr, "usage: %s [-I os=name] [-T output] "
             "srcdir dstdir\n");              "srcdir dstdir\n", BINM_CATMAN);
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.26

CVSweb