diff options
Diffstat (limited to 'usr.bin/crontab')
| -rw-r--r-- | usr.bin/crontab/Makefile | 19 | ||||
| -rw-r--r-- | usr.bin/crontab/crontab.1 | 93 | ||||
| -rw-r--r-- | usr.bin/crontab/crontab.386bsd | 27 | ||||
| -rw-r--r-- | usr.bin/crontab/crontab.5 | 188 | ||||
| -rw-r--r-- | usr.bin/crontab/crontab.c | 417 |
5 files changed, 744 insertions, 0 deletions
diff --git a/usr.bin/crontab/Makefile b/usr.bin/crontab/Makefile new file mode 100644 index 000000000000..64577960205a --- /dev/null +++ b/usr.bin/crontab/Makefile @@ -0,0 +1,19 @@ +# +# PATCHES MAGIC LEVEL PATCH THAT GOT US HERE +# -------------------- ----- ---------------------- +# CURRENT PATCH LEVEL: 1 00131 +# -------------------- ----- ---------------------- +# +# 06 Apr 93 Adam Glass Fixed so manual pages install, install crontab +# with proper permissions and owners +# +PROG= crontab +SRCS= crontab.c misc.c entry.c env.c +CFLAGS+=-I${.CURDIR} -I${.CURDIR}/../../libexec/crond -DDEBUGGING=1 -DBSD -DCRONDIR='"/var/cron"' -fstrength-reduce +BINOWN =root +BINMODE=4111 +MAN1= crontab.1 +MAN5= crontab.5 + +.include <bsd.prog.mk> +.PATH: ${.CURDIR}/../../libexec/crond diff --git a/usr.bin/crontab/crontab.1 b/usr.bin/crontab/crontab.1 new file mode 100644 index 000000000000..ab1acbb1abe9 --- /dev/null +++ b/usr.bin/crontab/crontab.1 @@ -0,0 +1,93 @@ +.\" $Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.1,v 1.1.1.1 1993/06/12 14:53:53 rgrimes Exp $ +.\" +.\"/* Copyright 1988,1990 by Paul Vixie +.\" * All rights reserved +.\" * +.\" * Distribute freely, except: don't remove my name from the source or +.\" * documentation (don't take credit for my work), mark your changes (don't +.\" * get me blamed for your possible bugs), don't alter or remove this +.\" * notice. May be sold if buildable source is provided to buyer. No +.\" * warrantee of any kind, express or implied, is included with this +.\" * software; use at your own risk, responsibility for damages (if any) to +.\" * anyone resulting from the use of this software rests entirely with the +.\" * user. +.\" * +.\" * Send bug reports, bug fixes, enhancements, requests, flames, etc., and +.\" * I'll try to keep a version up to date. I can be reached as follows: +.\" * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013, +.\" * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul +.\" */ +.TH CRONTAB 1 "9 December 1988" +.UC 4 +.SH NAME +crontab \- maintain crontab files for individual users +.SH SYNOPSIS +crontab [ -u user ] { -l | -d | -r file } +.SH DESCRIPTION +.I Crontab +is the program used to install, deinstall or list the tables +used to drive the +.IR crond (8) +daemon in Vixie Cron. Each user has their own crontab, and though these are +files in /var, they are not readable or writable by anyone or anything +except the super-user or the +.IR crond (8) +or +.I crontab +programs. +.PP +If the +.I allow +file exists, then you must be listed therein in order to be allowed to use +this command. If the +.I allow +file does not exist but the +.I deny +file does exist, then you must \fBnot\fR be listed in the +.I deny +file in order to use this command. If neither of these files exists, then +depending on site-dependent configuration parameters, only the super user +will be allowed to use this command, or all users will be able to use this +command. +.PP +If the +.I -u +option is given, it specifies the name of the user whose crontab is to be +tweaked. If this option is not given, +.I crontab +examines "your" crontab, i.e., the crontab of the person executing the +command. Note that +.IR su (8) +can confuse +.I crontab +and that if you are running inside of +.IR su (8) +you should always use the +.I -u +option for safety's sake. +.PP +The +.I -l +option causes the current crontab to be displayed on standard output. +.PP +The +.I -d +option causes the current crontab to be deleted. +.PP +The +.I -r +option is used to replace the current +crontab (if any) with the contents of the named file. +.SH "SEE ALSO" +crontab(5), crond(8) +.SH FILES +.nf +/var/cron/allow +/var/cron/deny +.fi +.SH DIAGNOSTICS +A fairly informative usage message appears if you run it with a bad command +line. +.SH AUTHOR +.nf +Paul Vixie, paul@vixie.sf.ca.us diff --git a/usr.bin/crontab/crontab.386bsd b/usr.bin/crontab/crontab.386bsd new file mode 100644 index 000000000000..9070efa38c02 --- /dev/null +++ b/usr.bin/crontab/crontab.386bsd @@ -0,0 +1,27 @@ +# /etc/crontab.src - root's crontab for Vixie's cron +# +# PATCHES MAGIC LEVEL PATCH THAT GOT US HERE +# -------------------- ----- ---------------------- +# CURRENT PATCH LEVEL: 1 00131 +# -------------------- ----- ---------------------- +# +# 06 Apr 93 Adam Glass Fixed to be a better template for 386bsd +# +SHELL=/bin/sh +PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin +HOME=/var/log +# +#minute hour mday month wday command +# +#0/10 * * * * /etc/dmesg - >> messages +#0/15 * * * * /usr/lib/atrun +#37 4 * * * ./cronrun-day > cronout-day 2>&1 +#43 4 * * Sun ./cronrun-wk > cronout-wk 2>&1 +#51 4 1 * * ./cronrun-mon > cronout-mon 2>&1 +0/15 * * * * /usr/libexec/atrun +0 2 * * * /etc/daily > /var/log/daily.out 2>&1 +30 3 * * 6 /etc/weekly > /var/log/weekly.out 2>&1 +30 5 1 * * /etc/monthly > /var/log/monthly.out 2>&1 +#45 * * * * /bin/echo /usr/local/bin/uucico -r1 | /bin/su uucpa +#0-59/5 * * * * /usr/local/bin/uucico -r1 +#37 * * * * touch /var/spool/uucp/jpunix/C./C.A0000 diff --git a/usr.bin/crontab/crontab.5 b/usr.bin/crontab/crontab.5 new file mode 100644 index 000000000000..3ea488704842 --- /dev/null +++ b/usr.bin/crontab/crontab.5 @@ -0,0 +1,188 @@ +.\" $Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.5,v 1.1 1993/07/02 07:25:42 root Exp $ +.\" +.\"/* Copyright 1988,1990 by Paul Vixie +.\" * All rights reserved +.\" * +.\" * Distribute freely, except: don't remove my name from the source or +.\" * documentation (don't take credit for my work), mark your changes (don't +.\" * get me blamed for your possible bugs), don't alter or remove this +.\" * notice. May be sold if buildable source is provided to buyer. No +.\" * warrantee of any kind, express or implied, is included with this +.\" * software; use at your own risk, responsibility for damages (if any) to +.\" * anyone resulting from the use of this software rests entirely with the +.\" * user. +.\" * +.\" * Send bug reports, bug fixes, enhancements, requests, flames, etc., and +.\" * I'll try to keep a version up to date. I can be reached as follows: +.\" * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013, +.\" * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul +.\" */ +.TH CRONTAB 5 "15 January 1990" +.UC 4 +.SH NAME +crontab \- tables for driving cron +.SH DESCRIPTION +A +.I crontab +file contains instructions to the +.IR crond (8) +daemon of the general form: ``run this command at this time on this date''. +Each user has their own crontab, and commands in any given crontab will be +executed as the user who owns the crontab. Uucp and News will usually have +their own crontabs, eliminating the need for explicitly running +.IR su (1) +as part of a cron command. +.PP +Blank lines and leading spaces and tabs are ignored. Lines whose first +non-space character is a pound-sign (#) are comments, and are ignored. +Note that comments are not allowed on the same line as cron commands, since +they will be taken to be part of the command. Similarly, comments are not +allowed on the same line as environment variable settings. +.PP +An active line in a crontab will be either an environment setting or a cron +command. An environment setting is of the form, +.PP + name = value +.PP +where the spaces around the equal-sign (=) are optional, and any subsequent +non-leading spaces in +.I value +will be part of the value assigned to +.IR name . +The +.I value +string may be placed in quotes (single or double, but matching) to preserve +leading or trailing blanks. +.PP +Several environment variables are set up +automatically by the +.IR crond (8) +daemon from the /etc/passwd line of the crontab's owner: USER, HOME, and SHELL. +HOME and SHELL may be overridden by settings in the crontab; USER may not. +.PP +(Note: for UUCP, always set SHELL=/bin/sh, or +.IR crond (8) +will cheerfully try to execute your commands using /usr/lib/uucp/uucico.) +.PP +(Another note: the USER variable is sometimes called LOGNAME or worse on +System V... on these systems, LOGNAME will be set rather than USER.) +.PP +In addition to USER, HOME, and SHELL, +.IR crond (8) +will look at MAILTO if it has any reason to send mail as a result of running +commands in ``this'' crontab. If MAILTO is defined (and non-empty), mail is +sent to the user so named. If MAILTO is defined but empty (MAILTO=""), no +mail will be sent. Otherwise mail is sent to the owner of the crontab. This +option is useful if you decide on /bin/mail instead of /usr/lib/sendmail as +your mailer when you install cron -- /bin/mail doesn't do aliasing, and UUCP +usually doesn't read its mail. +.PP +The format of a cron command is very much the V7 standard, with a number of +upward-compatible extensions. Each line has five time and date fields, +followed by a command. Commands are executed by +.IR crond (8) +when the minute, hour, and month of year fields match the current time, +.I and +when at least one of the two day fields (day of month, or day of week) +match the current time (see ``Note'' below). +.IR crond (8) +examines cron entries once every minute. +The time and date fields are: +.IP +.ta 1.5i +field allowed values +.br +----- -------------- +.br +minute 0-59 +.br +hour 0-23 +.br +day of month 0-31 +.br +month 0-12 (or names, see below) +.br +day of week 0-7 (0 or 7 is Sun, or use names) +.br +.PP +A field may be an asterisk (*), which always matches the +current time. +.PP +Ranges of numbers are allowed. Ranges are two numbers separated +with a hyphen. The specified range is inclusive. For example, +8-11 for an ``hours'' entry specifies execution at hours 8, 9, 10 +and 11. +.PP +Lists are allowed. A list is a set of numbers (or ranges) +separated by commas. Examples: ``1,2,5,9'', ``0-4,8-12''. +.PP +Step values can be used in conjunction with ranges. Following +a range with ``/<number>'' specifies skips of the number's value +through the range. For example, ``0-23/2'' can be used in the hours +field to specify command execution every other hour (the alternative +in the V7 standard is ``0,2,4,6,8,10,12,14,16,18,20,22''). +.PP +Names can also be used for the ``month'' and ``day of week'' +fields. Use the first three letters of the particular +day or month (case doesn't matter). Ranges or +lists of names are not allowed. +.PP +The ``sixth'' field (the rest of the line) specifies the command to be +run. +The entire command portion of the line, up to a newline or % +character, will be executed by the user's login shell or by the shell +specified in the SHELL variable of the cronfile. +Percent-signs (%) in the command, unless escaped with backslash +(\\), will be changed into newline characters, and all data +after the first % will be sent to the command as standard +input. +.PP +Note: The day of a command's execution can be specified by two +fields \(em day of month, and day of week. If both fields are +restricted (ie, aren't *), the command will be run when +.I either +field matches the current time. For example, +.br +``30 4 1,15 * 5'' +would cause a command to be run at 4:30 am on the 1st and 15th of each +month, plus every Friday. +.SH EXAMPLE CRON FILE +.nf + +# use /bin/sh to run commands, no matter what /etc/passwd says +SHELL=/bin/sh +# mail any output to `paul', no matter whose crontab this is +MAILTO=paul +# +# run five minutes after midnight, every day +5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1 +# run at 2:15pm on the first of every month -- output mailed to paul +15 14 1 * * $HOME/bin/monthly +# run at 10 pm on weekdays, annoy Joe +0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?% +23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday" +5 4 * * sun echo "run at 5 after 4 every sunday" +.fi +.SH SEE ALSO +crond(8), crontab(1) +.SH EXTENSIONS +When specifying day of week, both day 0 and day 7 will be considered Sunday. +BSD and ATT seem to disagree about this. +.PP +Lists and ranges are allowed to co-exist in the same field. "1-3,7-9" would +be rejected by ATT or BSD cron -- they want to see "1-3" or "7,8,9" ONLY. +.PP +Ranges can include "steps", so "1-9/2" is the same as "1,3,5,7,9". +.PP +Names of months or days of the week can be specified by name. +.PP +Environment variables can be set in the crontab. In BSD or ATT, the +environment handed to child processes is basically the one from /etc/rc. +.PP +Command output is mailed to the crontab owner (BSD can't do this), can be +mailed to a person other than the crontab owner (SysV can't do this), or the +feature can be turned off and no mail will be sent at all (SysV can't do this +either). +.SH AUTHOR +.nf +Paul Vixie, paul@vixie.sf.ca.us diff --git a/usr.bin/crontab/crontab.c b/usr.bin/crontab/crontab.c new file mode 100644 index 000000000000..e65dbbdb3d32 --- /dev/null +++ b/usr.bin/crontab/crontab.c @@ -0,0 +1,417 @@ +#if !defined(lint) && !defined(LINT) +static char rcsid[] = "$Header: /a/cvs/386BSD/src/usr.bin/crontab/crontab.c,v 1.1.1.1 1993/06/12 14:53:53 rgrimes Exp $"; +#endif + +/* Revision 1.5 87/05/02 17:33:22 paul + * pokecron? (RCS file has the rest of the log) + * + * Revision 1.5 87/05/02 17:33:22 paul + * baseline for mod.sources release + * + * Revision 1.4 87/03/31 13:11:48 paul + * I won't say that rs@mirror gave me this idea but crontab uses getopt() now + * + * Revision 1.3 87/03/30 23:43:48 paul + * another suggestion from rs@mirror: + * use getpwuid(getuid)->pw_name instead of getenv("USER") + * this is a boost to security... + * + * Revision 1.2 87/02/11 17:40:12 paul + * changed command syntax to allow append and replace instead of append as + * default and no replace at all. + * + * Revision 1.1 87/01/26 23:49:06 paul + * Initial revision + * + * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE + * -------------------- ----- ---------------------- + * CURRENT PATCH LEVEL: 1 00131 + * -------------------- ----- ---------------------- + * + * 06 Apr 93 Adam Glass Fixes so it compiles quitely + * + */ + +/* Copyright 1988,1990 by Paul Vixie + * All rights reserved + * + * Distribute freely, except: don't remove my name from the source or + * documentation (don't take credit for my work), mark your changes (don't + * get me blamed for your possible bugs), don't alter or remove this + * notice. May be sold if buildable source is provided to buyer. No + * warrantee of any kind, express or implied, is included with this + * software; use at your own risk, responsibility for damages (if any) to + * anyone resulting from the use of this software rests entirely with the + * user. + * + * Send bug reports, bug fixes, enhancements, requests, flames, etc., and + * I'll try to keep a version up to date. I can be reached as follows: + * Paul Vixie, 329 Noe Street, San Francisco, CA, 94114, (415) 864-7013, + * paul@vixie.sf.ca.us || {hoptoad,pacbell,decwrl,crash}!vixie!paul + */ + + +#define MAIN_PROGRAM + + +#include "cron.h" +#include <pwd.h> +#include <errno.h> +#include <sys/file.h> +#if defined(BSD) +# include <sys/time.h> +#endif /*BSD*/ + +/* extern char *sprintf(); */ + + +static int Pid; +static char User[MAX_UNAME], RealUser[MAX_UNAME]; +static char Filename[MAX_FNAME]; +static FILE *NewCrontab; +static int CheckErrorCount; +static enum {opt_unknown, opt_list, opt_delete, opt_replace} + Option; + +extern void log_it(); + +#if DEBUGGING +static char *Options[] = {"???", "list", "delete", "replace"}; +#endif + +void +usage() +{ + fprintf(stderr, "usage: %s [-u user] ...\n", ProgramName); + fprintf(stderr, " ... -l (list user's crontab)\n"); + fprintf(stderr, " ... -d (delete user's crontab)\n"); + fprintf(stderr, " ... -r file (replace user's crontab)\n"); + exit(ERROR_EXIT); +} + + +main(argc, argv) + int argc; + char *argv[]; +{ + void parse_args(), set_cron_uid(), set_cron_cwd(), + list_cmd(), delete_cmd(), replace_cmd(); + + Pid = getpid(); + ProgramName = argv[0]; +#if defined(BSD) + setlinebuf(stderr); +#endif + parse_args(argc, argv); /* sets many globals, opens a file */ + set_cron_uid(); + set_cron_cwd(); + if (!allowed(User)) { + fprintf(stderr, + "You (%s) are not allowed to use this program (%s)\n", + User, ProgramName); + fprintf(stderr, "See crontab(1) for more information\n"); + log_it(RealUser, Pid, "AUTH", "crontab command not allowed"); + exit(ERROR_EXIT); + } + switch (Option) + { + case opt_list: list_cmd(); + break; + case opt_delete: delete_cmd(); + break; + case opt_replace: replace_cmd(); + break; + } +} + + + void +parse_args(argc, argv) + int argc; + char *argv[]; +{ + void usage(); + char *getenv(), *strcpy(); + int getuid(); + struct passwd *getpwnam(); + extern int getopt(), optind; + extern char *optarg; + + struct passwd *pw; + int argch; + + if (!(pw = getpwuid(getuid()))) + { + fprintf(stderr, "%s: your UID isn't in the passwd file.\n", + ProgramName); + fprintf(stderr, "bailing out.\n"); + exit(ERROR_EXIT); + } + strcpy(User, pw->pw_name); + strcpy(RealUser, User); + Filename[0] = '\0'; + Option = opt_unknown; + while (EOF != (argch = getopt(argc, argv, "u:ldr:x:"))) + { + switch (argch) + { + case 'x': + if (!set_debug_flags(optarg)) + usage(); + break; + case 'u': + if (getuid() != ROOT_UID) + { + fprintf(stderr, + "must be privileged to use -u\n"); + exit(ERROR_EXIT); + } + if ((struct passwd *)NULL == getpwnam(optarg)) + { + fprintf(stderr, "%s: user `%s' unknown\n", + ProgramName, optarg); + exit(ERROR_EXIT); + } + (void) strcpy(User, optarg); + break; + case 'l': + if (Option != opt_unknown) + usage(); + Option = opt_list; + break; + case 'd': + if (Option != opt_unknown) + usage(); + Option = opt_delete; + break; + case 'r': + if (Option != opt_unknown) + usage(); + Option = opt_replace; + (void) strcpy(Filename, optarg); + break; + default: + usage(); + } + } + + endpwent(); + + if (Option == opt_unknown || argv[optind] != NULL) + usage(); + + if (Option == opt_replace) { + if (!Filename[0]) { + /* getopt(3) says this can't be true + * but I'm paranoid today. + */ + fprintf(stderr, "filename must be given for -a or -r\n"); + usage(); + } + /* we have to open the file here because we're going to + * chdir(2) into /var/cron before we get around to + * reading the file. + */ + if (!strcmp(Filename, "-")) { + NewCrontab = stdin; + } else { + if (!(NewCrontab = fopen(Filename, "r"))) { + perror(Filename); + exit(ERROR_EXIT); + } + } + } + + Debug(DMISC, ("user=%s, file=%s, option=%s\n", + User, Filename, Options[(int)Option])) +} + + + void +list_cmd() +{ + extern errno; + char n[MAX_FNAME]; + FILE *f; + int ch; + + log_it(RealUser, Pid, "LIST", User); + (void) sprintf(n, CRON_TAB(User)); + if (!(f = fopen(n, "r"))) + { + if (errno == ENOENT) + fprintf(stderr, "no crontab for %s\n", User); + else + perror(n); + exit(ERROR_EXIT); + } + + /* file is open. copy to stdout, close. + */ + Set_LineNum(1) + while (EOF != (ch = get_char(f))) + putchar(ch); + fclose(f); +} + + + void +delete_cmd() +{ + extern errno; + int unlink(); + void poke_daemon(); + char n[MAX_FNAME]; + + log_it(RealUser, Pid, "DELETE", User); + (void) sprintf(n, CRON_TAB(User)); + if (unlink(n)) + { + if (errno == ENOENT) + fprintf(stderr, "no crontab for %s\n", User); + else + perror(n); + exit(ERROR_EXIT); + } + poke_daemon(); +} + + + void +check_error(msg) + char *msg; +{ + CheckErrorCount += 1; + fprintf(stderr, "\"%s\", line %d: %s\n", Filename, LineNumber, msg); +} + + + void +replace_cmd() +{ + entry *load_entry(); + int load_env(); + int unlink(); + void free_entry(); + void check_error(); + void poke_daemon(); + extern errno; + + char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME]; + FILE *tmp; + int ch; + entry *e; + int status; + time_t now = time(NULL); + + (void) sprintf(n, "tmp.%d", Pid); + (void) sprintf(tn, CRON_TAB(n)); + if (!(tmp = fopen(tn, "w"))) { + perror(tn); + exit(ERROR_EXIT); + } + + /* write a signature at the top of the file. for brian. + */ + fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now)); + fprintf(tmp, "# (Cron version -- %s)\n", rcsid); + + /* copy the crontab to the tmp + */ + Set_LineNum(1) + while (EOF != (ch = get_char(NewCrontab))) + putc(ch, tmp); + fclose(NewCrontab); + fflush(tmp); rewind(tmp); + + if (ferror(tmp)) { + fprintf(stderr, "%s: error while writing new crontab to %s\n", + ProgramName, tn); + fclose(tmp); unlink(tn); + exit(ERROR_EXIT); + } + + /* check the syntax of the file being installed. + */ + + /* BUG: was reporting errors after the EOF if there were any errors + * in the file proper -- kludged it by stopping after first error. + * vix 31mar87 + */ + CheckErrorCount = 0; + while (!CheckErrorCount && (status = load_env(envstr, tmp)) >= OK) + { + if (status == FALSE) + { + if (NULL != (e = load_entry(NewCrontab, check_error))) + free((char *) e); + } + } + + if (CheckErrorCount != 0) + { + fprintf(stderr, "errors in crontab file, can't install.\n"); + fclose(tmp); unlink(tn); + exit(ERROR_EXIT); + } + + if (fchown(fileno(tmp), ROOT_UID, -1) < OK) + { + perror("chown"); + fclose(tmp); unlink(tn); + exit(ERROR_EXIT); + } + + if (fchmod(fileno(tmp), 0600) < OK) + { + perror("chown"); + fclose(tmp); unlink(tn); + exit(ERROR_EXIT); + } + + if (fclose(tmp) == EOF) { + perror("fclose"); + unlink(tn); + exit(ERROR_EXIT); + } + + (void) sprintf(n, CRON_TAB(User)); + if (rename(tn, n)) + { + fprintf(stderr, "%s: error renaming %s to %s\n", + ProgramName, tn, n); + perror("rename"); + unlink(tn); + exit(ERROR_EXIT); + } + log_it(RealUser, Pid, "REPLACE", User); + + poke_daemon(); +} + + + void +poke_daemon() +{ +#if defined(BSD) + struct timeval tvs[2]; + struct timezone tz; + + (void) gettimeofday(&tvs[0], &tz); + tvs[1] = tvs[0]; + if (utimes(SPOOL_DIR, tvs) < OK) + { + fprintf(stderr, "crontab: can't update mtime on spooldir\n"); + perror(SPOOL_DIR); + return; + } +#endif /*BSD*/ +#if defined(ATT) + if (utime(SPOOL_DIR, NULL) < OK) + { + fprintf(stderr, "crontab: can't update mtime on spooldir\n"); + perror(SPOOL_DIR); + return; + } +#endif /*ATT*/ +} |
