DæmonNews: News and views for the BSD community

June 2000 Get BSD New to BSD? Search BSD Submit News FAQ Contact Us Join Us
Search


Get BSD Stuff

Answer Man

by Gary Kline, David Leonard, and Dirk Myers

More questions and answers-in-depth for the BSD distributions, and with this column we begin the first of the "reprised" Q/A's---ones that could have been answered better initially or those in which the topic has changed enough to warrant re-coverage. Also this time after missing a couple of columns Dirk Myers rejoins us to cover the NetBSD side of things. Welcome back, Dirk!

Q. How do i set up my own personal cron--not as root?

A: Each user on a BSD system can use cron to run programs at a specific time. (You don't need to add a user to an ALLOW list to use cron, which differs from some other Unix-like systems.)

Before we get into the nuts and bolts of working with cron entries, though, we need to clarify the terminology that BSD (and Unix-like systems in general) use. The program that executes commands at specific times is known as cron. A set of commands to be run at specific times is referred to as a crontab (that is, a table of instructions for cron). The Unix command to work with a crontab is also called crontab.

To add entries to your personal set of cron jobs, use the crontab -e (crontab edit) command. This option will open your crontab in the default editor. Once you've finished editing the table, the crontab program will check the edited table for obvious syntax errors, and activate the crontab if all is well. If all is not well, crontab will let you know that there's a problem, and give you the option of re-editing the file, or throwing away your changes.

To list the entries in your crontab, use the crontab -l (crontab list) command.

The format of a crontab file entry is shown below. It's important to remember that columns in the table are separated by white space. (It's also important to notice that the crontab files for individual users are different than the system crontab, /etc/crontab, the system crontab has an extra column which specifies a username to use when running the command. For an individual user's crontab, every command will run as that user -- the username column is unnecessary, so cron doesn't expect to see one. If you accidentally include a username, cron will interpret it as the command to run.)

An entry in your personal cron table entry might look something like:


30 * * * * echo "This string will be mailed to you 30 minutes past every hour"

15 21 * * 1-5 mail -s "It's time!" smitty@work.com < /home/jqs/msgs/GoHome

*  0-23 *    *    *    /usr/local/bin/datamine
 

If you want to delete your entire crontab, use


  % crontab -r

This will remove your crontab. You can re-enter commands with crontab -e or feed crontab a file of commands in the format shown above. After you change your crontab, be sure to get a listing to confirm that your changes are correct:

  % crontab -l

Spending 5 or 10 minutes with the crontab utility will give you plenty of hands-on experience. And, as usual, reading the manual page (cron(8), crontab(5)) will reveal the fine details.


  % man 5 crontab

Q: I would like to run that job every 10 minutes 24 hours a day...is that possible as well??

A: Sure is - make an entry just like the atrun entry. You'll end up with something like this:

*/10    *       *       *       *       root    /usr/local/bin/scr

Snippet: Paul Vixie's cron is a popular implementation of cron used by both BSDs and Linux and has some nice extensions. Of most interest, you can simulate per-user boot "run commands" (á la /etc/rc) with something like the following entry:

@reboot /bin/sh $HOME/etc/rc


Q. I'm seeing "/kernel: file table is full" far too many times in my /var/log/messages file. There is definitely something wrong, but I can't figure out what. How can I find out how many files are actually open? How can I find out which program is using so many files? How can I get anywhere with this problem?

First, let's examine what's going wrong. The kernel keeps track of each open file with an entry in the system-wide file table. The number of entries which can fit in the table is known as `maxfiles', and is specified when the kernel is compiled. The length of the file table can be viewed with the `sysctl kern.maxfiles' command.

Often, the file table is exhausted by just one rogue process. The fstat(1) and lsof(1) utilities show open file descriptors for processes and can help identify heavy resource users. Fstat is a system utility, and is often sufficient to pick out the offender. Lsof has more formatting options for its output, and can be more convenient on a heavily-loaded system. With either of these tools, you may be able to find a runaway process, kill it, and solve the problem.

Sometimes, though, there's no one process which is behaving badly. Your system may be performing normally, and may have legitimately run out of space in the file table. In this case, you need to compile a new kernel with a larger number of file descriptors.

To get more file descriptors, increase the number of `maxusers' in your kernel configuration file. (Note that the `maxusers' parameter allocates the quantity of resources which that number of users are believed likely to use at any given time. Because it's a ``best guess'', it's not a precise number, so don't worry if the number you're filling in seems too high or too low for the actual number of users you have using the system. What's important is to allocate sufficient resources for the needs of your individual system.)

(See a previous Answerman column for notes on reconfiguring/rebuilding kernel.) How do I rebuild a new kernel?



Q. How do I get files in a directory and those in files in subdirectories with ftp? ftp won't create subdirectories on my own system so I have to create them myself, then go back with ftp.

A: Use ``wget'' from the ports/packages/pkgsrc collection. Given an ftp://path.name.to.a.URL, "wget -r" will do the job. For example:

wget -r -m --follow-ftp -T timeout_seconds -c "URL_HERE"

If you don't have wget on hand, and the ftp server is a WU-FTP variant, you can fetch the directory as a tarball. Try appending '.tar' or '.tar.gz' to the name of the directory and download that. If the server is configured appropriately, it will tar and compress the directory for you! The downside of this is that the size of the resulting download is usually not computed in advance, so your FTP client will be unable to give you feedback as to how much time is left to download.


Q. What's the scoop on the /etc/rc.* and the /etc/defaults/rc.conf stuff?

The rc (or 'run command') files executed by init(8) vary slightly over the different BSDs. The rc(8) manual page is the best reference.

FreeBSD:

If you poke around sufficiently in the freebsd-questions, -hackers, and -stable (maybe more) archives from the transition from FreeBSD 3.0-RELEASE to 3.1-R, you'll find that the way the "rc" customization was done has changed (though in a way that is compatible with the old style, generally).

The file that "unlocks the secrets" is /etc/defaults/rc.conf -- but /etc/rc is still a shell script, and if you study it hard enough, you'll see that it refers to the defaults/rc.conf file.

The way to use /etc/rc.conf is to add anything that you want changed from the defaults (in /etc/defaults/rc.conf) to the /etc/rc.conf file. Anything in /etc/rc.conf will override the defaults. This gives you a convenient way to change just those items you need to change, without altering the ``as-installed'' defaults.

And you can still create an /etc/rc.local file; it's just not there (as you noted) by default, even as a place-holder that says


        # Put your local stuff here.

NetBSD, OpenBSD:

/etc/rc.conf is the place that contains the default configurations for the commands run by /etc/rc.

/etc/rc.conf.local is another file that you can put configuration variables into, and is more easily preserved over operating system upgrades.

Q. Can you explain a few of the basics of the "ps" command?

'ps', without flags, will show only your processes that have a 'controlling terminal' (seen in the TT field). A controlling terminal is the tty or xterm through which processes receive signals (like control-C interrupts). Look at the TT field in the following:

inchoate:d$ ps
  PID TT   STAT      TIME COMMAND
 4543 p1  INs     0:00.28 -ksh (ksh)
 7944 p1  SN+     0:29.78 mpg123 --stereo --8bit --rate 21739 /cdrom/Moby - 07-
23331 p2  INs     0:00.14 -ksh (ksh)
24226 p2  SN+     0:02.46 vi june00.html 
 5985 p3  SNs     0:00.17 -ksh (ksh)
27083 p3  RN+     0:00.00 ps 

Sometimes, backgrounded processes can lose their controlling terminal - typically when you log out or close an xterm and they're still running. Other processes, like X11 applications, never had a tty to start with. So, to show all the processes that you have running, use the -x flag.

Processes without a controlling terminal have '??' in their TT field. Again, look at the TT field in the following and see if you can spot the ctty-less application that is not an X windows app:

inchoate:d$ ps -x
  PID TT   STAT      TIME COMMAND
 3859 ??  IN      0:00.55 xtickertape 
 9559 ??  Is      0:00.00 ssh-agent -s 
14108 ??  SN      0:00.50 xapm 
15652 ??  Is      0:00.11 /bin/sh /home/d/.xsession 
23517 ??  S       0:00.55 twm 
26596 ??  SN      0:01.31 xclock 
30791 ??  IN      0:00.23 xpostit 
 4543 p1  INs     0:00.28 -ksh (ksh)
 7944 p1  SN+     0:49.11 mpg123 --stereo --8bit --rate 21739 /cdrom/Moby - 07-
23331 p2  INs     0:00.14 -ksh (ksh)
24226 p2  SN+     0:02.61 vi june00.html 
 5985 p3  SNs     0:00.18 -ksh (ksh)
31074 p3  RN+     0:00.00 ps -x 

To show other user's processes you can either add the -a flag, or -U username to pick out a specific user. You'll also need -u to add a USER field to the output.

Here we can see root's /usr/libexec/getty process displaying a "login:" prompt on virtual consoles ttyC0 through ttyC5:

inchoate:d$ ps -ua
USER       PID %CPU %MEM   VSZ   RSS TT   STAT STARTED       TIME COMMAND
d         7944 27.9  1.4   316   660 p1  SN+    8:35AM    2:15.73 mpg123 --ster
root      8653  0.0  1.0    44   496 C0  Is+    8:15AM    0:00.03 /usr/libexec/
root      5699  0.0  1.0    44   496 C1  Is+    8:15AM    0:00.02 /usr/libexec/
root      5061  0.0  1.0    44   496 C2  Is+    8:15AM    0:00.02 /usr/libexec/
root     20479  0.0  1.0    44   496 C3  Is+    8:15AM    0:00.02 /usr/libexec/
root      8693  0.0  1.0    44   496 C5  Is+    8:15AM    0:00.02 /usr/libexec/
d         4543  0.0  0.7   404   328 p1  INs    8:15AM    0:00.28 -ksh (ksh)
d        23331  0.0  0.7   404   328 p2  INs    8:16AM    0:00.14 -ksh (ksh)
d        24226  0.0  2.4   504  1160 p2  SN+    8:23AM    0:03.97 vi june00.htm
d         5985  0.0  0.7   404   328 p3  SNs    8:25AM    0:00.19 -ksh (ksh)
d         1194  0.0  0.5   288   252 p3  RN+    8:43AM    0:00.00 ps -ua 

Some handy 'ps' incantations:

 
  ps -uax           # all processes
  ps -uxU username  # all processes owned by username
  ps -uxp pid       # just that pid  


Q. I've heard rumors that xhost + or xhost site.com is dangerous way of adding sites that can be used for doing X Window stuff over the net. What's the story here?

A: xhost site.com allows any machine at site.com to access your X display. xhost + allows any machine to access your X display.

When you allow a remote machine (or the rest of the world) access to your X display, it is possible for other people to quietly run keystroke-sniffing programs on you to get your passwords, take silent snapshots of what your display is showing, or even send keystrokes into your windows when they think you've been idle for some time.

If you're already using ssh(1) to log in to the remote host, you can send your X traffic through the ssh connection. (ssh may or may not be included with your system, depending on your specific system and version.)

If ssh is not an option, careful use of xauth(1) and/or Xnest(1) is viable.

See also this paraphrasing of the Xsecurity document.




Reprise

From time to time this column will update material from previous editions if the older writing has not kept current or if it needs changing for whatever reason. Below, we discuss using the BSD pkg_add utility that was last discussed in late 1998. In addition to the few changes, we can now cover all the distributions.


Q. I've heard of using pkg_add over the net, somehow, but don't understand the exact details. Can you explain how this works?

A. If you'd rather not build a program from source and don't have the CD set, you can (as root) type

# pkg_add URL

The package will be downloaded (usually with the URL-savvy ftp(1) program) and installed with a name such as somepkg-1.0. You can list what packages you have installed by typing pkg_info, and can uninstall the package with pkg_delete somepkg-1.0.

Each of the BSDs have their own style of package organisation. Here are some examples:

(In the examples below, we use the convention that a "\" at the end of the line means that the following line should be considered as a continuation of the the line with the "\". We use this convention because most shells use this convention. For example,

	% echo \
   	  continued

and

	% echo continued
are, effectively, the same command.)

FreeBSD

      # pkg_add \
ftp://ftp.freebsd.org/pub/FreeBSD/ports/<arch>\ /packages-*/<category>/pkg

As an explicit example:

   
# pkg_add \
  ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/\
  packages-stable/All/awele-1.0.tgz


If you check the /pub/FreeBSD/ports/i386 directory, you will find a number of subdirectories for the different branches. If you want to retrieve the audio package waveplay-1.0.tgz for FreeBSD-3.4, you would find it at

   
# pkg_add \
  ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/\
  packages-3.4-release/audio/waveplay-1.0.tgz

Additionally, of note is that FreeBSD now has an alpha port. If you wanted to auto-download ttt-1.4 for the Alpha platform, the following command would find it:

   
# pkg_add \
  ftp://ftp.freebsd.org/pub/FreeBSD/ports/alpha/\
  packages-4-current/tk82/ttt-1.4.tgz

NetBSD

# pkg_add ftp://ftp.netbsd.org/pub/NetBSD/\
       packages/<version>/<arch>/<category>/<pkgname>
and the package will be automatically be downloaded, uncompressed, unarchived, and installed. As an explicit example,
   
# pkg_add \
ftp://ftp.netbsd.org/pub/NetBSD/packages/1.4.2/sparc/sysutils/lsof-4.49.4.tgz

OpenBSD

The OpenBSD group archives the most common ports as installable packages. You can find them compiled against particular releases for particular architectures on international mirror sites. For example, using the Australian mirror:

# pkg_add \
         ftp://ftp.au.openbsd.org/pub/OpenBSD/2.7/\
         packages/i386/foo-1.0.tar.gz

If the program you're looking for is not available as a package, you might need to build it from a port (FreeBSD, OpenBSD), or pkgsrc (NetBSD). To find out which programs are available, use your favorite browser to go to

http://www.freebsd.org/ports/

(FreeBSD)

http://www.netbsd.org/Documentation/software/packages.html

(NetBSD)

http://www.openbsd.org/ports.html

(OpenBSD)


to find all of the categories; and within them the packages. If you have any problems fetching a package, be sure you are typing the path correctly.

As usual, see the manual pages for pkg_add(1), pkg_info(1) and pkg_delete(1) for details.

Security Note: It's probably a good idea to install only those packages found on an official site. As with any software, it's possible for an unscrupulous person to have altered a package for their own ends. Sticking to official distribution sites is one of the better ways to protect yourself. If you are truly paranoid you should probably compile packages from source code that you yourself have personally vetted.




Author maintains all copyrights on this article.
Images and layout Copyright © 1998-2004 Dæmon News. All Rights Reserved.