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*26402Slepreau static char sccsid[] = "@(#)catman.c 5.6 (Berkeley) 02/24/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> 2425892Sdonn #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/"; 3425892Sdonn int exstat = 0; 3511296Ssam char cat[MAXNAMLEN+6] = "catx/"; 3624205Smckusick char lncat[MAXNAMLEN+6] = "catx/"; 3725892Sdonn char *manpath = "/usr/man"; 3825892Sdonn char *sections = "12345678ln"; 3925892Sdonn char *makewhatis = "/usr/lib/makewhatis"; 4025892Sdonn char *index(), *rindex(); 4125892Sdonn char *strcpy(); 4225892Sdonn char *getenv(); 43964Sbill 44964Sbill main(ac, av) 4511296Ssam int ac; 4611296Ssam char *av[]; 4711296Ssam { 4825892Sdonn char *mp, *nextp; 49964Sbill 5025892Sdonn if ((mp = getenv("MANPATH")) != NULL) 5125892Sdonn manpath = mp; 5225892Sdonn 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) { 7225892Sdonn fprintf(stderr, "%s: missing path\n", 7318592Ssam av[0]); 7418592Ssam exit(1); 7518592Ssam } 7618592Ssam ac--, av++; 7725892Sdonn 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 } 9025892Sdonn if (ac == 1) 9125892Sdonn sections = *av; 9225892Sdonn for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) { 9325892Sdonn if (nextp) 9425892Sdonn *nextp++ = '\0'; 9525892Sdonn doit(mp); 9625892Sdonn } 9725892Sdonn exit(exstat); 9825892Sdonn } 9925892Sdonn 10025892Sdonn doit(mandir) 10125892Sdonn char *mandir; 10225892Sdonn { 10325892Sdonn register char *msp, *csp, *sp; 10425892Sdonn int changed = 0; 10525892Sdonn int status; 10625892Sdonn 107964Sbill if (wflag) 108964Sbill goto whatis; 10918592Ssam if (chdir(mandir) < 0) { 11025892Sdonn sprintf(buf, "catman: %s", mandir); 11125892Sdonn perror(buf); 11225892Sdonn /* exstat = 1; */ 11325892Sdonn return; 11418592Ssam } 11525892Sdonn if (pflag) 11625892Sdonn printf("cd %s\n", mandir); 117964Sbill msp = &man[5]; 118964Sbill csp = &cat[5]; 119*26402Slepreau (void) umask(0); 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) { 12825892Sdonn sprintf(buf, "catman: opendir: %s", man); 12925892Sdonn perror(buf); 13025892Sdonn /* exstat = 1; */ 131964Sbill continue; 132964Sbill } 133964Sbill if (stat(cat, &sbuf) < 0) { 13425892Sdonn register char *cp; 13511422Ssam 13625892Sdonn (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); 142*26402Slepreau else if (mkdir(buf, 0777) < 0) { 14311422Ssam sprintf(buf, "catman: mkdir: %s", cat); 14411422Ssam perror(buf); 14525892Sdonn exstat = 1; 14611422Ssam continue; 14711422Ssam } 14825892Sdonn (void) stat(cat, &sbuf); 149964Sbill } 15025892Sdonn if (access(cat, R_OK|W_OK|X_OK) == -1) { 15125892Sdonn sprintf(buf, "catman: %s", cat); 15225892Sdonn perror(buf); 15325892Sdonn exstat = 1; 15425892Sdonn continue; 15525892Sdonn } 15625892Sdonn if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { 15725892Sdonn fprintf(stderr, "catman: %s: Not a directory\n", cat); 15825892Sdonn exstat = 1; 15925892Sdonn continue; 16025892Sdonn } 1616813Sedward while ((dir = readdir(mdir)) != NULL) { 16211296Ssam time_t time; 16325892Sdonn 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; 18225892Sdonn (void) strcpy(msp, dir->d_name); 183964Sbill if ((inf = fopen(man, "r")) == NULL) { 18425892Sdonn sprintf(buf, "catman: %s"); 18525892Sdonn 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); 20925892Sdonn (void) strcpy(csp, dir->d_name); 210964Sbill if (stat(cat, &sbuf) >= 0) { 211964Sbill time = sbuf.st_mtime; 21225892Sdonn (void) stat(man, &sbuf); 213964Sbill if (time >= sbuf.st_mtime) 214964Sbill continue; 21525892Sdonn (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)) 22325892Sdonn (void) unlink(cat); 22424205Smckusick if (pflag) 22524205Smckusick printf("ln %s %s\n", lncat, cat); 22624205Smckusick else 22725892Sdonn if (link(lncat, cat) == -1) { 22825892Sdonn sprintf(buf, "catman: link: %s", cat); 22925892Sdonn perror(buf); 23025892Sdonn exstat = 1; 23125892Sdonn continue; 23225892Sdonn } 23324205Smckusick } 23424205Smckusick else { 23524205Smckusick sprintf(buf, "nroff -man %s > %s", man, cat); 23625892Sdonn if (pflag) 23725892Sdonn printf("%s\n", buf); 23825892Sdonn else if ((status = system(buf)) != 0) { 23925892Sdonn fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status); 24025892Sdonn exstat = 1; 24125892Sdonn continue; 24225892Sdonn } 24324205Smckusick } 244964Sbill changed = 1; 245964Sbill } 2466813Sedward closedir(mdir); 247964Sbill } 248964Sbill if (changed && !nflag) { 249964Sbill whatis: 25025892Sdonn sprintf(buf, "%s %s", makewhatis, mandir); 25125892Sdonn if (pflag) 25225892Sdonn printf("%s\n", buf); 25325892Sdonn else if ((status = system(buf)) != 0) { 25425892Sdonn fprintf(stderr, "catman: %s: exit status %d\n", 25525892Sdonn buf, status); 256964Sbill exstat = 1; 25725892Sdonn } 258964Sbill } 25925892Sdonn return; 260964Sbill } 261