diff --git a/bin/pax/extern.h b/bin/pax/extern.h index 5f7625e7b4c8..ff33e5bcdf0e 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,285 +1,285 @@ /*- * Copyright (c) 1992 Keith Muller. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Keith Muller of the University of California, San Diego. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)extern.h 8.2 (Berkeley) 4/18/94 * $FreeBSD$ */ /* * External references from each source file */ #include /* * ar_io.c */ extern char *arcname; int ar_open __P((char *)); void ar_close __P((void)); void ar_drain __P((void)); int ar_set_wr __P((void)); int ar_app_ok __P((void)); int ar_read __P((register char *, register int)); int ar_write __P((register char *, register int)); int ar_rdsync __P((void)); int ar_fow __P((off_t, off_t *)); int ar_rev __P((off_t )); int ar_next __P((void)); /* * ar_subs.c */ extern u_long flcnt; void list __P((void)); void extract __P((void)); void append __P((void)); void archive __P((void)); void copy __P((void)); /* * buf_subs.c */ extern int blksz; extern int wrblksz; extern int maxflt; extern int rdblksz; extern off_t wrlimit; extern off_t rdcnt; extern off_t wrcnt; int wr_start __P((void)); int rd_start __P((void)); void cp_start __P((void)); int appnd_start __P((off_t)); int rd_sync __P((void)); void pback __P((char *, int)); int rd_skip __P((off_t)); void wr_fin __P((void)); int wr_rdbuf __P((register char *, register int)); int rd_wrbuf __P((register char *, register int)); int wr_skip __P((off_t)); int wr_rdfile __P((ARCHD *, int, off_t *)); int rd_wrfile __P((ARCHD *, int, off_t *)); void cp_file __P((ARCHD *, int, int)); int buf_fill __P((void)); int buf_flush __P((register int)); /* * cache.c */ int uidtb_start __P((void)); int gidtb_start __P((void)); int usrtb_start __P((void)); int grptb_start __P((void)); char * name_uid __P((uid_t, int)); char * name_gid __P((gid_t, int)); int uid_name __P((char *, uid_t *)); int gid_name __P((char *, gid_t *)); /* * cpio.c */ int cpio_strd __P((void)); int cpio_trail __P((register ARCHD *)); int cpio_endwr __P((void)); int cpio_id __P((char *, int)); int cpio_rd __P((register ARCHD *, register char *)); off_t cpio_endrd __P((void)); int cpio_stwr __P((void)); int cpio_wr __P((register ARCHD *)); int vcpio_id __P((char *, int)); int crc_id __P((char *, int)); int crc_strd __P((void)); int vcpio_rd __P((register ARCHD *, register char *)); off_t vcpio_endrd __P((void)); int crc_stwr __P((void)); int vcpio_wr __P((register ARCHD *)); int bcpio_id __P((char *, int)); int bcpio_rd __P((register ARCHD *, register char *)); off_t bcpio_endrd __P((void)); int bcpio_wr __P((register ARCHD *)); /* * file_subs.c */ int file_creat __P((register ARCHD *)); void file_close __P((register ARCHD *, int)); int lnk_creat __P((register ARCHD *)); int cross_lnk __P((register ARCHD *)); int chk_same __P((register ARCHD *)); int node_creat __P((register ARCHD *)); int unlnk_exist __P((register char *, register int)); int chk_path __P((register char *, uid_t, gid_t)); void set_ftime __P((char *fnm, time_t mtime, time_t atime, int frc)); int set_ids __P((char *, uid_t, gid_t)); void set_pmode __P((char *, mode_t)); int file_write __P((int, char *, register int, int *, int *, int, char *)); void file_flush __P((int, char *, int)); void rdfile_close __P((register ARCHD *, register int *)); int set_crc __P((register ARCHD *, register int)); /* * ftree.c */ int ftree_start __P((void)); int ftree_add __P((register char *)); void ftree_sel __P((register ARCHD *)); void ftree_chk __P((void)); int next_file __P((register ARCHD *)); /* * gen_subs.c */ void ls_list __P((register ARCHD *, time_t)); void ls_tty __P((register ARCHD *)); void zf_strncpy __P((register char *, register char *, int)); int l_strncpy __P((register char *, register char *, int)); u_long asc_ul __P((register char *, int, register int)); int ul_asc __P((u_long, register char *, register int, register int)); #ifndef NET2_STAT u_quad_t asc_uqd __P((register char *, int, register int)); int uqd_asc __P((u_quad_t, register char *, register int, register int)); #endif /* * options.c */ extern FSUB fsub[]; extern int ford[]; void options __P((register int, register char **)); OPLIST * opt_next __P((void)); int opt_add __P((register char *)); int bad_opt __P((void)); /* * pat_rep.c */ int rep_add __P((register char *)); int pat_add __P((char *)); void pat_chk __P((void)); int pat_sel __P((register ARCHD *)); int pat_match __P((register ARCHD *)); int mod_name __P((register ARCHD *)); int set_dest __P((register ARCHD *, char *, int)); /* * pax.c */ extern int act; extern FSUB *frmt; extern int cflag; extern int dflag; extern int iflag; extern int kflag; extern int lflag; extern int nflag; extern int tflag; extern int uflag; extern int vflag; extern int Dflag; extern int Hflag; extern int Lflag; extern int Xflag; extern int Yflag; extern int Zflag; extern int vfpart; extern int patime; extern int pmtime; extern int pmode; extern int pids; extern int exit_val; extern int docrc; extern char *dirptr; extern char *argv0; int main __P((int, char **)); void sig_cleanup __P((int)); /* * sel_subs.c */ int sel_chk __P((register ARCHD *)); int grp_add __P((register char *)); int usr_add __P((register char *)); int trng_add __P((register char *)); /* * tables.c */ int lnk_start __P((void)); int chk_lnk __P((register ARCHD *)); void purg_lnk __P((register ARCHD *)); void lnk_end __P((void)); int ftime_start __P((void)); int chk_ftime __P((register ARCHD *)); int name_start __P((void)); int add_name __P((register char *, int, char *)); void sub_name __P((register char *, int *)); int dev_start __P((void)); int add_dev __P((register ARCHD *)); int map_dev __P((register ARCHD *, u_long, u_long)); int atdir_start __P((void)); void atdir_end __P((void)); void add_atdir __P((char *, dev_t, ino_t, time_t, time_t)); int get_atdir __P((dev_t, ino_t, time_t *, time_t *)); int dir_start __P((void)); void add_dir __P((char *, int, struct stat *, int)); void proc_dir __P((void)); u_int st_hash __P((char *, int, int)); /* * tar.c */ int tar_endwr __P((void)); off_t tar_endrd __P((void)); int tar_trail __P((register char *, register int, register int *)); int tar_id __P((register char *, int)); int tar_opt __P((void)); int tar_rd __P((register ARCHD *, register char *)); int tar_wr __P((register ARCHD *)); int ustar_strd __P((void)); int ustar_stwr __P((void)); int ustar_id __P((char *, int)); int ustar_rd __P((register ARCHD *, register char *)); int ustar_wr __P((register ARCHD *)); /* * tty_subs.c */ int tty_init __P((void)); -void tty_prnt __P((char *, ...)); +void tty_prnt __P((const char *, ...)) __printflike(1, 2); int tty_read __P((char *, int)); -void pax_warn __P((int, char *, ...)); -void sys_warn __P((int, int, char *, ...)); +void pax_warn __P((int, const char *, ...)) __printflike(2, 3); +void sys_warn __P((int, int, const char *, ...)) __printflike(3, 4); diff --git a/bin/pax/tty_subs.c b/bin/pax/tty_subs.c index d70bffac1827..805567c05e71 100644 --- a/bin/pax/tty_subs.c +++ b/bin/pax/tty_subs.c @@ -1,245 +1,245 @@ /*- * Copyright (c) 1992 Keith Muller. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Keith Muller of the University of California, San Diego. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)tty_subs.c 8.2 (Berkeley) 4/18/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ #include #include #include #include #include #include #include #include "pax.h" #include "extern.h" #if __STDC__ #include #else #include #endif /* * routines that deal with I/O to and from the user */ #define DEVTTY "/dev/tty" /* device for interactive i/o */ static FILE *ttyoutf = NULL; /* output pointing at control tty */ static FILE *ttyinf = NULL; /* input pointing at control tty */ /* * tty_init() * try to open the controlling terminal (if any) for this process. if the * open fails, future ops that require user input will get an EOF */ #if __STDC__ int tty_init(void) #else int tty_init() #endif { int ttyfd; if ((ttyfd = open(DEVTTY, O_RDWR)) >= 0) { if ((ttyoutf = fdopen(ttyfd, "w")) != NULL) { if ((ttyinf = fdopen(ttyfd, "r")) != NULL) return(0); (void)fclose(ttyoutf); } (void)close(ttyfd); } if (iflag) { pax_warn(1, "Fatal error, cannot open %s", DEVTTY); return(-1); } return(0); } /* * tty_prnt() * print a message using the specified format to the controlling tty * if there is no controlling terminal, just return. */ #if __STDC__ void -tty_prnt(char *fmt, ...) +tty_prnt(const char *fmt, ...) #else void tty_prnt(fmt, va_alist) - char *fmt; + const char *fmt; va_dcl #endif { va_list ap; # if __STDC__ va_start(ap, fmt); # else va_start(ap); # endif if (ttyoutf == NULL) return; (void)vfprintf(ttyoutf, fmt, ap); va_end(ap); (void)fflush(ttyoutf); } /* * tty_read() * read a string from the controlling terminal if it is open into the * supplied buffer * Return: * 0 if data was read, -1 otherwise. */ #if __STDC__ int tty_read(char *str, int len) #else int tty_read(str, len) char *str; int len; #endif { register char *pt; if ((--len <= 0) || (ttyinf == NULL) || (fgets(str,len,ttyinf) == NULL)) return(-1); *(str + len) = '\0'; /* * strip off that trailing newline */ if ((pt = strchr(str, '\n')) != NULL) *pt = '\0'; return(0); } /* * pax_warn() * write a pax_warning message to stderr. if "set" the exit value of pax * will be non-zero. */ #if __STDC__ void -pax_warn(int set, char *fmt, ...) +pax_warn(int set, const char *fmt, ...) #else void pax_warn(set, fmt, va_alist) int set; - char *fmt; + const char *fmt; va_dcl #endif { va_list ap; # if __STDC__ va_start(ap, fmt); # else va_start(ap); # endif if (set) exit_val = 1; /* * when vflag we better ship out an extra \n to get this message on a * line by itself */ if (vflag && vfpart) { (void)fputc('\n', stderr); vfpart = 0; } (void)fprintf(stderr, "%s: ", argv0); (void)vfprintf(stderr, fmt, ap); va_end(ap); (void)fputc('\n', stderr); } /* * sys_warn() * write a pax_warning message to stderr. if "set" the exit value of pax * will be non-zero. */ #if __STDC__ void -sys_warn(int set, int errnum, char *fmt, ...) +sys_warn(int set, int errnum, const char *fmt, ...) #else void sys_warn(set, errnum, fmt, va_alist) int set; int errnum; - char *fmt; + const char *fmt; va_dcl #endif { va_list ap; # if __STDC__ va_start(ap, fmt); # else va_start(ap); # endif if (set) exit_val = 1; /* * when vflag we better ship out an extra \n to get this message on a * line by itself */ if (vflag && vfpart) { (void)fputc('\n', stderr); vfpart = 0; } (void)fprintf(stderr, "%s: ", argv0); (void)vfprintf(stderr, fmt, ap); va_end(ap); /* * format and print the errno */ if (errnum > 0) (void)fprintf(stderr, " <%s>", sys_errlist[errnum]); (void)fputc('\n', stderr); } diff --git a/bin/rcp/extern.h b/bin/rcp/extern.h index 5081c9dcbb57..06e639b039c0 100644 --- a/bin/rcp/extern.h +++ b/bin/rcp/extern.h @@ -1,51 +1,51 @@ /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)extern.h 8.1 (Berkeley) 5/31/93 * $FreeBSD$ */ typedef struct { int cnt; char *buf; } BUF; extern int iamremote; BUF *allocbuf __P((BUF *, int, int)); char *colon __P((char *)); void lostconn __P((int)); void nospace __P((void)); int okname __P((char *)); -void run_err __P((const char *, ...)); +void run_err __P((const char *, ...)) __printflike(1, 2); int susystem __P((char *, int)); void verifydir __P((char *)); diff --git a/bin/rcp/rcp.c b/bin/rcp/rcp.c index a1534ea6d823..8f413bd0ab72 100644 --- a/bin/rcp/rcp.c +++ b/bin/rcp/rcp.c @@ -1,953 +1,954 @@ /* * Copyright (c) 1983, 1990, 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char const copyright[] = "@(#) Copyright (c) 1983, 1990, 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)rcp.c 8.2 (Berkeley) 4/2/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pathnames.h" #include "extern.h" #ifdef KERBEROS #include #include #include "bsd_locl.h" char dst_realm_buf[REALM_SZ]; char *dest_realm = NULL; int use_kerberos = 1; CREDENTIALS cred; Key_schedule schedule; extern char *krb_realmofhost(); #ifdef CRYPT int doencrypt = 0; #define OPTIONS "dfKk:prtx" #else #define OPTIONS "dfKk:prt" #endif #else #define OPTIONS "dfprt" #endif struct passwd *pwd; u_short port; uid_t userid; int errs, rem; int pflag, iamremote, iamrecursive, targetshouldbedirectory; static int argc_copy; static char **argv_copy; #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ #ifdef KERBEROS int kerberos __P((char **, char *, char *, char *)); -void oldw __P((const char *, ...)); +void oldw __P((const char *, ...)) __printflike(1, 2); #endif int response __P((void)); void rsource __P((char *, struct stat *)); +void run_err __P((const char *, ...)) __printflike(1, 2); void sink __P((int, char *[])); void source __P((int, char *[])); void tolocal __P((int, char *[])); void toremote __P((char *, int, char *[])); void usage __P((void)); int main(argc, argv) int argc; char *argv[]; { struct servent *sp; int ch, fflag, i, tflag; char *targ, *shell; #ifdef KERBEROS char *k; #endif /* * Prepare for execing ourselves. */ argc_copy = argc + 1; argv_copy = malloc((argc_copy + 1) * sizeof(*argv_copy)); if (argv_copy == NULL) err(1, "malloc"); argv_copy[0] = argv[0]; argv_copy[1] = "-K"; for (i = 1; i < argc; ++i) { argv_copy[i + 1] = strdup(argv[i]); if (argv_copy[i + 1] == NULL) errx(1, "strdup: out of memory"); } argv_copy[argc + 1] = NULL; fflag = tflag = 0; while ((ch = getopt(argc, argv, OPTIONS)) != -1) switch(ch) { /* User-visible flags. */ case 'K': #ifdef KERBEROS use_kerberos = 0; #endif break; #ifdef KERBEROS case 'k': dest_realm = dst_realm_buf; (void)strncpy(dst_realm_buf, optarg, REALM_SZ - 1); dst_realm_buf[REALM_SZ - 1] = '\0'; break; #ifdef CRYPT case 'x': doencrypt = 1; /* des_set_key(cred.session, schedule); */ break; #endif #endif case 'p': pflag = 1; break; case 'r': iamrecursive = 1; break; /* Server options. */ case 'd': targetshouldbedirectory = 1; break; case 'f': /* "from" */ iamremote = 1; fflag = 1; break; case 't': /* "to" */ iamremote = 1; tflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; #ifdef KERBEROS k = auth_getval("auth_list"); if (k && !strstr(k, "kerberos")) use_kerberos = 0; if (use_kerberos) { #ifdef CRYPT shell = doencrypt ? "ekshell" : "kshell"; #else shell = "kshell"; #endif if ((sp = getservbyname(shell, "tcp")) == NULL) { use_kerberos = 0; oldw("can't get entry for %s/tcp service", shell); sp = getservbyname(shell = "shell", "tcp"); } } else sp = getservbyname(shell = "shell", "tcp"); #else sp = getservbyname(shell = "shell", "tcp"); #endif if (sp == NULL) errx(1, "%s/tcp: unknown service", shell); port = sp->s_port; if ((pwd = getpwuid(userid = getuid())) == NULL) errx(1, "unknown user %d", (int)userid); rem = STDIN_FILENO; /* XXX */ if (fflag) { /* Follow "protocol", send data. */ (void)response(); (void)setuid(userid); source(argc, argv); exit(errs); } if (tflag) { /* Receive data. */ (void)setuid(userid); sink(argc, argv); exit(errs); } if (argc < 2) usage(); if (argc > 2) targetshouldbedirectory = 1; rem = -1; /* Command to be executed on remote system using "rsh". */ #ifdef KERBEROS (void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s%s", iamrecursive ? " -r" : "", #ifdef CRYPT (doencrypt && use_kerberos ? " -x" : ""), #else "", #endif pflag ? " -p" : "", targetshouldbedirectory ? " -d" : ""); #else (void)snprintf(cmd, sizeof(cmd), "rcp%s%s%s", iamrecursive ? " -r" : "", pflag ? " -p" : "", targetshouldbedirectory ? " -d" : ""); #endif (void)signal(SIGPIPE, lostconn); if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ toremote(targ, argc, argv); else { tolocal(argc, argv); /* Dest is local host. */ if (targetshouldbedirectory) verifydir(argv[argc - 1]); } exit(errs); } void toremote(targ, argc, argv) char *targ, *argv[]; int argc; { int i, len, tos; char *bp, *host, *src, *suser, *thost, *tuser; *targ++ = 0; if (*targ == 0) targ = "."; if ((thost = strchr(argv[argc - 1], '@'))) { /* user@host */ *thost++ = 0; tuser = argv[argc - 1]; if (*tuser == '\0') tuser = NULL; else if (!okname(tuser)) exit(1); } else { thost = argv[argc - 1]; tuser = NULL; } for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); if (src) { /* remote to remote */ *src++ = 0; if (*src == 0) src = "."; host = strchr(argv[i], '@'); len = strlen(_PATH_RSH) + strlen(argv[i]) + strlen(src) + (tuser ? strlen(tuser) : 0) + strlen(thost) + strlen(targ) + CMDNEEDS + 20; if (!(bp = malloc(len))) err(1, NULL); if (host) { *host++ = 0; suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; else if (!okname(suser)) continue; (void)snprintf(bp, len, "%s %s -l %s -n %s %s '%s%s%s:%s'", _PATH_RSH, host, suser, cmd, src, tuser ? tuser : "", tuser ? "@" : "", thost, targ); } else (void)snprintf(bp, len, "exec %s %s -n %s %s '%s%s%s:%s'", _PATH_RSH, argv[i], cmd, src, tuser ? tuser : "", tuser ? "@" : "", thost, targ); (void)susystem(bp, userid); (void)free(bp); } else { /* local to remote */ if (rem == -1) { len = strlen(targ) + CMDNEEDS + 20; if (!(bp = malloc(len))) err(1, NULL); (void)snprintf(bp, len, "%s -t %s", cmd, targ); host = thost; #ifdef KERBEROS if (use_kerberos) rem = kerberos(&host, bp, pwd->pw_name, tuser ? tuser : pwd->pw_name); else #endif rem = rcmd(&host, port, pwd->pw_name, tuser ? tuser : pwd->pw_name, bp, 0); if (rem < 0) exit(1); tos = IPTOS_THROUGHPUT; if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0) warn("TOS (ignored)"); if (response() < 0) exit(1); (void)free(bp); (void)setuid(userid); } source(1, argv+i); } } } void tolocal(argc, argv) int argc; char *argv[]; { int i, len, tos; char *bp, *host, *src, *suser; for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ len = strlen(_PATH_CP) + strlen(argv[i]) + strlen(argv[argc - 1]) + 20; if (!(bp = malloc(len))) err(1, NULL); (void)snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, iamrecursive ? " -PR" : "", pflag ? " -p" : "", argv[i], argv[argc - 1]); if (susystem(bp, userid)) ++errs; (void)free(bp); continue; } *src++ = 0; if (*src == 0) src = "."; if ((host = strchr(argv[i], '@')) == NULL) { host = argv[i]; suser = pwd->pw_name; } else { *host++ = 0; suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; else if (!okname(suser)) continue; } len = strlen(src) + CMDNEEDS + 20; if ((bp = malloc(len)) == NULL) err(1, NULL); (void)snprintf(bp, len, "%s -f %s", cmd, src); rem = #ifdef KERBEROS use_kerberos ? kerberos(&host, bp, pwd->pw_name, suser) : #endif rcmd(&host, port, pwd->pw_name, suser, bp, 0); (void)free(bp); if (rem < 0) { ++errs; continue; } (void)seteuid(userid); tos = IPTOS_THROUGHPUT; if (setsockopt(rem, IPPROTO_IP, IP_TOS, &tos, sizeof(int)) < 0) warn("TOS (ignored)"); sink(1, argv + argc - 1); (void)seteuid(0); (void)close(rem); rem = -1; } } void source(argc, argv) int argc; char *argv[]; { struct stat stb; static BUF buffer; BUF *bp; off_t i; int amt, fd, haderr, indx, result; char *last, *name, buf[BUFSIZ]; for (indx = 0; indx < argc; ++indx) { name = argv[indx]; if ((fd = open(name, O_RDONLY, 0)) < 0) goto syserr; if (fstat(fd, &stb)) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } switch (stb.st_mode & S_IFMT) { case S_IFREG: break; case S_IFDIR: if (iamrecursive) { rsource(name, &stb); goto next; } /* FALLTHROUGH */ default: run_err("%s: not a regular file", name); goto next; } if ((last = strrchr(name, '/')) == NULL) last = name; else ++last; if (pflag) { /* * Make it compatible with possible future * versions expecting microseconds. */ (void)snprintf(buf, sizeof(buf), "T%ld 0 %ld 0\n", (long)stb.st_mtimespec.tv_sec, (long)stb.st_atimespec.tv_sec); (void)write(rem, buf, strlen(buf)); if (response() < 0) goto next; } #define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO) (void)snprintf(buf, sizeof(buf), "C%04o %qd %s\n", stb.st_mode & MODEMASK, stb.st_size, last); (void)write(rem, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, BUFSIZ)) == NULL) { next: (void)close(fd); continue; } /* Keep writing after an error so that we stay sync'd up. */ for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; if (i + amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { result = read(fd, bp->buf, amt); if (result != amt) haderr = result >= 0 ? EIO : errno; } if (haderr) (void)write(rem, bp->buf, amt); else { result = write(rem, bp->buf, amt); if (result != amt) haderr = result >= 0 ? EIO : errno; } } if (close(fd) && !haderr) haderr = errno; if (!haderr) (void)write(rem, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void)response(); } } void rsource(name, statp) char *name; struct stat *statp; { DIR *dirp; struct dirent *dp; char *last, *vect[1], path[MAXPATHLEN]; if (!(dirp = opendir(name))) { run_err("%s: %s", name, strerror(errno)); return; } last = strrchr(name, '/'); if (last == 0) last = name; else last++; if (pflag) { (void)snprintf(path, sizeof(path), "T%ld 0 %ld 0\n", (long)statp->st_mtimespec.tv_sec, (long)statp->st_atimespec.tv_sec); (void)write(rem, path, strlen(path)); if (response() < 0) { closedir(dirp); return; } } (void)snprintf(path, sizeof(path), "D%04o %d %s\n", statp->st_mode & MODEMASK, 0, last); (void)write(rem, path, strlen(path)); if (response() < 0) { closedir(dirp); return; } while ((dp = readdir(dirp))) { if (dp->d_ino == 0) continue; if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; if (strlen(name) + 1 + strlen(dp->d_name) >= MAXPATHLEN - 1) { run_err("%s/%s: name too long", name, dp->d_name); continue; } (void)snprintf(path, sizeof(path), "%s/%s", name, dp->d_name); vect[0] = path; source(1, vect); } (void)closedir(dirp); (void)write(rem, "E\n", 2); (void)response(); } void sink(argc, argv) int argc; char *argv[]; { static BUF buffer; struct stat stb; struct timeval tv[2]; enum { YES, NO, DISPLAYED } wrerr; BUF *bp; off_t i, j, size; int amt, count, exists, first, mask, mode, ofd, omode; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[BUFSIZ]; #define atime tv[0] #define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } setimes = targisdir = 0; mask = umask(0); if (!pflag) (void)umask(mask); if (argc != 1) { run_err("ambiguous target"); exit(1); } targ = *argv; if (targetshouldbedirectory) verifydir(targ); (void)write(rem, "", 1); if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) targisdir = 1; for (first = 1;; first = 0) { cp = buf; if (read(rem, cp, 1) <= 0) return; if (*cp++ == '\n') SCREWUP("unexpected "); do { if (read(rem, &ch, sizeof(ch)) != sizeof(ch)) SCREWUP("lost connection"); *cp++ = ch; } while (cp < &buf[BUFSIZ - 1] && ch != '\n'); *cp = 0; if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) (void)write(STDERR_FILENO, buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); ++errs; continue; } if (buf[0] == 'E') { (void)write(rem, "", 1); return; } if (ch == '\n') *--cp = 0; cp = buf; if (*cp == 'T') { setimes++; cp++; mtime.tv_sec = strtol(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("mtime.sec not delimited"); mtime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("mtime.usec not delimited"); atime.tv_sec = strtol(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("atime.sec not delimited"); atime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != '\0') SCREWUP("atime.usec not delimited"); (void)write(rem, "", 1); continue; } if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". * In this case, the line "No match." can be returned * by the shell before the rcp command on the remote is * executed so the ^Aerror_message convention isn't * followed. */ if (first) { run_err("%s", cp); exit(1); } SCREWUP("expected control record"); } mode = 0; for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); mode = (mode << 3) | (*cp - '0'); } if (*cp++ != ' ') SCREWUP("mode not delimited"); for (size = 0; isdigit(*cp);) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); if (targisdir) { static char *namebuf; static int cursize; size_t need; need = strlen(targ) + strlen(cp) + 250; if (need > cursize) { if (!(namebuf = malloc(need))) run_err("%s", strerror(errno)); } (void)snprintf(namebuf, need, "%s%s%s", targ, *targ ? "/" : "", cp); np = namebuf; } else np = targ; exists = stat(np, &stb) == 0; if (buf[0] == 'D') { int mod_flag = pflag; if (exists) { if (!S_ISDIR(stb.st_mode)) { errno = ENOTDIR; goto bad; } if (pflag) (void)chmod(np, mode); } else { /* Handle copying from a read-only directory */ mod_flag = 1; if (mkdir(np, mode | S_IRWXU) < 0) goto bad; } vect[0] = np; sink(1, vect); if (setimes) { setimes = 0; if (utimes(np, tv) < 0) run_err("%s: set times: %s", np, strerror(errno)); } if (mod_flag) (void)chmod(np, mode); continue; } omode = mode; mode |= S_IWRITE; if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; } (void)write(rem, "", 1); if ((bp = allocbuf(&buffer, ofd, BUFSIZ)) == NULL) { (void)close(ofd); continue; } cp = bp->buf; wrerr = NO; for (count = i = 0; i < size; i += BUFSIZ) { amt = BUFSIZ; if (i + amt > size) amt = size - i; count += amt; do { j = read(rem, cp, amt); if (j <= 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); } amt -= j; cp += j; } while (amt > 0); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { j = write(ofd, bp->buf, count); if (j != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; } } count = 0; cp = bp->buf; } } if (count != 0 && wrerr == NO && (j = write(ofd, bp->buf, count)) != count) { wrerr = YES; wrerrno = j >= 0 ? EIO : errno; } if (ftruncate(ofd, size)) { run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } if (pflag) { if (exists || omode != mode) if (fchmod(ofd, omode)) run_err("%s: set mode: %s", np, strerror(errno)); } else { if (!exists && omode != mode) if (fchmod(ofd, omode & ~mask)) run_err("%s: set mode: %s", np, strerror(errno)); } (void)close(ofd); (void)response(); if (setimes && wrerr == NO) { setimes = 0; if (utimes(np, tv) < 0) { run_err("%s: set times: %s", np, strerror(errno)); wrerr = DISPLAYED; } } switch(wrerr) { case YES: run_err("%s: %s", np, strerror(wrerrno)); break; case NO: (void)write(rem, "", 1); break; case DISPLAYED: break; } } screwup: run_err("protocol error: %s", why); exit(1); } #ifdef KERBEROS int kerberos(host, bp, locuser, user) char **host, *bp, *locuser, *user; { if (use_kerberos) { setuid(getuid()); rem = KSUCCESS; errno = 0; if (dest_realm == NULL) dest_realm = krb_realmofhost(*host); rem = #ifdef CRYPT doencrypt ? krcmd_mutual(host, port, user, bp, 0, dest_realm, &cred, schedule) : #endif krcmd(host, port, user, bp, 0, dest_realm); if (rem < 0) { if (errno == ECONNREFUSED) oldw("remote host doesn't support Kerberos"); else if (errno == ENOENT) oldw("can't provide Kerberos authentication data"); execv(_PATH_RCP, argv_copy); err(1, "execv: %s", _PATH_RCP); } } else { #ifdef CRYPT if (doencrypt) errx(1, "the -x option requires Kerberos authentication"); #endif rem = rcmd(host, port, locuser, user, bp, 0); } return (rem); } #endif /* KERBEROS */ int response() { char ch, *cp, resp, rbuf[BUFSIZ]; if (read(rem, &resp, sizeof(resp)) != sizeof(resp)) lostconn(0); cp = rbuf; switch(resp) { case 0: /* ok */ return (0); default: *cp++ = resp; /* FALLTHROUGH */ case 1: /* error, followed by error msg */ case 2: /* fatal error, "" */ do { if (read(rem, &ch, sizeof(ch)) != sizeof(ch)) lostconn(0); *cp++ = ch; } while (cp < &rbuf[BUFSIZ] && ch != '\n'); if (!iamremote) (void)write(STDERR_FILENO, rbuf, cp - rbuf); ++errs; if (resp == 1) return (-1); exit(1); } /* NOTREACHED */ } void usage() { #ifdef KERBEROS #ifdef CRYPT (void)fprintf(stderr, "%s\n%s\n", "usage: rcp [-Kpx] [-k realm] f1 f2", " rcp [-Kprx] [-k realm] f1 ... fn directory"); #else (void)fprintf(stderr, "%s\n%s\n", "usage: rcp [-Kp] [-k realm] f1 f2", " rcp [-Kpr] [-k realm] f1 ... fn directory"); #endif #else (void)fprintf(stderr, "%s\n%s\n", "usage: rcp [-p] f1 f2", " rcp [-pr] f1 ... fn directory"); #endif exit(1); } #if __STDC__ #include #else #include #endif #ifdef KERBEROS void #if __STDC__ oldw(const char *fmt, ...) #else oldw(fmt, va_alist) char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif (void)fprintf(stderr, "rcp: "); (void)vfprintf(stderr, fmt, ap); (void)fprintf(stderr, ", using standard rcp\n"); va_end(ap); } #endif void #if __STDC__ run_err(const char *fmt, ...) #else run_err(fmt, va_alist) char *fmt; va_dcl #endif { static FILE *fp; va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif ++errs; if (fp == NULL && !(fp = fdopen(rem, "w"))) return; (void)fprintf(fp, "%c", 0x01); (void)fprintf(fp, "rcp: "); (void)vfprintf(fp, fmt, ap); (void)fprintf(fp, "\n"); (void)fflush(fp); if (!iamremote) vwarnx(fmt, ap); va_end(ap); } diff --git a/bin/sh/bltin/bltin.h b/bin/sh/bltin/bltin.h index a96c4761006d..5d2b02a8f80a 100644 --- a/bin/sh/bltin/bltin.h +++ b/bin/sh/bltin/bltin.h @@ -1,95 +1,95 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)bltin.h 8.2 (Berkeley) 5/4/95 * $FreeBSD$ */ /* * This file is included by programs which are optionally built into the * shell. If SHELL is defined, we try to map the standard UNIX library * routines to ash routines using defines. */ #include "../shell.h" #include "../mystring.h" #ifdef SHELL #include "../output.h" #undef stdout #define stdout out1 #undef stderr #define stderr out2 #define printf out1fmt #undef putc #define putc(c, file) outc(c, file) #undef putchar #define putchar(c) out1c(c) #define fprintf outfmt #define fputs outstr #define fflush flushout #define INITARGS(argv) #define warnx1(a, b, c) { \ char buf[64]; \ (void)snprintf(buf, sizeof(buf), a); \ error("%s", buf); \ } #define warnx2(a, b, c) { \ char buf[64]; \ (void)snprintf(buf, sizeof(buf), a, b); \ error("%s", buf); \ } #define warnx3(a, b, c) { \ char buf[64]; \ (void)snprintf(buf, sizeof(buf), a, b, c); \ error("%s", buf); \ } #else #undef NULL #include #undef main #define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else #endif #ifdef __STDC__ pointer stalloc(int); -void error(char *, ...); +void error(const char *, ...) __printf0like(1, 2); #else pointer stalloc(); void error(); #endif extern char *commandname; diff --git a/bin/sh/error.c b/bin/sh/error.c index e079699d8141..0407bac575d8 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -1,306 +1,306 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ /* * Errors and exceptions. */ #include "shell.h" #include "main.h" #include "options.h" #include "output.h" #include "error.h" #include "nodes.h" /* show.h needs nodes.h */ #include "show.h" #include "trap.h" #include #include #include /* * Code to handle exceptions in C. */ struct jmploc *handler; volatile sig_atomic_t exception; volatile sig_atomic_t suppressint; volatile sig_atomic_t intpending; char *commandname; -static void exverror __P((int, char *, va_list)); +static void exverror __P((int, const char *, va_list)) __printf0like(2, 0); /* * Called to raise an exception. Since C doesn't include exceptions, we * just do a longjmp to the exception handler. The type of exception is * stored in the global variable "exception". */ void exraise(e) int e; { if (handler == NULL) abort(); exception = e; longjmp(handler->loc, 1); } /* * Called from trap.c when a SIGINT is received. (If the user specifies * that SIGINT is to be trapped or ignored using the trap builtin, then * this routine is not called.) Suppressint is nonzero when interrupts * are held using the INTOFF macro. If SIGINTs are not suppressed and * the shell is not a root shell, then we want to be terminated if we * get here, as if we were terminated directly by a SIGINT. Arrange for * this here. */ void onint() { sigset_t sigset; /* * The !in_dotrap here is safe. The only way we can arrive here * with in_dotrap set is that a trap handler set SIGINT to SIG_DFL * and killed itself. */ if (suppressint && !in_dotrap) { intpending++; return; } intpending = 0; sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); /* * This doesn't seem to be needed, since main() emits a newline. */ #if 0 if (tcgetpgrp(0) == getpid()) write(STDERR_FILENO, "\n", 1); #endif if (rootshell && iflag) exraise(EXINT); else { signal(SIGINT, SIG_DFL); kill(getpid(), SIGINT); } } /* * Exverror is called to raise the error exception. If the first argument * is not NULL then error prints an error message using printf style * formatting. It then raises the error exception. */ static void exverror(cond, msg, ap) int cond; - char *msg; + const char *msg; va_list ap; { CLEAR_PENDING_INT; INTOFF; #ifdef DEBUG if (msg) TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid())); else TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid())); #endif if (msg) { if (commandname) outfmt(&errout, "%s: ", commandname); doformat(&errout, msg, ap); out2c('\n'); } flushall(); exraise(cond); } #ifdef __STDC__ void -error(char *msg, ...) +error(const char *msg, ...) #else void error(va_alist) va_dcl #endif { #ifndef __STDC__ - char *msg; + const char *msg; #endif va_list ap; #ifdef __STDC__ va_start(ap, msg); #else va_start(ap); msg = va_arg(ap, char *); #endif exverror(EXERROR, msg, ap); va_end(ap); } #ifdef __STDC__ void -exerror(int cond, char *msg, ...) +exerror(int cond, const char *msg, ...) #else void exerror(va_alist) va_dcl #endif { #ifndef __STDC__ int cond; char *msg; #endif va_list ap; #ifdef __STDC__ va_start(ap, msg); #else va_start(ap); cond = va_arg(ap, int); msg = va_arg(ap, char *); #endif exverror(cond, msg, ap); va_end(ap); } /* * Table of error messages. */ struct errname { short errcode; /* error number */ short action; /* operation which encountered the error */ char *msg; /* text describing the error */ }; #define ALL (E_OPEN|E_CREAT|E_EXEC) STATIC const struct errname errormsg[] = { { EINTR, ALL, "interrupted" }, { EACCES, ALL, "permission denied" }, { EIO, ALL, "I/O error" }, { ENOENT, E_OPEN, "no such file" }, { ENOENT, E_CREAT,"directory nonexistent" }, { ENOENT, E_EXEC, "not found" }, { ENOTDIR, E_OPEN, "no such file" }, { ENOTDIR, E_CREAT,"directory nonexistent" }, { ENOTDIR, E_EXEC, "not found" }, { EISDIR, ALL, "is a directory" }, #ifdef notdef { EMFILE, ALL, "too many open files" }, #endif { ENFILE, ALL, "file table overflow" }, { ENOSPC, ALL, "file system full" }, #ifdef EDQUOT { EDQUOT, ALL, "disk quota exceeded" }, #endif #ifdef ENOSR { ENOSR, ALL, "no streams resources" }, #endif { ENXIO, ALL, "no such device or address" }, { EROFS, ALL, "read-only file system" }, { ETXTBSY, ALL, "text busy" }, #ifdef SYSV { EAGAIN, E_EXEC, "not enough memory" }, #endif { ENOMEM, ALL, "not enough memory" }, #ifdef ENOLINK { ENOLINK, ALL, "remote access failed" }, #endif #ifdef EMULTIHOP { EMULTIHOP, ALL, "remote access failed" }, #endif #ifdef ECOMM { ECOMM, ALL, "remote access failed" }, #endif #ifdef ESTALE { ESTALE, ALL, "remote access failed" }, #endif #ifdef ETIMEDOUT { ETIMEDOUT, ALL, "remote access failed" }, #endif #ifdef ELOOP { ELOOP, ALL, "symbolic link loop" }, #endif { E2BIG, E_EXEC, "argument list too long" }, #ifdef ELIBACC { ELIBACC, E_EXEC, "shared library missing" }, #endif { 0, 0, NULL }, }; /* * Return a string describing an error. The returned string may be a * pointer to a static buffer that will be overwritten on the next call. * Action describes the operation that got the error. */ char * errmsg(e, action) int e; int action; { struct errname const *ep; static char buf[12]; for (ep = errormsg ; ep->errcode ; ep++) { if (ep->errcode == e && (ep->action & action) != 0) return ep->msg; } fmtstr(buf, sizeof buf, "error %d", e); return buf; } diff --git a/bin/sh/error.h b/bin/sh/error.h index b86e17799474..938ef9113cf1 100644 --- a/bin/sh/error.h +++ b/bin/sh/error.h @@ -1,107 +1,107 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)error.h 8.2 (Berkeley) 5/4/95 * $FreeBSD$ */ /* * Types of operations (passed to the errmsg routine). */ #define E_OPEN 01 /* opening a file */ #define E_CREAT 02 /* creating a file */ #define E_EXEC 04 /* executing a program */ /* * We enclose jmp_buf in a structure so that we can declare pointers to * jump locations. The global variable handler contains the location to * jump to when an exception occurs, and the global variable exception * contains a code identifying the exception. To implement nested * exception handlers, the user should save the value of handler on entry * to an inner scope, set handler to point to a jmploc structure for the * inner scope, and restore handler on exit from the scope. */ #include #include struct jmploc { jmp_buf loc; }; extern struct jmploc *handler; extern volatile sig_atomic_t exception; /* exceptions */ #define EXINT 0 /* SIGINT received */ #define EXERROR 1 /* a generic error */ #define EXSHELLPROC 2 /* execute a shell procedure */ #define EXEXEC 3 /* command execution failed */ /* * These macros allow the user to suspend the handling of interrupt signals * over a period of time. This is similar to SIGHOLD to or sigblock, but * much more efficient and portable. (But hacking the kernel is so much * more fun than worrying about efficiency and portability. :-)) */ extern volatile sig_atomic_t suppressint; extern volatile sig_atomic_t intpending; #define INTOFF suppressint++ #define INTON { if (--suppressint == 0 && intpending) onint(); } #define FORCEINTON {suppressint = 0; if (intpending) onint();} #define CLEAR_PENDING_INT intpending = 0 #define int_pending() intpending void exraise __P((int)); void onint __P((void)); -void error __P((char *, ...)); -void exerror __P((int, char *, ...)); +void error __P((const char *, ...)) __printf0like(1, 2); +void exerror __P((int, const char *, ...)) __printf0like(2, 3); char *errmsg __P((int, int)); /* * BSD setjmp saves the signal mask, which violates ANSI C and takes time, * so we use _setjmp instead. */ #ifdef BSD #define setjmp(jmploc) _setjmp(jmploc) #define longjmp(jmploc, val) _longjmp(jmploc, val) #endif diff --git a/bin/sh/mknodes.c b/bin/sh/mknodes.c index 007cb3247b2f..6fea8ecbf2e6 100644 --- a/bin/sh/mknodes.c +++ b/bin/sh/mknodes.c @@ -1,480 +1,480 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char const copyright[] = "@(#) Copyright (c) 1991, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ /* * This program reads the nodetypes file and nodes.c.pat file. It generates * the files nodes.h and nodes.c. */ #include #include #include #include #ifdef __STDC__ #include #else #include #endif #define MAXTYPES 50 /* max number of node types */ #define MAXFIELDS 20 /* max fields in a structure */ #define BUFLEN 100 /* size of character buffers */ /* field types */ #define T_NODE 1 /* union node *field */ #define T_NODELIST 2 /* struct nodelist *field */ #define T_STRING 3 #define T_INT 4 /* int field */ #define T_OTHER 5 /* other */ #define T_TEMP 6 /* don't copy this field */ struct field { /* a structure field */ char *name; /* name of field */ int type; /* type of field */ char *decl; /* declaration of field */ }; struct str { /* struct representing a node structure */ char *tag; /* structure tag */ int nfields; /* number of fields in the structure */ struct field field[MAXFIELDS]; /* the fields of the structure */ int done; /* set if fully parsed */ }; static int ntypes; /* number of node types */ static char *nodename[MAXTYPES]; /* names of the nodes */ static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ static int nstr; /* number of structures */ static struct str str[MAXTYPES]; /* the structures */ static struct str *curstr; /* current structure */ static FILE *infp = stdin; static char line[1024]; static int linno; static char *linep; static void parsenode __P((void)); static void parsefield __P((void)); static void output __P((char *)); static void outsizes __P((FILE *)); static void outfunc __P((FILE *, int)); static void indent __P((int, FILE *)); static int nextfield __P((char *)); static void skipbl __P((void)); static int readline __P((void)); -static void error __P((const char *, ...)); +static void error __P((const char *, ...)) __printf0like(1, 2); static char *savestr __P((const char *)); int main(argc, argv) int argc; char **argv; { if (argc != 3) error("usage: mknodes file"); if ((infp = fopen(argv[1], "r")) == NULL) error("Can't open %s: %s", argv[1], strerror(errno)); while (readline()) { if (line[0] == ' ' || line[0] == '\t') parsefield(); else if (line[0] != '\0') parsenode(); } output(argv[2]); exit(0); } static void parsenode() { char name[BUFLEN]; char tag[BUFLEN]; struct str *sp; if (curstr && curstr->nfields > 0) curstr->done = 1; nextfield(name); if (! nextfield(tag)) error("Tag expected"); if (*linep != '\0') error("Garbage at end of line"); nodename[ntypes] = savestr(name); for (sp = str ; sp < str + nstr ; sp++) { if (strcmp(sp->tag, tag) == 0) break; } if (sp >= str + nstr) { sp->tag = savestr(tag); sp->nfields = 0; curstr = sp; nstr++; } nodestr[ntypes] = sp; ntypes++; } static void parsefield() { char name[BUFLEN]; char type[BUFLEN]; char decl[2 * BUFLEN]; struct field *fp; if (curstr == NULL || curstr->done) error("No current structure to add field to"); if (! nextfield(name)) error("No field name"); if (! nextfield(type)) error("No field type"); fp = &curstr->field[curstr->nfields]; fp->name = savestr(name); if (strcmp(type, "nodeptr") == 0) { fp->type = T_NODE; sprintf(decl, "union node *%s", name); } else if (strcmp(type, "nodelist") == 0) { fp->type = T_NODELIST; sprintf(decl, "struct nodelist *%s", name); } else if (strcmp(type, "string") == 0) { fp->type = T_STRING; sprintf(decl, "char *%s", name); } else if (strcmp(type, "int") == 0) { fp->type = T_INT; sprintf(decl, "int %s", name); } else if (strcmp(type, "other") == 0) { fp->type = T_OTHER; } else if (strcmp(type, "temp") == 0) { fp->type = T_TEMP; } else { error("Unknown type %s", type); } if (fp->type == T_OTHER || fp->type == T_TEMP) { skipbl(); fp->decl = savestr(linep); } else { if (*linep) error("Garbage at end of line"); fp->decl = savestr(decl); } curstr->nfields++; } char writer[] = "\ /*\n\ * This file was generated by the mknodes program.\n\ */\n\ \n"; static void output(file) char *file; { FILE *hfile; FILE *cfile; FILE *patfile; int i; struct str *sp; struct field *fp; char *p; if ((patfile = fopen(file, "r")) == NULL) error("Can't open %s: %s", file, strerror(errno)); if ((hfile = fopen("nodes.h", "w")) == NULL) error("Can't create nodes.h: %s", strerror(errno)); if ((cfile = fopen("nodes.c", "w")) == NULL) error("Can't create nodes.c"); fputs(writer, hfile); for (i = 0 ; i < ntypes ; i++) fprintf(hfile, "#define %s %d\n", nodename[i], i); fputs("\n\n\n", hfile); for (sp = str ; sp < &str[nstr] ; sp++) { fprintf(hfile, "struct %s {\n", sp->tag); for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) { fprintf(hfile, " %s;\n", fp->decl); } fputs("};\n\n\n", hfile); } fputs("union node {\n", hfile); fprintf(hfile, " int type;\n"); for (sp = str ; sp < &str[nstr] ; sp++) { fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag); } fputs("};\n\n\n", hfile); fputs("struct nodelist {\n", hfile); fputs("\tstruct nodelist *next;\n", hfile); fputs("\tunion node *n;\n", hfile); fputs("};\n\n\n", hfile); fputs("#ifdef __STDC__\n", hfile); fputs("union node *copyfunc(union node *);\n", hfile); fputs("void freefunc(union node *);\n", hfile); fputs("#else\n", hfile); fputs("union node *copyfunc();\n", hfile); fputs("void freefunc();\n", hfile); fputs("#endif\n", hfile); fputs(writer, cfile); while (fgets(line, sizeof line, patfile) != NULL) { for (p = line ; *p == ' ' || *p == '\t' ; p++); if (strcmp(p, "%SIZES\n") == 0) outsizes(cfile); else if (strcmp(p, "%CALCSIZE\n") == 0) outfunc(cfile, 1); else if (strcmp(p, "%COPY\n") == 0) outfunc(cfile, 0); else fputs(line, cfile); } } static void outsizes(cfile) FILE *cfile; { int i; fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes); for (i = 0 ; i < ntypes ; i++) { fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag); } fprintf(cfile, "};\n"); } static void outfunc(cfile, calcsize) FILE *cfile; int calcsize; { struct str *sp; struct field *fp; int i; fputs(" if (n == NULL)\n", cfile); if (calcsize) fputs(" return;\n", cfile); else fputs(" return NULL;\n", cfile); if (calcsize) fputs(" funcblocksize += nodesize[n->type];\n", cfile); else { fputs(" new = funcblock;\n", cfile); fputs(" funcblock = (char *)funcblock + nodesize[n->type];\n", cfile); } fputs(" switch (n->type) {\n", cfile); for (sp = str ; sp < &str[nstr] ; sp++) { for (i = 0 ; i < ntypes ; i++) { if (nodestr[i] == sp) fprintf(cfile, " case %s:\n", nodename[i]); } for (i = sp->nfields ; --i >= 1 ; ) { fp = &sp->field[i]; switch (fp->type) { case T_NODE: if (calcsize) { indent(12, cfile); fprintf(cfile, "calcsize(n->%s.%s);\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_NODELIST: if (calcsize) { indent(12, cfile); fprintf(cfile, "sizenodelist(n->%s.%s);\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_STRING: if (calcsize) { indent(12, cfile); fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n", sp->tag, fp->name); } else { indent(12, cfile); fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n", sp->tag, fp->name, sp->tag, fp->name); } break; case T_INT: case T_OTHER: if (! calcsize) { indent(12, cfile); fprintf(cfile, "new->%s.%s = n->%s.%s;\n", sp->tag, fp->name, sp->tag, fp->name); } break; } } indent(12, cfile); fputs("break;\n", cfile); } fputs(" };\n", cfile); if (! calcsize) fputs(" new->type = n->type;\n", cfile); } static void indent(amount, fp) int amount; FILE *fp; { while (amount >= 8) { putc('\t', fp); amount -= 8; } while (--amount >= 0) { putc(' ', fp); } } static int nextfield(buf) char *buf; { char *p, *q; p = linep; while (*p == ' ' || *p == '\t') p++; q = buf; while (*p != ' ' && *p != '\t' && *p != '\0') *q++ = *p++; *q = '\0'; linep = p; return (q > buf); } static void skipbl() { while (*linep == ' ' || *linep == '\t') linep++; } static int readline() { char *p; if (fgets(line, 1024, infp) == NULL) return 0; for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++); while (p > line && (p[-1] == ' ' || p[-1] == '\t')) p--; *p = '\0'; linep = line; linno++; if (p - line > BUFLEN) error("Line too long"); return 1; } static void #ifdef __STDC__ error(const char *msg, ...) #else error(va_alist) va_dcl #endif { va_list va; #ifdef __STDC__ va_start(va, msg); #else - char *msg; + const char *msg; va_start(va); msg = va_arg(va, char *); #endif (void) fprintf(stderr, "line %d: ", linno); (void) vfprintf(stderr, msg, va); (void) fputc('\n', stderr); va_end(va); exit(2); } static char * savestr(s) const char *s; { char *p; if ((p = malloc(strlen(s) + 1)) == NULL) error("Out of space"); (void) strcpy(p, s); return p; } diff --git a/bin/sh/output.c b/bin/sh/output.c index 82ae3803774f..2989c9a6efd2 100644 --- a/bin/sh/output.c +++ b/bin/sh/output.c @@ -1,575 +1,575 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint #if 0 static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ /* * Shell output routines. We use our own output routines because: * When a builtin command is interrupted we have to discard * any pending output. * When a builtin command appears in back quotes, we want to * save the output of the command in a region obtained * via malloc, rather than doing a fork and reading the * output of the command via a pipe. * Our output routines may be smaller than the stdio routines. */ #include /* quad_t */ #include #include /* defines BUFSIZ */ #include #ifdef __STDC__ #include #else #include #endif #include #include #include #include "shell.h" #include "syntax.h" #include "output.h" #include "memalloc.h" #include "error.h" #define OUTBUFSIZ BUFSIZ #define BLOCK_OUT -2 /* output to a fixed block of memory */ #define MEM_OUT -3 /* output to dynamically allocated memory */ #define OUTPUT_ERR 01 /* error occurred on output */ struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; struct output errout = {NULL, 0, NULL, 100, 2, 0}; struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; struct output *out1 = &output; struct output *out2 = &errout; #ifdef mkinit INCLUDE "output.h" INCLUDE "memalloc.h" RESET { out1 = &output; out2 = &errout; if (memout.buf != NULL) { ckfree(memout.buf); memout.buf = NULL; } } #endif #ifdef notdef /* no longer used */ /* * Set up an output file to write to memory rather than a file. */ void open_mem(block, length, file) char *block; int length; struct output *file; { file->nextc = block; file->nleft = --length; file->fd = BLOCK_OUT; file->flags = 0; } #endif void out1str(p) const char *p; { outstr(p, out1); } void out2str(p) const char *p; { outstr(p, out2); } void outstr(p, file) const char *p; struct output *file; { while (*p) outc(*p++, file); if (file == out2) flushout(file); } char out_junk[16]; void emptyoutbuf(dest) struct output *dest; { int offset; if (dest->fd == BLOCK_OUT) { dest->nextc = out_junk; dest->nleft = sizeof out_junk; dest->flags |= OUTPUT_ERR; } else if (dest->buf == NULL) { INTOFF; dest->buf = ckmalloc(dest->bufsize); dest->nextc = dest->buf; dest->nleft = dest->bufsize; INTON; } else if (dest->fd == MEM_OUT) { offset = dest->bufsize; INTOFF; dest->bufsize <<= 1; dest->buf = ckrealloc(dest->buf, dest->bufsize); dest->nleft = dest->bufsize - offset; dest->nextc = dest->buf + offset; INTON; } else { flushout(dest); } dest->nleft--; } void flushall() { flushout(&output); flushout(&errout); } void flushout(dest) struct output *dest; { if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0) return; if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0) dest->flags |= OUTPUT_ERR; dest->nextc = dest->buf; dest->nleft = dest->bufsize; } void freestdout() { INTOFF; if (output.buf) { ckfree(output.buf); output.buf = NULL; output.nleft = 0; } INTON; } #ifdef __STDC__ void -outfmt(struct output *file, char *fmt, ...) { +outfmt(struct output *file, const char *fmt, ...) { va_list ap; va_start(ap, fmt); doformat(file, fmt, ap); va_end(ap); } void -out1fmt(char *fmt, ...) { +out1fmt(const char *fmt, ...) { va_list ap; va_start(ap, fmt); doformat(out1, fmt, ap); va_end(ap); } void -dprintf(char *fmt, ...) { +dprintf(const char *fmt, ...) { va_list ap; va_start(ap, fmt); doformat(out2, fmt, ap); va_end(ap); flushout(out2); } void -fmtstr(char *outbuf, int length, char *fmt, ...) { +fmtstr(char *outbuf, int length, const char *fmt, ...) { va_list ap; struct output strout; va_start(ap, fmt); strout.nextc = outbuf; strout.nleft = length; strout.fd = BLOCK_OUT; strout.flags = 0; doformat(&strout, fmt, ap); outc('\0', &strout); if (strout.flags & OUTPUT_ERR) outbuf[length - 1] = '\0'; } #else /* not __STDC__ */ void outfmt(va_alist) va_dcl { va_list ap; struct output *file; - char *fmt; + const char *fmt; va_start(ap); file = va_arg(ap, struct output *); fmt = va_arg(ap, char *); doformat(file, fmt, ap); va_end(ap); } void out1fmt(va_alist) va_dcl { va_list ap; - char *fmt; + const char *fmt; va_start(ap); fmt = va_arg(ap, char *); doformat(out1, fmt, ap); va_end(ap); } void dprintf(va_alist) va_dcl { va_list ap; - char *fmt; + const char *fmt; va_start(ap); fmt = va_arg(ap, char *); doformat(out2, fmt, ap); va_end(ap); flushout(out2); } void fmtstr(va_alist) va_dcl { va_list ap; struct output strout; char *outbuf; int length; - char *fmt; + const char *fmt; va_start(ap); outbuf = va_arg(ap, char *); length = va_arg(ap, int); fmt = va_arg(ap, char *); strout.nextc = outbuf; strout.nleft = length; strout.fd = BLOCK_OUT; strout.flags = 0; doformat(&strout, fmt, ap); outc('\0', &strout); if (strout.flags & OUTPUT_ERR) outbuf[length - 1] = '\0'; } #endif /* __STDC__ */ /* * Formatted output. This routine handles a subset of the printf formats: * - Formats supported: d, u, o, X, s, and c. * - The x format is also accepted but is treated like X. * - The l and q modifiers are accepted. * - The - and # flags are accepted; # only works with the o format. * - Width and precision may be specified with any format except c. * - An * may be given for the width or precision. * - The obsolete practice of preceding the width with a zero to get * zero padding is not supported; use the precision field. * - A % may be printed by writing %% in the format string. */ #define TEMPSIZE 24 static const char digit[] = "0123456789ABCDEF"; void doformat(dest, f, ap) struct output *dest; - char *f; /* format string */ + const char *f; /* format string */ va_list ap; { char c; char temp[TEMPSIZE]; int flushleft; int sharp; int width; int prec; int islong; int isquad; char *p; int sign; quad_t l; u_quad_t num; unsigned base; int len; int size; int pad; while ((c = *f++) != '\0') { if (c != '%') { outc(c, dest); continue; } flushleft = 0; sharp = 0; width = 0; prec = -1; islong = 0; isquad = 0; for (;;) { if (*f == '-') flushleft++; else if (*f == '#') sharp++; else break; f++; } if (*f == '*') { width = va_arg(ap, int); f++; } else { while (is_digit(*f)) { width = 10 * width + digit_val(*f++); } } if (*f == '.') { if (*++f == '*') { prec = va_arg(ap, int); f++; } else { prec = 0; while (is_digit(*f)) { prec = 10 * prec + digit_val(*f++); } } } if (*f == 'l') { islong++; f++; } else if (*f == 'q') { isquad++; f++; } switch (*f) { case 'd': if (isquad) l = va_arg(ap, quad_t); else if (islong) l = va_arg(ap, long); else l = va_arg(ap, int); sign = 0; num = l; if (l < 0) { num = -l; sign = 1; } base = 10; goto number; case 'u': base = 10; goto uns_number; case 'o': base = 8; goto uns_number; case 'x': /* we don't implement 'x'; treat like 'X' */ case 'X': base = 16; uns_number: /* an unsigned number */ sign = 0; if (isquad) num = va_arg(ap, u_quad_t); else if (islong) num = va_arg(ap, unsigned long); else num = va_arg(ap, unsigned int); number: /* process a number */ p = temp + TEMPSIZE - 1; *p = '\0'; while (num) { *--p = digit[num % base]; num /= base; } len = (temp + TEMPSIZE - 1) - p; if (prec < 0) prec = 1; if (sharp && *f == 'o' && prec <= len) prec = len + 1; pad = 0; if (width) { size = len; if (size < prec) size = prec; size += sign; pad = width - size; if (flushleft == 0) { while (--pad >= 0) outc(' ', dest); } } if (sign) outc('-', dest); prec -= len; while (--prec >= 0) outc('0', dest); while (*p) outc(*p++, dest); while (--pad >= 0) outc(' ', dest); break; case 's': p = va_arg(ap, char *); pad = 0; if (width) { len = strlen(p); if (prec >= 0 && len > prec) len = prec; pad = width - len; if (flushleft == 0) { while (--pad >= 0) outc(' ', dest); } } prec++; while (--prec != 0 && *p) outc(*p++, dest); while (--pad >= 0) outc(' ', dest); break; case 'c': c = va_arg(ap, int); outc(c, dest); break; default: outc(*f, dest); break; } f++; } } /* * Version of write which resumes after a signal is caught. */ int xwrite(fd, buf, nbytes) int fd; char *buf; int nbytes; { int ntry; int i; int n; n = nbytes; ntry = 0; for (;;) { i = write(fd, buf, n); if (i > 0) { if ((n -= i) <= 0) return nbytes; buf += i; ntry = 0; } else if (i == 0) { if (++ntry > 10) return nbytes - n; } else if (errno != EINTR) { return -1; } } } /* * Version of ioctl that retries after a signal is caught. * XXX unused function */ int xioctl(fd, request, arg) int fd; unsigned long request; char * arg; { int i; while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR); return i; } diff --git a/bin/sh/output.h b/bin/sh/output.h index f99db6b81b8b..425b49fd1583 100644 --- a/bin/sh/output.h +++ b/bin/sh/output.h @@ -1,84 +1,84 @@ /*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)output.h 8.2 (Berkeley) 5/4/95 * $FreeBSD$ */ #ifndef OUTPUT_INCL #ifdef __STDC__ #include #else #include #endif struct output { char *nextc; int nleft; char *buf; int bufsize; short fd; short flags; }; extern struct output output; extern struct output errout; extern struct output memout; extern struct output *out1; extern struct output *out2; void open_mem __P((char *, int, struct output *)); void out1str __P((const char *)); void out2str __P((const char *)); void outstr __P((const char *, struct output *)); void emptyoutbuf __P((struct output *)); void flushall __P((void)); void flushout __P((struct output *)); void freestdout __P((void)); -void outfmt __P((struct output *, char *, ...)); -void out1fmt __P((char *, ...)); -void dprintf __P((char *, ...)); -void fmtstr __P((char *, int, char *, ...)); -void doformat __P((struct output *, char *, va_list)); +void outfmt __P((struct output *, const char *, ...)) __printflike(2, 3); +void out1fmt __P((const char *, ...)) __printflike(1, 2); +void dprintf __P((const char *, ...)) __printflike(1, 2); +void fmtstr __P((char *, int, const char *, ...)) __printflike(3, 4); +void doformat __P((struct output *, const char *, va_list)) __printflike(2, 0); int xwrite __P((int, char *, int)); int xioctl __P((int, unsigned long, char *)); #define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c))) #define out1c(c) outc(c, out1); #define out2c(c) outc(c, out2); #define OUTPUT_INCL #endif diff --git a/bin/sh/show.h b/bin/sh/show.h index 837d21c04ce6..98ec398e6401 100644 --- a/bin/sh/show.h +++ b/bin/sh/show.h @@ -1,44 +1,44 @@ /*- * Copyright (c) 1995 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)show.h 1.1 (Berkeley) 5/4/95 * $FreeBSD$ */ void showtree __P((union node *)); #ifdef DEBUG -void sh_trace __P((const char *, ...)); +void sh_trace __P((const char *, ...)) __printflike(1, 2); void trargs __P((char **)); void trputc __P((int)); void trputs __P((char *)); void opentrace __P((void)); #endif