Index: head/benchmarks/tcpblast/src/tcpblast.c =================================================================== --- head/benchmarks/tcpblast/src/tcpblast.c (revision 404856) +++ head/benchmarks/tcpblast/src/tcpblast.c (nonexistent) @@ -1,127 +0,0 @@ -/* - * tcpblast - test and estimate TCP thruput - * - * Daniel Karrenberg - */ - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#define BLKSIZE 1024 - -struct sockaddr_in sock_in; -struct servent *sp; -struct hostent *host; - -long starts, startms, stops, stopms, expms; -struct timeval ti; -struct timezone tiz; - -char greet[BLKSIZE] = "Hi!"; -int nblocks; -int f; - -int main(argc, argv) -int argc; char **argv; -{ - struct addrinfo hints, *res, *res0; - char *cause = NULL; - int ch, proto, error; - register int i; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - - while ((ch = getopt(argc, argv, "46")) != -1) { - switch (ch) { - case '4': - hints.ai_family = PF_INET; - break; - case '6': - hints.ai_family = PF_INET6; - break; - } - } - argc -= optind; - argv += optind; - if (argc != 2) { - fprintf(stderr, - "usage: tcpblast [-4] [-6] destination nblkocks\n" - "blocksize: %d bytes %d\n", BLKSIZE, argc); - exit(1); - } - - nblocks = atoi(argv[1]); - if (nblocks<=1 || nblocks>10000) { - fprintf(stderr, "tcpblast: 1 < nblocks <= 10000 \n"); - exit(1); - } - - error = getaddrinfo(argv[0], "discard", &hints, &res0); - if (error) - errx(1, "%s", gai_strerror(error)); - f = -1; - cause = "no addresses"; - errno = EADDRNOTAVAIL; - for (res = res0; res; res = res->ai_next) { - f = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (f < 0) { - cause = "socket"; - continue; - } - if (connect(f, res->ai_addr, res->ai_addrlen) < 0) { - cause = "connect"; - close(f); - f = -1; - continue; - } - break; - } - if (f < 0) - err(1, cause); - freeaddrinfo(res); - - if (gettimeofday(&ti, &tiz) < 0) - { - perror("tcpblast time:"); - exit(1); - } - starts = ti.tv_sec; - startms = ti.tv_usec / 1000L; - - - for (i=0; i Property changes on: head/benchmarks/tcpblast/src/Makefile ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/benchmarks/tcpblast/Makefile =================================================================== --- head/benchmarks/tcpblast/Makefile (revision 404856) +++ head/benchmarks/tcpblast/Makefile (revision 404857) @@ -1,23 +1,24 @@ # Created by: mr # $FreeBSD$ PORTNAME= tcpblast PORTVERSION= 1.1 PORTREVISION= 1 CATEGORIES= benchmarks net ipv6 +MASTER_SITES= # none DISTFILES= # none MAINTAINER= ports@FreeBSD.org COMMENT= Measures the throughput of a TCP connection +NO_WRKSUBDIR= yes + PLIST_FILES= bin/tcpblast -USES= uidfix -WRKSRC= ${WRKDIR}/src +do-build: + ${CC} ${CFLAGS} ${FILESDIR}/${PORTNAME}.c -o ${WRKDIR}/${PORTNAME} -do-extract: - @${RM} -rf ${WRKDIR} - @${MKDIR} ${WRKDIR} - ${CP} -RP ${.CURDIR}/src ${WRKDIR} +do-install: + ${INSTALL_PROGRAM} ${WRKDIR}/${PORTNAME} ${STAGEDIR}${PREFIX}/bin .include Index: head/benchmarks/tcpblast/files/tcpblast.c =================================================================== --- head/benchmarks/tcpblast/files/tcpblast.c (nonexistent) +++ head/benchmarks/tcpblast/files/tcpblast.c (revision 404857) @@ -0,0 +1,128 @@ +/* + * tcpblast - test and estimate TCP thruput + * + * Daniel Karrenberg + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define BLKSIZE 1024 + +struct sockaddr_in sock_in; +struct servent *sp; +struct hostent *host; + +long starts, startms, stops, stopms, expms; +struct timeval ti; +struct timezone tiz; + +char greet[BLKSIZE] = "Hi!"; +int nblocks; +int f; + +int main(argc, argv) +int argc; char **argv; +{ + struct addrinfo hints, *res, *res0; + char *cause = NULL; + int ch, proto, error; + register int i; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + while ((ch = getopt(argc, argv, "46")) != -1) { + switch (ch) { + case '4': + hints.ai_family = PF_INET; + break; + case '6': + hints.ai_family = PF_INET6; + break; + } + } + argc -= optind; + argv += optind; + if (argc != 2) { + fprintf(stderr, + "usage: tcpblast [-4] [-6] destination nblkocks\n" + "blocksize: %d bytes %d\n", BLKSIZE, argc); + exit(1); + } + + nblocks = atoi(argv[1]); + if (nblocks<=1 || nblocks>10000) { + fprintf(stderr, "tcpblast: 1 < nblocks <= 10000 \n"); + exit(1); + } + + error = getaddrinfo(argv[0], "discard", &hints, &res0); + if (error) + errx(1, "%s", gai_strerror(error)); + f = -1; + cause = "no addresses"; + errno = EADDRNOTAVAIL; + for (res = res0; res; res = res->ai_next) { + f = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (f < 0) { + cause = "socket"; + continue; + } + if (connect(f, res->ai_addr, res->ai_addrlen) < 0) { + cause = "connect"; + close(f); + f = -1; + continue; + } + break; + } + if (f < 0) + err(1, cause); + freeaddrinfo(res); + + if (gettimeofday(&ti, &tiz) < 0) + { + perror("tcpblast time:"); + exit(1); + } + starts = ti.tv_sec; + startms = ti.tv_usec / 1000L; + + + for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void correct_mss(struct tcphdr *, ssize_t len, u_int16_t); -static int if_mtu(const char *, u_long *); -static void sigterm_handler(int); -static void usage(void); - -static int both; -static int verbose; - -char pidfilename[MAXPATHLEN]; - -/*- - * We are in liberal position about MSS - * (RFC 879, section 7). - */ -#define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr)) - -int -main(int argc, char *argv[]) -{ - char pkt[IP_MAXPACKET]; - ssize_t pktlen, hlen; - struct ip *pip = (struct ip *)pkt; - struct sockaddr_in sin; - socklen_t sinlen; - int s; - int mflag; - u_long mtu; - u_int16_t maxmss; - int rtsock; - int ifindex; - int pflag; - u_short port; - int ch; - fd_set fdset; - - mflag = pflag = 0; - port = 0; /* XXX gcc -Wuninitialized */ - ifindex = 0; - rtsock = -1; - - while ((ch = getopt(argc, argv, "bi:m:p:v")) != -1) - switch (ch) { - case 'b': - both = 1; - break; - case 'i': - if (!(ifindex = if_mtu(optarg, &mtu))) { - errx(1, "unknown interface %s", optarg); - /* NOTREACHED */ - } - snprintf(pidfilename, sizeof pidfilename, - "%stcpmssd.%s.pid", _PATH_VARRUN, optarg); - break; - case 'm': - if ((mtu = atoi(optarg)) < 68) { - errx(1, "invalid MTU value"); - /* NOTREACHED */ - } - mflag++; - break; - case 'p': - port = htons(atoi(optarg)); - pflag++; - break; - case 'v': - verbose = 1; - break; - case '?': - default: - usage(); - /* NOTREACHED */ - } - argc -= optind; - argv += optind; - - if (!(!mflag - !ifindex) || !pflag || argc) { - usage(); - /* NOTREACHED */ - } - - if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) { - err(1, "can't create divert socket"); - /* NOTREACHED */ - } - - bzero(&sin, sizeof(sin)); - sin.sin_family = PF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = port; - - if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - err(1, "can't bind divert socket"); - /* NOTREACHED */ - } - - if (ifindex) - if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) { - err(1, "can't create routing socket"); - /* NOTREACHED */ - } - - maxmss = MAXMSS(mtu); - if (verbose) - fprintf(stderr, "Maximum MSS: %u\n", maxmss); - - if (!verbose) - if (daemon(0, 0) == -1) { - err(1, "can't daemonize"); - /* NOTREACHED */ - } - - if (ifindex) { - FILE *pidfile; - - pidfile = fopen(pidfilename, "w"); - if (pidfile != NULL) { - fprintf(pidfile, "%d\n", (int)getpid()); - fclose(pidfile); - if (signal(SIGTERM, sigterm_handler) == SIG_ERR) { - err(1, "can't install SIGTERM handler"); - /* NOTREACHED */ - } - } - } - - while (1) { - FD_ZERO(&fdset); - FD_SET(s, &fdset); - if (rtsock != -1) - FD_SET(rtsock, &fdset); - - if (select(32, &fdset, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) == -1) { - warn("select failed"); - continue; - } - - if (rtsock != -1 && FD_ISSET(rtsock, &fdset)) { - struct if_msghdr ifm; - - if ((pktlen = read(rtsock, &ifm, sizeof(ifm))) == -1) { - warn("read from routing socket failed"); - continue; - } - if (ifm.ifm_version != RTM_VERSION) { - if (verbose) - warnx("routing message version %d " - "not understood", ifm.ifm_version); - continue; - } - if (ifm.ifm_type != RTM_IFINFO || - ifm.ifm_index != ifindex) - continue; - if (mtu != ifm.ifm_data.ifi_mtu) { - mtu = ifm.ifm_data.ifi_mtu; - maxmss = MAXMSS(mtu); - if (verbose) - fprintf(stderr, "Maximum MSS: %u\n", maxmss); - } - } - - if (FD_ISSET(s, &fdset)) { - sinlen = sizeof(sin); - - if ((pktlen = recvfrom(s, pkt, sizeof(pkt), 0, - (struct sockaddr *)&sin, &sinlen)) == -1) - if (errno != EINTR) { - warn("read from divert socket failed"); - continue; - } - - hlen = pip->ip_hl << 2; - - /*- - * Check for MSS option only for outgoing - * TCP packets with zero fragment offset - * and correct total and header lengths. - */ - if ((both || sin.sin_addr.s_addr == INADDR_ANY) && - pip->ip_p == IPPROTO_TCP && - (ntohs(pip->ip_off) & IP_OFFMASK) == 0 && - ntohs(pip->ip_len) == pktlen && - hlen <= pktlen && - pktlen - hlen >= sizeof(struct tcphdr)) - correct_mss((struct tcphdr *)(pkt + hlen), - pktlen - hlen, maxmss); - - if (sendto(s, pkt, pktlen, 0, - (struct sockaddr *)&sin, sinlen) == -1) - warn("write to divert socket failed"); - } - } -} - - -/*- - * The following macro is used to update an - * internet checksum. "acc" is a 32-bit - * accumulation of all the changes to the - * checksum (adding in old 16-bit words and - * subtracting out new words), and "cksum" - * is the checksum value to be updated. - */ -#define ADJUST_CHECKSUM(acc, cksum) { \ - acc += cksum; \ - if (acc < 0) { \ - acc = -acc; \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) ~acc; \ - } else { \ - acc = (acc >> 16) + (acc & 0xffff); \ - acc += acc >> 16; \ - cksum = (u_short) acc; \ - } \ -} - - -void -correct_mss(struct tcphdr *tc, ssize_t pktlen, u_int16_t maxmss) -{ - int hlen, olen, optlen; - u_char *opt; - u_int16_t *mss; - int accumulate; - - hlen = tc->th_off << 2; - - /* Invalid header length or header without options. */ - if (hlen <= sizeof(struct tcphdr) || hlen > pktlen) - return; - - /* MSS option only allowed within SYN packets. */ - if (!(tc->th_flags & TH_SYN)) - return; - - for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1); - olen > 0; olen -= optlen, opt += optlen) { - if (*opt == TCPOPT_EOL) - break; - else if (*opt == TCPOPT_NOP) - optlen = 1; - else { - optlen = *(opt + 1); - if (optlen <= 0 || optlen > olen) - break; - if (*opt == TCPOPT_MAXSEG) { - if (optlen != TCPOLEN_MAXSEG) - continue; - mss = (u_int16_t *)(opt + 2); - if (ntohs(*mss) > maxmss) { - if (verbose) - fprintf(stderr, - "MSS: %u -> %u\n", - ntohs(*mss), maxmss); - accumulate = *mss; - *mss = htons(maxmss); - accumulate -= *mss; - ADJUST_CHECKSUM(accumulate, tc->th_sum); - } - } - } - } -} - - -static int -if_mtu(const char *ifn, u_long *mtu) -{ - size_t needed; - int mib[6]; - char *buf, *lim, *next; - struct if_msghdr *ifm; - struct sockaddr_dl *sdl; - int ifindex; - - mib[0] = CTL_NET; - mib[1] = PF_ROUTE; - mib[2] = 0; - mib[3] = AF_INET; /* Only IP addresses please. */ - mib[4] = NET_RT_IFLIST; - mib[5] = 0; /* List all interfaces. */ -/* - * Get interface data. - */ - if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) - err(1, "iflist-sysctl-estimate"); - if ((buf = malloc(needed)) == NULL) - errx(1, "malloc failed"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) - err(1, "iflist-sysctl-get"); - lim = buf + needed; -/* - * Loop through interfaces until one with - * given name is found. This is done to - * find correct interface index for routing - * message processing. - */ - ifindex = 0; - next = buf; - while (next < lim) { - ifm = (struct if_msghdr *)next; - next += ifm->ifm_msglen; - if (ifm->ifm_version != RTM_VERSION) { - if (verbose) - warnx("routing message version %d " - "not understood", ifm->ifm_version); - continue; - } - if (ifm->ifm_type == RTM_IFINFO) { - sdl = (struct sockaddr_dl *)(ifm + 1); - if (strlen(ifn) == sdl->sdl_nlen && - strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) { - *mtu = ifm->ifm_data.ifi_mtu; - ifindex = ifm->ifm_index; - break; - } - } - } - free(buf); - return (ifindex); -} - - -static void -sigterm_handler(int sig) -{ - - (void)unlink(pidfilename); - exit(0); -} - - -void -usage(void) -{ - - fprintf(stderr, "usage: tcpmssd [-v] -p port {-i iface | -m mtu}\n"); - exit(1); -} Property changes on: head/net/tcpmssd/src/tcpmssd.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/net/tcpmssd/src/tcpmssd.8 =================================================================== --- head/net/tcpmssd/src/tcpmssd.8 (revision 404856) +++ head/net/tcpmssd/src/tcpmssd.8 (nonexistent) @@ -1,132 +0,0 @@ -.\" Copyright (c) 2000 Ruslan Ermilov -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd June 11, 2004 -.Dt TCPMSSD 8 -.Os -.Sh NAME -.Nm tcpmssd -.Nd "TCP Maximum Segment Size option corrector" -.Sh SYNOPSIS -.Nm -.Op Fl bv -.Fl p Ar port -.Brq Fl i Ar iface | Fl m Ar mtu -.Sh DESCRIPTION -The -.Nm -utility adjusts TCP SYN packets so that the maximum -receive segment size is not greater than the amount allowed by the -interface's MTU. -.Pp -This is necessary in many setups to avoid problems caused by routers that -drop ICMP -.Dq "Datagram Too Big" -messages, thus breaking the Path MTU Discovery algorithm (RFC 1191). -Without these messages, the originating machine sends data, it passes -the rogue router then hits a machine that has an MTU that is not big -enough for the data. -Because the IP -.Dq "don't fragment" -option is set, this machine sends an ICMP -.Dq "Datagram Too Big" -message back to the originator and drops the packet. -The rogue router drops the ICMP and the originator never gets to -discover that it must reduce the Path MTU value or exclude the IP -.Dq "don't fragment" -option from its outgoing data. -.Pp -The -.Nm -utility -normally runs in the background as a daemon. -It intercepts TCP packets -from a -.Xr divert 4 -socket bound to the -.Ar port -specified with the -.Fl p -option and reduces the value of TCP MSS option if necessary so that -the incoming TCP messages will pass through this host without need to -send ICMP -.Dq "Datagram Too Big" -messages. -.Pp -The maximum value for the TCP MSS option is determined based on an MTU -given either as an absolute value with the -.Fl m -option or derived from a network interface specified with the -.Fl i -option. -.Pp -If run with the -.Fl b -option, -.Nm -will attempt to update the TCP MSS option on both incoming and outgoing -TCP segments, as delivered on the -.Xr divert 4 -socket. -By default, only outgoing TCP segments are examined. -.Pp -If run with the -.Fl v -option, -.Nm -does not detach from its controlling terminal and writes various diagnostic -messages to the standard error output. -.Pp -The following steps are necessary to run -.Nm : -.Bl -enum -.It -Build your kernel with the following options: -.Bd -literal -offset indent -options IPFIREWALL -options IPDIVERT -.Ed -.Pp -Refer to the Handbook for detailed instructions on building a custom -kernel. -.It -Make sure to redirect TCP traffic to the -.Xr divert 4 -port -.Ar port . -Refer to the -.Xr ipfw 8 -manual page for details. -.El -.Sh SEE ALSO -.Xr divert 4 , -.Xr ipfw 8 -.Sh AUTHORS -.An -nosplit -This program was written by -.An Ruslan Ermilov Aq ru@FreeBSD.org -based on work done by -.An Patrick Bihan-Faou Aq patrick@mindstep.com . Property changes on: head/net/tcpmssd/src/tcpmssd.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/net/tcpmssd/Makefile =================================================================== --- head/net/tcpmssd/Makefile (revision 404856) +++ head/net/tcpmssd/Makefile (revision 404857) @@ -1,29 +1,24 @@ # Created by: ru # $FreeBSD$ PORTNAME= tcpmssd PORTVERSION= 1.1 CATEGORIES= net MASTER_SITES= # none DISTFILES= # none MAINTAINER= ports@FreeBSD.org COMMENT= Utility to correct requested TCP receive segment size -WRKSRC= ${WRKDIR}/src +NO_WRKSUBDIR= yes -SRC= ${.CURDIR}/src - PLIST_FILES= bin/tcpmssd man/man8/tcpmssd.8.gz -pre-patch: - @${CP} -R ${SRC} ${WRKDIR} - do-build: - (cd ${WRKSRC} && ${MAKE} tcpmssd) + ${CC} ${CFLAGS} ${FILESDIR}/${PORTNAME}.c -o ${WRKDIR}/${PORTNAME} do-install: - ${INSTALL_PROGRAM} ${WRKSRC}/tcpmssd ${STAGEDIR}${PREFIX}/bin - ${INSTALL_MAN} ${WRKSRC}/tcpmssd.8 ${STAGEDIR}${MAN8PREFIX}/man/man8 + ${INSTALL_PROGRAM} ${WRKDIR}/${PORTNAME} ${STAGEDIR}${PREFIX}/bin + ${INSTALL_MAN} ${FILESDIR}/${PORTNAME}.8 ${STAGEDIR}${MANPREFIX}/man/man8 .include Index: head/net/tcpmssd/files/tcpmssd.8 =================================================================== --- head/net/tcpmssd/files/tcpmssd.8 (nonexistent) +++ head/net/tcpmssd/files/tcpmssd.8 (revision 404857) @@ -0,0 +1,132 @@ +.\" Copyright (c) 2000 Ruslan Ermilov +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd June 11, 2004 +.Dt TCPMSSD 8 +.Os +.Sh NAME +.Nm tcpmssd +.Nd "TCP Maximum Segment Size option corrector" +.Sh SYNOPSIS +.Nm +.Op Fl bv +.Fl p Ar port +.Brq Fl i Ar iface | Fl m Ar mtu +.Sh DESCRIPTION +The +.Nm +utility adjusts TCP SYN packets so that the maximum +receive segment size is not greater than the amount allowed by the +interface's MTU. +.Pp +This is necessary in many setups to avoid problems caused by routers that +drop ICMP +.Dq "Datagram Too Big" +messages, thus breaking the Path MTU Discovery algorithm (RFC 1191). +Without these messages, the originating machine sends data, it passes +the rogue router then hits a machine that has an MTU that is not big +enough for the data. +Because the IP +.Dq "don't fragment" +option is set, this machine sends an ICMP +.Dq "Datagram Too Big" +message back to the originator and drops the packet. +The rogue router drops the ICMP and the originator never gets to +discover that it must reduce the Path MTU value or exclude the IP +.Dq "don't fragment" +option from its outgoing data. +.Pp +The +.Nm +utility +normally runs in the background as a daemon. +It intercepts TCP packets +from a +.Xr divert 4 +socket bound to the +.Ar port +specified with the +.Fl p +option and reduces the value of TCP MSS option if necessary so that +the incoming TCP messages will pass through this host without need to +send ICMP +.Dq "Datagram Too Big" +messages. +.Pp +The maximum value for the TCP MSS option is determined based on an MTU +given either as an absolute value with the +.Fl m +option or derived from a network interface specified with the +.Fl i +option. +.Pp +If run with the +.Fl b +option, +.Nm +will attempt to update the TCP MSS option on both incoming and outgoing +TCP segments, as delivered on the +.Xr divert 4 +socket. +By default, only outgoing TCP segments are examined. +.Pp +If run with the +.Fl v +option, +.Nm +does not detach from its controlling terminal and writes various diagnostic +messages to the standard error output. +.Pp +The following steps are necessary to run +.Nm : +.Bl -enum +.It +Build your kernel with the following options: +.Bd -literal -offset indent +options IPFIREWALL +options IPDIVERT +.Ed +.Pp +Refer to the Handbook for detailed instructions on building a custom +kernel. +.It +Make sure to redirect TCP traffic to the +.Xr divert 4 +port +.Ar port . +Refer to the +.Xr ipfw 8 +manual page for details. +.El +.Sh SEE ALSO +.Xr divert 4 , +.Xr ipfw 8 +.Sh AUTHORS +.An -nosplit +This program was written by +.An Ruslan Ermilov Aq ru@FreeBSD.org +based on work done by +.An Patrick Bihan-Faou Aq patrick@mindstep.com . Property changes on: head/net/tcpmssd/files/tcpmssd.8 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/net/tcpmssd/files/tcpmssd.c =================================================================== --- head/net/tcpmssd/files/tcpmssd.c (nonexistent) +++ head/net/tcpmssd/files/tcpmssd.c (revision 404857) @@ -0,0 +1,386 @@ +/*- + * Copyright (c) 2000 Ruslan Ermilov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void correct_mss(struct tcphdr *, ssize_t len, u_int16_t); +static int if_mtu(const char *, u_long *); +static void sigterm_handler(int); +static void usage(void); + +static int both; +static int verbose; + +char pidfilename[MAXPATHLEN]; + +/*- + * We are in liberal position about MSS + * (RFC 879, section 7). + */ +#define MAXMSS(mtu) (mtu - sizeof(struct ip) - sizeof(struct tcphdr)) + +int +main(int argc, char *argv[]) +{ + char pkt[IP_MAXPACKET]; + ssize_t pktlen, hlen; + struct ip *pip = (struct ip *)pkt; + struct sockaddr_in sin; + socklen_t sinlen; + int s; + int mflag; + u_long mtu; + u_int16_t maxmss; + int rtsock; + int ifindex; + int pflag; + u_short port; + int ch; + fd_set fdset; + + mflag = pflag = 0; + port = 0; /* XXX gcc -Wuninitialized */ + ifindex = 0; + rtsock = -1; + + while ((ch = getopt(argc, argv, "bi:m:p:v")) != -1) + switch (ch) { + case 'b': + both = 1; + break; + case 'i': + if (!(ifindex = if_mtu(optarg, &mtu))) { + errx(1, "unknown interface %s", optarg); + /* NOTREACHED */ + } + snprintf(pidfilename, sizeof pidfilename, + "%stcpmssd.%s.pid", _PATH_VARRUN, optarg); + break; + case 'm': + if ((mtu = atoi(optarg)) < 68) { + errx(1, "invalid MTU value"); + /* NOTREACHED */ + } + mflag++; + break; + case 'p': + port = htons(atoi(optarg)); + pflag++; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + usage(); + /* NOTREACHED */ + } + argc -= optind; + argv += optind; + + if (!(!mflag - !ifindex) || !pflag || argc) { + usage(); + /* NOTREACHED */ + } + + if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) == -1) { + err(1, "can't create divert socket"); + /* NOTREACHED */ + } + + bzero(&sin, sizeof(sin)); + sin.sin_family = PF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = port; + + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { + err(1, "can't bind divert socket"); + /* NOTREACHED */ + } + + if (ifindex) + if ((rtsock = socket(PF_ROUTE, SOCK_RAW, 0)) == -1) { + err(1, "can't create routing socket"); + /* NOTREACHED */ + } + + maxmss = MAXMSS(mtu); + if (verbose) + fprintf(stderr, "Maximum MSS: %u\n", maxmss); + + if (!verbose) + if (daemon(0, 0) == -1) { + err(1, "can't daemonize"); + /* NOTREACHED */ + } + + if (ifindex) { + FILE *pidfile; + + pidfile = fopen(pidfilename, "w"); + if (pidfile != NULL) { + fprintf(pidfile, "%d\n", (int)getpid()); + fclose(pidfile); + if (signal(SIGTERM, sigterm_handler) == SIG_ERR) { + err(1, "can't install SIGTERM handler"); + /* NOTREACHED */ + } + } + } + + while (1) { + FD_ZERO(&fdset); + FD_SET(s, &fdset); + if (rtsock != -1) + FD_SET(rtsock, &fdset); + + if (select(32, &fdset, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) == -1) { + warn("select failed"); + continue; + } + + if (rtsock != -1 && FD_ISSET(rtsock, &fdset)) { + struct if_msghdr ifm; + + if ((pktlen = read(rtsock, &ifm, sizeof(ifm))) == -1) { + warn("read from routing socket failed"); + continue; + } + if (ifm.ifm_version != RTM_VERSION) { + if (verbose) + warnx("routing message version %d " + "not understood", ifm.ifm_version); + continue; + } + if (ifm.ifm_type != RTM_IFINFO || + ifm.ifm_index != ifindex) + continue; + if (mtu != ifm.ifm_data.ifi_mtu) { + mtu = ifm.ifm_data.ifi_mtu; + maxmss = MAXMSS(mtu); + if (verbose) + fprintf(stderr, "Maximum MSS: %u\n", maxmss); + } + } + + if (FD_ISSET(s, &fdset)) { + sinlen = sizeof(sin); + + if ((pktlen = recvfrom(s, pkt, sizeof(pkt), 0, + (struct sockaddr *)&sin, &sinlen)) == -1) + if (errno != EINTR) { + warn("read from divert socket failed"); + continue; + } + + hlen = pip->ip_hl << 2; + + /*- + * Check for MSS option only for outgoing + * TCP packets with zero fragment offset + * and correct total and header lengths. + */ + if ((both || sin.sin_addr.s_addr == INADDR_ANY) && + pip->ip_p == IPPROTO_TCP && + (ntohs(pip->ip_off) & IP_OFFMASK) == 0 && + ntohs(pip->ip_len) == pktlen && + hlen <= pktlen && + pktlen - hlen >= sizeof(struct tcphdr)) + correct_mss((struct tcphdr *)(pkt + hlen), + pktlen - hlen, maxmss); + + if (sendto(s, pkt, pktlen, 0, + (struct sockaddr *)&sin, sinlen) == -1) + warn("write to divert socket failed"); + } + } +} + + +/*- + * The following macro is used to update an + * internet checksum. "acc" is a 32-bit + * accumulation of all the changes to the + * checksum (adding in old 16-bit words and + * subtracting out new words), and "cksum" + * is the checksum value to be updated. + */ +#define ADJUST_CHECKSUM(acc, cksum) { \ + acc += cksum; \ + if (acc < 0) { \ + acc = -acc; \ + acc = (acc >> 16) + (acc & 0xffff); \ + acc += acc >> 16; \ + cksum = (u_short) ~acc; \ + } else { \ + acc = (acc >> 16) + (acc & 0xffff); \ + acc += acc >> 16; \ + cksum = (u_short) acc; \ + } \ +} + + +void +correct_mss(struct tcphdr *tc, ssize_t pktlen, u_int16_t maxmss) +{ + int hlen, olen, optlen; + u_char *opt; + u_int16_t *mss; + int accumulate; + + hlen = tc->th_off << 2; + + /* Invalid header length or header without options. */ + if (hlen <= sizeof(struct tcphdr) || hlen > pktlen) + return; + + /* MSS option only allowed within SYN packets. */ + if (!(tc->th_flags & TH_SYN)) + return; + + for (olen = hlen - sizeof(struct tcphdr), opt = (u_char *)(tc + 1); + olen > 0; olen -= optlen, opt += optlen) { + if (*opt == TCPOPT_EOL) + break; + else if (*opt == TCPOPT_NOP) + optlen = 1; + else { + optlen = *(opt + 1); + if (optlen <= 0 || optlen > olen) + break; + if (*opt == TCPOPT_MAXSEG) { + if (optlen != TCPOLEN_MAXSEG) + continue; + mss = (u_int16_t *)(opt + 2); + if (ntohs(*mss) > maxmss) { + if (verbose) + fprintf(stderr, + "MSS: %u -> %u\n", + ntohs(*mss), maxmss); + accumulate = *mss; + *mss = htons(maxmss); + accumulate -= *mss; + ADJUST_CHECKSUM(accumulate, tc->th_sum); + } + } + } + } +} + + +static int +if_mtu(const char *ifn, u_long *mtu) +{ + size_t needed; + int mib[6]; + char *buf, *lim, *next; + struct if_msghdr *ifm; + struct sockaddr_dl *sdl; + int ifindex; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_INET; /* Only IP addresses please. */ + mib[4] = NET_RT_IFLIST; + mib[5] = 0; /* List all interfaces. */ +/* + * Get interface data. + */ + if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) + err(1, "iflist-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + errx(1, "malloc failed"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) + err(1, "iflist-sysctl-get"); + lim = buf + needed; +/* + * Loop through interfaces until one with + * given name is found. This is done to + * find correct interface index for routing + * message processing. + */ + ifindex = 0; + next = buf; + while (next < lim) { + ifm = (struct if_msghdr *)next; + next += ifm->ifm_msglen; + if (ifm->ifm_version != RTM_VERSION) { + if (verbose) + warnx("routing message version %d " + "not understood", ifm->ifm_version); + continue; + } + if (ifm->ifm_type == RTM_IFINFO) { + sdl = (struct sockaddr_dl *)(ifm + 1); + if (strlen(ifn) == sdl->sdl_nlen && + strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) { + *mtu = ifm->ifm_data.ifi_mtu; + ifindex = ifm->ifm_index; + break; + } + } + } + free(buf); + return (ifindex); +} + + +static void +sigterm_handler(int sig) +{ + + (void)unlink(pidfilename); + exit(0); +} + + +void +usage(void) +{ + + fprintf(stderr, "usage: tcpmssd [-v] -p port {-i iface | -m mtu}\n"); + exit(1); +} Property changes on: head/net/tcpmssd/files/tcpmssd.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/net-mgmt/nagios-check_cpu_usage/src/check_cpu_usage =================================================================== --- head/net-mgmt/nagios-check_cpu_usage/src/check_cpu_usage (revision 404856) +++ head/net-mgmt/nagios-check_cpu_usage/src/check_cpu_usage (nonexistent) @@ -1,120 +0,0 @@ -#!/bin/sh -# -# Plugin return codes -# -# OK = 0 -# The plugin was able to check the service and it appeared to be -# functioning properly -# -# Warning = 1 -# The plugin was able to check the service, but it appeared to be above -# some "warning" threshold or did not appear to be working properly -# -# Critical = 2 -# The plugin detected that either the service was not running or it was -# above some "critical" threshold -# -# Unknown = 3 -# Invalid command line arguments were supplied to the plugin or low-level -# failures internal to the plugin (such as unable to fork, or open a tcp -# socket) that prevent it from performing the specified operation. -# Higher-level errors (such as name resolution errors, socket timeouts, etc) -# are outside of the control of plugins and should generally NOT be reported -# as UNKNOWN states. - -# default path -PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin - -ST_OK=0 -ST_WR=1 -ST_CR=2 -ST_UN=3 - -# Plugin name -PROGNAME=`basename $0` - -# Version -VERSION="Version 1.0" - -# Author -AUTHOR="Majo Jamrich" - - -print_version() { - echo "$PROGNAME $VERSION $1" -} - -print_help() { - print_version "($AUTHOR)" - echo "" - echo "$PROGNAME is a Nagios plugin to check CPU utilization." - echo "" - echo "Options:" - echo "" - echo "--warning | -w" - echo "--critical | -c" - echo "--help | --usage" - echo "" - echo "Usage:" - echo "./check_cpu_usage -w 80 -c 100" - echo "" - exit $ST_UN -} - -case "$1" in - --help|-h|--usage|-u) - print_help - exit $ST_UN - ;; - --warning|-w) - host=$2 - ;; - --critical|-c) - host=$2 - ;; - -V) - print_version - exit - ;; - *) - echo "Unknown argument: $1" - echo "For more information please try -h or --help!" - exit $ST_UN - ;; -esac -shift - -if [ `uname` != "FreeBSD" ]; then - echo "This plugin is only for FreeBSD." -fi - -if [ -z $1 ] || [ -z $3 ]; then - print_help - exit $ST_UN -fi - -if [ "$1" -ge "$3" ]; then - echo "Warning value must be greater than critical value!" - exit $ST_UN -fi - -warn=$1 -crit=$3 - -cpu_all=$( vmstat -c 2 -n 0 | tail -n 1 | awk '{print $15 " " $16 " " $17}' ) -cpu_user=$( echo $cpu_all | awk '{print $1}') -cpu_sys=$( echo $cpu_all | awk '{print $2}') -cpu_idle=$( echo $cpu_all | awk '{print $3}') -cpu_usage=$(( 100 - $cpu_idle )) -perfdata="cpu_usage=$cpu_usage%;$warn;$crit; cpu_user=$cpu_user%; cpu_system=$cpu_sys%;" - -if [ $( echo "$cpu_usage>$1" | bc ) -gt 0 ] && [ $( echo "$cpu_usage<$3" | bc ) -gt 0 ]; then - echo "WARNING - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" - exit $ST_WR -elif [ $( echo "$cpu_usage>$3" | bc ) -gt 0 ]; then - echo "CRITICAL - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" - exit $ST_CR -else - echo "OK - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" - exit $ST_OK -fi Property changes on: head/net-mgmt/nagios-check_cpu_usage/src/check_cpu_usage ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/net-mgmt/nagios-check_cpu_usage/Makefile =================================================================== --- head/net-mgmt/nagios-check_cpu_usage/Makefile (revision 404856) +++ head/net-mgmt/nagios-check_cpu_usage/Makefile (revision 404857) @@ -1,22 +1,23 @@ # Created by: jamrich.majo@gmail.com # $FreeBSD$ PORTNAME= nagios-check_cpu_usage PORTVERSION= 1.0 CATEGORIES= net-mgmt MASTER_SITES= # none DISTFILES= # none MAINTAINER= ports@FreeBSD.org COMMENT= Nagios plug-in to check CPU usage NO_BUILD= yes +NO_ARCH= yes PLIST_FILES= libexec/nagios/check_cpu_usage do-install: - ${MKDIR} ${STAGEDIR}${PREFIX}/libexec/nagios - ${INSTALL_SCRIPT} ${.CURDIR}/src/check_cpu_usage \ + @${MKDIR} ${STAGEDIR}${PREFIX}/libexec/nagios + ${INSTALL_SCRIPT} ${FILESDIR}/check_cpu_usage \ ${STAGEDIR}${PREFIX}/libexec/nagios .include Index: head/net-mgmt/nagios-check_cpu_usage/files/check_cpu_usage =================================================================== --- head/net-mgmt/nagios-check_cpu_usage/files/check_cpu_usage (nonexistent) +++ head/net-mgmt/nagios-check_cpu_usage/files/check_cpu_usage (revision 404857) @@ -0,0 +1,120 @@ +#!/bin/sh +# +# Plugin return codes +# +# OK = 0 +# The plugin was able to check the service and it appeared to be +# functioning properly +# +# Warning = 1 +# The plugin was able to check the service, but it appeared to be above +# some "warning" threshold or did not appear to be working properly +# +# Critical = 2 +# The plugin detected that either the service was not running or it was +# above some "critical" threshold +# +# Unknown = 3 +# Invalid command line arguments were supplied to the plugin or low-level +# failures internal to the plugin (such as unable to fork, or open a tcp +# socket) that prevent it from performing the specified operation. +# Higher-level errors (such as name resolution errors, socket timeouts, etc) +# are outside of the control of plugins and should generally NOT be reported +# as UNKNOWN states. + +# default path +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin + +ST_OK=0 +ST_WR=1 +ST_CR=2 +ST_UN=3 + +# Plugin name +PROGNAME=`basename $0` + +# Version +VERSION="Version 1.0" + +# Author +AUTHOR="Majo Jamrich" + + +print_version() { + echo "$PROGNAME $VERSION $1" +} + +print_help() { + print_version "($AUTHOR)" + echo "" + echo "$PROGNAME is a Nagios plugin to check CPU utilization." + echo "" + echo "Options:" + echo "" + echo "--warning | -w" + echo "--critical | -c" + echo "--help | --usage" + echo "" + echo "Usage:" + echo "./check_cpu_usage -w 80 -c 100" + echo "" + exit $ST_UN +} + +case "$1" in + --help|-h|--usage|-u) + print_help + exit $ST_UN + ;; + --warning|-w) + host=$2 + ;; + --critical|-c) + host=$2 + ;; + -V) + print_version + exit + ;; + *) + echo "Unknown argument: $1" + echo "For more information please try -h or --help!" + exit $ST_UN + ;; +esac +shift + +if [ `uname` != "FreeBSD" ]; then + echo "This plugin is only for FreeBSD." +fi + +if [ -z $1 ] || [ -z $3 ]; then + print_help + exit $ST_UN +fi + +if [ "$1" -ge "$3" ]; then + echo "Warning value must be greater than critical value!" + exit $ST_UN +fi + +warn=$1 +crit=$3 + +cpu_all=$( vmstat -c 2 -n 0 | tail -n 1 | awk '{print $15 " " $16 " " $17}' ) +cpu_user=$( echo $cpu_all | awk '{print $1}') +cpu_sys=$( echo $cpu_all | awk '{print $2}') +cpu_idle=$( echo $cpu_all | awk '{print $3}') +cpu_usage=$(( 100 - $cpu_idle )) +perfdata="cpu_usage=$cpu_usage%;$warn;$crit; cpu_user=$cpu_user%; cpu_system=$cpu_sys%;" + +if [ $( echo "$cpu_usage>$1" | bc ) -gt 0 ] && [ $( echo "$cpu_usage<$3" | bc ) -gt 0 ]; then + echo "WARNING - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" + exit $ST_WR +elif [ $( echo "$cpu_usage>$3" | bc ) -gt 0 ]; then + echo "CRITICAL - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" + exit $ST_CR +else + echo "OK - CPU usage is $cpu_usage% for server `hostname`. |$perfdata" + exit $ST_OK +fi Property changes on: head/net-mgmt/nagios-check_cpu_usage/files/check_cpu_usage ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/net-mgmt/nagios-check_hdd_health/src/check_hdd_health =================================================================== --- head/net-mgmt/nagios-check_hdd_health/src/check_hdd_health (revision 404856) +++ head/net-mgmt/nagios-check_hdd_health/src/check_hdd_health (nonexistent) @@ -1,178 +0,0 @@ -#!/bin/sh -# -PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin - -ST_OK=0 -ST_WR=1 -ST_CR=2 -ST_UN=3 - -smartctl=$(which smartctl) - -## Smartmontools -SMT=Smartmontools - -# Plugin name -PROGNAME=`basename $0` - -# Version -VERSION="Version 1.1" - -# Author -AUTHOR="Marian Jamrich" - -TMPFILE=/tmp/smart.nagios.$$ - -# Clean up when done or when aborting -trap "rm -f ${TMPFILE}" 0 1 2 3 15 - -print_version() { - echo "Nagios-$PROGNAME ($VERSION)" -} - -mini_help() { - echo "Usage $0 --device $device --without [src rsc rec cps ou]" -} - -print_help() { - clear; - echo "**************************************************************************************" - echo "* $PROGNAME $VERSION $1""($AUTHOR) (2011) *" - echo "**************************************************************************************" - echo "This is Nagios plugin to check HDD health from S.M.A.R.T. by Smartmontools." - echo ' -The S.M.A.R.T. attributes are specific properties (parameters) of various parts of a disk. -S.M.A.R.T. uses attributes to monitor the disk condition and to analyze its reliability. - -Script check HDD from S.M.A.R.T with the following properties (if your HDD supports it): - -** Spin Retry Count (src) ** -Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the -condition that the first attempt was unsuccessful). A decrease of this attribute value is a sign of problems in the hard disk mechanical subsystem. - -** Reallocated Sector Count (rsc) ** -Count of reallocated sectors. When the hard drive finds a read/write/verification error, it marks this sector as "reallocated" and transfers data to a -special reserved area (spare area). This process is also known as remapping and "reallocated" sectors are called remaps. This is why, on a modern hard -disks, you can not see "bad blocks" while testing the surface - all bad blocks are hidden in reallocated sectors. - -** Reallocated Event Count (rec) ** -Count of remap operations (transferring data from a bad sector to a special reserved disk area - spare area). The raw value of this attribute shows the -total number of attempts to transfer data from reallocated sectors to a spare area. Unsuccessful attempts are counted as well as successful. - -** Current Pending Sector (cps) ** -Current count of unstable sectors (waiting for remapping). The raw value of this attribute indicates the total number of sectors waiting for remapping. -Later, when some of these sectors are read successfully, the value is decreased. If errors still occur when reading some sector, the hard drive will try -to restore the data, transfer it to the reserved disk area (spare area) and mark this sector as remapped. If this attribute value remains at zero, it -indicates that the quality of the corresponding surface area is low. - -** Offline Uncorrectable (ou) ** -Quantity of uncorrectable errors. The raw value of this attribute indicates the total number of uncorrectable errors when reading/writing a sector. -A rise in the value of this attribute indicates that there are evident defects of the disk surface and/or there are problems in the hard disk drive -mechanical subsystem. - -** Total health test (pass) ** -This is test provided by Smartmontools. If total disk state is "health", Smartmontools marked as "PASSED". - ' - echo "Nagios states:" - echo - echo "OK - if all values are \"0\"." - echo "Warning - if one or both values \"Spin Retry Count\" and \"Reallocated Event Count\" is between the values 1 to 9." - echo "Critical - if some value is greater than \"0\" except \"Spin Retry Count (>=10)\" and \"Reallocated Event Count (>=10)\"." - echo -e "\n---------------------------------------------------------------------" - echo "Usage:" - echo "$0 --device ad0 [ --without [src rsc rec cps ou]]" - echo "---------------------------------------------------------------------" - exit $ST_UN -} - -case "$1" in - --help|-h|--usage|-u) - print_help - exit $ST_UN - ;; - -d | --device) - device=$2 - ;; - -v) - print_version - exit $ST_UN - ;; - *) - echo "Unknown argument: $1" - echo "For more information please try -h or --help!" - exit $ST_UN - ;; -esac -shift - -test -z $device && echo -e "\nYou forgot to define device! Please try \"-h or --help\" to help." && exit $ST_UN -test `uname` != "FreeBSD" && echo "This plugin is only for FreeBSD." && exit $ST_UN - -format_device=`echo $device | grep -w 'dev'` -if [ -z $format_device ]; then - device=/dev/`echo $device` -fi - -if [ ! -e $device ]; then - echo "Unknown device \"$device\"!" - exit $ST_UN -fi - -if [ -z $smartctl ]; then - echo -e "\nYou don't have installed $SMT. Please install it from 'http://smartmontools.sourceforge.net' or pkg_add -r \"smartmontools\"..." - exit $ST_UN -fi - -$smartctl -a $device > ${TMPFILE} -SMART_SUPPORT=`awk '/SMART support is/ {print $4}' ${TMPFILE} | tail -n 1` - -if [ "${SMART_SUPPORT}" = "Unavailable" ]; then - echo -e "\nS.M.A.R.T support is unavailable for $device !!! You should enable it \"smartctl -s on $device\"." - exit $ST_UN -elif [ "${SMART_SUPPORT}" != "Enabled" ]; then - echo -e "\nMaybe you don't have enabled S.M.A.R.T support in $SMT! Please type \"smartctl -s on $device\" that you have it turned on, or device does not support S.M.A.R.T function." - exit $ST_UN -fi - -## start S.M.A.R.T test and set variables -src=`awk '/Spin_Retry_Count/ {print $10}' ${TMPFILE} ` -rsc=`awk '/Reallocated_Sector_Ct/ {print $10}' ${TMPFILE} ` -rec=`awk '/Reallocated_Event_Count/ {print $10}' ${TMPFILE} ` -cps=`awk '/Current_Pending_Sector/ {print $10}' ${TMPFILE} ` -ou=`awk '/Offline_Uncorrectable/ {print $10}' ${TMPFILE} ` -pass=`awk -F\: '/test result/ { if ( $2 == " PASSED") print "PASSED"; else print "FAILED" }' ${TMPFILE} ` - -## if one or more S.M.A.R.T function is not supported by your HDD, then you define --without variable and then value is set automatically to "0" -args=`getopt w:without: $*` -for arg; do - case "$arg" in - src) src=0;; - rsc) rsc=0;; - rec) rec=0;; - cps) cps=0;; - ou) ou=0;; - esac -done - -# test if your HDD support all this parameters: -[ -z "$src" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Spin Retry Count". Please try \"--without src\"." && mini_help && exit $ST_UN -[ -z "$rsc" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Reallocated Sector Ct". Please try \"--without rsc\"." && mini_help && exit $ST_UN -[ -z "$rec" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Reallocated Event Count". Please try --without rec." && mini_help && exit $ST_UN -[ -z "$cps" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Current Pending Sector". Please try --without cps." && mini_help && exit $ST_UN -[ -z "$ou" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Offline Uncorrectable". Please try \"--without ou\"." && mini_help && exit $ST_UN - -perfdata="smart=src=$src; rsc=$rsc; rec=$rec; cps=$cps; ou=$ou; pass=$pass" - -############################################################ -##### finally run test, print result and set exit code ##### -############################################################ -if [ $src -eq 0 ] && [ $rsc -eq 0 ] && [ $rec -eq 0 ] && [ $cps -eq 0 ] && [ $ou -eq 0 ] && [ "$pass" = "PASSED" ]; then - echo "OK - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALTH_STATUS=$pass for $device. |${perfdata}" - exit $ST_OK -elif [ $src -gt 1 -a $src -lt 10 ] && [ $rsc -gt 0 ] && [ $rec -gt 1 -a $rec -lt 10 ] && [ $cps -eq 0 ] && [ $ou -eq 0 ] && [ "$pass" = "PASSED" ]; then - echo "WARNING - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALTH_STATUS=$pass for $device. |${perfdata}" - exit $ST_WR -else - echo "CRITICAL - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALT_STATUS=$pass for $device. |${perfdata}" - exit $ST_CR -fi Property changes on: head/net-mgmt/nagios-check_hdd_health/src/check_hdd_health ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/net-mgmt/nagios-check_hdd_health/pkg-plist =================================================================== --- head/net-mgmt/nagios-check_hdd_health/pkg-plist (revision 404856) +++ head/net-mgmt/nagios-check_hdd_health/pkg-plist (nonexistent) @@ -1 +0,0 @@ -libexec/nagios/check_hdd_health Property changes on: head/net-mgmt/nagios-check_hdd_health/pkg-plist ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/net-mgmt/nagios-check_hdd_health/Makefile =================================================================== --- head/net-mgmt/nagios-check_hdd_health/Makefile (revision 404856) +++ head/net-mgmt/nagios-check_hdd_health/Makefile (revision 404857) @@ -1,21 +1,25 @@ # Created by: jamrich.majo@gmail.com # $FreeBSD$ PORTNAME= nagios-check_hdd_health PORTVERSION= 1.1 CATEGORIES= net-mgmt -MASTER_SITES= # No distfile -DISTFILES= # No distfile +MASTER_SITES= # none +DISTFILES= # none MAINTAINER= ports@FreeBSD.org COMMENT= Nagios plug-in to check HDD health from S.M.A.R.T RUN_DEPENDS= smartmontools>=0:${PORTSDIR}/sysutils/smartmontools NO_BUILD= yes +NO_ARCH= yes +PLIST_FILES= libexec/nagios/check_hdd_health + do-install: @${MKDIR} ${STAGEDIR}${PREFIX}/libexec/nagios - @${INSTALL_SCRIPT} ${.CURDIR}/src/check_hdd_health ${STAGEDIR}${PREFIX}/libexec/nagios + ${INSTALL_SCRIPT} ${FILESDIR}/check_hdd_health \ + ${STAGEDIR}${PREFIX}/libexec/nagios .include Index: head/net-mgmt/nagios-check_hdd_health/files/check_hdd_health =================================================================== --- head/net-mgmt/nagios-check_hdd_health/files/check_hdd_health (nonexistent) +++ head/net-mgmt/nagios-check_hdd_health/files/check_hdd_health (revision 404857) @@ -0,0 +1,178 @@ +#!/bin/sh +# +PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin + +ST_OK=0 +ST_WR=1 +ST_CR=2 +ST_UN=3 + +smartctl=$(which smartctl) + +## Smartmontools +SMT=Smartmontools + +# Plugin name +PROGNAME=`basename $0` + +# Version +VERSION="Version 1.1" + +# Author +AUTHOR="Marian Jamrich" + +TMPFILE=/tmp/smart.nagios.$$ + +# Clean up when done or when aborting +trap "rm -f ${TMPFILE}" 0 1 2 3 15 + +print_version() { + echo "Nagios-$PROGNAME ($VERSION)" +} + +mini_help() { + echo "Usage $0 --device $device --without [src rsc rec cps ou]" +} + +print_help() { + clear; + echo "**************************************************************************************" + echo "* $PROGNAME $VERSION $1""($AUTHOR) (2011) *" + echo "**************************************************************************************" + echo "This is Nagios plugin to check HDD health from S.M.A.R.T. by Smartmontools." + echo ' +The S.M.A.R.T. attributes are specific properties (parameters) of various parts of a disk. +S.M.A.R.T. uses attributes to monitor the disk condition and to analyze its reliability. + +Script check HDD from S.M.A.R.T with the following properties (if your HDD supports it): + +** Spin Retry Count (src) ** +Count of retry of spin start attempts. This attribute stores a total count of the spin start attempts to reach the fully operational speed (under the +condition that the first attempt was unsuccessful). A decrease of this attribute value is a sign of problems in the hard disk mechanical subsystem. + +** Reallocated Sector Count (rsc) ** +Count of reallocated sectors. When the hard drive finds a read/write/verification error, it marks this sector as "reallocated" and transfers data to a +special reserved area (spare area). This process is also known as remapping and "reallocated" sectors are called remaps. This is why, on a modern hard +disks, you can not see "bad blocks" while testing the surface - all bad blocks are hidden in reallocated sectors. + +** Reallocated Event Count (rec) ** +Count of remap operations (transferring data from a bad sector to a special reserved disk area - spare area). The raw value of this attribute shows the +total number of attempts to transfer data from reallocated sectors to a spare area. Unsuccessful attempts are counted as well as successful. + +** Current Pending Sector (cps) ** +Current count of unstable sectors (waiting for remapping). The raw value of this attribute indicates the total number of sectors waiting for remapping. +Later, when some of these sectors are read successfully, the value is decreased. If errors still occur when reading some sector, the hard drive will try +to restore the data, transfer it to the reserved disk area (spare area) and mark this sector as remapped. If this attribute value remains at zero, it +indicates that the quality of the corresponding surface area is low. + +** Offline Uncorrectable (ou) ** +Quantity of uncorrectable errors. The raw value of this attribute indicates the total number of uncorrectable errors when reading/writing a sector. +A rise in the value of this attribute indicates that there are evident defects of the disk surface and/or there are problems in the hard disk drive +mechanical subsystem. + +** Total health test (pass) ** +This is test provided by Smartmontools. If total disk state is "health", Smartmontools marked as "PASSED". + ' + echo "Nagios states:" + echo + echo "OK - if all values are \"0\"." + echo "Warning - if one or both values \"Spin Retry Count\" and \"Reallocated Event Count\" is between the values 1 to 9." + echo "Critical - if some value is greater than \"0\" except \"Spin Retry Count (>=10)\" and \"Reallocated Event Count (>=10)\"." + echo -e "\n---------------------------------------------------------------------" + echo "Usage:" + echo "$0 --device ad0 [ --without [src rsc rec cps ou]]" + echo "---------------------------------------------------------------------" + exit $ST_UN +} + +case "$1" in + --help|-h|--usage|-u) + print_help + exit $ST_UN + ;; + -d | --device) + device=$2 + ;; + -v) + print_version + exit $ST_UN + ;; + *) + echo "Unknown argument: $1" + echo "For more information please try -h or --help!" + exit $ST_UN + ;; +esac +shift + +test -z $device && echo -e "\nYou forgot to define device! Please try \"-h or --help\" to help." && exit $ST_UN +test `uname` != "FreeBSD" && echo "This plugin is only for FreeBSD." && exit $ST_UN + +format_device=`echo $device | grep -w 'dev'` +if [ -z $format_device ]; then + device=/dev/`echo $device` +fi + +if [ ! -e $device ]; then + echo "Unknown device \"$device\"!" + exit $ST_UN +fi + +if [ -z $smartctl ]; then + echo -e "\nYou don't have installed $SMT. Please install it from 'http://smartmontools.sourceforge.net' or pkg_add -r \"smartmontools\"..." + exit $ST_UN +fi + +$smartctl -a $device > ${TMPFILE} +SMART_SUPPORT=`awk '/SMART support is/ {print $4}' ${TMPFILE} | tail -n 1` + +if [ "${SMART_SUPPORT}" = "Unavailable" ]; then + echo -e "\nS.M.A.R.T support is unavailable for $device !!! You should enable it \"smartctl -s on $device\"." + exit $ST_UN +elif [ "${SMART_SUPPORT}" != "Enabled" ]; then + echo -e "\nMaybe you don't have enabled S.M.A.R.T support in $SMT! Please type \"smartctl -s on $device\" that you have it turned on, or device does not support S.M.A.R.T function." + exit $ST_UN +fi + +## start S.M.A.R.T test and set variables +src=`awk '/Spin_Retry_Count/ {print $10}' ${TMPFILE} ` +rsc=`awk '/Reallocated_Sector_Ct/ {print $10}' ${TMPFILE} ` +rec=`awk '/Reallocated_Event_Count/ {print $10}' ${TMPFILE} ` +cps=`awk '/Current_Pending_Sector/ {print $10}' ${TMPFILE} ` +ou=`awk '/Offline_Uncorrectable/ {print $10}' ${TMPFILE} ` +pass=`awk -F\: '/test result/ { if ( $2 == " PASSED") print "PASSED"; else print "FAILED" }' ${TMPFILE} ` + +## if one or more S.M.A.R.T function is not supported by your HDD, then you define --without variable and then value is set automatically to "0" +args=`getopt w:without: $*` +for arg; do + case "$arg" in + src) src=0;; + rsc) rsc=0;; + rec) rec=0;; + cps) cps=0;; + ou) ou=0;; + esac +done + +# test if your HDD support all this parameters: +[ -z "$src" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Spin Retry Count". Please try \"--without src\"." && mini_help && exit $ST_UN +[ -z "$rsc" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Reallocated Sector Ct". Please try \"--without rsc\"." && mini_help && exit $ST_UN +[ -z "$rec" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Reallocated Event Count". Please try --without rec." && mini_help && exit $ST_UN +[ -z "$cps" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Current Pending Sector". Please try --without cps." && mini_help && exit $ST_UN +[ -z "$ou" ] && echo -e "***********\n** ERROR **\n***********\n${device} don't support "Offline Uncorrectable". Please try \"--without ou\"." && mini_help && exit $ST_UN + +perfdata="smart=src=$src; rsc=$rsc; rec=$rec; cps=$cps; ou=$ou; pass=$pass" + +############################################################ +##### finally run test, print result and set exit code ##### +############################################################ +if [ $src -eq 0 ] && [ $rsc -eq 0 ] && [ $rec -eq 0 ] && [ $cps -eq 0 ] && [ $ou -eq 0 ] && [ "$pass" = "PASSED" ]; then + echo "OK - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALTH_STATUS=$pass for $device. |${perfdata}" + exit $ST_OK +elif [ $src -gt 1 -a $src -lt 10 ] && [ $rsc -gt 0 ] && [ $rec -gt 1 -a $rec -lt 10 ] && [ $cps -eq 0 ] && [ $ou -eq 0 ] && [ "$pass" = "PASSED" ]; then + echo "WARNING - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALTH_STATUS=$pass for $device. |${perfdata}" + exit $ST_WR +else + echo "CRITICAL - HDD S.M.A.R.T health: src=$src, rsc=$rsc, rec=$rec, cps=$cps, ou=$ou, HEALT_STATUS=$pass for $device. |${perfdata}" + exit $ST_CR +fi Property changes on: head/net-mgmt/nagios-check_hdd_health/files/check_hdd_health ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/security/safesh/src/safesh.1 =================================================================== --- head/security/safesh/src/safesh.1 (revision 404856) +++ head/security/safesh/src/safesh.1 (nonexistent) @@ -1,546 +0,0 @@ -.\"- -.\" Copyright (c) 2002 Eivind Eklund -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer -.\" in this position and unchanged. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 26, 2002 -.Dt SAFESH 1 -.Sh NAME -.Nm safesh -.Nd safe key manager for OpenSSH -.Sh SYNOPSIS -.Nm -.Oo Ar user@ Oc Ns Ar host -.Oo -.Fl Fl -.Ar ssh-parameters ... -.Oc -.Nm safeshinstall -.Oo Ar user@ Oc Ns Ar host -.Nm cvs-safesh -.Oo Ar user@ Oc Ns Ar host -.Op Ar command -.Nm scpsh -.Oo Ar user@ Oc Ns Ar host -.Sh DESCRIPTION -NOTE: This text often refers to -.Va $VARIABLE -in description. -What each of the references will be replaced with when -.Nm -runs is described at the end of the manpage. -.Pp -The -.Nm -utility -automatically creates one DSA key (called an identity) for each host you -connect to, and stores this in a separate agent for each host. -It is also capable of adding keys for other hosts to this agent, so you can -use it for restricted forwarding of authentication. -Because each host uses its own -.Xr ssh-agent 1 , -the hosts you forward authentication to can only get at the authentication for -the hosts you specifically say it should be able to get at. -.Pp -When run, -.Nm : -.Bl -enum -.It -Normalizes the hostname you are talking about, using the -.Pa $HOME/.safesh/map -file. -.It -Checks if the user and host has an SSH DSA key in -.Pa $HOME/.safesh , -and creates one using -.Xr ssh-keygen 1 -if it does not. -The DSA key is stored in -.Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id . -You will be asked for a passphrase when the key is created. -Note that if you use the same passphrase for all -.Nm -keys, you will only be asked for the passphrase once per host you connect to. -If you use different passphrases, you will be asked once per forwarded key -for each host you connect to (after a machine startup). -.It -Checks if you have the -.Xr ssh-agent 1 -for this host running, and starts it if not. -.It -Checks what keys you are supposed to have active when connecting to this host -(the key for the host and any keys listed in -.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys ) , -and which of these are missing from the active agent. -.It -If any identities were missing from the agent, it executes -.Xr ssh-add 1 -to add them to the agent. -.It -Executes -.Xr ssh 1 -with either -.Ar $USER@$HOST -or the extra command line supplied by the user. -.El -.Sh BASIC CONCEPT DESCRIPTION -The -.Nm -utility -is an authentication manager for OpenSSH. -It is an attempt at making it easy to use the built-in authentication features -of OpenSSH securely. -By default, the SSH security model is that all hosts the -user connects to are trusted, and are given complete access, including the -ability to authenticate as the user towards other hosts if the user is running -.Xr ssh-agent 1 . -OpenSSH has improved this security model somewhat by not forwarding SSH -authentication by default, but still allows the host that you connect to -to grab your credentials and authenticate as you to anybody else when you -do authentication forwarding to it. -.Sh SIMPLE HOWTO -Starting to make use of -.Nm -is trivial: -.Bl -enum -.It -Do -.Dq Li "safeshinstall <[user@]hostname>" . -.Pp -This will ask for a passphrase (three times), create a directory -.Pa $HOME/.safesh/@-22 , -which contains authentication -data for your user at -.Aq Ar hostname , -and add the contents of -.Pa $HOME/.safesh/@-22/id_dsa.pub -to -.Pa $HOME/.ssh/authorized_keys2 -on the host you connect to. -The latter will result in -.Xr ssh 1 -asking for authentication in the fashion you already use (most likely by -asking for your password). -.It -Log in with -.Dq Li "safesh " -from now on. -.Pp -This will ask you for a passphrase if you have not logged into that host this -session, and otherwise just let right in. -.El -.Sh UTILITY COMMANDS -The -.Nm -utility -ships with two utility hacks to work around the fact that it is not a complete -.Xr ssh 1 -replacement, -.Nm scpsh -and -.Nm cvs-safesh . -.Pp -The -.Nm scpsh -utility -is for supporting use of -.Xr scp 1 -with -.Nm . -The -.Nm scpsh -.Oo Ar user@ Oc Ns Ar host -command -will start a new interactive shell (using the -.Ev SHELL -environment variable to determine which it should be), with the environment -variables for using -.Xr ssh-agent 1 -to authenticate to -.Oo Ar user@ Oc Ns Ar host -already set. -This allows use of -.Xr scp 1 -without having to type passwords to authenticate. -.Pp -The -.Nm cvs-safesh -utility -makes it easy to use -.Nm -along with -.Xr cvs 1 -and other programs that use -.Xr rsh 1 -or -.Xr ssh 1 -with the format -.Dq Li "ssh " -or -.Dq Li "ssh " . -To use with -.Xr cvs 1 , -just set -.Ev CVS_RSH -to -.Dq Li cvs-safesh -instead of -.Dq Li ssh . -.Sh FILES -.Bl -tag -width ".Pa $HOME/.safesh" -.It Pa $HOME/.safesh/ -Directory containing information for -.Nm . -.It Pa $HOME/.safesh/map -Mapping file for -.Nm , -describing how to map host names to their canonical form. -This is usually used to map short names to their long form. -The format of the file is one mapping per line, what it is mapped from as the -first word, what it is mapped to as the second. -.Pp -It is also possible to use this to map domain names to their safe form by having -the name of the host as the first parameter, and the name of the host with a -period -.Pq Ql .\& -at the end as the second parameter, -e.g., -.Dq Li freefall.freebsd.org freefall.freebsd.org. . -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/ -Directory with data for a particular hostname. -Automatically generated on first connect to a host with -.Nm . -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id -Private key for use to authenticate as -.Ar $USER@$HOST . -Automatically generated on first connect to a host with -.Nm . -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id.pub -Public key for use by -.Ar $HOST -to authenticate -.Ar $USER . -To connect to -.Ar $HOST -as -.Ar $USER -using -.Nm -without giving a password, add the contents of this file -to the end of -.Pa $HOME/.ssh/authorized_keys2 . -Automatically generated on first connect to a host with -.Nm . -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET -Private key for use when -.Ar $HOST -authenticates towards -.Ar $AUTHTARGET . -This is used in preference to -.Pa $HOME/.safesh/$AUTHTARGET/dsa_id -for authentication forwarding through -.Ar $HOST -to -.Ar $AUTHTARGET . -The file is only used if -.Ar $AUTHTARGET -is listed in -.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys . -This file is not generated automatically by -.Nm . -It is only present if you have generated it using -.Xr ssh-keygen 1 . -Note that it is usually more than useless (can pose a security risk) to copy a -key used for other authentication to this location. -.Pp -The use of explict authentication files for authentication forwarding is -primarily for protection against the case where the machine you run -.Nm -on is compromised. -Using this file, you can use a separate passphrase from the one used for the -key for connecting directly to -.Ar $AUTHTARGET ; -that key need not even exist. -By using IP restrictions in the -.Pa authorized_keys -file for the key, you can make -sure that the host -.Nm -runs on cannot connect to -.Ar $AUTHTARGET -using the authentication forwarding -key. -The use of a separate forwarding key can also be used in combination with a -modified SSH to log which key was used where, and thus track key propagation. -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET.pub -Public key corresponding to the private key described above. -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys -List of extra keys to make available for this host. -Each line in the file is first attempted matched against the host/user/port -database in -.Pa $HOME/.safesh/ . -Username and/or port is added if just the hostname is specified -.Pa extra_keys , -and the hostname is always normalized using the map file. -If a key exists in -.Pa $HOME/.safesh/ , -.Nm -attempts to add that. -Otherwise, it first tries to look for the line as a file relative to -.Pa / , -then relative to -.Pa $HOME . -If it does not find either of these, -.Nm -will exit with an error message. -If it finds one, it will add it using -.Xr ssh-add 1 . -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.sh -Bourne shell (see -.Xr sh 1 , -.Xr bash 1 , -.Xr zsh 1 ) -script for setting up the environment variables for a particular -.Xr ssh-agent 1 -process used for this host. -Only valid if -.Nm -has been run against that host as this user since the machine -.Nm -runs on was last booted. -Note that this file must be source'd, not just run as a shell script. -.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.csh -CSH (see -.Xr csh 1 , -.Xr tcsh 1 ) -script for setting up the environment variables for a particular -.Xr ssh-agent 1 -process used for this host. -Only valid if -.Nm -has been run against that host as this user since the machine -.Nm -runs on was last booted. -Note that this file must be source'd, not just run as a shell script. -.El -.Sh AUTHORS -The -.Nm -utility -was written by -.An Eivind Eklund Aq eivind@FreeBSD.org . -.Sh SEE ALSO -.Xr ssh 1 , -.Xr ssh-add 1 , -.Xr ssh-agent 1 , -.Xr ssh-keygen 1 -.Sh KNOWN ISSUES -The -.Nm -utility -does not handle whitespace in filenames specified in -.Pa extra_keys -correctly. -.Pp -The -.Xr ssh-agent 1 -processes that are started by -.Nm -will hang around until next reboot unless -you put the -.Dq Li "killall ssh-agent" -command in -.Pa .logout -or similar. -This allows any login to your account to use your authentication towards -machines you have connected to (including anybody with root on the box), -persisting after you log out. -You must always assume that root can grab your authentication at the moment -you run do it, so this is only an issue in that the authentication stays -available longer. -This is not resolvable without rewriting -.Xr ssh-agent 1 . -.Sh MISSING FEATURES -.Bl -tag -width 4n -.It Em Two-step secure SSH with an untrusted host in the middle -It is possible to use the port forwarding capability of -.Xr ssh 1 -to forward -authentication through another server, without allowing the other server to -indepently authenticate to a third party, and without allowing it to see -what is going on in your connection. -This is based on just forwarding a tunnel through the untrusted host, and -doing direct authentication to the server on the other side. -With the present version of OpenSSH, this has the problem of leaving the -actual port forwarding open while the tunnel is open, allowing other users to -set up their own tunnels, and weakening another side of the security model. -.It Em Read out fingerprints -The -.Nm -utility -should make it trivial to retrieve the fingerprint for: -.Bl -enum -.It -The host it is running on. -.Pp -This must presently be done with -.Dq Li "ssh-keygen -l /etc/ssh/ssh_host_key.pub" -(to get the fingerprint for SSH 1) and -.Dq Li "ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key" -(for SSH 2). -.It -Other hosts, as registered in the -.Pa known_host -file on the host it is running -on. -.Pp -This must presently be done by manual inspection. -.El -.It Em Merge Pa known_hosts -The -.Nm -utility -should make it trivial to merge -.Pa known_hosts -and -.Pa known_hosts2 -with ones from -another host, including retrieving and uploading -.Pa known_hosts -as appropriate. -.It Em Manage Pa .ssh/authorized_keys2 -The -.Nm -utility -should be able to automatically remove keys from the -.Pa authorized_keys2 -file -on other machines, to make everything about the -.Nm -process self-contained. -.It Em Manage setup of key limitations -When managing -.Pa authorized_keys2 , -it is also reasonable to manage key limitation -in this. -IP restrictions -.Pq Qq Li from= -should be handled to make it easy to create setups -where the local machine does not have direct access to a target. -Command restrictions etc. would be good to have just for completeness. -.It Em Emulate the entire Xr ssh 1 Em syntax -Presently, the -.Nm -utility has a fairly weird syntax. -This is because it is a fairly quick hack, just made to be usable. -Later, it would be nice to rewrite it to be fully compatible with -.Xr ssh 1 . -This would allow use as a drop-in replacement. -.It Em Description of the trust/threat/security model -It would be nice to have a complete description of the normal SSH threat model -as well as the -.Nm -threat model, in order to make people fully conscious of their own model. -.It Em Emulate Xr scp 1 -The -.Xr scp 1 -utility -is very useful, and the only way to use it with -.Nm -at the moment is through a subshell created by -.Nm scpsh . -An ideal -.Nm -implementation would include wrapping of -.Xr scp 1 , -too. -.El -.Sh VARIABLE REPLACEMENT IN DESCRIPTIONS -.Bl -tag -width ".Va $AUTHTARGET" -.It Va $HOME -Path to your home directory. -.It Va $HOST -The name of the host you are running -.Nm -towards. -This is the machine you are -.Xr ssh 1 Ns 'ing -into. -.It Va $YOURHOST -The name of the host you are running -.Nm -on, as output by -.Xr hostname 1 . -This is the name of the machine you are -.Xr ssh 1 Ns 'ing -from. -The use of -.Va $YOURHOST -makes -.Nm -safe to use with NFS-mounted home directories. -.It Va $AUTHTARGET -The authentication target for an authentication forwarding. -This is -.Em not -the same as -.Va $HOST . -.Va $AUTHTARGET -is a machine you are -.Xr ssh 1 Ns 'ing -to -.Em from -.Va $HOST . -The format of -.Va $AUTHTARGET -is -.Sm off -.Ao Ar user Ac @ Ao Ar somehost Ac - Aq Ar someport , -.Sm on -where -.Aq Aq user -defaults to the username you run -.Nm -as, and -.Aq Aq someport -default to 22 (and it is not possible to set anything -else at this time). -.It Va $USER -The username used on -.Va $HOST ; -defaults to the same as the -username you have on -.Va $YOURHOST , -but will be different if you do -.Dq Li "safesh user@host" -instead of just -.Dq Li "safesh host" . -.It Va $PORT -The port used on -.Va $HOST . -Presently always 22. -.El Property changes on: head/security/safesh/src/safesh.1 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/safesh/src/cvs-safesh.sh =================================================================== --- head/security/safesh/src/cvs-safesh.sh (revision 404856) +++ head/security/safesh/src/cvs-safesh.sh (nonexistent) @@ -1,6 +0,0 @@ -#!/bin/sh -if [ "$2" = "-l" ]; then - exec safesh $3@$1 -- "$@" -else - exec safesh $1 -- "$@" -fi Property changes on: head/security/safesh/src/cvs-safesh.sh ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/safesh/src/safesh.sh =================================================================== --- head/security/safesh/src/safesh.sh (revision 404856) +++ head/security/safesh/src/safesh.sh (nonexistent) @@ -1,140 +0,0 @@ -#!/bin/sh - -AKEYS=${HOME}/.safesh -# Use username as supplied on the command line if user@host syntax is used, -# otherwise use the presently active username -USER=`whoami` -USER=`echo $1 | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` -# Use hostname as supplied on commandline, without username -HOST=`echo $1 | sed -e 's/.*@//' | tr A-Z a-z` - -# MY eXit -myx() { - echo $1 1>&2 - exit 1 -} - -# Normalize host name if necessary -normalizehost() { - cat ${AKEYS}/map 2> /dev/null | awk "(\$1 == \"$1\" && !gotit) {gotit = 1; print tolower(\$2)} END {if(!gotit) {print tolower(\"$1\")}}" -} - -HOST=`normalizehost $HOST` - -# -# Check that the user are using the right parameters -# -# XXX This should check for --, but it is unclear how to do that. -# -if ! shift; then - myx "Usage: $0 [-- ]" -fi - -# -# Lose the -- from the parameters - it is there for future extensibility -# using getopt() -# -shift 2> /dev/null; - -HOSTDIR=$AKEYS/$USER@${HOST}-22 -if [ ! -d $HOSTDIR ]; then - while ! [ "$answer" = "yes" -o "$answer" = "no" ]; do - echo -n "New user/host pair $USER@$HOST - create key (yes/no)? " 1>&2 - read answer - done - if [ "$answer" = "no" ]; then - exit 1 - fi - mkdir -p $HOSTDIR || myx "$0: Unable to create $HOSTDIR" -fi - -if [ ! -e $HOSTDIR/id_dsa ]; then - if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then - (ssh-keygen -t dsa -f $HOSTDIR/id_dsa >/dev/null < /dev/null 2>&1) || myx "$0: Unable to create $HOSTDIR/id_dsa" - else - ssh-keygen -t dsa -f $HOSTDIR/id_dsa || myx "Unable to create $HOSTDIR/id_dsa" - fi -fi - -# We now have a key in $HOSTDIR/id_dsa - -ACTIVEAGENT=$HOSTDIR/activeagent-`hostname` -if [ -e $ACTIVEAGENT.sh ]; then - . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh" -fi - -if ! ssh-add -l > /dev/null 2>& 1; then - ssh-agent -s > $ACTIVEAGENT.tmp || myx "Unable to start ssh-agent" - sed '/^echo/d' < $ACTIVEAGENT.tmp > $ACTIVEAGENT.sh - rm -f $ACTIVEAGENT.tmp - . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh after creating it" - (echo setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK\; - echo setenv SSH_AGENT_PID $SSH_AGENT_PID\;) > $ACTIVEAGENT.csh - #echo "Started agent with PID $SSH_AGENT_PID, socket $SSH_AUTH_SOCK" 1>&2 -fi - -# We now have a live agent, possibly without any keys in it - - -for i in $USER@${HOST}-22 `cat $HOSTDIR/extra_keys 2> /dev/null`; do - tmpuser=`echo $i | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` - tmpport=`echo $i | sed -e '/-\([0-9][0-9]*\)/!s/$/-22/' -e 's/.*-\([0-9][0-9]*\)/\1/'` - tmphost=`echo $i | sed -e 's/.*@\(.*\)/\1/' -e 's/-[0-9][0-9]*$//' | tr A-Z a-z` - tmp=$USER@`normalizehost $tmphost`-$tmpport - if [ -f $HOSTDIR/$tmp ]; then - IDENTITY=$HOSTDIR/$tmp - elif [ -d $AKEYS/$tmp/ ]; then - if ! [ -f $AKEYS/$tmp/id_dsa ]; then - myx "Missing key $AKEYS/$tmp/id_dsa" - elif ! [ -r $AKEYS/$tmp/id_dsa ]; then - myx "$AKEYS/$tmp/id_dsa is not readable" - fi - IDENTITY=$AKEYS/$tmp/id_dsa - elif [ -f "/$i" ]; then - IDENTITY="/$i" - elif [ -f "$HOME/$i" ]; then - IDENTITY="$HOME/$i" - else - myx "Unable to find key for \"$i\"" - fi - # Only add it to the list if it isn't already in the agent. This is a - # workaround for a bug in ssh-add, which asks for the password FIRST, - # and checks for the existence of the the key in the agent AFTERWARDS - if [ "`(ssh-add -l && ssh-keygen -l -f "$IDENTITY") | awk '{print $1, $2}' | sort | uniq -d)`" = "" ]; then - KEYLIST="$KEYLIST $IDENTITY" - fi -done - -if [ "${KEYLIST}" != "" ]; then - if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then - ssh-add $KEYLIST < /dev/null > /dev/null 2>&1 - else - ssh-add $KEYLIST - fi -fi - -BASENAME=`basename $0` -if [ "$BASENAME" = "scpsh" ]; then - # Print information if we are running entirely interactive (or - # somebody is attempting to make us believe we are) - if [ -t 0 -a -t 1 -a -t 2 ]; then - echo ">>>" 1>&2 - echo ">>> Starting up shell with authentication variables." 1>&2 - echo ">>> You can now scp to $USER@$HOST without passwords." 1>&2 - if [ "$TGT" = "" ]; then - echo ">>> $USER@$HOST is available through the shorthand \$TGT" 1>&2 - fi - echo ">>>" 1>&2 - fi - if [ "$TGT" = "" ]; then - TGT=$USER@$HOST - export TGT - fi - exec $SHELL -elif [ "$BASENAME" = "safeshinstall" ]; then - cat $HOSTDIR/id_dsa.pub | ssh $USER@$HOST 'mkdir -p .ssh && cat >> .ssh/authorized_keys2' -elif [ "$1" = "" ]; then - exec ssh -A $USER@$HOST -else - exec ssh "$@" -fi Property changes on: head/security/safesh/src/safesh.sh ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/safesh/pkg-plist =================================================================== --- head/security/safesh/pkg-plist (revision 404856) +++ head/security/safesh/pkg-plist (nonexistent) @@ -1,5 +0,0 @@ -bin/cvs-safesh -bin/safesh -bin/safeshinstall -bin/scpsh -man/man1/safesh.1.gz Property changes on: head/security/safesh/pkg-plist ___________________________________________________________________ Deleted: fbsd:nokeywords ## -1 +0,0 ## -yes \ No newline at end of property Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/security/safesh/Makefile =================================================================== --- head/security/safesh/Makefile (revision 404856) +++ head/security/safesh/Makefile (revision 404857) @@ -1,29 +1,32 @@ # Created by: eivind # $FreeBSD$ PORTNAME= safesh PORTVERSION= 1.5 CATEGORIES= security MASTER_SITES= # none DISTFILES= # none -EXTRACT_ONLY= # none MAINTAINER= ports@FreeBSD.org COMMENT= Authentication manager for OpenSSH (making secure auth easier) NO_BUILD= yes -NO_WRKSUBDIR= yes +NO_ARCH= yes -SRC= ${.CURDIR}/src +PLIST_FILES= bin/cvs-safesh \ + bin/safesh \ + bin/safeshinstall \ + bin/scpsh \ + man/man1/safesh.1.gz # XXX Anybody that know how to create manlinks from ports easily, please # contact me. do-install: - ${INSTALL_SCRIPT} ${SRC}/${PORTNAME}.sh ${STAGEDIR}${PREFIX}/bin/${PORTNAME} - ${INSTALL_SCRIPT} ${SRC}/cvs-safesh.sh ${STAGEDIR}${PREFIX}/bin/cvs-safesh - ${INSTALL_MAN} ${SRC}/${PORTNAME}.1 ${STAGEDIR}${PREFIX}/man/man1 - @${LN} -sf ${PORTNAME} ${STAGEDIR}${PREFIX}/bin/scpsh - @${LN} -sf ${PORTNAME} ${STAGEDIR}${PREFIX}/bin/safeshinstall + ${INSTALL_SCRIPT} ${FILESDIR}/${PORTNAME}.sh ${STAGEDIR}${PREFIX}/bin/${PORTNAME} + ${INSTALL_SCRIPT} ${FILESDIR}/cvs-safesh.sh ${STAGEDIR}${PREFIX}/bin/cvs-safesh + ${INSTALL_MAN} ${FILESDIR}/${PORTNAME}.1 ${STAGEDIR}${PREFIX}/man/man1 + ${LN} -sf ${PORTNAME} ${STAGEDIR}${PREFIX}/bin/scpsh + ${LN} -sf ${PORTNAME} ${STAGEDIR}${PREFIX}/bin/safeshinstall .include Index: head/security/safesh/files/cvs-safesh.sh =================================================================== --- head/security/safesh/files/cvs-safesh.sh (nonexistent) +++ head/security/safesh/files/cvs-safesh.sh (revision 404857) @@ -0,0 +1,6 @@ +#!/bin/sh +if [ "$2" = "-l" ]; then + exec safesh $3@$1 -- "$@" +else + exec safesh $1 -- "$@" +fi Property changes on: head/security/safesh/files/cvs-safesh.sh ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/security/safesh/files/safesh.1 =================================================================== --- head/security/safesh/files/safesh.1 (nonexistent) +++ head/security/safesh/files/safesh.1 (revision 404857) @@ -0,0 +1,546 @@ +.\"- +.\" Copyright (c) 2002 Eivind Eklund +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer +.\" in this position and unchanged. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd January 26, 2002 +.Dt SAFESH 1 +.Sh NAME +.Nm safesh +.Nd safe key manager for OpenSSH +.Sh SYNOPSIS +.Nm +.Oo Ar user@ Oc Ns Ar host +.Oo +.Fl Fl +.Ar ssh-parameters ... +.Oc +.Nm safeshinstall +.Oo Ar user@ Oc Ns Ar host +.Nm cvs-safesh +.Oo Ar user@ Oc Ns Ar host +.Op Ar command +.Nm scpsh +.Oo Ar user@ Oc Ns Ar host +.Sh DESCRIPTION +NOTE: This text often refers to +.Va $VARIABLE +in description. +What each of the references will be replaced with when +.Nm +runs is described at the end of the manpage. +.Pp +The +.Nm +utility +automatically creates one DSA key (called an identity) for each host you +connect to, and stores this in a separate agent for each host. +It is also capable of adding keys for other hosts to this agent, so you can +use it for restricted forwarding of authentication. +Because each host uses its own +.Xr ssh-agent 1 , +the hosts you forward authentication to can only get at the authentication for +the hosts you specifically say it should be able to get at. +.Pp +When run, +.Nm : +.Bl -enum +.It +Normalizes the hostname you are talking about, using the +.Pa $HOME/.safesh/map +file. +.It +Checks if the user and host has an SSH DSA key in +.Pa $HOME/.safesh , +and creates one using +.Xr ssh-keygen 1 +if it does not. +The DSA key is stored in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id . +You will be asked for a passphrase when the key is created. +Note that if you use the same passphrase for all +.Nm +keys, you will only be asked for the passphrase once per host you connect to. +If you use different passphrases, you will be asked once per forwarded key +for each host you connect to (after a machine startup). +.It +Checks if you have the +.Xr ssh-agent 1 +for this host running, and starts it if not. +.It +Checks what keys you are supposed to have active when connecting to this host +(the key for the host and any keys listed in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys ) , +and which of these are missing from the active agent. +.It +If any identities were missing from the agent, it executes +.Xr ssh-add 1 +to add them to the agent. +.It +Executes +.Xr ssh 1 +with either +.Ar $USER@$HOST +or the extra command line supplied by the user. +.El +.Sh BASIC CONCEPT DESCRIPTION +The +.Nm +utility +is an authentication manager for OpenSSH. +It is an attempt at making it easy to use the built-in authentication features +of OpenSSH securely. +By default, the SSH security model is that all hosts the +user connects to are trusted, and are given complete access, including the +ability to authenticate as the user towards other hosts if the user is running +.Xr ssh-agent 1 . +OpenSSH has improved this security model somewhat by not forwarding SSH +authentication by default, but still allows the host that you connect to +to grab your credentials and authenticate as you to anybody else when you +do authentication forwarding to it. +.Sh SIMPLE HOWTO +Starting to make use of +.Nm +is trivial: +.Bl -enum +.It +Do +.Dq Li "safeshinstall <[user@]hostname>" . +.Pp +This will ask for a passphrase (three times), create a directory +.Pa $HOME/.safesh/@-22 , +which contains authentication +data for your user at +.Aq Ar hostname , +and add the contents of +.Pa $HOME/.safesh/@-22/id_dsa.pub +to +.Pa $HOME/.ssh/authorized_keys2 +on the host you connect to. +The latter will result in +.Xr ssh 1 +asking for authentication in the fashion you already use (most likely by +asking for your password). +.It +Log in with +.Dq Li "safesh " +from now on. +.Pp +This will ask you for a passphrase if you have not logged into that host this +session, and otherwise just let right in. +.El +.Sh UTILITY COMMANDS +The +.Nm +utility +ships with two utility hacks to work around the fact that it is not a complete +.Xr ssh 1 +replacement, +.Nm scpsh +and +.Nm cvs-safesh . +.Pp +The +.Nm scpsh +utility +is for supporting use of +.Xr scp 1 +with +.Nm . +The +.Nm scpsh +.Oo Ar user@ Oc Ns Ar host +command +will start a new interactive shell (using the +.Ev SHELL +environment variable to determine which it should be), with the environment +variables for using +.Xr ssh-agent 1 +to authenticate to +.Oo Ar user@ Oc Ns Ar host +already set. +This allows use of +.Xr scp 1 +without having to type passwords to authenticate. +.Pp +The +.Nm cvs-safesh +utility +makes it easy to use +.Nm +along with +.Xr cvs 1 +and other programs that use +.Xr rsh 1 +or +.Xr ssh 1 +with the format +.Dq Li "ssh " +or +.Dq Li "ssh " . +To use with +.Xr cvs 1 , +just set +.Ev CVS_RSH +to +.Dq Li cvs-safesh +instead of +.Dq Li ssh . +.Sh FILES +.Bl -tag -width ".Pa $HOME/.safesh" +.It Pa $HOME/.safesh/ +Directory containing information for +.Nm . +.It Pa $HOME/.safesh/map +Mapping file for +.Nm , +describing how to map host names to their canonical form. +This is usually used to map short names to their long form. +The format of the file is one mapping per line, what it is mapped from as the +first word, what it is mapped to as the second. +.Pp +It is also possible to use this to map domain names to their safe form by having +the name of the host as the first parameter, and the name of the host with a +period +.Pq Ql .\& +at the end as the second parameter, +e.g., +.Dq Li freefall.freebsd.org freefall.freebsd.org. . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/ +Directory with data for a particular hostname. +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id +Private key for use to authenticate as +.Ar $USER@$HOST . +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/dsa_id.pub +Public key for use by +.Ar $HOST +to authenticate +.Ar $USER . +To connect to +.Ar $HOST +as +.Ar $USER +using +.Nm +without giving a password, add the contents of this file +to the end of +.Pa $HOME/.ssh/authorized_keys2 . +Automatically generated on first connect to a host with +.Nm . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET +Private key for use when +.Ar $HOST +authenticates towards +.Ar $AUTHTARGET . +This is used in preference to +.Pa $HOME/.safesh/$AUTHTARGET/dsa_id +for authentication forwarding through +.Ar $HOST +to +.Ar $AUTHTARGET . +The file is only used if +.Ar $AUTHTARGET +is listed in +.Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys . +This file is not generated automatically by +.Nm . +It is only present if you have generated it using +.Xr ssh-keygen 1 . +Note that it is usually more than useless (can pose a security risk) to copy a +key used for other authentication to this location. +.Pp +The use of explict authentication files for authentication forwarding is +primarily for protection against the case where the machine you run +.Nm +on is compromised. +Using this file, you can use a separate passphrase from the one used for the +key for connecting directly to +.Ar $AUTHTARGET ; +that key need not even exist. +By using IP restrictions in the +.Pa authorized_keys +file for the key, you can make +sure that the host +.Nm +runs on cannot connect to +.Ar $AUTHTARGET +using the authentication forwarding +key. +The use of a separate forwarding key can also be used in combination with a +modified SSH to log which key was used where, and thus track key propagation. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/$AUTHTARGET.pub +Public key corresponding to the private key described above. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/extra_keys +List of extra keys to make available for this host. +Each line in the file is first attempted matched against the host/user/port +database in +.Pa $HOME/.safesh/ . +Username and/or port is added if just the hostname is specified +.Pa extra_keys , +and the hostname is always normalized using the map file. +If a key exists in +.Pa $HOME/.safesh/ , +.Nm +attempts to add that. +Otherwise, it first tries to look for the line as a file relative to +.Pa / , +then relative to +.Pa $HOME . +If it does not find either of these, +.Nm +will exit with an error message. +If it finds one, it will add it using +.Xr ssh-add 1 . +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.sh +Bourne shell (see +.Xr sh 1 , +.Xr bash 1 , +.Xr zsh 1 ) +script for setting up the environment variables for a particular +.Xr ssh-agent 1 +process used for this host. +Only valid if +.Nm +has been run against that host as this user since the machine +.Nm +runs on was last booted. +Note that this file must be source'd, not just run as a shell script. +.It Pa $HOME/.safesh/$USER@$HOST-$PORT/activeagent-$YOURHOST.csh +CSH (see +.Xr csh 1 , +.Xr tcsh 1 ) +script for setting up the environment variables for a particular +.Xr ssh-agent 1 +process used for this host. +Only valid if +.Nm +has been run against that host as this user since the machine +.Nm +runs on was last booted. +Note that this file must be source'd, not just run as a shell script. +.El +.Sh AUTHORS +The +.Nm +utility +was written by +.An Eivind Eklund Aq eivind@FreeBSD.org . +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 +.Sh KNOWN ISSUES +The +.Nm +utility +does not handle whitespace in filenames specified in +.Pa extra_keys +correctly. +.Pp +The +.Xr ssh-agent 1 +processes that are started by +.Nm +will hang around until next reboot unless +you put the +.Dq Li "killall ssh-agent" +command in +.Pa .logout +or similar. +This allows any login to your account to use your authentication towards +machines you have connected to (including anybody with root on the box), +persisting after you log out. +You must always assume that root can grab your authentication at the moment +you run do it, so this is only an issue in that the authentication stays +available longer. +This is not resolvable without rewriting +.Xr ssh-agent 1 . +.Sh MISSING FEATURES +.Bl -tag -width 4n +.It Em Two-step secure SSH with an untrusted host in the middle +It is possible to use the port forwarding capability of +.Xr ssh 1 +to forward +authentication through another server, without allowing the other server to +indepently authenticate to a third party, and without allowing it to see +what is going on in your connection. +This is based on just forwarding a tunnel through the untrusted host, and +doing direct authentication to the server on the other side. +With the present version of OpenSSH, this has the problem of leaving the +actual port forwarding open while the tunnel is open, allowing other users to +set up their own tunnels, and weakening another side of the security model. +.It Em Read out fingerprints +The +.Nm +utility +should make it trivial to retrieve the fingerprint for: +.Bl -enum +.It +The host it is running on. +.Pp +This must presently be done with +.Dq Li "ssh-keygen -l /etc/ssh/ssh_host_key.pub" +(to get the fingerprint for SSH 1) and +.Dq Li "ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key" +(for SSH 2). +.It +Other hosts, as registered in the +.Pa known_host +file on the host it is running +on. +.Pp +This must presently be done by manual inspection. +.El +.It Em Merge Pa known_hosts +The +.Nm +utility +should make it trivial to merge +.Pa known_hosts +and +.Pa known_hosts2 +with ones from +another host, including retrieving and uploading +.Pa known_hosts +as appropriate. +.It Em Manage Pa .ssh/authorized_keys2 +The +.Nm +utility +should be able to automatically remove keys from the +.Pa authorized_keys2 +file +on other machines, to make everything about the +.Nm +process self-contained. +.It Em Manage setup of key limitations +When managing +.Pa authorized_keys2 , +it is also reasonable to manage key limitation +in this. +IP restrictions +.Pq Qq Li from= +should be handled to make it easy to create setups +where the local machine does not have direct access to a target. +Command restrictions etc. would be good to have just for completeness. +.It Em Emulate the entire Xr ssh 1 Em syntax +Presently, the +.Nm +utility has a fairly weird syntax. +This is because it is a fairly quick hack, just made to be usable. +Later, it would be nice to rewrite it to be fully compatible with +.Xr ssh 1 . +This would allow use as a drop-in replacement. +.It Em Description of the trust/threat/security model +It would be nice to have a complete description of the normal SSH threat model +as well as the +.Nm +threat model, in order to make people fully conscious of their own model. +.It Em Emulate Xr scp 1 +The +.Xr scp 1 +utility +is very useful, and the only way to use it with +.Nm +at the moment is through a subshell created by +.Nm scpsh . +An ideal +.Nm +implementation would include wrapping of +.Xr scp 1 , +too. +.El +.Sh VARIABLE REPLACEMENT IN DESCRIPTIONS +.Bl -tag -width ".Va $AUTHTARGET" +.It Va $HOME +Path to your home directory. +.It Va $HOST +The name of the host you are running +.Nm +towards. +This is the machine you are +.Xr ssh 1 Ns 'ing +into. +.It Va $YOURHOST +The name of the host you are running +.Nm +on, as output by +.Xr hostname 1 . +This is the name of the machine you are +.Xr ssh 1 Ns 'ing +from. +The use of +.Va $YOURHOST +makes +.Nm +safe to use with NFS-mounted home directories. +.It Va $AUTHTARGET +The authentication target for an authentication forwarding. +This is +.Em not +the same as +.Va $HOST . +.Va $AUTHTARGET +is a machine you are +.Xr ssh 1 Ns 'ing +to +.Em from +.Va $HOST . +The format of +.Va $AUTHTARGET +is +.Sm off +.Ao Ar user Ac @ Ao Ar somehost Ac - Aq Ar someport , +.Sm on +where +.Aq Aq user +defaults to the username you run +.Nm +as, and +.Aq Aq someport +default to 22 (and it is not possible to set anything +else at this time). +.It Va $USER +The username used on +.Va $HOST ; +defaults to the same as the +username you have on +.Va $YOURHOST , +but will be different if you do +.Dq Li "safesh user@host" +instead of just +.Dq Li "safesh host" . +.It Va $PORT +The port used on +.Va $HOST . +Presently always 22. +.El Property changes on: head/security/safesh/files/safesh.1 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/security/safesh/files/safesh.sh =================================================================== --- head/security/safesh/files/safesh.sh (nonexistent) +++ head/security/safesh/files/safesh.sh (revision 404857) @@ -0,0 +1,140 @@ +#!/bin/sh + +AKEYS=${HOME}/.safesh +# Use username as supplied on the command line if user@host syntax is used, +# otherwise use the presently active username +USER=`whoami` +USER=`echo $1 | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` +# Use hostname as supplied on commandline, without username +HOST=`echo $1 | sed -e 's/.*@//' | tr A-Z a-z` + +# MY eXit +myx() { + echo $1 1>&2 + exit 1 +} + +# Normalize host name if necessary +normalizehost() { + cat ${AKEYS}/map 2> /dev/null | awk "(\$1 == \"$1\" && !gotit) {gotit = 1; print tolower(\$2)} END {if(!gotit) {print tolower(\"$1\")}}" +} + +HOST=`normalizehost $HOST` + +# +# Check that the user are using the right parameters +# +# XXX This should check for --, but it is unclear how to do that. +# +if ! shift; then + myx "Usage: $0 [-- ]" +fi + +# +# Lose the -- from the parameters - it is there for future extensibility +# using getopt() +# +shift 2> /dev/null; + +HOSTDIR=$AKEYS/$USER@${HOST}-22 +if [ ! -d $HOSTDIR ]; then + while ! [ "$answer" = "yes" -o "$answer" = "no" ]; do + echo -n "New user/host pair $USER@$HOST - create key (yes/no)? " 1>&2 + read answer + done + if [ "$answer" = "no" ]; then + exit 1 + fi + mkdir -p $HOSTDIR || myx "$0: Unable to create $HOSTDIR" +fi + +if [ ! -e $HOSTDIR/id_dsa ]; then + if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then + (ssh-keygen -t dsa -f $HOSTDIR/id_dsa >/dev/null < /dev/null 2>&1) || myx "$0: Unable to create $HOSTDIR/id_dsa" + else + ssh-keygen -t dsa -f $HOSTDIR/id_dsa || myx "Unable to create $HOSTDIR/id_dsa" + fi +fi + +# We now have a key in $HOSTDIR/id_dsa + +ACTIVEAGENT=$HOSTDIR/activeagent-`hostname` +if [ -e $ACTIVEAGENT.sh ]; then + . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh" +fi + +if ! ssh-add -l > /dev/null 2>& 1; then + ssh-agent -s > $ACTIVEAGENT.tmp || myx "Unable to start ssh-agent" + sed '/^echo/d' < $ACTIVEAGENT.tmp > $ACTIVEAGENT.sh + rm -f $ACTIVEAGENT.tmp + . $ACTIVEAGENT.sh || myx "$0: Unable to read $ACTIVEAGENT.sh after creating it" + (echo setenv SSH_AUTH_SOCK $SSH_AUTH_SOCK\; + echo setenv SSH_AGENT_PID $SSH_AGENT_PID\;) > $ACTIVEAGENT.csh + #echo "Started agent with PID $SSH_AGENT_PID, socket $SSH_AUTH_SOCK" 1>&2 +fi + +# We now have a live agent, possibly without any keys in it + + +for i in $USER@${HOST}-22 `cat $HOSTDIR/extra_keys 2> /dev/null`; do + tmpuser=`echo $i | sed -e "/^[^@]*\$/s/.*/$USER/" -e "/@/s/\\(.*\\)@.*/\\1/"` + tmpport=`echo $i | sed -e '/-\([0-9][0-9]*\)/!s/$/-22/' -e 's/.*-\([0-9][0-9]*\)/\1/'` + tmphost=`echo $i | sed -e 's/.*@\(.*\)/\1/' -e 's/-[0-9][0-9]*$//' | tr A-Z a-z` + tmp=$USER@`normalizehost $tmphost`-$tmpport + if [ -f $HOSTDIR/$tmp ]; then + IDENTITY=$HOSTDIR/$tmp + elif [ -d $AKEYS/$tmp/ ]; then + if ! [ -f $AKEYS/$tmp/id_dsa ]; then + myx "Missing key $AKEYS/$tmp/id_dsa" + elif ! [ -r $AKEYS/$tmp/id_dsa ]; then + myx "$AKEYS/$tmp/id_dsa is not readable" + fi + IDENTITY=$AKEYS/$tmp/id_dsa + elif [ -f "/$i" ]; then + IDENTITY="/$i" + elif [ -f "$HOME/$i" ]; then + IDENTITY="$HOME/$i" + else + myx "Unable to find key for \"$i\"" + fi + # Only add it to the list if it isn't already in the agent. This is a + # workaround for a bug in ssh-add, which asks for the password FIRST, + # and checks for the existence of the the key in the agent AFTERWARDS + if [ "`(ssh-add -l && ssh-keygen -l -f "$IDENTITY") | awk '{print $1, $2}' | sort | uniq -d)`" = "" ]; then + KEYLIST="$KEYLIST $IDENTITY" + fi +done + +if [ "${KEYLIST}" != "" ]; then + if [ "$DISPLAY" != "" ] && (which ssh-askpass > /dev/null 2>&1); then + ssh-add $KEYLIST < /dev/null > /dev/null 2>&1 + else + ssh-add $KEYLIST + fi +fi + +BASENAME=`basename $0` +if [ "$BASENAME" = "scpsh" ]; then + # Print information if we are running entirely interactive (or + # somebody is attempting to make us believe we are) + if [ -t 0 -a -t 1 -a -t 2 ]; then + echo ">>>" 1>&2 + echo ">>> Starting up shell with authentication variables." 1>&2 + echo ">>> You can now scp to $USER@$HOST without passwords." 1>&2 + if [ "$TGT" = "" ]; then + echo ">>> $USER@$HOST is available through the shorthand \$TGT" 1>&2 + fi + echo ">>>" 1>&2 + fi + if [ "$TGT" = "" ]; then + TGT=$USER@$HOST + export TGT + fi + exec $SHELL +elif [ "$BASENAME" = "safeshinstall" ]; then + cat $HOSTDIR/id_dsa.pub | ssh $USER@$HOST 'mkdir -p .ssh && cat >> .ssh/authorized_keys2' +elif [ "$1" = "" ]; then + exec ssh -A $USER@$HOST +else + exec ssh "$@" +fi Property changes on: head/security/safesh/files/safesh.sh ___________________________________________________________________ Added: fbsd:nokeywords ## -0,0 +1 ## +yes \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sysutils/personality/src/personality.8 =================================================================== --- head/sysutils/personality/src/personality.8 (revision 404856) +++ head/sysutils/personality/src/personality.8 (nonexistent) @@ -1,72 +0,0 @@ -.\" Copyright (c) 2000 -.\" Andreas Klemm . All rights reserved. -.\" -.\" $FreeBSD$ -.\" -.Dd March 25, 2001 -.Dt PERSONALITY 8 -.Os -.Sh NAME -.Nm personality -.Nd system configuration management utility -.Sh SYNOPSIS -.Nm personality -.Op options ... -.Sh DESCRIPTION -This script provides functionality for manipulating collections of -configuration files which can be organised so as to alter the -personality of a system. -.Pp -Initially, the -.Ic base -personality is established. This personality contains the -.Ic reference -copies of configuration files, and is used when creating new personalities. -The files which are currently considered part of the system's personality -are those contained in the base personality. -.Pp -A new personality is established by making a copy of the base personality -under a new name. Each personality maintains a separate copy of all -configuration files under -.Ic /etc/personality . -.Pp -To install a new personality, the files currently in place are saved back -to the current personality as indicated in -.Ic /etc/personality/current , -and the files for the new personality copied into place. -.Pp -The -.Ic select -and -.Ic menu -commands which perform these installations are implemented in such a -fashion as to only require the tools available on the root filesystem, -so that they may be invoked at the earliest stage during system startup. -.Pp -If the current personality has become damaged, it can be restored -from the saved copy. -.Pp -Files can be added to and removed from the personality set. When a new -file is added, it is copied from the current system into all personalities -and added to the list file. When a file is removed the current version is -kept in place, but all copies are removed from saved personalities and the -file is removed from the list. -.Sh FILES -.Bl -tag -width /etc/personality/current -compact -.It Pa /etc/personality -configuration base -.It Pa /etc/personality/_base -system files under management of personality -.It Pa /etc/personality/current -backup location of current files before new personality is copied into place -.Sh SEE ALSO -.Xr rc 8 -.Sh BUGS -Currently none. -.Sh HISTORY -The -.Nm -script has been written 1997 by Mike Smith . -The -.Nm -manual page has been written by Andreas Klemm . Property changes on: head/sysutils/personality/src/personality.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sysutils/personality/src/personality =================================================================== --- head/sysutils/personality/src/personality (revision 404856) +++ head/sysutils/personality/src/personality (nonexistent) @@ -1,536 +0,0 @@ -#! /bin/sh -############################################################################## -# -# Copyright (c) 1997 Michael Smith -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################################## -# -# This script provides functionality for manipulating collections of -# configuration files which can be organised so as to alter the -# personality of a system. -# -# Initially, the "base" personality is established. This personality -# contains the "reference" copies of configuration files, and is used -# when creating new personalities. The files which are currently -# considered part of the system's personality are those contained in -# the base personality. -# -# A new personality is established by making a copy of the base -# personality under a new name. Each personality maintains a -# separate copy of all configuration files under /etc/personality. -# -# To install a new personality, the files currently in place are -# saved back to the current personality as indicated in -# /etc/personality/current, and the files for the new personality -# copied into place. The 'select' and 'menu' commands which perform -# these installations are implemented in such a fashion as to only -# require the tools available on the root filesystem, so that they -# may be invoked at the earliest stage during system startup. -# -# If the current personality has become damaged, it can be restored -# from the saved copy. -# -# Files can be added to and removed from the personality set. When -# a new file is added, it is copied from the current system into all -# personalities and added to the list file. When a file is removed -# the current version is kept in place, but all copies are removed -# from saved personalities and the file is removed from the list. -# -# XXX To Do : -# Files can be inherited by one personality from another. This is -# simply achieved by copying the relevant files under /etc/personality, -# and into the current system if required. -# -############################################################################## - -# Establish some global constants -P_ROOT=/etc/personality -#P_ROOT=/tmp/personality -P_BASE="${P_ROOT}/_base" -P_CURRENT="${P_ROOT}/current" -P_FILES="${P_ROOT}/files" -P_LIST="${P_ROOT}/list" -scriptname="$0" - -############################################################################## -# pers_main -# -# Execution begins here after the file has been read. -# -pers_main() -{ - case "$1" in - menu) - pers_menu $2 $3 - ;; - select) - pers_select $2 - ;; - restore) - pers_restore - ;; - save) - pers_save - ;; - saveas) - pers_saveas $2 - pers_reindex - ;; - create) - pers_create $2 - pers_reindex - ;; - delete) - pers_delete $2 - pers_reindex - ;; - add) - pers_add $2 - pers_reindex - ;; - list) - pers_list - ;; - remove) - pers_remove $2 - pers_reindex - ;; - init) - pers_init - pers_reindex - ;; - *) - usage - ;; - esac -} - -############################################################################## -# pers_menu -# -# Present a menu of currently-selectable personalities, assign hotkeys, -# describe the default and optionally go with the default after a timeout -# -pers_menu() -{ - # Look and see if there's actually anything to work with - if [ ! -d "${P_ROOT}" ]; then - return - fi - - # Pick up a timeout if specified, default to 10 seconds - timeout=10 - if [ ! -z "$1" ]; then - timeout="$1" - fi - - # Assign a default, if suitable - defpers="" - defname="" - if [ -f "${P_CURRENT}" ]; then - defpers=`cat "${P_CURRENT}"` - defname="${defpers}" - fi - - # Loop prompting/reading input until we get a result - while :; do - - # Print menu - echo ""; - echo "Select System Personality" - echo "=========================" - hkey=0 - for pers in `cat "${P_LIST}"`; do - echo " ${hkey}) ${pers}" - eval index_${hkey}="${pers}" - hkey=`expr ${hkey} + 1` - done - echo ""; - - echo " Default : ${defname}" - read -t "${timeout}" -p " Selection : " input - eval selvar=\$index_"${input}" - selpers="" - if [ -z "${input}" ]; then - selpers="${defpers}" - break - elif [ -n "${selvar}" ]; then - selpers="${selvar}" - break - elif [ -d "${P_ROOT}/_${input}" ]; then - selpers="${input}" - break - fi - done - - # $selpers now contains the personality we wish to select, - # or is empty if we selected the default when there was none - if [ -z "${selpers}" ]; then - return - fi - - # select the personality nominated - pers_select "${selpers}" -} - -############################################################################## -# pers_select -# -# Copy the files from the nominated personality out of the repository -# into the real system. Note that this must be able to run with -# nothing other than the contents of /bin available. -# -pers_select() -{ - src="${P_ROOT}/_$1"; - if [ ! -d "${src}" ]; then - fail "no such personality '$1'" - fi - - # Iterate over the file listing, copy them all out - for file in `cat "${P_FILES}"`; do - cp -p "${src}/${file}" "${file}" - done - - # Register this personality as being current - echo "$1" > "${P_CURRENT}" -} - -############################################################################## -# pers_restore -# -# Reload the configuration files for the current personality, eliminating -# any changes that may have been made. -# -pers_restore() -{ - if [ ! -e "${P_CURRENT}" ]; then - fail "no personality currently active" - fi - - # Check that the current personality exists - pers=`cat "${P_CURRENT}"` - src="${P_ROOT}/_${pers}" - if [ ! -d "${src}" ]; then - fail "current personality '${pers}' not in the repository!" - fi - - # Iterate over the file listing, copy them all out - for file in `cat "${P_FILES}"`; do - cp -p "${src}/${file}" "${file}" - done -} - -############################################################################## -# pers_save -# -# If a personality is current, save the current set of files to that -# personality. -# -pers_save() -{ - if [ ! -e "${P_CURRENT}" ]; then - fail "no personality currently active" - fi - - # Check that the current personality exists - pers=`cat "${P_CURRENT}"` - dest="${P_ROOT}/_${pers}" - if [ ! -d "${dest}" ]; then - fail "current personality '${pers}' not in the repository!" - fi - - # OK, go ahead and save stuff. If this fails, we're - # moderately stuffed, so don't worry about it. - for file in `cat "${P_FILES}"`; do - stub=`dirname "${file}"` - mkdir -p "${dest}/${stub}" - cp -p "${file}" "${dest}/${file}" - done -} - -############################################################################## -# pers_saveas -# -# Take the currently-active set of configuration files, and save them as -# a new personality, set the new personality as current. -# -pers_saveas() -{ - dest="${P_ROOT}/_$1" - if [ -e "${dest}" ]; then - fail "cannot create new personality '$1', name already in use" - fi - - # Create the personality directory - mkdir -p "${dest}" || pers_saveas_fail "$1" - - # iterate over files to save, copy them in - for file in `cat "${P_FILES}"`; do - stub=`dirname "${file}"` - mkdir -p "${dest}/${stub}" - cp -p "${file}" "${dest}/${file}" || pers_saveas_fail $1 - done - - # new personality is current - echo "$1" > "${P_CURRENT}" -} - -######################################## -# pers_saveas_fail -# -# The 'save as' operation failed. Clean -# up and emit a failure message. -# -pers_saveas_fail() -{ - rm -Rf "${P_ROOT}/_$1" - fail "could not save current personality as '$1'" -} - -############################################################################## -# pers_create -# -# Create a new personality, duplicated from the current base personality -# -pers_create() -{ - if [ -e "${P_ROOT}/_$1" ]; then - fail "cannot create new personality '$1', name already in use" - fi - - # Ok, duplicate it - cp -Rp "${P_BASE}" "${P_ROOT}/_$1" || pers_create_fail "$1" -} - -######################################## -# pers_create_fail -# -# An attempt to create a personality failed. -# Clean up and exit with an error message. -# -pers_create_fail() -{ - rm -Rf "${P_ROOT}/_$1" - fail "'$1' could not be created" -} - -############################################################################## -# pers_delete -# -# Remove a personality from the system. It is legitimate to remove -# the current personality. -# -pers_delete() -{ - if [ ! -e "${P_ROOT}/_$1" ]; then - fail "no such personality '$1' to remove" - fi - if [ "$1" = _base ]; then - fail "cannot remove base personality" - fi - - # If the requested personality is current, remove the - # reference. - if [ -e "${P_CURRENT}" ]; then - if [ `cat "${P_CURRENT}"` = "$1" ]; then - rm -f "${P_CURRENT}" - fi - fi - - # Remove the repository entry - rm -Rf "${P_ROOT}/_$1"; - - # Make sure it's gone - if [ -e "${P_ROOT}/_$1" ]; then - fail "failed to completely remove personality '$1'"; - fi -} - -############################################################################## -# pers_add -# -# Add a new file to the system; copy it from the 'real' path into -# each personality directory. Check first to make sure it's not already -# part of the system, and check that the path supplied is absolute. -# -# The file is stored with its full path relative to the repository -# directory. -# -pers_add() -{ - if [ ! -r "/$1" ]; then - fail "cannot read '$1' to add to the Personality System" - fi - if [ -e "${P_BASE}/$1" ]; then - fail "file '$1' already part of the Personality System" - fi - if [ ! -f "$1" ]; then - fail "only files can be added to the Personality System" - fi - - # looks OK, copy it in - stub=`dirname "$1"` - for targ in ${P_ROOT}/_*; do - mkdir -p "${targ}/${stub}" - cp -p "$1" "${targ}/${stub}" || pers_add_fail "$1"; - done -} - -######################################## -# pers_add_fail -# -# A failure occurred while adding a file to -# the repository; back out any copies that -# made it in and abort with an error. -# -pers_add_fail() -{ - for cand in ${P_ROOT}/_*; do - if [ -f "${cand}/$1" ]; then - rm -f "${cand}/$1"; - fi - done - fail "'$1' could not be added"; -} - -############################################################################## -# pers_remove -# -# Remove a file from all personalities in the repository. -# -pers_remove() -{ - if [ ! -f "${P_BASE}/$1" ]; then - fail "'$1' is not part of the Personality System"; - fi - - # OK, it should be there; nuke whatever we can find - for cand in ${P_ROOT}/_*; do - if [ -f "${cand}/$1" ]; then - rm -f "${cand}/$1"; - fi - done -} - -############################################################################## -# pers_list -# -# List all of the files that comprise the system personality. -# -pers_list() -{ - echo "Current personalities:" - for pers in `cat "${P_LIST}"`; do - echo " ${pers}"; - done - echo "Files in system personality:" - for file in `cat "${P_FILES}"`; do - echo " ${file}" - done -} - -############################################################################## -# pers_init -# -# Initialise the personality collection; refuse to do so if there is -# already one in place, or something else occupying the root path. -# -pers_init() -{ - if [ -e "${P_ROOT}" ]; then - fail "cannot initialise, '${P_ROOT}' already exists" - fi - - # Create the repository with no files, and no current personality - mkdir -p "${P_ROOT}" - mkdir -p "${P_BASE}" -} - -############################################################################## -# pers_reindex -# -# Clean out any empty directories in the repository. This is achieved -# by silently trying to rmdir everything that looks like a directory -# under any personality. -# -# Then rebuild the list of files that comprise the system personality, -# so that the select and menu functions work. -# -pers_reindex() -{ - # Remove empty directories - for cand in ${P_ROOT}/_*; do - find -dX "${cand}/." -type d | xargs rmdir >/dev/null 2>&1 - done - - # Regenerate the files list - find -X "${P_BASE}" -type f | sed "s%${P_BASE}%%" > "${P_FILES}" - # regenerate the personalities list - ls -d "${P_ROOT}/_"* | sed "s%${P_ROOT}/_%%" > "${P_LIST}" -} - -############################################################################## -# usage -# -# Emit a (hopefully) helpful diagnostic and exit -# -usage() -{ - echo "${scriptname}: incorrect argument(s)" - echo "" - echo " Usage is ${scriptname} , where valid commands are :" - echo " menu [] Invoke the menu-driven personality selector" - echo " select Select a specific personality" - echo " restore Restore the current personality from the saved version" - echo " save Save the current personality" - echo " saveas Save the current personality under a new name" - echo " create Create a new personality from the base" - echo " delete Delete a personality" - echo " add Add a new file" - echo " remove Remove a file" - echo " list List all files" - echo " init Initialise the Personality System" - echo "" - exit 2; -} - -############################################################################## -# fail -# -# Emit an error message to stderr and exit -# -fail () -{ - echo "${scriptname}: $1"; - exit 1; -} - -############################################################################## -# Now we have parsed everything, start. -pers_main $1 $2 $3 $4; -exit 0; Property changes on: head/sysutils/personality/src/personality ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sysutils/personality/Makefile =================================================================== --- head/sysutils/personality/Makefile (revision 404856) +++ head/sysutils/personality/Makefile (revision 404857) @@ -1,27 +1,23 @@ # Created by: Andreas Klemm # $FreeBSD$ PORTNAME= personality PORTVERSION= 1.0 CATEGORIES= sysutils +MASTER_SITES= # none DISTFILES= # none MAINTAINER= ports@FreeBSD.org COMMENT= System configuration management utility to alter system personality -WRKSRC= ${WRKDIR}/src -NO_BUILD= YES +NO_BUILD= yes +NO_ARCH= yes SUB_FILES= pkg-message -PLIST_FILES= man/man8/${PORTNAME}.8.gz sbin/personality +PLIST_FILES= man/man8/${PORTNAME}.8.gz sbin/${PORTNAME} -do-extract: - @ ${RM} -rf ${WRKDIR} - @ ${MKDIR} ${WRKDIR} - @ ${CP} -RP ${.CURDIR}/src ${WRKDIR} - do-install: - @ ${INSTALL_SCRIPT} ${WRKSRC}/${PORTNAME} ${STAGEDIR}${PREFIX}/sbin - @ ${INSTALL_DATA} ${WRKSRC}/${PORTNAME}.8 ${STAGEDIR}${PREFIX}/man/man8 + ${INSTALL_SCRIPT} ${FILESDIR}/${PORTNAME} ${STAGEDIR}${PREFIX}/sbin + ${INSTALL_DATA} ${FILESDIR}/${PORTNAME}.8 ${STAGEDIR}${PREFIX}/man/man8 .include Index: head/sysutils/personality/files/personality =================================================================== --- head/sysutils/personality/files/personality (nonexistent) +++ head/sysutils/personality/files/personality (revision 404857) @@ -0,0 +1,536 @@ +#! /bin/sh +############################################################################## +# +# Copyright (c) 1997 Michael Smith +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# +############################################################################## +# +# This script provides functionality for manipulating collections of +# configuration files which can be organised so as to alter the +# personality of a system. +# +# Initially, the "base" personality is established. This personality +# contains the "reference" copies of configuration files, and is used +# when creating new personalities. The files which are currently +# considered part of the system's personality are those contained in +# the base personality. +# +# A new personality is established by making a copy of the base +# personality under a new name. Each personality maintains a +# separate copy of all configuration files under /etc/personality. +# +# To install a new personality, the files currently in place are +# saved back to the current personality as indicated in +# /etc/personality/current, and the files for the new personality +# copied into place. The 'select' and 'menu' commands which perform +# these installations are implemented in such a fashion as to only +# require the tools available on the root filesystem, so that they +# may be invoked at the earliest stage during system startup. +# +# If the current personality has become damaged, it can be restored +# from the saved copy. +# +# Files can be added to and removed from the personality set. When +# a new file is added, it is copied from the current system into all +# personalities and added to the list file. When a file is removed +# the current version is kept in place, but all copies are removed +# from saved personalities and the file is removed from the list. +# +# XXX To Do : +# Files can be inherited by one personality from another. This is +# simply achieved by copying the relevant files under /etc/personality, +# and into the current system if required. +# +############################################################################## + +# Establish some global constants +P_ROOT=/etc/personality +#P_ROOT=/tmp/personality +P_BASE="${P_ROOT}/_base" +P_CURRENT="${P_ROOT}/current" +P_FILES="${P_ROOT}/files" +P_LIST="${P_ROOT}/list" +scriptname="$0" + +############################################################################## +# pers_main +# +# Execution begins here after the file has been read. +# +pers_main() +{ + case "$1" in + menu) + pers_menu $2 $3 + ;; + select) + pers_select $2 + ;; + restore) + pers_restore + ;; + save) + pers_save + ;; + saveas) + pers_saveas $2 + pers_reindex + ;; + create) + pers_create $2 + pers_reindex + ;; + delete) + pers_delete $2 + pers_reindex + ;; + add) + pers_add $2 + pers_reindex + ;; + list) + pers_list + ;; + remove) + pers_remove $2 + pers_reindex + ;; + init) + pers_init + pers_reindex + ;; + *) + usage + ;; + esac +} + +############################################################################## +# pers_menu +# +# Present a menu of currently-selectable personalities, assign hotkeys, +# describe the default and optionally go with the default after a timeout +# +pers_menu() +{ + # Look and see if there's actually anything to work with + if [ ! -d "${P_ROOT}" ]; then + return + fi + + # Pick up a timeout if specified, default to 10 seconds + timeout=10 + if [ ! -z "$1" ]; then + timeout="$1" + fi + + # Assign a default, if suitable + defpers="" + defname="" + if [ -f "${P_CURRENT}" ]; then + defpers=`cat "${P_CURRENT}"` + defname="${defpers}" + fi + + # Loop prompting/reading input until we get a result + while :; do + + # Print menu + echo ""; + echo "Select System Personality" + echo "=========================" + hkey=0 + for pers in `cat "${P_LIST}"`; do + echo " ${hkey}) ${pers}" + eval index_${hkey}="${pers}" + hkey=`expr ${hkey} + 1` + done + echo ""; + + echo " Default : ${defname}" + read -t "${timeout}" -p " Selection : " input + eval selvar=\$index_"${input}" + selpers="" + if [ -z "${input}" ]; then + selpers="${defpers}" + break + elif [ -n "${selvar}" ]; then + selpers="${selvar}" + break + elif [ -d "${P_ROOT}/_${input}" ]; then + selpers="${input}" + break + fi + done + + # $selpers now contains the personality we wish to select, + # or is empty if we selected the default when there was none + if [ -z "${selpers}" ]; then + return + fi + + # select the personality nominated + pers_select "${selpers}" +} + +############################################################################## +# pers_select +# +# Copy the files from the nominated personality out of the repository +# into the real system. Note that this must be able to run with +# nothing other than the contents of /bin available. +# +pers_select() +{ + src="${P_ROOT}/_$1"; + if [ ! -d "${src}" ]; then + fail "no such personality '$1'" + fi + + # Iterate over the file listing, copy them all out + for file in `cat "${P_FILES}"`; do + cp -p "${src}/${file}" "${file}" + done + + # Register this personality as being current + echo "$1" > "${P_CURRENT}" +} + +############################################################################## +# pers_restore +# +# Reload the configuration files for the current personality, eliminating +# any changes that may have been made. +# +pers_restore() +{ + if [ ! -e "${P_CURRENT}" ]; then + fail "no personality currently active" + fi + + # Check that the current personality exists + pers=`cat "${P_CURRENT}"` + src="${P_ROOT}/_${pers}" + if [ ! -d "${src}" ]; then + fail "current personality '${pers}' not in the repository!" + fi + + # Iterate over the file listing, copy them all out + for file in `cat "${P_FILES}"`; do + cp -p "${src}/${file}" "${file}" + done +} + +############################################################################## +# pers_save +# +# If a personality is current, save the current set of files to that +# personality. +# +pers_save() +{ + if [ ! -e "${P_CURRENT}" ]; then + fail "no personality currently active" + fi + + # Check that the current personality exists + pers=`cat "${P_CURRENT}"` + dest="${P_ROOT}/_${pers}" + if [ ! -d "${dest}" ]; then + fail "current personality '${pers}' not in the repository!" + fi + + # OK, go ahead and save stuff. If this fails, we're + # moderately stuffed, so don't worry about it. + for file in `cat "${P_FILES}"`; do + stub=`dirname "${file}"` + mkdir -p "${dest}/${stub}" + cp -p "${file}" "${dest}/${file}" + done +} + +############################################################################## +# pers_saveas +# +# Take the currently-active set of configuration files, and save them as +# a new personality, set the new personality as current. +# +pers_saveas() +{ + dest="${P_ROOT}/_$1" + if [ -e "${dest}" ]; then + fail "cannot create new personality '$1', name already in use" + fi + + # Create the personality directory + mkdir -p "${dest}" || pers_saveas_fail "$1" + + # iterate over files to save, copy them in + for file in `cat "${P_FILES}"`; do + stub=`dirname "${file}"` + mkdir -p "${dest}/${stub}" + cp -p "${file}" "${dest}/${file}" || pers_saveas_fail $1 + done + + # new personality is current + echo "$1" > "${P_CURRENT}" +} + +######################################## +# pers_saveas_fail +# +# The 'save as' operation failed. Clean +# up and emit a failure message. +# +pers_saveas_fail() +{ + rm -Rf "${P_ROOT}/_$1" + fail "could not save current personality as '$1'" +} + +############################################################################## +# pers_create +# +# Create a new personality, duplicated from the current base personality +# +pers_create() +{ + if [ -e "${P_ROOT}/_$1" ]; then + fail "cannot create new personality '$1', name already in use" + fi + + # Ok, duplicate it + cp -Rp "${P_BASE}" "${P_ROOT}/_$1" || pers_create_fail "$1" +} + +######################################## +# pers_create_fail +# +# An attempt to create a personality failed. +# Clean up and exit with an error message. +# +pers_create_fail() +{ + rm -Rf "${P_ROOT}/_$1" + fail "'$1' could not be created" +} + +############################################################################## +# pers_delete +# +# Remove a personality from the system. It is legitimate to remove +# the current personality. +# +pers_delete() +{ + if [ ! -e "${P_ROOT}/_$1" ]; then + fail "no such personality '$1' to remove" + fi + if [ "$1" = _base ]; then + fail "cannot remove base personality" + fi + + # If the requested personality is current, remove the + # reference. + if [ -e "${P_CURRENT}" ]; then + if [ `cat "${P_CURRENT}"` = "$1" ]; then + rm -f "${P_CURRENT}" + fi + fi + + # Remove the repository entry + rm -Rf "${P_ROOT}/_$1"; + + # Make sure it's gone + if [ -e "${P_ROOT}/_$1" ]; then + fail "failed to completely remove personality '$1'"; + fi +} + +############################################################################## +# pers_add +# +# Add a new file to the system; copy it from the 'real' path into +# each personality directory. Check first to make sure it's not already +# part of the system, and check that the path supplied is absolute. +# +# The file is stored with its full path relative to the repository +# directory. +# +pers_add() +{ + if [ ! -r "/$1" ]; then + fail "cannot read '$1' to add to the Personality System" + fi + if [ -e "${P_BASE}/$1" ]; then + fail "file '$1' already part of the Personality System" + fi + if [ ! -f "$1" ]; then + fail "only files can be added to the Personality System" + fi + + # looks OK, copy it in + stub=`dirname "$1"` + for targ in ${P_ROOT}/_*; do + mkdir -p "${targ}/${stub}" + cp -p "$1" "${targ}/${stub}" || pers_add_fail "$1"; + done +} + +######################################## +# pers_add_fail +# +# A failure occurred while adding a file to +# the repository; back out any copies that +# made it in and abort with an error. +# +pers_add_fail() +{ + for cand in ${P_ROOT}/_*; do + if [ -f "${cand}/$1" ]; then + rm -f "${cand}/$1"; + fi + done + fail "'$1' could not be added"; +} + +############################################################################## +# pers_remove +# +# Remove a file from all personalities in the repository. +# +pers_remove() +{ + if [ ! -f "${P_BASE}/$1" ]; then + fail "'$1' is not part of the Personality System"; + fi + + # OK, it should be there; nuke whatever we can find + for cand in ${P_ROOT}/_*; do + if [ -f "${cand}/$1" ]; then + rm -f "${cand}/$1"; + fi + done +} + +############################################################################## +# pers_list +# +# List all of the files that comprise the system personality. +# +pers_list() +{ + echo "Current personalities:" + for pers in `cat "${P_LIST}"`; do + echo " ${pers}"; + done + echo "Files in system personality:" + for file in `cat "${P_FILES}"`; do + echo " ${file}" + done +} + +############################################################################## +# pers_init +# +# Initialise the personality collection; refuse to do so if there is +# already one in place, or something else occupying the root path. +# +pers_init() +{ + if [ -e "${P_ROOT}" ]; then + fail "cannot initialise, '${P_ROOT}' already exists" + fi + + # Create the repository with no files, and no current personality + mkdir -p "${P_ROOT}" + mkdir -p "${P_BASE}" +} + +############################################################################## +# pers_reindex +# +# Clean out any empty directories in the repository. This is achieved +# by silently trying to rmdir everything that looks like a directory +# under any personality. +# +# Then rebuild the list of files that comprise the system personality, +# so that the select and menu functions work. +# +pers_reindex() +{ + # Remove empty directories + for cand in ${P_ROOT}/_*; do + find -dX "${cand}/." -type d | xargs rmdir >/dev/null 2>&1 + done + + # Regenerate the files list + find -X "${P_BASE}" -type f | sed "s%${P_BASE}%%" > "${P_FILES}" + # regenerate the personalities list + ls -d "${P_ROOT}/_"* | sed "s%${P_ROOT}/_%%" > "${P_LIST}" +} + +############################################################################## +# usage +# +# Emit a (hopefully) helpful diagnostic and exit +# +usage() +{ + echo "${scriptname}: incorrect argument(s)" + echo "" + echo " Usage is ${scriptname} , where valid commands are :" + echo " menu [] Invoke the menu-driven personality selector" + echo " select Select a specific personality" + echo " restore Restore the current personality from the saved version" + echo " save Save the current personality" + echo " saveas Save the current personality under a new name" + echo " create Create a new personality from the base" + echo " delete Delete a personality" + echo " add Add a new file" + echo " remove Remove a file" + echo " list List all files" + echo " init Initialise the Personality System" + echo "" + exit 2; +} + +############################################################################## +# fail +# +# Emit an error message to stderr and exit +# +fail () +{ + echo "${scriptname}: $1"; + exit 1; +} + +############################################################################## +# Now we have parsed everything, start. +pers_main $1 $2 $3 $4; +exit 0; Property changes on: head/sysutils/personality/files/personality ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sysutils/personality/files/personality.8 =================================================================== --- head/sysutils/personality/files/personality.8 (nonexistent) +++ head/sysutils/personality/files/personality.8 (revision 404857) @@ -0,0 +1,72 @@ +.\" Copyright (c) 2000 +.\" Andreas Klemm . All rights reserved. +.\" +.\" $FreeBSD$ +.\" +.Dd March 25, 2001 +.Dt PERSONALITY 8 +.Os +.Sh NAME +.Nm personality +.Nd system configuration management utility +.Sh SYNOPSIS +.Nm personality +.Op options ... +.Sh DESCRIPTION +This script provides functionality for manipulating collections of +configuration files which can be organised so as to alter the +personality of a system. +.Pp +Initially, the +.Ic base +personality is established. This personality contains the +.Ic reference +copies of configuration files, and is used when creating new personalities. +The files which are currently considered part of the system's personality +are those contained in the base personality. +.Pp +A new personality is established by making a copy of the base personality +under a new name. Each personality maintains a separate copy of all +configuration files under +.Ic /etc/personality . +.Pp +To install a new personality, the files currently in place are saved back +to the current personality as indicated in +.Ic /etc/personality/current , +and the files for the new personality copied into place. +.Pp +The +.Ic select +and +.Ic menu +commands which perform these installations are implemented in such a +fashion as to only require the tools available on the root filesystem, +so that they may be invoked at the earliest stage during system startup. +.Pp +If the current personality has become damaged, it can be restored +from the saved copy. +.Pp +Files can be added to and removed from the personality set. When a new +file is added, it is copied from the current system into all personalities +and added to the list file. When a file is removed the current version is +kept in place, but all copies are removed from saved personalities and the +file is removed from the list. +.Sh FILES +.Bl -tag -width /etc/personality/current -compact +.It Pa /etc/personality +configuration base +.It Pa /etc/personality/_base +system files under management of personality +.It Pa /etc/personality/current +backup location of current files before new personality is copied into place +.Sh SEE ALSO +.Xr rc 8 +.Sh BUGS +Currently none. +.Sh HISTORY +The +.Nm +script has been written 1997 by Mike Smith . +The +.Nm +manual page has been written by Andreas Klemm . Property changes on: head/sysutils/personality/files/personality.8 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/textproc/mkcatalog/scripts/configure =================================================================== --- head/textproc/mkcatalog/scripts/configure (revision 404856) +++ head/textproc/mkcatalog/scripts/configure (nonexistent) @@ -1,12 +0,0 @@ -#!/bin/sh -# $FreeBSD$ -# - -for i in ${CONFIGURE_TARGETS} -do - if [ -f ${WRKDIR}/${i}.in ]; then - cat ${WRKDIR}/${i}.in | /usr/bin/sed \ - -e "s;@@PREFIX@@;${PREFIX};g" \ - > ${WRKDIR}/${i} - fi -done Property changes on: head/textproc/mkcatalog/scripts/configure ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/textproc/mkcatalog/src/mkcatalog.in =================================================================== --- head/textproc/mkcatalog/src/mkcatalog.in (revision 404856) +++ head/textproc/mkcatalog/src/mkcatalog.in (nonexistent) @@ -1,293 +0,0 @@ -#!/bin/sh -# -# mkcatalog - script for making sgml catalog file. -# -# Created: 20001015 Shigeyuki Fukushima . -# Modified: 20001019 Hiroki Sato . -# -# $FreeBSD$ -# -sh_basename () -{ - l_value=$1 - IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old} - case $# in - 0) ;; - *) echo `eval echo \\$$#` ;; - esac -} - -sh_dirname () -{ - l_value=$1 - IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old} - l_dirname=$1; shift; - while - case $# in - 0) break ;; - 1) echo ${l_dirname}; break ;; - *) ;; - esac; - do - l_dirname="${l_dirname}/$1"; - shift; - done -} - -norm_dir () -{ - [ -d "$1" ] && echo `exec 2>/dev/null; cd $1; echo ${PWD}` -} - -verbose_msg () -{ - case ${F_VERBOSE} in - 1) echo " ===> $*" ;; - *) ;; - esac -} - -PREFIX=@@PREFIX@@ -TMPDIR=/tmp -ARGV0=`sh_basename $0` - -# default top-level catalog file -CAT_DIR=${PREFIX}/share/sgml -CAT_FILE=catalog - -F_PRESERVE_OLD="" -F_VERBOSE="" -args=`getopt pqvc: $*` ; set -- $args -for i -do - case "$i" in - -c) CAT_DIR=`sh_dirname $2`; - CAT_FILE=`sh_basename $2`; - shift; shift ;; - -p) F_PRESERVE_OLD=1; shift ;; - -q) exec 1> /dev/null 2>&1; shift ;; - -v) F_VERBOSE=1; shift ;; - --) shift; break ;; - esac -done - -dtd_act=$1 -dtd_dir=$2 -dtd_catalog=`sh_basename "$3"` - -### option check and normalize ${dtd_dir} -case "${dtd_act}" in -add|install|delete|deinstall|enable|disable) - if [ ! -d "${CAT_DIR}" ]; then - echo "${ARGV0}: top-level catalog dir \"${CAT_DIR}\" not found." - exit 1 - elif [ ! -n "${dtd_dir}" ]; then - echo "${ARGV0}: DTD directory is not specified." - exit 1 - elif [ ! -d "${CAT_DIR}/${dtd_dir}"\ - -a ! -d "${dtd_dir}" ]; then - echo "${ARGV0}: DTD directory \"${dtd_dir}\" not found." - exit 1 - elif [ ! -f "${CAT_DIR}/${dtd_dir}/${dtd_catalog:-catalog}"\ - -a ! -f "${dtd_dir}/${dtd_catalog:-catalog}" ]; then - echo "${ARGV0}: DTD catalog \"${dtd_dir}/${dtd_catalog:-catalog}\" not found." - exit 1 - fi - verbose_msg "top-level catalog dir (specified): ${CAT_DIR}" - CAT_DIR=`norm_dir ${CAT_DIR}` - verbose_msg "top-level catalog dir (normalized): ${CAT_DIR}" - verbose_msg "target catalog dir (specified): ${dtd_dir}" - dtd_dir=`norm_dir ${CAT_DIR}/${dtd_dir} || norm_dir ${dtd_dir}` - verbose_msg "target catalog dir (normalized): ${dtd_dir}" - - case "${dtd_dir}" in - ${CAT_DIR}/*) ;; - *) echo "${ARGV0}: DTD directory \"${dtd_dir}\" is invalid." - exit 1 ;; - esac - ### keep dtd_dir relative - dtd_dir=${dtd_dir#"${CAT_DIR}/"} - ;; -*) - echo "${ARGV0}: missing options." - cat < relative path from ${CAT_DIR} - # l_lower_cat -> relative path from l_upper - l_upper_cat=${l_upper}/${CAT_FILE} - l_lower_cat=`sh_basename ${l_lower}`/${catalog} - - # l_*_abs_* -> absolute path respectively - l_upper_abs=${CAT_DIR}/${l_upper} - l_lower_abs=${CAT_DIR}/${l_lower} - l_upper_abs_cat=${CAT_DIR}/${l_upper}/${CAT_FILE} - l_lower_abs_cat=${CAT_DIR}/${l_lower}/${catalog} - - # for debug - #echo ${l_bottom_p} ${l_upper_cat} ${l_lower_cat} - - l_cat_line="CATALOG \"${l_lower_cat}\"" - l_abs_path_head=`cd ${l_upper_abs}; echo ${PWD}` - - # for debug - #echo ${l_cat_line} - - # first, create temporary catalog from l_upper_cat - # not including CATALOG line of l_lower_cat (if no catalog, - # create empty one). - # - # NOTE: file manipulations require absolute path, but - # CATALOG line do relative from upper's one. - # - touch ${l_upper_abs_cat} || exit 1 - grep -v "\( *-- *\)\?CATALOG *\"\(${l_abs_path_head}/\)\?${l_lower_cat}\"\( *-- *\)\?" ${l_upper_abs_cat} > ${TMPCAT} - - # preserve old catalog as necessary - if [ "x${F_PRESERVE_OLD}" != "x" ]; then - cp ${l_upper_abs_cat} ${l_upper_abs_cat}.old || exit 1 - fi - - case "${dtd_act}" in - add|install|enable) - # - # if "install or add or enable", - # create "the tamporary catalog + l_cat_line" and install it. - # - echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}" - echo "${l_cat_line}" >> ${TMPCAT} - cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 - ;; - disable) - # - # if "disable", install the same above but l_cat_line is - # commented out. - # - case ${first_p} in - [Yy][Ee][Ss]) - echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}" - echo "-- ${l_cat_line} --" >> ${TMPCAT} - cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 - ;; - *) rm -f ${TMPCAT}; - exit 0; - ;; - esac - ;; - delete|deinstall) - # - # if "deinstall or delete" and the temporary catalog is - # not empty, install the catalog itself (in the case of being - # empty, delete it). ${l_bottom_p}=YES means that - # ${l_upper_cat} can be deleted safely, otherwise not. - # - case ${l_bottom_p} in - [Yy][Ee][Ss]) - echo " - ${dtd_act} ${l_cat_line} line from ${l_upper_cat}" - if [ ! -s ${TMPCAT} ]; then - echo " - delete empty catalog ${l_upper_cat}" - rm -f ${l_upper_abs_cat} - else - cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 - fi - ;; - *) rm -f ${TMPCAT}; - exit 0; - ;; - esac - ;; - esac - - # - # when flag "preserve old" is specified but - # there is no difference between new file and old one, - # preservation is silently denied. - # - if [ "x${F_PRESERVE_OLD}" != "x" ] && \ - cmp -s ${l_upper_abs_cat}.old ${l_upper_abs_cat}; then - rm -f ${l_upper_abs_cat}.old - fi - rm -f ${TMPCAT} -} - -compose_dir_list () -{ - l_dir=$1 - # - # Creates dirlist such as the following. - # input: docbook/4.1/my_extension - # return: docbook/4.1/my_extension docbook/4.1 docbook - # - IFS_old=${IFS}; IFS=" /"; set -- ${l_dir} - l_dir_top=$1; - shift; - l_dir_rest=$*; - IFS=${IFS_old} - - l_dir_item=${l_dir_top} - l_dir_list=${l_dir_top} - - for i in ${l_dir_rest} - do - l_dir_item="${l_dir_item}/${i}" - l_dir_list="${l_dir_item} ${l_dir_list}" - done - echo ${l_dir_list} -} - -bottom_p=YES -first_p=YES - -set -- `compose_dir_list ${dtd_dir}` . -verbose_msg "process catalog (relative to top one): $*" -while - case $# in - 1) break ;; - *) ;; - esac; -do - lower=$1 - upper=$2 - proc_catalog "${bottom_p}" "${upper}" "${lower}" - - first_p=NO - if [ -f ${CAT_DIR}/${upper}/${CAT_FILE} ]; then - bottom_p=NO - fi - shift; -done - -exit 0; Property changes on: head/textproc/mkcatalog/src/mkcatalog.in ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/textproc/mkcatalog/Makefile =================================================================== --- head/textproc/mkcatalog/Makefile (revision 404856) +++ head/textproc/mkcatalog/Makefile (revision 404857) @@ -1,31 +1,25 @@ # Created by: shige # $FreeBSD$ PORTNAME= mkcatalog PORTVERSION= 1.1 CATEGORIES= textproc MASTER_SITES= # none DISTFILES= # none EXTRACT_ONLY= # none MAINTAINER= ports@FreeBSD.org COMMENT= Maintenance utility for sgml catalog files NO_WRKSUBDIR= yes NO_BUILD= yes +NO_ARCH= yes + +SUB_FILES= mkcatalog PLIST_FILES= sbin/mkcatalog -SCRIPTS_ENV= CONFIGURE_TARGETS=${CONFIGURE_TARGETS} -SRC= ${.CURDIR}/src -CONFIGURE_TARGETS= mkcatalog - -pre-configure: -.for f in ${CONFIGURE_TARGETS} - ${CP} ${SRC}/${f}.in ${WRKDIR} -.endfor - do-install: - @${INSTALL_SCRIPT} ${WRKDIR}/mkcatalog \ + ${INSTALL_SCRIPT} ${WRKDIR}/mkcatalog \ ${STAGEDIR}${PREFIX}/sbin/mkcatalog .include Index: head/textproc/mkcatalog/files/mkcatalog.in =================================================================== --- head/textproc/mkcatalog/files/mkcatalog.in (nonexistent) +++ head/textproc/mkcatalog/files/mkcatalog.in (revision 404857) @@ -0,0 +1,293 @@ +#!/bin/sh +# +# mkcatalog - script for making sgml catalog file. +# +# Created: 20001015 Shigeyuki Fukushima . +# Modified: 20001019 Hiroki Sato . +# +# $FreeBSD$ +# +sh_basename () +{ + l_value=$1 + IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old} + case $# in + 0) ;; + *) echo `eval echo \\$$#` ;; + esac +} + +sh_dirname () +{ + l_value=$1 + IFS_old=${IFS}; IFS=" /"; set -- ${l_value}; IFS=${IFS_old} + l_dirname=$1; shift; + while + case $# in + 0) break ;; + 1) echo ${l_dirname}; break ;; + *) ;; + esac; + do + l_dirname="${l_dirname}/$1"; + shift; + done +} + +norm_dir () +{ + [ -d "$1" ] && echo `exec 2>/dev/null; cd $1; echo ${PWD}` +} + +verbose_msg () +{ + case ${F_VERBOSE} in + 1) echo " ===> $*" ;; + *) ;; + esac +} + +PREFIX=%%PREFIX%% +TMPDIR=/tmp +ARGV0=`sh_basename $0` + +# default top-level catalog file +CAT_DIR=${PREFIX}/share/sgml +CAT_FILE=catalog + +F_PRESERVE_OLD="" +F_VERBOSE="" +args=`getopt pqvc: $*` ; set -- $args +for i +do + case "$i" in + -c) CAT_DIR=`sh_dirname $2`; + CAT_FILE=`sh_basename $2`; + shift; shift ;; + -p) F_PRESERVE_OLD=1; shift ;; + -q) exec 1> /dev/null 2>&1; shift ;; + -v) F_VERBOSE=1; shift ;; + --) shift; break ;; + esac +done + +dtd_act=$1 +dtd_dir=$2 +dtd_catalog=`sh_basename "$3"` + +### option check and normalize ${dtd_dir} +case "${dtd_act}" in +add|install|delete|deinstall|enable|disable) + if [ ! -d "${CAT_DIR}" ]; then + echo "${ARGV0}: top-level catalog dir \"${CAT_DIR}\" not found." + exit 1 + elif [ ! -n "${dtd_dir}" ]; then + echo "${ARGV0}: DTD directory is not specified." + exit 1 + elif [ ! -d "${CAT_DIR}/${dtd_dir}"\ + -a ! -d "${dtd_dir}" ]; then + echo "${ARGV0}: DTD directory \"${dtd_dir}\" not found." + exit 1 + elif [ ! -f "${CAT_DIR}/${dtd_dir}/${dtd_catalog:-catalog}"\ + -a ! -f "${dtd_dir}/${dtd_catalog:-catalog}" ]; then + echo "${ARGV0}: DTD catalog \"${dtd_dir}/${dtd_catalog:-catalog}\" not found." + exit 1 + fi + verbose_msg "top-level catalog dir (specified): ${CAT_DIR}" + CAT_DIR=`norm_dir ${CAT_DIR}` + verbose_msg "top-level catalog dir (normalized): ${CAT_DIR}" + verbose_msg "target catalog dir (specified): ${dtd_dir}" + dtd_dir=`norm_dir ${CAT_DIR}/${dtd_dir} || norm_dir ${dtd_dir}` + verbose_msg "target catalog dir (normalized): ${dtd_dir}" + + case "${dtd_dir}" in + ${CAT_DIR}/*) ;; + *) echo "${ARGV0}: DTD directory \"${dtd_dir}\" is invalid." + exit 1 ;; + esac + ### keep dtd_dir relative + dtd_dir=${dtd_dir#"${CAT_DIR}/"} + ;; +*) + echo "${ARGV0}: missing options." + cat < relative path from ${CAT_DIR} + # l_lower_cat -> relative path from l_upper + l_upper_cat=${l_upper}/${CAT_FILE} + l_lower_cat=`sh_basename ${l_lower}`/${catalog} + + # l_*_abs_* -> absolute path respectively + l_upper_abs=${CAT_DIR}/${l_upper} + l_lower_abs=${CAT_DIR}/${l_lower} + l_upper_abs_cat=${CAT_DIR}/${l_upper}/${CAT_FILE} + l_lower_abs_cat=${CAT_DIR}/${l_lower}/${catalog} + + # for debug + #echo ${l_bottom_p} ${l_upper_cat} ${l_lower_cat} + + l_cat_line="CATALOG \"${l_lower_cat}\"" + l_abs_path_head=`cd ${l_upper_abs}; echo ${PWD}` + + # for debug + #echo ${l_cat_line} + + # first, create temporary catalog from l_upper_cat + # not including CATALOG line of l_lower_cat (if no catalog, + # create empty one). + # + # NOTE: file manipulations require absolute path, but + # CATALOG line do relative from upper's one. + # + touch ${l_upper_abs_cat} || exit 1 + grep -v "\( *-- *\)\?CATALOG *\"\(${l_abs_path_head}/\)\?${l_lower_cat}\"\( *-- *\)\?" ${l_upper_abs_cat} > ${TMPCAT} + + # preserve old catalog as necessary + if [ "x${F_PRESERVE_OLD}" != "x" ]; then + cp ${l_upper_abs_cat} ${l_upper_abs_cat}.old || exit 1 + fi + + case "${dtd_act}" in + add|install|enable) + # + # if "install or add or enable", + # create "the tamporary catalog + l_cat_line" and install it. + # + echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}" + echo "${l_cat_line}" >> ${TMPCAT} + cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 + ;; + disable) + # + # if "disable", install the same above but l_cat_line is + # commented out. + # + case ${first_p} in + [Yy][Ee][Ss]) + echo " - ${dtd_act} ${l_cat_line} line in ${l_upper_cat}" + echo "-- ${l_cat_line} --" >> ${TMPCAT} + cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 + ;; + *) rm -f ${TMPCAT}; + exit 0; + ;; + esac + ;; + delete|deinstall) + # + # if "deinstall or delete" and the temporary catalog is + # not empty, install the catalog itself (in the case of being + # empty, delete it). ${l_bottom_p}=YES means that + # ${l_upper_cat} can be deleted safely, otherwise not. + # + case ${l_bottom_p} in + [Yy][Ee][Ss]) + echo " - ${dtd_act} ${l_cat_line} line from ${l_upper_cat}" + if [ ! -s ${TMPCAT} ]; then + echo " - delete empty catalog ${l_upper_cat}" + rm -f ${l_upper_abs_cat} + else + cp ${TMPCAT} ${l_upper_abs_cat} || exit 1 + fi + ;; + *) rm -f ${TMPCAT}; + exit 0; + ;; + esac + ;; + esac + + # + # when flag "preserve old" is specified but + # there is no difference between new file and old one, + # preservation is silently denied. + # + if [ "x${F_PRESERVE_OLD}" != "x" ] && \ + cmp -s ${l_upper_abs_cat}.old ${l_upper_abs_cat}; then + rm -f ${l_upper_abs_cat}.old + fi + rm -f ${TMPCAT} +} + +compose_dir_list () +{ + l_dir=$1 + # + # Creates dirlist such as the following. + # input: docbook/4.1/my_extension + # return: docbook/4.1/my_extension docbook/4.1 docbook + # + IFS_old=${IFS}; IFS=" /"; set -- ${l_dir} + l_dir_top=$1; + shift; + l_dir_rest=$*; + IFS=${IFS_old} + + l_dir_item=${l_dir_top} + l_dir_list=${l_dir_top} + + for i in ${l_dir_rest} + do + l_dir_item="${l_dir_item}/${i}" + l_dir_list="${l_dir_item} ${l_dir_list}" + done + echo ${l_dir_list} +} + +bottom_p=YES +first_p=YES + +set -- `compose_dir_list ${dtd_dir}` . +verbose_msg "process catalog (relative to top one): $*" +while + case $# in + 1) break ;; + *) ;; + esac; +do + lower=$1 + upper=$2 + proc_catalog "${bottom_p}" "${upper}" "${lower}" + + first_p=NO + if [ -f ${CAT_DIR}/${upper}/${CAT_FILE} ]; then + bottom_p=NO + fi + shift; +done + +exit 0; Property changes on: head/textproc/mkcatalog/files/mkcatalog.in ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property