FFrreeeeBBSSDD HHaannddbbooookk The FreeBSD Documentation Project July 1998 AAbbssttrraacctt Welcome to FreeBSD! This handbook covers the installation and day to day use of FFrreeeeBBSSDD RReelleeaassee 22..22..77. This manual is a wwoorrkk iinn pprrooggrreessss and is the work of many individuals. Many sections do not yet exist and some of those that do exist need to be updated. If you are interested in helping with this project, send email to the FreeBSD documentation project mailing list The latest version of this document is always available from the FreeBSD World Wide Web server1 . It may also be downloaded in plain text2 , postscript3 , PDF or HTML4 with HTTP or gzip'd from the FreeBSD FTP server5 . or one of the numerous _m_i_r_r_o_r _s_i_t_e_s (section 25.2, page 446). You may also want to Search the Handbook6 . ____________________ 1. 2. 3. 4. 5. 6. FreeBSD Handbook 1 FreeBSD Handbook 2 Part I Getting Started _1_. _I_n_t_r_o_d_u_c_t_i_o_n FreeBSD is a 4.4BSD-Lite based operating system for Intel architecture (x86) based PCs. For an overview of FreeBSD, see _F_r_e_e_B_S_D _i_n _a _n_u_t_s_h_e_l_l (section 1.1, page 2). For a history of the project, read _a _b_r_i_e_f _h_i_s_t_o_r_y _o_f _F_r_e_e_B_S_D (sec tion 1.2, page 5). To see a description of the latest release, read _a_b_o_u_t _t_h_e _c_u_r_r_e_n_t _r_e_l_e_a_s_e (section 1.5, page 8). If you're interested in contributing something to the FreeBSD project (code, equipment, sacks of unmarked bills), please see about _c_o_n_t_r_i_b_u_t_i_n_g _t_o _F_r_e_e_B_S_D (section 19., page 375). _1_._1 _F_r_e_e_B_S_D _i_n _a _N_u_t_s_h_e_l_l FreeBSD is a state of the art operating system for personal computers based on the Intel CPU architecture, which includes the 386, 486 and Pentium processors (both SX and DX versions). Intel compatible CPUs from AMD and Cyrix are sup ported as well. FreeBSD provides you with many advanced features previously available only on much more expensive computers. These features include: PPrreeeemmppttiivvee mmuullttiittaasskkiinngg with dynamic priority adjustment to ensure smooth and fair sharing of the computer between applications and users. MMuullttiiuusseerr access means that many people can use a FreeBSD system simulta neously for a variety of things. System peripherals such as printers and tape drives are also properly SHARED BETWEEN ALL users on the system. Complete TTCCPP//IIPP nneettwwoorrkkiinngg including SLIP, PPP, NFS and NIS support. This means that your FreeBSD machine can inter-operate easily with other sys tems as well act as an enterprise server, providing vital functions such as NFS (remote file access) and e-mail services or putting your organiza tion on the Internet with WWW, ftp, routing and firewall (security) ser vices. MMeemmoorryy pprrootteeccttiioonn ensures that applications (or users) cannot interfere with each other. One application crashing will not affect others in any way. FreeBSD is a 3322--bbiitt operating system and was designed as such from the ground up. The industry standard XX WWiinnddooww SSyysstteemm (X11R6) provides a graphical user interface (GUI) for the cost of a common VGA card and monitor and comes with full sources. FreeBSD Handbook 3 BBiinnaarryy ccoommppaattiibbiilliittyy with many programs built for SCO, BSDI, NetBSD, Linux and 386BSD. Hundreds of rreeaaddyy--ttoo--rruunn applications are available from the FreeBSD ppoorrttss and ppaacckkaaggeess collection. Why search the net when you can find it all right here? Thousands of additional and eeaassyy--ttoo--ppoorrtt applications available on the Internet. FreeBSD is source code compatible with most popular commercial Unix systems and thus most applications require few, if any, changes to compile. Demand paged vviirrttuuaall mmeemmoorryy and `merged VM/buffer cache' design effi ciently satisfies applications with large appetites for memory while still maintaining interactive response to other users. SShhaarreedd lliibbrraarriieess (the Unix equivalent of MS-Windows DLLs) provide for efficient use of disk space and memory. A full complement of CC, CC++++ and FFoorrttrraann development tools. Many addi tional languages for advanced research and development are also available in the ports and packages collection. SSoouurrccee ccooddee for the entire system means you have the greatest degree of control over your environment. Why be locked into a proprietary solution and at the mercy of your vendor when you can have a truly Open System? Extensive oonn--lliinnee ddooccuummeennttaattiioonn. AAnndd mmaannyy mmoorree!! FreeBSD is based on the 4.4BSD-Lite release from Computer Systems Research Group (CSRG) at the University of California at Berkeley, and carries on the distinguished tradition of BSD systems development. In addition to the fine work provided by CSRG, the FreeBSD Project has put in many thousands of hours in fine tuning the system for maximum performance and reliability in real-life load situations. As many of the commercial giants struggle to field PC operat ing systems with such features, performance and reliability, FreeBSD can offer them nnooww! The applications to which FreeBSD can be put are truly limited only by your own imagination. From software development to factory automation, inventory con trol to azimuth correction of remote satellite antennae; if it can be done with a commercial UNIX product then it is more than likely that you can do it with FreeBSD, too! FreeBSD also benefits significantly from the literally thousands of high quality applications developed by research centers and universities around the world, often available at little to no cost. Commercial applica tions are also available and appearing in greater numbers every day. Because the source code for FreeBSD itself is generally available, the system can also be customized to an almost unheard of degree for special applications or projects, and in ways not generally possible with operating systems from most major commercial vendors. Here is just a sampling of some of the applica tions in which people are currently using FreeBSD: FreeBSD Handbook 4 IInntteerrnneett SSeerrvviicceess:: The robust TCP/IP networking built into FreeBSD makes it an ideal platform for a variety of Internet services such as: FTP servers World Wide Web servers Gopher servers Electronic Mail servers USENET News Bulletin Board Systems And more... You can easily start out small with an inexpensive 386 class PC and upgrade as your enterprise grows. EEdduuccaattiioonn:: Are you a student of computer science or a related engineering field? There is no better way of learning about operating systems, com puter architecture and networking than the hands on, under the hood expe rience that FreeBSD can provide. A number of freely available CAD, mathe matical and graphic design packages also make it highly useful to those whose primary interest in a computer is to get _o_t_h_e_r work done! RReesseeaarrcchh:: With source code for the entire system available, FreeBSD is an excellent platform for research in operating systems as well as other branches of computer science. FreeBSD's freely available nature also makes it possible for remote groups to collaborate on ideas or shared development without having to worry about special licensing agreements or limitations on what may be discussed in open forums. NNeettwwoorrkkiinngg:: Need a new router? A name server (DNS)? A firewall to keep people out of your internal network? FreeBSD can easily turn that unused 386 or 486 PC sitting in the corner into an advanced router with sophisti cated packet filtering capabilities. XX WWiinnddooww wwoorrkkssttaattiioonn:: FreeBSD is a fine choice for an inexpensive X termi nal solution, either using the freely available XFree86 server or one of the excellent commercial servers provided by X Inside. Unlike an X termi nal, FreeBSD allows many applications to be run locally, if desired, thus relieving the burden on a central server. FreeBSD can even boot "disk less", making individual workstations even cheaper and easier to adminis ter. SSooffttwwaarree DDeevveellooppmmeenntt:: The basic FreeBSD system comes with a full comple ment of development tools including the renowned GNU C/C++ compiler and debugger. FreeBSD is available in both source and binary form on CDROM and via anonymous ftp. See _O_b_t_a_i_n_i_n_g _F_r_e_e_B_S_D (section 25., page 445) for more details. FreeBSD Handbook 5 _1_._2 _A _B_r_i_e_f _H_i_s_t_o_r_y _o_f _F_r_e_e_B_S_D _C_o_n_t_r_i_b_u_t_e_d _b_y _J_o_r_d_a_n _K_. _H_u_b_b_a_r_d . The FreeBSD project had its genesis in the early part of 1993, partially as an outgrowth of the "Unofficial 386BSD Patchkit" by the patchkit's last 3 coordi nators: Nate Williams, Rod Grimes and myself. Our original goal was to produce an intermediate snapshot of 386BSD in order to fix a number of problems with it that the patchkit mechanism just was not capa ble of solving. Some of you may remember the early working title for the pro ject being "386BSD 0.5" or "386BSD Interim" in reference to that fact. 386BSD was Bill Jolitz's operating system, which had been up to that point suf fering rather severely from almost a year's worth of neglect. As the patchkit swelled ever more uncomfortably with each passing day, we were in unanimous agreement that something had to be done and decided to try and assist Bill by providing this interim "cleanup" snapshot. Those plans came to a rude halt when Bill Jolitz suddenly decided to withdraw his sanction from the project and without any clear indication of what would be done instead. It did not take us long to decide that the goal remained worthwhile, even with out Bill's support, and so we adopted the name "FreeBSD", coined by David Greenman. Our initial objectives were set after consulting with the system's current users and, once it became clear that the project was on the road to perhaps even becoming a reality, I contacted Walnut Creek CDROM with an eye towards improving FreeBSD's distribution channels for those many unfortunates without easy access to the Internet. Walnut Creek CDROM not only supported the idea of distributing FreeBSD on CD but went so far as to provide the project with a machine to work on and a fast Internet connection. Without Walnut Creek CDROM's almost unprecedented degree of faith in what was, at the time, a com pletely unknown project, it is quite unlikely that FreeBSD would have gotten as far, as fast, as it has today. The first CDROM (and general net-wide) distribution was FreeBSD 1.0, released in December of 1993. This was based on the 4.3BSD-Lite ("Net/2") tape from U.C. Berkeley, with many components also provided by 386BSD and the Free Soft ware Foundation. It was a fairly reasonable success for a first offering, and we followed it with the highly successful FreeBSD 1.1 release in May of 1994. Around this time, some rather unexpected storm clouds formed on the horizon as Novell and U.C. Berkeley settled their long-running lawsuit over the legal sta tus of the Berkeley Net/2 tape. A condition of that settlement was U.C. Berke ley's concession that large parts of Net/2 were "encumbered" code and the prop erty of Novell, who had in turn acquired it from AT&T some time previously. What Berkeley got in return was Novell's "blessing" that the 4.4BSD-Lite release, when it was finally released, would be declared unencumbered and all existing Net/2 users would be strongly encouraged to switch. This included FreeBSD, and the project was given until the end of July 1994 to stop shipping its own Net/2 based product. Under the terms of that agreement, the project was allowed one last release before the deadline, that release being FreeBSD 1.1.5.1. FreeBSD then set about the arduous task of literally re-inventing itself from a FreeBSD Handbook 6 completely new and rather incomplete set of 4.4BSD-Lite bits. The "Lite" releases were light in part because Berkeley's CSRG had removed large chunks of code required for actually constructing a bootable running system (due to vari ous legal requirements) and the fact that the Intel port of 4.4 was highly incomplete. It took the project until December of 1994 to make this transi tion, and in January of 1995 it released FreeBSD 2.0 to the net and on CDROM. Despite being still more than a little rough around the edges, the release was a significant success and was followed by the more robust and easier to install FreeBSD 2.0.5 release in June of 1995. We released FreeBSD 2.1.5 in August of 1996, and it appeared to be popular enough among the ISP and commercial communities that another release along the 2.1-stable branch was merited. This was FreeBSD 2.1.7.1, released in February 1997 and capping the end of mainstream development on 2.1-stable. Now in main tenance mode, only security enhancements and other critical bug fixes will be done on this branch (RELENG_2_1_0). FreeBSD 2.2 was branched from the development mainline ("-current") in November 1996 as the RELENG_2_2 branch, and the first full release (2.2.1) was released in April, 1997. Further releases along the 2.2 branch were done in the Summer and Fall of '97, the latest being 2.2.7 which appeared in late July of '98. The first official 3.0 release will appear in October, 1998 and the last release on the 2.2 branch, 2.2.8, will appear in November. Long term development projects for everything from SMP to DEC ALPHA support will continue to take place in the 3.0-current branch and SNAPshot releases of 3.0 on CDROM (and, of course, on the net). _1_._3 _F_r_e_e_B_S_D _P_r_o_j_e_c_t _G_o_a_l_s _C_o_n_t_r_i_b_u_t_e_d _b_y _J_o_r_d_a_n _K_. _H_u_b_b_a_r_d . The goals of the FreeBSD Project are to provide software that may be used for any purpose and without strings attached. Many of us have a significant investment in the code (and project) and would certainly not mind a little financial compensation now and then, but we're definitely not prepared to insist on it. We believe that our first and foremost "mission" is to provide code to any and all comers, and for whatever purpose, so that the code gets the widest possible use and provides the widest possible benefit. This is, I believe, one of the most fundamental goals of Free Software and one that we enthusiastically support. That code in our source tree which falls under the GNU Public License (GPL) or GNU Library Public License (GLPL) comes with slightly more strings attached, though at least on the side of enforced access rather than the usual opposite. Due to the additional complexities that can evolve in the commercial use of GPL software, we do, however, endeavor to replace such software with submissions under the more relaxed BSD copyright whenever possible. _1_._4 _T_h_e _F_r_e_e_B_S_D _D_e_v_e_l_o_p_m_e_n_t _M_o_d_e_l _C_o_n_t_r_i_b_u_t_e_d _b_y _S_a_t_o_s_h_i _A_s_a_m_i . The development of FreeBSD is a very open and flexible process, FreeBSD being FreeBSD Handbook 7 literally built from the contributions of hundreds of people around the world, as can be seen from our _l_i_s_t _o_f _c_o_n_t_r_i_b_u_t_o_r_s (section 28., page 477). We are constantly on the lookout for new developers and ideas, and those interested in becoming more closely involved with the project need simply contact us at the FreeBSD technical discussions mailing list . Those who prefer to work more independently are also accommodated, and they are free to use our FTP facilities at ftp.freebsd.org to distribute their own patches or work-in-progress sources. The FreeBSD announcements mailing list is also available to those wishing to make other FreeBSD users aware of major areas of work. Useful things to know about the FreeBSD project and its development process, whether working independently or in close cooperation: TThhee CCVVSS rreeppoossiittoorryy " The central source tree for FreeBSD is maintained by CVS (Concur rent Version System), a freely available source code control tool which comes bundled with FreeBSD. The primary CVS repository resides on a machine in Concord CA, USA from where it is replicated to numerous mirror machines throughout the world. The CVS tree, as well as the _-_c_u_r_r_e_n_t (section 18.1, page 350) and _-_s_t_a_b_l_e (section 18.2, page 352) trees which are checked out of it, can be easily replicated to your own machine as well. Please refer to the _S_y_n_ _c_h_r_o_n_i_z_i_n_g _y_o_u_r _s_o_u_r_c_e _t_r_e_e (section 18.3, page 355) section for more information on doing this. TThhee ccoommmmiitttteerrss lliisstt " The _c_o_m_m_i_t_t_e_r_s (section 28.2, page 478) are the people who have _w_r_i_t_e access to the CVS tree, and are thus authorized to make modi fications to the FreeBSD source (the term ``committer'' comes from the cvs(1) ``commit'' command, which is used to bring new changes into the CVS repository). The best way of making submissions for review by the committers list is to use the send-pr(1) command, though if something appears to be jammed in the system then you may also reach them by sending mail to committers@freebsd.org. TThhee FFrreeeeBBSSDD ccoorree tteeaamm " The _F_r_e_e_B_S_D _c_o_r_e _t_e_a_m (section 28.1, page 478) would be equivalent to the board of directors if the FreeBSD Project were a company. The primary task of the core team is to make sure the project, as a whole, is in good shape and is heading in the right directions. Inviting dedicated and responsible developers to join our group of committers is one of the functions of the core team, as is the recruitment of new core team members as others move on. Most cur rent members of the core team started as committers who's addiction to the project got the better of them. Some core team members also have specific _a_r_e_a_s _o_f _r_e_s_p_o_n_s_i_b_i_l_i_t_y FreeBSD Handbook 8 (section 28.4, page 483), meaning that they are committed to ensur ing that some large portion of the system works as advertised. Note that most members of the core team are volunteers when it comes to FreeBSD development and do not benefit from the project financially, so "commitment" should also not be misconstrued as meaning "guaranteed support." The ``board of directors'' analogy above is not actually very accurate, and it may be more suitable to say that these are the people who gave up their lives in favor of FreeBSD against their better judgement! ;) OOuuttssiiddee ccoonnttrriibbuuttoorrss Last, but definitely not least, the largest group of developers are the users themselves who provide feedback and bug-fixes to us on an almost constant basis. The primary way of keeping in touch with FreeBSD's more non-centralized development is to subscribe to the FreeBSD technical discussions mailing list (see _m_a_i_l_i_n_g _l_i_s_t _i_n_f_o (section 27.1, page 467)) where such things are discussed. _T_h_e _l_i_s_t (section 19.5, page 388) of those who have contributed something which made its way into our source tree is a long and growing one, so why not join it by contributing something back to FreeBSD today? :-) Providing code is not the only way of contributing to the project; for a more complete list of things that need doing, please refer to the _h_o_w _t_o _c_o_n_t_r_i_b_u_t_e (section 19., page 375) section in this hand book. In summary, our development model is organized as a loose set of concentric circles. The centralized model is designed for the convenience of the _u_s_e_r_s of FreeBSD, who are thereby provided with an easy way of tracking one central code base, not to keep potential contributors out! Our desire is to present a sta ble operating system with a large set of coherent _a_p_p_l_i_c_a_t_i_o_n _p_r_o_g_r_a_m_s (section 4., page 25) that the users can easily install and use, and this model works very well in accomplishing that. All we ask of those who would join us as FreeBSD developers is some of the same dedication its current people have to its continued success! _1_._5 _A_b_o_u_t _t_h_e _C_u_r_r_e_n_t _R_e_l_e_a_s_e FreeBSD is a freely available, full source 4.4BSD-Lite based release for Intel i386/i486/Pentium/PentiumPro/Pentium II (or compatible) based PC's. It is based primarily on software from U.C. Berkeley's CSRG group, with some enhance ments from NetBSD, OpenBSD, 386BSD, and the Free Software Foundation. Since our release of FreeBSD 2.0 in January of 95, the performance, feature set, and stability of FreeBSD has improved dramatically. The largest change is a revamped virtual memory system with a merged VM/file buffer cache that not only increases performance, but reduces FreeBSD's memory footprint, making a 5MB configuration a more acceptable minimum. Other enhancements include full NIS client and server support, transaction TCP support, dial-on-demand PPP, an FreeBSD Handbook 9 improved SCSI subsystem, early ISDN support, support for FDDI and Fast Ethernet (100Mbit) adapters, improved support for the Adaptec 2940 (WIDE and narrow) and many hundreds of bug fixes. We have also taken the comments and suggestions of many of our users to heart and have attempted to provide what we hope is a more sane and easily understood installation process. Your feedback on this (constantly evolving) process is especially welcome! In addition to the base distributions, FreeBSD offers a new ported software collection with hundreds of commonly sought-after programs. At the end of August 1998, there were more than 1700 ports! The list of ports ranges from http (WWW) servers, to games, languages, editors and almost everything in between. The entire ports collection requires approximately 26MB of storage, all ports being expressed as ``deltas'' to their original sources. This makes it much easier for us to update ports, and greatly reduces the disk space demands made by the older 1.0 ports collection. To compile a port, you simply change to the directory of the program you wish to install, type ``make all'' followed by ``make install'' after successful compilation and let the system do the rest. The full original distribution for each port you build is retrieved dynamically off the CDROM or a local ftp site, so you need only enough disk space to build the ports you want. (Almost) every port is also provided as a pre-compiled "package" which can be installed with a simple command (pkg_add) by those who do not wish to compile their own ports from source. A number of additional documents which you may find very helpful in the process of installing and using FreeBSD may now also be found in the //uussrr//sshhaarree//ddoocc directory on any machine running FreeBSD 2.1 or later. You may view the locally installed manuals with any HTML capable browser using the following URLs: The FreeBSD handbook The FreeBSD FAQ You can also visit the master (and most frequently updated) copies at http://www.freebsd.org. The core of FreeBSD does not contain DES code which would inhibit its being exported outside the United States. There is an add-on package to the core distribution, for use only in the United States, that contains the programs that normally use DES. The auxiliary packages provided separately can be used by anyone. A freely (from outside the U.S.) exportable European distribution of DES for our non-U.S. users also exists and is described in the FreeBSD FAQ. If password security for FreeBSD is all you need, and you have no requirement for copying encrypted passwords from different hosts (Suns, DEC machines, etc) into FreeBSD password entries, then FreeBSD's MD5 based security may be all you require! We feel that our default security model is more than a match for DES, and without any messy export issues to deal with. If you are outside (or even inside) the U.S., give it a try! FreeBSD Handbook 10 _2_. _I_n_s_t_a_l_l_i_n_g _F_r_e_e_B_S_D So, you would like to try out FreeBSD on your system? This section is a quick- start guide for what you need to do. FreeBSD can be installed from a variety of media including CD-ROM, floppy disk, magnetic tape, an MS-DOS partition and, if you have a network connection, via anonymous ftp or NFS. Regardless of the installation media you choose, you can get started by creat ing the iinnssttaallllaattiioonn ddiisskk as described below. Booting your computer into the FreeBSD installer, even if you aren't planning on installing FreeBSD right away, will provide important information about compatibility between FreeBSD and your hardware which may, in turn, dictate which installation options are even possible. It can also provide early clues to any compatibility problems which could prevent FreeBSD running on your system at all. If you plan on installing via anonymous FTP then this installation floppy is all that you will need to download and create - the installation program itself will handle any further required downloading directly (using an ethernet con nection, a modem and ppp dialup #, etc). For more information on obtaining the latest FreeBSD distributions, please see _O_b_t_a_i_n_i_n_g _F_r_e_e_B_S_D (section 25., page 445) in the Appendix. So, to get the show on the road, follow these steps: 1. Review the _s_u_p_p_o_r_t_e_d _c_o_n_f_i_g_u_r_a_t_i_o_n_s (section 2.1, page 13) section of this installation guide to be sure that your hardware is supported by FreeBSD. It may be helpful to make a list of any special cards you have installed, such as SCSI controllers, Ethernet adapters or sound cards. This list should include relevant configuration parameters such as inter rupts (IRQ) and IO port addresses. 2. If you're installing FreeBSD from CDROM media then you have several dif ferent installation options: If the CD has been mastered with El Torrito boot support and your system supports direct booting from CDROM (and many older systems do _n_o_t), simply insert the CD into the drive and boot directly from it. If you're running DOS and have the proper drivers to access your CD, run the install.bat script provided on the CD. This will attempt to boot into the FreeBSD installation straight from DOS (_n_o_t_e_: _Y_o_u _m_u_s_t _d_o _t_h_i_s _f_r_o_m _a_c_t_u_a_l _D_O_S _a_n_d _n_o_t _a _W_i_n_d_o_w_s _D_O_S _b_o_x). If you also want to install FreeBSD from your DOS partition (perhaps because your CDROM drive is completely unsupported by FreeBSD) then run the setup program first to copy the appropriate files from the CD to FreeBSD Handbook 11 your DOS partition, afterwards running install. If either of the two proceeding methods work then you can simply skip the rest of this section, otherwise your final option is to create a boot floppy from the floppies\boot.flp image - proceed to step 4 for instructions on how to do this. 3. If you don't have a CDROM distribution then simply download the installa tion boot disk image7 file to your hard drive, being sure to tell your browser to _s_a_v_e rather than _d_i_s_p_l_a_y the file. NNoottee:: This disk image can only be used with 1.44 megabyte 3.5 inch floppy disks. 4. Make the installation boot disk from the image file: If you are using MS-DOS then download fdimage.exe8 or get it from tools\fdimage.exe on the CDROM and then run it like so: E:\> tools\fdimage floppies\boot.flp a: The _f_d_i_m_a_g_e program will format the A: drive and then copy the boot.flp image onto it (assuming that you're at the top level of a FreeBSD distribution and the floppy images live in the floppies sub directory, as is typically the case). If you are using a UNIX system to create the floppy image: % dd if=boot.flp of=_d_i_s_k___d_e_v_i_c_e where _d_i_s_k___d_e_v_i_c_e is the /dev entry for the floppy drive. On FreeBSD systems, this is /dev/rfd0 for the A: drive and /dev/rfd1 for the B: drive. 5. With the installation disk in the A: drive, reboot your computer. You should get a boot prompt something like this: ____________________ 7. 8. FreeBSD Handbook 12 >> FreeBSD BOOT ... Usage: [[[0:][wd](0,a)]/kernel][-abcCdhrsv] Use 1:sd(0,a)kernel to boot sd0 if it is BIOS drive 1 Use ? for file list or press Enter for defaults Boot: If you do _n_o_t type anything, FreeBSD will automatically boot with its default configuration after a delay of about five seconds. As FreeBSD boots, it probes your computer to determine what hardware is installed. The results of this probing is displayed on the screen. 6. When the booting process is finished, The main FreeBSD installation menu will be displayed. IIff ssoommeetthhiinngg ggooeess wwrroonngg...... Due to limitations of the PC architecture, it is impossible for probing to be 100 percent reliable. In the event that your hardware is incorrectly identi fied, or that the probing causes your computer to lock up, first check the _s_u_p_ _p_o_r_t_e_d _c_o_n_f_i_g_u_r_a_t_i_o_n_s (section 2.1, page 13) section of this installation guide to be sure that your hardware is indeed supported by FreeBSD. If your hardware is supported, reset the computer and when the Boot: prompt comes up, type --cc. This puts FreeBSD into a configuration mode where you can supply hints about your hardware. The FreeBSD kernel on the installation disk is configured assuming that most hardware devices are in their factory default configuration in terms of IRQs, IO addresses and DMA channels. If your hard ware has been reconfigured, you will most likely need to use the --cc option at boot to tell FreeBSD where things are. It is also possible that a probe for a device not present will cause a later probe for another device that is present to fail. In that case, the probes for the conflicting driver(s) should be disabled. Do not disable any device you will need during installation, such as your screen (sc0). In the configuration mode, you can: List the device drivers installed in the kernel. Disable device drivers for hardware not present in your system. Change the IRQ, DRQ, and IO port addresses used by a device driver. While at the config> prompt, type help for more information on the available commands. After adjusting the kernel to match how you have your hardware con figured, type quit at the config> prompt to continue booting with the new set tings. FreeBSD Handbook 13 After FreeBSD has been installed, changes made in the configuration mode will be permanent so you do not have to reconfigure every time you boot. Even so, it is likely that you will want to build a custom kernel to optimize the per formance of your system. See _K_e_r_n_e_l _c_o_n_f_i_g_u_r_a_t_i_o_n (section 5., page 79) for more information on creating custom kernels. _2_._1 _S_u_p_p_o_r_t_e_d _C_o_n_f_i_g_u_r_a_t_i_o_n_s FreeBSD currently runs on a wide variety of ISA, VLB, EISA and PCI bus based PC's, ranging from 386sx to Pentium class machines (though the 386sx is not recommended). Support for generic IDE or ESDI drive configurations, various SCSI controller, network and serial cards is also provided. A minimum of four megabytes of RAM is required to run FreeBSD. To run the X Window System, eight megabytes of RAM is the recommended minimum. Following is a list of all disk controllers and Ethernet cards currently known to work with FreeBSD. Other configurations may very well work, and we have simply not received any indication of this. _2_._1_._1 _D_i_s_k _C_o_n_t_r_o_l_l_e_r_s WD1003 (any generic MFM/RLL) WD1007 (any generic IDE/ESDI) IDE ATA Adaptec 1505 ISA SCSI controller Adaptec 152x series ISA SCSI controllers Adaptec 1535 ISA SCSI controllers Adaptec 154x series ISA SCSI controllers Adaptec 174x series EISA SCSI controller in standard and enhanced mode. Adaptec 274x/284x/2940/2940U/3940 (Narrow/Wide/Twin) series EISA/VLB/PCI SCSI controllers Adaptec AIC7850 on-board SCSI controllers Adaptec AIC-6360 based boards, which includes the AHA-152x and Sound Blaster SCSI cards. NNoottee:: You cannot boot from the SoundBlaster cards as they have no on-board BIOS, which is necessary for mapping the boot device into the system BIOS I/O vectors. They are perfectly usable for external tapes, CDROMs, etc, however. The same goes for any other AIC-6x60 based card without a boot ROM. Some systems DO have a boot ROM, which is generally indicated by some sort of message when the system is first powered up or reset. Check FreeBSD Handbook 14 your system/board documentation for more details. Buslogic 545S & 545c NNoottee:: that Buslogic was formerly known as "Bustek". Buslogic 445S/445c VLB SCSI controller Buslogic 742A/747S/747c EISA SCSI controller. Buslogic 946c PCI SCSI controller Buslogic 956c PCI SCSI controller NCR 53C810/53C815/53C825/53C860/53C875 PCI SCSI controller. NCR5380/NCR53400 (``ProAudio Spectrum'') SCSI controller. DTC 3290 EISA SCSI controller in 1542 emulation mode. UltraStor 14F/24F/34F SCSI controllers. Seagate ST01/02 SCSI controllers. Future Domain 8xx/950 series SCSI controllers. WD7000 SCSI controllers. With all supported SCSI controllers, full support is provided for SCSI-I & SCSI-II peripherals, including Disks, tape drives (including DAT) and CD ROM drives. The following CD-ROM type systems are supported at this time: SoundBlaster SCSI and ProAudio Spectrum SCSI (cd) Mitsumi (all models) proprietary interface (mcd) Matsushita/Panasonic (Creative) CR-562/CR-563 proprietary interface (matcd) Sony proprietary interface (scd) ATAPI IDE interface (experimental and should be considered ALPHA quality!) (wcd) _2_._1_._2 _E_t_h_e_r_n_e_t _c_a_r_d_s Allied-Telesis AT1700 and RE2000 cards SMC Elite 16 WD8013 Ethernet interface, and most other WD8003E, WD8003EBT, WD8003W, WD8013W, WD8003S, WD8003SBT and WD8013EBT based clones. SMC Elite Ultra and 9432TX based cards are also supported. DEC EtherWORKS III NICs (DE203, DE204, and DE205) FreeBSD Handbook 15 DEC EtherWORKS II NICs (DE200, DE201, DE202, and DE422) DEC DC21040/DC21041/DC21140 based NICs: ASUS PCI-L101-TB Accton ENI1203 Cogent EM960PCI Compex CPXPCI/32C D-Link DE-530 DEC DE435 Danpex EN-9400P3 JCIS Condor JC1260 Kingston KNE100TX Linksys EtherPCI Mylex LNP101 SMC EtherPower 10/100 (Model 9332) SMC EtherPower (Model 8432) SMC EtherPower (2) Zynx ZX314 Zynx ZX342 DEC FDDI (DEFPA/DEFEA) NICs Fujitsu FMV-181 and FMV-182 Fujitsu MB86960A/MB86965A Intel EtherExpress Intel EtherExpress Pro/100B 100Mbit. Isolan AT 4141-0 (16 bit) Isolink 4110 (8 bit) Lucent WaveLAN wireless networking interface. Novell NE1000, NE2000, and NE2100 ethernet interface. FreeBSD Handbook 16 3Com 3C501 cards 3Com 3C503 Etherlink II 3Com 3c505 Etherlink/+ 3Com 3C507 Etherlink 16/TP 3Com 3C509, 3C579, 3C589 (PCMCIA) Etherlink III 3Com 3C590, 3C595 Etherlink III 3Com 3C90x cards. HP PC Lan Plus (27247B and 27252A) Toshiba ethernet cards PCMCIA ethernet cards from IBM and National Semiconductor are also sup ported. _N_o_t_e_: FreeBSD does not currently support PnP (plug-n-play) features present on some ethernet cards. If your card has PnP and is giving you problems, try dis abling its PnP features. _2_._1_._3 _M_i_s_c_e_l_l_a_n_e_o_u_s _d_e_v_i_c_e_s AST 4 port serial card using shared IRQ. ARNET 8 port serial card using shared IRQ. BOCA IOAT66 6 port serial card using shared IRQ. BOCA 2016 16 port serial card using shared IRQ. Cyclades Cyclom-y Serial Board. STB 4 port card using shared IRQ. SDL Communications Riscom/8 Serial Board. SDL Communications RISCom/N2 and N2pci sync serial cards. Digiboard Sync/570i high-speed sync serial card. Decision-Computer Intl. "Eight-Serial" 8 port serial cards using shared IRQ. Adlib, SoundBlaster, SoundBlaster Pro, ProAudioSpectrum, Gravis Ultra Sound, Gravis UltraSound MAX and Roland MPU-401 sound cards. Matrox Meteor video frame grabber. FreeBSD Handbook 17 Creative Labs Video spigot frame grabber. Omnimedia Talisman frame grabber. Brooktree BT848 chip based frame grabbers. X-10 power controllers. PC joystick and speaker. FreeBSD does not currently support IBM's microchannel (MCA) bus. _2_._2 _P_r_e_p_a_r_i_n_g _f_o_r _t_h_e _I_n_s_t_a_l_l_a_t_i_o_n There are a number of different methods by which FreeBSD can be installed. The following describes what preparation needs to be done for each type. _2_._2_._1 _B_e_f_o_r_e _i_n_s_t_a_l_l_i_n_g _f_r_o_m _C_D_R_O_M If your CDROM is of an unsupported type, then please skip to _M_S_-_D_O_S _P_r_e_p_a_r_a_t_i_o_n (section 2.2.3, page 19). There is not a lot of preparatory work that needs to be done to successfully install from one of Walnut Creek's FreeBSD CDROMs (other CDROM distributions may work as well, though we cannot say for certain as we have no hand or say in how they are created). You can either boot into the CD installation directly from DOS using Walnut Creek's supplied ``install.bat'' batch file or you can make a boot floppy with the ``makeflp.bat'' command. [NOTE: If you are run ning FreeBSD 2.1-RELEASE and have an IDE CDROM, use the inst_ide.bat or atapi flp.bat batch files instead]. For the easiest interface of all (from DOS), type ``view''. This will bring up a DOS menu utility that leads you through all the available options. If you are creating the boot floppy from a UNIX machine, see _t_h_e _b_e_g_i_n_n_i_n_g _o_f _t_h_i_s _g_u_i_d_e (section 2., page 10) for examples. of how to create the boot floppy. Once you have booted from DOS or floppy, you should then be able to select CDROM as the media type in the Media menu and load the entire distribution from CDROM. No other types of installation media should be required. After your system is fully installed and you have rebooted from the hard disk, you can mount the CDROM at any time by typing: mount /cdrom Before removing the CD again, also note that it is necessary to first type: umount /cdrom. Do not just remove it from the drive! SSppeecciiaall nnoottee:: Before invoking the installation, be sure that the CDROM is in the drive so that the install probe can find it. This is also true if you wish the CDROM to be added to the default system configuration automatically during the install (whether or not you actually use it as the installation media). FreeBSD Handbook 18 Finally, if you would like people to be able to FTP install FreeBSD directly from the CDROM in your machine, you will find it quite easy. After the machine is fully installed, you simply need to add the following line to the password file (using the vipw command): ftp:*:99:99::0:0:FTP:/cdrom:/nonexistent Anyone with network connectivity to your machine (and permission to log into it) can now chose a Media type of FTP and type in: ftp://_y_o_u_r _m_a_c_h_i_n_e after picking ``Other'' in the ftp sites menu. _2_._2_._2 _B_e_f_o_r_e _i_n_s_t_a_l_l_i_n_g _f_r_o_m _F_l_o_p_p_y If you must install from floppy disks, either due to unsupported hardware or simply because you enjoy doing things the hard way, you must first prepare some floppies for the install. You will need, at minimum, as many 1.44MB or 1.2MB floppies as it takes to hold all files in the bin (binary distribution) directory. If you are preparing these floppies under DOS, then THESE floppies *must* be formatted using the MS- DOS FORMAT command. If you are using Windows, use the Windows File Manager format command. Do _n_o_t trust Factory Preformatted floppies! Format them again yourself, just to make sure. Many problems reported by our users in the past have resulted from the use of improperly formatted media, which is why I am taking such spe cial care to mention it here! If you are creating the floppies from another FreeBSD machine, a format is still not a bad idea though you do not need to put a DOS filesystem on each floppy. You can use the `disklabel' and `newfs' commands to put a UFS filesys tem on them instead, as the following sequence of commands (for a 3.5" 1.44MB floppy disk) illustrates: fdformat -f 1440 fd0.1440 disklabel -w -r fd0.1440 floppy3 newfs -t 2 -u 18 -l 1 -i 65536 /dev/rfd0 (Use "fd0.1200" and "floppy5" for 5.25" 1.2MB disks). Then you can mount and write to them like any other file system. After you have formatted the floppies, you will need to copy the files onto them. The distribution files are split into chunks conveniently sized so that 5 of them will fit on a conventional 1.44MB floppy. Go through all your flop pies, packing as many files as will fit on each one, until you have got all the distributions you want packed up in this fashion. Each distribution should go into a subdirectory on the floppy, e.g.: aa::\\bbiinn\\bbiinn..aaaa, aa::\\bbiinn\\bbiinn..aabb, and so on. Once you come to the Media screen of the install, select ``Floppy'' and you will be prompted for the rest. FreeBSD Handbook 19 _2_._2_._3 _B_e_f_o_r_e _i_n_s_t_a_l_l_i_n_g _f_r_o_m _a _M_S_-_D_O_S _p_a_r_t_i_t_i_o_n To prepare for installation from an MS-DOS partition, copy the files from the distribution into a directory called C:\FREEBSD. The directory tree structure of the CDROM must be partially reproduced within this directory so we suggest using the DOS xcopy command. For example, to prepare for a minimal installa tion of FreeBSD: C> MD C:\FREEBSD C> XCOPY /S E:\BIN C:\FREEBSD\BIN\ C> XCOPY /S E:\MANPAGES C:\FREEBSD\MANPAGES\ assuming that C: is where you have free space and E: is where your CDROM is mounted. For as many `DISTS' you wish to install from MS-DOS (and you have free space for), install each one under C:\FREEBSD - the BIN dist is only the minimal requirement. _2_._2_._4 _B_e_f_o_r_e _i_n_s_t_a_l_l_i_n_g _f_r_o_m _Q_I_C_/_S_C_S_I _T_a_p_e Installing from tape is probably the easiest method, short of an on-line install using FTP or a CDROM install. The installation program expects the files to be simply tar'ed onto the tape, so after getting all of the files for distribution you are interested in, simply tar them onto the tape with a com mand like: cd /freebsd/distdir tar cvf /dev/rwt0 (or /dev/rst0) dist1 .. dist2 When you go to do the installation, you should also make sure that you leave enough room in some temporary directory (which you will be allowed to choose) to accommodate the ffuullll contents of the tape you have created. Due to the non- random access nature of tapes, this method of installation requires quite a bit of temporary storage. You should expect to require as much temporary storage as you have stuff written on tape. NNoottee:: When going to do the installation, the tape must be in the drive _b_e_f_o_r_e booting from the boot floppy. The installation probe may otherwise fail to find it. _2_._2_._5 _B_e_f_o_r_e _i_n_s_t_a_l_l_i_n_g _o_v_e_r _a _n_e_t_w_o_r_k You can do network installations over 3 types of communications links: Serial port SLIP or PPP Parallel port PLIP (laplink cable) FreeBSD Handbook 20 Ethernet A standard ethernet controller (includes some PCMCIA). SLIP support is rather primitive, and limited primarily to hard-wired links, such as a serial cable running between a laptop computer and another computer. The link should be hard-wired as the SLIP installation does not currently offer a dialing capability; that facility is provided with the PPP utility, which should be used in preference to SLIP whenever possible. If you are using a modem, then PPP is almost certainly your only choice. Make sure that you have your service provider's information handy as you will need to know it fairly soon in the installation process. You will need to know how to dial your ISP using the ``AT commands'' specific to your modem, as the PPP dialer provides only a very simple terminal emulator. If you're using PAP or CHAP, you'll need to type the necessary ``set authname'' and ``set authkey'' commands before typing ``term''. Refer to the user-ppp _h_a_n_d_b_o_o_k (section 15.1, page 293) and FAQ9 entries for further information. If you have problems, logging can be directed to the screen using the command set log local .... If a hard-wired connection to another FreeBSD (2.0R or later) machine is avail able, you might also consider installing over a ``laplink'' parallel port cable. The data rate over the parallel port is much higher than what is typi cally possible over a serial line (up to 50k/sec), thus resulting in a quicker installation. Finally, for the fastest possible network installation, an ethernet adaptor is always a good choice! FreeBSD supports most common PC ethernet cards, a table of supported cards (and their required settings) is provided in _S_u_p_p_o_r_t_e_d _H_a_r_d_w_a_r_e (section 2.1, page 13). If you are using one of the supported PCMCIA ethernet cards, also be sure that it is plugged in _b_e_f_o_r_e the laptop is powered on! FreeBSD does not, unfortunately, currently support hot insertion of PCMCIA cards during installation. You will also need to know your IP address on the network, the netmask value for your address class, and the name of your machine. Your system administra tor can tell you which values to use for your particular network setup. If you will be referring to other hosts by name rather than IP address, you will also need a name server and possibly the address of a gateway (if you are using PPP, it is your provider's IP address) to use in talking to it. If you do not know the answers to all or most of these questions, then you should really probably talk to your system administrator _f_i_r_s_t before trying this type of installa tion. Once you have a network link of some sort working, the installation can con tinue over NFS or FTP. _2_._2_._5_._1 _P_r_e_p_a_r_i_n_g _f_o_r _N_F_S _i_n_s_t_a_l_l_a_t_i_o_n NFS installation is fairly straight-forward: Simply copy the FreeBSD distribu tion files you want onto a server somewhere and then point the NFS media selec tion at it. ____________________ 9. FreeBSD Handbook 21 If this server supports only ``privileged port'' access (as is generally the default for Sun workstations), you will need to set this option in the Options menu before installation can proceed. If you have a poor quality ethernet card which suffers from very slow transfer rates, you may also wish to toggle the appropriate Options flag. In order for NFS installation to work, the server must support subdir mounts, e.g., if your FreeBSD 2.2.7 distribution directory lives on: zziiggggyy:://uussrr//aarrcchhiivvee//ssttuuffff//FFrreeeeBBSSDD Then ziggy will have to allow the direct mounting of //uussrr//aarrcchhiivvee//ssttuuffff//FFrreeeeBBSSDD, not just //uussrr or //uussrr//aarrcchhiivvee//ssttuuffff. In FreeBSD's //eettcc//eexxppoorrttss file, this is controlled by the ``-alldirs'' option. Other NFS servers may have different conventions. If you are getting `Permis sion Denied' messages from the server then it is likely that you do not have this enabled properly. _2_._2_._5_._2 _P_r_e_p_a_r_i_n_g _f_o_r _F_T_P _I_n_s_t_a_l_l_a_t_i_o_n FTP installation may be done from any mirror site containing a reasonably up- to-date version of FreeBSD 2.2.7. A full menu of reasonable choices from almost anywhere in the world is provided by the FTP site menu. If you are installing from some other FTP site not listed in this menu, or you are having troubles getting your name server configured properly, you can also specify your own URL by selecting the ``Other'' choice in that menu. A URL can also be a direct IP address, so the following would work in the absence of a name server: ftp://165.113.121.81/pub/FreeBSD/2.2.7-RELEASE There are two FTP installation modes you can use: FTP Active For all FTP transfers, use ``Active'' mode. This will not work through firewalls, but will often work with older ftp servers that do not support passive mode. If your connection hangs with passive mode (the default), try active! FTP Passive For all FTP transfers, use ``Passive'' mode. This allows the user to pass through firewalls that do not allow incoming connections on random port addresses. NNoottee:: Active and passive modes are not the same as a `proxy' connec tion, where a proxy FTP server is listening and forwarding FTP requests! For a proxy FTP server, you should usually give name of the server you really want as a part of the username, after an @-sign. The proxy server then 'fakes' the real server. An example: Say you want to install from ftp.freebsd.org, using the proxy FTP server foo.bar.com, listening on port 1234. In this case, you go to the options menu, set the FTP username to FreeBSD Handbook 22 ftp@ftp.freebsd.org, and the password to your e-mail address. As your instal lation media, you specify FTP (or passive FTP, if the proxy support it), and the URL ftp://foo.bar.com:1234/pub/FreeBSD /pub/FreeBSD from ftp.freebsd.org is proxied under foo.bar.com, allowing you to install from _that_ machine (which fetch the files from ftp.freebsd.org as your installation requests them). _2_._3 _I_n_s_t_a_l_l_i_n_g _F_r_e_e_B_S_D Once you have taken note of the appropriate preinstallation steps, you should be able to install FreeBSD without any further trouble. Should this not be true, then you may wish to go back and re-read the relevant preparation section above for the installation media type you are trying to use, perhaps there is a helpful hint there that you missed the first time? If you are having hardware trouble, or FreeBSD refuses to boot at all, read the Hardware Guide provided on the boot floppy for a list of possible solutions. The FreeBSD boot floppy contains all the on-line documentation you should need to be able to navigate through an installation and if it does not then we would like to know what you found most confusing. Send your comments to the FreeBSD documentation project mailing list . It is the objec tive of the FreeBSD installation program (sysinstall) to be self-documenting enough that painful ``step-by-step'' guides are no longer necessary. It may take us a little while to reach that objective, but that is the objective! Meanwhile, you may also find the following ``typical installation sequence'' to be helpful: 1. Boot the boot floppy. After a boot sequence which can take anywhere from 30 seconds to 3 minutes, depending on your hardware, you should be pre sented with a menu of initial choices. If the floppy does not boot at all, or the boot hangs at some stage, go read the Q&A section of the Hardware Guide for possible causes. 2. Press F1. You should see some basic usage instructions on the menu sys tem and general navigation. If you have not used this menu system before then PLEASE read this thoroughly! 3. Select the Options item and set any special preferences you may have. 4. Select a Novice, Custom or Express install, depending on whether or not you would like the installation to help you through a typical installa tion, give you a high degree of control over each step of the installa tion or simply whizz through it (using reasonable defaults when possible) as fast as possible. If you have never used FreeBSD before then the Novice installation method is most recommended. 5. The final configuration menu choice allows you to further configure your FreeBSD installation by giving you menu-driven access to various system FreeBSD Handbook 23 defaults. Some items, like networking, may be especially important if you did a CDROM/Tape/Floppy installation and have not yet configured your network interfaces (assuming you have any). Properly configuring such interfaces here will allow FreeBSD to come up on the network when you first reboot from the hard disk. _2_._4 _M_S_-_D_O_S _U_s_e_r_'_s _Q_u_e_s_t_i_o_n_s _a_n_d _A_n_s_w_e_r_s Many FreeBSD users wish to install FreeBSD on PCs inhabited by MS-DOS. Here are some commonly asked questions about installing FreeBSD on such systems. HHeellpp!! II hhaavvee nnoo ssppaaccee!! DDoo II nneeeedd ttoo ddeelleettee eevveerryytthhiinngg ffiirrsstt?? If your machine is already running MS-DOS and has little or no free space available for FreeBSD's installation, all is not lost! You may find the FIPS utility, provided in the tools directory on the FreeBSD CDROM or on the various FreeBSD ftp sites, to be quite useful. FIPS allows you to split an existing MS-DOS partition into two pieces, preserv ing the original partition and allowing you to install onto the second free piece. You first defragment your MS-DOS partition, using the DOS 6.xx DEFRAG utility or the Norton Disk tools, then run FIPS. It will prompt you for the rest of the information it needs. Afterwards, you can reboot and install FreeBSD on the new free slice. See the _D_i_s_t_r_i_b_u_t_i_o_n_s menu for an estimation of how much free space you will need for the kind of installation you want. CCaann II uussee ccoommpprreesssseedd MMSS--DDOOSS ffiilleessyysstteemmss ffrroomm FFrreeeeBBSSDD?? No. If you are using a utility such as Stacker(tm) or DoubleSpace(tm), FreeBSD will only be able to use whatever portion of the filesystem you leave uncom pressed. The rest of the filesystem will show up as one large file (the stacked/dblspaced file!). DDoo nnoott rreemmoovvee tthhaatt ffiillee!! You will probably regret it greatly! It is probably better to create another uncompressed MS-DOS primary partition and use this for communications between MS-DOS and FreeBSD. CCaann II mmoouunntt mmyy MMSS--DDOOSS eexxtteennddeedd ppaarrttiittiioonnss?? Yes. DOS extended partitions are mapped in at the end of the other ``slices'' in FreeBSD, e.g. your D: drive might be /dev/sd0s5, your E: drive /dev/sd0s6, and so on. This example assumes, of course, that your extended partition is on SCSI drive 0. For IDE drives, substitute ``wd'' for ``sd'' appropriately. You otherwise mount extended partitions exactly like you would mount any other DOS drive, e.g.: mount -t msdos /dev/sd0s5 /dos_d CCaann II rruunn MMSS--DDOOSS bbiinnaarriieess uunnddeerr FFrreeeeBBSSDD?? BSDI has donated their DOS emulator to the BSD world and this has been ported to FreeBSD. There is also a (technically) nice application available in the _T_h_e _P_o_r_t_s FreeBSD Handbook 24 _C_o_l_l_e_c_t_i_o_n (section 4., page 25) called pcemu which allows you to run many basic MS-DOS text-mode binaries by entirely emulating an 8088 CPU. _3_. _U_n_i_x _B_a_s_i_c_s _3_._1 _T_h_e _O_n_l_i_n_e _M_a_n_u_a_l The most comprehensive documentation on FreeBSD is in the form of _m_a_n _p_a_g_e_s. Nearly every program on the system comes with a short reference manual explain ing the basic operation and various arguments. These manuals can be view with the mmaann command. Use of the mmaann command is simple: mmaann _c_o_m_m_a_n_d where _c_o_m_m_a_n_d is the name of the command you wish to learn about. For example, to learn more about llss command type: % mmaann llss The online manual is divided up into numbered sections: 1. User commands 2. System calls and error numbers 3. Functions in the C libraries 4. Device drivers 5. File formats 6. Games and other diversions 7. Miscellaneous information 8. System maintenance and operation commands in some cases, the same topic may appear in more than one section of the on- line manual. For example, there is a cchhmmoodd user command and a cchhmmoodd(()) system call. In this case, you can tell the mmaann command which one you want by speci fying the section: % mmaann 11 cchhmmoodd which will display the manual page for the user command cchhmmoodd. References to a particular section of the on-line manual are traditionally placed in parenthe sis in written documentation, so cchhmmoodd((11)) refers to the cchhmmoodd user command and cchhmmoodd((22)) refers to the system call. This is fine if you know the name of the command and simply wish to know how to use it, but what if you cannot recall the command name? You can use mmaann to FreeBSD Handbook 25 search for keywords in the command _d_e_s_c_r_i_p_t_i_o_n_s by using the --kk switch: % mmaann --kk mmaaiill With this command you will be presented with a list of commands that have the keyword `mail' in their descriptions. This is actually functionally equivalent to using the aapprrooppooss command. So, you are looking at all those fancy commands in /usr/bin but do not even have the faintest idea what most of them actually do? Simply do a % ccdd //uussrr//bbiinn;; mmaann --ff ** or % ccdd //uussrr//bbiinn;; wwhhaattiiss ** which does the same thing. _3_._2 _G_N_U _I_n_f_o _F_i_l_e_s FreeBSD includes many applications and utilities produced by the Free Software Foundation (FSF). In addition to man pages, these programs come with more extensive hypertext documents called _i_n_f_o files which can be viewed with the info command or, if you installed emacs, the info mode of emacs. To use the info(1) command, simply type: % iinnffoo For a brief introduction, type hh. For a quick command reference, type ??. _4_. _I_n_s_t_a_l_l_i_n_g _A_p_p_l_i_c_a_t_i_o_n_s_: _T_h_e _P_o_r_t_s _c_o_l_l_e_c_t_i_o_n _C_o_n_t_r_i_b_u_t_e_d _b_y _J_a_m_e_s _R_a_y_n_a_r_d . The FreeBSD Ports collection allows you to compile and install a very wide range of applications with a minimum of effort. For all the hype about open standards, getting a program to work on different versions of Unix in the real world can be a tedious and tricky business, as anyone who has tried it will know. You may be lucky enough to find that the program you want will compile cleanly on your system, install itself in all the right places and run flawlessly ``out of the box'', but this is unfortunately rather rare. With most programs, you will find yourself doing a fair bit of head-scratching, and there are quite a few programs that will result in prema ture greying, or even chronic alopecia... Some software distributions have attacked this problem by providing configura tion scripts. Some of these are very clever, but they have an unfortunate FreeBSD Handbook 26 tendency to triumphantly announce that your system is something you have never heard of and then ask you lots of questions that sound like a final exam in system-level Unix programming (``Does your system's gethitlist function return a const pointer to a fromboz or a pointer to a const fromboz? Do you have Foonix style unacceptable exception handling? And if not, why not?''). Fortunately, with the Ports collection, all the hard work involved has already been done, and you can just type 'make install' and get a working program. _4_._1 _W_h_y _H_a_v_e _a _P_o_r_t_s _C_o_l_l_e_c_t_i_o_n_? The base FreeBSD system comes with a very wide range of tools and system utili ties, but a lot of popular programs are not in the base system, for good rea sons:- 1. Programs that some people cannot live without and other people cannot stand, such as a certain Lisp-based editor. 2. Programs which are too specialised to put in the base system (CAD, databases). 3. Programs which fall into the ``I must have a look at that when I get a spare minute'' category, rather than system-critical ones (some lan guages, perhaps). 4. Programs that are far too much fun to be supplied with a serious operat ing system like FreeBSD ;-) 5. However many programs you put in the base system, people will always want more, and a line has to be drawn somewhere (otherwise FreeBSD distribu tions would become absolutely enormous). Obviously it would be unreasonable to expect everyone to port their favourite programs by hand (not to mention a tremendous amount of duplicated work), so the FreeBSD Project came up with an ingenious way of using standard tools that would automate the process. Incidentally, this is an excellent illustration of how ``the Unix way'' works in practice by combining a set of simple but very flexible tools into something very powerful. _4_._2 _H_o_w _D_o_e_s _t_h_e _P_o_r_t_s _C_o_l_l_e_c_t_i_o_n _W_o_r_k_? Programs are typically distributed on the Internet as a _t_a_r_b_a_l_l (section 4.6, page 33) consisting of a Makefile and the source code for the program and usu ally some instructions (which are unfortunately not always as instructive as they could be), with perhaps a configuration script. The standard scenario is that you FTP down the tarball, extract it somewhere, glance through the instructions, make any changes that seem necessary, run the configure script to set things up and use the standard `make' program to com pile and install the program from the source. FreeBSD ports still use the tarball mechanism, but use a _s_k_e_l_e_t_o_n (section 4.4, FreeBSD Handbook 27 page 30) to hold the 'knowledge' of how to get the program working on FreeBSD, rather than expecting the user to be able to work it out. They also supply their own customised _M_a_k_e_f_i_l_e (section 4.4.1, page 30), so that almost every port can be built in the same way. If you look at a port skeleton (either on your FreeBSD system or the FTP site) and expect to find all sorts of pointy-headed rocket science lurking there, you may be disappointed by the one or two rather unexciting-looking files and directories you find there. (We will discuss in a minute how to go about _G_e_t_ _t_i_n_g _a _p_o_r_t (section 4.3, page 28)). ``How on earth can this do anything?'' I hear you cry. ``There is no source code there!'' Fear not, gentle reader, all will become clear (hopefully). Let's see what happens if we try and install a port. I have chosen `ElectricFence', a useful tool for developers, as the skeleton is more straightforward than most. _N_o_t_e if you are trying this at home, you will need to be root. # cd /usr/ports/devel/ElectricFence # make install >> Checksum OK for ElectricFence-2.0.5.tar.gz. ===> Extracting for ElectricFence-2.0.5 ===> Patching for ElectricFence-2.0.5 ===> Applying FreeBSD patches for ElectricFence-2.0.5 ===> Configuring for ElectricFence-2.0.5 ===> Building for ElectricFence-2.0.5 [lots of compiler output...] ===> Installing for ElectricFence-2.0.5 ===> Warning: your umask is "0002". If this is not desired, set it to an appropriate value and install this port again by ``make reinstall''. install -c -o bin -g bin -m 444 /usr/ports/devel/ElectricFence/work/ElectricFence-2.0.5/libefence.a /usr/local/lib install -c -o bin -g bin -m 444 /usr/ports/devel/ElectricFence/work/ElectricFence-2.0.5/libefence.3 /usr/local/man/man3 ===> Compressing manual pages for ElectricFence-2.0.5 ===> Registering installation for ElectricFence-2.0.5 To avoid confusing the issue, I have completely removed the build output. If you tried this yourself, you may well have got something like this at the start:- # make install >> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. >> Attempting to fetch from ftp://ftp.doc.ic.ac.uk/Mirrors/sunsite.unc.edu/pub/Linux/devel/lang/c/. The `make' program has noticed that you did not have a local copy of the source code and tried to FTP it down so it could get the job done. I already had the source handy in my example, so it did not need to fetch it. Let's go through this and see what the `make' program was doing. FreeBSD Handbook 28 1. Locate the source code _t_a_r_b_a_l_l_. (section 4.6, page 33) If it is not available locally, try to grab it from an FTP site. 2. Run a _c_h_e_c_k_s_u_m (section 4.6, page 33) test on the tarball to make sure it has not been tampered with, accidentally truncated, downloaded in ASCII mode, struck by neutrinos while in transit, etc. 3. Extract the tarball into a temporary work directory. 4. Apply any _p_a_t_c_h_e_s (section 4.6, page 33) needed to get the source to compile and run under FreeBSD. 5. Run any configuration script required by the build process and correctly answer any questions it asks. 6. (Finally!) Compile the code. 7. Install the program executable and other supporting files, man pages, etc. under the /usr/local hierarchy, where they will not get mixed up with system programs. This also makes sure that all the ports you install will go in the same place, instead of being flung all over your system. 8. Register the installation in a database. This means that, if you do not like the program, you can cleanly _r_e_m_o_v_e (section 4.6, page 36) all traces of it from your system. Scroll up to the make output and see if you can match these steps to it. And if you were not impressed before, you should be by now! _4_._3 _G_e_t_t_i_n_g _a _F_r_e_e_B_S_D _P_o_r_t There are two ways of getting hold of the FreeBSD port for a program. One requires a _F_r_e_e_B_S_D _C_D_R_O_M (section 4.3.1, page 28), the other involves using an _I_n_t_e_r_n_e_t _C_o_n_n_e_c_t_i_o_n_. (section 4.3.2, page 28) _4_._3_._1 _C_o_m_p_i_l_i_n_g _p_o_r_t_s _f_r_o_m _C_D_R_O_M Assuming that your _F_r_e_e_B_S_D CDROM is in the drive and mounted on /cdrom (and the mount point *must* be /cdrom), you should then be able to build ports just as you normally do and the port collection's built in search path should find the tarballs in file:/cdrom/ports/distfiles/ (if they exist there) rather than downloading them over the net. Note that there are some ports for which we cannot provide the original source in the CDROM due to licensing limitations. In that case, you will need to look at the section on _C_o_m_p_i_l_i_n_g _p_o_r_t_s _u_s_i_n_g _a_n _I_n_t_e_r_n_e_t _c_o_n_n_e_c_t_i_o_n_. (section 4.3.2, page 28) _4_._3_._2 _C_o_m_p_i_l_i_n_g _p_o_r_t_s _f_r_o_m _t_h_e _I_n_t_e_r_n_e_t If you do not have a CDROM, or you want to make sure you get the very latest version of the port you want, you will need to download the _s_k_e_l_e_t_o_n (section 4.4, page 30) for the port. Now this might sound like rather a fiddly job full of pitfalls, but it is actually very easy. FreeBSD Handbook 29 First, if you are running a release version of FreeBSD, make sure you get the appropriate ``upgrade kit'' for your release from the ports page. These pack ages include files that have been updated since the release that you may need to compile new ports. The key to the skeletons is that the FreeBSD FTP server can create on-the-fly _t_a_r_b_a_l_l_s (section 4.6, page 33) for you. Here is how it works, with the gnats program in the databases directory as an example (the bits in square brackets are comments. Do not type them in if you are trying this yourself!):- # cd /usr/ports # mkdir databases # cd databases # ftp ftp.freebsd.org [log in as `ftp' and give your email address when asked for a password. Remember to use binary (also known as image) mode!] > cd /pub/FreeBSD/ports/databases > get gnats.tar [tars up the gnats skeleton for us] > quit # tar xf gnats.tar [extract the gnats skeleton] # cd gnats # make install [build and install gnats] What happened here? We connected to the FTP server in the usual way and went to its databases sub-directory. When we gave it the command `get gnats.tar', the FTP server _t_a_r_r_e_d (section 4.6, page 33) up the gnats directory for us. We then extracted the gnats skeleton and went into the gnats directory to build the port. As we explained _e_a_r_l_i_e_r (section 4.2, page 27), the make process noticed we did not have a copy of the source locally, so it fetched one before extracting, patching and building it. Let's try something more ambitious now. Instead of getting a single port skele ton, let's get a whole sub-directory, for example all the database skeletons in the ports collection. It looks almost the same:- # cd /usr/ports # ftp ftp.freebsd.org [log in as `ftp' and give your email address when asked for a password. Remember to use binary (also known as image) mode!] > cd /pub/FreeBSD/ports > get databases.tar [tars up the databases directory for us] > quit # tar xf databases.tar [extract all the database skeletons] # cd databases # make install [build and install all the database ports] With half a dozen straightforward commands, we have now got a set of database programs on our FreeBSD machine! All we did that was different from getting a single port skeleton and building it was that we got a whole directory at once, and compiled everything in it at once. Pretty impressive, no? If you expect to be installing many ports, it is probably worth downloading all the ports directories. FreeBSD Handbook 30 _4_._4 _S_k_e_l_e_t_o_n_s A team of compulsive hackers who have forgotten to eat in a frantic attempt to make a deadline? Something unpleasant lurking in the FreeBSD attic? No, a skeleton here is a minimal framework that supplies everything needed to make the ports magic work. _4_._4_._1 _M_a_k_e_f_i_l_e The most important component of a skeleton is the Makefile. This contains vari ous statements that specify how the port should be compiled and installed. Here is the Makefile for ElectricFence:- # New ports collection makefile for: Electric Fence # Version required: 2.0.5 # Date created: 13 November 1997 # Whom: jraynard # # $Id: ports.sgml,v 1.33 1998/11/07 11:50:45 asami Exp $ # DISTNAME= ElectricFence-2.0.5 CATEGORIES= devel MASTER_SITES= ${MASTER_SITE_SUNSITE} MASTER_SITE_SUBDIR= devel/lang/c MAINTAINER= jraynard@freebsd.org MAN3= libefence.3 do-install: ${INSTALL_DATA} ${WRKSRC}/libefence.a ${PREFIX}/lib ${INSTALL_MAN} ${WRKSRC}/libefence.3 ${PREFIX}/man/man3 .include The lines beginning with a '#' sign are comments for the benefit of human read ers (as in most Unix script files). `DISTNAME' specifies the name of the _t_a_r_b_a_l_l (section 4.6, page 33), but with out the extension. `CATEGORIES' states what kind of program this is. In this case, a utility for developers. See the _c_a_t_e_g_o_r_i_e_s (section 4.7.11, page 74) section of this hand book for a complete list. `MASTER_SITES' is the URL(s) of the master FTP site, which is used to retrieve the _t_a_r_b_a_l_l (section 4.6, page 33) if it is not available on the local system. This is a site which is regarded as reputable, and is normally the one from which the program is officially distributed (in so far as any software is 'officially' distributed on the Internet). `MAINTAINER' is the email address of the person who is responsible for updating the skeleton if, for example a new version of the program comes out. FreeBSD Handbook 31 Skipping over the next few lines for a minute, the line .include says that the other statements and commands needed for this port are in a stan dard file called `bsd.port.mk'. As these are the same for all ports, there is no point in duplicating them all over the place, so they are kept in a single standard file. This is probably not the place to go into a detailed examination of how Make files work; suffice it to say that the line starting with ``MAN3'' ensures that the ElectricFence man page is compressed after installation, to help conserve your precious disk space. The original port did not provide an ``install'' target, so the three lines from ``do-install'' ensure that the files produced by this port are placed in the correct destination. _4_._4_._2 _T_h_e _f_i_l_e_s _d_i_r_e_c_t_o_r_y The file containing the _c_h_e_c_k_s_u_m (section 4.6, page 33) for the port is called 'md5', after the MD5 algorithm used for ports checksums. It lives in a direc tory with the slightly confusing name of 'files'. This directory can also contain other miscellaneous files that are required by the port and do not belong anywhere else. _4_._4_._3 _T_h_e _p_a_t_c_h_e_s _d_i_r_e_c_t_o_r_y This directory contains the _p_a_t_c_h_e_s (section 4.6, page 33) needed to make everything work properly under FreeBSD. _4_._4_._4 _T_h_e _p_k_g _d_i_r_e_c_t_o_r_y This program contains three quite useful files:- COMMENT - a one-line description of the program. DESCR - a more detailed description. PLIST - a list of all the files that will be created when the program is installed. _4_._5 _W_h_a_t _t_o _d_o _w_h_e_n _a _p_o_r_t _d_o_e_s _n_o_t _w_o_r_k_. Oh. You can do one of four (4) things : 1. Fix it yourself. Technical details on how ports work can be found in _P_o_r_t_i_n_g _a_p_p_l_i_c_a_t_i_o_n_s_. (section 4.7, page 37) 2. Gripe. This is done by e-mail *ONLY*! Send such e-mail to the FreeBSD ports mailing list and please include the name/version of the port, where you got both the port source & dist file(s) from, and what the text of the error was. FreeBSD Handbook 32 3. Forget it. This is the easiest for most - very few of the programs in ports can be classified as `essential'! 4. Grab the pre-compiled package from a ftp server. The ``master'' package collection is on FreeBSD's FTP server in the packages directory, though check your local mirror first, please! These are more likely to work (on the whole) than trying to compile from source and a lot faster besides! Use the pkg_add(1) program to install a package file on your system. _4_._6 _S_o_m_e _Q_u_e_s_t_i_o_n_s _a_n_d _A_n_s_w_e_r_s Q. I thought this was going to be a discussion about modems??! A. Ah. You must be thinking of the serial ports on the back of your com puter. We are using `port' here to mean the result of `porting' a program from one version of Unix to another. (It is an unfortunate bad habit of computer people to use the same word to refer to several completely dif ferent things). Q. I thought you were supposed to use packages to install extra programs? A. Yes, that is usually the quickest and easiest way of doing it. Q. So why bother with ports then? A. Several reasons:- 1. The licensing conditions on some software distributions require that they be distributed as source code, not binaries. 2. Some people do not trust binary distributions. At least with source code you can (in theory) read through it and look for potential problems yourself. 3. If you have some local patches, you will need the source to add them yourself. 4. You might have opinions on how a program should be compiled that differ from the person who did the package - some people have strong views on what optimisation setting should be used, whether to build debug versions and then strip them or not, etc. etc. 5. Some people like having code around, so they can read it if they get bored, hack around with it, borrow from it (licence terms per mitting, of course!) and so on. 6. If you ain't got the source, it ain't software! ;-) Q. What is a patch? A. A patch is a small (usually) file that specifies how to go from one version of a file to another. It contains text that says, in effect, FreeBSD Handbook 33 things like ``delete line 23'', ``add these two lines after line 468'' or ``change line 197 to this''. Also known as a `diff', since it is generated by a program of that name. Q. What is all this about tarballs? A. It is a file ending in .tar or .tar.gz (with variations like .tar.Z, or even .tgz if you are trying to squeeze the names into a DOS filesystem). Basically, it is a directory tree that has been archived into a single file (.tar) and optionally compressed (.gz). This technique was originally used for _Tape _A_Rchives (hence the name `tar'), but it is a widely used way of distributing program source code around the Internet. You can see what files are in them, or even extract them yourself, by using the standard Unix tar program, which comes with the base FreeBSD system, like this:- tar tvzf foobar.tar.gz # View contents of foobar.tar.gz tar xzvf foobar.tar.gz # Extract contents into the current directory tar tvf foobar.tar # View contents of foobar.tar tar xvf foobar.tar # Extract contents into the current directory Q. And a checksum? A. It is a number generated by adding up all the data in the file you want to check. If any of the characters change, the checksum will no longer be equal to the total, so a simple comparison will allow you to spot the dif ference. (In practice, it is done in a more complicated way to spot prob lems like position-swapping, which will not show up with a simplistic addition). Q. I did what you said for _c_o_m_p_i_l_i_n_g _p_o_r_t_s _f_r_o_m _a _C_D_R_O_M (section 4.3.1, page 28) and it worked great until I tried to install the kermit port:- # make install >> cku190.tar.gz doesn't seem to exist on this system. >> Attempting to fetch from ftp://kermit.columbia.edu/kermit/archives/. Why can it not be found? Have I got a dud CDROM? A. The licensing terms for kermit do not allow us to put the tarball for it on the CDROM, so you will have to fetch it by hand - sorry! The reason why you got all those error messages was because you were not connected to the Internet at the time. Once you have downloaded it from any of the sites above, you can re-start the process (try and choose the nearest site to you, though, to save your time and the Internet's bandwidth). Q. I did that, but when I tried to put it into /usr/ports/distfiles I got some error about not having permission. FreeBSD Handbook 34 A. The ports mechanism looks for the tarball in /usr/ports/distfiles, but you will not be able to copy anything there because it is sym-linked to the CDROM, which is read-only. You can tell it to look somewhere else by doing DISTDIR=/where/you/put/it make install Q. Does the ports scheme only work if you have everything in /usr/ports? My system administrator says I must put everything under /u/peo ple/guests/wurzburger, but it does not seem to work. A. You can use the PORTSDIR and PREFIX variables to tell the ports mecha nism to use different directories. For instance, make PORTSDIR=/u/people/guests/wurzburger/ports install will compile the port in /u/people/guests/wurzburger/ports and install everything under /usr/local. make PREFIX=/u/people/guests/wurzburger/local install will compile it in /usr/ports and install it in /u/peo ple/guests/wurzburger/local. And of course make PORTSDIR=.../ports PREFIX=.../local install will combine the two (it is too long to fit on the page if I write it in full, but I am sure you get the idea). If you do not fancy typing all that in every time you install a port (and to be honest, who would?), it is a good idea to put these variables into your environment. Q. I do not have a FreeBSD CDROM, but I would like to have all the tar balls handy on my system so I do not have to wait for a download every time I install a port. Is there an easy way to get them all at once? A. To get every single tarball for the ports collection, do # cd /usr/ports # make fetch For all the tarballs for a single ports directory, do # cd /usr/ports/directory # make fetch and for just one port - well, I think you have guessed already. Q. I know it is probably faster to fetch the tarballs from one of the FreeBSD mirror sites close by. Is there any way to tell the port to fetch FreeBSD Handbook 35 them from servers other than ones listed in the MASTER_SITES? A. Yes. If you know, for example, ftp.FreeBSD.ORG is much closer than sites listed in MASTER_SITES, do as following example. # cd /usr/ports/directory # make MASTER_SITE_OVERRIDE=ftp://ftp.FreeBSD.ORG/pub/FreeBSD/distfiles/ fetch Q. I want to know what files make is going to need before it tries to pull them down. A. 'make fetch-list' will display a list of the files needed for a port. Q. Is there any way to stop the port from compiling? I want to do some hacking on the source before I install it, but it is a bit tiresome having to watch it and hit control-C every time. A. Doing 'make extract' will stop it after it has fetched and extracted the source code. Q. I am trying to make my own port and I want to be able to stop it com piling until I have had a chance to see if my patches worked properly. Is there something like 'make extract', but for patches? A. Yep, 'make patch' is what you want. You will probably find the PATCH_DEBUG option useful as well. And by the way, thank you for your efforts! Q. I have heard that some compiler options can cause bugs. Is this true? How can I make sure that I compile ports with the right settings? A. Yes, with version 2.6.3 of gcc (the version shipped with FreeBSD 2.1.0 and 2.1.5), the -O2 option could result in buggy code unless you used the -fno-strength-reduce option as well. (Most of the ports don't use -O2). You _s_h_o_u_l_d be able to specify the compiler options used by something like make CFLAGS='-O2 -fno-strength-reduce' install or by editing /etc/make.conf, but unfortunately not all ports respect this. The surest way is to do 'make configure', then go into the source directory and inspect the Makefiles by hand, but this can get tedious if the source has lots of sub-directories, each with their own Makefiles. Q. There are so many ports it is hard to find the one I want. Is there a list anywhere of what ports are available? A. Look in the INDEX file in /usr/ports. If you would like to search the ports collection for a keyword, you can do that too. For example, you can find ports relevant to the LISP programming language using: cd /usr/ports make search key=lisp FreeBSD Handbook 36 Q. I went to install the 'foo' port but the system suddenly stopped com piling it and starting compiling the 'bar' port. What's going on? A. The 'foo' port needs something that is supplied with 'bar' - for instance, if 'foo' uses graphics, 'bar' might have a library with useful graphics processing routines. Or 'bar' might be a tool that is needed to compile the 'foo' port. Q. I installed the grizzle program from the ports and frankly it is a complete waste of disk space. I want to delete it but I do not know where it put all the files. Any clues? A. No problem, just do pkg_delete grizzle-6.5 Q. Hang on a minute, you have to know the version number to use that com mand. You do not seriously expect me to remember that, do you?? A. Not at all, you can find it out by doing pkg_info -a | grep grizzle And it will tell you:- Information for grizzle-6.5: grizzle-6.5 - the combined piano tutorial, LOGO interpreter and shoot 'em up arcade game. Q. Talking of disk space, the ports directory seems to be taking up an awful lot of room. Is it safe to go in there and delete things? A. Yes, if you have installed the program and are fairly certain you will not need the source again, there is no point in keeping it hanging around. The best way to do this is # cd /usr/ports # make clean which will go through all the ports subdirectories and delete everything except the skeletons for each port. Q. I tried that and it still left all those tarballs or whatever you called them in the distfiles directory. Can I delete those as well? A. Yes, if you are sure you have finished with them, those can go as well. Q. I like having lots and lots of programs to play with. Is there any way of installing all the ports in one go? A. Just do # cd /usr/ports # make install FreeBSD Handbook 37 Q. OK, I tried that, but I thought it would take a very long time so I went to bed and left it to get on with it. When I looked at the computer this morning, it had only done three and a half ports. Did something go wrong? A. No, the problem is that some of the ports need to ask you questions that we cannot answer for you (eg ``Do you want to print on A4 or US let ter sized paper?'') and they need to have someone on hand to answer them. Q. I really do not want to spend all day staring at the monitor. Any bet ter ideas? A. OK, do this before you go to bed/work/the local park:- # cd /usr/ports # make -DBATCH install This will install every port that does _n_o_t require user input. Then, when you come back, do # cd /usr/ports # make -DIS_INTERACTIVE install to finish the job. Q. At work, we are using frobble, which is in your ports collection, but we have altered it quite a bit to get it to do what we need. Is there any way of making our own packages, so we can distribute it more easily around our sites? A. No problem, assuming you know how to make patches for your changes:- # cd /usr/ports/somewhere/frobble # make extract # cd work/frobble-2.8 [Apply your patches] # cd ../.. # make package Q. This ports stuff is really clever. I am desperate to find out how you did it. What is the secret? A. Nothing secret about it at all, just look at the bsd.ports.mk and bsd.ports.subdir.mk files in your makefiles directory. (Note: readers with an aversion to intricate shell-scripts are advised not to follow this link...) _4_._7 _M_a_k_i_n_g _a _p_o_r_t _y_o_u_r_s_e_l_f _C_o_n_t_r_i_b_u_t_e_d _b_y _J_o_r_d_a_n _K_. _H_u_b_b_a_r_d , Gary Palmer , Satoshi Asami , David O'Brien and Tim Vanderhoek . 28 August 1996. FreeBSD Handbook 38 So, now you are interested in making your own port? Great! :) What follows are some guidelines for creating a new port for FreeBSD. The bulk of the work is done by /usr/share/mk/bsd.port.mk, which all port Makefiles include. Please refer to that file for more details on the inner workings of the ports collection. Even if you don't hack Makefiles daily, it is well com mented, and you will still gain much knowledge from it. Note: Only a fraction of the overridable variables (${..}) are mentioned in this document. Most (if not all) are documented at the start of bsd.port.mk. This file uses a non-standard tab setting. Emacs and Vim should recognize the setting on loading the file. vi or ex can be set to using the correct value by typing `:set tabstop=4' once the file has been loaded. _4_._7_._1 _Q_u_i_c_k _P_o_r_t_i_n_g This section tells you how to do a quick port. In many cases, it is not enough, but we will see. First, get the original tarball and put it into ${DISTDIR}, which defaults to /usr/ports/distfiles. Note: The following assumes that the software compiled out-of-the-box, i.e., there was absolutely no change required for the port to work on your FreeBSD box. If you needed to change something, you will have to refer to the next section too. _4_._7_._1_._1 _W_r_i_t_i_n_g _t_h_e _M_a_k_e_f_i_l_e The minimal Makefile would look something like this: # New ports collection makefile for: oneko # Version required: 1.1b # Date created: 5 December 1994 # Whom: asami # # $Id$ # DISTNAME= oneko-1.1b CATEGORIES= games MASTER_SITES= ftp://ftp.cs.columbia.edu/archives/X11R5/contrib/ MAINTAINER= asami@FreeBSD.ORG MAN1= oneko.1 MANCOMPRESSED= yes USE_IMAKE= yes .include See if you can figure it out. Do not worry about the contents of the $Id$ line, it will be filled in automatically by CVS when the port is imported to our main ports tree. You can find a more detailed example in the _s_a_m_p_l_e FreeBSD Handbook 39 _M_a_k_e_f_i_l_e (section 4.7.9, page 71) section. _4_._7_._1_._2 _W_r_i_t_i_n_g _t_h_e _d_e_s_c_r_i_p_t_i_o_n _f_i_l_e_s There are three description files that are required for any port, whether they actually package or not. They are COMMENT, DESCR, and PLIST, and reside in the pkg subdirectory. _4_._7_._1_._2_._1 _C_O_M_M_E_N_T This is the one-line description of the port. _P_l_e_a_s_e _d_o _n_o_t _i_n_c_l_u_d_e _t_h_e _p_a_c_k_ _a_g_e _n_a_m_e _(_o_r _v_e_r_s_i_o_n _n_u_m_b_e_r _o_f _t_h_e _s_o_f_t_w_a_r_e_) _i_n _t_h_e _c_o_m_m_e_n_t_. Here is an exam ple: A cat chasing a mouse all over the screen. _4_._7_._1_._2_._2 _D_E_S_C_R This is a longer description of the port. One to a few paragraphs concisely explaining what the port does is sufficient. This is _n_o_t a manual or an in- depth description on how to use or compile the port! _P_l_e_a_s_e _b_e _c_a_r_e_f_u_l _i_f _y_o_u _a_r_e _c_o_p_y_i_n_g _f_r_o_m _t_h_e README or manpage; too often they are not a concise description of the port or are in an awkward format (e.g. manpages have justi fied spacing). If the ported software has an official WWW homepage, you should list in here. It is recommended that you sign the name at the end of this file, as in: This is a port of oneko, in which a cat chases a poor mouse all over the screen. : (etc.) http://www.oneko.org/ - Satoshi asami@cs.berkeley.edu _4_._7_._1_._2_._3 _P_L_I_S_T This file lists all the files installed by the port. It is also called the `packing list' because the package is generated by packing the files listed here. The pathnames are relative to the installation prefix (usually /usr/local or /usr/X11R6). If you are using the MANx variables (as you should be), do not list any manpages here. Here is a small example: bin/oneko lib/X11/app-defaults/Oneko lib/X11/oneko/cat1.xpm lib/X11/oneko/cat2.xpm lib/X11/oneko/mouse.xpm @dirrm lib/X11/oneko FreeBSD Handbook 40 Refer to the pkg_create(1) man page for details on the packing list. Note that you should list all the files, but not the name directories, in the list. Also, if the port creates directories for itself during installation, make sure to add @dirrm lines as necessary to remove them when the port is deleted. It is recommended you keep all the filenames in this file sorted alphabeti cally. It will make verifying the changes when you upgrade the port much eas ier. _4_._7_._1_._3 _C_r_e_a_t_i_n_g _t_h_e _c_h_e_c_k_s_u_m _f_i_l_e Just type `make makesum'. The ports make rules will automatically generate the file files/md5. _4_._7_._1_._4 _T_e_s_t_i_n_g _t_h_e _p_o_r_t You should make sure that the port rules do exactly what you want it to do, including packaging up the port. These are the important points you need to verify: PLIST does not contain anything not installed by your port PLIST contains everything that is installed by your port your port can be installed multiple times using the reinstall target your port _c_l_e_a_n_s _u_p (section 4.7.8.11, page 69) after itself upon dein stall The recommended ordering of tests is: 1. make install 2. make package 3. make deinstall 4. pkg_add `make package-name` 5. make deinstall 6. make reinstall 7. make package Make sure there aren't any warnings issued in any of the package and deinstall stages. After step 3, check to see if all the new directories are correctly deleted. Also, try using the software after step 4, to ensure that it works correctly when installed from a package. _4_._7_._1_._5 _C_h_e_c_k_i_n_g _y_o_u_r _p_o_r_t _w_i_t_h _p_o_r_t_l_i_n_t Please use portlint to see if your port conforms to our guidelines. The portlint program is part of the ports collection. In particular, you may want FreeBSD Handbook 41 to check if the _M_a_k_e_f_i_l_e (section 4.7.9, page 71) is in the right shape and the _p_a_c_k_a_g_e (section 4.7.10, page 73) is named appropriately. _4_._7_._1_._6 _S_u_b_m_i_t_t_i_n_g _t_h_e _p_o_r_t First, make sure you have read the _D_o_'_s _a_n_d _D_o_n_t_'_s (section 4.7.8, page 63) section. Now that you are happy with your port, the only thing remaining is to put it in the main FreeBSD ports tree and make everybody else happy about it too. We do not need your work/ directory or the pkgname.tgz package, so delete them now. Next, simply include the output of `shar `find port_dir`' in a bug report and send it with the send-pr(1) program (see _B_u_g _R_e_p_o_r_t_s _a_n_d _G_e_n_e_r_a_l _C_o_m_m_e_n_t_a_r_y (section 19.2.1, page 380) for more information about send-pr). If the uncom pressed port is larger than 20KB, you should compress it into a tarfile and use uuencode(1) before including it in the bug report (uuencoded tarfiles are acceptable even if the report is smaller than 20KB but are not preferred). Be sure to classify the bug report as category `ports' and class `change-request'. (Do not mark the report `confidential'!) One more time, _d_o _n_o_t _i_n_c_l_u_d_e _t_h_e _o_r_i_g_i_n_a_l _s_o_u_r_c_e _d_i_s_t_f_i_l_e_, _t_h_e work/ direc tory, or the package you built with `make package'! Note: in the past, we asked you to upload new port submissions in our ftp site (ftp.freebsd.org). This is no longer recommended as read access is turned off on that incoming directory of that site due to the large amount of pirated software showing up there. :< We will look at your port, get back to you if necessary, and put it in the tree. Your name will also appear in the list of `Additional FreeBSD contribu tors' on the FreeBSD Handbook and other files. Isn't that great?!? :) _4_._7_._2 _S_l_o_w _P_o_r_t_i_n_g Ok, so it was not that simple, and the port required some modifications to get it to work. In this section, we will explain, step by step, how to modify it to get it to work with the ports paradigm. _4_._7_._2_._1 _H_o_w _t_h_i_n_g_s _w_o_r_k First, this is the sequence of events which occurs when the user first types `make' in your port's directory, and you may find that having bsd.port.mk in another window while you read this really helps to understand it. But do not worry if you do not really understand what bsd.port.mk is doing, not many people do... :> 1. The fetch target is run. The fetch target is responsible for making sure that the tarball exists locally in ${DISTDIR}. If fetch cannot find the required files in ${DISTDIR} it will look up the URL ${MASTER_SITES}, which is set in the Makefile, as well as our main ftp site at ftp://ftp.freebsd.org/pub/FreeBSD/distfiles/, where we put sanctioned distfiles as backup. It will then attempt to fetch the named distribu tion file with ${FETCH}, assuming that the requesting site has direct FreeBSD Handbook 42 access to the Internet. If that succeeds, it will save the file in ${DISTDIR} for future use and proceed. 2. The extract target is run. It looks for your port's distribution file (typically a gzip'd tarball) in ${DISTDIR} and unpacks it into a tempo rary subdirectory specified by ${WRKDIR} (defaults to work). 3. The patch target is run. First, any patches defined in ${PATCHFILES} are applied. Second, if any patches are found in ${PATCHDIR} (defaults to the patches subdirectory), they are applied at this time in alphabetical order. 4. The configure target is run. This can do any one of many different things. 1. If it exists, scripts/configure is run. 2. If ${HAS_CONFIGURE} or ${GNU_CONFIGURE} is set, ${WRKSRC}/configure is run. 3. If ${USE_IMAKE} is set, ${XMKMF} (default: `xmkmf -a') is run. 5. The build target is run. This is responsible for descending into the ports' private working directory (${WRKSRC}) and building it. If ${USE_GMAKE} is set, GNU make will be used, otherwise the system make will be used. The above are the default actions. In addition, you can define targets `pre-' or `post-', or put scripts with those names, in the scripts subdirectory, and they will be run before or after the default actions are done. For example, if you have a post-extract target defined in your Makefile, and a file pre-build in the scripts subdirectory, the post-extract target will be called after the regular extraction actions, and the pre-build script will be executed before the default build rules are done. It is recommended that you use Makefile targets if the actions are simple enough, because it will be eas ier for someone to figure out what kind of non-default action the port requires. The default actions are done by the bsd.port.mk targets `do-'. For example, the commands to extract a port are in the target `do-extract'. If you are not happy with the default target, you can fix it by redefining the `do-' target in your Makefile. Note that the `main' targets (e.g., extract, configure, etc.) do nothing more than make sure all the stages up to that one is completed and call the real targets or scripts, and they are not intended to be changed. If you want to fix the extraction, fix do-extract, but never ever touch extract! Now that you understand what goes on when the user types `make', let us go through the recommended steps to create the perfect port. FreeBSD Handbook 43 _4_._7_._2_._2 _G_e_t_t_i_n_g _t_h_e _o_r_i_g_i_n_a_l _s_o_u_r_c_e_s Get the original sources (normally) as a compressed tarball (.tar.gz or .tar.Z) and copy it into ${DISTDIR}. Always use _m_a_i_n_s_t_r_e_a_m sources when and where you can. If you cannot find a ftp/http site that is well-connected to the net, or can only find sites that have irritatingly non-standard formats, you might want to put a copy on a reliable ftp or http server that you control (e.g., your home page). Make sure you set MASTER_SITES to reflect your choice. If you cannot find somewhere convenient and reliable to put the distfile (note that if you are a FreeBSD committer, you can just put it in the public_html directory on freefall), we can `house' it ourselves by putting it on ftp://ftp.freebsd.org/pub/FreeBSD/distfiles/LOCAL_PORTS/ as the last resort. Please refer to this location as ${MASTER_SITE_LOCAL}. Send mail to the FreeBSD ports mailing list if you are not sure what to do. If your port's distfile changes all the time for no good reason, consider putting the distfile in your home page and listing it as the first MAS TER_SITES. This will prevent users from getting `checksum mismatch' errors, and also reduce the workload of maintainers of our ftp site. Also, if there is only one master site for the port, it is recommended that you house a backup at your site and list it as the second MASTER_SITES. If your port requires some additional `patches' that are available on the Internet, fetch them too and put them in ${DISTDIR}. Do not worry if they come from site other than where you got the main source tarball, we have a way to handle these situations (see the description of _$_{_P_A_T_C_H_F_I_L_E_S_} (section 4.7.3.6, page 46) below). _4_._7_._2_._3 _M_o_d_i_f_y_i_n_g _t_h_e _p_o_r_t Unpack a copy of the tarball in a private directory and make whatever changes are necessary to get the port to compile properly under the current version of FreeBSD. Keep _c_a_r_e_f_u_l _t_r_a_c_k of everything you do, as you will be automating the process shortly. Everything, including the deletion, addition or modifica tion of files should be doable using an automated script or patch file when your port is finished. If your port requires significant user interaction/customization to compile or install, you should take a look at one of Larry Wall's classic Configure scripts and perhaps do something similar yourself. The goal of the new ports collection is to make each port as `plug-and-play' as possible for the end-user while using a minimum of disk space. Note: Unless explicitly stated, patch files, scripts, and other files you have created and contributed to the FreeBSD ports collection are assumed to be cov ered by the standard BSD copyright conditions. FreeBSD Handbook 44 _4_._7_._2_._4 _P_a_t_c_h_i_n_g In the preparation of the port, files that have been added or changed can be picked up with a recursive diff for later feeding to patch. Each set of patches you wish to apply should be collected into a file named `patch-' where denotes the sequence in which the patches will be applied -- these are done in _a_l_p_h_a_b_e_t_i_c_a_l _o_r_d_e_r, thus `aa' first, `ab' second and so on. These files should be stored in ${PATCHDIR}, from where they will be automatically applied. All patches should be relative to ${WRKSRC} (generally the directory your port's tarball unpacks itself into, that being where the build is done). To make fixes and upgrades easier, you should avoid having more than one patch fix the same file (e.g., patch-aa and patch-ab both changing ${WRKSRC}/foo bar.c). _4_._7_._2_._5 _C_o_n_f_i_g_u_r_i_n_g Include any additional customization commands to your configure script and save it in the `scripts' subdirectory. As mentioned above, you can also do this as Makefile targets and/or scripts with the name pre-configure or post-configure. _4_._7_._2_._6 _H_a_n_d_l_i_n_g _u_s_e_r _i_n_p_u_t If your port requires user input to build, configure or install, then set IS_INTERACTIVE in your Makefile. This will allow `overnight builds' to skip your port if the user sets the variable BATCH in his environment (and if the user sets the variable INTERACTIVE, then _o_n_l_y those ports requiring interaction are built). It is also recommended that if there are reasonable default answers to the questions, you check the PACKAGE_BUILDING variable and turn off the interactive script when it is set. This will allow us to build the packages for CD-ROMs and ftp. _4_._7_._3 _C_o_n_f_i_g_u_r_i_n_g _t_h_e _M_a_k_e_f_i_l_e Configuring the Makefile is pretty simple, and again we suggest that you look at existing examples before starting. Also, there is a _s_a_m_p_l_e _M_a_k_e_f_i_l_e (sec tion 4.7.9, page 71) in this handbook, so take a look and please follow the ordering of variables and sections in that template to make your port easier for others to read. Now, consider the following problems in sequence as you design your new Make file: _4_._7_._3_._1 _T_h_e _o_r_i_g_i_n_a_l _s_o_u_r_c_e Does it live in ${DISTDIR} as a standard gzip'd tarball? If so, you can go on to the next step. If not, you should look at overriding any of the ${EXTRACT_CMD}, ${EXTRACT_BEFORE_ARGS}, ${EXTRACT_AFTER_ARGS}, ${EXTRACT_SUFX}, or ${DISTFILES} variables, depending on how alien a format your port's distri bution file is. (The most common case is `EXTRACT_SUFX=.tar.Z', when the tar ball is condensed by regular compress, not gzip.) In the worst case, you can simply create your own `do-extract' target to FreeBSD Handbook 45 override the default, though this should be rarely, if ever, necessary. _4_._7_._3_._2 _D_I_S_T_N_A_M_E You should set ${DISTNAME} to be the base name of your port. The default rules expect the distribution file list (${DISTFILES}) to be named ${DIST NAME}${EXTRACT_SUFX} which, if it is a normal tarball, is going to be something like: foozolix-1.0.tar.gz for a setting of `DISTNAME=foozolix-1.0'. The default rules also expect the tarball(s) to extract into a subdirectory called work/${DISTNAME}, e.g. work/foozolix-1.0/ All this behavior can be overridden, of course; it simply represents the most common time-saving defaults. For a port requiring multiple distribution files, simply set ${DISTFILES} explicitly. If only a subset of ${DISTFILES} are actual extractable archives, then set them up in ${EXTRACT_ONLY}, which will override the ${DISTFILES} list when it comes to extraction, and the rest will be just left in ${DISTDIR} for later use. _4_._7_._3_._3 _P_K_G_N_A_M_E If ${DISTNAME} does not conform to our _g_u_i_d_e_l_i_n_e_s _f_o_r _a _g_o_o_d _p_a_c_k_a_g_e _n_a_m_e (section 4.7.10, page 73), you should set the ${PKGNAME} variable to something better. See the abovementioned guideline for more details. _4_._7_._3_._4 _C_A_T_E_G_O_R_I_E_S When a package is created, it is put under /usr/ports/packages/All and links are made from one or more subdirectories of /usr/ports/packages. The names of these subdirectories are specified by the variable ${CATEGORIES}. It is intended to make life easier for the user when he is wading through the pile of packages on the ftp site or the CD-ROM. Please take a look at the existing _c_a_t_e_g_o_r_i_e_s (section 4.7.11, page 74) and pick the ones that are suitable for your port. This list also determines where in the ports tree the port is imported. If you put more than one category here, it is assumed that the port files will be put in the subdirectory with the name in the first category. See the _c_a_t_e_g_o_r_i_e_s (section 4.7.11, page 74) section for more discussion about how to pick the right categories. If your port truly belongs to something that is different from all the existing ones, you can even create a new category name. In that case, please send mail to the FreeBSD ports mailing list to propose a new category. FreeBSD Handbook 46 Note that there is no error checking for category names; `make package' will happily create a new directory if you mistype the category name, so be careful! _4_._7_._3_._5 _M_A_S_T_E_R___S_I_T_E_S Record the directory part of the ftp/http-URL pointing at the original tarball in ${MASTER_SITES}. Do not forget the trailing slash (/)! The make macros will try to use this specification for grabbing the distribution file with ${FETCH} if they cannot find it already on the system. It is recommended that you put multiple sites on this list, preferably from different continents. This will safeguard against wide-area network problems, and we are even planning to add support for automatically determining the clos est master site and fetching from there! If the original tarball is part of one of the following popular archives: X- contrib, GNU, Perl CPAN, TeX CTAN, or Linux Sunsite, you refer to those sites in an easy compact form using MASTER_SITE_XCONTRIB, MASTER_SITE_GNU, MAS TER_SITE_PERL_CPAN, MASTER_SITE_TEX_CTAN, and MASTER_SITE_SUNSITE. Simply set MASTER_SITE_SUBDIR to the path with in the archive. Here is an example: MASTER_SITES= ${MASTER_SITE_XCONTRIB} MASTER_SITE_SUBDIR= applications The user can also set the MASTER_SITE_* variables in /etc/make.conf to override our choices, and use their favorite mirrors of these popular archives instead. _4_._7_._3_._6 _P_A_T_C_H_F_I_L_E_S If your port requires some additional patches that are available by ftp or http, set ${PATCHFILES} to the names of the files and ${PATCH_SITES} to the URL of the directory that contains them (the format is the same as ${MAS TER_SITES}). If the patch is not relative to the top of the source tree (i.e., ${WKRSRC}) because it contains some extra pathnames, set ${PATCH_DIST_STRIP} accordingly. For instance, if all the pathnames in the patch has an extra `foozolix-1.0/' in front of the filenames, then set `PATCH_DIST_STRIP=-p1'. Do not worry if the patches are compressed, they will be decompressed automati cally if the filenames end with `.gz' or `.Z'. If the patch is distributed with some other files, such as documentation, in a gzip'd tarball, you can't just use ${PATCHFILES}. If that is the case, add the name and the location of the patch tarball to ${DISTFILES} and ${MASTER_SITES}. Then, from the pre-patch target, apply the patch either by running the patch command from there, or copying the patch file into the ${PATCHDIR} directory and calling it patch-. (Note the tarball will have been extracted along side the regular source by then, so there is no need to explicitly extract it if it is a regular gzip'd or compress'd tarball.) If you do the latter, take extra care not to overwrite something that already exists in that directory. Also do not forget to add a command to remove the copied patch in the pre-clean target. FreeBSD Handbook 47 _4_._7_._3_._7 _M_A_I_N_T_A_I_N_E_R Set your mail-address here. Please. :) For detailed description of the responsibility of maintainers, refer to _M_A_I_N_ _T_A_I_N_E_R _o_n _M_a_k_e_f_i_l_e_s (section 20.1, page 404) section. _4_._7_._3_._8 _D_e_p_e_n_d_e_n_c_i_e_s Many ports depend on other ports. There are five variables that you can use to ensure that all the required bits will be on the user's machine. There are also some pre-supported dependency variables for common cases, plus a few more to control the behavior of dependencies. _4_._7_._3_._8_._1 _L_I_B___D_E_P_E_N_D_S This variable specifies the shared libraries this port depends on. It is a list of `lib:dir[:target]' tuples where lib is the name of the shared library, and dir is the directory in which to find it in case it is not available, and target is the target to call in that directory. For example, LIB_DEPENDS= jpeg.9:${PORTSDIR}/graphics/jpeg:install will check for a shared jpeg library with major version 9, and descend into the graphics/jpeg subdirectory of your ports tree to build and install it if it is not found. The `:target' part can be omitted if it is equal to ${DEPENDS_TAR GET} (which defaults to `install'). Note that the lib part is an argument given to `ldconfig -r | grep -wF'. There shall be no regular expressions in this variable. The dependency is checked twice, once from within the extract target and then from within the install target. (This is to ensure that the library is avail able even if the port is installed on a different machine from where it was built.) Also, the name of the dependency is put in to the package so that pkg_add will automatically install it if it is not on the user's system. _4_._7_._3_._8_._2 _R_U_N___D_E_P_E_N_D_S This variable specifies executables or files this port depends on during run- time. It is a list of `path:dir[:target]' tuples where path is the name of the executable or file, and dir is the directory in which to find it in case it is not available, and `target' is the target to call in that directory. If path starts with a slash (/), it is treated as a file or directory and its existence is tested with `test -e'; otherwise, it is assumed to be an executable, and `which -s' is used to determine if the program exists in the user's search path. For example, RUN_DEPENDS= ${PREFIX}/etc/innd:${PORTSDIR}/news/inn \ wish8.0:${PORTSDIR}/x11-toolkits/tk80 FreeBSD Handbook 48 will check if the file or directory `/usr/local/etc/innd' exists, and build and install it from the news/inn subdirectory of the ports tree if it is not found. It will also see if an executable called `wish8.0' is in your search path, and descend into the x11-toolkits/tk80 subdirectory of your ports tree to build and install it if it is not found. (Note that in this case, `innd' is actually an executable; if an executable is in a place that is not expected to be in a nor mal user's search path, you should use the full pathname.) The dependency is checked from within the install target. Also, the name of the dependency is put in to the package so that pkg_add will automatically install it if it is not on the user's system. The `:target' part can be omit ted if it is the same as ${DEPENDS_TARGET}. _4_._7_._3_._8_._3 _B_U_I_L_D___D_E_P_E_N_D_S This variable specifies executables or files this port requires to build. Like RUN_DEPENDS, it is a list of `path:dir[:target]' tuples. For example, BUILD_DEPENDS= unzip:${PORTSDIR}/archivers/unzip will check for an executable called `unzip', and descend into the archivers/unzip subdirectory of your ports tree to build and install it if it is not found. Note that `build' here means everything from extracting to compilation. The dependency is checked from within the extract target. The `:target' part can be omitted if it is the same as ${DEPENDS_TARGET}. _4_._7_._3_._8_._4 _F_E_T_C_H___D_E_P_E_N_D_S This variable specifies executables or files this port requires to fetch. Like the previous two, it is a list of `path:dir[:target]' pairs. For example, FETCH_DEPENDS= ncftp2:${PORTSDIR}/net/ncftp2 will check for an executable called `ncftp2', and descend into the net/ncftp2 subdirectory of your ports tree to build and install it if it is not found. The dependency is checked from within the fetch target. The `:target' part can be omitted if it is the same as ${DEPENDS_TARGET}. _4_._7_._3_._8_._5 _D_E_P_E_N_D_S If there is a dependency that does not fall into either of the above four cate gories, or your port requires to have the source of the other port extracted in addition to having them installed, then use this variable. This is a list of `dir[:target]', as there is nothing to check, unlike the previous four. The `:target' part can be omitted if it is the same as ${DEPENDS_TARGET}. _4_._7_._3_._8_._6 _C_o_m_m_o_n _d_e_p_e_n_d_e_n_c_y _v_a_r_i_a_b_l_e_s Define `USE_XLIB=yes' if your port requires the X Window System to be installed FreeBSD Handbook 49 (it is implied by USE_IMAKE). Define `USE_GMAKE=yes' if your port requires GNU make instead of BSD make. Define `USE_AUTOCONF=yes' if your port requires GNU autoconf to be run. Define `USE_QT=yes' if your port uses the latest qt toolkit. Use `USE_PERL5=yes' if your port requires version 5 of the perl lan guage. (The last is especially important since some versions of FreeBSD has perl5 as part of the base system while others don't.) _4_._7_._3_._8_._7 _N_o_t_e_s _o_n _d_e_p_e_n_d_e_n_c_i_e_s As mentioned above, the default target to call when a dependency is required is ${DEPENDS_TARGET}. It defaults to `install'. This is a user variable; it is never defined in a port's Makefile. If your port needs a special way to handle a dependency, use the `:target' part of the *_DEPENDS variables instead of redefining ${DEPENDS_TARGET}. When you type `make clean', its dependencies are automatically cleaned too. If you do not wish this to happen, define the variable NOCLEANDEPENDS in your environment. To depend on another port unconditionally, it is customary to use the string `nonexistent' as the first field of BUILD_DEPENDS or RUN_DEPENDS. Use this only when you need the to get to the source of the other port. You can often save compilation time by specifying the target too. For instance, BUILD_DEPENDS= /nonexistent:${PORTSDIR}/graphics/jpeg:extract will always descend to the JPEG port and extract it. Do not use `DEPENDS' unless there is no other way the behavior you want can be accomplished. It will cause the other port to be always built (and installed, by default), and the dependency will go into the package as well. If this is really what you need, I recommend you to write it as BUILD_DEPENDS and RUN_DEPENDS instead -- at least the intention will be clear. _4_._7_._3_._9 _B_u_i_l_d_i_n_g _m_e_c_h_a_n_i_s_m_s If your package uses GNU make, set `USE_GMAKE=yes'. If your package uses con figure, set `HAS_CONFIGURE=yes'. If your package uses GNU configure, set `GNU_CONFIGURE=yes' (this implies HAS_CONFIGURE). If you want to give some extra arguments to configure (the default argument list `--prefix=${PREFIX}' for GNU configure and empty for non-GNU configure), set those extra arguments in ${CONFIGURE_ARGS}. If your package uses GNU autoconf, set `USE_AUTO CONF=yes'. This implies GNU_CONFIGURE, and will cause autoconf to be run before configure. If your package is an X application that creates Makefiles from Imakefiles using imake, then set `USE_IMAKE=yes'. This will cause the configure stage to automatically do an xmkmf -a. If the `-a' flag is a problem for your port, set `XMKMF=xmkmf'. If the port uses imake but does not understand the `install.man' target, `NO_INSTALL_MANPAGES=yes' should be set. In addition, the author of the original port should be shot. :> If your port's source Makefile has something else than `all' as the main build FreeBSD Handbook 50 target, set ${ALL_TARGET} accordingly. Same goes for `install' and ${INSTALL_TARGET}. _4_._7_._4 _S_p_e_c_i_a_l _C_o_n_s_i_d_e_r_a_t_i_o_n_s There are some more things you have to take into account when you create a port. This section explains the most common of those. _4_._7_._4_._1 _l_d_c_o_n_f_i_g If your port installs a shared library, add a post-install target to your Make file that runs `${LDCONFIG} -m' on the directory where the new library is installed (usually ${PREFIX}/lib) to register it into the shared library cache. Also, add a matching `@exec /sbin/ldconfig -m'/`@unexec /sbin/ldconfig -R' pair to your pkg/PLIST file so that a user who installed the package can start using the shared library immediately and deinstallation will not cause the system to still believe the library is there. These lines should immediately follow the line for the shared library itself, as in: lib/libtcl80.so.1 @exec /sbin/ldconfig -m %D/lib @unexec /sbin/ldconfig -R Never, ever, _e_v_e_r add a line that says `ldconfig' without any arguments to your Makefile or pkg/PLIST. This will reset the shared library cache to the con tents of /usr/lib only, and will royally screw up the user's machine ("Help, xinit does not run anymore after I install this port!"). Anybody who does this will be shot and cut into 65,536 pieces by a rusty knife and have his liver chopped out by a bunch of crows and will eternally rot to death in the deepest bowels of hell (not necessarily in that order).... _4_._7_._4_._2 _E_L_F _s_u_p_p_o_r_t Since FreeBSD is moving to ELF from 3.0-release onwards, we need to convert many ports that build shared libraries to support ELF. Complicating this task is that a 3.0 system can run as both ELF and a.out, and that there will be one more release (2.2.8) from the 2.2 branch. Below are the guidelines on how to convert a.out only ports to support both a.out and ELF compilation. Some part of this list is only applicable during the conversion, but will be left here for awhile for reference in case you have come across some old port you wish to upgrade. _4_._7_._4_._2_._1 _M_o_v_i_n_g _a_._o_u_t _l_i_b_r_a_r_i_e_s _o_u_t _o_f _t_h_e _w_a_y A.out libraries should be moved out of /usr/local/lib and similar to an `aout' subdirectory. (If you don't move them out of the way, ELF ports will happily overwrite a.out libraries.) The `move-aout-libs' target in the -current src/Makefile (called from `aout-to-elf') will do this for you. It will only move a.out libs so it is safe to call it on a system with both ELF and a.out libs in the standard directories. FreeBSD Handbook 51 _4_._7_._4_._2_._2 _F_o_r_m_a_t The ports tree will build packages in the format the machine is in. This means a.out for 2.2 and a.out or ELF for 3.0 depending on what `objformat` returns. Also, once users move a.out libraries to a subdirectory, building a.out libraries will be unsupported. (I.e., it may still work if you know what you are doing, but you are on your own.) Note: if a port only works for a.out, set BROKEN_ELF to a string describing the reason why. Such ports will be skipped during a build on an ELF system. _4_._7_._4_._2_._3 _P_O_R_T_O_B_J_F_O_R_M_A_T bsd.port.mk will set PORTOBJFORMAT to `aout' or `elf' and export it in the environments CONFIGURE_ENV, SCRIPTS_ENV and MAKE_ENV. (It's always going to be `aout' in -stable). It is also passed to PLIST_SUB as `PORTOBJFORMAT=${PORTOB JFORMAT}'. (See comment on ldconfig lines below.) The variable is set using this line: PORTOBJFORMAT!= test -x /usr/bin/objformat && /usr/bin/objformat || echo aout in bsd.port.mk. Ports' make processes should use this variable to decide what to do. However, if the port's configure script already automatically detects an ELF system, it is not necessary to refer to PORTOBJFORMAT. _4_._7_._4_._2_._4 _B_u_i_l_d_i_n_g _s_h_a_r_e_d _l_i_b_r_a_r_i_e_s The following are differences in handling shared libraries for a.out and ELF. Shared library versions An ELF shared library should be called "libfoo.so.M" where M is the single version number, and an a.out library should be called "lib foo.so.M.N" where M is the major version and N is the the minor version number. Do not mix those; _n_e_v_e_r install an ELF shared library called "libfoo.so.N.M" or an a.out shared library (or sym link) called "libfoo.so.N". Linker command lines Assuming `cc -shared' is used rather than `ld' directly, the only difference is that you need to add `-Wl,-soname,libfoo.so.M' on the command line for ELF. You need to install a symlink libfoo.so -> libfoo.so.N to make ELF linkers happy. Since it should be listed in PLIST too, and it won't hurt in the a.out case (some ports even require the link for dynamic loading), you should just make this link regardless of the setting of PORTOBJFORMAT. _4_._7_._4_._2_._5 _L_I_B___D_E_P_E_N_D_S All port Makefiles are edited to remove minor numbers from LIB_DEPENDS, and FreeBSD Handbook 52 also to have the regexp support removed. (E.g., `foo\\.1\\.\\(33|40\\)' -> `foo.2'.) They will be matched using `grep -wF'. _4_._7_._4_._2_._6 _P_L_I_S_T PLIST should contain the short (ELF) shlib names if the a.out minor number is zero, and the long (a.out) names otherwise. bsd.port.mk will automatically add `.0' to the end of short shlib lines if PORTOBJFORMAT equals aout, and will delete the minor number from long shlib names if PORTOBJFORMAT equals elf. In cases where you really need to install shlibs with two versions on an ELF system or those with one version on an a.out system (for instance, ports that install compatibility libraries for other operating systems), define the vari able NO_FILTER_SHLIBS. This will turn off the editing of PLIST mentioned in the previous paragraph. _4_._7_._4_._2_._7 _l_d_c_o_n_f_i_g The ldconfig line in Makefiles should read: ${SETENV} OBJFORMAT=${PORTOBJFORMAT} ${LDCONFIG} -m .... and in PLIST: @exec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -m ... @unexec /usr/bin/env OBJFORMAT=%%PORTOBJFORMAT%% /sbin/ldconfig -R This is to ensure that the correct ldconfig will be called depending on the format of the package, not the default format of the system. _4_._7_._4_._3 _M_A_S_T_E_R_D_I_R If your port needs to build slightly different versions of packages by having a variable (for instance, resolution or paper size) take different values, create one subdirectory per package to make it easier for users to see what to do, but try to share as many files as possible between ports. Typically you only need a very short Makefile in all but one of the directories if you use variables cleverly. In the sole Makefiles, you can use ${MASTERDIR} to specify the directory where the rest of the files are. Also, use a variable as part of _P_K_G_N_A_M_E (section 4.7.10, page 73) so the packages will have different names. This will be best demostrated by an example. This is part of japanese/xdvi300/Makefile: FreeBSD Handbook 53 : PKGNAME= ja-xdvi${RESOLUTION}-17 : # default RESOLUTION?= 300 .if ${RESOLUTION} != 118 && ${RESOLUTION} != 240 && \ ${RESOLUTION} != 300 && ${RESOLUTION} != 400 @${ECHO} "Error: invalid value for RESOLUTION: \"${RESOLUTION}\"" @${ECHO} "Possible values are: 118, 240, 300 (default) and 400." @${FALSE} .endif japanese/xdvi300 also has all the regular patches, package files, etc. If you type `make' there, it will take the default value for the resolution (300) and build the port normally. As for other resolutions, this is the _e_n_t_i_r_e xdvi118/Makefile (minus the com ments): RESOLUTION= 118 MASTERDIR= ${.CURDIR}/../xdvi300 .include "${MASTERDIR}/Makefile" (xdvi240/Makefile and xdvi400/Makefile are similar). The ${MASTERDIR} defini tion tells bsd.port.mk that the regular set of subdirectories like ${PATCHDIR} and ${PKGDIR} are to be found under xdvi300. The RESOLUTION=118 line will override the RESOLUTION?=300 line in xdvi300/Makefile and the port will be built with resolution set to 118. _4_._7_._4_._4 _S_h_a_r_e_d _l_i_b_r_a_r_y _v_e_r_s_i_o_n_s First, please read our _p_o_l_i_c_y _o_n _s_h_a_r_e_d _l_i_b_r_a_r_y _v_e_r_s_i_o_n_i_n_g (section 20.3, page 408) to understand what to do with shared library versions in general. Do not blindly assume software authors know what they are doing; many of them do not. It is very important that these details are carefully considered, as we have quite a unique situation where we are trying to have dozens of potentially incompatible software pairs co-exist. Careless port imports have caused great trouble regarding shared libraries in the past (ever wondered why the port jpeg-6b has a shared library version of `9.0'?). If in doubt, send a message to the FreeBSD ports mailing list . Most of the time, your job ends by determining the right shared library version and making appropriate patches to implement it. However, if there is a port which is a different version of the same software already in the tree, the situation is much more complex. In short, the FreeBSD implementation does not allow the user to specify to the linker which version of shared library to link against (the linker will always pick the highest num bered version). This means, if there is a libfoo.so.3.2 and libfoo.so.4.0 in the system, there is no way to tell the linker to link a particular application to libfoo.so.3.2. It is essentially completely overshadowed in terms of compi lation-time linkage. In this case, the only solution is to rename the `base' FreeBSD Handbook 54 part of the shared library. For instance, change libfoo.so.4.0 to lib foo4.so.1.0 so both version 3.2 and 4.0 can be linked from other ports. _4_._7_._4_._5 _M_a_n_p_a_g_e_s The MAN[1-9LN] variables will automatically add any manpages to pkg/PLIST (this means you must _n_o_t list manpages in the PLIST -- see _g_e_n_e_r_a_t_i_n_g _P_L_I_S_T (section 4.7.5.4, page 61) for more). It also makes the install stage automatically compress or uncompress manpages depending on the setting of NOMANCOMPRESS in /etc/make.conf. To specify whether the manpages are compressed upon installation, use the MAN COMPRESSED variable. This variable can take three values, `yes', `no' and `maybe'. `yes' means manpages are already installed compressed, `no' means they are not, and `maybe' means the software already respects the value of NOMANCOMPRESS so bsd.port.mk does not have to do anything special. MANCOMPRESSED is automatically set to `yes' if USE_IMAKE is set and NO_INSTALL_MANPAGES is not set, and to `no' otherwise. You don't have to explicitly define it unless the default is not suitable for your port. If your port anchors its man tree somewhere other than PREFIX, you can use the MANPREFIX to set it. Also, if only manpages in certain sections go in a non- standard place, such as some Perl modules ports, you can set individual man paths using MAN_s_e_c_tPREFIX (where _s_e_c_t is one of 1-9, L or N). If your manpages go to language-specific subdirectories, set the name of the languages to MANLANG. The value of this variable defaults to "" (i.e., English only). Here is an example that puts it all together. MAN1= foo.1 MAN3= bar.3 MAN4= baz.4 MANLANG= "" ja MAN3PREFIX= ${PREFIX}/share/foobar MANCOMPRESSED= yes states that six files ${PREFIX}/man/man1/foo.1.gz ${PREFIX}/man/ja/man1/foo.1.gz ${PREFIX}/share/foobar/man/man3/bar.3.gz ${PREFIX}/share/foobar/man/ja/man3/bar.3.gz ${PREFIX}/man/man4/baz.4.gz ${PREFIX}/man/ja/man4/baz.4.gz are installed by this port. FreeBSD Handbook 55 _4_._7_._4_._6 _P_o_r_t_s _t_h_a_t _r_e_q_u_i_r_e _M_o_t_i_f There are many programs that require a Motif library (available from several commercial vendors, while there is a free clone reported to be able to run many applications in x11-toolkits/lesstif) to compile. Since it is a popular toolkit and their licenses usually permit redistribution of statically linked binaries, we have made special provisions for handling ports that require Motif in a way that we can easily compile binaries linked either dynamically (for people who are compiling from the port) or statically (for people who dis tribute packages). _4_._7_._4_._6_._1 _R_E_Q_U_I_R_E_S___M_O_T_I_F If your port requires Motif, define this variable in the Makefile. This will prevent people who don't own a copy of Motif from even attempting to build it. _4_._7_._4_._6_._2 _$_{_M_O_T_I_F_L_I_B_} This variable will be set by bsd.port.mk to be the appropriate reference to the Motif library. Please patch the source to use this wherever the Motif library is referenced in the Makefile or Imakefile. There are two common cases: 1. If the port refers to the Motif library as `-lXm' in its Makefile or Imakefile, simply substitute `${MOTIFLIB}' for it. 2. If the port uses `XmClientLibs' in its Imakefile, change it to `${MOTI FLIB} ${XTOOLLIB} ${XLIB}'. Note that ${MOTIFLIB} (usually) expands to `-L/usr/X11R6/lib -lXm' or `/usr/X11R6/lib/libXm.a', so there is no need to add `-L' or `-l' in front. _4_._7_._4_._7 _X_1_1 _f_o_n_t_s If your port installs fonts for the X window system, put them in ${X11BASE}/lib/X11/fonts/local. This directory is new to XFree86 release 3.3.3. If it does not exist, please create it, and print out a message urging the user to update their XFree86 to 3.3.3 or newer, or at least add this direc tory to the font path in /etc/XF86Config. _4_._7_._4_._8 _I_n_f_o _f_i_l_e_s The new version of texinfo (included in 2.2.2-RELEASE and onwards) contains a utility called `install-info' to add and delete entries to the `dir' file. If your port installs any info documents, please follow these instructions so your port/package will correctly update the user's ${PREFIX}/info/dir file. (Sorry for the length of this section, but it is imperative to weave all the info files together. If done correctly, it will produce a _b_e_a_u_t_i_f_u_l listing, so please bear with me! :) First, this is what you (as a porter) need to know: FreeBSD Handbook 56 % install-info --help install-info [OPTION]... [INFO-FILE [DIR-FILE]] Install INFO-FILE in the Info directory file DIR-FILE. Options: --delete Delete existing entries in INFO-FILE; don't insert any new entries. : --entry=TEXT Insert TEXT as an Info directory entry. : --section=SEC Put this file's entries in section SEC of the directory. : Note that this program will not actually _i_n_s_t_a_l_l info files; it merely inserts or deletes entries in the dir file. Here's a seven-step procedure to convert ports to use install-info. I will use editors/emacs as an example. 1. Look at the texinfo sources and make a patch to insert @dircategory and @direntry statements to files that don't have them. This is part of my patch: --- ./man/vip.texi.org Fri Jun 16 15:31:11 1995 +++ ./man/vip.texi Tue May 20 01:28:33 1997 @@ -2,6 +2,10 @@ @setfilename ../info/vip @settitle VIP +@dircategory The Emacs editor and associated tools +@direntry +* VIP: (vip). A VI-emulation for Emacs. +@end direntry @iftex @finalout : The format should be self-explanatory. Many authors leave a dir file in the source tree that contains all the entries you need, so look around before you try to write your own. Also, make sure you look into related ports and make the section names and entry indentations consistent (we recommend that all entry text start at the 4th tab stop). Note that you can put only one info entry per file because of a bug in `install-info --delete' that deletes only the first entry if you specify multiple entries in the @direntry section. You can give the dir entries to install-info as arguments (--section and --entry) instead of patching the texinfo sources. I do not think this is FreeBSD Handbook 57 a good idea for ports because you need to duplicate the same information in _t_h_r_e_e places (Makefile and @exec/@unexec of PLIST; see below). How ever, if you have a Japanese (or other multibyte encoding) info files, you will have to use the extra arguments to install-info because makeinfo can't handle those texinfo sources. (See Makefile and PLIST of japanese/skk for examples on how to do this). 2. Go back to the port directory and do a `make clean; make' and verify that the info files are regenerated from the texinfo sources. Since the tex info sources are newer than the info files, they should be rebuilt when you type make; but many Makefiles don't include correct dependencies for info files. In emacs' case, I had to patch the main Makefile.in so it will descend into the man subdirectory to rebuild the info pages. --- ./Makefile.in.org Mon Aug 19 21:12:19 1996 +++ ./Makefile.in Tue Apr 15 00:15:28 1997 @@ -184,7 +184,7 @@ # Subdirectories to make recursively. `lisp' is not included # because the compiled lisp files are part of the distribution # and you cannot remake them without installing Emacs first. -SUBDIR = lib-src src +SUBDIR = lib-src src man # The makefiles of the directories in $SUBDIR. SUBDIR_MAKEFILES = lib-src/Makefile man/Makefile src/Makefile oldXMenu/Makefile lwlib/Makefile --- ./man/Makefile.in.org Thu Jun 27 15:27:19 1996 +++ ./man/Makefile.in Tue Apr 15 00:29:52 1997 @@ -66,6 +66,7 @@ ${srcdir}/gnu1.texi \ ${srcdir}/glossary.texi +all: info info: $(INFO_TARGETS) dvi: $(DVI_TARGETS) The second hunk was necessary because the default target in the man sub dir is called info, while the main Makefile wants to call all. I also deleted the installation of the info info file because we already have one with the same name in /usr/share/info (that patch is not shown here). 3. If there is a place in the Makefile that is installing the dir file, delete it. Your port may not be doing it. Also, remove any commands that are otherwise mucking around with the dir file. FreeBSD Handbook 58 --- ./Makefile.in.org Mon Aug 19 21:12:19 1996 +++ ./Makefile.in Mon Apr 14 23:38:07 1997 @@ -368,14 +368,8 @@ if [ `(cd ${srcdir}/info && /bin/pwd)` != `(cd ${infodir} && /bin/pwd)` ]; \ then \ (cd ${infodir}; \ - if [ -f dir ]; then \ - if [ ! -f dir.old ]; then mv -f dir dir.old; \ - else mv -f dir dir.bak; fi; \ - fi; \ cd ${srcdir}/info ; \ - (cd $${thisdir}; ${INSTALL_DATA} ${srcdir}/info/dir ${infodir}/dir); \ - (cd $${thisdir}; chmod a+r ${infodir}/dir); \ for f in ccmode* cl* dired-x* ediff* emacs* forms* gnus* info* message* mh-e* sc* vip*; do \ (cd $${thisdir}; \ ${INSTALL_DATA} ${srcdir}/info/$$f ${infodir}/$$f; \ chmod a+r ${infodir}/$$f); \ 4. (This step is only necessary if you are modifying an existing port.) Take a look at pkg/PLIST and delete anything that is trying to patch up info/dir. They may be in pkg/INSTALL or some other file, so search extensively. Index: pkg/PLIST =================================================================== RCS file: /usr/cvs/ports/editors/emacs/pkg/PLIST,v retrieving revision 1.15 diff -u -r1.15 PLIST --- PLIST 1997/03/04 08:04:00 1.15 +++ PLIST 1997/04/15 06:32:12 @@ -15,9 +15,6 @@ man/man1/emacs.1.gz man/man1/etags.1.gz man/man1/ctags.1.gz -@unexec cp %D/info/dir %D/info/dir.bak -info/dir -@unexec cp %D/info/dir.bak %D/info/dir info/cl info/cl-1 info/cl-2 5. Add a post-install target to the Makefile to create a dir file if it is not there. Also, call install-info with the installed info files. FreeBSD Handbook 59 Index: Makefile =================================================================== RCS file: /usr/cvs/ports/editors/emacs/Makefile,v retrieving revision 1.26 diff -u -r1.26 Makefile --- Makefile 1996/11/19 13:14:40 1.26 +++ Makefile 1997/05/20 10:25:09 1.28 @@ -20,5 +20,11 @@ post-install: .for file in emacs-19.34 emacsclient etags ctags b2m strip ${PREFIX}/bin/${file} .endfor + if [ ! -f ${PREFIX}/info/dir ]; then \ + ${SED} -ne '1,/Menu:/p' /usr/share/info/dir > ${PREFIX}/info/dir; \ + fi +.for info in emacs vip viper forms gnus mh-e cl sc dired-x ediff ccmode + install-info ${PREFIX}/info/${info} ${PREFIX}/info/dir +.endfor .include Do not use anything other than /usr/share/info/dir and the above command to create a new info file. In fact, I'd add the first three lines of the above patch to bsd.port.mk if you (the porter) wouldn't have to do it in PLIST by yourself anyway. 6. Edit PLIST and add equivalent @exec statements and also @unexec for pkg_delete. You do not need to delete info/dir with @unexec. FreeBSD Handbook 60 Index: pkg/PLIST =================================================================== RCS file: /usr/cvs/ports/editors/emacs/pkg/PLIST,v retrieving revision 1.15 diff -u -r1.15 PLIST --- PLIST 1997/03/04 08:04:00 1.15 +++ PLIST 1997/05/20 10:25:12 1.17 @@ -16,7 +14,15 @@ man/man1/etags.1.gz man/man1/ctags.1.gz +@unexec install-info --delete %D/info/emacs %D/info/dir : +@unexec install-info --delete %D/info/ccmode %D/info/dir info/cl info/cl-1 @@ -87,6 +94,18 @@ info/viper-3 info/viper-4 +@exec [ -f %D/info/dir ] || sed -ne '1,/Menu:/p' /usr/share/info/dir > %D/info/dir +@exec install-info %D/info/emacs %D/info/dir : +@exec install-info %D/info/ccmode %D/info/dir libexec/emacs/19.34/i386--freebsd/cvtmail libexec/emacs/19.34/i386--freebsd/digest-doc Note that the `@unexec install-info --delete' commands have to be listed before the info files themselves so they can read the files. Also, the `@exec install-info' commands have to be after the info files and the @exec command that creates the the dir file. 7. _T_e_s_t (section 4.7.1.4, page 40) and admire your work. :) Check the dir file before and after each step. _4_._7_._5 _T_h_e _p_k_g _S_u_b_d_i_r_e_c_t_o_r_y There are some tricks we haven't mentioned yet about the pkg subdirectory that come in handy sometimes. _4_._7_._5_._1 _M_E_S_S_A_G_E If you need to display a message to the installer, you may place the message in pkg/MESSAGE. This capability is often useful to display additional installa tion steps to be taken after a pkg_add, or to display licensing information. Note the pkg/MESSAGE file does not need to be added to pkg/PLIST. Also, it will not get automatically printed if the user is using the port, not the pack age, so you should probably display it from the post-install target by your self. _4_._7_._5_._2 _I_N_S_T_A_L_L If your port needs execute commands when the binary package is installed with FreeBSD Handbook 61 pkg_add you can do with via the pkg/INSTALL script. This script will automati cally be added to the package, and will be run twice by pkg_add. The first time will as `INSTALL ${PKGNAME} PRE-INSTALL' and the second time as `INSTALL ${PKGNAME} POST-INSTALL'. `$2' can be tested to determine which mode the script is being run in. The `PKG_PREFIX' environmental variable will be set to the package installation directory. See man pkg_add(1) for additional informa tion. Note, that this script is not run automatically if you install the port with `make install'. If you are depending on it being run, you will have to explicitly call it on your port's Makefile. _4_._7_._5_._3 _R_E_Q If your port needs to determine if it should install or not, you can create a pkg/REQ ``requirements'' script. It will be invoked automatically at installa tion/deinstallation time to determine whether or not installation/deinstalla tion should proceed. _4_._7_._5_._4 _C_h_a_n_g_i_n_g _P_L_I_S_T _b_a_s_e_d _o_n _m_a_k_e _v_a_r_i_a_b_l_e_s Some ports, particularly the p5- ports, need to change their PLIST depending on what options they are configured with (or version of perl, in the case of p5- ports). To make this easy, any instances in the PLIST of %%OSREL%%, %%PERL_VER%%, and %%PERL_VERSION%% will be substituted for appropriately. The value of %%OSREL%% is the numeric revision of the operating system (e.g., `2.2.7'). %%PERL_VERSION%% is the full version number of perl (e.g., `5.00502') and %%PERL_VER%% is the perl version number minus the patchlevel (e.g., `5.005'). If you need to make other substitutions, you can set the PLIST_SUB variable with a list of VAR=VALUE pairs and instances of `%%VAR%%' will be substituted with `VALUE' in the PLIST. For instance, if you have a port that installs many files in a version-specific subdirectory, you can put something like OCTAVE_VERSION= 2.0.13 PLIST_SUB= OCTAVE_VERSION=${OCTAVE_VERSION} in the Makefile and use %%OCTAVE_VERSION%% wherever the version shows up in PLIST. That way, when you upgrade the port, you will not have to change dozens (or in some cases, hundreds) of lines in the PLIST. This substitution (as well as addition of any _m_a_n _p_a_g_e_s (section 4.7.4.5, page 54)) will be done between the do-install and post-install targets, by reading from ${PLIST} and writing to ${TMPPLIST} (default: ${WRKDIR}/.PLIST.mktmp). So if your port builds ${PLIST} on the fly, do so in or before do-install. Also, if your port needs to edit the resulting file, do so in post-install to a file named ${TMPPLIST}. _4_._7_._6 _L_i_c_e_n_s_i_n_g _P_r_o_b_l_e_m_s Some software packages have restrictive licenses or can be in violation to the law (PKP's patent on public key crypto, ITAR (export of crypto software) to name just two of them). What we can do with them vary a lot, depending on the exact wordings of the respective licenses. FreeBSD Handbook 62 Note that it is your responsibility as a porter to read the licensing terms of the software and make sure that the FreeBSD project will not be held account able of violating them by redistributing the source or compiled binaries either via ftp or CD-ROM. If in doubt, please contact the FreeBSD ports mailing list . There are two variables you can set in the Makefile to handle the situations that arise frequently: 1. If the port has a `do not sell for profit' type of license, set the vari able NO_CDROM to the string describing the reason why. We will make sure such ports won't go into the CD-ROM come release time. The distfile and package will still be available via ftp. 2. If the resulting package needs to be built uniquely for each site, or the resulting binary package can't be distributed due to licensing, set the variable NO_PACKAGE to the string describing the reason why. We will make sure such packages won't go on the ftp site, nor into the CD-ROM come release time. The distfile will still be included on both however. 3. If the port has legal restrictions on who can use it (e.g., crypto stuff) or has a `no commercial use' license, set the variable RESTRICTED to be the string describing the reason why. For such ports, the dist files/packages will not be available even from our ftp sites. Note: The GNU General Public License (GPL), both version 1 and 2, should not be a problem for ports. Note: If you are a committer, make sure you update the ports/LEGAL file too. _4_._7_._7 _U_p_g_r_a_d_i_n_g When you notice that a port is out of date compared to the latest version from the original authors, first make sure you have the latest port. You can find them in the ports-current directory of the ftp mirror sites. The next step is to send a mail to the maintainer, if one is listed in the port's Makefile. That person may already be working on an upgrade, or have a reason to not upgrade the port right now (because of, for example, stability problems of the new version). If the maintainer asks you to do the upgrade or there isn't any such person to begin with, please make the upgrade and send the recursive diff (either unified or context diff is fine, but port committers appear to prefer unified diff more) of the new and old ports directories to us (e.g., if your modified port directory is called `superedit' and the original as in our tree is `superedit.bak', then send us the result of `diff -ruN superedit.bak superedit'). Please examine the output to make sure all the changes make sense. The best way to send us the diff is by including it to send-pr(1) (cat egory `ports'). Please mention any added or deleted files in the message, as they have to be explicitly specified to CVS when doing a commit. If the diff is more than about 20KB, please compress and uuencode it; otherwise, just include it in as is in the PR. FreeBSD Handbook 63 _4_._7_._8 _D_o_'_s _a_n_d _D_o_n_t_'_s " Here is a list of common do's and dont's that you encounter during the porting process. You should check your own port against this list, but you can also check ports in the PR database that others have submitted. Submit any comments on ports you check as described in _B_u_g _R_e_p_o_r_t_s _a_n_d _G_e_n_e_r_a_l _C_o_m_m_e_n_t_a_r_y (section 19.2.1, page 380). Checking ports in the PR database will both make it faster for us to commit them, and prove that you know what you are doing. _4_._7_._8_._1 _S_t_r_i_p _B_i_n_a_r_i_e_s Do strip binaries. If the original source already strips the binaries, fine; otherwise you should add a post-install rule to do it yourself. Here is an example: post-install: strip ${PREFIX}/bin/xdl Use the file command on the installed executable to check whether the binary is stripped or not. If it does not say `not stripped', it is stripped. _4_._7_._8_._2 _I_N_S_T_A_L_L___* _m_a_c_r_o_s Do use the macros provided in bsd.port.mk to ensure correct modes and ownership of files in your own *-install targets. They are: ${INSTALL_PROGRAM} is a command to install binary executables. ${INSTALL_SCRIPT} is a command to install executable scripts. ${INSTALL_DATA} is a command to install sharable data. ${INSTALL_MAN} is a command to install manpages and other documentation (it doesn't compress anything). These are basically the install command with all the appropriate flags. See below for an example on how to use them. _4_._7_._8_._3 _D_i_f_f_e_r_e_n_t_i_a_t_i_n_g _o_p_e_r_a_t_i_n_g _s_y_s_t_e_m_s _a_n_d _O_S _v_e_r_s_i_o_n_s You may come across code that needs modifications or conditional compilation based upon what version of UNIX it is running under. If you need to make such changes to the code for conditional compilation, make sure you make the changes as general as possible so that we can back-port code to FreeBSD 1.x systems and cross-port to other BSD systems such as 4.4BSD from CSRG, BSD/386, 386BSD, NetBSD, and OpenBSD. The preferred way to tell 4.3BSD/Reno (1990) and newer versions of the BSD code apart is by using the `BSD' macro defined in . Hopefully that file is already included; if not, add the code: FreeBSD Handbook 64 #if (defined(__unix__) || defined(unix)) && !defined(USG) #include #endif to the proper place in the .c file. We believe that every system that defines these to symbols has sys/param.h. If you find a system that doesn't, we would like to know. Please send mail to the FreeBSD ports mailing list . Another way is to use the GNU Autoconf style of doing this: #ifdef HAVE_SYS_PARAM_H #include #endif Don't forget to add -DHAVE_SYS_PARAM_H to the CFLAGS in the Makefile for this method. Once you have included, you may use: #if (defined(BSD) && (BSD >= 199103)) to detect if the code is being compiled on a 4.3 Net2 code base or newer (e.g. FreeBSD 1.x, 4.3/Reno, NetBSD 0.9, 386BSD, BSD/386 1.1 and below). Use: #if (defined(BSD) && (BSD >= 199306)) to detect if the code is being compiled on a 4.4 code base or newer (e.g. FreeBSD 2.x, 4.4, NetBSD 1.0, BSD/386 2.0 or above). The value of the BSD macro is 199506 for the 4.4BSD-Lite2 code base. This is stated for informational purposes only. It should not be used to distinguish between version of FreeBSD based only on 4.4-Lite vs. versions that have merged in changes from 4.4-Lite2. The __FreeBSD__ macro should be used instead. Use sparingly: __FreeBSD__ is defined in all versions of FreeBSD. Use it if the change you are making ONLY affects FreeBSD. Porting gotchas like the use of sys_errlist[] vs strerror() are Berkeleyisms, not FreeBSD changes. In FreeBSD 2.x, __FreeBSD__ is defined to be 2. In earlier versions, it is 1. Later versions will bump it to match their major version number. If you need to tell the difference between a FreeBSD 1.x system and a FreeBSD 2.x or 3.x system, usually the right answer is to use the BSD macros described above. If there actually is a FreeBSD specific change (such as special shared library options when using `ld') then it is OK to use __FreeBSD__ and `#if __FreeBSD__ > 1' to detect a FreeBSD 2.x and later system. If you need more granularity in detecting FreeBSD systems since FreeBSD Handbook 65 2.0-RELEASE you can use the following: #if __FreeBSD__ >= 2 #include # if __FreeBSD_version >= 199504 /* 2.0.5+ release specific code here */ # endif #endif __FreeBSD_version values: 2.0-RELEASE: 199411 2.1-current's: 199501, 199503 2.0.5-RELEASE: 199504 2.2-current before 2.1: 199508 2.1.0-RELEASE: 199511 2.2-current before 2.1.5: 199512 2.1.5-RELEASE: 199607 2.2-current before 2.1.6: 199608 2.1.6-RELEASE: 199612 2.1.7-RELEASE: 199612 2.2-RELEASE: 220000 2.2.1-RELEASE: 220000 (yes, no change) 2.2-STABLE after 2.2.1-RELEASE: 220000 (yes, still no change) 2.2-STABLE after texinfo-3.9: 221001 2.2-STABLE after top: 221002 2.2.2-RELEASE: 222000 2.2-STABLE after 2.2.2-RELEASE: 222001 2.2.5-RELEASE: 225000 2.2-STABLE after 2.2.5-RELEASE: 225001 2.2-STABLE after ldconfig -R merge: 225002 2.2.6-RELEASE: 226000 2.2.7-RELEASE: 227000 2.2-STABLE after 2.2.7-RELEASE: 227001 2.2-STABLE after semctl(2) change: 227002 2.2.8-RELEASE: 228000 2.2-STABLE after 2.2.8-RELEASE: 228001 3.0-current before mount(2) change: 300000 3.0-current after mount(2) change: 300001 3.0-current after semctl(2) change: 300002 3.0-current after ioctl arg changes: 300003 3.0-current after ELF conversion: 300004 3.0-RELEASE: 300005 3.0-current after 3.0-RELEASE: 300006 (Note that 2.2-STABLE sometimes identifies itself as "2.2.[5678]-STABLE" after the 2.2.5-RELEASE.) The pattern used to be year followed by the month, but we decided to change it to a more straightforward major/minor system starting from 2.2. This is because the parallel development on several branches made it infeasible to classify the releases simply by their real release dates. (Note that if you are making a port now, you FreeBSD Handbook 66 don't have to worry about old -current's; they are listed here just for your reference.) In the hundreds of ports that have been done, there have only been one or two cases where __FreeBSD__ should have been used. Just because an earlier port screwed up and used it in the wrong place does not mean you should do so too. _4_._7_._8_._4 _W_r_i_t_i_n_g _s_o_m_e_t_h_i_n_g _a_f_t_e_r _b_s_d_._p_o_r_t_._m_k Do not write anything after the `.include ' line. It usually can be avoided by including bsd.port.pre.mk somewhere in the middle of your Make file and bsd.port.post.mk at the end. (Note that you need to include either the pre.mk/post.mk pair or bsd.port.mk only; don't mix those two.) The former only defines a few variables, which can be used in tests in Makefiles; the lat ter defines the rest. Here are some important variables defined in bsd.port.pre.mk. (This is not the entire list; please read bsd.port.mk for the complete list.) ${ARCH} The archetecture, as returned by `uname -m' (e.g., `i386'). ${OPSYS} The operating system type, as returned by `uname -s' (e.g., `FreeBSD'). ${OSREL} The release version of the operating system (e.g., `2.1.5', `2.2.7'). ${OSVERSION} The numeric version of the operating system, same as _____F_r_e_e_B_S_D___v_e_r_ _s_i_o_n (section 4.7.8.3, page 63) above. ${PORTOBJFORMAT} The object format of the system (`aout' or `elf'). ${LOCALBASE} The base of the `local' tree (e.g., `/usr/local/'). ${X11BASE} The base of the `X11' tree (e.g., `/usr/X11R6/'). ${PREFIX} Where the port installs itself (see _m_o_r_e _o_n _P_R_E_F_I_X (section 4.7.8.9, page 68)). Note: if you have to define the variables USE_IMAKE, USE_X_PREFIX or MASTERDIR, do so before including bsd.port.pre.mk; everything else can be either before or after bsd.port.pre.mk. Here are some examples of things you can write after bsd.port.pre.mk: FreeBSD Handbook 67 # no need to compile lang/perl5 if perl5 is already in system .if ${OSVERSION} > 300003 BROKEN= perl is in system .endif # only one shlib version number for ELF .if ${PORTOBJFORMAT} == "elf" TCL_LIB_FILE= ${TCL_LIB}.${SHLIB_MAJOR} .else TCL_LIB_FILE= ${TCL_LIB}.${SHLIB_MAJOR}.${SHLIB_MINOR} .endif # software already makes link for ELF, but not for a.out post-install: .if ${PORTOBJFORMAT} == "aout" ${LN} -sf liblinpack.so.1.0 ${PREFIX}/lib/liblinpack.so .endif _4_._7_._8_._5 _I_n_s_t_a_l_l _a_d_d_i_t_i_o_n_a_l _d_o_c_u_m_e_n_t_a_t_i_o_n If your software has some documentation other than the standard man and info pages that you think is useful for the user, install it under ${PRE FIX}/share/doc. This can be done, like the previous item, in the post-install target. Create a new directory for your port. The directory name should reflect what the port is. This usually means ${PKGNAME} minus the version part. However, if you think the user might want different versions of the port to be installed at the same time, you can use the whole ${PKGNAME}. Make the installation dependent to the variable NOPORTDOCS so that users can disable it in /etc/make.conf, like this: post-install: .if !defined(NOPORTDOCS) ${MKDIR} ${PREFIX}/share/doc/xv ${INSTALL_MAN} ${WRKSRC}/docs/xvdocs.ps ${PREFIX}/share/doc/xv .endif Do not forget to add them to pkg/PLIST too! (Do not worry about NOPORTDOCS here; there is currently no way for the packages to read variables from /etc/make.conf.) Also, you can use the pkg/MESSAGE file to display messages upon installation. See the _u_s_i_n_g _p_k_g_/_M_E_S_S_A_G_E (section 4.7.5.1, page 60) section for details. _4_._7_._8_._6 _D_I_S_T___S_U_B_D_I_R Do not let your port clutter /usr/ports/distfiles. If your port requires a lot of files to be fetched, or contains a file that has a name that might conflict with other ports (e.g., `Makefile'), set ${DIST_SUBDIR} to the name of the port (${PKGNAME} without the version part should work fine). This will change ${DISTDIR} from the default /usr/ports/distfiles to /usr/ports/dist files/${DIST_SUBDIR}, and in effect puts everything that is required for your FreeBSD Handbook 68 port into that subdirectory. It will also look at the subdirectory with the same name on the backup master site at ftp.freebsd.org. (Setting ${DISTDIR} explicitly in your Makefile will not accomplish this, so please use ${DIST_SUBDIR}.) Note this does not affect the ${MASTER_SITES} you define in your Makefile. _4_._7_._8_._7 _R_C_S _s_t_r_i_n_g_s Do not put RCS strings in patches. CVS will mangle them when we put the files into the ports tree, and when we check them out again, they will come out dif ferent and the patch will fail. RCS strings are surrounded by dollar (`$') signs, and typically start with `$Id' or `$RCS'. _4_._7_._8_._8 _R_e_c_u_r_s_i_v_e _d_i_f_f Using the recurse (`-r') option to diff to generate patches is fine, but please take a look at the resulting patches to make sure you don't have any unneces sary junk in there. In particular, diffs between two backup files, Makefiles when the port uses Imake or GNU configure, etc., are unnecessary and should be deleted. If you had to edit configure.in and run autoconf to regenerate con figure, do not take the diffs of configure (it often grows to a few thousand lines!); define USE_AUTOCONF=yes and take the diffs of configure.in. Also, if you had to delete a file, then you can do it in the post-extract tar get rather than as part of the patch. Once you are happy with the resulting diff, please split it up into one source file per patch file. _4_._7_._8_._9 _P_R_E_F_I_X Do try to make your port install relative to ${PREFIX}. (The value of this variable will be set to ${LOCALBASE} (default /usr/local), unless ${USE_X_PRE FIX} or ${USE_IMAKE} is set, in which case it will be ${X11BASE} (default /usr/X11R6).) Not hard-coding `/usr/local' or `/usr/X11R6' anywhere in the source will make the port much more flexible and able to cater to the needs of other sites. For X ports that use imake, this is automatic; otherwise, this can often be done by simply replacing the occurrences of `/usr/local' (or `/usr/X11R6' for X ports that do not use imake) in the various scripts/Makefiles in the port to read `${PREFIX}', as this variable is automatically passed down to every stage of the build and install processes. Do not set USE_X_PREFIX unless your port truly requires it (i.e. it links against X libs or it needs to reference files in ${X11BASE}). The variable ${PREFIX} can be reassigned in your Makefile or in the user's environment. However, it is strongly discouraged for individual ports to set this variable explicitly in the Makefiles. Also, refer to programs/files from other ports with the variables mentioned above, not explicit pathnames. For instance, if your port requires a macro PAGER to be the full pathname of less, use the compiler flag: FreeBSD Handbook 69 -DPAGER=\"${PREFIX}/bin/less\" or -DPAGER=\"${LOCALBASE}/bin/less\" if this is an X port, instead of -DPAGER=\"/usr/local/bin/less\". This way it will have a better chance of working if the system administrator has moved the whole `/usr/local' tree somewhere else. _4_._7_._8_._1_0 _S_u_b_d_i_r_e_c_t_o_r_i_e_s Try to let the port put things in the right subdirectories of ${PREFIX}. Some ports lump everything and put it in the subdirectory with the port's name, which is incorrect. Also, many ports put everything except binaries, header files and manual pages in the a subdirectory of `lib', which does not bode well with the BSD paradigm. Many of the files should be moved to one of the follow ing: `etc' (setup/configuration files), `libexec' (executables started inter nally), `sbin' (executables for superusers/managers), `info' (documentation for info browser) or `share' (architecture independent files). See man hier(7) for details, the rule governing /usr pretty much applies to /usr/local too. The exception are ports dealing with USENET `news'. They may use ${PREFIX}/news as a destination for their files. _4_._7_._8_._1_1 _C_l_e_a_n_i_n_g _u_p _e_m_p_t_y _d_i_r_e_c_t_o_r_i_e_s Do make your ports clean up after themselves when they are deinstalled. This is usually accomplished by adding @dirrm lines for all directories that are specifically created by the port. Note you need to delete subdirectories before you can delete parent directories, as in: : lib/X11/oneko/pixmaps/cat.xpm lib/X11/oneko/sounds/cat.au : @dirrm lib/X11/oneko/pixmaps @dirrm lib/X11/oneko/sounds @dirrm lib/X11/oneko However, sometimes @dirrm will give you errors because other ports also share the same subdirectory. You can call rmdir from @unexec to remove only empty directories without warning: : @unexec rmdir %D/share/doc/gimp 2>/dev/null || true This will neither print any error messages nor cause pkg_delete to exit abnor mally even if ${PREFIX}/share/doc/gimp is not empty due to other ports installing some files in there. FreeBSD Handbook 70 _4_._7_._8_._1_2 _U_I_D_s If your port requires a certain user to be on the installed system, let the pkg/INSTALL script call pw to create it automatically. Look at net/cvsup-mir ror for an example. If your port must use the same user/group ID number when it is installed as a binary package as when it was compiled, then you must choose a free UID from 50 to 99 and register it below. Look at japanese/Wnn for an example. Make sure you don't use a UID already used by the system or other ports. This is the current list of UIDs between 50 and 99. majordom:*:54:54:Majordomo Pseudo User:/usr/local/majordomo:/nonexistent cyrus:*:60:60:the cyrus mail server:/nonexistent:/nonexistent gnats:*:61:1:GNATS database owner:/usr/local/share/gnats/gnats-db:/bin/sh uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico xten:*:67:67:X-10 daemon:/usr/local/xten:/nonexistent pop:*:68:6:Post Office Owner (popper):/nonexistent:/nonexistent wnn:*:69:7:Wnn:/nonexistent:/nonexistent ifmail:*:70:66:Ifmail user:/nonexistent:/nonexistent pgsql:*:70:70:PostgreSQL pseudo-user:/usr/local/pgsql:/bin/sh ircd:*:72:72:IRCd hybrid:/nonexistent:/nonexistent alias:*:81:81:QMail user:/var/qmail/alias:/nonexistent qmaill:*:83:81:QMail user:/var/qmail:/nonexistent qmaild:*:82:81:QMail user:/var/qmail:/nonexistent qmailq:*:85:82:QMail user:/var/qmail:/nonexistent qmails:*:87:82:QMail user:/var/qmail:/nonexistent qmailp:*:84:81:QMail user:/var/qmail:/nonexistent qmailr:*:86:82:QMail user:/var/qmail:/nonexistent msql:*:87:87:mSQL-2 pseudo-user:/var/db/msqldb:/bin/sh Please include a notice when you submit a port (or an upgrade) that reserves a new UID or GID in this range. This allows us to keep the list of reserved IDs up to date. _4_._7_._8_._1_3 _D_o _t_h_i_n_g_s _r_a_t_i_o_n_a_l_l_y The Makefile should do things simply and reasonably. If you can make it a cou ple of lines shorter or more readable, then do so. Examples include using a make `.if' construct instead of a shell `if' construct, not redefining do- extract if you can redefine ${EXTRACT*} instead, and using $GNU_CONFIGURE instead of `CONFIGURE_ARGS += --prefix=${PREFIX}'. _4_._7_._8_._1_4 _R_e_s_p_e_c_t _C_F_L_A_G_S The port should respect the ${CFLAGS} variable. If it doesn't, please add `NO_PACKAGE=ignores cflags' to the Makefile. _4_._7_._8_._1_5 _C_o_n_f_i_g_u_r_a_t_i_o_n _f_i_l_e_s If your port requires some configuration files in ${PREFIX}/etc, do _n_o_t just install them and list them in pkg/PLIST. That will cause pkg_delete to delete files carefully edited by the user and a new installation to wipe them out. FreeBSD Handbook 71 Instead, install sample files with a suffix (`.sample' will work well) and print out a _m_e_s_s_a_g_e (section 4.7.5.1, page 60) pointing out that the user has to copy and edit the file before the software can be made to work. _4_._7_._8_._1_6 _P_o_r_t_l_i_n_t Do check your port with _p_o_r_t_l_i_n_t (section 4.7.1.5, page 40) before you submit or commit it. _4_._7_._8_._1_7 _F_e_e_d_b_a_c_k Do send applicable changes/patches to the original author/maintainer for inclu sion in next release of the code. This will only make your job that much eas ier for the next release. _4_._7_._8_._1_8 _M_i_s_c_e_l_l_a_n_e_a The files pkg/DESCR, pkg/COMMENT, and pkg/PLIST should each be double-checked. If you are reviewing a port and feel they can be worded better, do so. Don't copy more copies of the GNU General Public License into our system, please. Please be careful to note any legal issues! Don't let us illegally distribute software! _4_._7_._8_._1_9 _I_f _y_o_u _a_r_e _s_t_u_c_k_._._._. Do look at existing examples and the bsd.port.mk file before asking us ques tions! ;) Do ask us questions if you have any trouble! Do not just beat your head against a wall! :) _4_._7_._9 _A _S_a_m_p_l_e _M_a_k_e_f_i_l_e Here is a sample Makefile that you can use to create a new port. Make sure you remove all the extra comments (ones between brackets)! It is recommended that you follow this format (ordering of variables, empty lines between sections, etc.). This format is designed so that the most impor tant information is easy to locate. We recommend that you use _p_o_r_t_l_i_n_t (sec tion 4.7.1.5, page 40) to check the Makefile. FreeBSD Handbook 72 [the header...just to make it easier for us to identify the ports.] # New ports collection makefile for: xdvi [the version required header should updated when upgrading a port.] # Version required: pl18 [things like "1.5alpha" are fine here too] [this is the date when the first version of this Makefile was created. Never change this when doing an update of the port.] # Date created: 26 May 1995 [this is the person who did the original port to FreeBSD, in particular, the person who wrote the first version of this Makefile. Remember, this should not be changed when upgrading the port later.] # Whom: Satoshi Asami # # $Id$ [ ^^^^ This will be automatically replaced with RCS ID string by CVS when it is committed to our repository.] # [section to describe the port itself and the master site - DISTNAME is always first, followed by PKGNAME (if necessary), CATEGORIES, and then MASTER_SITES, which can be followed by MASTER_SITE_SUBDIR. After those, one of EXTRACT_SUFX or DISTFILES can be specified too.] DISTNAME= xdvi PKGNAME= xdvi-pl18 CATEGORIES= print [do not forget the trailing slash ("/")! if you aren't using MASTER_SITE_* macros] MASTER_SITES= ${MASTER_SITE_XCONTRIB} MASTER_SITE_SUBDIR= applications [set this if the source is not in the standard ".tar.gz" form] EXTRACT_SUFX= .tar.Z [section for distributed patches -- can be empty] PATCH_SITES= ftp://ftp.sra.co.jp/pub/X11/japanese/ PATCHFILES= xdvi-18.patch1.gz xdvi-18.patch2.gz [maintainer; *mandatory*! This is the person (preferably with commit privileges) who a user can contact for questions and bug reports - this person should be the porter or someone who can forward questions to the original porter reasonably promptly. If you really do not want to have your address here, set it to "ports@FreeBSD.ORG".] MAINTAINER= asami@FreeBSD.ORG [dependencies -- can be empty] RUN_DEPENDS= gs:${PORTSDIR}/print/ghostscript LIB_DEPENDS= Xpm.5:${PORTSDIR}/graphics/xpm [this section is for other standard bsd.port.mk variables that do not belong to any of the above] [If it asks questions during configure, build, install...] IS_INTERACTIVE= yes [If it extracts to a directory other than ${DISTNAME}...] WRKSRC= ${WRKDIR}/xdvi-new [If the distributed patches were not made relative to ${WRKSRC}, you may need to tweak this] FreeBSD Handbook 73 PATCH_DIST_STRIP= -p1 [If it requires a "configure" script generated by GNU autoconf to be run] GNU_CONFIGURE= yes [If it requires GNU make, not /usr/bin/make, to build...] USE_GMAKE= yes [If it is an X application and requires "xmkmf -a" to be run...] USE_IMAKE= yes [et cetera.] [non-standard variables to be used in the rules below] MY_FAVORITE_RESPONSE= "yeah, right" [then the special rules, in the order they are called] pre-fetch: i go fetch something, yeah post-patch: i need to do something after patch, great pre-install: and then some more stuff before installing, wow [and then the epilogue] .include _4_._7_._1_0 _P_a_c_k_a_g_e _N_a_m_e_s The following are the conventions you should follow in naming your packages. This is to have our package directory easy to scan, as there are already lots and lots of packages and users are going to turn away if they hurt their eyes! The package name should look like [-][[-]]-; If your ${DISTNAME} doesn't look like that, set ${PKGNAME} to something in that format. 1. FreeBSD strives to support the native language of its users. The `' part should be a two letter abbreviation of the natural language defined by ISO-639 if the port is specific to a certain language. Exam ples are `ja' for Japanese, `ru' for Russian, `vi' for Vietnamese, `zh' for Chinese, `ko' for Korean and `de' for German. 2. The `' part should be all lowercases, except for a really large package (with lots of programs in it). Things like XFree86 (yes there really is a port of it, check it out) and ImageMagick fall into this cat egory. Otherwise, convert the name (or at least the first letter) to lowercase. If the capital letters are important to the name (for exam ple, with one-letter names like R or V) you may use capital letters at your discretion. There is a tradition of naming Perl 5 modules by prepending `p5-' and converting the double-colon separator to a hyphen; for example, the `Data::Dumper' module becomes `p5-Data-Dumper'. If the software in question has numbers, hyphens, or underscores in its name, FreeBSD Handbook 74 you may include them as well (like `kinput2'). 3. If the port can be built with different _h_a_r_d_c_o_d_e_d _d_e_f_a_u_l_t_s (section 4.7.4.3, page 52) (usually part of the directory name in a family of ports), the `' part should state the compiled-in defaults (the hyphen is optional). Examples are papersize and font units. 4. The version string should be a period-separated list of integers and sin gle lowercase alphabetics. The only exception is the string `pl' (mean ing `patchlevel'), which can be used _o_n_l_y when there are no major and minor version numbers in the software. Here are some (real) examples on how to convert a ${DISTNAME} into a suitable ${PKGNAME}: DISTNAME PKGNAME Reason mule-2.2.2 mule-2.2.2 no prob at all XFree86-3.1.2 XFree86-3.1.2 ditto EmiClock-1.0.2 emiclock-1.0.2 no uppercase names for single programs gmod1.4 gmod-1.4 need hyphen after `' xmris.4.02 xmris-4.02 ditto rdist-1.3alpha rdist-1.3a no strings like `alpha' allowed es-0.9-beta1 es-0.9b1 ditto v3.3beta021.src tiff-3.3 what the heck was that anyway? ;) tvtwm tvtwm-pl11 version string always required piewm piewm-1.0 ditto xvgr-2.10pl1 xvgr-2.10.1 `pl' allowed only when no maj/minor numbers gawk-2.15.6 ja-gawk-2.15.6 Japanese language version psutils-1.13 psutils-letter-1.13 papersize hardcoded at package build time pkfonts pkfonts300-1.0 package for 300dpi fonts If there is absolutely no trace of version information in the original source and it is unlikely that the original author will ever release another version, just set the version string to `1.0' (like the piewm example above). Other wise, ask the original author or use the date string (`yy.mm.dd') as the ver sion. _4_._7_._1_1 _C_a_t_e_g_o_r_i_e_s As you already know, ports are classified in several categories. But for this to work, it is important that porters and users understand what each category is and how we decide what to put in each category. _4_._7_._1_1_._1 _C_u_r_r_e_n_t _l_i_s_t _o_f _c_a_t_e_g_o_r_i_e_s First, this is the current list of port categories. Those marked with an asterisk (*) are _v_i_r_t_u_a_l categories -- those that do not have a corresponding subdirectory in the ports tree. Note that for non-virtual categories, you will find a one-line description in the pkg/COMMENT file in that subdirectory (e.g., archivers/pkg/COMMENT). archivers Archiving tools. FreeBSD Handbook 75 astro Astronomical ports. audio Sound support. benchmarks Benchmarking utilities. biology Biology-related software. cad Computer aided design tools. chinese Chinese language support. comms Communication software. Mostly software to talk to your serial port. converters Character code converters. databases Databases. deskutils Things that used to be on the desktop before computers were invented. devel Development utilities. Do not put libraries here just because they are libraries -- unless they truly don't belong to anywhere else, they shouldn't be in this category. editors General editors. Specialized editors go in the section for those tools (e.g., a mathematical-formula editor will go in math). elisp Emacs-lisp ports. emulators Emulators for other operating systems. Terminal emulators do _n_o_t belong here -- X-based ones should go to x11 and text-based ones to either comms or misc, depending on the exact functionality. games Games. german German language support. FreeBSD Handbook 76 graphics Graphics utilities. japanese Japanese language support. kde* Ports that form the K Desktop Environment (kde). korean Korean language support. lang Programming languages. mail Mail software. math Numerical computation software and other utilities for mathematics. mbone MBone applications. misc Miscellaneous utilities -- basically things that doesn't belong to anywhere else. This is the only category that should not appear with any other non-virtual category. If you have misc with some thing else in your CATEGORIES line, that means you can safely delete misc and just put the port in that other subdirectory! :) net Miscellaneous networking software. news USENET news software. offix* Ports from the OffiX suite. perl5* Ports that require perl version 5 to run. pilot* Software to use with the 3Com PalmPilot. plan9 Various programs from Plan9. print Printing software. Desktop publishing tools (previewers, etc.) belong here too. FreeBSD Handbook 77 python* Software written in python. russian Russian language support. security Security utilities. shells Command line shells. sysutils System utilities. tcl75* Ports that use tcl version 7.5 to run. tcl76* Ports that use tcl version 7.6 to run. tcl80* Ports that use tcl version 8.0 to run. tcl81* Ports that use tcl version 8.1 to run. textproc Text processing utilities. It does not include desktop publishing tools, which go to print. tk41* Ports that use tk version 4.1 to run. tk42* Ports that use tk version 4.2 to run. tk80* Ports that use tk version 8.0 to run. tk81* Ports that use tk version 8.1 to run. vietnamese Vietnamese language support. www Software related to the World Wide Web. HTML language support belong here too. x11 The X window system and friends. This category is only for soft ware that directly support the window system. Do not put regular X applications here. If your port is an X application, define FreeBSD Handbook 78 USE_XLIB (implied by USE_IMAKE) and put it in appropriate cate gories. Also, many of them go into other x11-* categories (see below). x11-clocks X11 clocks. x11-fm X11 file managers. x11-fonts X11 fonts and font utilities. x11-toolkits X11 toolkits. x11-wm X11 window managers. _4_._7_._1_1_._2 _C_h_o_o_s_i_n_g _t_h_e _r_i_g_h_t _c_a_t_e_g_o_r_y As many of the categories overlap, you often have to choose which of the cate gories should be the `primary' category of your port. There are several rules that govern this issue. Here is the list of priorities, in decreasing order of precedence. 1. Language specific categories always come first. For example, if your port installs Japanese X11 fonts, then your CATEGORIES line should read `japanese x11-fonts'. 2. Specific categories win over less-specific ones. For instance, an HTML editor should be listed as `www editors', not the other way around. Also, you don't need to list net when the port belongs to either of mail, mbone, news, security or www. 3. x11 is used as a secondary category only when the primary category is a natural language. In particular, you should _n_o_t put x11 in the category line for X applications. 4. If your port truly doesn't belong to anywhere else, put it in misc. If you are not sure about the category, please put a comment to that effect in your send-pr submission so we can discuss it before importing it. (If you are a committer, send a note to FreeBSD ports mailing list so we can discuss it first -- too often new ports are imported to a wrong category only to be moved right away.) _4_._7_._1_2 _C_h_a_n_g_e_s _t_o _t_h_i_s _d_o_c_u_m_e_n_t _a_n_d _t_h_e _p_o_r_t_s _s_y_s_t_e_m If you maintain a lot of ports, you should consider following the FreeBSD ports mailing list . Important changes to the way ports work will be announced there. You can always find more detailed information on the latest changes by looking at the bsd.port.mk CVS log. FreeBSD Handbook 79 _4_._7_._1_3 _T_h_a_t _i_s _I_t_, _F_o_l_k_s_! Boy, this sure was a long tutorial, wasn't it? Thanks for following us to here, really. Well, now that you know how to do a port, let us go at it and convert every thing in the world into ports! That is the easiest way to start contributing to the FreeBSD Project! :) Part II System Administration _5_. _C_o_n_f_i_g_u_r_i_n_g _t_h_e _F_r_e_e_B_S_D _K_e_r_n_e_l _C_o_n_t_r_i_b_u_t_e_d _b_y _J_a_k_e _H_a_m_b_y . 6 October 1995. This large section of the handbook discusses the basics of building your own custom kernel for FreeBSD. This section is appropriate for both novice system administrators and those with advanced Unix experience. _5_._1 _W_h_y _B_u_i_l_d _a _C_u_s_t_o_m _K_e_r_n_e_l_? Building a custom kernel is one of the most important rites of passage every Unix system administrator must endure. This process, while time-consuming, will provide many benefits to your FreeBSD system. Unlike the GENERIC kernel, which must support every possible SCSI and network card, along with tons of FreeBSD Handbook 80 other rarely used hardware support, a custom kernel only contains support for _y_o_u_r PC's hardware. This has a number of benefits: It will take less time to boot because it does not have to spend time probing for hardware which you do not have. A custom kernel often uses less memory, which is important because the kernel is the one process which must always be present in memory, and so all of that unused code ties up pages of RAM that your programs would oth erwise be able to use. Therefore, on a system with limited RAM, building a custom kernel is of critical importance. Finally, there are several kernel options which you can tune to fit your needs, and device driver support for things like sound cards which you can include in your kernel but are _n_o_t present in the GENERIC kernel. _5_._2 _B_u_i_l_d_i_n_g _a_n_d _I_n_s_t_a_l_l_i_n_g _a _C_u_s_t_o_m _K_e_r_n_e_l First, let us take a quick tour of the kernel build directory. All directories mentioned will be relative to the main /usr/src/sys directory, which is also accessible through /sys. There are a number of subdirectories here represent ing different parts of the kernel, but the most important, for our purposes, are i386/conf, where you will edit your custom kernel configuration, and com pile, which is the staging area where your kernel will be built. Notice the logical organization of the directory tree, with each supported device, filesystem, and option in its own subdirectory. Also, anything inside the i386 directory deals with PC hardware only, while everything outside the i386 direc tory is common to all platforms which FreeBSD could potentially be ported to. _N_o_t_e_: If there is _n_o_t a /usr/src/sys directory on your system, then the kernel source has not been been installed. Follow the instruc tions for installing packages to add this package to your system. Next, move to the i386/conf directory and copy the GENERIC configuration file to the name you want to give your kernel. For example: # cd /usr/src/sys/i386/conf # cp GENERIC MYKERNEL Traditionally, this name is in all capital letters and, if you are maintaining multiple FreeBSD machines with different hardware, it is a good idea to name it after your machine's hostname. We will call it MYKERNEL for the purpose of this example. _N_o_t_e_: You must execute these and all of the following commands under the root account or you will get ``permission denied'' errors. Now, edit MYKERNEL with your favorite text editor. If you are just starting out, the only editor available will probably be vi, which is too complex to explain here, but is covered well in many books in the _b_i_b_l_i_o_g_r_a_p_h_y (section 26., page 461). Feel free to change the comment lines at the top to reflect your configuration or the changes you have made to differentiate it from GENERIC. FreeBSD Handbook 81 If you have build a kernel under SunOS or some other BSD operating system, much of this file will be very familiar to you. If you are coming from some other operating system such as DOS, on the other hand, the GENERIC configuration file might seem overwhelming to you, so follow the descriptions in the _C_o_n_f_i_g_u_r_a_t_i_o_n _F_i_l_e (section 5.3, page 81) section slowly and carefully. _N_o_t_e_: If you are trying to upgrade your kernel from an older version of FreeBSD, you will probably have to get a new version of config(8) from the same place you got the new kernel sources. It is located in /usr/src/usr.sbin, so you will need to download those sources as well. Re-build and install it before running the next commands. When you are finished, type the following to compile and install your kernel: # /usr/sbin/config MYKERNEL # cd ../../compile/MYKERNEL # make depend # make # make install The new kernel will be copied to the root directory as /kernel and the old ker nel will be moved to /kernel.old. Now, shutdown the system and reboot to use your kernel. In case something goes wrong, there are some _t_r_o_u_b_l_e_s_h_o_o_t_i_n_g (section 5.5, page 97) instructions at the end of this document. Be sure to read the section which explains how to recover in case your new kernel _d_o_e_s _n_o_t _b_o_o_t (section 5.5, page 97). _N_o_t_e_: If you have added any new devices (such as sound cards) you may have to add some _d_e_v_i_c_e _n_o_d_e_s (section 5.4, page 96) to your /dev directory before you can use them. _5_._3 _T_h_e _C_o_n_f_i_g_u_r_a_t_i_o_n _F_i_l_e The general format of a configuration file is quite simple. Each line contains a keyword and one or more arguments. For simplicity, most lines only contain one argument. Anything following a # is considered a comment and ignored. The following sections describe each keyword, generally in the order they are listed in GENERIC, although some related keywords have been grouped together in a single section (such as Networking) even though they are actually scattered throughout the GENERIC file. An exhaustive list of options and more detailed explanations of the device lines is present in the LINT configuration file, located in the same directory as GENERIC. If you are in doubt as to the purpose or necessity of a line, check first in LINT. The kernel is currently being moved to a better organization of the option han dling. Traditionally, each option in the config file was simply converted into a -D switch for the CFLAGS line of the kernel Makefile. Naturally, this caused a creeping optionism, with nobody really knowing which option has been refer enced in what files. In the new scheme, every #ifdef that is intended to be dependent upon an option FreeBSD Handbook 82 gets this option out of an opt__f_o_o.h declaration file created in the compile directory by config. The list of valid options for config lives in two files: options that do not depend on the architecture are listed in /sys/conf/options, architecture-dependent ones in /sys/_a_r_c_h/conf/options._a_r_c_h, with _a_r_c_h being for example i386. _5_._3_._1 _M_a_n_d_a_t_o_r_y _K_e_y_w_o_r_d_s These keywords are required in every kernel you build. machine ``i386'' The first keyword is machine, which, since FreeBSD only runs on Intel 386 and compatible chips, is i386. _N_o_t_e_: that any keyword which contains numbers used as text must be enclosed in quotation marks, otherwise con fig gets confused and thinks you mean the actual number 386. cpu ``_c_p_u___t_y_p_e'' The next keyword is cpu, which includes support for each CPU sup ported by FreeBSD. The possible values of _c_p_u___t_y_p_e include: I386_CPU I486_CPU I586_CPU I686_CPU and multiple instances of the cpu line may be present with differ ent values of _c_p_u___t_y_p_e as are present in the GENERIC kernel. For a custom kernel, it is best to specify only the cpu you have. If, for example, you have an Intel Pentium, use I586_CPU for _c_p_u___t_y_p_e. ident _m_a_c_h_i_n_e___n_a_m_e Next, we have ident, which is the identification of the kernel. You should change this from GENERIC to whatever you named your ker nel, in this example, MYKERNEL. The value you put in ident will print when you boot up the kernel, so it is useful to give a kernel a different name if you want to keep it separate from your usual kernel (if you want to build an experimental kernel, for example). Note that, as with machine and cpu, enclose your kernel's name in quotation marks if it contains any numbers. Since this name is passed to the C compiler as a -D switch, do not use names like DEBUG, or something that could be confused with another machine or CPU name, like vax. FreeBSD Handbook 83 maxusers _n_u_m_b_e_r This file sets the size of a number of important system tables. This number is supposed to be roughly equal to the number of simul taneous users you expect to have on your machine. However, under normal circumstances, you will want to set maxusers to at least four, especially if you are using the X Window System or compiling software. The reason is that the most important table set by maxusers is the maximum number of processes, which is set to 20 + 16 * maxusers, so if you set maxusers to one, then you can only have 36 simultaneous processes, including the 18 or so that the system starts up at boot time, and the 15 or so you will probably create when you start the X Window System. Even a simple task like reading a man page will start up nine processes to filter, decom press, and view it. Setting maxusers to 4 will allow you to have up to 84 simultaneous processes, which should be enough for anyone. If, however, you see the dreaded ``proc table full'' error when trying to start another program, or are running a server with a large number of simultaneous users (like Walnut Creek CDROM's FTP site), you can always increase this number and rebuild. _N_o_t_e_: maxuser does _n_o_t limit the number of users which can log into your machine. It simply sets various table sizes to reasonable values considering the maximum number of users you will likely have on your system and how many processes each of them will be running. One keyword which _d_o_e_s limit the number of simultaneous _r_e_m_o_t_e _l_o_g_i_n_s is _p_s_e_u_d_o_-_d_e_v_i_c_e _p_t_y _1_6 (section 5.3.10, page 95). config _k_e_r_n_e_l___n_a_m_e root on _r_o_o_t___d_e_v_i_c_e This line specifies the location and name of the kernel. Tradi tionally the kernel is called vmunix but in FreeBSD, it is aptly named kernel. You should always use kernel for _k_e_r_n_e_l___n_a_m_e because changing it will render numerous system utilities inoperative. The second part of the line specifies the disk and partition where the root filesystem and kernel can be found. Typically this will be wd0 for systems with non-SCSI drives, or sd0 for systems with SCSI drives. _5_._3_._2 _G_e_n_e_r_a_l _O_p_t_i_o_n_s These lines provide kernel support for various filesystems and other options. options MATH_EMULATE This line allows the kernel to simulate a math co-processor if your computer does not have one (386 or 486SX). If you have a Pentium, a 486DX, or a 386 or 486SX with a separate 387 or 487 chip, you can comment this line out. FreeBSD Handbook 84 _N_o_t_e_: The normal math co-processor emulation routines that come with FreeBSD are _n_o_t very accurate. If you do not have a math co-processor, and you need the best accu racy, I recommend that you change this option to GPL_MATH_EMULATE to use the superior GNU math support, which is not included by default for licensing reasons. options ``COMPAT_43'' Compatibility with 4.3BSD. Leave this in; some programs will act strangely if you comment this out. options BOUNCE_BUFFERS ISA devices and EISA devices operating in an ISA compatibility mode can only perform DMA (Direct Memory Access) to memory below 16 megabytes. This option enables such devices to work in systems with more than 16 megabytes of memory. options UCONSOLE Allow users to grab the console, useful for X Windows. For exam ple, you can create a console xterm by typing xterm -C, which will display any `write', `talk', and other messages you receive, as well as any console messages sent by the kernel. options SYSVSHM This option provides for System V shared memory. The most common use of this is the XSHM extension in X Windows, which many graph ics-intensive programs (such as the movie player XAnim, and Linux DOOM) will automatically take advantage of for extra speed. If you use the X Window System, you will definitely want to include this. options SYSVSEM Support for System V semaphores. Less commonly used but only adds a few hundred bytes to the kernel. options SYSVMSG Support for System V messages. Again, only adds a few hundred bytes to the kernel. _N_o_t_e_: The ipcs(1) command will tell will list any pro cesses using each of these System V facilities. _5_._3_._3 _F_i_l_e_s_y_s_t_e_m _O_p_t_i_o_n_s These options add support for various filesystems. You must include at least one of these to support the device you boot from; typically this will be FFS if you boot from a hard drive, or NFS if you are booting a diskless workstation from Ethernet. You can include other commonly-used filesystems in the kernel, but feel free to comment out support for filesystems you use less often FreeBSD Handbook 85 (perhaps the MS-DOS filesystem?), since they will be dynamically loaded from the Loadable Kernel Module directory /lkm the first time you mount a partition of that type. options FFS The basic hard drive filesystem; leave it in if you boot from the hard disk. options NFS Network Filesystem. Unless you plan to mount partitions from a Unix file server over Ethernet, you can comment this out. options MSDOSFS MS-DOS Filesystem. Unless you plan to mount a DOS formatted hard drive partition at boot time, you can safely comment this out. It will be automatically loaded the first time you mount a DOS parti tion, as described above. Also, the excellent mtools software (in the ports collection) allows you to access DOS floppies without having to mount and unmount them (and does not require MSDOSFS at all). options ``CD9660'' ISO 9660 filesystem for CD-ROMs. Comment it out if you do not have a CD-ROM drive or only mount data CD's occasionally (since it will be dynamically loaded the first time you mount a data CD). Audio CD's do not need this filesystem. options PROCFS Process filesystem. This is a pretend filesystem mounted on /proc which allows programs like ps(1) to give you more information on what processes are running. options MFS Memory-mapped file system. This is basically a RAM disk for fast storage of temporary files, useful if you have a lot of swap space that you want to take advantage of. A perfect place to mount an MFS partition is on the /tmp directory, since many programs store temporary data here. To mount an MFS RAM disk on /tmp, add the following line to /etc/fstab and then reboot or type mount /tmp: /dev/wd1s2b /tmp mfs rw 0 0 _N_o_t_e_: Replace the /dev/wd1s2b with the name of your swap partition, which will be listed in your /etc/fstab as follows: /dev/wd1s2b none swap sw 0 0 FreeBSD Handbook 86 _N_o_t_e_: Also, the MFS filesystem can _n_o_t be dynamically loaded, so you _m_u_s_t compile it into your kernel if you want to experiment with it. options "EXT2FS" Linux's native file system. With ext2fs support you are able to read and write to Linux partitions. This is useful if you dual- boot FreeBSD and Linux and want to share data between the two sys tems. options QUOTA Enable disk quotas. If you have a public access system, and do not want users to be able to overflow the /home partition, you can establish disk quotas for each user. Refer to the _D_i_s_k _Q_u_o_t_a_s (section 10., page 193) section for more information. _5_._3_._4 _B_a_s_i_c _C_o_n_t_r_o_l_l_e_r_s _a_n_d _D_e_v_i_c_e_s These sections describe the basic disk, tape, and CD-ROM controllers supported by FreeBSD. There are separate sections for _S_C_S_I (section 5.3.5, page 87) con trollers and _n_e_t_w_o_r_k (section 5.3.8, page 90) cards. controller isa0 All PC's supported by FreeBSD have one of these. If you have an IBM PS/2 (Micro Channel Architecture), then you cannot run FreeBSD at this time. controller pci0 Include this if you have a PCI motherboard. This enables auto- detection of PCI cards and gatewaying from the PCI to the ISA bus. controller fdc0 Floppy drive controller: fd0 is the ``A:'' floppy drive, and fd1 is the ``B:'' drive. ft0 is a QIC-80 tape drive attached to the floppy controller. Comment out any lines corresponding to devices you do not have. _N_o_t_e_: QIC-80 tape support requires a separate filter pro gram called ft(8), see the manual page for details. controller wdc0 This is the primary IDE controller. wd0 and wd1 are the master and slave hard drive, respectively. wdc1 is a secondary IDE controller where you might have a third or fourth hard drive, or an IDE CD- ROM. Comment out the lines which do not apply (if you have a SCSI hard drive, you will probably want to comment out all six lines, for example). FreeBSD Handbook 87 device wcd0 " This device provides IDE CD-ROM support. Be sure to leave wdc0 uncommented, and wdc1 if you have more than one IDE controller and your CD-ROM is on the second one card. To use this, you must also include the line options ATAPI. device npx0 at isa? port ``IO_NPX'' irq 13 vector npxintr npx0 is the interface to the floating point math unit in FreeBSD, either the hardware co-processor or the software math emulator. It is _N_O_T optional. device wt0 at isa? port 0x300 bio irq 5 drq 1 vector wtintr Wangtek and Archive QIC-02/QIC-36 tape drive support Proprietary CD-ROM support The following drivers are for the so-called _p_r_o_p_r_i_e_t_a_r_y CD-ROM drives. These drives have their own controller card or might plug into a sound card such as the SoundBlaster 16. They are _n_o_t IDE or SCSI. Most older single-speed and double-speed CD-ROMs use these interfaces, while newer quad-speeds are likely to be _I_D_E (section 5.3.4, page 87) or _S_C_S_I (section 5.3.5, page 87). device mcd0 at isa? port 0x300 bio irq 10 vector mcdintr Mitsumi CD-ROM (LU002, LU005, FX001D). device scd0 at isa? port 0x230 bio Sony CD-ROM (CDU31, CDU33A). controller matcd0 at isa? port ? bio Matsushita/Panasonic CD-ROM (sold by Creative Labs for SoundBlaster). _5_._3_._5 _S_C_S_I _D_e_v_i_c_e _S_u_p_p_o_r_t This section describes the various SCSI controllers and devices supported by FreeBSD. SCSI Controllers The next ten or so lines include support for different kinds of SCSI controllers. Comment out all except for the one(s) you have: controller bt0 at isa? port ``IO_BT0'' bio irq ? vector btintr Most Buslogic controllers FreeBSD Handbook 88 controller uha0 at isa? port ``IO_UHA0'' bio irq ? drq 5 vector uhaintr UltraStor 14F and 34F controller ahc0 Adaptec 274x/284x/294x controller ahb0 at isa? bio irq ? vector ahbintr Adaptec 174x controller aha0 at isa? port ``IO_AHA0'' bio irq ? drq 5 vector ahaintr Adaptec 154x controller aic0 at isa? port 0x340 bio irq 11 vector aicintr Adaptec 152x and sound cards using Adaptec AIC-6360 (slow!) controller nca0 at isa? port 0x1f88 bio irq 10 vector ncaintr ProAudioSpectrum cards using NCR 5380 or Trantor T130 controller sea0 at isa? bio irq 5 iomem 0xc8000 iosiz 0x2000 vector seaintr Seagate ST01/02 8 bit controller (slow!) controller wds0 at isa? port 0x350 bio irq 15 drq 6 vector wdsintr Western Digital WD7000 controller controller ncr0 NCR 53C810, 53C815, 53C825, 53C860, 53C875 PCI SCSI controller options ``SCSI_DELAY=15'' This causes the kernel to pause 15 seconds before probing each SCSI device in your system. If you only have IDE hard drives, you can ignore this, otherwise you will probably want to lower this number, perhaps to 5 seconds, to speed up booting. Of course if you do this, and FreeBSD has trouble recognizing your SCSI devices, you will have to raise it back up. controller scbus0 If you have any SCSI controllers, this line provides generic SCSI support. If you do not have SCSI, you can comment this, and the following three lines, out. FreeBSD Handbook 89 device sd0 Support for SCSI hard drives. device st0 Support for SCSI tape drives. device cd0 Support for SCSI CD-ROM drives. Note that the number 00 in the above entries is slightly misleading: all these devices are automatically configured as they are found, regardless of how many of them are hooked up to the SCSI bus(es), and which target IDs they have. If you want to ``wire down'' specific target IDs to particular devices, refer to the appropriate section of the LINT kernel config file. _5_._3_._6 _C_o_n_s_o_l_e_, _B_u_s _M_o_u_s_e_, _a_n_d _X _S_e_r_v_e_r _S_u_p_p_o_r_t You must choose one of these two console types, and, if you plan to use the X Window System with the vt220 console, enable the XSERVER option and optionally, a bus mouse or PS/2 mouse device. device sc0 at isa? port ``IO_KBD' tty irq 1 vector scintr sc0 is the default console driver, which resembles an SCO console. Since most full-screen programs access the console through a termi nal database library like _t_e_r_m_c_a_p, it should not matter much whether you use this or vt0, the VT220 compatible console driver. When you log in, set your TERM variable to ``scoansi'' if full- screen programs have trouble running under this console. device vt0 at isa? port ``IO_KBD'' tty irq 1 vector pcrint This is a VT220-compatible console driver, backwards compatible to VT100/102. It works well on some laptops which have hardware incompatibilities with sc0. Also, set your TERM variable to ``vt100'' or ``vt220'' when you log in. This driver might also prove useful when connecting to a large number of different machines over the network, where the _t_e_r_m_c_a_p or _t_e_r_m_i_n_f_o entries for the sc0 device are often not available -- ``vt100'' should be available on virtually any platform. options ``PCVT_FREEBSD=210'' Required with the vt0 console driver. options XSERVER Only applicable with the vt0 console driver. This FreeBSD Handbook 90 includes code required to run the XFree86 X Window Server under the vt0 console driver. device mse0 at isa? port 0x23c tty irq 5 vector ms Use this device if you have a Logitech or ATI InPort bus mouse card. _N_o_t_e_: If you have a serial mouse, ignore these two lines, and instead, make sure the appropriate _s_e_r_i_a_l (section 5.3.7, page 90) port is enabled (probably COM1). device psm0 at isa? port ``IO_KBD'' conflicts tty irq 12 vector psmintr Use this device if your mouse plugs into the PS/2 mouse port. _5_._3_._7 _S_e_r_i_a_l _a_n_d _P_a_r_a_l_l_e_l _P_o_r_t_s Nearly all systems have these. If you are attaching a printer to one of these ports, the _P_r_i_n_t_i_n_g (section 7., page 121) section of the handbook is very use ful. If you are using modem, _D_i_a_l_u_p _a_c_c_e_s_s (section 14.3, page 276) provides extensive detail on serial port configuration for use with such devices. device sio0 at isa? port ``IO_COM1'' tty irq 4 vector siointr " sio0 through sio3 are the four serial ports referred to as COM1 through COM4 in the MS-DOS world. Note that if you have an inter nal modem on COM4 and a serial port at COM2 you will have to change the IRQ of the modem to 2 (for obscure technical reasons IRQ 2 = IRQ 9) in order to access it from FreeBSD. If you have a multiport serial card, check the manual page for sio(4) for more information on the proper values for these lines. Some video cards (notably those based on S3 chips) use IO addresses of the form 0x*2e8, and since many cheap serial cards do not fully decode the 16-bit IO address space, they clash with these cards, making the COM4 port practically unavailable. Each serial port is required to have a unique IRQ (unless you are using one of the multiport cards where shared interrupts are sup ported), so the default IRQs for COM3 and COM4 cannot be used. device lpt0 at isa? port? tty irq 7 vector lptintr lpt0 through lpt2 are the three printer ports you could conceivably have. Most people just have one, though, so feel free to comment out the other two lines if you do not have them. _5_._3_._8 _N_e_t_w_o_r_k_i_n_g FreeBSD, as with Unix in general, places a _b_i_g emphasis on networking. There fore, even if you do not have an Ethernet card, pay attention to the mandatory options and the dial-up networking support. FreeBSD Handbook 91 options INET Networking support. Leave it in even if you do not plan to be con nected to a network. Most programs require at least loopback net working (i.e. making network connections within your PC) so this is essentially mandatory. Ethernet cards The next lines enable support for various Ethernet cards. If you do not have a network card, you can comment out all of these lines. Otherwise, you will want to leave in support for your particular Ethernet card(s): device de0 Ethernet adapters based on Digital Equipment DC21040, DC21041 or DC21140 chips device fxp0 Intel EtherExpress Pro/100B device vx0 3Com 3C590 and 3C595 (buggy) device cx0 at isa? port 0x240 net irq 15 drq 7 vector cxintr Cronyx/Sigma multiport sync/async (with Cisco or PPP framing) device ed0 at isa? port 0x280 net irq 5 iomem 0xd8000 vector edintr Western Digital and SMC 80xx and 8216; Novell NE1000 and NE2000; 3Com 3C503; HP PC Lan Plus (HP27247B and HP27252A) device el0 at isa? port 0x300 net irq 9 vector elintr 3Com 3C501 (slow!) device eg0 at isa? port 0x310 net irq 5 vector egintr 3Com 3C505 device ep0 at isa? port 0x300 net irq 10 vector epintr 3Com 3C509 (buggy) device fe0 at isa? port 0x240 net irq ? vector feintr Fujitsu MB86960A/MB86965A Ethernet device fea0 at isa? net irq ? vector feaintr FreeBSD Handbook 92 DEC DEFEA EISA FDDI adapter device ie0 at isa? port 0x360 net irq 7 iomem 0xd0000 vector ieintr AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210; Intel EtherExpress 16 device le0 at isa? port 0x300 net irq 5 iomem 0xd0000 vector le_intr Digital Equipment EtherWorks 2 and EtherWorks 3 (DEPCA, DE100, DE101, DE200, DE201, DE202, DE203, DE204, DE205, DE422) device lnc0 at isa? port 0x300 net irq 10 drq 0 vector lncintr Lance/PCnet cards (Isolan, Novell NE2100, NE32-VL) device ze0 at isa? port 0x300 net irq 5 iomem 0xd8000 vector zeintr IBM/National Semiconductor PCMCIA ethernet controller. device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000 vector zpintr 3Com PCMCIA Etherlink III _N_o_t_e_: With certain cards (notably the NE2000) you will have to change the port and/or IRQ since there is no ``standard'' location for these cards. pseudo-device loop loop is the generic loopback device for TCP/IP. If you telnet or FTP to _l_o_c_a_l_h_o_s_t (a.k.a. 127.0.0.1) it will come back at you through this pseudo-device. Mandatory. pseudo-device ether ether is only needed if you have an Ethernet card and includes generic Ethernet protocol code. pseudo-device sl _n_u_m_b_e_r sl is for SLIP (Serial Line Internet Protocol) support. This has been almost entirely supplanted by PPP, which is easier to set up, better suited for modem-to-modem connections, as well as more pow erful. The _n_u_m_b_e_r after sl specifies how many simultaneous SLIP sessions to support. This handbook has more information on setting up a SLIP _c_l_i_e_n_t (section 15.3, page 317) or _s_e_r_v_e_r (section 15.4, page 320). pseudo-device ppp _n_u_m_b_e_r ppp is for kernel-mode PPP (Point-to-Point Protocol) support for dial-up Internet connections. There is also version of PPP FreeBSD Handbook 93 implemented as a user application that uses the tun and offers more flexibility and features such as demand dialing. If you still want to use this PPP driver, read the _k_e_r_n_e_l_-_m_o_d_e _P_P_P (section 15.2, page 308) section of the handbook. As with the sl device, _n_u_m_b_e_r specifies how many simultaneous PPP connections to support. pseudo-device tun _n_u_m_b_e_r tun is used by the user-mode PPP software. This program is easy to set up and very fast. It also has special features such as auto matic dial-on-demand. The number after tun specifies the number of simultaneous PPP sessions to support. See the _u_s_e_r_-_m_o_d_e _P_P_P (sec tion 15.1, page 293) section of the handbook for more information. pseudo-device bpfilter _n_u_m_b_e_r Berkeley packet filter. This pseudo-device allows network inter faces to be placed in promiscuous mode, capturing every packet on a broadcast network (e.g. an ethernet). These packets can be cap tured to disk and/or examined with the tcpdump(1) program. Note that implementation of this capability can seriously compromise your overall network security. The _n_u_m_b_e_r after bpfilter is the number of interfaces that can be examined simultaneously. Optional, not recommended except for those who are fully aware of the poten tial pitfalls. Not all network cards support this capability. _5_._3_._9 _S_o_u_n_d _c_a_r_d_s This is the first section containing lines that are not in the GENERIC kernel. To include sound card support, you will have to copy the appropriate lines from the LINT kernel (which contains support for _e_v_e_r_y device) as follows: controller snd0 Generic sound driver code. Required for all of the following sound cards except pca. device pas0 at isa? port 0x388 irq 10 drq 6 vector pasintr ProAudioSpectrum digital audio and MIDI. device sb0 at isa? port 0x220 irq 7 conflicts drq 1 vector sbintr SoundBlaster digital audio. _N_o_t_e_: If your SoundBlaster is on a different IRQ (such as 5), change irq 7 to, for example, irq 5 and remove the conflicts keyword. Also, you must add the line: options ``SBC_IRQ=5'' device sbxvi0 at isa? drq 5 SoundBlaster 16 digital 16-bit audio. FreeBSD Handbook 94 _N_o_t_e_: If your SB16 is on a different 16-bit DMA channel (such as 6 or 7), change the drq 5 keyword appropriately, and then add the line: options "SB16_DMA=6" device sbmidi0 at isa? port 0x330 SoundBlaster 16 MIDI interface. If you have a SoundBlaster 16, you must include this line, or the kernel will not compile. device gus0 at isa? port 0x220 irq 10 drq 1 vector gusintr Gravis Ultrasound. device mss0 at isa? port 0x530 irq 10 drq 1 vector adintr Microsoft Sound System. device opl0 at isa? port 0x388 conflicts AdLib FM-synthesis audio. Include this line for AdLib, Sound Blaster, and ProAudioSpectrum users, if you want to play MIDI songs with a program such as playmidi (in the ports collection). device mpu0 at isa? port 0x330 irq 6 drq 0 Roland MPU-401 stand-alone card. device uart0 at isa? port 0x330 irq 5 vector ``m6850intr'' Stand-alone 6850 UART for MIDI. device pca0 at isa? port ``IO_TIMER1'' tty " Digital audio through PC speaker. This is going to be very poor sound quality and quite CPU-intensive, so you have been warned (but it does not require a sound card). _N_o_t_e_: There is some additional documentation in /usr/src/sys/i386/isa/sound/sound.doc. Also, if you add any of these devices, be sure to create the sound _d_e_v_i_c_e _n_o_d_e_s (section 5.4, page 96). _5_._3_._1_0 _P_s_e_u_d_o_-_d_e_v_i_c_e_s Pseudo-device drivers are parts of the kernel that act like device drivers but do not correspond to any actual hardware in the machine. The _n_e_t_w_o_r_k_-_r_e_l_a_t_e_d (section 5.3.8, page 90) pseudo-devices are in that section, while the remain der are here. pseudo-device gzip gzip allows you to run FreeBSD programs that have been compressed with gzip. The programs in /stand are compressed so it is a good idea to have this option in your kernel. FreeBSD Handbook 95 pseudo-device log log is used for logging of kernel error messages. Mandatory. pseudo-device pty _n_u_m_b_e_r " pty is a ``pseudo-terminal'' or simulated login port. It is used by incoming tteellnneett and rrllooggiinn sessions, xterm, and some other applications such as emacs. The _n_u_m_b_e_r indicates the number of ptys to create. If you need more than GENERIC default of 16 simul taneous xterm windows and/or remote logins, be sure to increase this number accordingly, up to a maximum of 64. pseudo-device snp _n_u_m_b_e_r Snoop device. This pseudo-device allows one terminal session to watch another using the watch(8) command. Note that implementation of this capability has important security and privacy implications. The _n_u_m_b_e_r after snp is the total number of simultaneous snoop ses sions. Optional. pseudo-device vn Vnode driver. Allows a file to be treated as a device after being set up with the vnconfig(8) command. This driver can be useful for manipulating floppy disk images and using a file as a swap device (e.g. an MS Windows swap file). Optional. pseudo-device ccd _n_u_m_b_e_r Concatenated disks. This pseudo-device allows you to concatenate multiple disk partitions into one large ``meta''-disk. The _n_u_m_b_e_r after ccd is the total number of concatenated disks (not total num ber of disks that can be concatenated) that can be created. (See ccd(4) and ccdconfig(8) man pages for more details.) Optional. _5_._3_._1_1 _J_o_y_s_t_i_c_k_, _P_C _S_p_e_a_k_e_r_, _M_i_s_c_e_l_l_a_n_e_o_u_s This section describes some miscellaneous hardware devices supported by FreeBSD. Note that none of these lines are included in the GENERIC kernel, you will have to copy them from this handbook or the LINT kernel (which contains support for _e_v_e_r_y device): device joy0 at isa? port ``IO_GAME'' PC joystick device. pseudo-device speaker Supports IBM BASIC-style noises through the PC speaker. Some fun programs which use this are /usr/sbin/spkrtest, which is a shell script that plays some simple songs, and /usr/games/piano which lets you play songs using the keyboard as a simple piano (this file FreeBSD Handbook 96 only exists if you have installed the _g_a_m_e_s package). Also, the excellent text role-playing game NetHack (in the ports collection) can be configured to use this device to play songs when you play musical instruments in the game. See also the _p_c_a_0 (section 5.3.9, page 94) device. _5_._4 _M_a_k_i_n_g _D_e_v_i_c_e _N_o_d_e_s Almost every device in the kernel has a corresponding ``node'' entry in the /dev directory. These nodes look like regular files, but are actually special entries into the kernel which programs use to access the device. The shell script /dev/MAKEDEV, which is executed when you first install the operating system, creates nearly all of the device nodes supported. However, it does not create _a_l_l of them, so when you add support for a new device, it pays to make sure that the appropriate entries are in this directory, and if not, add them. Here is a simple example: Suppose you add the IDE CD-ROM support to the kernel. The line to add is: controller wcd0 This means that you should look for some entries that start with wcd0 in the /dev directory, possibly followed by a letter, such as `c', or preceded by the letter 'r', which means a `raw' device. It turns out that those files are not there, so I must change to the /dev directory and type: # sh MAKEDEV wcd0 When this script finishes, you will find that there are now wcd0c and rwcd0c entries in /dev so you know that it executed correctly. For sound cards, the command: # sh MAKEDEV snd0 creates the appropriate entries. Note: when creating device nodes for devices such as sound cards, if other people have access to your machine, it may be desirable to protect the devices from outside access by adding them to the /etc/fbtab file. See man fbtab for more information. Follow this simple procedure for any other non-GENERIC devices which do not have entries. _N_o_t_e_: All SCSI controllers use the same set of /dev entries, so you do not need to create these. Also, network cards and SLIP/PPP pseudo-devices do not have entries in /dev at all, so you do not have to worry about these either. FreeBSD Handbook 97 _5_._5 _I_f _S_o_m_e_t_h_i_n_g _G_o_e_s _W_r_o_n_g There are four categories of trouble that can occur when building a custom ker nel. They are: Config command fails If the config command fails when you give it your kernel descrip tion, you have probably made a simple error somewhere. Fortu nately, config will print the line number that it had trouble with, so you can quickly skip to it with vi. For example, if you see: config: line 17: syntax error you can skip to the problem in vi by typing ``17G'' in command mode. Make sure the keyword is typed correctly, by comparing it to the GENERIC kernel or another reference. Make command fails If the make command fails, it usually signals an error in your ker nel description, but not severe enough for config to catch it. Again, look over your configuration, and if you still cannot resolve the problem, send mail to the FreeBSD general questions mailing list with your kernel con figuration, and it should be diagnosed very quickly. Kernel will not boot " If your new kernel does not boot, or fails to recognize your devices, do not panic! Fortunately, BSD has an excellent mechanism for recovering from incompatible kernels. Simply type the name of the kernel you want to boot from (i.e. ``kernel.old'') at the FreeBSD boot prompt instead of pressing return. When reconfiguring a kernel, it is always a good idea to keep a kernel that is known to work on hand. After booting with a good kernel you can check over your configura tion file and try to build it again. One helpful resource is the /var/log/messages file which records, among other things, all of the kernel messages from every successful boot. Also, the dmesg(8) command will print the kernel messages from the current boot. FreeBSD Handbook 98 _N_o_t_e_: If you are having trouble building a kernel, make sure to keep a GENERIC, or some other kernel that is known to work on hand as a different name that will not get erased on the next build. You cannot rely on ker nel.old because when installing a new kernel, kernel.old is overwritten with the last installed kernel which may be non-functional. Also, as soon as possible, move the working kernel to the proper ``kernel'' location or com mands such as ps(1) will not work properly. The proper command to ``unlock'' the kernel file that make installs (in order to move another kernel back permanently) is: # chflags noschg /kernel And, if you want to ``lock'' your new kernel into place, or any file for that matter, so that it cannot be moved or tampered with: # chflags schg /kernel Kernel works, but ps does not work any more! If you have installed a different version of the kernel from the one that the system utilities have been built with, for example, an experimental ``2.2.0'' kernel on a 2.1.0-RELEASE system, many sys tem-status commands like ps(1) and vmstat(8) will not work any more. You must recompile the libkvm library as well as these util ities. This is one reason it is not normally a good idea to use a different version of the kernel from the rest of the operating sys tem. _6_. _S_e_c_u_r_i_t_y _6_._1 _D_E_S_, _M_D_5_, _a_n_d _C_r_y_p_t _C_o_n_t_r_i_b_u_t_e_d _b_y _G_a_r_r_e_t_t _W_o_l_l_m_a_n 24 September 1995. In order to protect the security of passwords on UN*X systems from being easily exposed, passwords have traditionally been scrambled in some way. Starting with Bell Labs' Seventh Edition Unix, passwords were encrypted using what the security people call a ``one-way hash function''. That is to say, the password is transformed in such a way that the original password cannot be regained except by brute-force searching the space of possible passwords. Unfortu nately, the only secure method that was available to the AT&T researchers at the time was based on DES, the Data Encryption Standard. This causes only min imal difficulty for commercial vendors, but is a serious problem for an operat ing system like FreeBSD where all the source code is freely available, because national governments in many places like to place restrictions on cross-border transport of DES and other encryption software. FreeBSD Handbook 99 So, the FreeBSD team was faced with a dilemma: how could we provide compatibil ity with all those UNIX systems out there while still not running afoul of the law? We decided to take a dual-track approach: we would make distributions which contained only a non-regulated password scrambler, and then provide as a separate add-on library the DES-based password hash. The password-scrambling function was moved out of the C library to a separate library, called `libcrypt' because the name of the C function to implement it is `crypt'. In FreeBSD 1.x and some pre-release 2.0 snapshots, the non-regulated scrambler uses an insecure function written by Nate Williams; in subsequent releases this was replaced by a mechanism using the RSA Data Security, Inc., MD5 one-way hash function. Because neither of these functions involve encryption, they are believed to be exportable from the US and importable into many other countries. Meanwhile, work was also underway on the DES-based password hash function. First, a version of the `crypt' function which was written outside the US was imported, thus synchronizing the US and non-US code. Then, the library was modified and split into two; the DES `libcrypt' contains only the code involved in performing the one-way password hash, and a separate `libcipher' was created with the entry points to actually perform encryption. The code was partitioned in this way to make it easier to get an export license for the compiled library. _6_._1_._1 _R_e_c_o_g_n_i_z_i_n_g _y_o_u_r _`_c_r_y_p_t_' _m_e_c_h_a_n_i_s_m It is fairly easy to recognize whether a particular password string was created using the DES- or MD5-based hash function. MD5 password strings always begin with the characters `$1$'. DES password strings do not have any particular identifying characteristics, but they are shorter than MD5 passwords, and are coded in a 64-character alphabet which does not include the `$' character, so a relatively short string which doesn't begin with a dollar sign is very likely a DES password. Determining which library is being used on your system is fairly easy for most programs, except for those like `init' which are statically linked. (For those programs, the only way is to try them on a known password and see if it works.) Programs which use `crypt' are linked against `libcrypt', which for each type of library is a symbolic link to the appropriate implementation. For example, on a system using the DES versions: $ cd /usr/lib $ ls -l /usr/lib/libcrypt* lrwxr-xr-x 1 bin bin 13 Sep 5 12:50 libcrypt.a -> libdescrypt.a lrwxr-xr-x 1 bin bin 18 Sep 5 12:50 libcrypt.so.2.0 -> libdescrypt.so.2.0 lrwxr-xr-x 1 bin bin 15 Sep 5 12:50 libcrypt_p.a -> libdescrypt_p.a On a system using the MD5-based libraries, the same links will be present, but the target will be `libscrypt' rather than `libdescrypt'. _6_._2 _S_/_K_e_y _C_o_n_t_r_i_b_u_t_e_d _b_y _G_a_r_r_e_t_t _W_o_l_l_m_a_n 25 September 1995. S/Key is a one-time password scheme based on a one-way hash function (in our FreeBSD Handbook 100 version, this is MD4 for compatibility; other versions have used MD5 and DES- MAC). S/Key has been a standard part of all FreeBSD distributions since ver sion 1.1.5, and is also implemented on a large and growing number of other sys tems. S/Key is a registered trademark of Bell Communications Research, Inc. There are three different sorts of passwords which we will talk about in the discussion below. The first is your usual UNIX-style or Kerberos password; we will call this a ``UNIX password''. The second sort is the one-time password which is generated by the S/Key `key' program and accepted by the `keyinit' program and the login prompt; we will call this a ``one-time password''. The final sort of password is the secret password which you give to the `key' pro gram (and sometimes the `keyinit' program) which it uses to generate one-time passwords; we will call it a ``secret password'' or just unqualified ``pass word''. The secret password does not necessarily have anything to do with your UNIX password (while they can be the same, this is not recommended). While UNIX passwords are limited to eight characters in length, your S/Key secret password can be as long as you like; I use seven-word phrases. In general, the S/Key system operates completely independently of the UNIX password system. There are in addition two other sorts of data involved in the S/Key system; one is called the ``seed'' or (confusingly) ``key'', and consists of two letters and five digits, and the other is the ``iteration count'' and is a number between 100 and 1. S/Key constructs a one-time password from these components by concatenating the seed and the secret password, then applying a one-way hash (the RSA Data Security, Inc., MD4 secure hash function) iteration-count times, and turning the result into six short English words. The `login' and `su' pro grams keep track of the last one-time password used, and the user is authenti cated if the hash of the user-provided password is equal to the previous pass word. Because a one-way hash function is used, it is not possible to generate future one-time passwords having overheard one which was successfully used; the iteration count is decremented after each successful login to keep the user and login program in sync. (When you get the iteration count down to 1, it is time to reinitialize S/Key.) There are four programs involved in the S/Key system which we will discuss below. The `key' program accepts an iteration count, a seed, and a secret password, and generates a one-time password. The `keyinit' program is used to initialized S/Key, and to change passwords, iteration counts, or seeds; it takes either a secret password, or an iteration count, seed, and one-time pass word. The `keyinfo' program examines the /etc/skeykeys file and prints out the invoking user's current iteration count and seed. Finally, the `login' and `su' programs contain the necessary logic to accept S/Key one-time passwords for authentication. The `login' program is also capable of disallowing the use of UNIX passwords on connections coming from specified addresses. There are four different sorts of operations we will cover. The first is using the `keyinit' program over a secure connection to set up S/Key for the first time, or to change your password or seed. The second operation is using the `keyinit' program over an insecure connection, in conjunction with the `key' program over a secure connection, to do the same. The third is using the `key' program to log in over an insecure connection. The fourth is using the `key' program to generate a number of keys which can be written down or printed out FreeBSD Handbook 101 to carry with you when going to some location without secure connections to anywhere (like at a conference). _6_._2_._1 _S_e_c_u_r_e _c_o_n_n_e_c_t_i_o_n _i_n_i_t_i_a_l_i_z_a_t_i_o_n To initialize S/Key, change your password, or change your seed while logged in over a secure connection (e.g., on the console of a machine), use the `keyinit' command without any parameters while logged in as yourself: $ keyinit Updating wollman: ) these will not appear if you Old key: ha73895 ) have not used S/Key before Reminder - Only use this method if you are directly connected. If you are using telnet or rlogin exit with no password and use keyinit -s. Enter secret password: ) I typed my pass phrase here Again secret password: ) I typed it again ID wollman s/key is 99 ha73896 ) discussed below SAG HAS FONT GOUT FATE BOOM ) There is a lot of information here. At the `Enter secret password:' prompt, you should enter some password or phrase (I use phrases of minimum seven words) which will be needed to generate login keys. The line starting `ID' gives the parameters of your particular S/Key instance: your login name, the iteration count, and seed. When logging in with S/Key, the system will remember these parameters and present them back to you so you do not have to remember them. The last line gives the particular one-time password which corresponds to those parameters and your secret password; if you were to re-login immediately, this one-time password is the one you would use. _6_._2_._2 _I_n_s_e_c_u_r_e _c_o_n_n_e_c_t_i_o_n _i_n_i_t_i_a_l_i_z_a_t_i_o_n To initialize S/Key or change your password or seed over an insecure connec tion, you will need to already have a secure connection to some place where you can run the `key' program; this might be in the form of a desk accessory on a Macintosh, or a shell prompt on a machine you trust (we will show the latter). You will also need to make up an iteration count (100 is probably a good value), and you may make up your own seed or use a randomly-generated one. Over on the insecure connection (to the machine you are initializing), use the `keyinit -s' command: $ keyinit -s Updating wollman: Old key: kh94741 Reminder you need the 6 English words from the skey command. Enter sequence count from 1 to 9999: 100 ) I typed this Enter new key [default kh94742]: s/key 100 kh94742 To accept the default seed (which the `keyinit' program confusingly calls a `key'), press return. Then move over to your secure connection or S/Key desk accessory, and give it the same parameters: FreeBSD Handbook 102 $ key 100 kh94742 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: ) I typed my secret password HULL NAY YANG TREE TOUT VETO Now switch back over to the insecure connection, and copy the one-time password generated by `key' over to the `keyinit' program: s/key access password: HULL NAY YANG TREE TOUT VETO ID wollman s/key is 100 kh94742 HULL NAY YANG TREE TOUT VETO The rest of the description from the previous section applies here as well. _6_._2_._3 _D_i_v_e_r_s_i_o_n_: _a _l_o_g_i_n _p_r_o_m_p_t Before explaining how to generate one-time passwords, we should go over an S/Key login prompt: $ telnet himalia Trying 18.26.0.186... Connected to himalia.lcs.mit.edu. Escape character is '^]'. s/key 92 hi52030 Password: Note that, before prompting for a password, the login program prints out the iteration number and seed which you will need in order to generate the appro priate key. You will also find a useful feature (not shown here): if you press return at the password prompt, the login program will turn echo on, so you can see what you are typing. This can be extremely useful if you are attempting to type in an S/Key by hand, such as from a printout. If this machine were configured to disallow UNIX passwords over a connection from my machine, the prompt would have also included the annotation `(s/key required)', indicating that only S/Key one-time passwords will be accepted. _6_._2_._4 _G_e_n_e_r_a_t_i_n_g _a _s_i_n_g_l_e _o_n_e_-_t_i_m_e _p_a_s_s_w_o_r_d Now, to generate the one-time password needed to answer this login prompt, we use a trusted machine and the `key' program. (There are versions of the `key' program from DOS and Windows machines, and there is an S/Key desk accessory for Macintosh computers as well.) The command-line `key' program takes as its parameters the iteration count and seed; you can cut-and-paste right from the login prompt starting at ``key'' to the end of the line. Thus: $ key 92 hi52030 ) pasted from previous section Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: ) I typed my secret password ADEN BED WOLF HAW HOT STUN And in the other window: FreeBSD Handbook 103 s/key 92 hi52030 ) from previous section Password: (turning echo on) Password:ADEN BED WOLF HAW HOT STUN Last login: Wed Jun 28 15:31:00 from halloran-eldar.l [etc.] This is the easiest mechanism _i_f you have a trusted machine. There is a Java S/Key key applet, The Java OTP Calculator10 , that you can download and run locally on any Java supporting brower. _6_._2_._5 _G_e_n_e_r_a_t_i_n_g _m_u_l_t_i_p_l_e _o_n_e_-_t_i_m_e _p_a_s_s_w_o_r_d_s Sometimes we have to go places where no trusted machines or connections are available. In this case, it is possible to use the `key' command to generate a number of one-time passwords in the same command; these can then be printed out. For example: $ key -n 25 57 zz99999 Reminder - Do not use this program while logged in via telnet or rlogin. Enter secret password: 33: WALT THY MALI DARN NIT HEAD 34: ASK RICE BEAU GINA DOUR STAG [...] 56: AMOS BOWL LUG FAT CAIN INCH 57: GROW HAYS TUN DISH CAR BALM The `-n 25' requests twenty-five keys in sequence; the `57' indicates the _e_n_d_ _i_n_g iteration number; and the rest is as before. Note that these are printed out in _r_e_v_e_r_s_e order of eventual use. If you are really paranoid, you might want to write the results down by hand; otherwise you can cut-and-paste into `lpr'. Note that each line shows both the iteration count and the one-time password; you may still find it handy to scratch off passwords as you use them. _6_._2_._6 _R_e_s_t_r_i_c_t_i_n_g _u_s_e _o_f _U_N_I_X _p_a_s_s_w_o_r_d_s The configuration file /etc/skey.access can be used to configure restrictions on the use of UNIX passwords based on the host name, user name, terminal port, or IP address of a login session. The complete format of the file is docu mented in the _s_k_e_y_._a_c_c_e_s_s(5) manual page; there are also some security cautions there which should be read before depending on this file for security. If there is no /etc/skey.access file (which is the default state as FreeBSD is shipped), then all users will be allowed to use UNIX passwords. If the file exists, however, then all users will be required to use S/Key unless explicitly permitted to do otherwise by configuration statements in the skey.access file. In all cases, UNIX passwords are permitted on the console. Here is a sample configuration file which illustrates the three most common sorts of configuration statements: ____________________ 10. FreeBSD Handbook 104 permit internet 18.26.0.0 255.255.0.0 permit user jrl permit port ttyd0 The first line (`permit internet') allows users whose IP source address (which is vulnerable to spoofing) matches the specified value and mask, to use UNIX passwords. This should not be considered a security mechanism, but rather, a means to remind authorized users that they are using an insecure network and need to use S/Key for authentication. The second line (`permit user') allows the specified user to use UNIX passwords at any time. Generally speaking, this should only be used for people who are either unable to use the `key' program, like those with dumb terminals, or those who are uneducable. The third line (`permit port') allows all users logging in on the specified terminal line to use UNIX passwords; this would be used for dial-ups. _6_._3 _K_e_r_b_e_r_o_s _C_o_n_t_r_i_b_u_t_e_d _b_y _M_a_r_k _M_u_r_r_a_y (based on contribution by Mark Dapoz ). Kerberos is a network add-on system/protocol that allows users to authenticate themselves through the services of a secure server. Services such as remote login, remote copy, secure inter-system file copying and other high-risk tasks are made considerably safer and more controllable. The following instructions can be used as a guide on how to set up Kerberos as distributed for FreeBSD. However, you should refer to the relevant manual pages for a complete description. In FreeBSD, the Kerberos is not that from the original 4.4BSD-Lite, distribu tion, but eBones, which had been previously ported to FreeBSD 1.1.5.1, and was sourced from outside the USA/Canada, and is thus available to system owners outside those countries. For those needing to get a legal foreign distribution of this software, please _D_O _N_O_T get it from a USA or Canada site. You will get that site in _b_i_g trou ble! A legal copy of this is available from ftp.internat.freebsd.org, which is in South Africa and an official FreeBSD mirror site. _6_._3_._1 _C_r_e_a_t_i_n_g _t_h_e _i_n_i_t_i_a_l _d_a_t_a_b_a_s_e This is done on the Kerberos server only. First make sure that you do not have any old Kerberos databases around. You should change to the directory /etc/ker berosIV and check that only the following files are present: grunt# cd /etc/kerberosIV grunt# ls README krb.conf krb.realms If any additional files (such as principal.* or master_key) exist, then use the kdb_destroy command to destroy the old Kerberos database, of if Kerberos is not FreeBSD Handbook 105 running, simply delete the extra files. You should now edit the krb.conf and krb.realms files to define your Kerberos realm. In this case the realm will be _G_R_O_N_D_A_R_._Z_A and the server is _g_r_u_n_t_._g_r_o_n_ _d_a_r_._z_a. We edit or create the krb.conf file: grunt# cat krb.conf GRONDAR.ZA GRONDAR.ZA grunt.grondar.za admin server CS.BERKELEY.EDU okeeffe.berkeley.edu ATHENA.MIT.EDU kerberos.mit.edu ATHENA.MIT.EDU kerberos-1.mit.edu ATHENA.MIT.EDU kerberos-2.mit.edu ATHENA.MIT.EDU kerberos-3.mit.edu LCS.MIT.EDU kerberos.lcs.mit.edu TELECOM.MIT.EDU bitsy.mit.edu ARC.NASA.GOV trident.arc.nasa.gov In this case, the other realms do not need to be there. They are here as an example of how a machine may be made aware of multiple realms. You may wish to not include them for simplicity. The first line names the realm in which this system works. The other lines con tain realm/host entries. The first item on a line is a realm, and the second is a host in that realm that is acting as a ``key distribution centre''. The words ``admin server'' following a hosts name means that host also provides an admin istrative database server. For further explanation of these terms, please con sult the Kerberos man pages. Now we have to add _g_r_u_n_t_._g_r_o_n_d_a_r_._z_a to the _G_R_O_N_D_A_R_._Z_A realm and also add an entry to put all hosts in the _._g_r_o_n_d_a_r_._z_a domain in the _G_R_O_N_D_A_R_._Z_A realm. The krb.realms file would be updated as follows: grunt# cat krb.realms grunt.grondar.za GRONDAR.ZA .grondar.za GRONDAR.ZA .berkeley.edu CS.BERKELEY.EDU .MIT.EDU ATHENA.MIT.EDU .mit.edu ATHENA.MIT.EDU Again, the other realms do not need to be there. They are here as an example of how a machine may be made aware of multiple realms. You may wish to remove them to simplify things. The first line puts the _s_p_e_c_i_f_i_c system into the named realm. The rest of the lines show how to default systems of a particular subdomain to a named realm. Now we are ready to create the database. This only needs to run on the Kerberos server (or Key Distribution Centre). Issue the kdb_init command to do this: FreeBSD Handbook 106 grunt# kdb_init Realm name [default ATHENA.MIT.EDU ]: GRONDAR.ZA You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter Kerberos master key: Now we have to save the key so that servers on the local machine can pick it up. Use the kstash command to do this. grunt# kstash Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! This saves the encrypted master password in /etc/kerberosIV/master_key. _6_._3_._2 _M_a_k_i_n_g _i_t _a_l_l _r_u_n Two principals need to be added to the database for _e_a_c_h system that will be secured with Kerberos. Their names are kpasswd and rcmd These two principals are made for each system, with the instance being the name of the individual system. These daemons, kpasswd and rcmd allow other systems to change Kerberos pass words and run commands like rcp, rlogin and rsh. Now let's add these entries: FreeBSD Handbook 107 grunt# kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: passwd Instance: grunt , Create [y] ? y Principal: passwd, Instance: grunt, kdc_key_ver: 1 New Password: <---- enter RANDOM here Verifying password New Password: <---- enter RANDOM here Random password [y] ? y Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: rcmd Instance: grunt , Create [y] ? Principal: rcmd, Instance: grunt, kdc_key_ver: 1 New Password: <---- enter RANDOM here Verifying password New Password: <---- enter RANDOM here Random password [y] ? Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit _6_._3_._3 _C_r_e_a_t_i_n_g _t_h_e _s_e_r_v_e_r _f_i_l_e We now have to extract all the instances which define the services on each machine. For this we use the ext_srvtab command. This will create a file which must be copied or moved _b_y _s_e_c_u_r_e _m_e_a_n_s to each Kerberos client's FreeBSD Handbook 108 /etc/kerberosIV directory. This file must be present on each server and client, and is crucial to the operation of Kerberos. grunt# ext_srvtab grunt Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Generating 'grunt-new-srvtab'.... Now, this command only generates a temporary file which must be renamed to srvtab so that all the server can pick it up. Use the mv command to move it into place on the original system: grunt# mv grunt-new-srvtab srvtab If the file is for a client system, and the network is not deemed safe, then copy the -new-srvtab to removable media and transport it by secure physical means. Be sure to rename it to srvtab in the client's /etc/kerberosIV directory, and make sure it is mode 600: grumble# mv grumble-new-srvtab srvtab grumble# chmod 600 srvtab _6_._3_._4 _P_o_p_u_l_a_t_i_n_g _t_h_e _d_a_t_a_b_a_s_e We now have to add some user entries into the database. First let's create an entry for the user _j_a_n_e. Use the kdb_edit command to do this: FreeBSD Handbook 109 grunt# kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: jane Instance: , Create [y] ? y Principal: jane, Instance: , kdc_key_ver: 1 New Password: <---- enter a secure password here Verifying password New Password: <---- re-enter the password here Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit _6_._3_._5 _T_e_s_t_i_n_g _i_t _a_l_l _o_u_t First we have to start the Kerberos daemons. NOTE that if you have correctly edited your /etc/rc.conf then this will happen automatically when you reboot. This is only necessary on the Kerberos server. Kerberos clients will automagi cally get what they need from the /etc/kerberosIV directory. grunt# kerberos & grunt# Kerberos server starting Sleep forever on error Log file is /var/log/kerberos.log Current Kerberos master key version is 1. Master key entered. BEWARE! Current Kerberos master key version is 1 Local realm: GRONDAR.ZA grunt# kadmind -n & grunt# KADM Server KADM0.0A initializing Please do not use 'kill -9' to kill this job, use a regular kill instead Current Kerberos master key version is 1. Master key entered. BEWARE! FreeBSD Handbook 110 Now we can try using the kinit command to get a ticket for the id _j_a_n_e that we created above: grunt$ kinit jane MIT Project Athena (grunt.grondar.za) Kerberos Initialization for "jane" Password: Try listing the tokens using klist to see if we really have them: grunt$ klist Ticket file: /tmp/tkt245 Principal: jane@GRONDAR.ZA Issued Expires Principal Apr 30 11:23:22 Apr 30 19:23:22 krbtgt.GRONDAR.ZA@GRONDAR.ZA Now try changing the password using passwd to check if the kpasswd daemon can get authorization to the Kerberos database: grunt$ passwd realm GRONDAR.ZA Old password for jane: New Password for jane: Verifying password New Password for jane: Password changed. _6_._3_._6 _A_d_d_i_n_g _s_u _p_r_i_v_i_l_e_g_e_s Kerberos allows us to give _e_a_c_h user who needs root privileges their own _s_e_p_a_ _r_a_t_e supassword. We could now add an id which is authorized to su to _r_o_o_t. This is controlled by having an instance of _r_o_o_t associated with a principal. Using kdb_edit we can create the entry _j_a_n_e_._r_o_o_t in the Kerberos database: FreeBSD Handbook 111 grunt# kdb_edit Opening database... Enter Kerberos master key: Current Kerberos master key version is 1. Master key entered. BEWARE! Previous or default values are in [brackets] , enter return to leave the same, or new value. Principal name: jane Instance: root , Create [y] ? y Principal: jane, Instance: root, kdc_key_ver: 1 New Password: <---- enter a SECURE password here Verifying password New Password: <---- re-enter the password here Principal's new key version = 1 Expiration date (enter yyyy-mm-dd) [ 2000-01-01 ] ? Max ticket lifetime (*5 minutes) [ 255 ] ? 12 <--- Keep this short! Attributes [ 0 ] ? Edit O.K. Principal name: <---- null entry here will cause an exit Now try getting tokens for it to make sure it works: grunt# kinit jane.root MIT Project Athena (grunt.grondar.za) Kerberos Initialization for "jane.root" Password: Now we need to add the user to root's .klogin file: grunt# cat /root/.klogin jane.root@GRONDAR.ZA Now try doing the su: [jane@grunt 10407] su Password: grunt# and take a look at what tokens we have: FreeBSD Handbook 112 grunt# klist Ticket file: /tmp/tkt_root_245 Principal: jane.root@GRONDAR.ZA Issued Expires Principal May 2 20:43:12 May 3 04:43:12 krbtgt.GRONDAR.ZA@GRONDAR.ZA _6_._3_._7 _U_s_i_n_g _o_t_h_e_r _c_o_m_m_a_n_d_s In an earlier example, we created a principal called jane with an instance root. This was based on a user with the same name as the principal, and this is a Kerberos default; that a _<_p_r_i_n_c_i_p_a_l_>_._<_i_n_s_t_a_n_c_e_> of the form _<_u_s_e_r_n_a_m_e_>_.root will allow that _<_u_s_e_r_n_a_m_e_> to su to root if the necessary entries are in the .klogin file in root's home directory: grunt# cat /root/.klogin jane.root@GRONDAR.ZA Likewise, if a user has in their own home directory lines of the form: [jane@grunt 10543] cat ~/.klogin jane@GRONDAR.ZA jack@GRONDAR.ZA This allows anyone in the _G_R_O_N_D_A_R_._Z_A realm who has authenticated themselves to _j_a_n_e or _j_a_c_k (via kinit, see above) access to rlogin to _j_a_n_e's account or files on this system (_g_r_u_n_t) via rlogin, rsh or rcp. For example, Jane now logs into another system, using Kerberos: [jane@grumble 573] kinit MIT Project Athena (grunt.grondar.za) Password: [jane@grumble 574] rlogin grunt Last login: Mon May 1 21:14:47 from grumble Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995 [jane@grunt 10567] Or Jack logs into Jane's account on the same machine (Jane having set up the .klogin file as above, and the person in charge of Kerberos having set up prin cipal _j_a_c_k with a null instance: FreeBSD Handbook 113 [jack@grumble 573] kinit [jack@grumble 574] rlogin grunt -l jane MIT Project Athena (grunt.grondar.za) Password: Last login: Mon May 1 21:16:55 from grumble Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD BUILT-19950429 (GR386) #0: Sat Apr 29 17:50:09 SAT 1995 [jane@grunt 10578] _6_._4 _F_i_r_e_w_a_l_l_s _C_o_n_t_r_i_b_u_t_e_d _b_y _G_a_r_y _P_a_l_m_e_r and Alex Nash . Firewalls are an area of increasing interest for people who are connected to the Internet, and are even finding applications on private networks to provide enhanced security. This section will hopefully explain what firewalls are, how to use them, and how to use the facilities provided in the FreeBSD kernel to implement them. NNoottee: People often think that having a firewall between your compa nies internal network and the ``Big Bad Internet'' will solve all your security problems. It may help, but a poorly setup firewall sys tem is more of a security risk than not having one at all. A fire wall can only add another layer of security to your systems, but they will not be able to stop a really determined cracker from penetrating your internal network. If you let internal security lapse because you believe your firewall to be impenetrable, you have just made the crackers job that bit easier. _6_._4_._1 _W_h_a_t _i_s _a _f_i_r_e_w_a_l_l_? There are currently two distinct types of firewalls in common use on the Inter net today. The first type is more properly called a ppaacckkeett ffiilltteerriinngg rroouutteerr, where the kernel on a multi-homed machine chooses whether to forward or block packets based on a set of rules. The second type, known as pprrooxxyy sseerrvveerrss, rely on daemons to provide authentication and to forward packets, possibly on a multi-homed machine which has kernel packet forwarding disabled. Sometimes sites combine the two types of firewalls, so that only a certain machine (known as a bbaassttiioonn hhoosstt) is allowed to send packets through a packet filtering router onto an internal network. Proxy services are run on the bas tion host, which are generally more secure than normal authentication mecha nisms. FreeBSD comes with a kernel packet filter (known as IPFW), which is what the rest of this section will concentrate on. Proxy servers can be built on FreeBSD from third party software, but there is such a variety of proxy servers avail able that it would be impossible to cover them in this document. FreeBSD Handbook 114 _6_._4_._1_._1 _P_a_c_k_e_t _f_i_l_t_e_r_i_n_g _r_o_u_t_e_r_s A router is a machine which forwards packets between two or more networks. A packet filtering router has an extra piece of code in its kernel, which com pares each packet to a list of rules before deciding if it should be forwarded or not. Most modern IP routing software has packet filtering code in it, which defaults to forwarding all packets. To enable the filters, you need to define a set of rules for the filtering code, so that it can decide if the packet should be allowed to pass or not. To decide if a packet should be passed on or not, the code looks through its set of rules for a rule which matches the contents of this packets headers. Once a match is found, the rule action is obeyed. The rule action could be to drop the packet, to forward the packet, or even to send an ICMP message back to the originator. Only the first match counts, as the rules are searched in order. Hence, the list of rules can be referred to as a ``rule chain''. The packet matching criteria varies depending on the software used, but typi cally you can specify rules which depend on the source IP address of the packet, the destination IP address, the source port number, the destination port number (for protocols which support ports), or even the packet type (UDP, TCP, ICMP, etc). _6_._4_._1_._2 _P_r_o_x_y _s_e_r_v_e_r_s Proxy servers are machines which have had the normal system daemons (telnetd, ftpd, etc) replaced with special servers. These servers are called pprrooxxyy sseerrvveerrss as they normally only allow onward connections to be made. This enables you to run (for example) a proxy telnet server on your firewall host, and peo ple can telnet in to your firewall from the outside, go through some authenti cation mechanism, and then gain access to the internal network (alternatively, proxy servers can be used for signals coming from the internal network and heading out). Proxy servers are normally more secure than normal servers, and often have a wider variety of authentication mechanisms available, including ``one-shot'' password systems so that even if someone manages to discover what password you used, they will not be able to use it to gain access to your systems as the password instantly expires. As they do not actually give users access to the host machine, it becomes a lot more difficult for someone to install backdoors around your security system. Proxy servers often have ways of restricting access further, so that only cer tain hosts can gain access to the servers, and often they can be set up so that you can limit which users can talk to which destination machine. Again, what facilities are available depends largely on what proxy software you choose. _6_._4_._2 _W_h_a_t _d_o_e_s _I_P_F_W _a_l_l_o_w _m_e _t_o _d_o_? IPFW, the software supplied with FreeBSD, is a packet filtering and accounting system which resides in the kernel, and has a user-land control utility, ipfw(8). Together, they allow you to define and query the rules currently used by the kernel in its routing decisions. FreeBSD Handbook 115 There are two related parts to IPFW. The firewall section allows you to perform packet filtering. There is also an IP accounting section which allows you to track usage of your router, based on similar rules to the firewall section. This allows you to see (for example) how much traffic your router is getting from a certain machine, or how much WWW (World Wide Web) traffic it is forward ing. As a result of the way that IPFW is designed, you can use IPFW on non-router machines to perform packet filtering on incoming and outgoing connections. This is a special case of the more general use of IPFW, and the same commands and techniques should be used in this situation. _6_._4_._3 _E_n_a_b_l_i_n_g _I_P_F_W _o_n _F_r_e_e_B_S_D As the main part of the IPFW system lives in the kernel, you will need to add one or more options to your kernel configuration file, depending on what facil ities you want, and recompile your kernel. See _r_e_c_o_n_f_i_g_u_r_i_n_g _t_h_e _k_e_r_n_e_l (sec tion 5., page 79) for more details on how to recompile your kernel. There are currently three kernel configuration options relevant to IPFW: options IPFIREWALL Compiles into the kernel the code for packet filtering. options IPFIREWALL_VERBOSE Enables code to allow logging of packets through syslogd(8). With out this option, even if you specify that packets should be logged in the filter rules, nothing will happen. options IPFIREWALL_VERBOSE_LIMIT=10 Limits the number of packets logged through syslogd(8) on a per entry basis. You may wish to use this option in hostile environ ments in which you want to log firewall activity, but do not want to be open to a denial of service attack via syslog flooding. When a chain entry reaches the packet limit specified, logging is turned off for that particular entry. To resume logging, you will need to reset the associated counter using the ipfw(8) utility: ipfw zero 4500 Where 4500 is the chain entry you wish to continue logging. Previous versions of FreeBSD contained an IPFIREWALL_ACCT option. This is now obsolete as the firewall code automatically includes accounting facilities. _6_._4_._4 _C_o_n_f_i_g_u_r_i_n_g _I_P_F_W The configuration of the IPFW software is done through the ipfw(8) utility. The syntax for this command looks quite complicated, but it is relatively simple once you understand its structure. There are currently four different command categories used by the utility: addition/deletion, listing, flushing, and clearing. Addition/deletion is used FreeBSD Handbook 116 to build the rules that control how packets are accepted, rejected, and logged. Listing is used to examine the contents of your rule set (otherwise known as the chain) and packet counters (accounting). Flushing is used to remove all entries from the chain. Clearing is used to zero out one or more accounting entries. _6_._4_._4_._1 _A_l_t_e_r_i_n_g _t_h_e _I_P_F_W _r_u_l_e_s The syntax for this form of the command is: ipfw [-N] _c_o_m_m_a_n_d [_i_n_d_e_x] _a_c_t_i_o_n [log] _p_r_o_t_o_c_o_l _a_d_d_r_e_s_s_e_s [_o_p_t_i_o_n_s] There is one valid flag when using this form of the command: -N Resolve addresses and service names in output. The _c_o_m_m_a_n_d given can be shortened to the shortest unique form. The valid _c_o_m_ _m_a_n_d_s are: add Add an entry to the firewall/accounting rule list delete Delete an entry from the firewall/accounting rule list Previous versions of IPFW used separate firewall and accounting entries. The present version provides packet accounting with each firewall entry. If an index value is supplied, it used to place the entry at a specific point in the chain. Otherwise, the entry is placed at the end of the chain at an index 100 greater than the last chain entry (this does not include the default policy, rule 65535, deny). The lloogg option causes matching rules to be output to the system console if the kernel was compiled with IIPPFFIIRREEWWAALLLL__VVEERRBBOOSSEE. Valid _a_c_t_i_o_n_s are: reject Drop the packet, and send an ICMP host or port unreachable (as appropriate) packet to the source. allow Pass the packet on as normal. (aliases: ppaassss and aacccceepptt) deny Drop the packet. The source is not notified via an ICMP message (thus it appears that the packet never arrived at the destination). count Update packet counters but do not allow/deny the packet based on FreeBSD Handbook 117 this rule. The search continues with the next chain entry. Each _a_c_t_i_o_n will be recognized by the shortest unambiguous prefix. The _p_r_o_t_o_c_o_l_s which can be specified are: all Matches any IP packet icmp Matches ICMP packets tcp Matches TCP packets udp Matches UDP packets The _a_d_d_r_e_s_s specification is: ffrroomm <_a_d_d_r_e_s_s_/_m_a_s_k>[_p_o_r_t] ttoo <_a_d_d_r_e_s_s_/_m_a_s_k>[_p_o_r_t] [vviiaa <_i_n_t_e_r_f_a_c_e>] You can only specify _p_o_r_t in conjunction with _p_r_o_t_o_c_o_l_s which support ports (UDP and TCP). The vviiaa is optional and may specify the IP address or domain name of a local IP interface, or an interface name (e.g. ed0) to match only packets coming through this interface. Interface unit numbers can be specified with an optional wildcard. For example, ppp* would match all kernel PPP interfaces. The syntax used to specify an
is:
or
/mask-bits or
:mask-pattern A valid hostname may be specified in place of the IP address. mask-bits is a decimal number representing how many bits in the address mask should be set. e.g. specifying 192.216.222.1/24 will create a mask which will allow any address in a class C subnet (in this case, 192.216.222) to be matched. mask-pattern is an IP address which will be FreeBSD Handbook 118 logically AND'ed with the address given. The keyword any may be used to spec ify ``any IP address''. The port numbers to be blocked are specified as: port[,port[,port[...]]] to specify either a single port or a list of ports, or port-port to specify a range of ports. You may also combine a single range with a list, but the range must always be specified first. The _o_p_t_i_o_n_s available are: frag Matches if the packet is not the first fragment of the datagram. in Matches if the packet is on the way in. out Matches if the packet is on the way out. ipoptions _s_p_e_c Matches if the IP header contains the comma separated list of options specified in _s_p_e_c. The supported list of IP options are: ssssrrrr (strict source route), llssrrrr (loose source route), rrrr (record packet route), and ttss (timestamp). The absence of a particular option may be denoted with a leading '!'. established Matches if the packet is part of an already established TCP connec tion (i.e. it has the RST or ACK bits set). You can optimize the performance of the firewall by placing _e_s_t_a_b_l_i_s_h_e_d rules early in the chain. setup Matches if the packet is an attempt to establish a TCP connection (the SYN bit set is set but the ACK bit is not). tcpflags _f_l_a_g_s Matches if the TCP header contains the comma separated list of _f_l_a_g_s. The supported flags are ffiinn, ssyynn, rrsstt, ppsshh, aacckk, and uurrgg. The absence of a particular flag may be indicated by a leading '!'. icmptypes _t_y_p_e_s Matches if the ICMP type is present in the list _t_y_p_e_s. The list may be specified as any combination of ranges and/or individual types separated by commas. Commonly used ICMP types are: 00 echo reply (ping reply), 55 redirect, 88 echo request (ping request), and FreeBSD Handbook 119 1111 time exceeded (used to indicate TTL expiration as with tracer oute(8)). _6_._4_._4_._2 _L_i_s_t_i_n_g _t_h_e _I_P_F_W _r_u_l_e_s The syntax for this form of the command is: ipfw [-atN] l There are three valid flags when using this form of the command: -a While listing, show counter values. This option is the only way to see accounting counters. -t Display the last match times for each chain entry. The time list ing is incompatible with the input syntax used by the ipfw(8) util ity. -N Attempt to resolve given addresses and service names. _6_._4_._4_._3 _F_l_u_s_h_i_n_g _t_h_e _I_P_F_W _r_u_l_e_s The syntax for flushing the chain is: ipfw flush This causes all entries in the firewall chain to be removed except the fixed default policy enforced by the kernel (index 65535). Use caution when flushing rules, the default deny policy will leave your system cut off from the network until allow entries are added to the chain. _6_._4_._4_._4 _C_l_e_a_r_i_n_g _t_h_e _I_P_F_W _p_a_c_k_e_t _c_o_u_n_t_e_r_s The syntax for clearing one or more packet counters is: ipfw zero [index] When used without an _i_n_d_e_x argument, all packet counters are cleared. If an _i_n_d_e_x is supplied, the clearing operation only affects a specific chain entry. _6_._4_._5 _E_x_a_m_p_l_e _c_o_m_m_a_n_d_s _f_o_r _i_p_f_w This command will deny all packets from the host eevviill..ccrraacckkeerrss..oorrgg to the tel net port of the host nniiccee..ppeeooppllee..oorrgg by being forwarded by the router: ipfw add deny tcp from evil.crackers.org to nice.people.org 23 The next example denies and logs any TCP traffic from the entire ccrraacckkeerrss..oorrgg network (a class C) to the nniiccee..ppeeooppllee..oorrgg machine (any port). ipfw add deny log tcp from evil.crackers.org/24 to nice.people.org FreeBSD Handbook 120 If you do not want people sending X sessions to your internal network (a subnet of a class C), the following command will do the necessary filtering: ipfw add deny tcp from any to my.org/28 6000 setup To see the accounting records: ipfw -a list or in the short form ipfw -a l You can also see the last time a chain entry was matched with ipfw -at l _6_._4_._6 _B_u_i_l_d_i_n_g _a _p_a_c_k_e_t _f_i_l_t_e_r_i_n_g _f_i_r_e_w_a_l_l NNoottee:: The following suggestions are just that: suggestions. The requirements of each firewall are different and I cannot tell you how to build a firewall to meet your particular requirements. When initially setting up your firewall, unless you have a test bench setup where you can configure your firewall host in a controlled environment, I strongly recommend you use the logging version of the commands and enable log ging in the kernel. This will allow you to quickly identify problem areas and cure them without too much disruption. Even after the initial setup phase is complete, I recommend using the logging for of `deny' as it allows tracing of possible attacks and also modification of the firewall rules if your require ments alter. NNoottee:: If you use the logging versions of the aacccceepptt command, it can generate _l_a_r_g_e amounts of log data as one log line will be generated for every packet that passes through the firewall, so large ftp/http transfers, etc, will really slow the system down. It also increases the latencies on those packets as it requires more work to be done by the kernel before the packet can be passed on. syslogd with also start using up a lot more processor time as it logs all the extra data to disk, and it could quite easily fill the partition /var/log is located on. As currently supplied, FreeBSD does not have the ability to load firewall rules at boot time. My suggestion is to put a call to a shell script in the /etc/net start script. Put the call early enough in the netstart file so that the fire wall is configured before any of the IP interfaces are configured. This means that there is no window during which time your network is open. The actual script used to load the rules is entirely up to you. There is cur rently no support in the ipfw utility for loading multiple rules in the one command. The system I use is to use the command: FreeBSD Handbook 121 # ipfw list to write a list of the current rules out to a file, and then use a text editor to prepend ``ipfw '' before all the lines. This will allow the script to be fed into /bin/sh and reload the rules into the kernel. Perhaps not the most effi cient way, but it works. The next problem is what your firewall should actually DDOO! This is largely dependent on what access to your network you want to allow from the outside, and how much access to the outside world you want to allow from the inside. Some general rules are: Block all incoming access to ports below 1024 for TCP. This is where most of the security sensitive services are, like finger, SMTP (mail) and tel net. Block aallll incoming UDP traffic. There are very few useful services that travel over UDP, and what useful traffic there is is normally a security threat (e.g. Suns RPC and NFS protocols). This has its disadvantages also, since UDP is a connectionless protocol, denying incoming UDP traffic also blocks the replies to outgoing UDP traffic. This can cause a problem for people (on the inside) using external archie (prospero) servers. If you want to allow access to archie, you'll have to allow packets coming from ports 191 and 1525 to any internal UDP port through the firewall. ntp is another service you may consider allowing through, which comes from port 123. Block traffic to port 6000 from the outside. Port 6000 is the port used for access to X11 servers, and can be a security threat (especially if people are in the habit of doing xhost + on their workstations). X11 can actually use a range of ports starting at 6000, the upper limit being how many X displays you can run on the machine. The upper limit as defined by RFC 1700 (Assigned Numbers) is 6063. Check what ports any internal servers use (e.g. SQL servers, etc). It is probably a good idea to block those as well, as they normally fall outside the 1-1024 range specified above. Another checklist for firewall configuration is available from CERT at ftp://ftp.cert.org/pub/tech_tips/packet_filtering As I said above, these are only _g_u_i_d_e_l_i_n_e_s. You will have to decide what filter rules you want to use on your firewall yourself. I cannot accept ANY responsi bility if someone breaks into your network, even if you follow the advice given above. _7_. _P_r_i_n_t_i_n_g _C_o_n_t_r_i_b_u_t_e_d _b_y _S_e_a_n _K_e_l_l_y 30 September 1995 In order to use printers with FreeBSD, you will need to set them up to work with the Berkeley line printer spooling system, also known as the LPD spooling FreeBSD Handbook 122 system. It is the standard printer control system in FreeBSD. This section introduces the LPD spooling system, often simply called LPD. If you are already familiar with LPD or another printer spooling system, you may wish to skip to section _S_e_t_t_i_n_g _u_p _t_h_e _s_p_o_o_l_i_n_g _s_y_s_t_e_m (section 7.3, page 123). _7_._1 _W_h_a_t _t_h_e _S_p_o_o_l_e_r _D_o_e_s LPD controls everything about a host's printers. It is responsible for a num ber of things: It controls access to attached printers and printers attached to other hosts on the network. It enables users to submit files to be printed; these submissions are known as _j_o_b_s. It prevents multiple users from accessing a printer at the same time by maintaining a _q_u_e_u_e for each printer. It can print _h_e_a_d_e_r _p_a_g_e_s (also known as _b_a_n_n_e_r or _b_u_r_s_t pages) so users can easily find jobs they have printed in a stack of printouts. It takes care of communications parameters for printers connected on serial ports. It can send jobs over the network to another LPD spooler on another host. It can run special filters to format jobs to be printed for various printer languages or printer capabilities. It can account for printer usage. Through a configuration file, and by providing the special filter programs, you can enable the LPD system to do all or some subset of the above for a great variety of printer hardware. _7_._2 _W_h_y _Y_o_u _S_h_o_u_l_d _U_s_e _t_h_e _S_p_o_o_l_e_r If you are the sole user of your system, you may be wondering why you should bother with the spooler when you do not need access control, header pages, or printer accounting. While it is possible to enable direct access to a printer, you should use the spooler anyway since LPD prints jobs in the background; you do not have to wait for data to be copied to the printer. LPD can conveniently run a job to be printed through filters to add date/time headers or convert a special file format (such as a TeX DVI file) into a format the printer will understand. You will not have to do these steps manually. FreeBSD Handbook 123 Many free and commercial programs that provide a print feature usually expect to talk to the spooler on your system. By setting up the spooling system, you will more easily support other software you may later add or already have. _7_._3 _S_e_t_t_i_n_g _U_p _t_h_e _S_p_o_o_l_i_n_g _S_y_s_t_e_m To use printers with the LPD spooling system, you will need to set up both your printer hardware and the LPD software. This document describes two levels of setup: See section _S_i_m_p_l_e _P_r_i_n_t_e_r _S_e_t_u_p (section 7.4, page 123) to learn how to connect a printer, tell LPD how to communicate with it, and print plain text files to the printer. See section _A_d_v_a_n_c_e_d _P_r_i_n_t_e_r _S_e_t_u_p (section 7.6, page 148) to find out how to print a variety of special file formats, to print header pages, to print across a network, to control access to printers, and to do printer accounting. _7_._4 _S_i_m_p_l_e _P_r_i_n_t_e_r _S_e_t_u_p This section tells how to configure printer hardware and the LPD software to use the printer. It teaches the basics: Section _H_a_r_d_w_a_r_e _S_e_t_u_p (section 7.4.1, page 123) gives some hints on connecting the printer to a port on your computer. Section _S_o_f_t_w_a_r_e _S_e_t_u_p (section 7.4.2, page 125) shows how to setup the LPD spooler configuration file /etc/printcap. If you are setting up a printer that uses a network protocol to accept data to print instead of a serial or parallel interface, see _P_r_i_n_t_e_r_s _W_i_t_h _N_e_t_w_o_r_k_e_d _D_a_t_a _S_t_r_e_a_m _I_n_t_e_r_a_c_e_s (section 7.6.3.2, page 171). Although this section is called ``Simple Printer Setup,'' it is actually fairly complex. Getting the printer to work with your computer and the LPD spooler is the hardest part. The advanced options like header pages and accounting are fairly easy once you get the printer working. _7_._4_._1 _H_a_r_d_w_a_r_e _S_e_t_u_p This section tells about the various ways you can connect a printer to your PC. It talks about the kinds of ports and cables, and also the kernel configu ration you may need to enable FreeBSD to speak to the printer. If you have already connected your printer and have successfully printed with it under another operating system, you can probably skip to section _S_o_f_t_w_a_r_e _S_e_t_u_p (section 7.4.2, page 125). _7_._4_._1_._1 _P_o_r_t_s _a_n_d _C_a_b_l_e_s Nearly all printers you can get for a PC today support one or both of the fol lowing interfaces: FreeBSD Handbook 124 _S_e_r_i_a_l interfaces use a serial port on your computer to send data to the printer. Serial interfaces are common in the computer industry and cables are readily available and also easy to construct. Serial interfaces some times need special cables and might require you to configure somewhat com plex communications options. _P_a_r_a_l_l_e_l interfaces use a parallel port on your computer to send data to the printer. Parallel interfaces are common in the PC market. Cables are readily available but more difficult to construct by hand. There are usu ally no communications options with parallel interfaces, making their con figuration exceedingly simple. Parallel interfaces are sometimes known as ``Centronics'' interfaces, named after the connector type on the printer. In general, serial interfaces are slower than parallel interfaces. Parallel interfaces usually offer just one-way communication (computer to printer) while serial gives you two-way. Many newer parallel ports can also receive data from the printer, but only few printers need to send data back to the computer. And FreeBSD does not support two-way parallel communication yet. Usually, the only time you need two-way communication with the printer is if the printer speaks PostScript. PostScript printers can be very verbose. In fact, PostScript jobs are actually programs sent to the printer; they need not produce paper at all and may return results directly to the computer. PostScript also uses two-way communication to tell the computer about problems, such as errors in the PostScript program or paper jams. Your users may be appreciative of such information. Furthermore, the best way to do effective accounting with a PostScript printer requires two-way communication: you ask the printer for its page count (how many pages it has printed in its lifetime), then send the user's job, then ask again for its page count. Subtract the two values and you know how much paper to charge the user. So, which interface should you use? If you need two-way communication, use a serial port. FreeBSD does not yet support two-way communication over a parallel port. If you do not need two-way communication and can pick parallel or serial, prefer the parallel interface. It keeps a serial port free for other peripherals---such as a terminal or a modem---and is faster most of the time. It is also easier to configure. Finally, use whatever works. _7_._4_._1_._2 _P_a_r_a_l_l_e_l _P_o_r_t_s To hook up a printer using a parallel interface, connect the Centronics cable between the printer and the computer. The instructions that came with the printer, the computer, or both should give you complete guidance. Remember which parallel port you used on the computer. The first parallel port is /dev/lpt0 to FreeBSD; the second is /dev/lpt1, and so on. FreeBSD Handbook 125 _7_._4_._1_._3 _S_e_r_i_a_l _P_o_r_t_s To hook up a printer using a serial interface, connect the proper serial cable between the printer and the computer. The instructions that came with the printer, the computer, or both should give you complete guidance. If you are unsure what the ``proper serial cable'' is, you may wish to try one of the following alternatives: A _m_o_d_e_m cable connects each pin of the connector on one end of the cable straight through to its corresponding pin of the connector on the other end. This type of cable is also known as a DTE-to-DCE cable. A _n_u_l_l_-_m_o_d_e_m cable connects some pins straight through, swaps others (send data to receive data, for example), and shorts some internally in each connector hood. This type of cable is also known as a DTE-to-DTE cable. A _s_e_r_i_a_l _p_r_i_n_t_e_r cable, required for some unusual printers, is like the null modem cable, but sends some signals to their counterparts instead of being internally shorted. You should also set up the communications parameters for the printer, usually through front-panel controls or DIP switches on the printer. Choose the high est bps (bits per second, sometimes _b_a_u_d _r_a_t_e) rate that both your computer and the printer can support. Choose 7 or 8 data bits; none, even, or odd parity; and 1 or 2 stop bits. Also choose a flow control protocol: either none, or XON/XOFF (also known as _i_n_-_b_a_n_d or _s_o_f_t_w_a_r_e) flow control. Remember these set tings for the software configuration that follows. _7_._4_._2 _S_o_f_t_w_a_r_e _S_e_t_u_p This section describes the software setup necessary to print with the LPD spooling system in FreeBSD. Here is an outline of the steps involved: 1. Configure your kernel, if necessary, for the port you are using for the printer; section _K_e_r_n_e_l _C_o_n_f_i_g_u_r_a_t_i_o_n (section 7.4.2.1, page 125) tells you what you need to do. 2. Set the communications mode for the parallel port, if you are using a parallel port; section _S_e_t_t_i_n_g _t_h_e _C_o_m_m_u_n_i_c_a_t_i_o_n _M_o_d_e _f_o_r _t_h_e _P_a_r_ _a_l_l_e_l _P_o_r_t (section 7.4.2.1.2, page 127) gives details. 3. Test if the operating system can send data to the printer. Section _C_h_e_c_k_i_n_g _P_r_i_n_t_e_r _C_o_m_m_u_n_i_c_a_t_i_o_n_s (section 7.4.2.1.3, page 128) gives some suggestions on how to do this. 4. Set up LPD for the printer by modifying the file /etc/printcap. Section _T_h_e _/_e_t_c_/_p_r_i_n_t_c_a_p _F_i_l_e (section 7.4.2.2, page 130) shows you how. _7_._4_._2_._1 _K_e_r_n_e_l _C_o_n_f_i_g_u_r_a_t_i_o_n The operating system kernel is compiled to work with a specific set of FreeBSD Handbook 126 devices. The serial or parallel interface for your printer is a part of that set. Therefore, it might be necessary to add support for an additional serial or parallel port if your kernel is not already configured for one. To find out if the kernel you are currently using supports a serial interface, type dmesg | grep sio_N where _N is the number of the serial port, starting from zero. If you see out put similar to the following sio2 at 0x3e8-0x3ef irq 5 on isa sio2: type 16550A then the kernel supports the port. To find out if the kernel supports a parallel interface, type dmesg | grep lpt_N where _N is the number of the parallel port, starting from zero. If you see output similar to the following lpt0 at 0x378-0x37f on isa then the kernel supports the port. You might have to reconfigure your kernel in order for the operating system to recognize and use the parallel or serial port you are using for the printer. To add support for a serial port, see the section on kernel configuration. To add support for a parallel port, see that section _a_n_d the section that follows. _7_._4_._2_._1_._1 _A_d_d_i_n_g _/_d_e_v _E_n_t_r_i_e_s _f_o_r _t_h_e _P_o_r_t_s " Even though the kernel may support communication along a serial or parallel port, you will still need a software interface through which programs running on the system can send and receive data. That is what entries in the /dev directory are for. TToo aadddd aa /dev entry for a port: 1. Become root with the su command. Enter the root password when prompted. 2. Change to the /dev directory: FreeBSD Handbook 127 cd /dev 3. Type ./MAKEDEV _p_o_r_t where _p_o_r_t is the device entry for the port you want to make. Use lpt0 for the first parallel port, lpt1 for the second, and so on; use ttyd0 for the first serial port, ttyd1 for the second, and so on. 4. Type ls -l _p_o_r_t to make sure the device entry got created. _7_._4_._2_._1_._2 _S_e_t_t_i_n_g _t_h_e _C_o_m_m_u_n_i_c_a_t_i_o_n _M_o_d_e _f_o_r _t_h_e _P_a_r_a_l_l_e_l _P_o_r_t " When you are using the parallel interface, you can choose whether FreeBSD should use interrupt-driven or polled communication with the printer. The _i_n_t_e_r_r_u_p_t_-_d_r_i_v_e_n method is the default with the GENERIC kernel. With this method, the operating system uses an IRQ line to determine when the printer is ready for data. The _p_o_l_l_e_d method directs the operating system to repeatedly ask the printer if it is ready for more data. When it responds ready, the kernel sends more data. The interrupt-driven method is somewhat faster but uses up a precious IRQ line. You should use whichever one works. You can set the communications mode in two ways: by configuring the kernel or by using the lptcontrol program. TToo sseett tthhee ccoommmmuunniiccaattiioonnss mmooddee bbyy ccoonnffiigguurriinngg tthhee kkeerrnneell:: 1. Edit your kernel configuration file. Look for or add an lpt0 entry. If you are setting up the second parallel port, use lpt1 instead. Use lpt2 for the third port, and so on. If you want interrupt-driven mode, add the irq specifier: device lpt0 at isa? port? tty irq _N vector lptintr FreeBSD Handbook 128 where _N is the IRQ number for your computer's parallel port. If you want polled mode, do not add the irq specifier: device lpt0 at isa? port? tty vector lptintr 2. Save the file. Then configure, build, and install the kernel, then reboot. See _k_e_r_n_e_l _c_o_n_f_i_g_u_r_a_t_i_o_n (section 5., page 79) for more details. TToo sseett tthhee ccoommmmuunniiccaattiioonnss mmooddee wwiitthh lptcontrol: Type lptcontrol -i -u _N to set interrupt-driven mode for lpt_N. Type lptcontrol -p -u _N to set polled-mode for lpt_N. You could put these commands in your /etc/rc.local file to set the mode each time your system boots. See lptcontrol(8) for more information. _7_._4_._2_._1_._3 _C_h_e_c_k_i_n_g _P_r_i_n_t_e_r _C_o_m_m_u_n_i_c_a_t_i_o_n_s Before proceeding to configure the spooling system, you should make sure the operating system can successfully send data to your printer. It is a lot eas ier to debug printer communication and the spooling system separately. To test the printer, we will send some text to it. For printers that can imme diately print characters sent to them, the program lptest is perfect: it gener ates all 96 printable ASCII characters in 96 lines. For a PostScript (or other language-based) printer, we will need a more sophis ticated test. A small PostScript program, such as the following, will suffice: %!PS 100 100 moveto 300 300 lineto stroke 310 310 moveto /Helvetica findfont 12 scalefont setfont (Is this thing working?) show showpage _N_o_t_e_: When this document refers to a printer language, I am assuming a language like PostScript, and not Hewlett Packard's PCL. Although PCL has great func tionality, you can intermingle plain text with its escape sequences. PostScript cannot directly print plain text, and that is the kind of printer language for which we must make special accommodations. FreeBSD Handbook 129 _7_._4_._2_._1_._3_._1 _C_h_e_c_k_i_n_g _a _P_a_r_a_l_l_e_l _P_r_i_n_t_e_r This section tells you how to check if FreeBSD can communicate with a printer connected to a parallel port. TToo tteesstt aa pprriinntteerr oonn aa ppaarraalllleell ppoorrtt:: 1. Become root with su. 2. Send data to the printer. If the printer can print plain text, then use lptest. Type: lptest > /dev/lpt_N where _N is the number of the parallel port, starting from zero. If the printer understands PostScript or other printer language, then send a small program to the printer. Type cat > /dev/lpt_N Then, line by line, type the program _c_a_r_e_f_u_l_l_y as you cannot edit a line once you have pressed RETURN or ENTER. When you have finished entering the program, press CONTROL+D, or whatever your end of file key is. Alternatively, you can put the program in a file and type cat _f_i_l_e > /dev/lpt_N where _f_i_l_e is the name of the file containing the program you want to send to the printer. You should see something print. Do not worry if the text does not look right; we will fix such things later. _7_._4_._2_._1_._3_._2 _C_h_e_c_k_i_n_g _a _S_e_r_i_a_l _P_r_i_n_t_e_r This section tells you how to check if FreeBSD can communicate with a printer on a serial port. TToo tteesstt aa pprriinntteerr oonn aa sseerriiaall ppoorrtt:: 1. Become root with su. 2. Edit the file /etc/remote. Add the following entry: printer:dv=/dev/_p_o_r_t:br#_b_p_s_-_r_a_t_e:pa=_p_a_r_i_t_y where _p_o_r_t is the device entry for the serial port (ttyd0, ttyd1, etc.), _b_p_s_-_r_a_t_e is the bits-per-second rate at which the printer communicates, and _p_a_r_i_t_y is the parity required by the printer (either even, odd, none, FreeBSD Handbook 130 or zero). Here is a sample entry for a printer connected via a serial line to the third serial port at 19200 bps with no parity: printer:dv=/dev/ttyd2:br#19200:pa=none 3. Connect to the printer with tip. Type: tip printer If this step does not work, edit the file /etc/remote again and try using /dev/cuaa_N instead of /dev/ttyd_N. 4. Send data to the printer. If the printer can print plain text, then use lptest. Type: ~$lptest If the printer understands PostScript or other printer language, then send a small program to the printer. Type the program, line by line, _v_e_r_y _c_a_r_e_f_u_l_l_y as backspacing or other editing keys may be significant to the printer. You may also need to type a special end- of-file key for the printer so it knows it received the whole pro gram. For PostScript printers, press CONTROL+D. Alternatively, you can put the program in a file and type ~>_f_i_l_e where _f_i_l_e is the name of the file containing the program. After tip sends the file, press any required end-of-file key. You should see something print. Do not worry if the text does not look right; we will fix that later. _7_._4_._2_._2 _E_n_a_b_l_i_n_g _t_h_e _S_p_o_o_l_e_r_: _T_h_e _/_e_t_c_/_p_r_i_n_t_c_a_p _F_i_l_e " At this point, your printer should be hooked up, your kernel configured to communicate with it (if necessary), and you have been able to send some simple data to the printer. Now, we are ready to configure LPD to control access to your printer. You configure LPD by editing the file /etc/printcap. The LPD spooling system reads this file each time the spooler is used, so updates to the file take immediate effect. FreeBSD Handbook 131 The format of the printcap file is straightforward. Use your favorite text editor to make changes to /etc/printcap. The format is identical to other capability files like /usr/share/misc/termcap and /etc/remote. For complete information about the format, see the cgetent(3). The simple spooler configuration consists of the following steps: 1. Pick a name (and a few convenient aliases) for the printer, and put them in the /etc/printcap file; see _N_a_m_i_n_g _t_h_e _P_r_i_n_t_e_r (section 7.4.2.2.1, page 131). 2. Turn off header pages (which are on by default) by inserting the sh capa bility; see _S_u_p_p_r_e_s_s_i_n_g _H_e_a_d_e_r _P_a_g_e_s (section 7.4.2.2.2, page 132). 3. Make a spooling directory, and specify its location with the sd capabil ity; see _M_a_k_i_n_g _t_h_e _S_p_o_o_l_i_n_g _D_i_r_e_c_t_o_r_y (section 7.4.2.2.3, page 133). 4. Set the /dev entry to use for the printer, and note it in /etc/printcap with the lp capability; see _I_d_e_n_t_i_f_y_i_n_g _t_h_e _P_r_i_n_t_e_r _D_e_v_i_c_e (section 7.4.2.2.4, page 134). Also, if the printer is on a serial port, set up the communication parameters with the fs, fc, xs, and xc capabilities; see _C_o_n_f_i_g_u_r_i_n_g _S_p_o_o_l_e_r _C_o_m_m_u_n_i_c_a_t_i_o_n_s _P_a_r_a_m_e_t_e_r_s (section 7.4.2.2.5, page 134). 5. Install a plain text input filter; see _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r (section 7.4.2.2.6, page 135) 6. Test the setup by printing something with the lpr command; see _T_r_y_i_n_g _I_t _O_u_t (section 7.4.2.2.7, page 136) and _T_r_o_u_b_l_e_s_h_o_o_t_i_n_g (section 7.4.2.2.8, page 137). _N_o_t_e_: Language-based printers, such as PostScript printers, cannot directly print plain text. The simple setup outlined above and described in the follow ing sections assumes that if you are installing such a printer you will print only files that the printer can understand. Users often expect that they can print plain text to any of the printers installed on your system. Programs that interface to LPD to do their printing usually make the same assumption. If you are installing such a printer and want to be able to print jobs in the printer language _a_n_d print plain text jobs, you are strongly urged to add an additional step to the simple setup out lined above: install an automatic plain-text--to--PostScript (or other printer language) conversion program. Section _A_c_c_o_m_m_o_d_a_t_i_n_g _P_l_a_i_n _T_e_x_t _J_o_b_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s (section 7.6.1.2, page 152) tells how to do this. _7_._4_._2_._2_._1 _N_a_m_i_n_g _t_h_e _P_r_i_n_t_e_r The first (easy) step is to pick a name for your printer. It really does not matter whether you choose functional or whimsical names since you can also pro vide a number aliases for the printer. At least one of the printers specified in the /etc/printcap should have the alias lp. This is the default printer's name. If users do not have the PRINTER environment variable nor specify a printer name on the command line of any of FreeBSD Handbook 132 the LPD commands, then lp will be the default printer they get to use. Also, it is common practice to make the last alias for a printer be a full description of the printer, including make and model. Once you have picked a name and some common aliases, put them in the /etc/printcap file. The name of the printer should start in the leftmost col umn. Separate each alias with a vertical bar and put a colon after the last alias. In the following example, we start with a skeletal /etc/printcap that defines two printers (a Diablo 630 line printer and a Panasonic KX-P4455 PostScript laser printer): # # /etc/printcap for host rose # rattan|line|diablo|lp|Diablo 630 Line Printer: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4: In this example, the first printer is named rattan and has as aliases line, diablo, lp, and Diablo 630 Line Printer. Since it has the alias lp, it is also the default printer. The second is named bamboo, and has as aliases ps, PS, S, panasonic, and Panasonic KX-P4455 PostScript v51.4. _7_._4_._2_._2_._2 _S_u_p_p_r_e_s_s_i_n_g _H_e_a_d_e_r _P_a_g_e_s The LPD spooling system will by default print a _h_e_a_d_e_r _p_a_g_e for each job. The header page contains the user name who requested the job, the host from which the job came, and the name of the job, in nice large letters. Unfortunately, all this extra text gets in the way of debugging the simple printer setup, so we will suppress header pages. To suppress header pages, add the sh capability to the entry for the printer in /etc/printcap. Here is the example /etc/printcap with sh added: # # /etc/printcap for host rose - no header pages anywhere # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh: Note how we used the correct format: the first line starts in the leftmost col umn, and subsequent lines are indented with a single TAB. Every line in an entry except the last ends in a backslash character. FreeBSD Handbook 133 _7_._4_._2_._2_._3 _M_a_k_i_n_g _t_h_e _S_p_o_o_l_i_n_g _D_i_r_e_c_t_o_r_y The next step in the simple spooler setup is to make a _s_p_o_o_l_i_n_g _d_i_r_e_c_t_o_r_y, a directory where print jobs reside until they are printed, and where a number of other spooler support files live. Because of the variable nature of spooling directories, it is customary to put these directories under /var/spool. It is not necessary to backup the contents of spooling directories, either. Recreating them is as simple as running mkdir. It is also customary to make the directory with a name that is identical to the name of the printer, as shown below: mkdir /var/spool/_p_r_i_n_t_e_r_-_n_a_m_e However, if you have a lot of printers on your network, you might want to put the spooling directories under a single directory that you reserve just for printing with LPD. We will do this for our two example printers rattan and bamboo: mkdir /var/spool/lpd mkdir /var/spool/lpd/rattan mkdir /var/spool/lpd/bamboo _N_o_t_e_: If you are concerned about the privacy of jobs that users print, you might want to protect the spooling directory so it is not publicly accessible. Spooling directories should be owned and be readable, writable, and searchable by user daemon and group daemon, and no one else. We will do this for our example printers: chown daemon.daemon /var/spool/lpd/rattan chown daemon.daemon /var/spool/lpd/bamboo chmod 770 /var/spool/lpd/rattan chmod 770 /var/spool/lpd/bamboo Finally, you need to tell LPD about these directories using the /etc/printcap file. You specify the pathname of the spooling directory with the sd capabil ity: # # /etc/printcap for host rose - added spooling directories # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo: Note that the name of the printer starts in the first column but all other entries describing the printer should be indented with a tab and each line escaped with a backslash. FreeBSD Handbook 134 If you do not specify a spooling directory with sd, the spooling system will use /var/spool/lpd as a default. _7_._4_._2_._2_._4 _I_d_e_n_t_i_f_y_i_n_g _t_h_e _P_r_i_n_t_e_r _D_e_v_i_c_e In section _A_d_d_i_n_g _/_d_e_v _E_n_t_r_i_e_s _f_o_r _t_h_e _P_o_r_t_s (section 7.4.2.1.1, page 126), we identified which entry in the /dev directory FreeBSD will use to communicate with the printer. Now, we tell LPD that information. When the spooling system has a job to print, it will open the specified device on behalf of the filter program (which is responsible for passing data to the printer). List the /dev entry pathname in the /etc/printcap file using the lp capability. In our running example, let us assume that rattan is on the first parallel port, and bamboo is on a sixth serial port; here are the additions to /etc/printcap: # # /etc/printcap for host rose - identified what devices to use # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5: If you do not specify the lp capability for a printer in your /etc/printcap file, LPD uses /dev/lp as a default. /dev/lp currently does not exist in FreeBSD. If the printer you are installing is connected to a parallel port, skip to the section _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r (section 7.4.2.2.6, page 135). Oth erwise, be sure to follow the instructions in the next section. _7_._4_._2_._2_._5 _C_o_n_f_i_g_u_r_i_n_g _S_p_o_o_l_e_r _C_o_m_m_u_n_i_c_a_t_i_o_n Parameters" For printers on serial ports, LPD can set up the bps rate, parity, and other serial communication parameters on behalf of the filter program that sends data to the printer. This is advantageous since It lets you try different communication parameters by simply editing the /etc/printcap file; you do not have to recompile the filter program. It enables the spooling system to use the same filter program for multiple printers which may have different serial communication settings. The following /etc/printcap capabilities control serial communication parame ters of the device listed in the lp capability: FreeBSD Handbook 135 br#_b_p_s_-_r_a_t_e Sets the communications speed of the device to _b_p_s_-_r_a_t_e, where _b_p_s_- _r_a_t_e can be 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, or 38400 bits-per-second. fc#_c_l_e_a_r_-_b_i_t_s Clears the flag bits _c_l_e_a_r_-_b_i_t_s in the sgttyb structure after open ing the device. fs#_s_e_t_-_b_i_t_s Sets the flag bits _s_e_t_-_b_i_t_s in the sgttyb structure. xc#_c_l_e_a_r_-_b_i_t_s Clears local mode bits _c_l_e_a_r_-_b_i_t_s after opening the device. xs#_s_e_t_-_b_i_t_s Sets local mode bits _s_e_t_-_b_i_t_s. For more information on the bits for the fc, fs, xc, and xs capabilities, see the file /usr/include/sys/ioctl_compat.h. When LPD opens the device specified by the lp capability, it reads the flag bits in the sgttyb structure; it clears any bits in the fc capability, then sets bits in the fs capability, then applies the resultant setting. It does the same for the local mode bits as well. Let us add to our example printer on the sixth serial port. We will set the bps rate to 38400. For the flag bits, we will set the TANDEM, ANYP, LITOUT, FLUSHO, and PASS8 flags. For the local mode bits, we will set the LITOUT and PASS8 flags: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000c1:xs#0x820: _7_._4_._2_._2_._6 _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r We are now ready to tell LPD what text filter to use to send jobs to the printer. A _t_e_x_t _f_i_l_t_e_r, also known as an _i_n_p_u_t _f_i_l_t_e_r, is a program that LPD runs when it has a job to print. When LPD runs the text filter for a printer, it sets the filter's standard input to the job to print, and its standard out put to the printer device specified with the lp capability. The filter is expected to read the job from standard input, perform any necessary translation for the printer, and write the results to standard output, which will get printed. For more information on the text filter, see section _F_i_l_t_e_r_s (section 7.6.1.1, page 150). For our simple printer setup, the text filter can be a small shell script that just executes /bin/cat to send the job to the printer. FreeBSD comes with another filter called lpf that handles backspacing and underlining for printers that might not deal with such character streams well. And, of course, you can use any other filter program you want. The filter lpf is described in detail in section _l_p_f_: _a _T_e_x_t _F_i_l_t_e_r (section 7.6.1.6, page 161). FreeBSD Handbook 136 First, let us make the shell script /usr/local/libexec/if-simple be a simple text filter. Put the following text into that file with your favorite text edi tor: #!/bin/sh # # if-simple - Simple text input filter for lpd # Installed in /usr/local/libexec/if-simple # # Simply copies stdin to stdout. Ignores all filter arguments. /bin/cat && exit 0 exit 2 Make the file executable: chmod 555 /usr/local/libexec/if-simple And then tell LPD to use it by specifying it with the if capability in /etc/printcap. We will add it to the two printers we have so far in the exam ple /etc/printcap: # # /etc/printcap for host rose - added text filter # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:\ :if=/usr/local/libexec/if-simple: _7_._4_._2_._2_._7 _T_r_y_i_n_g _I_t _O_u_t You have reached the end of the simple LPD setup. Unfortunately, congratula tions are not quite yet in order, since we still have to test the setup and correct any problems. To test the setup, try printing something. To print with the LPD system, you use the command lpr, which submits a job for printing. You can combine lpr with the lptest program, introduced in section _C_h_e_c_k_i_n_g _P_r_i_n_t_e_r _C_o_m_m_u_n_i_c_a_t_i_o_n_s (section 7.4.2.1.3, page 128) to generate some test text. TToo tteesstt tthhee ssiimmppllee LLPPDD sseettuupp:: Type: lptest 20 5 | lpr -P_p_r_i_n_t_e_r_-_n_a_m_e FreeBSD Handbook 137 where _p_r_i_n_t_e_r_-_n_a_m_e is a the name of a printer (or an alias) specified in /etc/printcap. To test the default printer, type lpr without any -P argument. Again, if you are testing a printer that expects PostScript, send a PostScript program in that language instead of using lptest. You can do so by putting the program in a file and typing lpr _f_i_l_e. For a PostScript printer, you should get the results of the program. If you are using lptest, then your results should look like the following: !"#$%&'()*+,-./01234 "#$%&'()*+,-./012345 #$%&'()*+,-./0123456 $%&'()*+,-./01234567 %&'()*+,-./012345678 To further test the printer, try downloading larger programs (for language- based printers) or running lptest with different arguments. For example, lptest 80 60 will produce 60 lines of 80 characters each. If the printer did not work, see the next section, _T_r_o_u_b_l_e_s_h_o_o_t_i_n_g (section 7.4.2.2.8, page 137). _7_._4_._2_._2_._8 _T_r_o_u_b_l_e_s_h_o_o_t_i_n_g After performing the simple test with lptest, you might have gotten one of the following results instead of the correct printout: It worked, after awhile; or, it did not eject a full sheet. The printer printed the above, but it sat for awhile and did noth ing. In fact, you might have needed to press a PRINT REMAINING or FORM FEED button on the printer to get any results to appear. If this is the case, the printer was probably waiting to see if there was any more data for your job before it printed anything. To fix this problem, you can have the text filter send a FORM FEED character (or whatever is necessary) to the printer. This is usu ally sufficient to have the printer immediately print any text remaining in its internal buffer. It is also useful to make sure each print job ends on a full sheet, so the next job does not start somewhere on the middle of the last page of the previous job. The following replacement for the shell script /usr/local/libexec/if-simple prints a form feed after it sends the job to the printer: FreeBSD Handbook 138 #!/bin/sh # # if-simple - Simple text input filter for lpd # Installed in /usr/local/libexec/if-simple # # Simply copies stdin to stdout. Ignores all filter arguments. # Writes a form feed character (\f) after printing job. /bin/cat && printf "\f" && exit 0 exit 2 It produced the ``staircase effect.'' You got the following on paper: !"#$%&'()*+,-./01234 "#$%&'()*+,-./012345 #$%&'()*+,-./0123456 You have become another victim of the _s_t_a_i_r_c_a_s_e _e_f_f_e_c_t, caused by conflicting interpretations of what characters should indicate a new-line. UNIX-style operating systems use a single character: ASCII code 10, the line feed (LF). MS-DOS, OS/2, and others uses a pair of characters, ASCII code 10 _a_n_d ASCII code 13 (the carriage return or CR). Many printers use the MS-DOS convention for repre senting new-lines. When you print with FreeBSD, your text used just the line feed character. The printer, upon seeing a line feed character, advanced the paper one line, but maintained the same horizontal position on the page for the next character to print. That is what the carriage return is for: to move the location of the next char acter to print to the left edge of the paper. Here is what FreeBSD wants your printer to do: Printer received CR Printer prints CR Printer received LF Printer prints CR + LF Here are some ways to achieve this: Use the printer's configuration switches or control panel to alter its interpretation of these characters. Check your printer's manual to find out how to do this. _N_o_t_e_: If you boot your system into other operating systems besides FreeBSD, you may have to _r_e_c_o_n_f_i_g_u_r_e the printer to use a an interpretation for CR and LF characters that those other operating systems use. You might prefer one of the other solutions, below. Have FreeBSD's serial line driver automatically convert LF to CR+LF. Of course, this works with printers on serial ports FreeBSD Handbook 139 _o_n_l_y. To enable this feature, set the CRMOD bit in fs capa bility in the /etc/printcap file for the printer. Send an _e_s_c_a_p_e _c_o_d_e to the printer to have it temporarily treat LF characters differently. Consult your printer's man ual for escape codes that your printer might support. When you find the proper escape code, modify the text filter to send the code first, then send the print job. Here is an example text filter for printers that understand the Hewlett-Packard PCL escape codes. This filter makes the printer treat LF characters as a LF and CR; then it sends the job; then it sends a form feed to eject the last page of the job. It should work with nearly all Hewlett Packard printers. #!/bin/sh # # hpif - Simple text input filter for lpd for HP-PCL based printers # Installed in /usr/local/libexec/hpif # # Simply copies stdin to stdout. Ignores all filter arguments. # Tells printer to treat LF as CR+LF. Writes a form feed character # after printing job. printf "\033&k2G" && cat && printf "\f" && exit 0 exit 2 Here is an example /etc/printcap from a host called orchid. It has a single printer attached to its first parallel port, a Hewlett Packard LaserJet 3Si named teak. It is using the above script as its text filter: # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif: It overprinted each line. The printer never advanced a line. All of the lines of text were printed on top of each other on one line. This problem is the ``opposite'' of the staircase effect, described above, and is much rarer. Somewhere, the LF characters that FreeBSD uses to end a line are being treated as CR characters to return the print location to the left edge of the paper, but not also down a line. Use the printer's configuration switches or control panel to enforce the following interpretation of LF and CR characters: Printer received CR Printer prints CR FreeBSD Handbook 140 Printer received LF Printer prints CR + LF The printer lost characters. While printing, the printer did not print a few characters in each line. The problem might have gotten worse as the printer ran, los ing more and more characters. The problem is that the printer cannot keep up with the speed at which the computer sends data over a serial line. (This problem should not occur with printers on parallel ports.) There are two ways to overcome the problem: If the printer supports XON/XOFF flow control, have FreeBSD use it by specifying the TANDEM bit in the fs capability. If the printer supports carrier flow control, specify the MDM BUF bit in the fs capability. Make sure the cable connecting the printer to the computer is correctly wired for carrier flow control. If the printer does not support any flow control, use some combination of the NLDELAY, TBDELAY, CRDELAY, VTDELAY, and BSDELAY bits in the fs capability to add appropriate delays to the stream of data sent to the printer. It printed garbage. The printer printed what appeared to be random garbage, but not the desired text. This is usually another symptom of incorrect communications parame ters with a serial printer. Double-check the bps rate in the br capability, and the parity bits in the fs and fc capabilities; make sure the printer is using the same settings as specified in the /etc/printcap file. Nothing happened. If nothing happened, the problem is probably within FreeBSD and not the hardware. Add the log file (lf) capability to the entry for the printer you are debugging in the /etc/printcap file. For exam ple, here is the entry for rattan, with the lf capability: rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple:\ :lf=/var/log/rattan.log Then, try printing again. Check the log file (in our example, /var/log/rattan.log) to see any error messages that might appear. Based on the messages you see, try to correct the problem. If you do not specify a lf capability, LPD uses /dev/console as a default. FreeBSD Handbook 141 _7_._5 _U_s_i_n_g _P_r_i_n_t_e_r_s This section tells you how to use printers you have setup with FreeBSD. Here is an overview of the user-level commands: lpr Print jobs lpq Check printer queues lprm Remove jobs from a printer's queue There is also an administrative command, lpc, described in the section _A_d_m_i_n_i_s_ _t_r_a_t_i_n_g _t_h_e _L_P_D _S_p_o_o_l_e_r (section 7.5.5, page 147), used to control printers and their queues. All three of the commands lpr, lprm, and lpq accept an option ``-P _p_r_i_n_t_e_r_- _n_a_m_e'' to specify on which printer/queue to operate, as listed in the /etc/printcap file. This enables you to submit, remove, and check on jobs for various printers. If you do not use the -P option, then these commands use the printer specified in the PRINTER environment variable. Finally, if you do not have a PRINTER environment variable, these commands default to the printer named lp. Hereafter, the terminology _d_e_f_a_u_l_t _p_r_i_n_t_e_r means the printer named in the PRINTER environment variable, or the printer named lp when there is no PRINTER environment variable. _7_._5_._1 _P_r_i_n_t_i_n_g _J_o_b_s To print files, type lpr _f_i_l_e_n_a_m_e_._._. This prints each of the listed files to the default printer. If you list no files, lpr reads data to print from standard input. For example, this command prints some important system files: lpr /etc/host.conf /etc/hosts.equiv To select a specific printer, type lpr -P _p_r_i_n_t_e_r_-_n_a_m_e _f_i_l_e_n_a_m_e_._._. This example prints a long listing of the current directory to the printer named rattan: ls -l | lpr -P rattan FreeBSD Handbook 142 Because no files were listed for the lpr command, lpr read the data to print from standard input, which was the output of the ls -l command. The lpr command can also accept a wide variety of options to control format ting, apply file conversions, generate multiple copies, and so forth. For more information, see the section _P_r_i_n_t_i_n_g _O_p_t_i_o_n_s (section 7.5.4, page 144). _7_._5_._2 _C_h_e_c_k_i_n_g _J_o_b_s When you print with lpr, the data you wish to print is put together in a pack age called a _p_r_i_n_t _j_o_b, which is sent to the LPD spooling system. Each printer has a queue of jobs, and your job waits in that queue along with other jobs from yourself and from other users. The printer prints those jobs in a first- come, first-served order. To display the queue for the default printer, type lpq. For a specific printer, use the -P option. For example, the command lpq -P bamboo shows the queue for the printer named bamboo. Here is an example of the output of the lpq command: bamboo is ready and printing Rank Owner Job Files Total Size active kelly 9 /etc/host.conf, /etc/hosts.equiv 88 bytes 2nd kelly 10 (standard input) 1635 bytes 3rd mary 11 ... 78519 bytes This shows three jobs in the queue for bamboo. The first job, submitted by user kelly, got assigned _j_o_b _n_u_m_b_e_r 9. Every job for a printer gets a unique job number. Most of the time you can ignore the job number, but you will need it if you want to cancel the job; see section _R_e_m_o_v_i_n_g _J_o_b_s (section 7.5.3, page 143) for details. Job number nine consists of two files; multiple files given on the lpr command line are treated as part of a single job. It is the currently active job (note the word active under the ``Rank'' column), which means the printer should be currently printing that job. The second job consists of data passed as the standard input to the lpr command. The third job came from user mary; it is a much larger job. The pathname of the files she's trying to print is too long to fit, so the lpq com mand just shows three dots. The very first line of the output from lpq is also useful: it tells what the printer is currently doing (or at least what LPD thinks the printer is doing). The lpq command also support a -l option to generate a detailed long listing. Here is an example of lpq -l: FreeBSD Handbook 143 waiting for bamboo to become ready (offline ?) kelly: 1st [job 009rose] /etc/host.conf 73 bytes /etc/hosts.equiv 15 bytes kelly: 2nd [job 010rose] (standard input) 1635 bytes mary: 3rd [job 011rose] /home/orchid/mary/research/venus/alpha-regio/mapping 78519 bytes _7_._5_._3 _R_e_m_o_v_i_n_g _J_o_b_s If you change your mind about printing a job, you can remove the job from the queue with the lprm command. Often, you can even use lprm to remove an active job, but some or all of the job might still get printed. To remove a job from the default printer, first use lpq to find the job number. Then type lprm _j_o_b_-_n_u_m_b_e_r To remove the job from a specific printer, add the -P option. The following command removes job number 10 from the queue for the printer bamboo: lprm -P bamboo 10 The lprm command has a few shortcuts: lprm - Removes all jobs (for the default printer) belonging to you. lprm _u_s_e_r Removes all jobs (for the default printer) belonging to _u_s_e_r. The superuser can remove other users' jobs; you can remove only your own jobs. lprm With no job number, user name, or ``-'' appearing on the command line, lprm removes the currently active job on the default printer, if it belongs to you. The superuser can remove any active job. Just use the -P option with the above shortcuts to operate on a specific printer instead of the default. For example, the following command removes all jobs for the current user in the queue for the printer named rattan: lprm -P rattan - _N_o_t_e_: If you are working in a networked environment, lprm will let you remove jobs only from the host from which the jobs were FreeBSD Handbook 144 submitted, even if the same printer is available from other hosts. The follow ing command sequence demonstrates this: rose% lpr -P rattan myfile rose% rlogin orchid orchid% lpq -P rattan Rank Owner Job Files Total Size active seeyan 12 ... 49123 bytes 2nd kelly 13 myfile 12 bytes orchid% lprm -P rattan 13 rose: Permission denied orchid% logout rose% lprm -P rattan 13 dfA013rose dequeued cfA013rose dequeued rose% _7_._5_._4 _B_e_y_o_n_d _P_l_a_i_n _T_e_x_t_: _P_r_i_n_t_i_n_g _O_p_t_i_o_n_s The lpr command supports a number of options that control formatting text, converting graphic and other file formats, producing multiple copies, handling of the job, and more. This section describes the options. _7_._5_._4_._1 _F_o_r_m_a_t_t_i_n_g _a_n_d _C_o_n_v_e_r_s_i_o_n _O_p_t_i_o_n_s The following lpr options control formatting of the files in the job. Use these options if the job does not contain plain text or if you want plain text formatted through the pr utility. For example, the following command prints a DVI file (from the TeX typesetting system) named fish-report.dvi to the printer named bamboo: lpr -P bamboo -d fish-report.dvi These options apply to every file in the job, so you cannot mix (say) DVI and ditroff files together in a job. Instead, submit the files as separate jobs, using a different conversion option for each job. _N_o_t_e_: All of these options except -p and -T require conversion filters installed for the destination printer. For example, the -d option requires the DVI conversion filter. Section _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s (section 7.6.1.4, page 154) gives details. -c Print cifplot files. -d Print DVI files. -f Print FORTRAN text files. FreeBSD Handbook 145 -g Print plot data. -i _n_u_m_b_e_r Indent the output by _n_u_m_b_e_r columns; if you omit _n_u_m_b_e_r, indent by 8 columns. This option works only with certain conversion filters. _N_o_t_e_: Do not put any space between the -i and the number. -l Print literal text data, including control characters. -n Print ditroff (device independent troff) data. -p Format plain text with pr before printing. See pr(1) for more information. -T _t_i_t_l_e Use _t_i_t_l_e on the pr header instead of the file name. This option has effect only when used with the -p option. -t Print troff data. -v Print raster data. Here is an example: this command prints a nicely formatted version of the ls manual page on the default printer: zcat /usr/share/man/man1/ls.1.gz | troff -t -man | lpr -t The zcat command uncompresses the source of the ls manual page and passes it to the troff command, which formats that source and makes GNU troff output and passes it to lpr, which submits the job to the LPD spooler. Because we used the -t option to lpr, the spooler will convert the GNU troff output into a format the default printer can understand when it prints the job. _7_._5_._4_._2 _J_o_b _H_a_n_d_l_i_n_g _O_p_t_i_o_n_s The following options to lpr tell LPD to handle the job specially: -# _c_o_p_i_e_s Produce a number of _c_o_p_i_e_s of each file in the job instead of just one copy. An administrator may disable this option to reduce printer wear-and-tear and encourage photocopier usage. See section _R_e_s_t_r_i_c_t_i_n_g _M_u_l_t_i_p_l_e _C_o_p_i_e_s (section 7.6.4.1, page 172). FreeBSD Handbook 146 This example prints three copies of parser.c followed by three copies of parser.h to the default printer: lpr -#3 parser.c parser.h -m Send mail after completing the print job. With this option, the LPD system will send mail to your account when it finishes handling your job. In its message, it will tell you if the job completed successfully or if there was an error, and (often) what the error was. -s Do not copy the files to the spooling directory, but make symbolic links to them instead. If you are printing a large job, you probably want to use this option. It saves space in the spooling directory (your job might overflow the free space on the filesystem where the spooling direc tory resides). It saves time as well since LPD will not have to copy each and every byte of your job to the spooling directory. There is a drawback, though: since LPD will refer to the original files directly, you cannot modify or remove them until they have been printed. _N_o_t_e_: If you are printing to a remote printer, LPD will eventually have to copy files from the local host to the remote host, so the -s option will save space only on the local spooling directory, not the remote. It is still useful, though. -r Remove the files in the job after copying them to the spooling directory, or after printing them with the -s option. Be careful with this option! _7_._5_._4_._3 _H_e_a_d_e_r _P_a_g_e _O_p_t_i_o_n_s These options to lpr adjust the text that normally appears on a job's header page. If header pages are suppressed for the destination printer, these options have no effect. See section _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2, page 162) for information about setting up header pages. -C _t_e_x_t Replace the hostname on the header page with _t_e_x_t. The hostname is normally the name of the host from which the job was submitted. -J _t_e_x_t Replace the job name on the header page with _t_e_x_t. The job name is normally the name of the first file of the job, or ``stdin'' if you are printing standard input. -h Do not print any header page. _N_o_t_e_: At some sites, this option may FreeBSD Handbook 147 have no effect due to the way header pages are generated. See _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2, page 162) for details. _7_._5_._5 _A_d_m_i_n_i_s_t_r_a_t_i_n_g _P_r_i_n_t_e_r_s As an administrator for your printers, you have had to install, set up, and test them. Using the lpc command, you can interact with your printers in yet more ways. With lpc, you can Start and stop the printers Enable and disable their queues Rearrange the order of the jobs in each queue. First, a note about terminology: if a printer is _s_t_o_p_p_e_d, it will not print anything in its queue. Users can still submit jobs, which will wait in the queue until the printer is _s_t_a_r_t_e_d or the queue is cleared. If a queue is _d_i_s_a_b_l_e_d, no user (except root) can submit jobs for the printer. An _e_n_a_b_l_e_d queue allows jobs to be submitted. A printer can be _s_t_a_r_t_e_d for a disabled queue, in which case it will continue to print jobs in the queue until the queue is empty. In general, you have to have root privileges to use the lpc command. Ordinary users can use the lpc command to get printer status and to restart a hung printer only. Here is a summary of the lpc commands. Most of the commands takes a _p_r_i_n_t_e_r_- _n_a_m_e argument to tell on which printer to operate. You can use all for the _p_r_i_n_t_e_r_-_n_a_m_e to mean all printers listed in /etc/printcap. abort _p_r_i_n_t_e_r_-_n_a_m_e Cancel the current job and stop the printer. Users can still sub mit jobs if the queue's enabled. clean _p_r_i_n_t_e_r_-_n_a_m_e Remove old files from the printer's spooling directory. Occasion ally, the files that make up a job are not properly removed by LPD, particularly if there have been errors during printing or a lot of administrative activity. This command finds files that do not belong in the spooling directory and removes them. disable _p_r_i_n_t_e_r_-_n_a_m_e Disable queuing of new jobs. If the printer's started, it will continue to print any jobs remaining in the queue. The superuser (root) can always submit jobs, even to a disabled queue. This command is useful while you are testing a new printer or fil ter installation: disable the queue and submit jobs as root. Other users will not be able to submit jobs until you complete your FreeBSD Handbook 148 testing and re-enable the queue with the enable command. down _p_r_i_n_t_e_r_-_n_a_m_e _m_e_s_s_a_g_e_._._. Take a printer down. Equivalent to disable followed by stop. The _m_e_s_s_a_g_e appears as the printer's status whenever a user checks the printer's queue with lpq or status with lpc status. enable _p_r_i_n_t_e_r_-_n_a_m_e Enable the queue for a printer. Users can submit jobs but the printer will not print anything until it is started. help _c_o_m_m_a_n_d_-_n_a_m_e Print help on the command _c_o_m_m_a_n_d_-_n_a_m_e. With no _c_o_m_m_a_n_d_-_n_a_m_e, print a summary of the commands available. restart _p_r_i_n_t_e_r_-_n_a_m_e Start the printer. Ordinary users can use this command if some extraordinary circumstance hangs LPD, but they cannot start a printer stopped with either the stop or down commands. The restart command is equivalent to abort followed by start. start _p_r_i_n_t_e_r_-_n_a_m_e Start the printer. The printer will print jobs in its queue. stop _p_r_i_n_t_e_r_-_n_a_m_e Stop the printer. The printer will finish the current job and will not print anything else in its queue. Even though the printer is stopped, users can still submit jobs to an enabled queue. topq _p_r_i_n_t_e_r_-_n_a_m_e _j_o_b_-_o_r_-_u_s_e_r_n_a_m_e_._._. Rearrange the queue for _p_r_i_n_t_e_r_-_n_a_m_e by placing the jobs with the listed _j_o_b numbers or the jobs belonging to _u_s_e_r_n_a_m_e at the top of the queue. For this command, you cannot use all as the _p_r_i_n_t_e_r_- _n_a_m_e. up _p_r_i_n_t_e_r_-_n_a_m_e Bring a printer up; the opposite of the down command. Equivalent to start followed by enable. lpc accepts the above commands on the command line. If you do not enter any commands, lpc enters an interactive mode, where you can enter commands until you type exit, quit, or end-of-file. _7_._6 _A_d_v_a_n_c_e_d _P_r_i_n_t_e_r _S_e_t_u_p This section describes filters for printing specially formatted files, header pages, printing across networks, and restricting and accounting for printer usage. _7_._6_._1 _F_i_l_t_e_r_s Although LPD handles network protocols, queuing, access control, and other aspects of printing, most of the _r_e_a_l work happens in the _f_i_l_t_e_r_s. Filters are programs that communicate with the printer and handle its device dependencies FreeBSD Handbook 149 and special requirements. In the simple printer setup, we installed a plain text filter---an extremely simple one that should work with most printers (sec tion _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r (section 7.4.2.2.6, page 135)). However, in order to take advantage of format conversion, printer accounting, specific printer quirks, and so on, you should understand how filters work. It will ultimately be the filter's responsibility to handle these aspects. And the bad news is that most of the time _y_o_u have to provide filters yourself. The good news is that many are generally available; when they are not, they are usually easy to write. Also, FreeBSD comes with one, /usr/libexec/lpr/lpf, that works with many print ers that can print plain text. (It handles backspacing and tabs in the file, and does accounting, but that is about all it does.) There are also several filters and filter components in the FreeBSD ports collection. Here is what you will find in this section: Section _H_o_w _F_i_l_t_e_r_s _W_o_r_k (section 7.6.1.1, page 150), tries to give an overview of a filter's role in the printing process. You should read this section to get an understanding of what is happening ``under the hood'' when LPD uses filters. This knowledge could help you anticipate and debug problems you might encounter as you install more and more filters on each of your printers. LPD expects every printer to be able to print plain text by default. This presents a problem for PostScript (or other language-based printers) which cannot directly print plain text. Section _A_c_c_o_m_m_o_d_a_t_i_n_g _P_l_a_i_n _T_e_x_t _J_o_b_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s (section 7.6.1.2, page 152) tells you what you should do to overcome this problem. I recommend reading this section if you have a PostScript printer. PostScript is a popular output format for many programs. Even some people (myself included) write PostScript code directly. But PostScript printers are expensive. Section _S_i_m_u_l_a_t_i_n_g _P_o_s_t_S_c_r_i_p_t _o_n _N_o_n_-_P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s (section 7.6.1.3, page 153) tells how you can further modify a printer's text filter to accept and print PostScript data on a _n_o_n_-_P_o_s_t_S_c_r_i_p_t printer. I recommend reading this section if you do not have a PostScript printer. Section _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s (section 7.6.1.4, page 154) tells about a way you can automate the conversion of specific file formats, such as graphic or typesetting data, into formats your printer can understand. After reading this section, you should be able to set up your printers such that users can type lpr -t to print troff data, or lpr -d to print TeX DVI data, or lpr -v to print raster image data, and so forth. I recommend reading this section. Section _O_u_t_p_u_t _F_i_l_t_e_r_s (section 7.6.1.5, page 160) tells all about a not often used feature of LPD: output filters. Unless you are printing header pages (see _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2, page 162)), you can probably skip that section altogether. FreeBSD Handbook 150 Section _l_p_f_: _a _T_e_x_t _F_i_l_t_e_r (section 7.6.1.6, page 161) describes lpf, a fairly complete if simple text filter for line printers (and laser print ers that act like line printers) that comes with FreeBSD. If you need a quick way to get printer accounting working for plain text, or if you have a printer which emits smoke when it sees backspace characters, you should definitely consider lpf. _7_._6_._1_._1 _H_o_w _F_i_l_t_e_r_s _W_o_r_k As mentioned before, a filter is an executable program started by LPD to han dle the device-dependent part of communicating with the printer. When LPD wants to print a file in a job, it starts a filter program. It sets the filter's standard input to the file to print, its standard output to the printer, and its standard error to the error logging file (specified in the lf capability in /etc/printcap, or /dev/console by default). Which filter LPD starts and the filter's arguments depend on what is listed in the /etc/printcap file and what arguments the user specified for the job on the lpr command line. For example, if the user typed lpr -t, LPD would start the troff filter, listed in the tf capability for the destination printer. If the user wanted to print plain text, it would start the if filter (this is mostly true: see _O_u_t_p_u_t _F_i_l_t_e_r_s (section 7.6.1.5, page 160) for details). There are three kinds of filters you can specify in /etc/printcap: The _t_e_x_t _f_i_l_t_e_r, confusingly called the _i_n_p_u_t _f_i_l_t_e_r in LPD documentation, handles regular text printing. Think of it as the default filter. LPD expects every printer to be able to print plain text by default, and it is the text filter's job to make sure backspaces, tabs, or other special characters do not confuse the printer. If you are in an environment where you have to account for printer usage, the text filter must also account for pages printed, usually by counting the number of lines printed and comparing that to the number of lines per page the printer supports. The text filter is started with the following argument list: [-c] -w_w_i_d_t_h -l_l_e_n_g_t_h -i_i_n_d_e_n_t -n _l_o_g_i_n -h _h_o_s_t _a_c_c_t_-_f_i_l_e where -c appears if the job's submitted with lpr -l _w_i_d_t_h is the value from the pw (page width) capability specified in /etc/printcap, default 132 _l_e_n_g_t_h is the value from the pl (page length) capability, default 66 FreeBSD Handbook 151 _i_n_d_e_n_t is the amount of the indentation from lpr -i, default 0 _l_o_g_i_n is the account name of the user printing the file _h_o_s_t is the host name from which the job was submitted _a_c_c_t_-_f_i_l_e is the name of the accounting file from the af capability. A _c_o_n_v_e_r_s_i_o_n _f_i_l_t_e_r converts a specific file format into one the printer can render onto paper. For example, ditroff typesetting data cannot be directly printed, but you can install a conversion filter for ditroff files to convert the ditroff data into a form the printer can digest and print. Section _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s (section 7.6.1.4, page 154) tells all about them. Conversion filters also need to do accounting, if you need printer accounting. Conversion filters are started with the following arguments: -x_p_i_x_e_l_-_w_i_d_t_h -y_p_i_x_e_l_-_h_e_i_g_h_t -n _l_o_g_i_n -h _h_o_s_t _a_c_c_t_-_f_i_l_e where _p_i_x_e_l_-_w_i_d_t_h is the value from the px capability (default 0) and _p_i_x_e_l_-_h_e_i_g_h_t is the value from the py capability (default 0). The _o_u_t_p_u_t _f_i_l_t_e_r is used only if there is no text filter, or if header pages are enabled. In my experience, output filters are rarely used. Section _O_u_t_p_u_t _F_i_l_t_e_r_s (section 7.6.1.5, page 160) describe them. There are only two arguments to an output filter: -w_w_i_d_t_h -l_l_e_n_g_t_h which are identical to the text filters -w and -l arguments. Filters should also _e_x_i_t with the following exit status: exit 0 If the filter printed the file successfully. exit 1 If the filter failed to print the file but wants LPD to try to print the file again. LPD will restart a filter if it exits with this status. exit 2 If the filter failed to print the file and does not want LPD to try again. LPD will throw out the file. The text filter that comes with the FreeBSD release, /usr/libexec/lpr/lpf, FreeBSD Handbook 152 takes advantage of the page width and length arguments to determine when to send a form feed and how to account for printer usage. It uses the login, host, and accounting file arguments to make the accounting entries. If you are shopping for filters, see if they are LPD-compatible. If they are, they must support the argument lists described above. If you plan on writing filters for general use, then have them support the same argument lists and exit codes. _7_._6_._1_._2 _A_c_c_o_m_m_o_d_a_t_i_n_g _P_l_a_i_n _T_e_x_t _J_o_b_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s " If you are the only user of your computer and PostScript (or other language- based) printer, and you promise to never send plain text to your printer and to never use features of various programs that will want to send plain text to your printer, then you do not need to worry about this section at all. But, if you would like to send both PostScript and plain text jobs to the printer, then you are urged to augment your printer setup. To do so, we have the text filter detect if the arriving job is plain text or PostScript. All PostScript jobs must start with %! (for other printer languages, see your printer documentation). If those are the first two characters in the job, we have PostScript, and can pass the rest of the job directly. If those are not the first two characters in the file, then the filter will convert the text into PostScript and print the result. How do we do this? If you have got a serial printer, a great way to do it is to install lprps. lprps is a PostScript printer filter which performs two-way communication with the printer. It updates the printer's status file with verbose information from the printer, so users and administrators can see exactly what the state of the printer is (such as ``toner low'' or ``paper jam''). But more importantly, it includes a program called psif which detects whether the incoming job is plain text and calls textps (another program that comes with lprps) to convert it to PostScript. It then uses lprps to send the job to the printer. lprps is part of the FreeBSD ports collection (see _T_h_e _P_o_r_t_s _C_o_l_l_e_c_t_i_o_n (sec tion 4., page 25)). You can fetch, build and install it yourself, of course. After installing lprps, just specify the pathname to the psif program that is part of lprps. If you installed lprps from the ports collection, use the fol lowing in the serial PostScript printer's entry in /etc/printcap: :if=/usr/local/libexec/psif: You should also specify the rw capability; that tells LPD to open the printer in read-write mode. If you have a parallel PostScript printer (and therefore cannot use two-way communication with the printer, which lprps needs), you can use the following shell script as the text filter: FreeBSD Handbook 153 #!/bin/sh # # psif - Print PostScript or plain text on a PostScript printer # Script version; NOT the version that comes with lprps # Installed in /usr/local/libexec/psif # read first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # PostScript job, print it. # echo $first_line && cat && printf "\004" && exit 0 exit 2 else # # Plain text, convert it, then print it. # ( echo $first_line; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 exit 2 fi In the above script, textps is a program we installed separately to convert plain text to PostScript. You can use any text-to-PostScript program you wish. The FreeBSD ports collection (see _T_h_e _P_o_r_t_s _C_o_l_l_e_c_t_i_o_n (section 4., page 25)) includes a full featured text-to-PostScript program called a2ps that you might want to investigate. _7_._6_._1_._3 _S_i_m_u_l_a_t_i_n_g _P_o_s_t_S_c_r_i_p_t _o_n _N_o_n_-_P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s " PostScript is the _d_e _f_a_c_t_o standard for high quality typesetting and printing. PostScript is, however, an _e_x_p_e_n_s_i_v_e standard. Thankfully, Alladin Enterprises has a free PostScript work-alike called _G_h_o_s_t_s_c_r_i_p_t that runs with FreeBSD. Ghostscript can read most PostScript files and can render their pages onto a variety of devices, including many brands of non-PostScript printers. By installing Ghostscript and using a special text filter for your printer, you can make your non-PostScript printer act like a real PostScript printer. Ghostscript should be in the FreeBSD ports collection, if you would like to install it from there. You can fetch, build, and install it quite easily your self, as well. To simulate PostScript, we have the text filter detect if it is printing a PostScript file. If it is not, then the filter will pass the file directly to the printer; otherwise, it will use Ghostscript to first convert the file into a format the printer will understand. Here is an example: the following script is a text filter for Hewlett Packard DeskJet 500 printers. For other printers, substitute the -sDEVICE argument to FreeBSD Handbook 154 the gs (Ghostscript) command. (Type gs -h to get a list of devices the current installation of Ghostscript supports.) #!/bin/sh # # ifhp - Print Ghostscript-simulated PostScript on a DeskJet 500 # Installed in /usr/local/libexec/hpif # # Treat LF as CR+LF: # printf "\033&k2G" || exit 2 # # Read first two characters of the file # read first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # It is PostScript; use Ghostscript to scan-convert and print it # /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 -sOutputFile=- - \ && exit 0 else # # Plain text or HP/PCL, so just print it directly; print a form # at the end to eject the last page. # echo $first_line && cat && printf "\f" && exit 0 fi exit 2 Finally, you need to notify LPD of the filter via the if capability: :if=/usr/local/libexec/hpif: That is it. You can type lpr plain.text and lpr whatever.ps and both should print successfully. _7_._6_._1_._4 _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s After completing the simple setup described in _S_i_m_p_l_e _P_r_i_n_t_e_r _S_e_t_u_p (section 7.4, page 123), the first thing you will probably want to do is install conver sion filters for your favorite file formats (besides plain ASCII text). FreeBSD Handbook 155 _7_._6_._1_._4_._1 _W_h_y _I_n_s_t_a_l_l _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s_? Conversion filters make printing various kinds of files easy. As an example, suppose we do a lot of work with the TeX typesetting system, and we have a PostScript printer. Every time we generate a DVI file from TeX, we cannot print it directly until we convert the DVI file into PostScript. The command sequence goes like this: dvips seaweed-analysis.dvi lpr seaweed-analysis.ps By installing a conversion filter for DVI files, we can skip the hand conver sion step each time by having LPD do it for us. Now, each time we get a DVI file, we are just one step away from printing it: lpr -d seaweed-analysis.dvi We got LPD to do the DVI file conversion for us by specifying the -d option. Section _F_o_r_m_a_t_t_i_n_g _a_n_d _C_o_n_v_e_r_s_i_o_n _O_p_t_i_o_n_s (section 7.5.4.1, page 144) lists the conversion options. For each of the conversion options you want a printer to support, install a _c_o_n_v_e_r_s_i_o_n _f_i_l_t_e_r and specify its pathname in /etc/printcap. A conversion fil ter is like the text filter for the simple printer setup (see section _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r (section 7.4.2.2.6, page 135)) except that instead of printing plain text, the filter converts the file into a format the printer can understand. _7_._6_._1_._4_._2 _W_h_i_c_h _C_o_n_v_e_r_s_i_o_n_s _F_i_l_t_e_r_s _S_h_o_u_l_d _I _I_n_s_t_a_l_l_? " You should install the conversion filters you expect to use. If you print a lot of DVI data, then a DVI conversion filter is in order. If you have got plenty of troff to print out, then you probably want a troff filter. The following table summarizes the filters that LPD works with, their capabil ity entries for the /etc/printcap file, and how to invoke them with the lpr command: /etc/printcap File type Capability lpr option ------------ ------------- ---------- cifplot cf -c DVI df -d plot gf -g ditroff nf -n FORTRAN text rf -f troff tf -t raster vf -v plain text if none, -p, or -l FreeBSD Handbook 156 In our example, using lpr -d means the printer needs a df capability in its entry in /etc/printcap. Despite what others might contend, formats like FORTRAN text and plot are prob ably obsolete. At your site, you can give new meanings to these or any of the formatting options just by installing custom filters. For example, suppose you would like to directly print Printerleaf files (files from the Interleaf desk top publishing program), but will never print plot files. You could install a Printerleaf conversion filter under the gf capability and then educate your users that lpr -g mean ``print Printerleaf files.'' _7_._6_._1_._4_._3 _I_n_s_t_a_l_l_i_n_g _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s Since conversion filters are programs you install outside of the base FreeBSD installation, they should probably go under /usr/local. The directory /usr/local/libexec is a popular location, since they are specialized programs that only LPD will run; regular users should not ever need to run them. To enable a conversion filter, specify its pathname under the appropriate capa bility for the destination printer in /etc/printcap. In our example, we will add the DVI conversion filter to the entry for the printer named bamboo. Here is the example /etc/printcap file again, with the new df capability for the printer bamboo # # /etc/printcap for host rose - added df filter for bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: The DVI filter is a shell script named /usr/local/libexec/psdf. Here is that script: #!bin/sh # # psdf - DVI to PostScript printer filter # Installed in /usr/local/libexec/psdf # # Invoked by lpd when user runs lpr -d # exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@" This script runs dvips in filter mode (the -f argument) on standard input, FreeBSD Handbook 157 which is the job to print. It then starts the PostScript printer filter lprps (see section _A_c_c_o_m_m_o_d_a_t_i_n_g _P_l_a_i_n _T_e_x_t _J_o_b_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s (sec tion 7.6.1.2, page 152)) with the arguments LPD passed to this script. lprps will use those arguments to account for the pages printed. _7_._6_._1_._4_._4 _M_o_r_e _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r _E_x_a_m_p_l_e_s Since there is no fixed set of steps to install conversion filters, let me instead provide more examples. Use these as guidance to making your own fil ters. Use them directly, if appropriate. This example script is a raster (well, GIF file, actually) conversion filter for a Hewlett Packard LaserJet III-Si printer: #!/bin/sh # # hpvf - Convert GIF files into HP/PCL, then print # Installed in /usr/local/libexec/hpvf PATH=/usr/X11R6/bin:$PATH; export PATH giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ && exit 0 \ || exit 2 It works by converting the GIF file into a portable anymap, converting that into a portable graymap, converting that into a portable bitmap, and converting that into LaserJet/PCL-compatible data. Here is the /etc/printcap file with an entry for a printer using the above fil ter: # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf: The following script is a conversion filter for troff data from the groff type setting system for the PostScript printer named bamboo: #!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops | /usr/local/libexec/lprps "$@" The above script makes use of lprps again to handle the communication with the printer. If the printer were on a parallel port, we would use this script FreeBSD Handbook 158 instead: #!/bin/sh # # pstf - Convert groff's troff data into PS, then print. # Installed in /usr/local/libexec/pstf # exec grops That is it. Here is the entry we need to add to /etc/printcap to enable the filter: :tf=/usr/local/libexec/pstf: Here is an example that might make old hands at FORTRAN blush. It is a FOR TRAN-text filter for any printer that can directly print plain text. We will install it for the printer teak: #!/bin/sh # # hprf - FORTRAN text filter for LaserJet 3si: # Installed in /usr/local/libexec/hprf # printf "\033&k2G" && fpr && printf "\f" && exit 0 exit 2 And we will add this line to the /etc/printcap for the printer teak to enable this filter: :rf=/usr/local/libexec/hprf: Here is one final, somewhat complex example. We will add a DVI filter to the LaserJet printer teak introduced earlier. First, the easy part: updating /etc/printcap with the location of the DVI filter: :df=/usr/local/libexec/hpdf: Now, for the hard part: making the filter. For that, we need a DVI-to-Laser Jet/PCL conversion program. The FreeBSD ports collection (see _T_h_e _P_o_r_t_s _C_o_l_l_e_c_t_i_o_n (section 4., page 25)) has one: dvi2xx is the name of the package. Installing this package gives us the program we need, dvilj2p, which converts DVI into LaserJet IIp, LaserJet III, and LaserJet 2000 compatible codes. dvilj2p makes the filter hpdf quite complex since dvilj2p cannot read from standard input. It wants to work with a filename. What is worse, the filename has to end in .dvi so using /dev/fd/0 for standard input is problematic. We can get around that problem by linking (symbolically) a temporary file name (one that ends in .dvi) to /dev/fd/0, thereby forcing dvilj2p to read from standard input. The only other fly in the ointment is the fact that we cannot use /tmp for the FreeBSD Handbook 159 temporary link. Symbolic links are owned by user and group bin. The filter runs as user daemon. And the /tmp directory has the sticky bit set. The fil ter can create the link, but it will not be able clean up when done and remove it since the link will belong to a different user. Instead, the filter will make the symbolic link in the current working direc tory, which is the spooling directory (specified by the sd capability in /etc/printcap). This is a perfect place for filters to do their work, espe cially since there is (sometimes) more free disk space in the spooling direc tory than under /tmp. Here, finally, is the filter: #!/bin/sh # # hpdf - Print DVI data on HP/PCL printer # Installed in /usr/local/libexec/hpdf PATH=/usr/local/bin:$PATH; export PATH # # Define a function to clean up our temporary files. These exist # in the current directory, which will be the spooling directory # for the printer. # cleanup() { rm -f hpdf$$.dvi } # # Define a function to handle fatal errors: print the given message # and exit 2. Exiting with 2 tells LPD to do not try to reprint the # job. # fatal() { echo "$@" 1>&2 cleanup exit 2 } # # If user removes the job, LPD will send SIGINT, so trap SIGINT # (and a few other signals) to clean up after ourselves. # trap cleanup 1 2 15 # # Make sure we are not colliding with any existing files. # cleanup # # Link the DVI input file to standard input (the file to print). # FreeBSD Handbook 160 ln -s /dev/fd/0 hpdf$$.dvi || fatal "Cannot symlink /dev/fd/0" # # Make LF = CR+LF # printf "\033&k2G" || fatal "Cannot initialize printer" # # Convert and print. Return value from dvilj2p does not seem to be # reliable, so we ignore it. # dvilj2p -M1 -q -e- dfhp$$.dvi # # Clean up and exit # cleanup exit 0 _7_._6_._1_._4_._5 _A_u_t_o_m_a_t_e_d _C_o_n_v_e_r_s_i_o_n_: _A_n _A_l_t_e_r_n_a_t_i_v_e _T_o _C_o_n_v_e_r_s_i_o_n _F_i_l_t_e_r_s " All these conversion filters accomplish a lot for your printing environment, but at the cost forcing the user to specify (on the lpr command line) which one to use. If your users are not particularly computer literate, having to spec ify a filter option will become annoying. What is worse, though, is that an incorrectly specified filter option may run a filter on the wrong type of file and cause your printer to spew out hundreds of sheets of paper. Rather than install conversion filters at all, you might want to try having the text filter (since it is the default filter) detect the type of file it has been asked to print and then automatically run the right conversion filter. Tools such as file can be of help here. Of course, it will be hard to deter mine the differences between _s_o_m_e file types---and, of course, you can still provide conversion filters just for them. The FreeBSD ports collection has a text filter that performs automatic conver sion called apsfilter. It can detect plain text, PostScript, and DVI files, run the proper conversions, and print. _7_._6_._1_._5 _O_u_t_p_u_t _F_i_l_t_e_r_s The LPD spooling system supports one other type of filter that we have not yet explored: an output filter. An output filter is intended for printing plain text only, like the text filter, but with many simplifications. If you are using an output filter but no text filter, then LPD starts an output filter once for the entire job instead of once for each file in the job. LPD does not make any provision to identify the start or the end of files within the job for the output filter. FreeBSD Handbook 161 LPD does not pass the user's login or host to the filter, so it is not intended to do accounting. In fact, it gets only two arguments: -w_w_i_d_t_h -l_l_e_n_g_t_h where _w_i_d_t_h is from the pw capability and _l_e_n_g_t_h is from the pl capability for the printer in question. Do not be seduced by an output filter's simplicity. If you would like each file in a job to start on a different page an output filter _w_i_l_l _n_o_t _w_o_r_k. Use a text filter (also known as an input filter); see section _I_n_s_t_a_l_l_i_n_g _t_h_e _T_e_x_t _F_i_l_t_e_r (section 7.4.2.2.6, page 135). Furthermore, an output filter is actu ally _m_o_r_e _c_o_m_p_l_e_x in that it has to examine the byte stream being sent to it for special flag characters and must send signals to itself on behalf of LPD. However, an output filter is _n_e_c_e_s_s_a_r_y if you want header pages and need to send escape sequences or other initialization strings to be able to print the header page. (But it is also _f_u_t_i_l_e if you want to charge header pages to the requesting user's account, since LPD does not give any user or host information to the output filter.) On a single printer, LPD allows both an output filter and text or other fil ters. In such cases, LPD will start the output filter to print the header page (see section _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2, page 162)) only. LPD then expects the output filter to _s_t_o_p _i_t_s_e_l_f by sending two bytes to the filter: ASCII 031 followed by ASCII 001. When an output filter sees these two bytes (031, 001), it should stop by sending SIGSTOP to itself. When LPD's done running other filters, it will restart the output filter by sending SIGCONT to it. If there is an output filter but _n_o text filter and LPD is working on a plain text job, LPD uses the output filter to do the job. As stated before, the out put filter will print each file of the job in sequence with no intervening form feeds or other paper advancement, and this is probably _n_o_t what you want. In almost all cases, you need a text filter. The program lpf, which we introduced earlier as a text filter, can also run as an output filter. If you need a quick-and-dirty output filter but do not want to write the byte detection and signal sending code, try lpf. You can also wrap lpf in a shell script to handle any initialization codes the printer might require. _7_._6_._1_._6 _l_p_f_: _a _T_e_x_t _F_i_l_t_e_r The program /usr/libexec/lpr/lpf that comes with FreeBSD binary distribution is a text filter (input filter) that can indent output (job submitted with lpr -i), allow literal characters to pass (job submitted with lpr -l), adjust the printing position for backspaces and tabs in the job, and account for pages printed. It can also act like an output filter. lpf is suitable for many printing environments. And although it has no capa bility to send initialization sequences to a printer, it is easy to write a shell script to do the needed initialization and then execute lpf. FreeBSD Handbook 162 In order for lpf to do page accounting correctly, it needs correct values filled in for the pw and pl capabilities in the /etc/printcap file. It uses these values to determine how much text can fit on a page and how many pages were in a user's job. For more information on printer accounting, see _A_c_c_o_u_n_t_ _i_n_g _f_o_r _P_r_i_n_t_e_r _U_s_a_g_e (section 7.6.5, page 177). _7_._6_._2 _H_e_a_d_e_r _P_a_g_e_s If you have _l_o_t_s of users, all of them using various printers, then you proba bly want to consider _h_e_a_d_e_r _p_a_g_e_s as a necessary evil. Header pages, also known as _b_a_n_n_e_r or _b_u_r_s_t _p_a_g_e_s identify to whom jobs belong after they are printed. They are usually printed in large, bold letters, per haps with decorative borders, so that in a stack of printouts they stand out from the real documents that comprise users' jobs. They enable users to locate their jobs quickly. The obvious drawback to a header page is that it is yet one more sheet that has to be printed for every job, their ephemeral usefulness lasting not more than a few minutes, ultimately finding themselves in a recy cling bin or rubbish heap. (Note that header pages go with each job, not each file in a job, so the paper waste might not be that bad.) The LPD system can provide header pages automatically for your printouts _i_f your printer can directly print plain text. If you have a PostScript printer, you will need an external program to generate the header page; see _H_e_a_d_e_r _P_a_g_e_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s (section 7.6.2.4, page 166). _7_._6_._2_._1 _E_n_a_b_l_i_n_g _H_e_a_d_e_r _P_a_g_e_s In the _S_i_m_p_l_e _P_r_i_n_t_e_r _S_e_t_u_p (section 7.4, page 123), we turned off header pages by specifying sh (meaning ``suppress header'') in the /etc/print cap file. To enable header pages for a printer, just remove the sh capability. Sounds too easy, right? You are right. You _m_i_g_h_t have to provide an output filter to send initializa tion strings to the printer. Here is an example output filter for Hewlett Packard PCL-compatible printers: #!/bin/sh # # hpof - Output filter for Hewlett Packard PCL-compatible printers # Installed in /usr/local/libexec/hpof printf "\033&k2G" || exit 2 exec /usr/libexec/lpr/lpf Specify the path to the output filter in the of capability. See _O_u_t_p_u_t _F_i_l_t_e_r_s (section 7.6.1.5, page 160) for more information. Here is an example /etc/printcap file for the printer teak that we introduced earlier; we enabled header pages and added the above output filter: FreeBSD Handbook 163 # # /etc/printcap for host orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf:\ :of=/usr/local/libexec/hpof: Now, when users print jobs to teak, they get a header page with each job. If users want to spend time searching for their printouts, they can suppress header pages by submitting the job with lpr -h; see _H_e_a_d_e_r _P_a_g_e _O_p_t_i_o_n_s (sec tion 7.5.4.3, page 146) for more lpr options. Note: LPD prints a form feed character after the header page. If your printer uses a different character or sequence of characters to eject a page, specify them with the ff capability in /etc/printcap. _7_._6_._2_._2 _C_o_n_t_r_o_l_l_i_n_g _H_e_a_d_e_r _P_a_g_e_s By enabling header pages, LPD will produce a _l_o_n_g _h_e_a_d_e_r, a full page of large letters identifying the user, host, and job. Here is an example (kelly printed the job named outline from host rose): FreeBSD Handbook 164 k ll ll k l l k l l k k eeee l l y y k k e e l l y y k k eeeeee l l y y kk k e l l y y k k e e l l y yy k k eeee lll lll yyy y y y y yyyy ll t l i t l oooo u u ttttt l ii n nnn eeee o o u u t l i nn n e e o o u u t l i n n eeeeee o o u u t l i n n e o o u uu t t l i n n e e oooo uuu u tt lll iii n n eeee r rrr oooo ssss eeee rr r o o s s e e r o o ss eeeeee r o o ss e r o o s s e e r oooo ssss eeee Job: outline Date: Sun Sep 17 11:04:58 1995 LPD appends a form feed after this text so the job starts on a new page (unless you have sf (suppress form feeds) in the destination printer's entry in /etc/printcap). If you prefer, LPD can make a _s_h_o_r_t _h_e_a_d_e_r; specify sb (short banner) in the FreeBSD Handbook 165 /etc/printcap file. The header page will look like this: rose:kelly Job: outline Date: Sun Sep 17 11:07:51 1995 Also by default, LPD prints the header page first, then the job. To reverse that, specify hl (header last) in /etc/printcap. _7_._6_._2_._3 _A_c_c_o_u_n_t_i_n_g _f_o_r _H_e_a_d_e_r _P_a_g_e_s Using LPD's built-in header pages enforces a particular paradigm when it comes to printer accounting: header pages must be _f_r_e_e _o_f _c_h_a_r_g_e. Why? Because the output filter is the only external program that will have control when the header page is printed that could do accounting, and it is not pro vided with any _u_s_e_r _o_r _h_o_s_t information or an accounting file, so it has no idea whom to charge for printer use. It is also not enough to just ``add one page'' to the text filter or any of the conversion filters (which do have user and host information) since users can suppress header pages with lpr -h. They could still be charged for header pages they did not print. Basically, lpr -h will be the preferred option of environmentally-minded users, but you cannot offer any incentive to use it. It is _s_t_i_l_l _n_o_t _e_n_o_u_g_h to have each of the filters generate their own header pages (thereby being able to charge for them). If users wanted the option of suppressing the header pages with lpr -h, they will still get them and be charged for them since LPD does not pass any knowledge of the -h option to any of the filters. So, what are your options? You can Accept LPD's paradigm and make header pages free. Install an alternative to LPD, such as LPDng or PLP. Section _A_l_t_e_r_n_a_t_i_v_e_s _t_o _t_h_e _S_t_a_n_d_a_r_d _S_p_o_o_l_e_r (section 7.7, page 180) tells more about other spooling software you can substitute for LPD. Write a _s_m_a_r_t output filter. Normally, an output filter is not meant to do anything more than initialize a printer or do some simple character conversion. It is suited for header pages and plain text jobs (when there is no text (input) filter). But, if there is a text filter for the plain text jobs, then LPD will start the output filter only for the header pages. And the output filter can parse the header page text that LPD generates to determine what user and host to charge for the header page. The only other problem with this method is that the output filter still does not know what accounting file to use (it is not passed the name of the file from the af capability), but if you have a well-known accounting file, you can hard-code that into the output filter. FreeBSD Handbook 166 To facilitate the parsing step, use the sh (short header) capability in /etc/printcap. Then again, all that might be too much trouble, and users will certainly appreciate the more generous system administrator who makes header pages free. _7_._6_._2_._4 _H_e_a_d_e_r _P_a_g_e_s _o_n _P_o_s_t_S_c_r_i_p_t _P_r_i_n_t_e_r_s As described above, LPD can generate a plain text header page suitable for many printers. Of course, PostScript cannot directly print plain text, so the header page feature of LPD is useless---or mostly so. One obvious way to get header pages is to have every conversion filter and the text filter generate the header page. The filters should should use the user and host arguments to generate a suitable header page. The drawback of this method is that users will always get a header page, even if they submit jobs with lpr -h. Let us explore this method. The following script takes three arguments (user login name, host name, and job name) and makes a simple PostScript header page: #!/bin/sh # # make-ps-header - make a PostScript header page on stdout # Installed in /usr/local/libexec/make-ps-header # # # These are PostScript units (72 to the inch). Modify for A4 or # whatever size paper you are using: # page_width=612 page_height=792 border=72 # # Check arguments # if [ $# -ne 3 ]; then echo "Usage: `basename $0` " 1>&2 exit 1 fi # # Save these, mostly for readability in the PostScript, below. # user=$1 host=$2 job=$3 date=`date` # # Send the PostScript code to stdout. FreeBSD Handbook 167 # exec cat <&2 exit 2 } while getopts "x:y:n:h:" option; do case $option in x|y) ;; # Ignore n) login=$OPTARG ;; h) host=$OPTARG ;; *) echo "LPD started `basename $0` wrong." 1>&2 exit 2 ;; esac done [ "$login" ] || fail "No login name" [ "$host" ] || fail "No host name" ( /usr/local/libexec/make-ps-header $login $host "DVI File" /usr/local/bin/dvips -f ) | eval /usr/local/libexec/lprps $orig_args Notice how the filter has to parse the argument list in order to determine the user and host name. The parsing for the other conversion filters is identical. The text filter takes a slightly different set of arguments, though (see sec tion _H_o_w _F_i_l_t_e_r_s _W_o_r_k (section 7.6.1.1, page 150)). As we have mentioned before, the above scheme, though fairly simple, disables the ``suppress header page'' option (the -h option) to lpr. If users wanted to save a tree (or a few pennies, if you charge for header pages), they would not be able to do so, since every filter's going to print a header page with every job. To allow users to shut off header pages on a per-job basis, you will need to use the trick introduced in section _A_c_c_o_u_n_t_i_n_g _f_o_r _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2.3, page 165): write an output filter that parses the LPD-generated header page and produces a PostScript version. If the user submits the job with lpr -h, then LPD will not generate a header page, and neither will your output fil ter. Otherwise, your output filter will read the text from LPD and send the appropriate header page PostScript code to the printer. If you have a PostScript printer on a serial line, you can make use of lprps, which comes with an output filter, psof, which does the above. Note that psof FreeBSD Handbook 169 does not charge for header pages. _7_._6_._3 _N_e_t_w_o_r_k_e_d _P_r_i_n_t_i_n_g FreeBSD supports networked printing: sending jobs to remote printers. Net worked printing generally refers to two different things: Accessing a printer attached to a remote host. You install a printer that has a conventional serial or parallel interface on one host. Then, you set up LPD to enable access to the printer from other hosts on the net work. Section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169) tells how to do this. Accessing a printer attached directly to a network. The printer has a network interface in addition (or in place of) a more conventional serial or parallel interface. Such a printer might work as follows: It might understand the LPD protocol and can even queue jobs from remote hosts. In this case, it acts just like a regular host running LPD. Follow the same procedure in section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169) to set up such a printer. It might support a data stream network connection. In this case, you ``attach'' the printer to one host on the network by making that host responsible for spooling jobs and sending them to the printer. Sec tion _P_r_i_n_t_e_r_s _w_i_t_h _N_e_t_w_o_r_k_e_d _D_a_t_a _S_t_r_e_a_m _I_n_t_e_r_f_a_c_e_s (section 7.6.3.2, page 171) gives some suggestions on installing such print ers. _7_._6_._3_._1 _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s The LPD spooling system has built-in support for sending jobs to other hosts also running LPD (or are compatible with LPD). This feature enables you to install a printer on one host and make it accessible from other hosts. It also works with printers that have network interfaces that understand the LPD proto col. To enable this kind of remote printing, first install a printer on one host, the _p_r_i_n_t_e_r _h_o_s_t, using the simple printer setup described in _S_i_m_p_l_e _P_r_i_n_t_e_r _S_e_t_u_p (section 7.4, page 123). Do any advanced setup in _A_d_v_a_n_c_e_d _P_r_i_n_t_e_r _S_e_t_u_p (section 7.6, page 148) that you need. Make sure to test the printer and see if it works with the features of LPD you have enabled. Also ensure that the _l_o_c_a_l _h_o_s_t has authorization to use the LPD service in the _p_r_i_n_t_e_r _h_o_s_t (see _R_e_s_t_r_i_c_t_i_n_g _J_o_b_s _f_r_o_m _R_e_m_o_t_e _P_r_i_n_t_e_r_s (section 7.6.4.4, page 175)). If you are using a printer with a network interface that is compatible with LPD, then the _p_r_i_n_t_e_r _h_o_s_t in the discussion below is the printer itself, and the _p_r_i_n_t_e_r _n_a_m_e is the name you configured for the printer. See the documen tation that accompanied your printer and/or printer-network interface. Then, on the other hosts you want to have access to the printer, make an entry in their /etc/printcap files with the following: FreeBSD Handbook 170 1. Name the entry anything you want. For simplicity, though, you probably want to use the same name and aliases as on the printer host. 2. Leave the lp capability blank, explicitly (:lp=:). 3. Make a spooling directory and specify its location in the sd capability. LPD will store jobs here before they get sent to the printer host. 4. Place the name of the printer host in the rm capability. 5. Place the printer name on the _p_r_i_n_t_e_r _h_o_s_t in the rp capability. That is it. You do not need to list conversion filters, page dimensions, or anything else in the /etc/printcap file. Here is an example. The host rose has two printers, bamboo and rattan. We will enable users on the host orchid to print to those printers. Here is the /etc/printcap file for orchid (back from section _E_n_a_b_l_i_n_g _H_e_a_d_e_r _P_a_g_e_s (section 7.6.2.1, page 162)). It already had the entry for the printer teak; we have added entries for the two printers on the host rose: # # /etc/printcap for host orchid - added (remote) printers on rose # # # teak is local; it is connected directly to orchid: # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/ifhp:\ :vf=/usr/local/libexec/vfhp:\ :of=/usr/local/libexec/ofhp: # # rattan is connected to rose; send jobs for rattan to rose: # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: # # bamboo is connected to rose as well: # bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo: Then, we just need to make spooling directories on orchid: mkdir -p /var/spool/lpd/rattan /var/spool/lpd/bamboo chmod 770 /var/spool/lpd/rattan /var/spool/lpd/bamboo chown daemon.daemon /var/spool/lpd/rattan /var/spool/lpd/bamboo Now, users on orchid can print to rattan and bamboo. If, for example, a user FreeBSD Handbook 171 on orchid typed lpr -P bamboo -d sushi-review.dvi the LPD system on orchid would copy the job to the spooling directory /var/spool/lpd/bamboo and note that it was a DVI job. As soon as the host rose has room in its bamboo spooling directory, the two LPDs would transfer the file to rose. The file would wait in rose's queue until it was finally printed. It would be converted from DVI to PostScript (since bamboo is a PostScript printer) on rose. _7_._6_._3_._2 _P_r_i_n_t_e_r_s _w_i_t_h _N_e_t_w_o_r_k_e_d _D_a_t_a _S_t_r_e_a_m _I_n_t_e_r_f_a_c_e_s Often, when you buy a network interface card for a printer, you can get two versions: one which emulates a spooler (the more expensive version), or one which just lets you send data to it as if you were using a serial or parallel port (the cheaper version). This section tells how to use the cheaper version. For the more expensive one, see the previous section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169). The format of the /etc/printcap file lets you specify what serial or parallel interface to use, and (if you are using a serial interface), what baud rate, whether to use flow control, delays for tabs, conversion of newlines, and more. But there is no way to specify a connection to a printer that is listening on a TCP/IP or other network port. To send data to a networked printer, you need to develop a communications pro gram that can be called by the text and conversion filters. Here is one such example: the script netprint takes all data on standard input and sends it to a network-attached printer. We specify the hostname of the printer as the first argument and the port number to which to connect as the second argument to net print. Note that this supports one-way communication only (FreeBSD to printer); many network printers support two-way communication, and you might want to take advantage of that (to get printer status, perform accounting, etc.). FreeBSD Handbook 172 #!/usr/bin/perl # # netprint - Text filter for printer attached to network # Installed in /usr/local/libexec/netprint # $#ARGV eq 1 || die "Usage: $0 "; $printer_host = $ARGV[0]; $printer_port = $ARGV[1]; require 'sys/socket.ph'; ($ignore, $ignore, $protocol) = getprotobyname('tcp'); ($ignore, $ignore, $ignore, $ignore, $address) = gethostbyname($printer_host); $sockaddr = pack('S n a4 x8', &AF_INET, $printer_port, $address); socket(PRINTER, &PF_INET, &SOCK_STREAM, $protocol) || die "Can't create TCP/IP stream socket: $!"; connect(PRINTER, $sockaddr) || die "Can't contact $printer_host: $!"; while () { print PRINTER; } exit 0; We can then use this script in various filters. Suppose we had a Diablo 750-N line printer connected to the network. The printer accepts data to print on port number 5100. The host name of the printer is scrivener. Here is the text filter for the printer: #!/bin/sh # # diablo-if-net - Text filter for Diablo printer `scrivener' listening # on port 5100. Installed in /usr/local/libexec/diablo-if-net # exec /usr/libexec/lpr/lpf "$@" | /usr/local/libexec/netprint scrivener 5100 _7_._6_._4 _R_e_s_t_r_i_c_t_i_n_g _P_r_i_n_t_e_r _U_s_a_g_e This section gives information on restricting printer usage. The LPD system lets you control who can access a printer, both locally or remotely, whether they can print multiple copies, how large their jobs can be, and how large the printer queues can get. _7_._6_._4_._1 _R_e_s_t_r_i_c_t_i_n_g _M_u_l_t_i_p_l_e _C_o_p_i_e_s The LPD system makes it easy for users to print multiple copies of a file. Users can print jobs with lpr -#5 (for example) and get five copies of each file in the job. Whether this is a good thing is up to you. If you feel multiple copies cause unnecessary wear and tear on your printers, you can disable the -# option to lpr by adding the sc capability to the FreeBSD Handbook 173 /etc/printcap file. When users submit jobs with the -# option, they will see lpr: multiple copies are not allowed Note that if you have set up access to a printer remotely (see section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169)), you need the sc capability on the remote /etc/printcap files as well, or else users will still be able to submit multiple-copy jobs by using another host. Here is an example. This is the /etc/printcap file for the host rose. The printer rattan is quite hearty, so we will allow multiple copies, but the laser printer bamboo's a bit more delicate, so we will disable multiple copies by adding the sc capability: # # /etc/printcap for host rose - restrict multiple copies on bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Now, we also need to add the sc capability on the host orchid's /etc/printcap (and while we are at it, let us disable multiple copies for the printer teak): # # /etc/printcap for host orchid - no multiple copies for local # printer teak or remote printer bamboo teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sd=/var/spool/lpd/teak:mx#0:sc:\ :if=/usr/local/libexec/ifhp:\ :vf=/usr/local/libexec/vfhp:\ :of=/usr/local/libexec/ofhp: rattan|line|diablo|lp|Diablo 630 Line Printer:\ :lp=:rm=rose:rp=rattan:sd=/var/spool/lpd/rattan: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :lp=:rm=rose:rp=bamboo:sd=/var/spool/lpd/bamboo:sc: By using the sc capability, we prevent the use of lpr -#, but that still does not prevent users from running lpr multiple times, or from submitting the same file multiple times in one job like this: lpr forsale.sign forsale.sign forsale.sign forsale.sign forsale.sign FreeBSD Handbook 174 There are many ways to prevent this abuse (including ignoring it) which you are free to explore. _7_._6_._4_._2 _R_e_s_t_r_i_c_t_i_n_g _A_c_c_e_s_s _T_o _P_r_i_n_t_e_r_s You can control who can print to what printers by using the UNIX group mecha nism and the rg capability in /etc/printcap. Just place the users you want to have access to a printer in a certain group, and then name that group in the rg capability. Users outside the group (including root) will be greeted with lpr: Not a member of the restricted group if they try to print to the controlled printer. As with the sc (suppress multiple copies) capability, you need to specify rg on remote hosts that also have access to your printers, if you feel it is appro priate (see section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169)). For example, we will let anyone access the printer rattan, but only those in group artists can use bamboo. Here is the familiar /etc/printcap for host rose: # # /etc/printcap for host rose - restricted group for bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Let us leave the other example /etc/printcap file (for the host orchid) alone. Of course, anyone on orchid can print to bamboo. It might be the case that we only allow certain logins on orchid anyway, and want them to have access to the printer. Or not. _N_o_t_e_: there can be only one restricted group per printer. _7_._6_._4_._3 _C_o_n_t_r_o_l_l_i_n_g _S_i_z_e_s _o_f _J_o_b_s _S_u_b_m_i_t_t_e_d If you have many users accessing the printers, you probably need to put an upper limit on the sizes of the files users can submit to print. After all, there is only so much free space on the filesystem that houses the spooling directories, and you also need to make sure there is room for the jobs of other FreeBSD Handbook 175 users. LPD enables you to limit the maximum byte size a file in a job can be with the mx capability. The units are in BUFSIZ blocks, which are 1024 bytes. If you put a zero for this capability, there will be no limit on file size. Note that the limit applies to _f_i_l_e_s in a job, and _n_o_t the total job size. LPD will not refuse a file that is larger than the limit you place on a printer. Instead, it will queue as much of the file up to the limit, which will then get printed. The rest will be discarded. Whether this is correct behavior is up for debate. Let us add limits to our example printers rattan and bamboo. Since those artists' PostScript files tend to be large, we will limit them to five megabytes. We will put no limit on the plain text line printer: # # /etc/printcap for host rose # # # No limit on job size: # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: # # Limit of five megabytes: # bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: Again, the limits apply to the local users only. If you have set up access to your printers remotely, remote users will not get those limits. You will need to specify the mx capability in the remote /etc/printcap files as well. See section _P_r_i_n_t_e_r_s _I_n_s_t_a_l_l_e_d _o_n _R_e_m_o_t_e _H_o_s_t_s (section 7.6.3.1, page 169) for more information on remote printing. There is another specialized way to limit job sizes from remote printers; see section _R_e_s_t_r_i_c_t_i_n_g _J_o_b_s _f_r_o_m _R_e_m_o_t_e _P_r_i_n_t_e_r_s (section 7.6.4.4, page 175). _7_._6_._4_._4 _R_e_s_t_r_i_c_t_i_n_g _J_o_b_s _f_r_o_m _R_e_m_o_t_e _P_r_i_n_t_e_r_s The LPD spooling system provides several ways to restrict print jobs submitted from remote hosts: Host restrictions You can control from which remote hosts a local LPD accepts FreeBSD Handbook 176 requests with the files /etc/hosts.equiv and /etc/hosts.lpd. LPD checks to see if an incoming request is from a host listed in either one of these files. If not, LPD refuses the request. The format of these files is simple: one host name per line. Note that the file /etc/hosts.equiv is also used by the ruserok(3) pro tocol, and affects programs like rsh and rcp, so be careful. For example, here is the /etc/hosts.lpd file on the host rose: orchid violet madrigal.fishbaum.de This means rose will accept requests from the hosts orchid, violet, and madrigal.fishbaum.de. If any other host tries to access rose's LPD, LPD will refuse them. Size restrictions You can control how much free space there needs to remain on the filesystem where a spooling directory resides. Make a file called minfree in the spooling directory for the local printer. Insert in that file a number representing how many disk blocks (512 bytes) of free space there has to be for a remote job to be accepted. This lets you insure that remote users will not fill your filesys tem. You can also use it to give a certain priority to local users: they will be able to queue jobs long after the free disk space has fallen below the amount specified in the minfree file. For example, let us add a minfree file for the printer bamboo. We examine /etc/printcap to find the spooling directory for this printer; here is bamboo's entry: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:sc:rg=artists:mx#5000:\ :lp=/dev/ttyd5:fs#0x82000e1:xs#0x820:rw:mx#5000:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf: The spooling directory is the given in the sd capability. We will make three megabytes (which is 6144 disk blocks) the amount of free disk space that must exist on the filesystem for LPD to accept remote jobs: echo 6144 > /var/spool/lpd/bamboo/minfree User restrictions You can control which remote users can print to local printers by specifying the rs capability in /etc/printcap. When rs appears in the entry for a locally-attached printer, LPD will accept jobs from remote hosts _i_f the user submitting the job also has an account of FreeBSD Handbook 177 the same login name on the local host. Otherwise, LPD refuses the job. This capability is particularly useful in an environment where there are (for example) different departments sharing a network, and some users transcend departmental boundaries. By giving them accounts on your systems, they can use your printers from their own departmental systems. If you would rather allow them to use _o_n_l_y your printers and not your compute resources, you can give them ``token'' accounts, with no home directory and a useless shell like /usr/bin/false. _7_._6_._5 _A_c_c_o_u_n_t_i_n_g _f_o_r _P_r_i_n_t_e_r _U_s_a_g_e So, you need to charge for printouts. And why not? Paper and ink cost money. And then there are maintenance costs---printers are loaded with moving parts and tend to break down. You have examined your printers, usage patterns, and maintenance fees and have come up with a per-page (or per-foot, per-meter, or per-whatever) cost. Now, how do you actually start accounting for printouts? Well, the bad news is the LPD spooling system does not provide much help in this department. Accounting is highly dependent on the kind of printer in use, the formats being printed, and _y_o_u_r requirements in charging for printer usage. To implement accounting, you have to modify a printer's text filter (to charge for plain text jobs) and the conversion filters (to charge for other file for mats), to count pages or query the printer for pages printed. You cannot get away with using the simple output filter, since it cannot do accounting. See section _F_i_l_t_e_r_s (section 7.6.1, page 148). Generally, there are two ways to do accounting: _P_e_r_i_o_d_i_c _a_c_c_o_u_n_t_i_n_g is the more common way, possibly because it is easier. Whenever someone prints a job, the filter logs the user, host, and number of pages to an accounting file. Every month, semester, year, or whatever time period you prefer, you collect the accounting files for the various printers, tally up the pages printed by users, and charge for usage. Then you truncate all the logging files, starting with a clean slate for the next period. _T_i_m_e_l_y _a_c_c_o_u_n_t_i_n_g is less common, probably because it is more difficult. This method has the filters charge users for printouts as soon as they use the printers. Like disk quotas, the accounting is immediate. You can prevent users from printing when their account goes in the red, and might provide a way for users to check and adjust their ``print quotas.'' But this method requires some database code to track users and their quotas. The LPD spooling system supports both methods easily: since you have to provide the filters (well, most of the time), you also have to provide the accounting code. But there is a bright side: you have enormous flexibility in your accounting methods. For example, you choose whether to use periodic or timely accounting. You choose what information to log: user names, host names, job types, pages printed, square footage of paper used, how long the job took to print, and so forth. And you do so by modifying the filters to save this FreeBSD Handbook 178 information. _7_._6_._5_._1 _Q_u_i_c_k _a_n_d _D_i_r_t_y _P_r_i_n_t_e_r _A_c_c_o_u_n_t_i_n_g FreeBSD comes with two programs that can get you set up with simple periodic accounting right away. They are the text filter lpf, described in section _l_p_f_: _a _T_e_x_t _F_i_l_t_e_r (section 7.6.1.6, page 161), and pac, a program to gather and total entries from printer accounting files. As mentioned in the section on filters (_F_i_l_t_e_r_s (section 7.6.1.1, page 150)), LPD starts the text and the conversion filters with the name of the accounting file to use on the filter command line. The filters can use this argument to know where to write an accounting file entry. The name of this file comes from the af capability in /etc/printcap, and if not specified as an absolute path, is relative to the spooling directory. LPD starts lpf with page width and length arguments (from the pw and pl capa bilities). lpf uses these arguments to determine how much paper will be used. After sending the file to the printer, it then writes an accounting entry in the accounting file. The entries look like this: 2.00 rose:andy 3.00 rose:kelly 3.00 orchid:mary 5.00 orchid:mary 2.00 orchid:zhang You should use a separate accounting file for each printer, as lpf has no file locking logic built into it, and two lpfs might corrupt each other's entries if they were to write to the same file at the same time. A easy way to insure a separate accounting file for each printer is to use af=acct in /etc/printcap. Then, each accounting file will be in the spooling directory for a printer, in a file named acct. When you are ready to charge users for printouts, run the pac program. Just change to the spooling directory for the printer you want to collect on and type pac. You will get a dollar-centric summary like the fol lowing: Login pages/feet runs price orchid:kelly 5.00 1 $ 0.10 orchid:mary 31.00 3 $ 0.62 orchid:zhang 9.00 1 $ 0.18 rose:andy 2.00 1 $ 0.04 rose:kelly 177.00 104 $ 3.54 rose:mary 87.00 32 $ 1.74 rose:root 26.00 12 $ 0.52 total 337.00 154 $ 6.74 FreeBSD Handbook 179 These are the arguments pac expects: -P_p_r_i_n_t_e_r Which _p_r_i_n_t_e_r to summarize. This option works only if there is an absolute path in the af capability in /etc/printcap. -c Sort the output by cost instead of alphabetically by user name. -m Ignore host name in the accounting files. With this option, user smith on host alpha is the same user smith on host gamma. Without, they are different users. -p_p_r_i_c_e Compute charges with _p_r_i_c_e dollars per page or per foot instead of the price from the pc capability in /etc/printcap, or two cents (the default). You can specify _p_r_i_c_e as a floating point number. -r Reverse the sort order. -s Make an accounting summary file and truncate the accounting file. _n_a_m_e_s_._._. Print accounting information for the given user _n_a_m_e_s only. In the default summary that pac produces, you see the number of pages printed by each user from various hosts. If, at your site, host does not matter (because users can use any host), run pac -m, to produce the following summary: Login pages/feet runs price andy 2.00 1 $ 0.04 kelly 182.00 105 $ 3.64 mary 118.00 35 $ 2.36 root 26.00 12 $ 0.52 zhang 9.00 1 $ 0.18 total 337.00 154 $ 6.74 To compute the dollar amount due, pac uses the pc capability in the /etc/print cap file (default of 200, or 2 cents per page). Specify, in hundredths of cents, the price per page or per foot you want to charge for printouts in this capability. You can override this value when you run pac with the -p option. The units for the -p option are in dollars, though, not hundredths of cents. For example, pac -p1.50 makes each page cost one dollar and fifty cents. You can really rake in the profits by using this option. FreeBSD Handbook 180 Finally, running pac -s will save the summary information in a summary account ing file, which is named the same as the printer's accounting file, but with _sum appended to the name. It then truncates the accounting file. When you run pac again, it rereads the summary file to get starting totals, then adds information from the regular accounting file. _7_._6_._5_._2 _H_o_w _C_a_n _Y_o_u _C_o_u_n_t _P_a_g_e_s _P_r_i_n_t_e_d_? In order to perform even remotely accurate accounting, you need to be able to determine how much paper a job uses. This is the essential problem of printer accounting. For plain text jobs, the problem's not that hard to solve: you count how many lines are in a job and compare it to how many lines per page your printer sup ports. Do not forget to take into account backspaces in the file which over print lines, or long logical lines that wrap onto one or more additional physi cal lines. The text filter lpf (introduced in _l_p_f_: _a _T_e_x_t _F_i_l_t_e_r (section 7.6.1.6, page 161)) takes into account these things when it does accounting. If you are writing a text filter which needs to do accounting, you might want to examine lpf's source code. How do you handle other file formats, though? Well, for DVI-to-LaserJet or DVI-to-PostScript conversion, you can have your filter parse the diagnostic output of dvilj or dvips and look to see how many pages were converted. You might be able to do similar things with other file formats and conversion programs. But these methods suffer from the fact that the printer may not actually print all those pages. For example, it could jam, run out of toner, or explode---and the user would still get charged. So, what can you do? There is only one _s_u_r_e way to do _a_c_c_u_r_a_t_e accounting. Get a printer that can tell you how much paper it uses, and attach it via a serial line or a network connection. Nearly all PostScript printers support this notion. Other makes and models do as well (networked Imagen laser printers, for example). Modify the filters for these printers to get the page usage after they print each job and have them log accounting information based on that value _o_n_l_y. There is no line counting nor error-prone file examination required. Of course, you can always be generous and make all printouts free. _7_._7 _A_l_t_e_r_n_a_t_i_v_e_s _t_o _t_h_e _S_t_a_n_d_a_r_d _S_p_o_o_l_e_r If you have been reading straight through this manual, by now you have learned just about everything there is to know about the LPD spooling system that comes with FreeBSD. You can probably appreciate many of its shortcomings, which nat urally leads to the question: ``What other spooling systems are out there (and work with FreeBSD)?'' FreeBSD Handbook 181 Unfortunately, I have located only _t_w_o alternatives---and they are almost iden tical to each other! They are: PLP, the Portable Line Printer Spooler System PLP was based on software developed by Patrick Powell and then maintained by an Internet-wide group of developers. The main site for the software is at ftp://ftp.iona.ie/pub/plp. There is also a web page. It is quite similar to the BSD LPD spooler, but boasts a host of features, including: Better network support, including built-in support for net worked printers, NIS-maintained printcaps, and NFS-mounted spooling directories Sophisticated queue management, allowing multiple printers on a queue, transfer of jobs between queues, and queue redirec tion Remote printer control functions Prioritization of jobs Expansive security and access options LPRng LPRng, which purportedly means ``LPR: the Next Generation'' is a complete rewrite of PLP. Patrick Powell and Justin Mason (the principal maintainer of PLP) collaborated to make LPRng. The main site for LPRng is ftp://dickory.sdsu.edu/pub/LPRng. _7_._8 _A_c_k_n_o_w_l_e_d_g_m_e_n_t_s I would like to thank the following people who have assisted in the develop ment of this document: Daniel Eischen For providing a plethora of HP filter programs for perusal. Jake Hamby " For the Ghostscript-to-HP filter. My wife, Mary Kelly For allowing me to spend more time with FreeBSD than with her. _8_. _D_i_s_k_s _C_o_n_t_r_i_b_u_t_e_d _b_y _D_a_v_i_d _O_'_B_r_i_e_n 26 April 1998 Lets say we want to add a new SCSI disk to a machine that currently only has a FreeBSD Handbook 182 single drive. First turn off the computer and install the drive in the com puter following the instructions of the computer, controller, and drive manu facturer. Due the wide variations of procedures to do this, the details are beyond the scope of this document. Login as user _r_o_o_t. After you've installed the drive, inspect /var/run/dmesg.boot to ensure the new disk was found. Continuing with our example, the newly added drive will be sd1 and we want to mount it on /1. (if you are adding an IDE drive substitute wd for sd) Because FreeBSD runs on IBM-PC compatible computers, it must take into account the PC BIOS partitions. These are different from the traditional BSD parti tions. A PC disk has up to four BIOS partition entries. If the disk is going to be truly dedicated to FreeBSD, you can use the _d_e_d_i_c_a_t_e_d mode. Otherwise, FreeBSD will have to live with in one of the PC BIOS partitions. FreeBSD calls the PC BIOS partitions, _s_l_i_c_e_s so as not to confuse them with traditional BSD partitions. You may also use slices on a disk that is dedicated to FreeBSD, but used in a computer that also has another operating system installed. This is to not confuse the fdisk utility of the other operating system. In the slice case the drive will be added as /dev/sd1s1e. This is read as: SCSI disk, unit number 1 (second SCSI disk), slice 1 (PC BIOS partition 1), and e BSD partition. In the dedicated case, the drive will be added simply as /dev/sd1e. _8_._1 _U_s_i_n_g _s_y_s_i_n_s_t_a_l_l You may use /stand/sysinstall to partition and label a new disk using its easy to use menus. Either login as user _r_o_o_t or use the su command. Run /stand/sysinstall and enter the _C_o_n_f_i_g_u_r_e menu. With in the FreeBSD Configura tion Menu, scroll down and select the _P_a_r_t_i_t_i_o_n item. Next you should be pre sented with a list of hard drives installed in your system. If you do not see sd1 listed, you need to recheck your physical installation and dmesg output in the file /var/run/dmesg.boot. Select sd1 to enter the FDISK Partition Editor. Choose A to use the entire disk for FreeBSD. When asked if you want to ``remain cooperative with any future possible operating systems'', answer _Y_E_S. Write the changes to the disk using _W. Now exit the FDISK editor using _q. Next you will be asked about the Master Boot Record. Since you are adding a disk to an already running system, choose _N_o_n_e. Next enter the _D_i_s_k _L_a_b_e_l _E_d_i_t_o_r. This is where you will create the tradi tional BSD partitions. A disk can have up to eight partitions, labeled a-h. A few of the partition labels have special uses. The _a partition is used for the root partition (/). Thus only your system disk (e.g, the disk you boot from) should have an _a partition. The _b partition is used for swap partitions, and you may have many disks with swap partitions. The _c partition addresses the entire disk in dedicated mode, or the entire FreeBSD slice in slice mode. The other partitions are for general use. Sysinstall's Label editor favors the _e partition for non-root, non-swap parti tions. With in the Label editor, create a single file system using _C. When prompted if this will be a FS (file system) or swap, choose ``FS'' and give a FreeBSD Handbook 183 mount point (e.g, /mnt). When adding a disk in post-install mode, Sysinstall will not create entries in /etc/fstab for you, so the mount point you specify isn't important. You are now ready to write the new label to the disk and create a file system on it. Do this by hitting _W. Ignore any errors from Sysinstall that it could not mount the new partition. Exit the Label Editor and Sysinstall completely. The last step is to edit /etc/fstab to add an entry for your new disk. _8_._2 _U_s_i_n_g _c_o_m_m_a_n_d _l_i_n_e _u_t_i_l_i_t_i_e_s _8_._2_._1 _* _U_s_i_n_g _S_l_i_c_e_s _8_._2_._2 _D_e_d_i_c_a_t_e_d If you will not be sharing the new drive with another operating system, you may use the _d_e_d_i_c_a_t_e_d mode. Remember this mode can confuse Microsoft operating systems; however, no damage will be done by them. IBM's OS/2 however, will "appropriate" any partition it finds which it doesn't understand. dd if=/dev/zero of=/dev/rsd1 bs=1k count=1 disklabel -Brw sd1 auto disklabel -e sd1 # create the `e' partition newfs -d0 /dev/rsd1e mkdir -p /1 vi /etc/fstab # add an entry for /dev/sd1e mount /1 An alternate method is: dd if=/dev/zero of=/dev/rsd1 count=2 disklabel /dev/rsd1 | disklabel -BrR sd1 /dev/stdin newfs /dev/rsd1e mkdir -p /1 vi /etc/fstab # add an entry for /dev/sd1e mount /1 _8_._3 _* _N_o_n_-_t_r_a_d_i_t_i_o_n_a_l _D_r_i_v_e_s _8_._3_._1 _* _Z_i_p _D_r_i_v_e_s _8_._3_._2 _* _J_a_z_z _D_r_i_v_e_s _8_._3_._3 _* _S_e_q_u_e_s_t _D_r_i_v_e_s _9_. _B_a_c_k_u_p_s Issues of hardware compatibility are among the most troublesome in the computer industry today and FreeBSD is by no means immune to trouble. In this respect, FreeBSD's advantage of being able to run on inexpensive commodity PC hardware FreeBSD Handbook 184 is also its liability when it comes to support for the amazing variety of com ponents on the market. While it would be impossible to provide a exhaustive listing of hardware that FreeBSD supports, this section serves as a catalog of the device drivers included with FreeBSD and the hardware each drivers sup ports. Where possible and appropriate, notes about specific products are included. You may also want to refer to _t_h_e _k_e_r_n_e_l _c_o_n_f_i_g_u_r_a_t_i_o_n _f_i_l_e (section 5.3, page 81) section in this handbook for a list of supported devices. As FreeBSD is a volunteer project without a funded testing department, we depend on you, the user, for much of the information contained in this catalog. If you have direct experience of hardware that does or does not work with FreeBSD, please let us know by sending e-mail to the FreeBSD documentation pro ject mailing list . Questions about supported hard ware should be directed to the FreeBSD general questions mailing list (see _M_a_i_l_i_n_g _L_i_s_t_s (section 27.1, page 467) for more information). When submitting information or asking a question, please remem ber to specify exactly what version of FreeBSD you are using and include as many details of your hardware as possible. _9_._1 _* _W_h_a_t _a_b_o_u_t _b_a_c_k_u_p_s _t_o _f_l_o_p_p_i_e_s_? _9_._2 _T_a_p_e _M_e_d_i_a The major tape media are the 4mm, 8mm, QIC, mini-cartridge and DLT. _9_._2_._1 _4_m_m _(_D_D_S_: _D_i_g_i_t_a_l _D_a_t_a _S_t_o_r_a_g_e_) " 4mm tapes are replacing QIC as the workstation backup media of choice. This trend accelerated greatly when Conner purchased Archive, a leading manufacturer of QIC drives, and then stopped production of QIC drives. 4mm drives are small and quiet but do not have the reputation for reliability that is enjoyed by 8mm drives. The cartridges are less expensive and smaller (3 x 2 x 0.5 inches, 76 x 51 x 12 mm) than 8mm cartridges. 4mm, like 8mm, has comparatively short head life for the same reason, both use helical scan. Data thruput on these drives starts ~150kB/s, peaking at ~500kB/s. Data capac ity starts at 1.3 GB and ends at 2.0 GB. Hardware compression, available with most of these drives, approximately doubles the capacity. Multi-drive tape library units can have 6 drives in a single cabinet with automatic tape chang ing. Library capacities reach 240 GB. 4mm drives, like 8mm drives, use helical-scan. All the benefits and drawbacks of helical-scan apply to both 4mm and 8mm drives. Tapes should be retired from use after 2,000 passes or 100 full backups. _9_._2_._2 _8_m_m _(_E_x_a_b_y_t_e_) " 8mm tapes are the most common SCSI tape drives; they are the best choice of exchanging tapes. Nearly every site has an exabyte 2 GB 8mm tape drive. 8mm FreeBSD Handbook 185 drives are reliable, convenient and quiet. Cartridges are inexpensive and small (4.8 x 3.3 x 0.6 inches; 122 x 84 x 15 mm). One downside of 8mm tape is relatively short head and tape life due to the high rate of relative motion of the tape across the heads. Data thruput ranges from ~250kB/s to ~500kB/s. Data sizes start at 300 MB and go up to 7 GB. Hardware compression, available with most of these drives, approximately doubles the capacity. These drives are available as single units or multi-drive tape libraries with 6 drives and 120 tapes in a single cabinet. Tapes are changed automatically by the unit. Library capacities reach 840+ GB. Data is recorded onto the tape using helical-scan, the heads are positioned at an angle to the media (approximately 6 degrees). The tape wraps around 270 degrees of the spool that holds the heads. The spool spins while the tape slides over the spool. The result is a high density of data and closely packed tracks that angle across the tape from one edge to the other. _9_._2_._3 _Q_I_C QIC-150 tapes and drives are, perhaps, the most common tape drive and media around. QIC tape drives are the least expensive "serious" backup drives. The downside is the cost of media. QIC tapes are expensive compared to 8mm or 4mm tapes, up to 5 times the price per GB data storage. But, if your needs can be satisfied with a half-dozen tapes, QIC may be the correct choice. QIC is the _m_o_s_t common tape drive. Every site has a QIC drive of some density or another. Therein lies the rub, QIC has a large number of densities on physically similar (sometimes identical) tapes. QIC drives are not quiet. These drives audibly seek before they begin to record data and are clearly audible whenever reading, writing or seeking. QIC tapes measure (6 x 4 x 0.7 inches; 15.2 x 10.2 x 1.7 mm). _M_i_n_i_-_c_a_r_t_r_i_d_g_e_s (section 9.2.4, page 185), which also use 1/4" wide tape are discussed separately. Tape libraries and changers are not available. Data thruput ranges from ~150kB/s to ~500kB/s. Data capacity ranges from 40 MB to 15 GB. Hardware compression is available on many of the newer QIC drives. QIC drives are less frequently installed; they are being supplanted by DAT drives. Data is recorded onto the tape in tracks. The tracks run along the long axis of the tape media from one end to the other. The number of tracks, and there fore the width of a track, varies with the tape's capacity. Most if not all newer drives provide backward-compatibility at least for reading (but often also for writing). QIC has a good reputation regarding the safety of the data (the mechanics are simpler and more robust than for helical scan drives). Tapes should be retired from use after 5,000 backups. _9_._2_._4 _* _M_i_n_i_-_C_a_r_t_r_i_d_g_e _9_._2_._5 _D_L_T DLT has the fastest data transfer rate of all the drive types listed here. The 1/2" (12.5mm) tape is contained in a single spool cartridge (4 x 4 x 1 inches; 100 x 100 x 25 mm). The cartridge has a swinging gate along one entire side of the cartridge. The drive mechanism opens this gate to extract the tape leader. FreeBSD Handbook 186 The tape leader has an oval hole in it which the drive uses to "hook" the tape. The take-up spool is located inside the tape drive. All the other tape car tridges listed here (9 track tapes are the only exception) have both the supply and take-up spools located inside the tape cartridge itself. Data thruput is approximately 1.5MB/s, three times the thruput of 4mm, 8mm, or QIC tape drives. Data capacities range from 10GB to 20GB for a single drive. Drives are available in both multi-tape changers and multi-tape, multi-drive tape libraries containing from 5 to 900 tapes over 1 to 20 drives, providing from 50GB to 9TB of storage. Data is recorded onto the tape in tracks parallel to the direction of travel (just like QIC tapes). Two tracks are written at once. Read/write head life times are relatively long; once the tape stops moving, there is no relative motion between the heads and the tape. _9_._2_._6 _U_s_i_n_g _a _n_e_w _t_a_p_e _f_o_r _t_h_e _f_i_r_s_t _t_i_m_e The first time that you try to read or write a new, completely blank tape, the operation will fail. The console messages should be similar to: st0(ncr1:4:0): NOT READY asc:4,1 st0(ncr1:4:0): Logical unit is in process of becoming ready The tape does not contain an Identifier Block (block number 0). All QIC tape drives since the adoption of QIC-525 standard write an Identifier Block to the tape. There are two solutions: mt fsf 1 causes the tape drive to write an Identifier Block to the tape. Use the front panel button to eject the tape. Re-insert the tape and dump(8) data to the tape. dump(8) will report DUMP: End of tape detected and the console will show: HARD WARE FAILURE info:280 asc:80,96 rewind the tape using: mt rewind Subsequent tape operations are successful. _9_._3 _B_a_c_k_u_p _P_r_o_g_r_a_m_s The three major programs are dump(8), tar(1), and cpio(1). _9_._3_._1 _D_u_m_p _a_n_d _R_e_s_t_o_r_e dump(8) and restore(8) are the traditional Unix backup programs. They operate on the drive as a collection of disk blocks, below the abstractions of files, links and directories that are created by the filesystems. dump(8) backs up devices, entire filesystems, not parts of a filesystem and not directory trees that span more than one filesystem, using either soft links ln(1) or mounting one filesystem onto another. dump(8) does not write files and directories to tape, but rather writes the data blocks that are the building blocks of files FreeBSD Handbook 187 and directories. dump(8) has quirks that remain from its early days in Version 6 of ATT Unix (circa 1975). The default parameters are suitable for 9-track tapes (6250 bpi), not the high-density media available today (up to 62,182 ftpi). These defaults must be overridden on the command line to utilize the capacity of current tape drives. rdump(8) and rrestore(8) backup data across the network to a tape drive attached to another computer. Both programs rely upon rcmd(3) and ruserok(3) to access the remote tape drive. Therefore, the user performing the backup must have rhosts access to the remote computer. The arguments to rdump(8) and rrestore(8) must suitable to use on the remote computer. (e.g. When rdump'ing from a FreeBSD computer to an Exabyte tape drive connected to a Sun called komodo, use: /sbin/rdump 0dsbfu 54000 13000 126 komodo:/dev/nrst8 /dev/rsd0a 2>&1) Beware: there are security implications to allowing rhosts commands. Evaluate your situation carefully. _9_._3_._2 _T_a_r tar(1) also dates back to Version 6 of ATT Unix (circa 1975). tar(1) operates in cooperation with the filesystem; tar(1) writes files and directories to tape. tar(1) does not support the full range of options that are available from cpio(1), but tar(1) does not require the unusual command pipeline that cpio(1) uses. Most versions of tar(1) do not support backups across the network. The GNU version of tar(1), which FreeBSD utilizes, supports remote devices using the same syntax as rdump. To tar(1) to an Exabyte tape drive connected to a Sun called komodo, use: /usr/bin/tar cf komodo:/dev/nrst8 . 2>&1. For versions without remote device support, you can use a pipeline and rsh(1) to send the data to a remote tape drive. (XXX add an example command) _9_._3_._3 _C_p_i_o cpio(1) is the original Unix file interchange tape program for magnetic media. cpio(1) has options (among many others) to perform byte-swapping, write a num ber of different archives format, and pipe the data to other programs. This last feature makes cpio(1) and excellent choice for installation media. cpio(1) does not know how to walk the directory tree and a list of files must be provided thru STDIN. cpio(1) does not support backups across the network. You can use a pipeline and rsh(1) to send the data to a remote tape drive. (XXX add an example com mand) _9_._3_._4 _P_a_x pax(1) is IEEE/POSIX's answer to tar and cpio. Over the years the various ver sions of tar and cpio have gotten slightly incompatible. So rather than fight it out to fully standardize them, POSIX created a new archive utility. pax attempts to read and write many of the various cpio and tar formats, plus new formats of its own. Its command set more resembles cpio than tar. FreeBSD Handbook 188 _9_._3_._5 _A_m_a_n_d_a Amanda (Advanced Maryland Network Disk Archiver) is a client/server backup sys tem, rather than a single program. An Amanda server will backup to a single tape drive any number of computers that have Amanda clients and network commu nications with the Amanda server. A common problem at locations with a number of large disks is the length of time required to backup to data directly to tape exceeds the amount of time available for the task. Amanda solves this problem. Amanda can use a "holding disk" to backup several filesystems at the same time. Amanda creates "archive sets": a group of tapes used over a period of time to create full backups of all the filesystems listed in Amanda's con figuration file. The "archive set" also contains nightly incremental (or dif ferential) backups of all the filesystems. Restoring a damaged filesystem requires the most recent full backup and the incremental backups. The configuration file provides fine control backups and the network traffic that Amanda generates. Amanda will use any of the above backup programs to write the data to tape. Amanda is available as either a port or a package, it is not installed by default. _9_._3_._6 _D_o _n_o_t_h_i_n_g "Do nothing" is not a computer program, but it is the most widely used backup strategy. There are no initial costs. There is no backup schedule to follow. Just say no. If something happens to your data, grin and bear it! If your time and your data is worth little to nothing, then "Do nothing" is the most suitable backup program for your computer. But beware, Unix is a useful tool, you may find that within six months you have a collection of files that are valuable to you. "Do nothing" is the correct backup method for /usr/obj and other directory trees that can be exactly recreated by your computer. An example is the files that comprise these handbook pages-they have been generated from SGML input files. Creating backups of these HTML files is not necessary. The SGML source files are backed up regularly. _9_._3_._7 _W_h_i_c_h _B_a_c_k_u_p _P_r_o_g_r_a_m _i_s _B_e_s_t_? dump(8) _P_e_r_i_o_d_. Elizabeth D. Zwicky torture tested all the backup programs dis cussed here. The clear choice for preserving all your data and all the pecu liarities of Unix filesystems is dump(8). Elizabeth created filesystems con taining a large variety of unusual conditions (and some not so unusual ones) and tested each program by do a backup and restore of that filesystems. The peculiarities included: files with holes, files with holes and a block of nulls, files with funny characters in their names, unreadable and unwritable files, devices, files that change size during the backup, files that are cre ated/deleted during the backup and more. She presented the results at LISA V in Oct. 1991. See torture-testing Backup and Archive Programs. _9_._3_._8 _E_m_e_r_g_e_n_c_y _R_e_s_t_o_r_e _P_r_o_c_e_d_u_r_e FreeBSD Handbook 189 _9_._3_._8_._1 _B_e_f_o_r_e _t_h_e _D_i_s_a_s_t_e_r There are only four steps that you need to perform in preparation for any dis aster that may occur. First, print the disklabel from each of your disks (e.g. disklabel sd0 | lpr), your filesystem table (/etc/fstab) and all boot messages, two copies of each. Second, determine that the boot and fixit floppies (boot.flp and fixit.flp) have all your devices. The easiest way to check is to reboot your machine with the boot floppy in the floppy drive and check the boot messages. If all your devices are listed and functional, skip on to step three. Otherwise, you have to create two custom bootable floppies which has a kernel that can mount your all of your disks and access your tape drive. These flop pies must contain: fdisk(8), disklabel(8), newfs(8), mount(8), and whichever backup program you use. These programs must be statically linked. If you use dump(8), the floppy must contain restore(8). Third, create backup tapes regularly. Any changes that you make after your last backup may be irretrievably lost. Write-protect the backup tapes. Fourth, test the floppies (either boot.flp and fixit.flp or the two custom bootable floppies you made in step two.) and backup tapes. Make notes of the procedure. Store these notes with the bootable floppy, the printouts and the backup tapes. You will be so distraught when restoring that the notes may pre vent you from destroying your backup tapes (How? In place of tar xvf /dev/rst0, you might accidently type tar cvf /dev/rst0 and over-write your backup tape). For an added measure of security, make bootable floppies and two backup tapes each time. Store one of each at a remote location. A remote location is NOT the basement of the same office building. A number of firms in the World Trade Center learned this lesson the hard way. A remote location should be physi cally separated from your computers and disk drives by a significant distance. An example script for creating a bootable floppy: FreeBSD Handbook 190 #!/bin/sh # # create a restore floppy # # format the floppy # PATH=/bin:/sbin:/usr/sbin:/usr/bin fdformat -q fd0 if [ $? -ne 0 ] then echo "Bad floppy, please use a new one" exit 1 fi # place boot blocks on the floppy # disklabel -w -B -b /usr/mdec/fdboot -s /usr/mdec/bootfd /dev/rfd0c fd1440 # # newfs the one and only partition # newfs -t 2 -u 18 -l 1 -c 40 -i 5120 -m 5 -o space /dev/rfd0a # # mount the new floppy # mount /dev/fd0a /mnt # # create required directories # mkdir /mnt/dev mkdir /mnt/bin mkdir /mnt/sbin mkdir /mnt/etc mkdir /mnt/root mkdir /mnt/mnt # for the root partition mkdir /mnt/tmp mkdir /mnt/var # # populate the directories # if [ ! -x /sys/compile/MINI/kernel ] then cat << EOM The MINI kernel does not exist, please create one. Here is an example config file: # # MINI -- A kernel to get FreeBSD on onto a disk. # machine "i386" cpu "I486_CPU" FreeBSD Handbook 191 ident MINI maxusers 5 options INET # needed for _tcp _icmpstat _ipstat # _udpstat _tcpstat _udb options FFS #Berkeley Fast File System options FAT_CURSOR #block cursor in syscons or pccons options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device options NCONS=2 #1 virtual consoles options USERCONFIG #Allow user configuration with -c XXX config kernel root on sd0 swap on sd0 and sd1 dumps on sd0 controller isa0 controller pci0 controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2 vector fdintr disk fd0 at fdc0 drive 0 controller ncr0 controller scbus0 device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr device npx0 at isa? port "IO_NPX" irq 13 vector npxintr device sd0 device sd1 device sd2 device st0 pseudo-device loop # required by INET pseudo-device gzip # Exec gzipped a.out's EOM exit 1 fi cp -f /sys/compile/MINI/kernel /mnt gzip -c -best /sbin/init > /mnt/sbin/init gzip -c -best /sbin/fsck > /mnt/sbin/fsck gzip -c -best /sbin/mount > /mnt/sbin/mount gzip -c -best /sbin/halt > /mnt/sbin/halt gzip -c -best /sbin/restore > /mnt/sbin/restore gzip -c -best /bin/sh > /mnt/bin/sh gzip -c -best /bin/sync > /mnt/bin/sync cp /root/.profile /mnt/root cp -f /dev/MAKEDEV /mnt/dev chmod 755 /mnt/dev/MAKEDEV FreeBSD Handbook 192 chmod 500 /mnt/sbin/init chmod 555 /mnt/sbin/fsck /mnt/sbin/mount /mnt/sbin/halt chmod 555 /mnt/bin/sh /mnt/bin/sync chmod 6555 /mnt/sbin/restore # # create the devices nodes # cd /mnt/dev ./MAKEDEV std ./MAKEDEV sd0 ./MAKEDEV sd1 ./MAKEDEV sd2 ./MAKEDEV st0 ./MAKEDEV pty0 cd / # # create minimum filesystem table # cat > /mnt/etc/fstab < /mnt/etc/passwd < /mnt/etc/master.passwd <. 26 February 1996 Quotas are an optional feature of the operating system that allow you to limit the amount of disk space and/or the number of files a user, or members of a group, may allocate on a per-file system basis. This is used most often on timesharing systems where it is desirable to limit the amount of resources any one user or group of users may allocate. This will prevent one user from con suming all of the available disk space. _1_0_._1 _C_o_n_f_i_g_u_r_i_n_g _Y_o_u_r _S_y_s_t_e_m _t_o _E_n_a_b_l_e _D_i_s_k _Q_u_o_t_a_s Before attempting to use disk quotas it is necessary to make sure that quotas are configured in your kernel. This is done by adding the following line to your kernel configuration file: options QUOTA The stock GENERIC kernel does not have this enabled by default, so you will have to configure, build and install a custom kernel in order to use disk quo tas. Please refer to the _C_o_n_f_i_g_u_r_i_n_g _t_h_e _F_r_e_e_B_S_D _K_e_r_n_e_l (section 5., page 79) section for more information on kernel configuration. Next you will need to enable disk quotas in /etc/sysconfig. This is done by changing the line: FreeBSD Handbook 194 quotas=NO to: quotas=YES If you are running FreeBSD 2.2.2 or later, the configuration file will be /etc/rc.conf instead and the variable name changed to check_quotas=YES Finally you will need to edit /etc/fstab to enable disk quotas on a per-file system basis. This is where you can either enable user or group quotas or both for all of your file systems. To enable per-user quotas on a file system, add the userquota option to the options field in the /etc/fstab entry for the file system you want to to enable quotas on. For example: /dev/sd1s2g /home ufs rw,userquota 1 2 Similarly, to enable group quotas, use the groupquota option instead of the userquota keyword. To enable both user and group quotas, change the entry as follows: /dev/sd1s2g /home ufs rw,userquota,groupquota 1 2 By default the quota files are stored in the root directory of the file system with the names quota.user and quota.group for user and group quotas respec tively. See man fstab for more information. Even though that man page says that you can specify an alternate location for the quota files, this is not recommended since all of the various quota utilities do not seem to handle this properly. At this point you should reboot your system with your new kernel. /etc/rc will automatically run the appropriate commands to create the initial quota files for all of the quotas you enabled in /etc/fstab, so there is no need to manu ally create any zero length quota files. In the normal course of operations you should not be required to run the quo tacheck, quotaon, or quotaoff commands manually. However, you may want to read their man pages just to be familiar with their operation. _1_0_._2 _S_e_t_t_i_n_g _Q_u_o_t_a _L_i_m_i_t_s Once you have configured your system to enable quotas, verify that they really are enabled. An easy way to do this is to run quota -v. You should see a one line summary of disk usage and current quota limits for each file system that quotas are enabled on. You are now ready to start assigning quota limits with the edquota command. You have several options on how to enforce limits on the amount of disk space a FreeBSD Handbook 195 user or group may allocate, and how many files they may create. You may limit allocations based on disk space (block quotas) or number of files (inode quo tas) or a combination of both. Each of these limits are further broken down into two categories: hard and soft limits. A hard limit may not be exceeded. Once a user reaches their hard limit they may not make any further allocations on the file system in question. For exam ple, if the user has a hard limit of 500 blocks on a file system and is cur rently using 490 blocks, the user can only allocate an additional 10 blocks. Attempting to allocate an additional 11 blocks will fail. Soft limits on the other hand can be exceeded for a limited amount of time. This period of time is known as the grace period, which is one week by default. If a user stays over his or her soft limit longer than their grace period, the soft limit will turn into a hard limit and no further allocations will be allowed. When the user drops back below the soft limit, the grace period will be reset. The following is an example of what you might see when you run then edquota command. When the edquota command is invoked, you are placed into the editor specified by the EDITOR environment variable, or in the vi editor if the EDITOR variable is not set, to allow you to edit the quota limits. # edquota -u test Quotas for user test: /usr: blocks in use: 65, limits (soft = 50, hard = 75) inodes in use: 7, limits (soft = 50, hard = 60) /usr/var: blocks in use: 0, limits (soft = 50, hard = 75) inodes in use: 0, limits (soft = 50, hard = 60) You will normally see two lines for each file system that has quotas enabled. One line for the block limits, and one line for inode limits. Simply change the value you want updated to modify the quota limit. For example, to raise this users block limit from a soft limit of 50 and a hard limit of 75 to a soft limit of 500 and a hard limit of 600, change: /usr: blocks in use: 65, limits (soft = 50, hard = 75) to: /usr: blocks in use: 65, limits (soft = 500, hard = 600) The new quota limits will be in place when you exit the editor. Sometimes it is desirable to set quota limits on a range of uids. This can be done by use of the -p option on the edquota command. First, assign the desired quota limit to a user, and then run edquota -p protouser startuid-enduid. For example, if user test has the desired quota limits, the following command can be used to duplicate those quota limits for uids 10,000 through 19,999: edquota -p test 10000-19999 FreeBSD Handbook 196 The ability to specify uid ranges was added to the system after 2.1 was released. If you need this feature on a 2.1 system, you will need to obtain a newer copy of edquota. See man edquota for more detailed information. _1_0_._3 _C_h_e_c_k_i_n_g _Q_u_o_t_a _L_i_m_i_t_s _a_n_d _D_i_s_k _U_s_a_g_e You can use either the quota or the repquota commands to check quota limits and disk usage. The quota command can be used to check individual user and group quotas and disk usage. Only the super-user may examine quotas and usage for other users, or for groups that they are not a member of. The repquota command can be used to get a summary of all quotas and disk usage for file systems with quotas enabled. The following is some sample output from the quota -v command for a user that has quota limits on two file systems. Disk quotas for user test (uid 1002): Filesystem blocks quota limit grace files quota limit grace /usr 65* 50 75 5days 7 50 60 /usr/var 0 50 75 0 50 60 On the /usr file system in the above example this user is currently 15 blocks over their soft limit of 50 blocks and has 5 days of their grace period left. Note the asterisk (*) which indicates that the user is currently over their quota limit. Normally file systems that the user is not using any disk space on will not show up in the output from the quota command, even if they have a quota limit assigned for that file system. The -v option will display those file systems, such as the /usr/var file system in the above example. _1_0_._4 _* _Q_u_o_t_a_s _o_v_e_r _N_F_S This section is still under development. _1_1_. _T_h_e _X _W_i_n_d_o_w _S_y_s_t_e_m Pending the completion of this section, please refer to documentation supplied by the The XFree86 Project, Inc11 . _1_2_. _P_C _H_a_r_d_w_a_r_e _c_o_m_p_a_t_i_b_i_l_i_t_y Issues of hardware compatibility are among the most troublesome in the computer industry today and FreeBSD is by no means immune to trouble. In this respect, FreeBSD's advantage of being able to run on inexpensive commodity PC hardware is also its liability when it comes to support for the amazing variety of ____________________ 11. FreeBSD Handbook 197 components on the market. While it would be impossible to provide a exhaustive listing of hardware that FreeBSD supports, this section serves as a catalog of the device drivers included with FreeBSD and the hardware each drivers sup ports. Where possible and appropriate, notes about specific products are included. You may also want to refer to _t_h_e _k_e_r_n_e_l _c_o_n_f_i_g_u_r_a_t_i_o_n _f_i_l_e (section 5.3, page 81) section in this handbook for a list of supported devices. As FreeBSD is a volunteer project without a funded testing department, we depend on you, the user, for much of the information contained in this catalog. If you have direct experience of hardware that does or does not work with FreeBSD, please let us know by sending e-mail to the FreeBSD documentation pro ject mailing list . Questions about supported hard ware should be directed to the FreeBSD general questions mailing list (see _M_a_i_l_i_n_g _L_i_s_t_s (section 27.1, page 467) for more information). When submitting information or asking a question, please remem ber to specify exactly what version of FreeBSD you are using and include as many details of your hardware as possible. _1_2_._1 _R_e_s_o_u_r_c_e_s _o_n _t_h_e _I_n_t_e_r_n_e_t The following links have proven useful in selecting hardware. Though some of what you see won't necessarily be specific (or even applicable) to FreeBSD, most of the hardware information out there is OS independent. Please check with the FreeBSD hardware guide to make sure that your chosen configuration is supported before making any purchases. The Pentium Systems Hardware Performance Guide _1_2_._2 _S_a_m_p_l_e _C_o_n_f_i_g_u_r_a_t_i_o_n_s The following list of sample hardware configurations by no means constitutes an endorsement of a given hardware vendor or product by _T_h_e _F_r_e_e_B_S_D _P_r_o_j_e_c_t. This information is provided only as a public service and merely catalogs some of the experiences that various individuals have had with different hardware com binations. Your mileage may vary. Slippery when wet. Beware of dog. _1_2_._2_._1 _J_o_r_d_a_n_'_s _P_i_c_k_s I have had fairly good luck building workstation and server configurations with the following components. I can't guarantee that you will too, nor that any of the companies here will remain "best buys" forever. I will try, when I can, to keep this list up-to-date but cannot obviously guarantee that it will be at any given time. _1_2_._2_._1_._1 _M_o_t_h_e_r_b_o_a_r_d_s For Pentium Pro (P6) systems, I'm quite fond of the Tyan S1668 dual-processor motherboard as well as the Intel PR440FX motherboard with on-board SCSI WIDE and 100/10MB Intel Etherexpress NIC. You can build a dandy little single or dual processor system (which is supported in FreeBSD 3.0) for very little cost now that the Pentium Pro 180/256K chips have fallen so greatly in price, but no telling how much longer this will last. For the Pentium II, I'm rather partial to the ASUS P2l97-S motherboard with the FreeBSD Handbook 198 on-board Adaptec SCSI WIDE controller. For Pentium machines, the ASUS P55T2P4 motherboard appears to be a good choice for a mid-to-high range Pentium server or workstation system. Those wishing to build more fault-tolerant systems should also be sure to use Parity memory or, for truly 24/7 applications, ECC memory. Note that ECC mem ory does involve a slight performance trade-off (which may or may not be noticeable depending on your application) but buys you significantly increased fault-tolerance to memory errors. _1_2_._2_._1_._2 _D_i_s_k _C_o_n_t_r_o_l_l_e_r_s This one is a bit trickier, and while I used to recommend the Buslogic con trollers unilaterally for everything from ISA to PCI, now I tend to lean towards the Adaptec 1542CF for ISA, Buslogic Bt747c for EISA and Adaptec 2940UW for PCI. The NCR/Symbios cards for PCI have also worked well for me, though you need to make sure that your motherboard supports the BIOS-less model if you're using one of those (if your card has nothing which looks even vaguely like a ROM chip on it, you've probably got one which expects its BIOS to be on your mother board). If you should find that you need more than one SCSI controller in a PCI machine, you may wish to consider conserving your scarce PCI bus resources by buying the Adaptec 3940 card, which puts two SCSI controllers (and internal busses) in a single slot. Note that there are two types of 3940 on the market - the older model with AIC 7880 chips on it, and the newer one with AIC 7895 chips. The newer model requires CAM support which is not yet a part of FreeBSD - you have to add it, or install from one of the CAM binary snapshot releases (follow the URL). _1_2_._2_._1_._3 _D_i_s_k _d_r_i_v_e_s In this particular game of Russian roulette, I'll make few specific recommenda tions except to say "SCSI over IDE whenever you can afford it." Even in small desktop configurations, SCSI often makes more sense since it allows you to eas ily migrate drives from server to desktop as falling drive prices make it eco nomical to do so. If you have more than one machine to administer then think of it not simply as storage, think of it as a food chain! For a serious server configuration, there's not even any argument - use SCSI equipment and good cables. :) _1_2_._2_._1_._4 _C_D_R_O_M _d_r_i_v_e_s My SCSI preferences extend to SCSI CDROM drives as well, and while the Toshiba drives have always been favorites of mine (in whatever speed is hot that week), I'm still fond of my good old Plextor PX-12CS drive. It's only a 12 speed, but it's offered excellent performance and reliability. Generally speaking, most SCSI CDROM drives I've seen have been of pretty solid construction and you probably won't go wrong with an HP or NEC SCSI CDROM drive either. SCSI CDROM prices also appear to have dropped considerably in the last FreeBSD Handbook 199 few months and are now quite competitive with IDE CDROMs while remaining a technically superior solution. I now see no reason whatsoever to settle for an IDE CDROM drive if given a choice between the two. _1_2_._2_._1_._5 _C_D _R_e_c_o_r_d_a_b_l_e _(_W_O_R_M_) _d_r_i_v_e_s At the time of this writing, FreeBSD supports 3 types of CDR drives (though I believe they all ultimately come from Phillips anyway): The Phillips CDD 522 (Acts like a Plasmon), the PLASMON RF4100 and the HP 6020i. I myself use the HP 6020i for burning CDROMs (in 2.2 and later releases - it does not work with earlier releases of the SCSI code) and it works very well. See /usr/share/examples/worm on your system for example scripts used to created ISO9660 filesystem images (with RockRidge extensions) and burn them onto an HP6020i CDR. _1_2_._2_._1_._6 _T_a_p_e _d_r_i_v_e_s I've had pretty good luck with both 8mm drives from Exabyte and 4mm (DAT) drives from HP. For backup purposes, I'd have to give the higher recommendation to the Exabyte due to the more robust nature (and higher storage capacity) of 8mm tape. _1_2_._2_._1_._7 _V_i_d_e_o _C_a_r_d_s If you can also afford to buy a commercial X server for US$99 from Xi Graphics, Inc. (formerly X Inside, Inc) then I can heartily recommend the Matrox Mille nium II cards. Note that support for this card is also very good with the XFree86 server, which is now at version 3.3.2. You also certainly can't go wrong with one of Number 9's cards - their S3 Vision 868 and 968 based cards (the 9FX series) also being quite fast and very well supported by XFree86's S3 server in addition to being extremely cheap, nowadays. You can also pick up their Revolution 3D cards very cheaply these days, especially if you require a lot of video memory. _1_2_._2_._1_._8 _M_o_n_i_t_o_r_s I have had very good luck with the Sony Multiscan 17seII monitors, as have I with the Viewsonic offering in the same (Trinitron) tube. For larger than 17", all I can recommend at the time of this writing is to not spend any less than U.S. $2,000 for a 21" monitor or $1,700 for a 20" monitor if that's what you really need. There are good monitors available in the >=20" range and there are also cheap monitors in the >=20" range. Unfortunately, very few are both cheap and good! _1_2_._2_._1_._9 _N_e_t_w_o_r_k_i_n_g I can recommend the Intel EtherExpress Pro/100B card first and foremost, fol lowed by the SMC Ultra 16 controller for ISA applications and the SMC SMC9332DST, SMC EtherPower or Compex ENET32 cards for slightly cheaper PCI based networking. In general, any PCI NIC based around DEC's DC2104x Ethernet controller chip, such as the Zynx ZX342 or DEC DE435, will generally work quite well and can frequently be found in 2-port and 4-port versions (useful for FreeBSD Handbook 200 firewalls and routers), though the Pro/100B card has the edge when it comes to providing the best performance with the lowest overhead. If what you're looking for is the cheapest possible solution, on the other hand, then almost any NE2000 clone will do a fine job for very little cost. _1_2_._2_._1_._1_0 _S_e_r_i_a_l If you're looking for high-speed serial networking solutions, then Digi Inter national makes the SYNC/570 series, with drivers now in FreeBSD-current. Emerg ing Technologies also manufactures a board with T1/E1 capabilities, using soft ware they provide. I have no direct experience using either product, however. Multiport card options are somewhat more numerous, though it has to be said that FreeBSD's support for Cyclades's products is probably the tightest, pri marily as a result of that company's commitment to making sure that we are ade quately supplied with evaluation boards and technical specs. I've heard that the Cyclom-16Ye offers the best price/performance, though I've not checked the prices lately. Other multiport cards I've heard good things about are the BOCA and AST cards, and Stallion Technologies apparently offers an unofficial driver for their cards at this location. _1_2_._2_._1_._1_1 _A_u_d_i_o I currently use a Creative Labs AWE32 though just about anything from Creative Labs will generally work these days. This is not to say that other types of sound cards don't also work, simply that I have little experience with them (I was a former GUS fan, but Gravis's soundcard situation has been dire for some time). _1_2_._2_._1_._1_2 _V_i_d_e_o For video capture, there are two good choices - any card based on the Brooktree BT848 chip, such as the Hauppage or WinTV boards, will work very nicely with FreeBSD. Another board which works for me is the Matrox Meteor card. FreeBSD also supports the older video spigot card from Creative Labs, but those are getting somewhat difficult to find. Note that the Meteor frame grabber card _w_i_l_l _n_o_t _w_o_r_k with motherboards based on the 440FX chipset! See the _m_o_t_h_e_r_ _b_o_a_r_d _r_e_f_e_r_e_n_c_e (section 12.2.1.1, page 197) section for details. In such cases, it's better to go with a BT848 based board. _1_2_._3 _C_o_r_e_/_P_r_o_c_e_s_s_i_n_g _1_2_._3_._1 _M_o_t_h_e_r_b_o_a_r_d_s_, _b_u_s_s_e_s_, _a_n_d _c_h_i_p_s_e_t_s _1_2_._3_._1_._1 _* _I_S_A _1_2_._3_._1_._2 _* _E_I_S_A _1_2_._3_._1_._3 _* _V_L_B _1_2_._3_._1_._4 _P_C_I _C_o_n_t_r_i_b_u_t_e_d _b_y _D_a_v_i_d _O_'_B_r_i_e_n from postings by Rodney FreeBSD Handbook 201 Grimes . 25 April 1995. _C_o_n_t_i_n_u_i_n_g _u_p_d_a_t_e_s _b_y _J_o_r_d_a_n _K_. _H_u_b_b_a_r_d . Last update on _2_6 _A_u_g_u_s_t _1_9_9_6_. Of the Intel PCI chip sets, the following list describes various types of known-brokenness and the degree of breakage, listed from worst to best. Mercury: Cache coherency problems, especially if there are ISA bus masters behind the ISA to PCI bridge chip. Hardware flaw, only known work around is to turn the cache off. Saturn-I _(_i_e_, _8_2_4_2_4_Z_X _a_t _r_e_v _0_, _1 _o_r _2_): Write back cache coherency problems. Hardware flaw, only known work around is to set the external cache to write-through mode. Upgrade to Saturn-II. Saturn-II _(_i_e_, _8_2_4_2_4_Z_X _a_t _r_e_v _3 _o_r _4_): Works fine, but many MB manufactures leave out the external dirty bit SRAM needed for write back operation. Work arounds are either run it in write through mode, or get the dirty bit SRAM installed. (I have these for the ASUS PCI/I-486SP3G rev 1.6 and later boards). Neptune: Can not run more than 2 bus master devices. Admitted Intel design flaw. Workarounds include do not run more than 2 bus masters, spe cial hardware design to replace the PCI bus arbiter (appears on Intel Altair board and several other Intel server group MB's). And of course Intel's official answer, move to the Triton chip set, we ``fixed it there''. Triton _(_i_e_, _4_3_0_F_X_): No known cache coherency or bus master problems, chip set does not implement parity checking. Workaround for parity issue. Use Tri ton-II based motherboards if you have the choice. Triton-II _(_i_e_, _4_3_0_H_X_): All reports on motherboards using this chipset have been favorable so far. No known problems. Orion: Early versions of this chipset suffered from a PCI write-posting bug which can cause noticeable performance degradation in applica tions where large amounts of PCI bus traffic is involved. B0 step ping or later revisions of the chipset fixed this problem. 440FX: This Pentium Pro support chipset seems to work well, and does not suffer from any of the early Orion chipset problems. It also sup ports a wider variety of memory, including ECC and parity. The only known problem with it is that the Matrox Meteor frame grabber FreeBSD Handbook 202 card doesn't like it. _1_2_._3_._2 _C_P_U_s_/_F_P_U_s _C_o_n_t_r_i_b_u_t_e_d _b_y _S_a_t_o_s_h_i _A_s_a_m_i . 26 December 1997. _1_2_._3_._2_._1 _P_6 _c_l_a_s_s _(_P_e_n_t_i_u_m _P_r_o_/_P_e_n_t_i_u_m _I_I_) Both the Pentium Pro and Pentium II work fine with FreeBSD. In fact, our main ftp site ftp.freebsd.org (also known as "ftp.cdrom.com", world's largest ftp site) runs FreeBSD on a Pentium Pro. Configurations details are available for interested parties. _1_2_._3_._2_._2 _P_e_n_t_i_u_m _c_l_a_s_s The Intel Pentium (P54C), Pentium MMX (P55C), AMD K6 and Cyrix/IBM 6x86MX pro cessors are all reported to work with FreeBSD. I will not go into details of which processor is faster than what, there are zillions of web sites on the Internet that tells you one way or another. :) Note that various CPUs have different voltage/cooling requirements. Make sure your motherboard can supply the exact voltage needed by the CPU. For instance, many recent MMX chips require split voltage (e.g., 2.9V core, 3.3V I/O). Also, some AMD and Cyrix/IBM chips run hotter than Intel chips. In that case, make sure you have good heatsink/fans (you can get the list of certified parts from their web pages). _1_2_._3_._2_._2_._1 _C_l_o_c_k _s_p_e_e_d_s _C_o_n_t_r_i_b_u_t_e_d _b_y _R_o_d_n_e_y _G_r_i_m_e_s . 1 October 1996. _U_p_d_a_t_e_d _b_y _S_a_t_o_s_h_i _A_s_a_m_i . 27 December 1997. Pentium class machines use different clock speeds for the various parts of the system. These being the speed of the CPU, external memory bus, and the PCI bus. It is not always true that a "faster" processor will make a system faster than a "slower" one, due to the various clock speeds used. Below is a table showing the differences: FreeBSD Handbook 203 Rated External Clock External to PCI Bus CPU and Memory Bus Internal Clock Clock MHz MHz** Multiplier MHz 60 60 1.0 30 66 66 1.0 33 75 50 1.5 25 90 60 1.5 30 100 50* 2 25 100 66 1.5 33 120 60 2 30 133 66 2 33 150 60 2.5 30 (Intel, AMD) 150 75 2 37.5 (Cyrix/IBM 6x86MX) 166 66 2.5 33 180 60 3 30 200 66 3 33 233 66 3.5 33 * The Pentium 100 can be run at either 50MHz external clock with a multiplier of 2 or at 66MHz and a multiplier of 1.5. ** 66 MHz may actually be 66.667 MHz, but don't assume so. As can be seen the best parts to be using are the 100, 133, 166, 200 and 233, with the exception that at a multiplier of 3 or more the CPU starves for mem ory. _1_2_._3_._2_._2_._2 _T_h_e _A_M_D _K_6 _B_u_g In 1997, there have been reports of the AMD K6 seg faulting during heavy compi lation. That problem has been fixed in 3Q '97. According to reports, K6 chips with date mark "9733" or larger (i.e., manufactured in the 33rd week of '97 or later) do not have this bug. _1_2_._3_._2_._3 _* _4_8_6 _c_l_a_s_s _1_2_._3_._2_._4 _* _3_8_6 _c_l_a_s_s _1_2_._3_._2_._5 _2_8_6 _c_l_a_s_s Sorry, FreeBSD does not run on 80286 machines. It is nearly impossible to run today's large full-featured UNIXes on such hardware. _1_2_._3_._3 _* _M_e_m_o_r_y The minimum amount of memory you must have to install FreeBSD is 5 MB. Once your system is up and running you can _b_u_i_l_d _a _c_u_s_t_o_m _k_e_r_n_e_l (section 5.2, page 80) that will use less memory. If you use the boot4.flp you can get away with having only 4 MB. _1_2_._3_._4 _* _B_I_O_S FreeBSD Handbook 204 _1_2_._4 _I_n_p_u_t_/_O_u_t_p_u_t _D_e_v_i_c_e_s _1_2_._4_._1 _* _V_i_d_e_o _c_a_r_d_s _1_2_._4_._2 _* _S_o_u_n_d _c_a_r_d_s _1_2_._4_._3 _S_e_r_i_a_l _p_o_r_t_s _a_n_d _m_u_l_t_i_p_o_r_t _c_a_r_d_s _1_2_._4_._3_._1 _T_h_e _U_A_R_T_: _W_h_a_t _i_t _i_s _a_n_d _h_o_w _i_t _w_o_r_k_s _C_o_p_y_r_i_g_h_t __1_9_9_6 _F_r_a_n_k _D_u_r_d_a _I_V , All Rights Reserved. 13 January 1996. The Universal Asynchronous Receiver/Transmitter (UART) controller is the key component of the serial communications subsystem of a computer. The UART takes bytes of data and transmits the individual bits in a sequential fashion. At the destination, a second UART re-assembles the bits into complete bytes. Serial transmission is commonly used with modems and for non-networked communi cation between computers, terminals and other devices. There are two primary forms of serial transmission: Synchronous and Asyn chronous. Depending on the modes that are supported by the hardware, the name of the communication sub-system will usually include a "A" if it supports Asyn chronous communications, and a "S" if it supports Synchronous communications. Both forms are described below. Some common acronyms are: UART Universal Asynchronous Receiver/Transmitter USART Universal Synchronous-Asynchronous Receiver/Transmitter _1_2_._4_._3_._1_._1 _S_y_n_c_h_r_o_n_o_u_s _S_e_r_i_a_l _T_r_a_n_s_m_i_s_s_i_o_n Synchronous serial transmission requires that the sender and receiver share a clock with one another, or that the sender provide a strobe or other timing signal so that the receiver knows when to "read" the next bit of the data. In most forms of serial Synchronous communication, if there is no data available at a given instant to transmit, a fill character must be sent instead so that data is always being transmitted. Synchronous communication is usually more efficient because only data bits are transmitted between sender and receiver, and synchronous communication can be more more costly if extra wiring and cir cuits are required to share a clock signal between the sender and receiver. A form of Synchronous transmission is used with printers and fixed disk devices in that the data is sent on one set of wires while a clock or strobe is sent on a different wire. Printers and fixed disk devices are not normally serial devices because most fixed disk interface standards send an entire word of data for each clock or strobe signal by using a separate wire for each bit of the word. In the PC industry, these are known as Parallel devices. FreeBSD Handbook 205 The standard serial communications hardware in the PC does not support Syn chronous operations. This mode is described here for comparison purposes only. _1_2_._4_._3_._1_._2 _A_s_y_n_c_h_r_o_n_o_u_s _S_e_r_i_a_l _T_r_a_n_s_m_i_s_s_i_o_n Asynchronous transmission allows data to be transmitted without the sender hav ing to send a clock signal to the receiver. Instead, the sender and receiver must agree on timing parameters in advance and special bits are added to each word which are used to synchronize the sending and receiving units. When a word is given to the UART for Asynchronous transmissions, a bit called the "Start Bit" is added to the beginning of each word that is to be transmit ted. The Start Bit is used to alert the receiver that a word of data is about to be sent, and to force the clock in the receiver into synchronization with the clock in the transmitter. These two clocks must be accurate enough to not have the frequency drift by more than 10% during the transmission of the remaining bits in the word. (This requirement was set in the days of mechani cal teleprinters and is easily met by modern electronic equipment.) After the Start Bit, the individual bits of the word of data are sent, with the Least Significant Bit (LSB) being sent first. Each bit in the transmission is transmitted for exactly the same amount of time as all of the other bits, and the receiver "looks" at the wire at approximately halfway through the period assigned to each bit to determine if the bit is a "1" or a "0". For example, if it takes two seconds to send each bit, the receiver will examine the signal to determine if it is a "1" or a "0" after one second has passed, then it will wait two seconds and then examine the value of the next bit, and so on. The sender does not know when the receiver has "looked" at the value of the bit. The sender only knows when the clock says to begin transmitting the next bit of the word. When the entire data word has been sent, the transmitter may add a Parity Bit that the transmitter generates. The Parity Bit may be used by the receiver to perform simple error checking. Then at least one Stop Bit is sent by the transmitter. When the receiver has received all of the bits in the data word, it may check for the Parity Bits (both sender and receiver must agree on whether a Parity Bit is to be used), and then the receiver looks for a Stop Bit. If the Stop Bit does not appear when it is supposed to, the UART considers the entire word to be garbled and will report a Framing Error to the host processor when the data word is read. The usual cause of a Framing Error is that the sender and receiver clocks were not running at the same speed, or that the signal was interrupted. Regardless of whether the data was received correctly or not, the UART automat ically discards the Start, Parity and Stop bits. If the sender and receiver are configured identically, these bits are not passed to the host. If another word is ready for transmission, the Start Bit for the new word can be sent as soon as the Stop Bit for the previous word has been sent. Because asynchronous data is "self synchronizing", if there is no data to FreeBSD Handbook 206 transmit, the transmission line can be idle. _1_2_._4_._3_._1_._3 _O_t_h_e_r _U_A_R_T _F_u_n_c_t_i_o_n_s In addition to the basic job of converting data from parallel to serial for transmission and from serial to parallel on reception, a UART will usually pro vide additional circuits for signals that can be used to indicate the state of the transmission media, and to regulate the flow of data in the event that the remote device is not prepared to accept more data. For example, when the device connected to the UART is a modem, the modem may report the presence of a carrier on the phone line while the computer may be able to instruct the modem to reset itself or to not take calls by asserting or deasserting one more more of these extra signals. The function of each of these additional signals is defined in the EIA RS232-C standard. _1_2_._4_._3_._1_._4 _T_h_e _R_S_2_3_2_-_C _a_n_d _V_._2_4 _S_t_a_n_d_a_r_d_s In most computer systems, the UART is connected to circuitry that generates signals that comply with the EIA RS232-C specification. There is also a CCITT standard named V.24 that mirrors the specifications included in RS232-C. _1_2_._4_._3_._1_._4_._1 _R_S_2_3_2_-_C _B_i_t _A_s_s_i_g_n_m_e_n_t_s _(_M_a_r_k_s _a_n_d _S_p_a_c_e_s_) In RS232-C, a value of "1" is called a "Mark" and a value of "0" is called a "Space". When a com munication line is idle, the line is said to be "Marking", or transmitting con tinuous "1" values. The Start bit always has a value of "0" (a Space). The Stop Bit always has a value of "1" (a Mark). This means that there will always be a Mark (1) to Space (0) transition on the line at the start of every word, even when multiple word are transmitted back to back. This guarantees that sender and receiver can resynchronize their clocks regardless of the content of the data bits that are being transmitted. The idle time between Stop and Start bits does not have to be an exact multiple (including zero) of the bit rate of the communication link, but most UARTs are designed this way for simplicity. In RS232-C, the "Marking" signal (a "1") is represented by a voltage between -2 VDC and -12 VDC, and a "Spacing" signal (a "0") is represented by a voltage between 0 and +12 VDC. The transmitter is supposed to send +12 VDC or -12 VDC, and the receiver is supposed to allow for some voltage loss in long cables. Some transmitters in low power devices (like portable computers) sometimes use only +5 VDC and -5 VDC, but these values are still acceptable to a RS232-C receiver, provided that the cable lengths are short. _1_2_._4_._3_._1_._4_._2 _R_S_2_3_2_-_C _B_r_e_a_k _S_i_g_n_a_l RS232-C also specifies a signal called a "Break", which is caused by sending continuous Spacing values (no Start or Stop bits). When there is no electricity present on the data circuit, the line is considered to be sending "Break". The "Break" signal must be of a duration longer than the time it takes to send a complete byte plus Start, Stop and Parity bits. Most UARTs can distinguish between a Framing Error and a Break, but if the UART cannot do this, the Fram ing Error detection can be used to identify Breaks. FreeBSD Handbook 207 In the days of teleprinters, when numerous printers around the country were wired in series (such as news services), any unit could cause a "Break" by tem porarily opening the entire circuit so that no current flowed. This was used to allow a location with urgent news to interrupt some other location that was currently sending information. In modern systems there are two types of Break signals. If the Break is longer than 1.6 seconds, it is considered a "Modem Break", and some modems can be pro grammed to terminate the conversation and go on-hook or enter the modems' com mand mode when the modem detects this signal. If the Break is smaller than 1.6 seconds, it signifies a Data Break and it is up to the remote computer to respond to this signal. Sometimes this form of Break is used as an Attention or Interrupt signal and sometimes is accepted as a substitute for the ASCII CONTROL-C character. Marks and Spaces are also equivalent to "Holes" and "No Holes" in paper tape systems. Note that Breaks cannot be generated from paper tape or from any other byte value, since bytes are always sent with Start and Stop bit. The UART is usu ally capable of generating the continuous Spacing signal in response to a spe cial command from the host processor. _1_2_._4_._3_._1_._4_._3 _R_S_2_3_2_-_C _D_T_E _a_n_d _D_C_E _D_e_v_i_c_e_s The RS232-C specification defines two types of equipment: the Data Terminal Equipment (DTE) and the Data Carrier Equipment (DCE). Usually, the DTE device is the terminal (or computer), and the DCE is a modem. Across the phone line at the other end of a conversation, the receiving modem is also a DCE device and the computer that is connected to that modem is a DTE device. The DCE device receives signals on the pins that the DTE device transmits on, and vice versa. When two devices that are both DTE or both DCE must be connected together with out a modem or a similar media translater between them, a NULL modem must be used. The NULL modem electrically re-arranges the cabling so that the trans mitter output is connected to the receiver input on the other device, and vice versa. Similar translations are performed on all of the control signals so that each device will see what it thinks are DCE (or DTE) signals from the other device. The number of signals generated by the DTE and DCE devices are not symmetrical. The DTE device generates fewer signals for the DCE device than the DTE device receives from the DCE. _1_2_._4_._3_._1_._4_._4 _R_S_2_3_2_-_C _P_i_n _A_s_s_i_g_n_m_e_n_t_s The EIA RS232-C specification (and the ITU equivalent, V.24) calls for a twenty-five pin connector (usually a DB25) and defines the purpose of most of the pins in that connector. In the IBM Personal Computer and similar systems, a subset of RS232-C signals are provided via nine pin connectors (DB9). The signals that are not included on the PC connector deal mainly with synchronous operation, and this transmis sion mode is not supported by the UART that IBM selected for use in the IBM PC. Depending on the computer manufacturer, a DB25, a DB9, or both types of connec tor may be used for RS232-C communications. (The IBM PC also uses a DB25 FreeBSD Handbook 208 connector for the parallel printer interface which causes some confusion.) Below is a table of the RS232-C signal assignments in the DB25 and DB9 connec tors. DB25 DB9 EIA CCITT Common Signal Description RS232-C IBM PC Circuit Circuit Name Source Pin Pin Symbol Symbol 1 - AA 101 PG/FG --- Frame/Protective Ground 2 3 BA 103 TD DTE Transmit Data 3 2 BB 104 RD DCE Receive Data 4 7 CA 105 RTS DTE Request to Send 5 8 CB 106 CTS DCE Clear to Send 6 6 CC 107 DSR DCE Data Set Ready 7 5 AV 102 SG/GND --- Signal Ground 8 1 CF 109 DCD/CD DCE Data Carrier Detect 9 - - - - - Reserved for Test 10 - - - - - Reserved for Test 11 - - - - - Unassigned 12 - CI 122 SRLSD DCE Sec. Recv. Line Signal Detector 13 - SCB 121 SCTS DCE Secondary Clear To Send 14 - SBA 118 STD DTE Secondary Transmit Data 15 - DB 114 TSET DCE Trans. Sig. Element Timing 16 - SBB 119 SRD DCE Secondary Received Data 17 - DD 115 RSET DCE Receiver Signal Element Timing 18 - - 141 LOOP DTE Local Loopback 19 - SCA 120 SRS DTE Secondary Request to Send 20 4 CD 108.2 DTR DTE Data Terminal Ready 21 - - - RDL DTE Remote Digital Loopback 22 9 CE 125 RI DCE Ring Indicator 23 - CH 111 DSRS DTE Data Signal Rate Selector 24 - DA 113 TSET DTE Trans. Sig. Element Timing 25 - - 142 - DCE Test Mode _1_2_._4_._3_._1_._5 _B_i_t_s_, _B_a_u_d _a_n_d _S_y_m_b_o_l_s Baud is a measurement of transmission speed in asynchronous communication. Because of advances in modem communication technology, this term is frequently misused when describing the data rates in newer devices. Traditionally, a Baud Rate represents the number of bits that are actually being sent over the media, not the amount of data that is actually moved from one DTE device to the other. The Baud count includes the overhead bits Start, Stop and Parity that are generated by the sending UART and removed by the receiving UART. This means that seven-bit words of data actually take 10 bits to be completely transmitted. Therefore, a modem capable of moving 300 bits per second from one place to another can normally only move 30 7-bit words if Parity is used and one Start and Stop bit are present. If 8-bit data words are used and Parity bits are also used, the data rate falls to 27.27 words per second, because it now takes 11 bits to send the eight-bit words, and the modem still only sends 300 bits per second. FreeBSD Handbook 209 The formula for converting bytes per second into a baud rate and vice versa was simple until error-correcting modems came along. These modems receive the serial stream of bits from the UART in the host computer (even when internal modems are used the data is still frequently serialized) and converts the bits back into bytes. These bytes are then combined into packets and sent over the phone line using a Synchronous transmission method. This means that the Stop, Start, and Parity bits added by the UART in the DTE (the computer) were removed by the modem before transmission by the sending modem. When these bytes are received by the remote modem, the remote modem adds Start, Stop and Parity bits to the words, converts them to a serial format and then sends them to the receiving UART in the remote computer, who then strips the Start, Stop and Par ity bits. The reason all these extra conversions are done is so that the two modems can perform error correction, which means that the receiving modem is able to ask the sending modem to resend a block of data that was not received with the cor rect checksum. This checking is handled by the modems, and the DTE devices are usually unaware that the process is occurring. By striping the Start, Stop and Parity bits, the additional bits of data that the two modems must share between themselves to perform error-correction are mostly concealed from the effective transmission rate seen by the sending and receiving DTE equipment. For example, if a modem sends ten 7-bit words to another modem without including the Start, Stop and Parity bits, the sending modem will be able to add 30 bits of its own information that the receiving modem can use to do error-correction without impacting the transmission speed of the real data. The use of the term Baud is further confused by modems that perform compres sion. A single 8-bit word passed over the telephone line might represent a dozen words that were transmitted to the sending modem. The receiving modem will expand the data back to its original content and pass that data to the receiving DTE. Modern modems also include buffers that allow the rate that bits move across the phone line (DCE to DCE) to be a different speed than the speed that the bits move between the DTE and DCE on both ends of the conversation. Normally the speed between the DTE and DCE is higher than the DCE to DCE speed because of the use of compression by the modems. Because the number of bits needed to describe a byte varied during the trip between the two machines plus the differing bits-per-seconds speeds that are used present on the DTE-DCE and DCE-DCE links, the usage of the term Baud to describe the overall communication speed causes problems and can misrepresent the true transmission speed. So Bits Per Second (bps) is the correct term to use to describe the transmission rate seen at the DCE to DCE interface and Baud or Bits Per Second are acceptable terms to use when a connection is made between two systems with a wired connection, or if a modem is in use that is not performing error-correction or compression. Modern high speed modems (2400, 9600, 14,400, and 19,200bps) in reality still operate at or below 2400 baud, or more accurately, 2400 Symbols per second. High speed modem are able to encode more bits of data into each Symbol using a technique called Constellation Stuffing, which is why the effective bits per FreeBSD Handbook 210 second rate of the modem is higher, but the modem continues to operate within the limited audio bandwidth that the telephone system provides. Modems operat ing at 28,800 and higher speeds have variable Symbol rates, but the technique is the same. _1_2_._4_._3_._1_._6 _T_h_e _I_B_M _P_e_r_s_o_n_a_l _C_o_m_p_u_t_e_r _U_A_R_T Starting with the original IBM Personal Computer, IBM selected the National Semiconductor INS8250 UART for use in the IBM PC Parallel/Serial Adapter. Sub sequent generations of compatible computers from IBM and other vendors contin ued to use the INS8250 or improved versions of the National Semiconductor UART family. _1_2_._4_._3_._1_._6_._1 _N_a_t_i_o_n_a_l _S_e_m_i_c_o_n_d_u_c_t_o_r _U_A_R_T _F_a_m_i_l_y _T_r_e_e There have been several versions and subsequent generations of the INS8250 UART. Each major version is described below. INS8250 -> INS8250B \ \ \-> INS8250A -> INS82C50A \ \ \-> NS16450 -> NS16C450 \ \ \-> NS16550 -> NS16550A -> PC16550D INS8250 This part was used in the original IBM PC and IBM PC/XT. The orig inal name for this part was the INS8250 ACE (Asynchronous Communi cations Element) and it is made from NMOS technology. The 8250 uses eight I/O ports and has a one-byte send and a one- byte receive buffer. This original UART has several race condi tions and other flaws. The original IBM BIOS includes code to work around these flaws, but this made the BIOS dependent on the flaws being present, so subsequent parts like the 8250A, 16450 or 16550 could not be used in the original IBM PC or IBM PC/XT. INS8250-B This is the slower speed of the INS8250 made from NMOS technology. It contains the same problems as the original INS8250. INS8250A An improved version of the INS8250 using XMOS technology with vari ous functional flaws corrected. The INS8250A was used initially in PC clone computers by vendors who used "clean" BIOS designs. Because of the corrections in the chip, this part could not be used with a BIOS compatible with the INS8250 or INS8250B. INS82C50A This is a CMOS version (low power consumption) of the INS8250A and has similar functional characteristics. FreeBSD Handbook 211 NS16450 Same as NS8250A with improvements so it can be used with faster CPU bus designs. IBM used this part in the IBM AT and updated the IBM BIOS to no longer rely on the bugs in the INS8250. NS16C450 This is a CMOS version (low power consumption) of the NS16450. NS16550 Same as NS16450 with a 16-byte send and receive buffer but the buffer design was flawed and could not be reliably be used. NS16550A Same as NS16550 with the buffer flaws corrected. The 16550A and its successors have become the most popular UART design in the PC industry, mainly due it its ability to reliably handle higher data rates on operating systems with sluggish interrupt response times. NS16C552 This component consists of two NS16C550A CMOS UARTs in a single package. PC16550D Same as NS16550A with subtle flaws corrected. This is revision D of the 16550 family and is the latest design available from National Semiconductor. _1_2_._4_._3_._1_._6_._2 _T_h_e _N_S_1_6_5_5_0_A_F _a_n_d _t_h_e _P_C_1_6_5_5_0_D _a_r_e _t_h_e _s_a_m_e _t_h_i_n_g National reor ganized their part numbering system a few years ago, and the NS16550AFN no longer exists by that name. (If you have a NS16550AFN, look at the date code on the part, which is a four digit number that usually starts with a nine. The first two digits of the number are the year, and the last two digits are the week in that year when the part was packaged. If you have a NS16550AFN, it is probably a few years old.) The new numbers are like PC16550DV, with minor differences in the suffix let ters depending on the package material and its shape. (A description of the numbering system can be found below.) It is important to understand that in some stores, you may pay $15(US) for a NS16550AFN made in 1990 and in the next bin are the new PC16550DN parts with minor fixes that National has made since the AFN part was in production, the PC16550DN was probably made in the past six months and it costs half (as low as $5(US) in volume) as much as the NS16550AFN because they are readily available. As the supply of NS16550AFN chips continues to shrink, the price will probably continue to increase until more people discover and accept that the PC16550DN really has the same function as the old part number. _1_2_._4_._3_._1_._6_._3 _N_a_t_i_o_n_a_l _S_e_m_i_c_o_n_d_u_c_t_o_r _P_a_r_t _N_u_m_b_e_r_i_n_g _S_y_s_t_e_m The older NS_n_n_n_n_n_r_q_p part numbers are now of the format PC_n_n_n_n_n_r_g_p. The "_r" is the revision field. The current revision of the 16550 from National Semiconductor is "D". FreeBSD Handbook 212 The "_p" is the package-type field. The types are: "F" QFP (quad flat pack) L lead type "N" DIP (dual inline package) through hole straight lead type "V" LPCC (lead plastic chip carrier) J lead type The "_g" is the product grade field. If an "I" precedes the package-type let ter, it indicates an "industrial" grade part, which has higher specs than a standard part but not as high as Military Specification (Milspec) component. This is an optional field. So what we used to call a NS16550AFN (DIP Package) is now called a PC16550DN or PC16550DIN. _1_2_._4_._3_._1_._7 _O_t_h_e_r _V_e_n_d_o_r_s _a_n_d _S_i_m_i_l_a_r _U_A_R_T_s Over the years, the 8250, 8250A, 16450 and 16550 have been licensed or copied by other chip vendors. In the case of the 8250, 8250A and 16450, the exact circuit (the "megacell") was licensed to many vendors, including Western Digi tal and Intel. Other vendors reverse-engineered the part or produced emula tions that had similar behavior. In internal modems, the modem designer will frequently emulate the 8250A/16450 with the modem microprocessor, and the emulated UART will frequently have a hidden buffer consisting of several hundred bytes. Because of the size of the buffer, these emulations can be as reliable as a 16550A in their ability to handle high speed data. However, most operating systems will still report that the UART is only a 8250A or 16450, and may not make effective use of the extra buffering present in the emulated UART unless special drivers are used. Some modem makers are driven by market forces to abandon a design that has hun dreds of bytes of buffer and instead use a 16550A UART so that the product will compare favorably in market comparisons even though the effective performance may be lowered by this action. A common misconception is that all parts with "16550A" written on them are identical in performance. There are differences, and in some cases, outright flaws in most of these 16550A clones. When the NS16550 was developed, the National Semiconductor obtained several patents on the design and they also limited licensing, making it harder for other vendors to provide a chip with similar features. Because of the patents, reverse-engineered designs and emulations had to avoid infringing the claims covered by the patents. Subsequently, these copies almost never perform exactly the same as the NS16550A or PC16550D, which are the parts most computer and modem makers want to buy but are sometimes unwilling to pay the price required to get the genuine part. Some of the differences in the clone 16550A parts are unimportant, while others can prevent the device from being used at all with a given operating system or driver. These differences may show up when using other drivers, or when par ticular combinations of events occur that were not well tested or considered in the Windows driver. This is because most modem vendors and 16550-clone makers use the Microsoft drivers from Windows for Workgroups 3.11 and the Microsoft FreeBSD Handbook 213 MSD utility as the primary tests for compatibility with the NS16550A. This over-simplistic criteria means that if a different operating system is used, problems could appear due to subtle differences between the clones and genuine components. National Semiconductor has made available a program named COMTEST that performs compatibility tests independent of any OS drivers. It should be remembered that the purpose of this type of program is to demonstrate the flaws in the products of the competition, so the program will report major as well as extremely subtle differences in behavior in the part being tested. In a series of tests performed by the author of this document in 1994, compo nents made by National Semiconductor, TI, StarTech, and CMD as well as mega cells and emulations embedded in internal modems were tested with COMTEST. A difference count for some of these components is listed below. Because these tests were performed in 1994, they may not reflect the current performance of the given product from a vendor. It should be noted that COMTEST normally aborts when an excessive number or certain types of problems have been detected. As part of this testing, COMTEST was modified so that it would not abort no matter how many differences were encountered. Vendor Part number Errors aka "differences" reported National (PC16550DV) 0 * National (NS16550AFN) 0 National (NS16C552V) 0 * TI (TL16550AFN) 3 CMD (16C550PE) 19 StarTech (ST16C550J) 23 Rockwell reference modem with internal 16550 or an emulation (RC144DPi/C3000-25) 117 Sierra modem with an internal 16550 (SC11951/SC11351) 91 It is important to understand that a simple count of differences from COMTEST does not reveal a lot about what differences are important and which are not. For example, about half of the differences reported in the two modems listed above that have internal UARTs were caused by the clone UARTs not supporting five- and six-bit character modes. The real 16550, 16450, and 8250 UARTs all support these modes and COMTEST checks the functionality of these modes so over fifty differences are reported. However, almost no modern modem supports five- or six-bit characters, particularly those with error-correction and compression capabilities. This means that the differences related to five- and six-bit character modes can be discounted. FreeBSD Handbook 214 Many of the differences COMTEST reports have to do with timing. In many of the clone designs, when the host reads from one port, the status bits in some other port may not update in the same amount of time (some faster, some slower) as a _r_e_a_l NS16550AFN and COMTEST looks for these differences. This means that the number of differences can be misleading in that one device may only have one or two differences but they are extremely serious, and some other device that updates the status registers faster or slower than the reference part (that would probably never affect the operation of a properly written driver) could have dozens of differences reported. * To date, the author of this document has not found any non-National parts that report zero differences using the COMTEST program. It should also be noted that National has had five versions of the 16550 over the years and the newest parts behave a bit differently than the classic NS16550AFN that is con sidered the benchmark for functionality. COMTEST appears to turn a blind eye to the differences within the National product line and reports no errors on the National parts (except for the original 16550) even when there are official erratas that describe bugs in the A, B and C revisions of the parts, so this bias in COMTEST must be taken into account. COMTEST can be used as a screening tool to alert the administrator to the pres ence of potentially incompatible components that might cause problems or have to be handled as a special case. If you run COMTEST on a 16550 that is in a modem or a modem is attached to the serial port, you need to first issue a ATE0&W command to the modem so that the modem will not echo any of the test characters. If you forget to do this, COMTEST will report at least this one difference: Error (6)...Timeout interrupt failed: IIR = c1 LSR = 61 _1_2_._4_._3_._1_._8 _8_2_5_0_/_1_6_4_5_0_/_1_6_5_5_0 _R_e_g_i_s_t_e_r_s The 8250/16450/16550 UART occupies eight contiguous I/O port addresses. In the IBM PC, there are two defined locations for these eight ports and they are known collectively as COM1 and COM2. The makers of PC-clones and add-on cards have created two additional areas known as COM3 and COM4, but these extra COM ports conflict with other hardware on some systems. The most common conflict is with video adapters that provide IBM 8514 emulation. COM1 is located from 0x3f8 to 0x3ff and normally uses IRQ 4 COM2 is located from 0x2f8 to 0x2ff and normally uses IRQ 3 COM3 is located from 0x3e8 to 0x3ef and has no standardized IRQ COM4 is located from 0x2e8 to 0x2ef and has no standardized IRQ A description of the I/O ports of the 8250/16450/16550 UART is provided below. FreeBSD Handbook 215 I/O Access Description Port Allowed +0x00 write Transmit Holding Register (THR) (DLAB==0) Information written to this port are treated as data words and will be transmitted by the UART. +0x00 read Receive Buffer Register (RBR) (DLAB==0) Any data words received by the UART from the serial link are accessed by the host by reading this port. +0x00 write/read Divisor Latch LSB (DLL) (DLAB==1) This value will be divided from the master input clock (in the IBM PC, the master clock is 1.8432MHz) and the resulting clock will determine the baud rate of the UART. This register holds bits 0 thru 7 of the divisor. +0x01 write/read Divisor Latch MSB (DLH) (DLAB==1) This value will be divided from the master input clock (in the IBM PC, the master clock is 1.8432MHz) and the resulting clock will determine the baud rate of the UART. This register holds bits 8 thru 15 of the divisor. +0x01 write/read Interrupt Enable Register (IER) (DLAB==0) The 8250/16450/16550 UART classifies events into one of four categories. Each category can be configured to generate an interrupt when any of the events occurs. The 8250/16450/16550 UART generates a single external interrupt signal regardless of how many events in the enabled categories have occurred. It is up to the host processor to respond to the interrupt and then poll the enabled interrupt categories (usually all categories have interrupts enabled) to determine the true cause(s) of the interrupt. Bit 7 Reserved, always 0. Bit 6 Reserved, always 0. Bit 5 Reserved, always 0. Bit 4 Reserved, always 0. Bit 3 Enable Modem Status Interrupt (EDSSI) FreeBSD Handbook 216 Setting this bit to "1" allows the UART to generate an interrupt when a change occurs on one or more of the status lines. Bit 2 Enable Receiver Line Status Interrupt (ELSI) Setting this bit to "1" causes the UART to generate an interrupt when the an error (or a BREAK signal) has been detected in the incoming data. Bit 1 Enable Transmitter Holding Register Empty Interrupt (ETBEI) Setting this bit to "1" causes the UART to generate an interrupt when the UART has room for one or more additional characters that are to be transmitted. Bit 0 Enable Received Data Available Interrupt (ERBFI) Setting this bit to "1" causes the UART to generate an interrupt when the UART has received enough characters to exceed the trigger level of the FIFO, or the FIFO timer has expired (stale data), or a single character has been received when the FIFO is disabled. +0x02 write FIFO Control Register (FCR) (This port does not exist on the 8250 and 16450 UART.) Bit 7 Receiver Trigger Bit #1 Bit 6 Receiver Trigger Bit #0 These two bits control at what point the receiver is to generate an interrupt when the FIFO is active. 7 6 How many words are received before an interrupt is generated. 0 0 1 0 1 4 1 0 8 1 1 14 Bit 5 Reserved, always 0. Bit 4 Reserved, always 0. FreeBSD Handbook 217 Bit 3 DMA Mode Select If Bit 0 is set to "1" (FIFOs enabled), setting this bit changes the operation of the -RXRDY and -TXRDY signals from Mode 0 to Mode 1. Bit 2 Transmit FIFO Reset When a "1" is written to this bit, the contents of the FIFO are discarded. Any word currently being transmitted will be sent intact. This function is useful in aborting transfers. Bit 1 Receiver FIFO Reset When a "1" is written to this bit, the contents of the FIFO are discarded. Any word currently being assembled in the shift register will be received intact. Bit 0 16550 FIFO Enable When set, both the transmit and receive FIFOs are enabled. Any contents in the holding register, shift registers or FIFOs are lost when FIFOs are enabled or disabled. +0x02 read Interrupt Identification Register (IIR) Bit 7 FIFOs enabled. On the 8250/16450 UART, this bit is zero. Bit 6 FIFOs enabled. On the 8250/16450 UART, this bit is zero. Bit 5 Reserved, always 0. Bit 4 Reserved, always 0. Bit 3 Interrupt ID Bit #2 On the 8250/16450 UART, this bit is zero. Bit 2 Interrupt ID Bit #1 Bit 1 Interrupt ID Bit #0 These three bits combine to report the category of event that caused the interrupt that is in progress. These categories have priorities, so if multiple categories of events occur at the same time, the UART will report the more important events first and the host must resolve the events in the order they are reported. All events that caused the current interrupt must be resolved before FreeBSD Handbook 218 any new interrupts will be generated. (This is a limitation of the PC architecture.) 2 1 0 Priority Description 0 1 1 First Receiver Error (OE, PE, BI or FE) 0 1 0 Second Received Data Available 1 1 0 Second Trigger level identification (Stale data in receive buffer) 0 0 1 Third Transmitter has room for more words (THRE) 0 0 0 Fourth Modem Status Change (-CTS, -DSR, -RI, or -DCD) Bit 0 Interrupt Pending Bit If this bit is set to "0", then at least one interrupt is pending. +0x03 write/read Line Control Register (LCR) Bit 7 Divisor Latch Access Bit (DLAB) When set, access to the data transmit/receive register (THR/RBR) and the Interrupt Enable Register (IER) is disabled. Any access to these ports is now redirected to the Divisor Latch Registers. Setting this bit, loading the Divisor Registers, and clearing DLAB should be done with interrupts disabled. Bit 6 Set Break When set to "1", the transmitter begins to transmit continuous Spacing until this bit is set to "0". This overrides any bits of characters that are being transmitted. Bit 5 Stick Parity When parity is enabled, setting this bit causes parity to always be "1" or FreeBSD Handbook 219 "0", based on the value of Bit 4. Bit 4 Even Parity Select (EPS) When parity is enabled and Bit 5 is "0", setting this bit causes even parity to be transmitted and expected. Otherwise, odd parity is used. Bit 3 Parity Enable (PEN) When set to "1", a parity bit is inserted between the last bit of the data and the Stop Bit. The UART will also expect parity to be present in the received data. Bit 2 Number of Stop Bits (STB) If set to "1" and using 5-bit data words, 1.5 Stop Bits are transmitted and expected in each data word. For 6, 7 and 8-bit data words, 2 Stop Bits are transmitted and expected. When this bit is set to "0", one Stop Bit is used on each data word. Bit 1 Word Length Select Bit #1 (WLSB1) Bit 0 Word Length Select Bit #0 (WLSB0) Together these bits specify the number of bits in each data word. 1 0 Word Length 0 0 5 Data Bits 0 1 6 Data Bits 1 0 7 Data Bits 1 1 8 Data Bits +0x04 write/read Modem Control Register (MCR) Bit 7 Reserved, always 0. Bit 6 Reserved, always 0. Bit 5 Reserved, always 0. Bit 4 Loop-Back Enable When set to "1", the UART transmitter and receiver are internally connected together to allow diagnostic operations. In addition, the UART modem control outputs are connected to the UART modem control inputs. CTS is connected to RTS, DTR is connected to DSR, OUT1 is connected to RI, and OUT 2 is connected FreeBSD Handbook 220 to DCD. Bit 3 OUT 2 An auxiliary output that the host processor may set high or low. In the IBM PC serial adapter (and most clones), OUT 2 is used to tri-state (disable) the interrupt signal from the 8250/16450/16550 UART. Bit 2 OUT 1 An auxiliary output that the host processor may set high or low. This output is not used on the IBM PC serial adapter. Bit 1 Request to Send (RTS) When set to "1", the output of the UART -RTS line is Low (Active). Bit 0 Data Terminal Ready (DTR) When set to "1", the output of the UART -DTR line is Low (Active). +0x05 write/read Line Status Register (LSR) Bit 7 Error in Receiver FIFO On the 8250/16450 UART, this bit is zero. This bit is set to "1" when any of the bytes in the FIFO have one or more of the following error conditions: PE, FE, or BI. Bit 6 Transmitter Empty (TEMT) When set to "1", there are no words remaining in the transmit FIFO or the transmit shift register. The transmitter is completely idle. Bit 5 Transmitter Holding Register Empty (THRE) When set to "1", the FIFO (or holding register) now has room for at least one additional word to transmit. The transmitter may still be transmitting when this bit is set to "1". Bit 4 Break Interrupt (BI) The receiver has detected a Break signal. Bit 3 Framing Error (FE) A Start Bit was detected but the Stop Bit did not appear at the expected time. The received word is probably garbled. FreeBSD Handbook 221 Bit 2 Parity Error (PE) The parity bit was incorrect for the word received. Bit 1 Overrun Error (OE) A new word was received and there was no room in the receive buffer. The newly-arrived word in the shift register is discarded. On 8250/16450 UARTs, the word in the holding register is discarded and the newly- arrived word is put in the holding register. Bit 0 Data Ready (DR) One or more words are in the receive FIFO that the host may read. A word must be completely received and moved from the shift register into the FIFO (or holding register for 8250/16450 designs) before this bit is set. +0x06 write/read Modem Status Register (MSR) Bit 7 Data Carrier Detect (DCD) Reflects the state of the DCD line on the UART. Bit 6 Ring Indicator (RI) Reflects the state of the RI line on the UART. Bit 5 Data Set Ready (DSR) Reflects the state of the DSR line on the UART. Bit 4 Clear To Send (CTS) Reflects the state of the CTS line on the UART. Bit 3 Delta Data Carrier Detect (DDCD) Set to "1" if the -DCD line has changed state one more more times since the last time the MSR was read by the host. Bit 2 Trailing Edge Ring Indicator (TERI) Set to "1" if the -RI line has had a low to high transition since the last time the MSR was read by the host. Bit 1 Delta Data Set Ready (DDSR) Set to "1" if the -DSR line has changed FreeBSD Handbook 222 state one more more times since the last time the MSR was read by the host. Bit 0 Delta Clear To Send (DCTS