122487Sdist /* 222487Sdist * Copyright (c) 1980 Regents of the University of California. 322487Sdist * All rights reserved. The Berkeley software License Agreement 422487Sdist * specifies the terms and conditions for redistribution. 522487Sdist */ 622487Sdist 711296Ssam #ifndef lint 822487Sdist char copyright[] = 922487Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022487Sdist All rights reserved.\n"; 1122487Sdist #endif not lint 12964Sbill 1322487Sdist #ifndef lint 14*25892Sdonn static char sccsid[] = "@(#)catman.c 5.5 (Berkeley) 01/13/86"; 1522487Sdist #endif not lint 1622487Sdist 1711296Ssam /* 1811296Ssam * catman: update cat'able versions of manual pages 1911296Ssam * (whatis database also) 2011296Ssam */ 2111296Ssam #include <stdio.h> 2211296Ssam #include <sys/types.h> 2313549Ssam #include <sys/stat.h> 24*25892Sdonn #include <sys/file.h> 2513549Ssam #include <sys/time.h> 2613549Ssam #include <sys/dir.h> 2711296Ssam #include <ctype.h> 28964Sbill 2911296Ssam char buf[BUFSIZ]; 3011296Ssam char pflag; 3111296Ssam char nflag; 3211296Ssam char wflag; 3311296Ssam char man[MAXNAMLEN+6] = "manx/"; 34*25892Sdonn int exstat = 0; 3511296Ssam char cat[MAXNAMLEN+6] = "catx/"; 3624205Smckusick char lncat[MAXNAMLEN+6] = "catx/"; 37*25892Sdonn char *manpath = "/usr/man"; 38*25892Sdonn char *sections = "12345678ln"; 39*25892Sdonn char *makewhatis = "/usr/lib/makewhatis"; 40*25892Sdonn char *index(), *rindex(); 41*25892Sdonn char *strcpy(); 42*25892Sdonn char *getenv(); 43964Sbill 44964Sbill main(ac, av) 4511296Ssam int ac; 4611296Ssam char *av[]; 4711296Ssam { 48*25892Sdonn char *mp, *nextp; 49964Sbill 50*25892Sdonn if ((mp = getenv("MANPATH")) != NULL) 51*25892Sdonn manpath = mp; 52*25892Sdonn 5318592Ssam ac--, av++; 5418593Ssam while (ac > 0 && av[0][0] == '-') { 5518592Ssam switch (av[0][1]) { 5618592Ssam 5718592Ssam case 'p': 58964Sbill pflag++; 5918592Ssam break; 6018592Ssam 6118592Ssam case 'n': 62964Sbill nflag++; 6318592Ssam break; 6418592Ssam 6518592Ssam case 'w': 66964Sbill wflag++; 6718592Ssam break; 6818592Ssam 6918592Ssam case 'M': 7018592Ssam case 'P': 7118592Ssam if (ac < 1) { 72*25892Sdonn fprintf(stderr, "%s: missing path\n", 7318592Ssam av[0]); 7418592Ssam exit(1); 7518592Ssam } 7618592Ssam ac--, av++; 77*25892Sdonn manpath = *av; 7818592Ssam break; 7918592Ssam 8018592Ssam default: 81964Sbill goto usage; 8218592Ssam } 8318592Ssam ac--, av++; 84964Sbill } 8518593Ssam if (ac > 1) { 86964Sbill usage: 8718592Ssam printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n"); 88964Sbill exit(-1); 89964Sbill } 90*25892Sdonn if (ac == 1) 91*25892Sdonn sections = *av; 92*25892Sdonn for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) { 93*25892Sdonn if (nextp) 94*25892Sdonn *nextp++ = '\0'; 95*25892Sdonn doit(mp); 96*25892Sdonn } 97*25892Sdonn exit(exstat); 98*25892Sdonn } 99*25892Sdonn 100*25892Sdonn doit(mandir) 101*25892Sdonn char *mandir; 102*25892Sdonn { 103*25892Sdonn register char *msp, *csp, *sp; 104*25892Sdonn int changed = 0; 105*25892Sdonn int status; 106*25892Sdonn 107964Sbill if (wflag) 108964Sbill goto whatis; 10918592Ssam if (chdir(mandir) < 0) { 110*25892Sdonn sprintf(buf, "catman: %s", mandir); 111*25892Sdonn perror(buf); 112*25892Sdonn /* exstat = 1; */ 113*25892Sdonn return; 11418592Ssam } 115*25892Sdonn if (pflag) 116*25892Sdonn printf("cd %s\n", mandir); 117964Sbill msp = &man[5]; 118964Sbill csp = &cat[5]; 119*25892Sdonn (void) umask(02); 120964Sbill for (sp = sections; *sp; sp++) { 12111296Ssam register DIR *mdir; 12211296Ssam register struct direct *dir; 12311296Ssam struct stat sbuf; 12411296Ssam 125964Sbill man[3] = cat[3] = *sp; 126964Sbill *msp = *csp = '\0'; 1276813Sedward if ((mdir = opendir(man)) == NULL) { 128*25892Sdonn sprintf(buf, "catman: opendir: %s", man); 129*25892Sdonn perror(buf); 130*25892Sdonn /* exstat = 1; */ 131964Sbill continue; 132964Sbill } 133964Sbill if (stat(cat, &sbuf) < 0) { 134*25892Sdonn register char *cp; 13511422Ssam 136*25892Sdonn (void) strcpy(buf, cat); 13711422Ssam cp = rindex(buf, '/'); 13811422Ssam if (cp && cp[1] == '\0') 13911422Ssam *cp = '\0'; 14011422Ssam if (pflag) 14111422Ssam printf("mkdir %s\n", buf); 14224232Smckusick else if (mkdir(buf, 0775) < 0) { 14311422Ssam sprintf(buf, "catman: mkdir: %s", cat); 14411422Ssam perror(buf); 145*25892Sdonn exstat = 1; 14611422Ssam continue; 14711422Ssam } 148*25892Sdonn (void) stat(cat, &sbuf); 149964Sbill } 150*25892Sdonn if (access(cat, R_OK|W_OK|X_OK) == -1) { 151*25892Sdonn sprintf(buf, "catman: %s", cat); 152*25892Sdonn perror(buf); 153*25892Sdonn exstat = 1; 154*25892Sdonn continue; 155*25892Sdonn } 156*25892Sdonn if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { 157*25892Sdonn fprintf(stderr, "catman: %s: Not a directory\n", cat); 158*25892Sdonn exstat = 1; 159*25892Sdonn continue; 160*25892Sdonn } 1616813Sedward while ((dir = readdir(mdir)) != NULL) { 16211296Ssam time_t time; 163*25892Sdonn register char *tsp; 16411296Ssam FILE *inf; 16524205Smckusick int makelink; 16611296Ssam 1676813Sedward if (dir->d_ino == 0 || dir->d_name[0] == '.') 168964Sbill continue; 169964Sbill /* 17011296Ssam * Make sure this is a man file, i.e., that it 171964Sbill * ends in .[0-9] or .[0-9][a-z] 172964Sbill */ 1736813Sedward tsp = rindex(dir->d_name, '.'); 174964Sbill if (tsp == NULL) 175964Sbill continue; 17616079Sralph if (!isdigit(*++tsp) && *tsp != *sp) 177964Sbill continue; 17811296Ssam if (*++tsp && !isalpha(*tsp)) 17911296Ssam continue; 18011296Ssam if (*tsp && *++tsp) 18111296Ssam continue; 182*25892Sdonn (void) strcpy(msp, dir->d_name); 183964Sbill if ((inf = fopen(man, "r")) == NULL) { 184*25892Sdonn sprintf(buf, "catman: %s"); 185*25892Sdonn perror(buf); 186964Sbill exstat = 1; 187964Sbill continue; 188964Sbill } 18924205Smckusick makelink = 0; 190964Sbill if (getc(inf) == '.' && getc(inf) == 's' 191964Sbill && getc(inf) == 'o') { 19224205Smckusick if (getc(inf) != ' ' || 19324205Smckusick fgets(lncat, sizeof(lncat), inf)==NULL) { 19424205Smckusick fclose(inf); 19524205Smckusick continue; 19624205Smckusick } 19724205Smckusick if (lncat[strlen(lncat)-1] == '\n') 19824205Smckusick lncat[strlen(lncat)-1] = '\0'; 19924205Smckusick if (strncmp(lncat, "man", 3) != 0) { 20024205Smckusick fclose(inf); 20124205Smckusick continue; 20224205Smckusick } 20324205Smckusick lncat[0] = 'c'; 20424205Smckusick lncat[1] = 'a'; 20524205Smckusick lncat[2] = 't'; 20624205Smckusick makelink = 1; 207964Sbill } 208964Sbill fclose(inf); 209*25892Sdonn (void) strcpy(csp, dir->d_name); 210964Sbill if (stat(cat, &sbuf) >= 0) { 211964Sbill time = sbuf.st_mtime; 212*25892Sdonn (void) stat(man, &sbuf); 213964Sbill if (time >= sbuf.st_mtime) 214964Sbill continue; 215*25892Sdonn (void) unlink(cat); 216964Sbill } 21724205Smckusick if (makelink) { 21824205Smckusick /* 21924205Smckusick * Don't unlink a directory by accident. 22024205Smckusick */ 22124205Smckusick if (stat(lncat, &sbuf) >= 0 && 22225214Smckusick ((sbuf.st_mode&S_IFMT)==S_IFREG)) 223*25892Sdonn (void) unlink(cat); 22424205Smckusick if (pflag) 22524205Smckusick printf("ln %s %s\n", lncat, cat); 22624205Smckusick else 227*25892Sdonn if (link(lncat, cat) == -1) { 228*25892Sdonn sprintf(buf, "catman: link: %s", cat); 229*25892Sdonn perror(buf); 230*25892Sdonn exstat = 1; 231*25892Sdonn continue; 232*25892Sdonn } 23324205Smckusick } 23424205Smckusick else { 23524205Smckusick sprintf(buf, "nroff -man %s > %s", man, cat); 236*25892Sdonn if (pflag) 237*25892Sdonn printf("%s\n", buf); 238*25892Sdonn else if ((status = system(buf)) != 0) { 239*25892Sdonn fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status); 240*25892Sdonn exstat = 1; 241*25892Sdonn continue; 242*25892Sdonn } 24324205Smckusick } 244964Sbill changed = 1; 245964Sbill } 2466813Sedward closedir(mdir); 247964Sbill } 248964Sbill if (changed && !nflag) { 249964Sbill whatis: 250*25892Sdonn sprintf(buf, "%s %s", makewhatis, mandir); 251*25892Sdonn if (pflag) 252*25892Sdonn printf("%s\n", buf); 253*25892Sdonn else if ((status = system(buf)) != 0) { 254*25892Sdonn fprintf(stderr, "catman: %s: exit status %d\n", 255*25892Sdonn buf, status); 256964Sbill exstat = 1; 257*25892Sdonn } 258964Sbill } 259*25892Sdonn return; 260964Sbill } 261