diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 3ab8f2c5e600..d57406ffaca7 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -130,6 +130,32 @@ OLD_FILES+=usr/lib/clang/3.8.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_ OLD_DIRS+=usr/lib/clang/3.8.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.8.0/lib OLD_DIRS+=usr/lib/clang/3.8.0 +# 20161015: Remove GNU rcs +OLD_FILES+=usr/bin/ci +OLD_FILES+=usr/bin/co +OLD_FILES+=usr/bin/merge +OLD_FILES+=usr/bin/rcs +OLD_FILES+=usr/bin/rcsclean +OLD_FILES+=usr/bin/rcsdiff +OLD_FILES+=usr/bin/rcsfreeze +OLD_FILES+=usr/bin/rcsmerge +OLD_FILES+=usr/bin/rlog +OLD_FILES+=usr/share/doc/psd/13.rcs/paper.ascii.gz +OLD_FILES+=usr/share/doc/psd/13.rcs/rcs_func.ascii.gz +OLD_DIRS+=usr/share/doc/psd/13.rcs +OLD_FILES+=usr/share/man/man1/ci.1.gz +OLD_FILES+=usr/share/man/man1/co.1.gz +OLD_FILES+=usr/share/man/man1/merge.1.gz +OLD_FILES+=usr/share/man/man1/rcs.1.gz +OLD_FILES+=usr/share/man/man1/rcsclean.1.gz +OLD_FILES+=usr/share/man/man1/rcsdiff.1.gz +OLD_FILES+=usr/share/man/man1/rcsfreeze.1.gz +OLD_FILES+=usr/share/man/man1/rcsintro.1.gz +OLD_FILES+=usr/share/man/man1/rcsmerge.1.gz +OLD_FILES+=usr/share/man/man1/rlog.1.gz +OLD_FILES+=usr/share/man/man5/rcsfile.5.gz +# 20161010: remove link to removed m_getclr(9) macro +OLD_FILES+=usr/share/man/man9/m_getclr.9.gz # 20161003: MK_ELFCOPY_AS_OBJCOPY option retired OLD_FILES+=usr/bin/elfcopy OLD_FILES+=usr/share/man/man1/elfcopy.1.gz @@ -572,9 +598,6 @@ OLD_FILES+=usr/lib/clang/3.7.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_ OLD_DIRS+=usr/lib/clang/3.7.0/lib/freebsd OLD_DIRS+=usr/lib/clang/3.7.0/lib OLD_DIRS+=usr/lib/clang/3.7.0 -# 20151201: mqueue tests 3 and 4 disabled -OLD_FILES+=usr/tests/sys/mqueue/mqtest3 -OLD_FILES+=usr/tests/sys/mqueue/mqtest4 # 20151130: libelf moved from /usr/lib to /lib (libkvm dependency in r291406) OLD_LIBS+=usr/lib/libelf.so.2 # 20151115: Fox bad upgrade scheme diff --git a/UPDATING b/UPDATING index 970401bff532..3e4aa3d61976 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,17 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20161015: + GNU rcs has been removed from base. It is available as packages: + - rcs: Latest GPLv3 GNU rcs version. + - rcs57: Copy of the latest version of GNU rcs (GPLv2) before it was + removed from base. + +20161008: + Use of the cc_cdg, cc_chd, cc_hd, or cc_vegas congestion control + modules now requires that the kernel configuration contain the + TCP_HHOOK option. (This option is included in the GENERIC kernel.) + 20161003: The WITHOUT_ELFCOPY_AS_OBJCOPY src.conf(5) knob has been retired. ELF Tool Chain's elfcopy is always installed as /usr/bin/objcopy. diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c index 72fd08aee2c1..2d8c24a0a596 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c @@ -581,6 +581,7 @@ int dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...) { va_list ap; + va_list ap2; int n; #ifndef illumos @@ -605,11 +606,13 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...) len = dtp->dt_sprintf_buflen - len; assert(len >= 0); - if ((n = vsnprintf(buf, len, format, ap)) < 0) + va_copy(ap2, ap); + if ((n = vsnprintf(buf, len, format, ap2)) < 0) n = dt_set_errno(dtp, errno); + va_end(ap2); va_end(ap); - + return (n); } @@ -640,11 +643,14 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...) dtp->dt_buffered_buf[0] = '\0'; } - if ((needed = vsnprintf(NULL, 0, format, ap)) < 0) { + va_copy(ap2, ap); + if ((needed = vsnprintf(NULL, 0, format, ap2)) < 0) { rval = dt_set_errno(dtp, errno); + va_end(ap2); va_end(ap); return (rval); } + va_end(ap2); if (needed == 0) { va_end(ap); @@ -670,12 +676,15 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...) dtp->dt_buffered_size <<= 1; } + va_copy(ap2, ap); if (vsnprintf(&dtp->dt_buffered_buf[dtp->dt_buffered_offs], - avail, format, ap) < 0) { + avail, format, ap2) < 0) { rval = dt_set_errno(dtp, errno); + va_end(ap2); va_end(ap); return (rval); } + va_end(ap2); dtp->dt_buffered_offs += needed; assert(dtp->dt_buffered_buf[dtp->dt_buffered_offs] == '\0'); @@ -683,8 +692,10 @@ dt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...) return (0); } - n = vfprintf(fp, format, ap); + va_copy(ap2, ap); + n = vfprintf(fp, format, ap2); fflush(fp); + va_end(ap2); va_end(ap); if (n < 0) { diff --git a/contrib/libarchive/cpio/test/main.c b/contrib/libarchive/cpio/test/main.c index 541a55030a53..77bf60613c1d 100644 --- a/contrib/libarchive/cpio/test/main.c +++ b/contrib/libarchive/cpio/test/main.c @@ -130,6 +130,13 @@ __FBSDID("$FreeBSD$"); # include #endif +mode_t umasked(mode_t expected_mode) +{ + mode_t mode = umask(0); + umask(mode); + return expected_mode & ~mode; +} + /* Path to working directory for current test */ const char *testworkdir; #ifdef PROGRAM @@ -1294,6 +1301,11 @@ assertion_file_time(const char *file, int line, switch (type) { case 'a': filet_nsec = st.st_atimespec.tv_nsec; break; case 'b': filet = st.st_birthtime; + /* FreeBSD filesystems that don't support birthtime + * (e.g., UFS1) always return -1 here. */ + if (filet == -1) { + return (1); + } filet_nsec = st.st_birthtimespec.tv_nsec; break; case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break; default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); @@ -1425,7 +1437,7 @@ assertion_file_nlinks(const char *file, int line, assertion_count(file, line); r = lstat(pathname, &st); if (r == 0 && (int)st.st_nlink == nlinks) - return (1); + return (1); failure_start(file, line, "File %s has %d links, expected %d", pathname, st.st_nlink, nlinks); failure_finish(NULL); @@ -1661,6 +1673,7 @@ assertion_make_file(const char *file, int line, if (0 != chmod(path, mode)) { failure_start(file, line, "Could not chmod %s", path); failure_finish(NULL); + close(fd); return (0); } if (contents != NULL) { @@ -1675,6 +1688,7 @@ assertion_make_file(const char *file, int line, failure_start(file, line, "Could not write to %s", path); failure_finish(NULL); + close(fd); return (0); } } diff --git a/contrib/libarchive/cpio/test/test.h b/contrib/libarchive/cpio/test/test.h index 1d219647560f..e42840083db5 100644 --- a/contrib/libarchive/cpio/test/test.h +++ b/contrib/libarchive/cpio/test/test.h @@ -182,6 +182,8 @@ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) #define assertFileSize(pathname, size) \ assertion_file_size(__FILE__, __LINE__, pathname, size) +#define assertFileMode(pathname, mode) \ + assertion_file_mode(__FILE__, __LINE__, pathname, mode) #define assertTextFileContents(text, pathname) \ assertion_text_file_contents(__FILE__, __LINE__, text, pathname) #define assertFileContainsLinesAnyOrder(pathname, lines) \ @@ -327,6 +329,9 @@ void copy_reference_file(const char *); */ void extract_reference_files(const char **); +/* Subtract umask from mode */ +mode_t umasked(mode_t expected_mode); + /* Path to working directory for current test */ extern const char *testworkdir; diff --git a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c index 4cffdeb95eb1..f4a861cf29f7 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c +++ b/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c @@ -627,7 +627,6 @@ translate_acl(struct archive_read_disk *a, archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Unknown ACL brand"); return (ARCHIVE_WARN); - break; } #endif diff --git a/contrib/libarchive/libarchive/archive_read_disk_set_standard_lookup.c b/contrib/libarchive/libarchive/archive_read_disk_set_standard_lookup.c index 60a9376bf5d9..719196985878 100644 --- a/contrib/libarchive/libarchive/archive_read_disk_set_standard_lookup.c +++ b/contrib/libarchive/libarchive/archive_read_disk_set_standard_lookup.c @@ -232,6 +232,7 @@ static const char * lookup_uname_helper(struct name_cache *cache, id_t id) { struct passwd *result; + (void)cache; /* UNUSED */ result = getpwuid((uid_t)id); @@ -298,6 +299,7 @@ static const char * lookup_gname_helper(struct name_cache *cache, id_t id) { struct group *result; + (void)cache; /* UNUSED */ result = getgrgid((gid_t)id); diff --git a/contrib/libarchive/libarchive/test/main.c b/contrib/libarchive/libarchive/test/main.c index 0f9c64b69adb..cb3810e548c3 100644 --- a/contrib/libarchive/libarchive/test/main.c +++ b/contrib/libarchive/libarchive/test/main.c @@ -128,6 +128,13 @@ __FBSDID("$FreeBSD$"); # include #endif +mode_t umasked(mode_t expected_mode) +{ + mode_t mode = umask(0); + umask(mode); + return expected_mode & ~mode; +} + /* Path to working directory for current test */ const char *testworkdir; #ifdef PROGRAM @@ -1364,6 +1371,31 @@ assertion_file_birthtime_recent(const char *file, int line, return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); } +/* Verify mode of 'pathname'. */ +int +assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) +{ + int mode; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + failure_start(file, line, "assertFileMode not yet implemented for Windows"); +#else + { + struct stat st; + r = lstat(pathname, &st); + mode = (int)(st.st_mode & 0777); + } + if (r == 0 && mode == expected_mode) + return (1); + failure_start(file, line, "File %s has mode %o, expected %o", + pathname, mode, expected_mode); +#endif + failure_finish(NULL); + return (0); +} + /* Verify mtime of 'pathname'. */ int assertion_file_mtime(const char *file, int line, @@ -1403,7 +1435,7 @@ assertion_file_nlinks(const char *file, int line, assertion_count(file, line); r = lstat(pathname, &st); if (r == 0 && (int)st.st_nlink == nlinks) - return (1); + return (1); failure_start(file, line, "File %s has %d links, expected %d", pathname, st.st_nlink, nlinks); failure_finish(NULL); @@ -1440,31 +1472,6 @@ assertion_file_size(const char *file, int line, const char *pathname, long size) return (0); } -/* Verify mode of 'pathname'. */ -int -assertion_file_mode(const char *file, int line, const char *pathname, int expected_mode) -{ - int mode; - int r; - - assertion_count(file, line); -#if defined(_WIN32) && !defined(__CYGWIN__) - failure_start(file, line, "assertFileMode not yet implemented for Windows"); -#else - { - struct stat st; - r = lstat(pathname, &st); - mode = (int)(st.st_mode & 0777); - } - if (r == 0 && mode == expected_mode) - return (1); - failure_start(file, line, "File %s has mode %o, expected %o", - pathname, mode, expected_mode); -#endif - failure_finish(NULL); - return (0); -} - /* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */ int assertion_is_dir(const char *file, int line, const char *pathname, int mode) @@ -1664,6 +1671,7 @@ assertion_make_file(const char *file, int line, if (0 != chmod(path, mode)) { failure_start(file, line, "Could not chmod %s", path); failure_finish(NULL); + close(fd); return (0); } if (contents != NULL) { @@ -1678,6 +1686,7 @@ assertion_make_file(const char *file, int line, failure_start(file, line, "Could not write to %s", path); failure_finish(NULL); + close(fd); return (0); } } diff --git a/contrib/libarchive/libarchive/test/test.h b/contrib/libarchive/libarchive/test/test.h index bcf68690c405..6b61778c4a35 100644 --- a/contrib/libarchive/libarchive/test/test.h +++ b/contrib/libarchive/libarchive/test/test.h @@ -243,12 +243,12 @@ int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); +int assertion_file_mode(const char *, int, const char *, int); int assertion_file_mtime(const char *, int, const char *, long, long); int assertion_file_mtime_recent(const char *, int, const char *); int assertion_file_nlinks(const char *, int, const char *, int); int assertion_file_not_exists(const char *, int, const char *); int assertion_file_size(const char *, int, const char *, long); -int assertion_file_mode(const char *, int, const char *, int); int assertion_is_dir(const char *, int, const char *, int); int assertion_is_hardlink(const char *, int, const char *, const char *); int assertion_is_not_hardlink(const char *, int, const char *, const char *); @@ -329,6 +329,9 @@ void copy_reference_file(const char *); */ void extract_reference_files(const char **); +/* Subtract umask from mode */ +mode_t umasked(mode_t expected_mode); + /* Path to working directory for current test */ extern const char *testworkdir; diff --git a/contrib/libarchive/libarchive/test/test_read_set_format.c b/contrib/libarchive/libarchive/test/test_read_set_format.c index f9be978351c4..d333269c2ee9 100644 --- a/contrib/libarchive/libarchive/test/test_read_set_format.c +++ b/contrib/libarchive/libarchive/test/test_read_set_format.c @@ -200,6 +200,8 @@ DEFINE_TEST(test_read_append_filter_wrong_program) { struct archive_entry *ae; struct archive *a; + int fd; + fpos_t pos; /* * If we have "bunzip2 -q", try using that. @@ -208,6 +210,13 @@ DEFINE_TEST(test_read_append_filter_wrong_program) skipping("Can't run bunzip2 program on this platform"); return; } + + /* bunzip2 will write to stderr, redirect it to a file */ + fflush(stderr); + fgetpos(stderr, &pos); + fd = dup(fileno(stderr)); + freopen("stderr1", "w", stderr); + assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); assertEqualIntA(a, ARCHIVE_OK, @@ -217,4 +226,13 @@ DEFINE_TEST(test_read_append_filter_wrong_program) assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN)); assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + + /* restore stderr */ + fflush(stderr); + dup2(fd, fileno(stderr)); + close(fd); + clearerr(stderr); + fsetpos(stderr, &pos); + + assertTextFileContents("bunzip2: (stdin) is not a bzip2 file.\n", "stderr1"); } diff --git a/contrib/libarchive/tar/test/main.c b/contrib/libarchive/tar/test/main.c index 8bf1d36b3413..7a035fe2c94a 100644 --- a/contrib/libarchive/tar/test/main.c +++ b/contrib/libarchive/tar/test/main.c @@ -1164,6 +1164,35 @@ assertion_file_contains_lines_any_order(const char *file, int line, return (0); } +/* Verify that a text file does not contains the specified strings */ +int +assertion_file_contains_no_invalid_strings(const char *file, int line, + const char *pathname, const char *strings[]) +{ + char *buff; + int i; + + buff = slurpfile(NULL, "%s", pathname); + if (buff == NULL) { + failure_start(file, line, "Can't read file: %s", pathname); + failure_finish(NULL); + return (0); + } + + for (i = 0; strings[i] != NULL; ++i) { + if (strstr(buff, strings[i]) != NULL) { + failure_start(file, line, "Invalid string in %s: %s", pathname, + strings[i]); + failure_finish(NULL); + free(buff); + return(0); + } + } + + free(buff); + return (0); +} + /* Test that two paths point to the same file. */ /* As a side-effect, asserts that both files exist. */ static int @@ -1301,6 +1330,11 @@ assertion_file_time(const char *file, int line, switch (type) { case 'a': filet_nsec = st.st_atimespec.tv_nsec; break; case 'b': filet = st.st_birthtime; + /* FreeBSD filesystems that don't support birthtime + * (e.g., UFS1) always return -1 here. */ + if (filet == -1) { + return (1); + } filet_nsec = st.st_birthtimespec.tv_nsec; break; case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break; default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); @@ -1432,7 +1466,7 @@ assertion_file_nlinks(const char *file, int line, assertion_count(file, line); r = lstat(pathname, &st); if (r == 0 && (int)st.st_nlink == nlinks) - return (1); + return (1); failure_start(file, line, "File %s has %d links, expected %d", pathname, st.st_nlink, nlinks); failure_finish(NULL); @@ -1668,6 +1702,7 @@ assertion_make_file(const char *file, int line, if (0 != chmod(path, mode)) { failure_start(file, line, "Could not chmod %s", path); failure_finish(NULL); + close(fd); return (0); } if (contents != NULL) { @@ -1682,6 +1717,7 @@ assertion_make_file(const char *file, int line, failure_start(file, line, "Could not write to %s", path); failure_finish(NULL); + close(fd); return (0); } } diff --git a/contrib/libarchive/tar/test/test.h b/contrib/libarchive/tar/test/test.h index 340eadcd1b32..d8bdf2804643 100644 --- a/contrib/libarchive/tar/test/test.h +++ b/contrib/libarchive/tar/test/test.h @@ -174,6 +174,9 @@ /* Assert that file contents match a string. */ #define assertFileContents(data, data_size, pathname) \ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname) +/* Verify that a file does not contain invalid strings */ +#define assertFileContainsNoInvalidStrings(pathname, strings) \ + assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings) #define assertFileMtime(pathname, sec, nsec) \ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) #define assertFileMtimeRecent(pathname) \ @@ -182,6 +185,8 @@ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) #define assertFileSize(pathname, size) \ assertion_file_size(__FILE__, __LINE__, pathname, size) +#define assertFileMode(pathname, mode) \ + assertion_file_mode(__FILE__, __LINE__, pathname, mode) #define assertTextFileContents(text, pathname) \ assertion_text_file_contents(__FILE__, __LINE__, text, pathname) #define assertFileContainsLinesAnyOrder(pathname, lines) \ @@ -239,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *); int assertion_file_birthtime(const char *, int, const char *, long, long); int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); +int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); int assertion_file_mode(const char *, int, const char *, int); diff --git a/contrib/libarchive/tar/test/test_missing_file.c b/contrib/libarchive/tar/test/test_missing_file.c index e2e5da5bddf7..808e384e10b0 100644 --- a/contrib/libarchive/tar/test/test_missing_file.c +++ b/contrib/libarchive/tar/test/test_missing_file.c @@ -27,11 +27,15 @@ __FBSDID("$FreeBSD$"); DEFINE_TEST(test_missing_file) { + const char * invalid_stderr[] = { "INTERNAL ERROR", NULL }; assertMakeFile("file1", 0644, "file1"); assertMakeFile("file2", 0644, "file2"); assert(0 == systemf("%s -cf archive.tar file1 file2 2>stderr1", testprog)); assertEmptyFile("stderr1"); assert(0 != systemf("%s -cf archive.tar file1 file2 file3 2>stderr2", testprog)); + assertFileContainsNoInvalidStrings("stderr2", invalid_stderr); assert(0 != systemf("%s -cf archive.tar 2>stderr3", testprog)); - assert(0 != systemf("%s -cf archive.tar file3 2>stderr4", testprog)); + assertFileContainsNoInvalidStrings("stderr3", invalid_stderr); + assert(0 != systemf("%s -cf archive.tar file3 file4 2>stderr4", testprog)); + assertFileContainsNoInvalidStrings("stderr4", invalid_stderr); } diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c index 6c04cb05256c..d727ce0e9a37 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mdocml/mandocdb.c @@ -103,6 +103,7 @@ struct mpage { char *arch; /* architecture from file content */ char *title; /* title from file content */ char *desc; /* description from file content */ + struct mpage *next; /* singly linked list */ struct mlink *mlinks; /* singly linked list */ int form; /* format from file content */ int name_head_done; @@ -146,6 +147,7 @@ static void dbadd_mlink_name(const struct mlink *mlink); static int dbopen(int); static void dbprune(void); static void filescan(const char *); +static int fts_compare(const FTSENT *const *, const FTSENT *const *); static void mlink_add(struct mlink *, const struct stat *); static void mlink_check(struct mpage *, struct mlink *); static void mlink_free(struct mlink *); @@ -204,6 +206,7 @@ static struct ohash strings; /* table of all strings */ static sqlite3 *db = NULL; /* current database */ static sqlite3_stmt *stmts[STMT__MAX]; /* current statements */ static uint64_t name_mask; +static struct mpage *mpage_head; static const struct mdoc_handler mdocs[MDOC_MAX] = { { NULL, 0 }, /* Ap */ @@ -571,6 +574,20 @@ mandocdb(int argc, char *argv[]) return (int)MANDOCLEVEL_BADARG; } +static int +fts_compare(const FTSENT *const *a, const FTSENT *const *b) +{ + + /* + * The mpage list is processed in the opposite order to which pages are + * added, so traverse the hierarchy in reverse alpha order, resulting + * in database inserts in alpha order. This is not required for correct + * operation, but is helpful when inspecting the database during + * development. + */ + return -strcmp((*a)->fts_name, (*b)->fts_name); +} + /* * Scan a directory tree rooted at "basedir" for manpages. * We use fts(), scanning directory parts along the way for clues to our @@ -600,8 +617,8 @@ treescan(void) argv[0] = "."; argv[1] = (char *)NULL; - f = fts_open((char * const *)argv, - FTS_PHYSICAL | FTS_NOCHDIR, NULL); + f = fts_open((char * const *)argv, FTS_PHYSICAL | FTS_NOCHDIR, + fts_compare); if (f == NULL) { exitcode = (int)MANDOCLEVEL_SYSERR; say("", "&fts_open"); @@ -966,6 +983,8 @@ mlink_add(struct mlink *mlink, const struct stat *st) mpage = mandoc_calloc(1, sizeof(struct mpage)); mpage->inodev.st_ino = inodev.st_ino; mpage->inodev.st_dev = inodev.st_dev; + mpage->next = mpage_head; + mpage_head = mpage; ohash_insert(&mpages, slot, mpage); } else mlink->next = mpage->mlinks; @@ -989,20 +1008,18 @@ mpages_free(void) { struct mpage *mpage; struct mlink *mlink; - unsigned int slot; - mpage = ohash_first(&mpages, &slot); - while (NULL != mpage) { + while (NULL != (mpage = mpage_head)) { while (NULL != (mlink = mpage->mlinks)) { mpage->mlinks = mlink->next; mlink_free(mlink); } + mpage_head = mpage->next; free(mpage->sec); free(mpage->arch); free(mpage->title); free(mpage->desc); free(mpage); - mpage = ohash_next(&mpages, &slot); } } @@ -1123,16 +1140,14 @@ mpages_merge(struct mparse *mp) char *sodest; char *cp; int fd; - unsigned int pslot; if ( ! nodb) SQL_EXEC("BEGIN TRANSACTION"); - mpage = ohash_first(&mpages, &pslot); - while (mpage != NULL) { + for (mpage = mpage_head; mpage != NULL; mpage = mpage->next) { mlinks_undupe(mpage); if ((mlink = mpage->mlinks) == NULL) { - mpage = ohash_next(&mpages, &pslot); + mpage = mpage->next; continue; } @@ -1256,7 +1271,6 @@ mpages_merge(struct mparse *mp) nextpage: ohash_delete(&strings); ohash_delete(&names); - mpage = ohash_next(&mpages, &pslot); } if (0 == nodb) diff --git a/contrib/netbsd-tests/fs/tmpfs/h_tools.c b/contrib/netbsd-tests/fs/tmpfs/h_tools.c index 6a7b8fd38c46..64abe7b1b989 100644 --- a/contrib/netbsd-tests/fs/tmpfs/h_tools.c +++ b/contrib/netbsd-tests/fs/tmpfs/h_tools.c @@ -50,6 +50,10 @@ #include #include +#ifdef __FreeBSD__ +#include +#endif + /* --------------------------------------------------------------------- */ static int getfh_main(int, char **); @@ -70,7 +74,12 @@ getfh_main(int argc, char **argv) if (argc < 2) return EXIT_FAILURE; +#ifdef __FreeBSD__ + fh_size = sizeof(fhandle_t); +#else fh_size = 0; +#endif + fh = NULL; for (;;) { if (fh_size) { @@ -85,7 +94,11 @@ getfh_main(int argc, char **argv) * but it may change if someone moves things around, * so retry untill we have enough memory. */ +#ifdef __FreeBSD__ + error = getfh(argv[1], fh); +#else error = getfh(argv[1], fh, &fh_size); +#endif if (error == 0) { break; } else { diff --git a/contrib/netbsd-tests/fs/tmpfs/t_mount.sh b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh index 11a77d49c24a..ec9d42f0f279 100755 --- a/contrib/netbsd-tests/fs/tmpfs/t_mount.sh +++ b/contrib/netbsd-tests/fs/tmpfs/t_mount.sh @@ -93,7 +93,18 @@ negative_body() { test_unmount } +# Begin FreeBSD +if true; then +atf_test_case large cleanup +large_cleanup() { + umount -f tmp 2>/dev/null +} +else +# End FreeBSD atf_test_case large +# Begin FreeBSD +fi +# End FreeBSD large_head() { atf_set "descr" "Tests that extremely long values passed to -s" \ "are handled correctly" @@ -103,6 +114,10 @@ large_body() { test_mount -o -s9223372036854775807 test_unmount + # Begin FreeBSD + atf_expect_fail "-o -s succeeds unexpectedly on FreeBSD - bug 212862" + # End FreeBSD + mkdir tmp atf_check -s eq:1 -o empty -e ignore \ mount -t tmpfs -o -s9223372036854775808 tmpfs tmp diff --git a/contrib/netbsd-tests/fs/tmpfs/t_remove.sh b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh index df868f9ccf52..78a6e2221aff 100755 --- a/contrib/netbsd-tests/fs/tmpfs/t_remove.sh +++ b/contrib/netbsd-tests/fs/tmpfs/t_remove.sh @@ -46,13 +46,28 @@ single_body() { test_unmount } +# Begin FreeBSD +if true; then +atf_test_case uchg cleanup +uchg_cleanup() { + Mount_Point=$(pwd)/mntpt test_unmount || : +} +else +# End FreeBSD atf_test_case uchg +# Begin FreeBSD +fi +# End FreeBSD uchg_head() { atf_set "descr" "Checks that files with the uchg flag set cannot" \ "be removed" atf_set "require.user" "root" } uchg_body() { + # Begin FreeBSD + atf_expect_fail "this fails on FreeBSD with root - bug 212861" + # End FreeBSD + test_mount atf_check -s eq:0 -o empty -e empty touch a diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 0d6e7a69fc4c..de11e7229148 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -695,6 +695,7 @@ iovctl_files="" # Config files for iovctl(8) ### Jail Configuration (see rc.conf(5) manual page) ########## ############################################################## jail_enable="NO" # Set to NO to disable starting of any jails +jail_confwarn="YES" # Prevent warning about obsolete per-jail configuration jail_parallel_start="NO" # Start jails in the background jail_list="" # Space separated list of names of jails jail_reverse_stop="NO" # Stop jails in reverse order diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 481675c7395c..feaed8ee6d10 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -228,8 +228,6 @@ .. 12.make .. - 13.rcs - .. 15.yacc .. 16.lex diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 9ad9f91ee756..ad43a20a268f 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -314,6 +314,7 @@ FILES+= wpa_supplicant .if ${MK_ZFS} != "no" FILESGROUPS+= ZFS ZFS+= zfs +ZFS+= zfsbe ZFS+= zfsd ZFS+= zvol ZFSPACKAGE= zfs diff --git a/etc/rc.d/jail b/etc/rc.d/jail index 216c80e7fca3..8cf830a139a3 100755 --- a/etc/rc.d/jail +++ b/etc/rc.d/jail @@ -147,7 +147,8 @@ parse_options() # # To relieve confusion, show a warning message. # - _confwarn=1 + : ${jail_confwarn:=YES} + checkyesno jail_confwarn && _confwarn=1 if [ -r "$jail_conf" -o -r "$_jconf" ]; then if ! checkyesno jail_parallel_start; then warn "$_conf is created and used for jail $_j." diff --git a/etc/rc.d/zfs b/etc/rc.d/zfs index a98487c1393c..2d35f9b54642 100755 --- a/etc/rc.d/zfs +++ b/etc/rc.d/zfs @@ -4,7 +4,7 @@ # # PROVIDE: zfs -# REQUIRE: mountcritlocal +# REQUIRE: zfsbe # BEFORE: FILESYSTEMS var . /etc/rc.subr diff --git a/etc/rc.d/zfsbe b/etc/rc.d/zfsbe new file mode 100755 index 000000000000..3c852017aa41 --- /dev/null +++ b/etc/rc.d/zfsbe @@ -0,0 +1,71 @@ +#!/bin/sh +# +# $FreeBSD$ +# + +# PROVIDE: zfsbe +# REQUIRE: mountcritlocal + +# Handle boot environment subordinate filesystems +# that may have canmount property set to noauto. +# For these filesystems mountpoint relative to / +# must be the same as their dataset name relative +# to BE root dataset. + +. /etc/rc.subr + +name="zfsbe" +rcvar="zfs_enable" +start_cmd="be_start" +stop_cmd="be_stop" +required_modules="zfs" + +mount_subordinate() +{ + local _be + + _be=$1 + zfs list -rH -o mountpoint,name,canmount,mounted -s mountpoint -t filesystem $_be | \ + while read _mp _name _canmount _mounted ; do + # skip filesystems that must not be mounted + [ "$_canmount" = "off" ] && continue + # skip filesystems that are already mounted + [ "$_mounted" = "yes" ] && continue + case "$_mp" in + "none" | "legacy" | "/" | "/$_be") + # do nothing for filesystems with unset or legacy mountpoint + # or those that would be mounted over / + ;; + "/$_be/"*) + # filesystems with mountpoint relative to BE + mount -t zfs $_name ${_mp#/$_be} + ;; + *) + # filesystems with mountpoint elsewhere + zfs mount $_name + ;; + esac + done +} + +be_start() +{ + if [ `$SYSCTL_N security.jail.jailed` -eq 1 ]; then + : + else + mount -p | while read _dev _mp _type _rest; do + [ $_mp = "/" ] || continue + if [ $_type = "zfs" ] ; then + mount_subordinate $_dev + fi + break + done + fi +} + +be_stop() +{ +} + +load_rc_config $name +run_rc_command "$1" diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile index 6ba9ef2e1fe3..8e42053c08ab 100644 --- a/gnu/usr.bin/Makefile +++ b/gnu/usr.bin/Makefile @@ -11,7 +11,6 @@ SUBDIR= ${_binutils} \ ${_gperf} \ grep \ ${_groff} \ - ${_rcs} \ ${_tests} SUBDIR_DEPEND_gdb= ${_binutils} @@ -29,10 +28,6 @@ _groff= groff _dtc= dtc .endif -.if ${MK_RCS} != "no" -_rcs= rcs -.endif - .if ${MK_TESTS} != "no" _tests= tests .endif diff --git a/gnu/usr.bin/groff/mdate.sh b/gnu/usr.bin/groff/mdate.sh index 70a052abc046..03a4a090685e 100755 --- a/gnu/usr.bin/groff/mdate.sh +++ b/gnu/usr.bin/groff/mdate.sh @@ -4,6 +4,5 @@ set -e test -r "$1" export LC_ALL=C -changelog_date=$(sed -E -n 's/^([0-9]{4}-[0-9]{2}-[0-9]{2}).*$/\1/p' "$1" |\ - head -n 1) +changelog_date=$(sed -E -n '1s/^([0-9]{4}-[0-9]{2}-[0-9]{2}).*$/\1/p' "$1") echo $(date -j -f %Y-%m-%d +"%e %B %Y" $changelog_date) diff --git a/gnu/usr.bin/rcs/CREDITS b/gnu/usr.bin/rcs/CREDITS deleted file mode 100644 index 589e8b685091..000000000000 --- a/gnu/usr.bin/rcs/CREDITS +++ /dev/null @@ -1,24 +0,0 @@ -RCS was designed and built by Walter F. Tichy of Purdue University. -RCS version 3 was released in 1983. - -Adam Hammer, Thomas Narten, and Daniel Trinkle of Purdue supported RCS through -version 4.3, released in 1990. Guy Harris of Sun contributed many porting -fixes. Paul Eggert of System Development Corporation contributed bug fixes -and tuneups. Jay Lepreau contributed 4.3BSD support. - -Paul Eggert of Twin Sun wrote the changes for RCS versions 5.5 and 5.6 (1991). -Rich Braun of Kronos and Andy Glew of Intel contributed ideas for new options. -Bill Hahn of Stratus contributed ideas for setuid support. -Ideas for piece tables came from Joe Berkovitz of Stratus and Walter F. Tichy. -Matt Cross of Stratus contributed test case ideas. -Adam Hammer of Purdue QAed. - -Paul Eggert wrote most of the changes for this version of RCS, -currently in beta test. K. Richard Pixley of Cygnus Support -contributed several bug fixes. Robert Lupton of Princeton -and Daniel Trinkle contributed ideas for $Name expansion. -Brendan Kehoe of Cygnus Support suggested rlog's -N option. -Paul D. Smith of Data General suggested improvements in option -and error processing. Adam Hammer of Purdue QAed. - -$FreeBSD$ diff --git a/gnu/usr.bin/rcs/Makefile b/gnu/usr.bin/rcs/Makefile deleted file mode 100644 index 6b2bd1c3a8f1..000000000000 --- a/gnu/usr.bin/rcs/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ - -SUBDIR= lib .WAIT \ - ci co merge rcs rcsclean rcsdiff rcsmerge rlog rcsfreeze -SUBDIR_PARALLEL= - -.include diff --git a/gnu/usr.bin/rcs/Makefile.inc b/gnu/usr.bin/rcs/Makefile.inc deleted file mode 100644 index a46437ad8c82..000000000000 --- a/gnu/usr.bin/rcs/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -# $FreeBSD$ - -LIBRCS= ${.OBJDIR}/../lib/librcs.a diff --git a/gnu/usr.bin/rcs/NEWS b/gnu/usr.bin/rcs/NEWS deleted file mode 100644 index 99208064bd32..000000000000 --- a/gnu/usr.bin/rcs/NEWS +++ /dev/null @@ -1,548 +0,0 @@ -Recent changes to RCS (and possible future changes) - - $FreeBSD$ - - Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - - This file is part of RCS. - - RCS is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 2, or (at your - option) any later version. - - RCS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with RCS; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - - -Here is a brief summary of user-visible changes since 5.6. - - New options: - `-kb' supports binary files. - `-T' preserves the modification time of RCS files. - `-V' prints the version number. - `-zLT' causes RCS to use local time in working files and logs. - `rcsclean -n' outputs what rcsclean would do, without actually doing it. - `rlog -N' omits symbolic names. - There is a new keyword `Name'. - Inserted log lines now have the same prefix as the preceding `$Log' line. - -Most changes for RCS version 5.7 are to fix bugs and improve portability. -RCS now conforms to GNU configuration standards and to Posix 1003.1b-1993. - - -Features new to RCS version 5.7, and possibly incompatible -in minor ways with previous practice, include: - - Inserted log lines now have the same prefix as the preceding `$Log' line. - E.g. if a $Log line starts with `// $Log', log lines are prefixed with `// '. - RCS still records the (now obsolescent) comment leader inside RCS files, - but it ignores the comment leader unless it is emulating older RCS versions. - If you plan to access a file with both old and new versions of RCS, - make sure its comment leader matches its `$Log' line prefix. - For backwards compatibility with older versions of RCS, - if the log prefix is `/*' or `(*' surrounded by optional white space, - inserted log lines contain ` *' instead of `/*' or `(*'; - however, this usage is obsolescent and should not be relied on. - - $Log string `Revision' times now use the same format as other times. - - Log lines are now inserted even if -kk is specified; this simplifies merging. - - ci's -rR option (with a nonempty R) now just specifies a revision number R. - In some beta versions, it also reestablished the default behavior of - releasing a lock and removing the working file. - Now, only the bare -r option does this. - - With an empty extension, any appearance of a directory named `RCS' - in a pathname identifies the pathname as being that of an RCS file. - For example, `a/RCS/b/c' is now an RCS file with an empty extension. - Formerly, `RCS' had to be the last directory in the pathname. - - rlog's -d option by default now uses exclusive time ranges. - E.g. `rlog -d" - - for software engineering; e.g. see - . - - - - for configuration management - - - - for CVS (see below) - - -RCS and related GNU project software - - - The RCS project distribution directory also contains beta versions, - ports, and prebuilt documentation. - - - The GNU project distribution directory contains: - diffutils-N-tar.gz - the latest diffutils release; recommended for RCS - emacs-N-tar.gz - The latest Emacs release contains VC, a version-control package - that makes RCS easier to use. - make-N-tar.gz - GNU Make, which can automatically build from RCS files. - rcs-N-tar.gz - the latest RCS release - cvs-N-tar.gz - the latest official CVS release (see below) - - DOS, OS/2 ports - NT port - - -CVS - -CVS, the Concurrent Versions System, keeps tracks of source changes -made by groups of developers working on the same files concurrently, -allowing them to resync as needed. - - - - These pages have useful information about CVS. - - - CVS 1.3 is the latest released version. - - - CVS 1.4 is in alpha test, but it is recommended if you are installing CVS - for the first time, or on a recent operating system. - - DOS, OS/2 ports - NT port - - - Cyclic CVS adds network transparency to CVS; it supports efficient, - reliable, and authenticated repository access via TCP/IP. - - -Other software that uses RCS - - - Aegis manages revisions, baselines, mandatory reviews, and mandatory testing. - - - BCS, the Baseline Configuration System, - manages revisions, baselines, and staging areas. - - - ODE, the Open Software Foundation Development Environment, - manages revisions, builds, and sandboxes. - OSF uses it for their own development. - - - Odin, a `make' replacement, can build directly from arbitrary revisions - without requiring checkouts of working copies. It also handles - parallel builds on multiple remote hosts and of multiple variants. diff --git a/gnu/usr.bin/rcs/ci/Makefile b/gnu/usr.bin/rcs/ci/Makefile deleted file mode 100644 index 2fbb74f4238d..000000000000 --- a/gnu/usr.bin/rcs/ci/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= ci -SRCS= ci.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/ci/Makefile.depend b/gnu/usr.bin/rcs/ci/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/ci/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/ci/ci.1 b/gnu/usr.bin/rcs/ci/ci.1 deleted file mode 100644 index 1378af222cb8..000000000000 --- a/gnu/usr.bin/rcs/ci/ci.1 +++ /dev/null @@ -1,898 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds i \&\s-1ISO\s0 -.ds r \&\s-1RCS\s0 -.ds u \&\s-1UTC\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH CI 1 \*(Dt GNU -.SH NAME -ci \- check in RCS revisions -.SH SYNOPSIS -.B ci -.RI [ options ] " file " .\|.\|. -.SH DESCRIPTION -.B ci -stores new revisions into \*r files. -Each pathname matching an \*r suffix -is taken to be an \*r file. -All others -are assumed to be working files containing new revisions. -.B ci -deposits the contents of each working file -into the corresponding \*r file. -If only a working file is given, -.B ci -tries to find the corresponding \*r file in an \*r subdirectory -and then in the working file's directory. -For more details, see -.SM "FILE NAMING" -below. -.PP -For -.B ci -to work, the caller's login must be on the access list, -except if the access list is empty or the caller is the superuser or the -owner of the file. -To append a new revision to an existing branch, the tip revision on -that branch must be locked by the caller. Otherwise, only a -new branch can be created. This restriction is not enforced -for the owner of the file if non-strict locking is used -(see -.BR rcs (1)). -A lock held by someone else can be broken with the -.B rcs -command. -.PP -Unless the -.B \-f -option is given, -.B ci -checks whether the revision to be deposited differs from the preceding one. -If not, instead of creating a new revision -.B ci -reverts to the preceding one. -To revert, ordinary -.B ci -removes the working file and any lock; -.B "ci\ \-l" -keeps and -.B "ci\ \-u" -removes any lock, and then they both generate a new working file much as if -.B "co\ \-l" -or -.B "co\ \-u" -had been applied to the preceding revision. -When reverting, any -.B \-n -and -.B \-s -options apply to the preceding revision. -.PP -For each revision deposited, -.B ci -prompts for a log message. -The log message should summarize the change and must be terminated by -end-of-file or by a line containing -.BR \&. "\ by" -itself. -If several files are checked in -.B ci -asks whether to reuse the -previous log message. -If the standard input is not a terminal, -.B ci -suppresses the prompt -and uses the same log message for all files. -See also -.BR \-m . -.PP -If the \*r file does not exist, -.B ci -creates it and -deposits the contents of the working file as the initial revision -(default number: -.BR 1.1 ). -The access list is initialized to empty. -Instead of the log message, -.B ci -requests descriptive text (see -.B \-t -below). -.PP -The number -.I rev -of the deposited revision can be given by any of the options -.BR \-f , -.BR \-i , -.BR \-I , -.BR \-j , -.BR \-k , -.BR \-l , -.BR \-M , -.BR \-q , -.BR \-r , -or -.BR \-u . -.I rev -can be symbolic, numeric, or mixed. -Symbolic names in -.I rev -must already be defined; -see the -.B \-n -and -.B \-N -options for assigning names during checkin. -If -.I rev -is -.BR $ , -.B ci -determines the revision number from keyword values in the working file. -.PP -If -.I rev -begins with a period, -then the default branch (normally the trunk) is prepended to it. -If -.I rev -is a branch number followed by a period, -then the latest revision on that branch is used. -.PP -If -.I rev -is a revision number, it must be higher than the latest -one on the branch to which -.I rev -belongs, or must start a new branch. -.PP -If -.I rev -is a branch rather than a revision number, -the new revision is appended to that branch. The level number is obtained -by incrementing the tip revision number of that branch. -If -.I rev -indicates a non-existing branch, -that branch is created with the initial revision numbered -.IB rev .1\f1.\fP -.br -.ne 8 -.PP -If -.I rev -is omitted, -.B ci -tries to derive the new revision number from -the caller's last lock. If the caller has locked the tip revision of a branch, -the new revision is appended to that branch. -The new revision number is obtained -by incrementing the tip revision number. -If the caller locked a non-tip revision, a new branch is started at -that revision by incrementing the highest branch number at that revision. -The default initial branch and level numbers are -.BR 1 . -.PP -If -.I rev -is omitted and the caller has no lock, but owns -the file and locking -is not set to -.IR strict , -then the revision is appended to the -default branch (normally the trunk; see the -.B \-b -option of -.BR rcs (1)). -.PP -Exception: On the trunk, revisions can be appended to the end, but -not inserted. -.SH OPTIONS -.TP -.BI \-r rev -Check in revision -.IR rev . -.TP -.BR \-r -The bare -.B \-r -option (without any revision) has an unusual meaning in -.BR ci . -With other \*r commands, a bare -.B \-r -option specifies the most recent revision on the default branch, -but with -.BR ci , -a bare -.B \-r -option reestablishes the default behavior of releasing a lock and -removing the working file, and is used to override any default -.B \-l -or -.B \-u -options established by shell aliases or scripts. -.TP -.BR \-l [\f2rev\fP] -works like -.BR \-r , -except it performs an additional -.B "co\ \-l" -for the -deposited revision. Thus, the deposited revision is immediately -checked out again and locked. -This is useful for saving a revision although one wants to continue -editing it after the checkin. -.TP -.BR \-u [\f2rev\fP] -works like -.BR \-l , -except that the deposited revision is not locked. -This lets one read the working file -immediately after checkin. -.RS -.PP -The -.BR \-l , -bare -.BR \-r , -and -.B \-u -options are mutually exclusive and silently override each other. -For example, -.B "ci\ \-u\ \-r" -is equivalent to -.B "ci\ \-r" -because bare -.B \-r -overrides -.BR \-u . -.RE -.TP -.BR \-f [\f2rev\fP] -forces a deposit; the new revision is deposited even it is not different -from the preceding one. -.TP -.BR \-k [\f2rev\fP] -searches the working file for keyword values to determine its revision number, -creation date, state, and author (see -.BR co (1)), -and assigns these -values to the deposited revision, rather than computing them locally. -It also generates a default login message noting the login of the caller -and the actual checkin date. -This option is useful for software distribution. A revision that is sent to -several sites should be checked in with the -.B \-k -option at these sites to -preserve the original number, date, author, and state. -The extracted keyword values and the default log message can be overridden -with the options -.BR \-d , -.BR \-m , -.BR \-s , -.BR \-w , -and any option that carries a revision number. -.TP -.BR \-q [\f2rev\fP] -quiet mode; diagnostic output is not printed. -A revision that is not different from the preceding one is not deposited, -unless -.B \-f -is given. -.TP -.BR \-i [\f2rev\fP] -initial checkin; report an error if the \*r file already exists. -This avoids race conditions in certain applications. -.TP -.BR \-j [\f2rev\fP] -just checkin and do not initialize; -report an error if the \*r file does not already exist. -.TP -.BR \-I [\f2rev\fP] -interactive mode; -the user is prompted and questioned -even if the standard input is not a terminal. -.TP -.BR \-d "[\f2date\fP]" -uses -.I date -for the checkin date and time. -The -.I date -is specified in free format as explained in -.BR co (1). -This is useful for lying about the checkin date, and for -.B \-k -if no date is available. -If -.I date -is empty, the working file's time of last modification is used. -.TP -.BR \-M [\f2rev\fP] -Set the modification time on any new working file -to be the date of the retrieved revision. -For example, -.BI "ci\ \-d\ \-M\ \-u" "\ f" -does not alter -.IR f 's -modification time, even if -.IR f 's -contents change due to keyword substitution. -Use this option with care; it can confuse -.BR make (1). -.TP -.BI \-m "msg" -uses the string -.I msg -as the log message for all revisions checked in. -By convention, log messages that start with -.B # -are comments and are ignored by programs like GNU Emacs's -.B vc -package. -Also, log messages that start with -.BI { clumpname } -(followed by white space) are meant to be clumped together if possible, -even if they are associated with different files; the -.BI { clumpname } -label is used only for clumping, -and is not considered to be part of the log message itself. -.TP -.BI \-n "name" -assigns the symbolic name -.I name -to the number of the checked-in revision. -.B ci -prints an error message if -.I name -is already assigned to another -number. -.TP -.BI \-N "name" -same as -.BR \-n , -except that it overrides a previous assignment of -.IR name . -.TP -.BI \-s "state" -sets the state of the checked-in revision to the identifier -.IR state . -The default state is -.BR Exp . -.TP -.BI \-t file -writes descriptive text from the contents of the named -.I file -into the \*r file, -deleting the existing text. -The -.I file -cannot begin with -.BR \- . -.TP -.BI \-t\- string -Write descriptive text from the -.I string -into the \*r file, deleting the existing text. -.RS -.PP -The -.B \-t -option, in both its forms, has effect only during an initial checkin; -it is silently ignored otherwise. -.PP -During the initial checkin, if -.B \-t -is not given, -.B ci -obtains the text from standard input, -terminated by end-of-file or by a line containing -.BR \&. "\ by" -itself. -The user is prompted for the text if interaction is possible; see -.BR \-I . -.PP -For backward compatibility with older versions of \*r, a bare -.B \-t -option is ignored. -.RE -.TP -.B \-T -Set the \*r file's modification time to the new revision's time -if the former precedes the latter and there is a new revision; -preserve the \*r file's modification time otherwise. -If you have locked a revision, -.B ci -usually updates the \*r file's modification time to the current time, -because the lock is stored in the \*r file -and removing the lock requires changing the \*r file. -This can create an \*r file newer than the working file in one of two ways: -first, -.B "ci\ \-M" -can create a working file with a date before the current time; -second, when reverting to the previous revision -the \*r file can change while the working file remains unchanged. -These two cases can cause excessive recompilation caused by a -.BR make (1) -dependency of the working file on the \*r file. -The -.B \-T -option inhibits this recompilation by lying about the \*r file's date. -Use this option with care; it can suppress recompilation even when -a checkin of one working file should affect -another working file associated with the same \*r file. -For example, suppose the \*r file's time is 01:00, -the (changed) working file's time is 02:00, -some other copy of the working file has a time of 03:00, -and the current time is 04:00. -Then -.B "ci\ \-d\ \-T" -sets the \*r file's time to 02:00 instead of the usual 04:00; -this causes -.BR make (1) -to think (incorrectly) that the other copy is newer than the \*r file. -.TP -.BI \-w "login" -uses -.I login -for the author field of the deposited revision. -Useful for lying about the author, and for -.B \-k -if no author is available. -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.IR n . -See -.BR co (1) -for details. -.TP -.BI \-x "suffixes" -specifies the suffixes for \*r files. -A nonempty suffix matches any pathname ending in the suffix. -An empty suffix matches any pathname of the form -.BI RCS/ path -or -.IB path1 /RCS/ path2. -The -.B \-x -option can specify a list of suffixes -separated by -.BR / . -For example, -.B \-x,v/ -specifies two suffixes: -.B ,v -and the empty suffix. -If two or more suffixes are specified, -they are tried in order when looking for an \*r file; -the first one that works is used for that file. -If no \*r file is found but an \*r file can be created, -the suffixes are tried in order -to determine the new \*r file's name. -The default for -.IR suffixes -is installation-dependent; normally it is -.B ,v/ -for hosts like Unix that permit commas in filenames, -and is empty (i.e. just the empty suffix) for other hosts. -.TP -.BI \-z zone -specifies the date output format in keyword substitution, -and specifies the default time zone for -.I date -in the -.BI \-d date -option. -The -.I zone -should be empty, a numeric \*u offset, or the special string -.B LT -for local time. -The default is an empty -.IR zone , -which uses the traditional \*r format of \*u without any time zone indication -and with slashes separating the parts of the date; -otherwise, times are output in \*i 8601 format with time zone indication. -For example, if local time is January 11, 1990, 8pm Pacific Standard Time, -eight hours west of \*u, -then the time is output as follows: -.RS -.LP -.RS -.nf -.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u -.ne 4 -\f2option\fP \f2time output\fP -\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP -\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP -\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP -.ta 4n +4n +4n +4n -.fi -.RE -.LP -The -.B \-z -option does not affect dates stored in \*r files, -which are always \*u. -.SH "FILE NAMING" -Pairs of \*r files and working files can be specified in three ways -(see also the -example section). -.PP -1) Both the \*r file and the working file are given. The \*r pathname is of -the form -.IB path1 / workfileX -and the working pathname is of the form -.IB path2 / workfile -where -.IB path1 / -and -.IB path2 / -are (possibly different or empty) paths, -.I workfile -is a filename, and -.I X -is an \*r suffix. -If -.I X -is empty, -.IB path1 / -must start with -.B RCS/ -or must contain -.BR /RCS/ . -.PP -2) Only the \*r file is given. Then the working file is created in the current -directory and its name is derived from the name of the \*r file -by removing -.IB path1 / -and the suffix -.IR X . -.PP -3) Only the working file is given. -Then -.B ci -considers each \*r suffix -.I X -in turn, looking for an \*r file of the form -.IB path2 /RCS/ workfileX -or (if the former is not found and -.I X -is nonempty) -.IB path2 / workfileX. -.PP -If the \*r file is specified without a path in 1) and 2), -.B ci -looks for the \*r file first in the directory -.B ./RCS -and then in the current -directory. -.PP -.B ci -reports an error if an attempt to open an \*r file fails for an unusual reason, -even if the \*r file's pathname is just one of several possibilities. -For example, to suppress use of \*r commands in a directory -.IR d , -create a regular file named -.IB d /RCS -so that casual attempts to use \*r commands in -.I d -fail because -.IB d /RCS -is not a directory. -.SH EXAMPLES -Suppose -.B ,v -is an \*r suffix and the current directory contains a subdirectory -.B RCS -with an \*r file -.BR io.c,v . -Then each of the following commands check in a copy of -.B io.c -into -.B RCS/io.c,v -as the latest revision, removing -.BR io.c . -.LP -.RS -.nf -.ft 3 -ci io.c; ci RCS/io.c,v; ci io.c,v; -ci io.c RCS/io.c,v; ci io.c io.c,v; -ci RCS/io.c,v io.c; ci io.c,v io.c; -.ft -.fi -.RE -.PP -Suppose instead that the empty suffix -is an \*r suffix and the current directory contains a subdirectory -.B RCS -with an \*r file -.BR io.c . -The each of the following commands checks in a new revision. -.LP -.RS -.nf -.ft 3 -ci io.c; ci RCS/io.c; -ci io.c RCS/io.c; -ci RCS/io.c io.c; -.ft -.fi -.RE -.SH "FILE MODES" -An \*r file created by -.B ci -inherits the read and execute permissions -from the working file. If the \*r file exists already, -.B ci -preserves its read and execute permissions. -.B ci -always turns off all write permissions of \*r files. -.SH FILES -Temporary files are created in the directory containing -the working file, and also in the temporary directory (see -.B \s-1TMPDIR\s0 -under -.BR \s-1ENVIRONMENT\s0 ). -A semaphore file or files are created in the directory containing the \*r file. -With a nonempty suffix, the semaphore names begin with -the first character of the suffix; therefore, do not specify an suffix -whose first character could be that of a working filename. -With an empty suffix, the semaphore names end with -.B _ -so working filenames should not end in -.BR _ . -.PP -.B ci -never changes an \*r or working file. -Normally, -.B ci -unlinks the file and creates a new one; -but instead of breaking a chain of one or more symbolic links to an \*r file, -it unlinks the destination file instead. -Therefore, -.B ci -breaks any hard or symbolic links to any working file it changes; -and hard links to \*r files are ineffective, -but symbolic links to \*r files are preserved. -.PP -The effective user must be able to -search and write the directory containing the \*r file. -Normally, the real user must be able to -read the \*r and working files -and to search and write the directory containing the working file; -however, some older hosts -cannot easily switch between real and effective users, -so on these hosts the effective user is used for all accesses. -The effective user is the same as the real user -unless your copies of -.B ci -and -.B co -have setuid privileges. -As described in the next section, -these privileges yield extra security if -the effective user owns all \*r files and directories, -and if only the effective user can write \*r directories. -.PP -Users can control access to \*r files by setting the permissions -of the directory containing the files; only users with write access -to the directory can use \*r commands to change its \*r files. -For example, in hosts that allow a user to belong to several groups, -one can make a group's \*r directories writable to that group only. -This approach suffices for informal projects, -but it means that any group member can arbitrarily change the group's \*r files, -and can even remove them entirely. -Hence more formal projects sometimes distinguish between an \*r administrator, -who can change the \*r files at will, and other project members, -who can check in new revisions but cannot otherwise change the \*r files. -.SH "SETUID USE" -To prevent anybody but their \*r administrator from deleting revisions, -a set of users can employ setuid privileges as follows. -.nr n \w'\(bu'+2n-1/1n -.ds n \nn -.if \n(.g .if r an-tag-sep .ds n \w'\(bu'u+\n[an-tag-sep]u -.IP \(bu \*n -Check that the host supports \*r setuid use. -Consult a trustworthy expert if there are any doubts. -It is best if the -.B seteuid -system call works as described in Posix 1003.1a Draft 5, -because \*r can switch back and forth easily -between real and effective users, even if the real user is -.BR root . -If not, the second best is if the -.B setuid -system call supports saved setuid -(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990); -this fails only if the real or effective user is -.BR root . -If \*r detects any failure in setuid, it quits immediately. -.IP \(bu \nn -Choose a user -.I A -to serve as \*r administrator for the set of users. -Only -.I A -can invoke the -.B rcs -command on the users' \*r files. -.I A -should not be -.B root -or any other user with special powers. -Mutually suspicious sets of users should use different administrators. -.IP \(bu \nn -Choose a pathname -.I B -to be a directory of files to be executed by the users. -.IP \(bu \nn -Have -.I A -set up -.I B -to contain copies of -.B ci -and -.B co -that are setuid to -.I A -by copying the commands from their standard installation directory -.I D -as follows: -.LP -.RS -.nf -.ne 3 -\f3mkdir\fP \f2B\fP -\f3cp\fP \f2D\fP\^\f3/c[io]\fP \f2B\fP -\f3chmod go\-w,u+s\fP \f2B\fP\f3/c[io]\fP -.fi -.RE -.IP \(bu \nn -Have each user prepend -.I B -to their path as follows: -.LP -.RS -.nf -.ne 2 -\f3PATH=\fP\f2B\fP\f3:$PATH; export PATH\fP # ordinary shell -\f3set path=(\fP\f2B\fP \f3$path)\fP # C shell -.fi -.RE -.IP \(bu \nn -Have -.I A -create each \*r directory -.I R -with write access only to -.I A -as follows: -.LP -.RS -.nf -.ne 2 -\f3mkdir\fP \f2R\fP -\f3chmod go\-w\fP \f2R\fP -.fi -.RE -.IP \(bu \nn -If you want to let only certain users read the \*r files, -put the users into a group -.IR G , -and have -.I A -further protect the \*r directory as follows: -.LP -.RS -.nf -.ne 2 -\f3chgrp\fP \f2G R\fP -\f3chmod g\-w,o\-rwx\fP \f2R\fP -.fi -.RE -.IP \(bu \nn -Have -.I A -copy old \*r files (if any) into -.IR R , -to ensure that -.I A -owns them. -.IP \(bu \nn -An \*r file's access list limits who can check in and lock revisions. -The default access list is empty, -which grants checkin access to anyone who can read the \*r file. -If you want limit checkin access, -have -.I A -invoke -.B "rcs\ \-a" -on the file; see -.BR rcs (1). -In particular, -.BI "rcs\ \-e\ \-a" A -limits access to just -.IR A . -.IP \(bu \nn -Have -.I A -initialize any new \*r files with -.B "rcs\ \-i" -before initial checkin, adding the -.B \-a -option if you want to limit checkin access. -.IP \(bu \nn -Give setuid privileges only to -.BR ci , -.BR co , -and -.BR rcsclean ; -do not give them to -.B rcs -or to any other command. -.IP \(bu \nn -Do not use other setuid commands to invoke \*r commands; -setuid is trickier than you think! -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -A backslash escapes spaces within an option. -The -.B \s-1RCSINIT\s0 -options are prepended to the argument lists of most \*r commands. -Useful -.B \s-1RCSINIT\s0 -options include -.BR \-q , -.BR \-V , -.BR \-x , -and -.BR \-z . -.TP -.B \s-1TMPDIR\s0 -Name of the temporary directory. -If not set, the environment variables -.B \s-1TMP\s0 -and -.B \s-1TEMP\s0 -are inspected instead and the first value found is taken; -if none of them are set, -a host-dependent default is used, typically -.BR /tmp . -.SH DIAGNOSTICS -For each revision, -.B ci -prints the \*r file, the working file, and the number -of both the deposited and the preceding revision. -The exit status is zero if and only if all operations were successful. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH "SEE ALSO" -co(1), -ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1), -rcsintro(1), rcsmerge(1), rlog(1), setuid(2), rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.br diff --git a/gnu/usr.bin/rcs/ci/ci.c b/gnu/usr.bin/rcs/ci/ci.c deleted file mode 100644 index 749a4cf6dbe9..000000000000 --- a/gnu/usr.bin/rcs/ci/ci.c +++ /dev/null @@ -1,1318 +0,0 @@ -/* Check in revisions of RCS files from working files. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.30 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.29 1995/06/01 16:23:43 eggert - * (main): Add -kb. - * Use `cmpdate', not `cmpnum', to compare dates. - * This is for MKS RCS's incompatible 20th-century date format. - * Don't worry about errno after ftruncate fails. - * Fix input file rewinding bug when large_memory && !maps_memory - * and checking in a branch tip. - * - * (fixwork): Fall back on chmod if fchmod fails, since it might be ENOSYS. - * - * Revision 5.28 1994/03/20 04:52:58 eggert - * Do not generate a corrupted RCS file if the user modifies the working file - * while `ci' is running. - * Do not remove the lock when `ci -l' reverts. - * Move buffer-flushes out of critical sections, since they aren't critical. - * Use ORCSerror to clean up after a fatal error. - * Specify subprocess input via file descriptor, not file name. - * - * Revision 5.27 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. Don't print usage twice. - * - * Revision 5.26 1993/11/03 17:42:27 eggert - * Add -z. Don't subtract from RCS file timestamp even if -T. - * Scan for and use Name keyword if -k. - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.25 1992/07/28 16:12:44 eggert - * Add -i, -j, -V. Check that working and RCS files are distinct. - * - * Revision 5.24 1992/02/17 23:02:06 eggert - * `-rREV' now just specifies a revision REV; only bare `-r' reverts to default. - * Add -T. - * - * Revision 5.23 1992/01/27 16:42:51 eggert - * Always unlock branchpoint if caller has a lock. - * Add support for bad_chmod_close, bad_creat0. lint -> RCS_lint - * - * Revision 5.22 1992/01/06 02:42:34 eggert - * Invoke utime() before chmod() to keep some buggy systems happy. - * - * Revision 5.21 1991/11/20 17:58:07 eggert - * Don't read the delta tree from a nonexistent RCS file. - * - * Revision 5.20 1991/10/07 17:32:46 eggert - * Fix log bugs. Remove lint. - * - * Revision 5.19 1991/09/26 23:10:30 eggert - * Plug file descriptor leak. - * - * Revision 5.18 1991/09/18 07:29:10 eggert - * Work around a common ftruncate() bug. - * - * Revision 5.17 1991/09/10 22:15:46 eggert - * Fix test for redirected stdin. - * - * Revision 5.16 1991/08/19 23:17:54 eggert - * When there are no changes, revert to previous revision instead of aborting. - * Add piece tables, -M, -r$. Tune. - * - * Revision 5.15 1991/04/21 11:58:14 eggert - * Ensure that working file is newer than RCS file after ci -[lu]. - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.14 1991/02/28 19:18:47 eggert - * Don't let a setuid ci create a new RCS file; rcs -i -a must be run first. - * Fix ci -ko -l mode bug. Open work file at most once. - * - * Revision 5.13 1991/02/25 07:12:33 eggert - * getdate -> getcurdate (SVR4 name clash) - * - * Revision 5.12 1990/12/31 01:00:12 eggert - * Don't use uninitialized storage when handling -{N,n}. - * - * Revision 5.11 1990/12/04 05:18:36 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.10 1990/11/05 20:30:10 eggert - * Don't remove working file when aborting due to no changes. - * - * Revision 5.9 1990/11/01 05:03:23 eggert - * Add -I and new -t behavior. Permit arbitrary data in logs. - * - * Revision 5.8 1990/10/04 06:30:09 eggert - * Accumulate exit status across files. - * - * Revision 5.7 1990/09/25 20:11:46 hammer - * fixed another small typo - * - * Revision 5.6 1990/09/24 21:48:50 hammer - * added cleanups from Paul Eggert. - * - * Revision 5.5 1990/09/21 06:16:38 hammer - * made it handle multiple -{N,n}'s. Also, made it treat re-directed stdin - * the same as the terminal - * - * Revision 5.4 1990/09/20 02:38:51 eggert - * ci -k now checks dates more thoroughly. - * - * Revision 5.3 1990/09/11 02:41:07 eggert - * Fix revision bug with `ci -k file1 file2'. - * - * Revision 5.2 1990/09/04 08:02:10 eggert - * Permit adjacent revisions with identical time stamps (possible on fast hosts). - * Improve incomplete line handling. Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:13:44 eggert - * Expand locker value like co. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:10:00 eggert - * Don't require a final newline. - * Make lock and temp files faster and safer. - * Remove compile-time limits; use malloc instead. - * Permit dates past 1999/12/31. Switch to GMT. - * Add setuid support. Don't pass +args to diff. Check diff's output. - * Ansify and Posixate. Add -k, -V. Remove snooping. Tune. - * Check diff's output. - * - * Revision 4.9 89/05/01 15:10:54 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.8 88/11/08 13:38:23 narten - * changes from root@seismo.CSS.GOV (Super User) - * -d with no arguments uses the mod time of the file it is checking in - * - * Revision 4.7 88/08/09 19:12:07 eggert - * Make sure workfile is a regular file; use its mode if RCSfile doesn't have one. - * Use execv(), not system(); allow cc -R; remove lint. - * isatty(fileno(stdin)) -> ttystdin() - * - * Revision 4.6 87/12/18 11:34:41 narten - * lint cleanups (from Guy Harris) - * - * Revision 4.5 87/10/18 10:18:48 narten - * Updating version numbers. Changes relative to revision 1.1 are actually - * relative to 4.3 - * - * Revision 1.3 87/09/24 13:57:19 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:21:33 jenkins - * Port to suns - * - * Revision 4.3 83/12/15 12:28:54 wft - * ci -u and ci -l now set mode of working file properly. - * - * Revision 4.2 83/12/05 13:40:54 wft - * Merged with 3.9.1.1: added calls to clearerr(stdin). - * made rewriteflag external. - * - * Revision 4.1 83/05/10 17:03:06 wft - * Added option -d and -w, and updated assingment of date, etc. to new delta. - * Added handling of default branches. - * Option -k generates std. log message; fixed undef. pointer in reading of log. - * Replaced getlock() with findlock(), link--unlink with rename(), - * getpwuid() with getcaller(). - * Moved all revision number generation to new routine addelta(). - * Removed calls to stat(); now done by pairfilenames(). - * Changed most calls to catchints() with restoreints(). - * Directed all interactive messages to stderr. - * - * Revision 3.9.1.1 83/10/19 04:21:03 lepreau - * Added clearerr(stdin) to getlogmsg() for re-reading stdin. - * - * Revision 3.9 83/02/15 15:25:44 wft - * 4.2 prerelease - * - * Revision 3.9 83/02/15 15:25:44 wft - * Added call to fastcopy() to copy remainder of RCS file. - * - * Revision 3.8 83/01/14 15:34:05 wft - * Added ignoring of interrupts while new RCS file is renamed; - * Avoids deletion of RCS files by interrupts. - * - * Revision 3.7 82/12/10 16:09:20 wft - * Corrected checking of return code from diff. - * - * Revision 3.6 82/12/08 21:34:49 wft - * Using DATEFORM to prepare date of checked-in revision; - * Fixed return from addbranch(). - * - * Revision 3.5 82/12/04 18:32:42 wft - * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. Updated - * field lockedby in removelock(), moved getlogmsg() before calling diff. - * - * Revision 3.4 82/12/02 13:27:13 wft - * added option -k. - * - * Revision 3.3 82/11/28 20:53:31 wft - * Added mustcheckin() to check for redundant checkins. - * Added xpandfile() to do keyword expansion for -u and -l; - * -m appends linefeed to log message if necessary. - * getlogmsg() suppresses prompt if stdin is not a terminal. - * Replaced keeplock with lockflag, fclose() with ffclose(), - * %02d with %.2d, getlogin() with getpwuid(). - * - * Revision 3.2 82/10/18 20:57:23 wft - * An RCS file inherits its mode during the first ci from the working file, - * otherwise it stays the same, except that write permission is removed. - * Fixed ci -l, added ci -u (both do an implicit co after the ci). - * Fixed call to getlogin(), added call to getfullRCSname(), added check - * for write error. - * Changed conflicting identifiers. - * - * Revision 3.1 82/10/13 16:04:59 wft - * fixed type of variables receiving from getc() (char -> int). - * added include file dbm.h for getting BYTESIZ. This is used - * to check the return code from diff portably. - */ - -#include "rcsbase.h" - -struct Symrev { - char const *ssymbol; - int override; - struct Symrev * nextsym; -}; - -static char const *getcurdate P((void)); -static int addbranch P((struct hshentry*,struct buf*,int)); -static int addelta P((void)); -static int addsyms P((char const*)); -static int fixwork P((mode_t,time_t)); -static int removelock P((struct hshentry*)); -static int xpandfile P((RILE*,struct hshentry const*,char const**,int)); -static struct cbuf getlogmsg P((void)); -static void cleanup P((void)); -static void incnum P((char const*,struct buf*)); -static void addassoclst P((int,char const*)); - -static FILE *exfile; -static RILE *workptr; /* working file pointer */ -static struct buf newdelnum; /* new revision number */ -static struct cbuf msg; -static int exitstatus; -static int forceciflag; /* forces check in */ -static int keepflag, keepworkingfile, rcsinitflag; -static struct hshentries *gendeltas; /* deltas to be generated */ -static struct hshentry *targetdelta; /* old delta to be generated */ -static struct hshentry newdelta; /* new delta to be inserted */ -static struct stat workstat; -static struct Symrev *assoclst, **nextassoc; - -mainProg(ciId, "ci", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nci usage: ci -{fIklMqru}[rev] -d[date] -mmsg -{nN}name -sstate -ttext -T -Vn -wwho -xsuff -zzone file ..."; - static char const default_state[] = DEFAULTSTATE; - - char altdate[datesize]; - char olddate[datesize]; - char newdatebuf[datesize + zonelenmax]; - char targetdatebuf[datesize + zonelenmax]; - char *a, **newargv, *textfile; - char const *author, *krev, *rev, *state; - char const *diffname, *expname; - char const *newworkname; - int initflag, mustread; - int lockflag, lockthis, mtimeflag, removedlock, Ttimeflag; - int r; - int changedRCS, changework, dolog, newhead; - int usestatdate; /* Use mod time of file for -d. */ - mode_t newworkmode; /* mode for working file */ - time_t mtime, wtime; - struct hshentry *workdelta; - - setrid(); - - author = rev = state = textfile = 0; - initflag = lockflag = mustread = false; - mtimeflag = false; - Ttimeflag = false; - altdate[0]= '\0'; /* empty alternate date for -d */ - usestatdate=false; - suffixes = X_DEFAULT; - nextassoc = &assoclst; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - switch (*a++) { - - case 'r': - if (*a) - goto revno; - keepworkingfile = lockflag = false; - break; - - case 'l': - keepworkingfile = lockflag = true; - revno: - if (*a) { - if (rev) warn("redefinition of revision number"); - rev = a; - } - break; - - case 'u': - keepworkingfile=true; lockflag=false; - goto revno; - - case 'i': - initflag = true; - goto revno; - - case 'j': - mustread = true; - goto revno; - - case 'I': - interactiveflag = true; - goto revno; - - case 'q': - quietflag=true; - goto revno; - - case 'f': - forceciflag=true; - goto revno; - - case 'k': - keepflag=true; - goto revno; - - case 'm': - if (msg.size) redefined('m'); - msg = cleanlogmsg(a, strlen(a)); - if (!msg.size) - error("missing message for -m option"); - break; - - case 'n': - if (!*a) { - error("missing symbolic name after -n"); - break; - } - checkssym(a); - addassoclst(false, a); - break; - - case 'N': - if (!*a) { - error("missing symbolic name after -N"); - break; - } - checkssym(a); - addassoclst(true, a); - break; - - case 's': - if (*a) { - if (state) redefined('s'); - checksid(a); - state = a; - } else - error("missing state for -s option"); - break; - - case 't': - if (*a) { - if (textfile) redefined('t'); - textfile = a; - } - break; - - case 'd': - if (altdate[0] || usestatdate) - redefined('d'); - altdate[0] = '\0'; - if (!(usestatdate = !*a)) - str2date(a, altdate); - break; - - case 'M': - mtimeflag = true; - goto revno; - - case 'w': - if (*a) { - if (author) redefined('w'); - checksid(a); - author = a; - } else - error("missing author for -w option"); - break; - - case 'x': - suffixes = a; - break; - - case 'V': - setRCSversion(*argv); - break; - - case 'z': - zone_set(a); - break; - - case 'T': - if (!*a) { - Ttimeflag = true; - break; - } - /* fall into */ - default: - error("unknown option: %s%s", *argv, cmdusage); - }; - } /* end processing of options */ - - /* Handle all pathnames. */ - if (nerror) cleanup(); - else if (argc < 1) faterror("no input file%s", cmdusage); - else for (; 0 < argc; cleanup(), ++argv, --argc) { - targetdelta = 0; - ffree(); - - switch (pairnames(argc, argv, rcswriteopen, mustread, false)) { - - case -1: /* New RCS file */ -# if has_setuid && has_getuid - if (euid() != ruid()) { - workerror("setuid initial checkin prohibited; use `rcs -i -a' first"); - continue; - } -# endif - rcsinitflag = true; - break; - - case 0: /* Error */ - continue; - - case 1: /* Normal checkin with prev . RCS file */ - if (initflag) { - rcserror("already exists"); - continue; - } - rcsinitflag = !Head; - } - - /* - * RCSname contains the name of the RCS file, and - * workname contains the name of the working file. - * If the RCS file exists, finptr contains the file descriptor for the - * RCS file, and RCSstat is set. The admin node is initialized. - */ - - diagnose("%s <-- %s\n", RCSname, workname); - - if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) { - eerror(workname); - continue; - } - - if (finptr) { - if (same_file(RCSstat, workstat, 0)) { - rcserror("RCS file is the same as working file %s.", - workname - ); - continue; - } - if (!checkaccesslist()) - continue; - } - - krev = rev; - if (keepflag) { - /* get keyword values from working file */ - if (!getoldkeys(workptr)) continue; - if (!rev && !*(krev = prevrev.string)) { - workerror("can't find a revision number"); - continue; - } - if (!*prevdate.string && *altdate=='\0' && usestatdate==false) - workwarn("can't find a date"); - if (!*prevauthor.string && !author) - workwarn("can't find an author"); - if (!*prevstate.string && !state) - workwarn("can't find a state"); - } /* end processing keepflag */ - - /* Read the delta tree. */ - if (finptr) - gettree(); - - /* expand symbolic revision number */ - if (!fexpandsym(krev, &newdelnum, workptr)) - continue; - - /* splice new delta into tree */ - if ((removedlock = addelta()) < 0) - continue; - - newdelta.num = newdelnum.string; - newdelta.branches = 0; - newdelta.lockedby = 0; /* This might be changed by addlock(). */ - newdelta.selector = true; - newdelta.name = 0; - clear_buf(&newdelta.ig); - clear_buf(&newdelta.igtext); - /* set author */ - if (author) - newdelta.author=author; /* set author given by -w */ - else if (keepflag && *prevauthor.string) - newdelta.author=prevauthor.string; /* preserve old author if possible*/ - else newdelta.author=getcaller();/* otherwise use caller's id */ - newdelta.state = default_state; - if (state) - newdelta.state=state; /* set state given by -s */ - else if (keepflag && *prevstate.string) - newdelta.state=prevstate.string; /* preserve old state if possible */ - if (usestatdate) { - time2date(workstat.st_mtime, altdate); - } - if (*altdate!='\0') - newdelta.date=altdate; /* set date given by -d */ - else if (keepflag && *prevdate.string) { - /* Preserve old date if possible. */ - str2date(prevdate.string, olddate); - newdelta.date = olddate; - } else - newdelta.date = getcurdate(); /* use current date */ - /* now check validity of date -- needed because of -d and -k */ - if (targetdelta && - cmpdate(newdelta.date,targetdelta->date) < 0) { - rcserror("Date %s precedes %s in revision %s.", - date2str(newdelta.date, newdatebuf), - date2str(targetdelta->date, targetdatebuf), - targetdelta->num - ); - continue; - } - - - if (lockflag && addlock(&newdelta, true) < 0) continue; - - if (keepflag && *prevname.string) - if (addsymbol(newdelta.num, prevname.string, false) < 0) - continue; - if (!addsyms(newdelta.num)) - continue; - - - putadmin(); - puttree(Head,frewrite); - putdesc(false,textfile); - - changework = Expand < MIN_UNCHANGED_EXPAND; - dolog = true; - lockthis = lockflag; - workdelta = &newdelta; - - /* build rest of file */ - if (rcsinitflag) { - diagnose("initial revision: %s\n", newdelta.num); - /* get logmessage */ - newdelta.log=getlogmsg(); - putdftext(&newdelta, workptr, frewrite, false); - RCSstat.st_mode = workstat.st_mode; - RCSstat.st_nlink = 0; - changedRCS = true; - } else { - diffname = maketemp(0); - newhead = Head == &newdelta; - if (!newhead) - foutptr = frewrite; - expname = buildrevision( - gendeltas, targetdelta, (FILE*)0, false - ); - if ( - !forceciflag && - strcmp(newdelta.state, targetdelta->state) == 0 && - (changework = rcsfcmp( - workptr, &workstat, expname, targetdelta - )) <= 0 - ) { - diagnose("file is unchanged; reverting to previous revision %s\n", - targetdelta->num - ); - if (removedlock < lockflag) { - diagnose("previous revision was not locked; ignoring -l option\n"); - lockthis = 0; - } - dolog = false; - if (! (changedRCS = lockflagnum, (char*)0, (char*)0, (char*)0, - &gendeltas - ))) - continue; - workdelta->log = targetdelta->log; - if (newdelta.state != default_state) - workdelta->state = newdelta.state; - if (lockthisnum)) - continue; - if (dorewrite(true, true) != 0) - continue; - fastcopy(finptr, frewrite); - if (bad_truncate) - while (ftell(frewrite) < hwm) - /* White out any earlier mistake with '\n's. */ - /* This is unlikely. */ - afputc('\n', frewrite); - } - } else { - int wfd = Ifileno(workptr); - struct stat checkworkstat; - char const *diffv[6 + !!OPEN_O_BINARY], **diffp; -# if large_memory && !maps_memory - FILE *wfile = workptr->stream; - long wfile_off; -# endif -# if !has_fflush_input && !(large_memory && maps_memory) - off_t wfd_off; -# endif - - diagnose("new revision: %s; previous revision: %s\n", - newdelta.num, targetdelta->num - ); - newdelta.log = getlogmsg(); -# if !large_memory - Irewind(workptr); -# if has_fflush_input - if (fflush(workptr) != 0) - Ierror(); -# endif -# else -# if !maps_memory - if ( - (wfile_off = ftell(wfile)) == -1 - || fseek(wfile, 0L, SEEK_SET) != 0 -# if has_fflush_input - || fflush(wfile) != 0 -# endif - ) - Ierror(); -# endif -# endif -# if !has_fflush_input && !(large_memory && maps_memory) - wfd_off = lseek(wfd, (off_t)0, SEEK_CUR); - if (wfd_off == -1 - || (wfd_off != 0 - && lseek(wfd, (off_t)0, SEEK_SET) != 0)) - Ierror(); -# endif - diffp = diffv; - *++diffp = DIFF; - *++diffp = DIFFFLAGS; -# if OPEN_O_BINARY - if (Expand == BINARY_EXPAND) - *++diffp = "--binary"; -# endif - *++diffp = newhead ? "-" : expname; - *++diffp = newhead ? expname : "-"; - *++diffp = 0; - switch (runv(wfd, diffname, diffv)) { - case DIFF_FAILURE: case DIFF_SUCCESS: break; - default: rcsfaterror("diff failed"); - } -# if !has_fflush_input && !(large_memory && maps_memory) - if (lseek(wfd, wfd_off, SEEK_CUR) == -1) - Ierror(); -# endif -# if large_memory && !maps_memory - if (fseek(wfile, wfile_off, SEEK_SET) != 0) - Ierror(); -# endif - if (newhead) { - Irewind(workptr); - putdftext(&newdelta, workptr, frewrite, false); - if (!putdtext(targetdelta,diffname,frewrite,true)) continue; - } else - if (!putdtext(&newdelta,diffname,frewrite,true)) continue; - - /* - * Check whether the working file changed during checkin, - * to avoid producing an inconsistent RCS file. - */ - if ( - fstat(wfd, &checkworkstat) != 0 - || workstat.st_mtime != checkworkstat.st_mtime - || workstat.st_size != checkworkstat.st_size - ) { - workerror("file changed during checkin"); - continue; - } - - changedRCS = true; - } - } - - /* Deduce time_t of new revision if it is needed later. */ - wtime = (time_t)-1; - if (mtimeflag | Ttimeflag) - wtime = date2time(workdelta->date); - - if (donerewrite(changedRCS, - !Ttimeflag ? (time_t)-1 - : finptr && wtime < RCSstat.st_mtime ? RCSstat.st_mtime - : wtime - ) != 0) - continue; - - if (!keepworkingfile) { - Izclose(&workptr); - r = un_link(workname); /* Get rid of old file */ - } else { - newworkmode = WORKMODE(RCSstat.st_mode, - ! (Expand==VAL_EXPAND || lockthis < StrictLocks) - ); - mtime = mtimeflag ? wtime : (time_t)-1; - - /* Expand if it might change or if we can't fix mode, time. */ - if (changework || (r=fixwork(newworkmode,mtime)) != 0) { - Irewind(workptr); - /* Expand keywords in file. */ - locker_expansion = lockthis; - workdelta->name = - namedrev( - assoclst ? assoclst->ssymbol - : keepflag && *prevname.string ? prevname.string - : rev, - workdelta - ); - switch (xpandfile( - workptr, workdelta, &newworkname, dolog - )) { - default: - continue; - - case 0: - /* - * No expansion occurred; try to reuse working file - * unless we already tried and failed. - */ - if (changework) - if ((r=fixwork(newworkmode,mtime)) == 0) - break; - /* fall into */ - case 1: - Izclose(&workptr); - aflush(exfile); - ignoreints(); - r = chnamemod(&exfile, newworkname, - workname, 1, newworkmode, mtime - ); - keepdirtemp(newworkname); - restoreints(); - } - } - } - if (r != 0) { - eerror(workname); - continue; - } - diagnose("done\n"); - - } - - tempunlink(); - exitmain(exitstatus); -} /* end of main (ci) */ - - static void -cleanup() -{ - if (nerror) exitstatus = EXIT_FAILURE; - Izclose(&finptr); - Izclose(&workptr); - Ozclose(&exfile); - Ozclose(&fcopy); - ORCSclose(); - dirtempunlink(); -} - -#if RCS_lint -# define exiterr ciExit -#endif - void -exiterr() -{ - ORCSerror(); - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} - -/*****************************************************************/ -/* the rest are auxiliary routines */ - - - static int -addelta() -/* Function: Appends a delta to the delta tree, whose number is - * given by newdelnum. Updates Head, newdelnum, newdelnumlength, - * and the links in newdelta. - * Return -1 on error, 1 if a lock is removed, 0 otherwise. - */ -{ - register char *tp; - register int i; - int removedlock; - int newdnumlength; /* actual length of new rev. num. */ - - newdnumlength = countnumflds(newdelnum.string); - - if (rcsinitflag) { - /* this covers non-existing RCS file and a file initialized with rcs -i */ - if (newdnumlength==0 && Dbranch) { - bufscpy(&newdelnum, Dbranch); - newdnumlength = countnumflds(Dbranch); - } - if (newdnumlength==0) bufscpy(&newdelnum, "1.1"); - else if (newdnumlength==1) bufscat(&newdelnum, ".1"); - else if (newdnumlength>2) { - rcserror("Branch point doesn't exist for revision %s.", - newdelnum.string - ); - return -1; - } /* newdnumlength == 2 is OK; */ - Head = &newdelta; - newdelta.next = 0; - return 0; - } - if (newdnumlength==0) { - /* derive new revision number from locks */ - switch (findlock(true, &targetdelta)) { - - default: - /* found two or more old locks */ - return -1; - - case 1: - /* found an old lock */ - /* check whether locked revision exists */ - if (!genrevs(targetdelta->num,(char*)0,(char*)0,(char*)0,&gendeltas)) - return -1; - if (targetdelta==Head) { - /* make new head */ - newdelta.next=Head; - Head= &newdelta; - } else if (!targetdelta->next && countnumflds(targetdelta->num)>2) { - /* new tip revision on side branch */ - targetdelta->next= &newdelta; - newdelta.next = 0; - } else { - /* middle revision; start a new branch */ - bufscpy(&newdelnum, ""); - return addbranch(targetdelta, &newdelnum, 1); - } - incnum(targetdelta->num, &newdelnum); - return 1; /* successful use of existing lock */ - - case 0: - /* no existing lock; try Dbranch */ - /* update newdelnum */ - if (StrictLocks || !myself(RCSstat.st_uid)) { - rcserror("no lock set by %s", getcaller()); - return -1; - } - if (Dbranch) { - bufscpy(&newdelnum, Dbranch); - } else { - incnum(Head->num, &newdelnum); - } - newdnumlength = countnumflds(newdelnum.string); - /* now fall into next statement */ - } - } - if (newdnumlength<=2) { - /* add new head per given number */ - if(newdnumlength==1) { - /* make a two-field number out of it*/ - if (cmpnumfld(newdelnum.string,Head->num,1)==0) - incnum(Head->num, &newdelnum); - else - bufscat(&newdelnum, ".1"); - } - if (cmpnum(newdelnum.string,Head->num) <= 0) { - rcserror("revision %s too low; must be higher than %s", - newdelnum.string, Head->num - ); - return -1; - } - targetdelta = Head; - if (0 <= (removedlock = removelock(Head))) { - if (!genrevs(Head->num,(char*)0,(char*)0,(char*)0,&gendeltas)) - return -1; - newdelta.next = Head; - Head = &newdelta; - } - return removedlock; - } else { - /* put new revision on side branch */ - /*first, get branch point */ - tp = newdelnum.string; - for (i = newdnumlength - ((newdnumlength&1) ^ 1); --i; ) - while (*tp++ != '.') - continue; - *--tp = 0; /* Kill final dot to get old delta temporarily. */ - if (!(targetdelta=genrevs(newdelnum.string,(char*)0,(char*)0,(char*)0,&gendeltas))) - return -1; - if (cmpnum(targetdelta->num, newdelnum.string) != 0) { - rcserror("can't find branch point %s", newdelnum.string); - return -1; - } - *tp = '.'; /* Restore final dot. */ - return addbranch(targetdelta, &newdelnum, 0); - } -} - - - - static int -addbranch(branchpoint, num, removedlock) - struct hshentry *branchpoint; - struct buf *num; - int removedlock; -/* adds a new branch and branch delta at branchpoint. - * If num is the null string, appends the new branch, incrementing - * the highest branch number (initially 1), and setting the level number to 1. - * the new delta and branchhead are in globals newdelta and newbranch, resp. - * the new number is placed into num. - * Return -1 on error, 1 if a lock is removed, 0 otherwise. - * If REMOVEDLOCK is 1, a lock was already removed. - */ -{ - struct branchhead *bhead, **btrail; - struct buf branchnum; - int result; - int field, numlength; - static struct branchhead newbranch; /* new branch to be inserted */ - - numlength = countnumflds(num->string); - - if (!branchpoint->branches) { - /* start first branch */ - branchpoint->branches = &newbranch; - if (numlength==0) { - bufscpy(num, branchpoint->num); - bufscat(num, ".1.1"); - } else if (numlength&1) - bufscat(num, ".1"); - newbranch.nextbranch = 0; - - } else if (numlength==0) { - /* append new branch to the end */ - bhead=branchpoint->branches; - while (bhead->nextbranch) bhead=bhead->nextbranch; - bhead->nextbranch = &newbranch; - bufautobegin(&branchnum); - getbranchno(bhead->hsh->num, &branchnum); - incnum(branchnum.string, num); - bufautoend(&branchnum); - bufscat(num, ".1"); - newbranch.nextbranch = 0; - } else { - /* place the branch properly */ - field = numlength - ((numlength&1) ^ 1); - /* field of branch number */ - btrail = &branchpoint->branches; - while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) { - btrail = &(*btrail)->nextbranch; - if (!*btrail) { - result = -1; - break; - } - } - if (result < 0) { - /* insert/append new branchhead */ - newbranch.nextbranch = *btrail; - *btrail = &newbranch; - if (numlength&1) bufscat(num, ".1"); - } else { - /* branch exists; append to end */ - bufautobegin(&branchnum); - getbranchno(num->string, &branchnum); - targetdelta = genrevs( - branchnum.string, (char*)0, (char*)0, (char*)0, - &gendeltas - ); - bufautoend(&branchnum); - if (!targetdelta) - return -1; - if (cmpnum(num->string,targetdelta->num) <= 0) { - rcserror("revision %s too low; must be higher than %s", - num->string, targetdelta->num - ); - return -1; - } - if (!removedlock - && 0 <= (removedlock = removelock(targetdelta)) - ) { - if (numlength&1) - incnum(targetdelta->num,num); - targetdelta->next = &newdelta; - newdelta.next = 0; - } - return removedlock; - /* Don't do anything to newbranch. */ - } - } - newbranch.hsh = &newdelta; - newdelta.next = 0; - if (branchpoint->lockedby) - if (strcmp(branchpoint->lockedby, getcaller()) == 0) - return removelock(branchpoint); /* This returns 1. */ - return removedlock; -} - - static int -addsyms(num) - char const *num; -{ - register struct Symrev *p; - - for (p = assoclst; p; p = p->nextsym) - if (addsymbol(num, p->ssymbol, p->override) < 0) - return false; - return true; -} - - - static void -incnum(onum,nnum) - char const *onum; - struct buf *nnum; -/* Increment the last field of revision number onum by one and - * place the result into nnum. - */ -{ - register char *tp, *np; - register size_t l; - - l = strlen(onum); - bufalloc(nnum, l+2); - np = tp = nnum->string; - VOID strcpy(np, onum); - for (tp = np + l; np != tp; ) - if (isdigit(*--tp)) { - if (*tp != '9') { - ++*tp; - return; - } - *tp = '0'; - } else { - tp++; - break; - } - /* We changed 999 to 000; now change it to 1000. */ - *tp = '1'; - tp = np + l; - *tp++ = '0'; - *tp = 0; -} - - - - static int -removelock(delta) -struct hshentry * delta; -/* function: Finds the lock held by caller on delta, - * removes it, and returns nonzero if successful. - * Print an error message and return -1 if there is no such lock. - * An exception is if !StrictLocks, and caller is the owner of - * the RCS file. If caller does not have a lock in this case, - * return 0; return 1 if a lock is actually removed. - */ -{ - register struct rcslock *next, **trail; - char const *num; - - num=delta->num; - for (trail = &Locks; (next = *trail); trail = &next->nextlock) - if (next->delta == delta) - if (strcmp(getcaller(), next->login) == 0) { - /* We found a lock on delta by caller; delete it. */ - *trail = next->nextlock; - delta->lockedby = 0; - return 1; - } else { - rcserror("revision %s locked by %s", num, next->login); - return -1; - } - if (!StrictLocks && myself(RCSstat.st_uid)) - return 0; - rcserror("no lock set by %s for revision %s", getcaller(), num); - return -1; -} - - - - static char const * -getcurdate() -/* Return a pointer to the current date. */ -{ - static char buffer[datesize]; /* date buffer */ - - if (!buffer[0]) - time2date(now(), buffer); - return buffer; -} - - static int -#if has_prototypes -fixwork(mode_t newworkmode, time_t mtime) - /* The `#if has_prototypes' is needed because mode_t might promote to int. */ -#else - fixwork(newworkmode, mtime) - mode_t newworkmode; - time_t mtime; -#endif -{ - return - 1 < workstat.st_nlink - || (newworkmode&S_IWUSR && !myself(workstat.st_uid)) - || setmtime(workname, mtime) != 0 - ? -1 - : workstat.st_mode == newworkmode ? 0 -#if has_fchmod - : fchmod(Ifileno(workptr), newworkmode) == 0 ? 0 -#endif -#if bad_chmod_close - : -1 -#else - : chmod(workname, newworkmode) -#endif - ; -} - - static int -xpandfile(unexfile, delta, exname, dolog) - RILE *unexfile; - struct hshentry const *delta; - char const **exname; - int dolog; -/* - * Read unexfile and copy it to a - * file, performing keyword substitution with data from delta. - * Return -1 if unsuccessful, 1 if expansion occurred, 0 otherwise. - * If successful, stores the stream descriptor into *EXFILEP - * and its name into *EXNAME. - */ -{ - char const *targetname; - int e, r; - - targetname = makedirtemp(1); - if (!(exfile = fopenSafer(targetname, FOPEN_W_WORK))) { - eerror(targetname); - workerror("can't build working file"); - return -1; - } - r = 0; - if (MIN_UNEXPAND <= Expand) - fastcopy(unexfile,exfile); - else { - for (;;) { - e = expandline( - unexfile, exfile, delta, false, (FILE*)0, dolog - ); - if (e < 0) - break; - r |= e; - if (e <= 1) - break; - } - } - *exname = targetname; - return r & 1; -} - - - - -/* --------------------- G E T L O G M S G --------------------------------*/ - - - static struct cbuf -getlogmsg() -/* Obtain and yield a log message. - * If a log message is given with -m, yield that message. - * If this is the initial revision, yield a standard log message. - * Otherwise, reads a character string from the terminal. - * Stops after reading EOF or a single '.' on a - * line. getlogmsg prompts the first time it is called for the - * log message; during all later calls it asks whether the previous - * log message can be reused. - */ -{ - static char const - emptych[] = EMPTYLOG, - initialch[] = "Initial revision"; - static struct cbuf const - emptylog = { emptych, sizeof(emptych)-sizeof(char) }, - initiallog = { initialch, sizeof(initialch)-sizeof(char) }; - static struct buf logbuf; - static struct cbuf logmsg; - - register char *tp; - register size_t i; - char const *caller; - - if (msg.size) return msg; - - if (keepflag) { - /* generate std. log message */ - caller = getcaller(); - i = sizeof(ciklog)+strlen(caller)+3; - bufalloc(&logbuf, i + datesize + zonelenmax); - tp = logbuf.string; - VOID sprintf(tp, "%s%s at ", ciklog, caller); - VOID date2str(getcurdate(), tp+i); - logmsg.string = tp; - logmsg.size = strlen(tp); - return logmsg; - } - - if (!targetdelta && ( - cmpnum(newdelnum.string,"1.1")==0 || - cmpnum(newdelnum.string,"1.0")==0 - )) - return initiallog; - - if (logmsg.size) { - /*previous log available*/ - if (yesorno(true, "reuse log message of previous file? [yn](y): ")) - return logmsg; - } - - /* now read string from stdin */ - logmsg = getsstdin("m", "log message", "", &logbuf); - - /* now check whether the log message is not empty */ - if (logmsg.size) - return logmsg; - return emptylog; -} - -/* Make a linked list of Symbolic names */ - - static void -addassoclst(flag, sp) - int flag; - char const *sp; -{ - struct Symrev *pt; - - pt = talloc(struct Symrev); - pt->ssymbol = sp; - pt->override = flag; - pt->nextsym = 0; - *nextassoc = pt; - nextassoc = &pt->nextsym; -} diff --git a/gnu/usr.bin/rcs/co/Makefile b/gnu/usr.bin/rcs/co/Makefile deleted file mode 100644 index 0c73865d09fc..000000000000 --- a/gnu/usr.bin/rcs/co/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= co -SRCS= co.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/co/Makefile.depend b/gnu/usr.bin/rcs/co/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/co/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/co/co.1 b/gnu/usr.bin/rcs/co/co.1 deleted file mode 100644 index 2aea3ad1b40d..000000000000 --- a/gnu/usr.bin/rcs/co/co.1 +++ /dev/null @@ -1,736 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds i \&\s-1ISO\s0 -.ds r \&\s-1RCS\s0 -.ds u \&\s-1UTC\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH CO 1 \*(Dt GNU -.SH NAME -co \- check out RCS revisions -.SH SYNOPSIS -.B co -.RI [ options ] " file " .\|.\|. -.SH DESCRIPTION -.B co -retrieves a revision from each \*r file and stores it into -the corresponding working file. -.PP -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -Names are paired as explained in -.BR ci (1). -.PP -Revisions of an \*r file can be checked out locked or unlocked. Locking a -revision prevents overlapping updates. A revision checked out for reading or -processing (e.g., compiling) need not be locked. A revision checked out -for editing and later checkin must normally be locked. Checkout with locking -fails if the revision to be checked out is currently locked by another user. -(A lock can be broken with -.BR rcs "(1).)\ \&" -Checkout with locking also requires the caller to be on the access list of -the \*r file, unless he is the owner of the -file or the superuser, or the access list is empty. -Checkout without locking is not subject to accesslist restrictions, and is -not affected by the presence of locks. -.PP -A revision is selected by options for revision or branch number, -checkin date/time, author, or state. -When the selection options -are applied in combination, -.B co -retrieves the latest revision -that satisfies all of them. -If none of the selection options -is specified, -.B co -retrieves the latest revision -on the default branch (normally the trunk, see the -.B \-b -option of -.BR rcs (1)). -A revision or branch number can be attached -to any of the options -.BR \-f , -.BR \-I , -.BR \-l , -.BR \-M , -.BR \-p , -.BR \-q , -.BR \-r , -or -.BR \-u . -The options -.B \-d -(date), -.B \-s -(state), and -.B \-w -(author) -retrieve from a single branch, the -.I selected -branch, -which is either specified by one of -.BR \-f , -\&.\|.\|., -.BR \-u , -or the default branch. -.PP -A -.B co -command applied to an \*r -file with no revisions creates a zero-length working file. -.B co -always performs keyword substitution (see below). -.SH OPTIONS -.TP -.BR \-r [\f2rev\fP] -retrieves the latest revision whose number is less than or equal to -.IR rev . -If -.I rev -indicates a branch rather than a revision, -the latest revision on that branch is retrieved. -If -.I rev -is omitted, the latest revision on the default branch -(see the -.B \-b -option of -.BR rcs (1)) -is retrieved. -If -.I rev -is -.BR $ , -.B co -determines the revision number from keyword values in the working file. -Otherwise, a revision is composed of one or more numeric or symbolic fields -separated by periods. -If -.I rev -begins with a period, -then the default branch (normally the trunk) is prepended to it. -If -.I rev -is a branch number followed by a period, -then the latest revision on that branch is used. -The numeric equivalent of a symbolic field -is specified with the -.B \-n -option of the commands -.BR ci (1) -and -.BR rcs (1). -.TP -.BR \-l [\f2rev\fP] -same as -.BR \-r , -except that it also locks the retrieved revision for -the caller. -.TP -.BR \-u [\f2rev\fP] -same as -.BR \-r , -except that it unlocks the retrieved revision if it was -locked by the caller. If -.I rev -is omitted, -.B \-u -retrieves the revision locked by the caller, if there is one; otherwise, -it retrieves the latest revision on the default branch. -.TP -.BR \-f [\f2rev\fP] -forces the overwriting of the working file; -useful in connection with -.BR \-q . -See also -.SM "FILE MODES" -below. -.TP -.B \-kkv -Generate keyword strings using the default form, e.g.\& -.B "$\&Revision: \*(Rv $" -for the -.B Revision -keyword. -A locker's name is inserted in the value of the -.BR Header , -.BR Id , -and -.B Locker -keyword strings -only as a file is being locked, -i.e. by -.B "ci\ \-l" -and -.BR "co\ \-l". -This is the default. -.TP -.B \-kkvl -Like -.BR \-kkv , -except that a locker's name is always inserted -if the given revision is currently locked. -.TP -.B \-kk -Generate only keyword names in keyword strings; omit their values. -See -.SM "KEYWORD SUBSTITUTION" -below. -For example, for the -.B Revision -keyword, generate the string -.B $\&Revision$ -instead of -.BR "$\&Revision: \*(Rv $" . -This option is useful to ignore differences due to keyword substitution -when comparing different revisions of a file. -Log messages are inserted after -.B $\&Log$ -keywords even if -.B \-kk -is specified, -since this tends to be more useful when merging changes. -.TP -.B \-ko -Generate the old keyword string, -present in the working file just before it was checked in. -For example, for the -.B Revision -keyword, generate the string -.B "$\&Revision: 1.1 $" -instead of -.B "$\&Revision: \*(Rv $" -if that is how the string appeared when the file was checked in. -This can be useful for file formats -that cannot tolerate any changes to substrings -that happen to take the form of keyword strings. -.TP -.B \-kb -Generate a binary image of the old keyword string. -This acts like -.BR \-ko , -except it performs all working file input and output in binary mode. -This makes little difference on Posix and Unix hosts, -but on DOS-like hosts one should use -.B "rcs\ \-i\ \-kb" -to initialize an \*r file intended to be used for binary files. -Also, on all hosts, -.BR rcsmerge (1) -normally refuses to merge files when -.B \-kb -is in effect. -.TP -.B \-kv -Generate only keyword values for keyword strings. -For example, for the -.B Revision -keyword, generate the string -.B \*(Rv -instead of -.BR "$\&Revision: \*(Rv $" . -This can help generate files in programming languages where it is hard to -strip keyword delimiters like -.B "$\&Revision:\ $" -from a string. -However, further keyword substitution cannot be performed once the -keyword names are removed, so this option should be used with care. -Because of this danger of losing keywords, -this option cannot be combined with -.BR \-l , -and the owner write permission of the working file is turned off; -to edit the file later, check it out again without -.BR \-kv . -.TP -.BR \-p [\f2rev\fP] -prints the retrieved revision on the standard output rather than storing it -in the working file. -This option is useful when -.B co -is part of a pipe. -.TP -.BR \-q [\f2rev\fP] -quiet mode; diagnostics are not printed. -.TP -.BR \-I [\f2rev\fP] -interactive mode; -the user is prompted and questioned -even if the standard input is not a terminal. -.TP -.BI \-d date -retrieves the latest revision on the selected branch whose checkin date/time is -less than or equal to -.IR date . -The date and time can be given in free format. -The time zone -.B LT -stands for local time; -other common time zone names are understood. -For example, the following -.IR date s -are equivalent -if local time is January 11, 1990, 8pm Pacific Standard Time, -eight hours west of Coordinated Universal Time (\*u): -.RS -.LP -.RS -.nf -.ta \w'\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP 'u -.ne 10 -\f38:00 pm lt\fP -\f34:00 AM, Jan. 12, 1990\fP default is \*u -\f31990-01-12 04:00:00+00\fP \*i 8601 (\*u) -\f31990-01-11 20:00:00\-08\fP \*i 8601 (local time) -\f31990/01/12 04:00:00\fP traditional \*r format -\f3Thu Jan 11 20:00:00 1990 LT\fP output of \f3ctime\fP(3) + \f3LT\fP -\f3Thu Jan 11 20:00:00 PST 1990\fP output of \f3date\fP(1) -\f3Fri Jan 12 04:00:00 GMT 1990\fP -\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP Internet RFC 822 -\f312-January-1990, 04:00 WET\fP -.ta 4n +4n +4n +4n -.fi -.RE -.LP -Most fields in the date and time can be defaulted. -The default time zone is normally \*u, but this can be overridden by the -.B \-z -option. -The other defaults are determined in the order year, month, day, -hour, minute, and second (most to least significant). At least one of these -fields must be provided. For omitted fields that are of higher significance -than the highest provided field, the time zone's current values are assumed. -For all other omitted fields, -the lowest possible values are assumed. -For example, without -.BR \-z , -the date -.B "20, 10:30" -defaults to -10:30:00 \*u of the 20th of the \*u time zone's current month and year. -The date/time must be quoted if it contains spaces. -.RE -.TP -.BR \-M [\f2rev\fP] -Set the modification time on the new working file -to be the date of the retrieved revision. -Use this option with care; it can confuse -.BR make (1). -.TP -.BI \-s state -retrieves the latest revision on the selected branch whose state is set to -.IR state . -.TP -.B \-T -Preserve the modification time on the \*r file -even if the \*r file changes because a lock is added or removed. -This option can suppress extensive recompilation caused by a -.BR make (1) -dependency of some other copy of the working file on the \*r file. -Use this option with care; it can suppress recompilation even when it is needed, -i.e. when the change of lock -would mean a change to keyword strings in the other working file. -.TP -.BR \-w [\f2login\fP] -retrieves the latest revision on the selected branch which was checked in -by the user with login name -.IR login . -If the argument -.I login -is -omitted, the caller's login is assumed. -.TP -.BI \-j joinlist -generates a new revision which is the join of the revisions on -.IR joinlist . -This option is largely obsoleted by -.BR rcsmerge (1) -but is retained for backwards compatibility. -.RS -.PP -The -.I joinlist -is a comma-separated list of pairs of the form -.IB rev2 : rev3, -where -.I rev2 -and -.I rev3 -are (symbolic or numeric) -revision numbers. -For the initial such pair, -.I rev1 -denotes the revision selected -by the above options -.BR \-f , -\&.\|.\|., -.BR \-w . -For all other pairs, -.I rev1 -denotes the revision generated by the previous pair. -(Thus, the output -of one join becomes the input to the next.) -.PP -For each pair, -.B co -joins revisions -.I rev1 -and -.I rev3 -with respect to -.IR rev2 . -This means that all changes that transform -.I rev2 -into -.I rev1 -are applied to a copy of -.IR rev3 . -This is particularly useful if -.I rev1 -and -.I rev3 -are the ends of two branches that have -.I rev2 -as a common ancestor. If -.IR rev1 < rev2 < rev3 -on the same branch, -joining generates a new revision which is like -.I rev3, -but with all changes that lead from -.I rev1 -to -.I rev2 -undone. -If changes from -.I rev2 -to -.I rev1 -overlap with changes from -.I rev2 -to -.I rev3, -.B co -reports overlaps as described in -.BR merge (1). -.PP -For the initial pair, -.I rev2 -can be omitted. The default is the common -ancestor. -If any of the arguments indicate branches, the latest revisions -on those branches are assumed. -The options -.B \-l -and -.B \-u -lock or unlock -.IR rev1 . -.RE -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.I n, -where -.I n -can be -.BR 3 , -.BR 4 , -or -.BR 5 . -This can be useful when interchanging \*r files with others who are -running older versions of \*r. -To see which version of \*r your correspondents are running, have them invoke -.BR "rcs \-V" ; -this works with newer versions of \*r. -If it doesn't work, have them invoke -.B rlog -on an \*r file; -if none of the first few lines of output contain the string -.B branch: -it is version 3; -if the dates' years have just two digits, it is version 4; -otherwise, it is version 5. -An \*r file generated while emulating version 3 loses its default branch. -An \*r revision generated while emulating version 4 or earlier has -a time stamp that is off by up to 13 hours. -A revision extracted while emulating version 4 or earlier contains -abbreviated dates of the form -.IB yy / mm / dd -and can also contain different white space and line prefixes -in the substitution for -.BR $\&Log$ . -.TP -.BI \-x "suffixes" -Use -.I suffixes -to characterize \*r files. -See -.BR ci (1) -for details. -.TP -.BI \-z zone -specifies the date output format in keyword substitution, -and specifies the default time zone for -.I date -in the -.BI \-d date -option. -The -.I zone -should be empty, a numeric \*u offset, or the special string -.B LT -for local time. -The default is an empty -.IR zone , -which uses the traditional \*r format of \*u without any time zone indication -and with slashes separating the parts of the date; -otherwise, times are output in \*i 8601 format with time zone indication. -For example, if local time is January 11, 1990, 8pm Pacific Standard Time, -eight hours west of \*u, -then the time is output as follows: -.RS -.LP -.RS -.nf -.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u -.ne 4 -\f2option\fP \f2time output\fP -\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP -\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP -\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP -.ta 4n +4n +4n +4n -.fi -.RE -.LP -The -.B \-z -option does not affect dates stored in \*r files, -which are always \*u. -.RE -.SH "KEYWORD SUBSTITUTION" -Strings of the form -.BI $ keyword $ -and -.BI $ keyword : .\|.\|. $ -embedded in -the text are replaced -with strings of the form -.BI $ keyword : value $ -where -.I keyword -and -.I value -are pairs listed below. -Keywords can be embedded in literal strings -or comments to identify a revision. -.PP -Initially, the user enters strings of the form -.BI $ keyword $ . -On checkout, -.B co -replaces these strings with strings of the form -.BI $ keyword : value $ . -If a revision containing strings of the latter form -is checked back in, the value fields will be replaced during the next -checkout. -Thus, the keyword values are automatically updated on checkout. -This automatic substitution can be modified by the -.B \-k -options. -.PP -Keywords and their corresponding values: -.TP -.B $\&Author$ -The login name of the user who checked in the revision. -.TP -.B $\&Date$ -The date and time the revision was checked in. -With -.BI \-z zone -a numeric time zone offset is appended; otherwise, the date is \*u. -.TP -.B $\&Header$ -A standard header containing the full pathname of the \*r file, the -revision number, the date and time, the author, the state, -and the locker (if locked). -With -.BI \-z zone -a numeric time zone offset is appended to the date; otherwise, the date is \*u. -.TP -.B $\&Id$ -Same as -.BR $\&Header$ , -except that the \*r filename is without a path. -.TP -.B $\&Locker$ -The login name of the user who locked the revision (empty if not locked). -.TP -.B $\&Log$ -The log message supplied during checkin, preceded by a header -containing the \*r filename, the revision number, the author, and the date -and time. -With -.BI \-z zone -a numeric time zone offset is appended; otherwise, the date is \*u. -Existing log messages are -.I not -replaced. -Instead, the new log message is inserted after -.BR $\&Log: .\|.\|. $ . -This is useful for -accumulating a complete change log in a source file. -.RS -.LP -Each inserted line is prefixed by the string that prefixes the -.B $\&Log$ -line. For example, if the -.B $\&Log$ -line is -.RB \*(lq "//\ $\&Log: tan.cc\ $" \*(rq, -\*r prefixes each line of the log with -.RB \*(lq "//\ " \*(rq. -This is useful for languages with comments that go to the end of the line. -The convention for other languages is to use a -.RB \*(lq " \(** " \(rq -prefix inside a multiline comment. -For example, the initial log comment of a C program -conventionally is of the following form: -.RS -.LP -.nf -.ft 3 -.ne 3 -/\(** -.in +\w'/'u -\(** $\&Log$ -\(**/ -.in -.ft -.fi -.RE -.LP -For backwards compatibility with older versions of \*r, if the log prefix is -.B /\(** -or -.B (\(** -surrounded by optional white space, inserted log lines contain a space -instead of -.B / -or -.BR ( ; -however, this usage is obsolescent and should not be relied on. -.RE -.TP -.B $\&Name$ -The symbolic name used to check out the revision, if any. -For example, -.B "co\ \-rJoe" -generates -.BR "$\&Name:\ Joe\ $" . -Plain -.B co -generates just -.BR "$\&Name:\ \ $" . -.TP -.B $\&RCSfile$ -The name of the \*r file without a path. -.TP -.B $\&Revision$ -The revision number assigned to the revision. -.TP -.B $\&Source$ -The full pathname of the \*r file. -.TP -.B $\&State$ -The state assigned to the revision with the -.B \-s -option of -.BR rcs (1) -or -.BR ci (1). -.PP -The following characters in keyword values are represented by escape sequences -to keep keyword strings well-formed. -.LP -.RS -.nf -.ne 6 -.ta \w'newline 'u -\f2char escape sequence\fP -tab \f3\et\fP -newline \f3\en\fP -space \f3\e040 -$ \e044 -\e \e\e\fP -.fi -.RE -.SH "FILE MODES" -The working file inherits the read and execute permissions from the \*r -file. In addition, the owner write permission is turned on, unless -.B \-kv -is set or the file -is checked out unlocked and locking is set to strict (see -.BR rcs (1)). -.PP -If a file with the name of the working file exists already and has write -permission, -.B co -aborts the checkout, -asking beforehand if possible. -If the existing working file is -not writable or -.B \-f -is given, the working file is deleted without asking. -.SH FILES -.B co -accesses files much as -.BR ci (1) -does, except that it does not need to read the working file -unless a revision number of -.B $ -is specified. -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -See -.BR ci (1) -for details. -.SH DIAGNOSTICS -The \*r pathname, the working pathname, -and the revision number retrieved are -written to the diagnostic output. -The exit status is zero if and only if all operations were successful. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH "SEE ALSO" -rcsintro(1), ci(1), ctime(3), date(1), ident(1), make(1), -rcs(1), rcsclean(1), rcsdiff(1), rcsmerge(1), rlog(1), -rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.SH LIMITS -Links to the \*r and working files are not preserved. -.PP -There is no way to selectively suppress the expansion of keywords, except -by writing them differently. In nroff and troff, this is done by embedding the -null-character -.B \e& -into the keyword. -.br diff --git a/gnu/usr.bin/rcs/co/co.c b/gnu/usr.bin/rcs/co/co.c deleted file mode 100644 index 51cb2b277927..000000000000 --- a/gnu/usr.bin/rcs/co/co.c +++ /dev/null @@ -1,826 +0,0 @@ -/* Check out working files from revisions of RCS files. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.18 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.17 1995/06/01 16:23:43 eggert - * (main, preparejoin): Pass argument instead of using `join' static variable. - * (main): Add -kb. - * - * Revision 5.16 1994/03/17 14:05:48 eggert - * Move buffer-flushes out of critical sections, since they aren't critical. - * Use ORCSerror to clean up after a fatal error. Remove lint. - * Specify subprocess input via file descriptor, not file name. - * - * Revision 5.15 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. Don't print usage twice. - * - * Revision 5.14 1993/11/03 17:42:27 eggert - * Add -z. Generate a value for the Name keyword. - * Don't arbitrarily limit the number of joins. - * Improve quality of diagnostics. - * - * Revision 5.13 1992/07/28 16:12:44 eggert - * Add -V. Check that working and RCS files are distinct. - * - * Revision 5.12 1992/02/17 23:02:08 eggert - * Add -T. - * - * Revision 5.11 1992/01/24 18:44:19 eggert - * Add support for bad_creat0. lint -> RCS_lint - * - * Revision 5.10 1992/01/06 02:42:34 eggert - * Update usage string. - * - * Revision 5.9 1991/10/07 17:32:46 eggert - * -k affects just working file, not RCS file. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Warn before removing somebody else's file. - * Add -M. Fix co -j bugs. Tune. - * - * Revision 5.7 1991/04/21 11:58:15 eggert - * Ensure that working file is newer than RCS file after co -[lu]. - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.6 1990/12/04 05:18:38 eggert - * Don't checkaccesslist() unless necessary. - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.5 1990/11/01 05:03:26 eggert - * Fix -j. Add -I. - * - * Revision 5.4 1990/10/04 06:30:11 eggert - * Accumulate exit status across files. - * - * Revision 5.3 1990/09/11 02:41:09 eggert - * co -kv yields a readonly working file. - * - * Revision 5.2 1990/09/04 08:02:13 eggert - * Standardize yes-or-no procedure. - * - * Revision 5.0 1990/08/22 08:10:02 eggert - * Permit multiple locks by same user. Add setuid support. - * Remove compile-time limits; use malloc instead. - * Permit dates past 1999/12/31. Switch to GMT. - * Make lock and temp files faster and safer. - * Ansify and Posixate. Add -k, -V. Remove snooping. Tune. - * - * Revision 4.7 89/05/01 15:11:41 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.6 88/08/09 19:12:15 eggert - * Fix "co -d" core dump; rawdate wasn't always initialized. - * Use execv(), not system(); fix putchar('\0') and diagnose() botches; remove lint - * - * Revision 4.5 87/12/18 11:35:40 narten - * lint cleanups (from Guy Harris) - * - * Revision 4.4 87/10/18 10:20:53 narten - * Updating version numbers changes relative to 1.1, are actually - * relative to 4.2 - * - * Revision 1.3 87/09/24 13:58:30 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:21:38 jenkins - * Port to suns - * - * Revision 4.2 83/12/05 13:39:48 wft - * made rewriteflag external. - * - * Revision 4.1 83/05/10 16:52:55 wft - * Added option -u and -f. - * Added handling of default branch. - * Replaced getpwuid() with getcaller(). - * Removed calls to stat(); now done by pairfilenames(). - * Changed and renamed rmoldfile() to rmworkfile(). - * Replaced catchints() calls with restoreints(), unlink()--link() with rename(); - * - * Revision 3.7 83/02/15 15:27:07 wft - * Added call to fastcopy() to copy remainder of RCS file. - * - * Revision 3.6 83/01/15 14:37:50 wft - * Added ignoring of interrupts while RCS file is renamed; this avoids - * deletion of RCS files during the unlink/link window. - * - * Revision 3.5 82/12/08 21:40:11 wft - * changed processing of -d to use DATEFORM; removed actual from - * call to preparejoin; re-fixed printing of done at the end. - * - * Revision 3.4 82/12/04 18:40:00 wft - * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. - * Fixed printing of "done". - * - * Revision 3.3 82/11/28 22:23:11 wft - * Replaced getlogin() with getpwuid(), flcose() with ffclose(), - * %02d with %.2d, mode generation for working file with WORKMODE. - * Fixed nil printing. Fixed -j combined with -l and -p, and exit - * for non-existing revisions in preparejoin(). - * - * Revision 3.2 82/10/18 20:47:21 wft - * Mode of working file is now maintained even for co -l, but write permission - * is removed. - * The working file inherits its mode from the RCS file, plus write permission - * for the owner. The write permission is not given if locking is strict and - * co does not lock. - * An existing working file without write permission is deleted automatically. - * Otherwise, co asks (empty answer: abort co). - * Call to getfullRCSname() added, check for write error added, call - * for getlogin() fixed. - * - * Revision 3.1 82/10/13 16:01:30 wft - * fixed type of variables receiving from getc() (char -> int). - * removed unused variables. - */ - - - - -#include "rcsbase.h" - -static char *addjoin P((char*)); -static char const *getancestor P((char const*,char const*)); -static int buildjoin P((char const*)); -static int preparejoin P((char*)); -static int rmlock P((struct hshentry const*)); -static int rmworkfile P((void)); -static void cleanup P((void)); - -static char const quietarg[] = "-q"; - -static char const *expandarg, *suffixarg, *versionarg, *zonearg; -static char const **joinlist; /* revisions to be joined */ -static int joinlength; -static FILE *neworkptr; -static int exitstatus; -static int forceflag; -static int lastjoin; /* index of last element in joinlist */ -static int lockflag; /* -1 -> unlock, 0 -> do nothing, 1 -> lock */ -static int mtimeflag; -static struct hshentries *gendeltas; /* deltas to be generated */ -static struct hshentry *targetdelta; /* final delta to be generated */ -static struct stat workstat; - -mainProg(coId, "co", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nco usage: co -{fIlMpqru}[rev] -ddate -jjoins -ksubst -sstate -T -w[who] -Vn -xsuff -zzone file ..."; - - char *a, *joinflag, **newargv; - char const *author, *date, *rev, *state; - char const *joinname, *newdate, *neworkname; - int changelock; /* 1 if a lock has been changed, -1 if error */ - int expmode, r, tostdout, workstatstat; - int Ttimeflag; - struct buf numericrev; /* expanded revision number */ - char finaldate[datesize]; -# if OPEN_O_BINARY - int stdout_mode = 0; -# endif - - setrid(); - author = date = rev = state = 0; - joinflag = 0; - bufautobegin(&numericrev); - expmode = -1; - suffixes = X_DEFAULT; - tostdout = false; - Ttimeflag = false; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - switch (*a++) { - - case 'r': - revno: - if (*a) { - if (rev) warn("redefinition of revision number"); - rev = a; - } - break; - - case 'f': - forceflag=true; - goto revno; - - case 'l': - if (lockflag < 0) { - warn("-u overridden by -l."); - } - lockflag = 1; - goto revno; - - case 'u': - if (0 < lockflag) { - warn("-l overridden by -u."); - } - lockflag = -1; - goto revno; - - case 'p': - tostdout = true; - goto revno; - - case 'I': - interactiveflag = true; - goto revno; - - case 'q': - quietflag=true; - goto revno; - - case 'd': - if (date) - redefined('d'); - str2date(a, finaldate); - date=finaldate; - break; - - case 'j': - if (*a) { - if (joinflag) redefined('j'); - joinflag = a; - } - break; - - case 'M': - mtimeflag = true; - goto revno; - - case 's': - if (*a) { - if (state) redefined('s'); - state = a; - } - break; - - case 'T': - if (*a) - goto unknown; - Ttimeflag = true; - break; - - case 'w': - if (author) redefined('w'); - if (*a) - author = a; - else - author = getcaller(); - break; - - case 'x': - suffixarg = *argv; - suffixes = a; - break; - - case 'V': - versionarg = *argv; - setRCSversion(versionarg); - break; - - case 'z': - zonearg = *argv; - zone_set(a); - break; - - case 'k': /* set keyword expand mode */ - expandarg = *argv; - if (0 <= expmode) redefined('k'); - if (0 <= (expmode = str2expmode(a))) - break; - /* fall into */ - default: - unknown: - error("unknown option: %s%s", *argv, cmdusage); - - }; - } /* end of option processing */ - - /* Now handle all pathnames. */ - if (nerror) cleanup(); - else if (argc < 1) faterror("no input file%s", cmdusage); - else for (; 0 < argc; cleanup(), ++argv, --argc) { - ffree(); - - if (pairnames(argc, argv, lockflag?rcswriteopen:rcsreadopen, true, false) <= 0) - continue; - - /* - * RCSname contains the name of the RCS file, and finptr - * points at it. workname contains the name of the working file. - * Also, RCSstat has been set. - */ - diagnose("%s --> %s\n", RCSname, tostdout?"standard output":workname); - - workstatstat = -1; - if (tostdout) { -# if OPEN_O_BINARY - int newmode = Expand==BINARY_EXPAND ? OPEN_O_BINARY : 0; - if (stdout_mode != newmode) { - stdout_mode = newmode; - oflush(); - VOID setmode(STDOUT_FILENO, newmode); - } -# endif - neworkname = 0; - neworkptr = workstdout = stdout; - } else { - workstatstat = stat(workname, &workstat); - if (workstatstat == 0 && same_file(RCSstat, workstat, 0)) { - rcserror("RCS file is the same as working file %s.", - workname - ); - continue; - } - neworkname = makedirtemp(1); - if (!(neworkptr = fopenSafer(neworkname, FOPEN_W_WORK))) { - if (errno == EACCES) - workerror("permission denied on parent directory"); - else - eerror(neworkname); - continue; - } - } - - gettree(); /* reads in the delta tree */ - - if (!Head) { - /* no revisions; create empty file */ - diagnose("no revisions present; generating empty revision 0.0\n"); - if (lockflag) - warn( - "no revisions, so nothing can be %slocked", - lockflag < 0 ? "un" : "" - ); - Ozclose(&fcopy); - if (workstatstat == 0) - if (!rmworkfile()) continue; - changelock = 0; - newdate = 0; - } else { - int locks = lockflag ? findlock(false, &targetdelta) : 0; - if (rev) { - /* expand symbolic revision number */ - if (!expandsym(rev, &numericrev)) - continue; - } else { - switch (locks) { - default: - continue; - case 0: - bufscpy(&numericrev, Dbranch?Dbranch:""); - break; - case 1: - bufscpy(&numericrev, targetdelta->num); - break; - } - } - /* get numbers of deltas to be generated */ - if (!(targetdelta=genrevs(numericrev.string,date,author,state,&gendeltas))) - continue; - /* check reservations */ - changelock = - lockflag < 0 ? - rmlock(targetdelta) - : lockflag == 0 ? - 0 - : - addlock(targetdelta, true); - - if ( - changelock < 0 - || (changelock && !checkaccesslist()) - || dorewrite(lockflag, changelock) != 0 - ) - continue; - - if (0 <= expmode) - Expand = expmode; - if (0 < lockflag && Expand == VAL_EXPAND) { - rcserror("cannot combine -kv and -l"); - continue; - } - - if (joinflag && !preparejoin(joinflag)) - continue; - - diagnose("revision %s%s\n",targetdelta->num, - 0name = namedrev(rev, targetdelta); - joinname = buildrevision( - gendeltas, targetdelta, - joinflag&&tostdout ? (FILE*)0 : neworkptr, - Expand < MIN_UNEXPAND - ); -# if !large_memory - if (fcopy == neworkptr) - fcopy = 0; /* Don't close it twice. */ -# endif - if_advise_access(changelock && gendeltas->first!=targetdelta, - finptr, MADV_SEQUENTIAL - ); - - if (donerewrite(changelock, - Ttimeflag ? RCSstat.st_mtime : (time_t)-1 - ) != 0) - continue; - - if (changelock) { - locks += lockflag; - if (1 < locks) - rcswarn("You now have %d locks.", locks); - } - - newdate = targetdelta->date; - if (joinflag) { - newdate = 0; - if (!joinname) { - aflush(neworkptr); - joinname = neworkname; - } - if (Expand == BINARY_EXPAND) - workerror("merging binary files"); - if (!buildjoin(joinname)) - continue; - } - } - if (!tostdout) { - mode_t m = WORKMODE(RCSstat.st_mode, - ! (Expand==VAL_EXPAND || (lockflag<=0 && StrictLocks)) - ); - time_t t = mtimeflag&&newdate ? date2time(newdate) : (time_t)-1; - aflush(neworkptr); - ignoreints(); - r = chnamemod(&neworkptr, neworkname, workname, 1, m, t); - keepdirtemp(neworkname); - restoreints(); - if (r != 0) { - eerror(workname); - error("see %s", neworkname); - continue; - } - diagnose("done\n"); - } - } - - tempunlink(); - Ofclose(workstdout); - exitmain(exitstatus); - -} /* end of main (co) */ - - static void -cleanup() -{ - if (nerror) exitstatus = EXIT_FAILURE; - Izclose(&finptr); - ORCSclose(); -# if !large_memory - if (fcopy!=workstdout) Ozclose(&fcopy); -# endif - if (neworkptr!=workstdout) Ozclose(&neworkptr); - dirtempunlink(); -} - -#if RCS_lint -# define exiterr coExit -#endif - void -exiterr() -{ - ORCSerror(); - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} - - -/***************************************************************** - * The following routines are auxiliary routines - *****************************************************************/ - - static int -rmworkfile() -/* - * Prepare to remove workname, if it exists, and if - * it is read-only. - * Otherwise (file writable): - * if !quietmode asks the user whether to really delete it (default: fail); - * otherwise failure. - * Returns true if permission is gotten. - */ -{ - if (workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH) && !forceflag) { - /* File is writable */ - if (!yesorno(false, "writable %s exists%s; remove it? [ny](n): ", - workname, - myself(workstat.st_uid) ? "" : ", and you do not own it" - )) { - error(!quietflag && ttystdin() - ? "checkout aborted" - : "writable %s exists; checkout aborted", workname); - return false; - } - } - /* Actual unlink is done later by caller. */ - return true; -} - - - static int -rmlock(delta) - struct hshentry const *delta; -/* Function: removes the lock held by caller on delta. - * Returns -1 if someone else holds the lock, - * 0 if there is no lock on delta, - * and 1 if a lock was found and removed. - */ -{ register struct rcslock * next, * trail; - char const *num; - struct rcslock dummy; - int whomatch, nummatch; - - num=delta->num; - dummy.nextlock=next=Locks; - trail = &dummy; - while (next) { - whomatch = strcmp(getcaller(), next->login); - nummatch=strcmp(num,next->delta->num); - if ((whomatch==0) && (nummatch==0)) break; - /*found a lock on delta by caller*/ - if ((whomatch!=0)&&(nummatch==0)) { - rcserror("revision %s locked by %s; use co -r or rcs -u", - num, next->login - ); - return -1; - } - trail=next; - next=next->nextlock; - } - if (next) { - /*found one; delete it */ - trail->nextlock=next->nextlock; - Locks=dummy.nextlock; - next->delta->lockedby = 0; - return 1; /*success*/ - } else return 0; /*no lock on delta*/ -} - - - - -/***************************************************************** - * The rest of the routines are for handling joins - *****************************************************************/ - - - static char * -addjoin(joinrev) - char *joinrev; -/* Add joinrev's number to joinlist, yielding address of char past joinrev, - * or 0 if no such revision exists. - */ -{ - register char *j; - register struct hshentry *d; - char terminator; - struct buf numrev; - struct hshentries *joindeltas; - - j = joinrev; - for (;;) { - switch (*j++) { - default: - continue; - case 0: - case ' ': case '\t': case '\n': - case ':': case ',': case ';': - break; - } - break; - } - terminator = *--j; - *j = 0; - bufautobegin(&numrev); - d = 0; - if (expandsym(joinrev, &numrev)) - d = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&joindeltas); - bufautoend(&numrev); - *j = terminator; - if (d) { - joinlist[++lastjoin] = d->num; - return j; - } - return 0; -} - - static int -preparejoin(j) - register char *j; -/* Parse join list J and place pointers to the - * revision numbers into joinlist. - */ -{ - lastjoin= -1; - for (;;) { - while ((*j==' ')||(*j=='\t')||(*j==',')) j++; - if (*j=='\0') break; - if (lastjoin>=joinlength-2) { - joinlist = - (joinlength *= 2) == 0 - ? tnalloc(char const *, joinlength = 16) - : trealloc(char const *, joinlist, joinlength); - } - if (!(j = addjoin(j))) return false; - while ((*j==' ') || (*j=='\t')) j++; - if (*j == ':') { - j++; - while((*j==' ') || (*j=='\t')) j++; - if (*j!='\0') { - if (!(j = addjoin(j))) return false; - } else { - rcsfaterror("join pair incomplete"); - } - } else { - if (lastjoin==0) { /* first pair */ - /* common ancestor missing */ - joinlist[1]=joinlist[0]; - lastjoin=1; - /*derive common ancestor*/ - if (!(joinlist[0] = getancestor(targetdelta->num,joinlist[1]))) - return false; - } else { - rcsfaterror("join pair incomplete"); - } - } - } - if (lastjoin < 1) - rcsfaterror("empty join"); - return true; -} - - - - static char const * -getancestor(r1, r2) - char const *r1, *r2; -/* Yield the common ancestor of r1 and r2 if successful, 0 otherwise. - * Work reliably only if r1 and r2 are not branch numbers. - */ -{ - static struct buf t1, t2; - - int l1, l2, l3; - char const *r; - - l1 = countnumflds(r1); - l2 = countnumflds(r2); - if ((22 ? 2 : l1); - VOID partialno(&t2, r2, l2>2 ? 2 : l2); - r = cmpnum(t1.string,t2.string)<0 ? t1.string : t2.string; - if (cmpnum(r,r1)!=0 && cmpnum(r,r2)!=0) - return r; - } else if (cmpnumfld(r1, r2, l3+1)!=0) - return partialno(&t1,r1,l3); - } - rcserror("common ancestor of %s and %s undefined", r1, r2); - return 0; -} - - - - static int -buildjoin(initialfile) - char const *initialfile; -/* Function: merge pairs of elements in joinlist into initialfile - * If workstdout is set, copy result to stdout. - * All unlinking of initialfile, rev2, and rev3 should be done by tempunlink(). - */ -{ - struct buf commarg; - struct buf subs; - char const *rev2, *rev3; - int i; - char const *cov[10], *mergev[11]; - char const **p; - - bufautobegin(&commarg); - bufautobegin(&subs); - rev2 = maketemp(0); - rev3 = maketemp(3); /* buildrevision() may use 1 and 2 */ - - cov[1] = CO; - /* cov[2] setup below */ - p = &cov[3]; - if (expandarg) *p++ = expandarg; - if (suffixarg) *p++ = suffixarg; - if (versionarg) *p++ = versionarg; - if (zonearg) *p++ = zonearg; - *p++ = quietarg; - *p++ = RCSname; - *p = 0; - - mergev[1] = MERGE; - mergev[2] = mergev[4] = "-L"; - /* rest of mergev setup below */ - - i=0; - while (inum); - else { - bufscat(&subs, ","); - bufscat(&subs, joinlist[i-2]); - bufscat(&subs, ":"); - bufscat(&subs, joinlist[i-1]); - } - diagnose("revision %s\n",joinlist[i]); - bufscpy(&commarg, "-p"); - bufscat(&commarg, joinlist[i]); - cov[2] = commarg.string; - if (runv(-1, rev2, cov)) - goto badmerge; - diagnose("revision %s\n",joinlist[i+1]); - bufscpy(&commarg, "-p"); - bufscat(&commarg, joinlist[i+1]); - cov[2] = commarg.string; - if (runv(-1, rev3, cov)) - goto badmerge; - diagnose("merging...\n"); - mergev[3] = subs.string; - mergev[5] = joinlist[i+1]; - p = &mergev[6]; - if (quietflag) *p++ = quietarg; - if (lastjoin<=i+2 && workstdout) *p++ = "-p"; - *p++ = initialfile; - *p++ = rev2; - *p++ = rev3; - *p = 0; - switch (runv(-1, (char*)0, mergev)) { - case DIFF_FAILURE: case DIFF_SUCCESS: - break; - default: - goto badmerge; - } - i=i+2; - } - bufautoend(&commarg); - bufautoend(&subs); - return true; - - badmerge: - nerror++; - bufautoend(&commarg); - bufautoend(&subs); - return false; -} diff --git a/gnu/usr.bin/rcs/doc/rcs.ms b/gnu/usr.bin/rcs/doc/rcs.ms deleted file mode 100644 index 20f7defa03c1..000000000000 --- a/gnu/usr.bin/rcs/doc/rcs.ms +++ /dev/null @@ -1,1518 +0,0 @@ -.\" Format this file with: -.\" pic file | tbl | troff -ms -.\" -.\" \*s stands for $, and avoids problems when this file is checked in. -.ds s $ -.de D( -.DS -.nr VS 12p -.vs 12p -.I -.. -.de D) -.DE -.nr VS 18p -.vs 18p -.R -.. -.de Id -.ND 1 June 1995 -.. -.Id $FreeBSD$ -.RP -.TL -RCS\*-A System for Version Control -.sp -.AU -Walter F. Tichy -.AI -Department of Computer Sciences -Purdue University -West Lafayette, Indiana 47907 -.sp -.AB -An important problem in program development and maintenance is version control, -i.e., the task of keeping a software system consisting of many versions and -configurations well organized. -The Revision Control System (RCS) -is a software tool that assists with that task. -RCS manages revisions of text documents, in particular source programs, -documentation, and test data. -It automates the storing, retrieval, logging and identification of revisions, -and it provides selection mechanisms for composing configurations. -This paper introduces basic version control concepts and -discusses the practice of version control -using RCS. -For conserving space, RCS stores deltas, i.e., differences between -successive revisions. Several delta storage methods are discussed. -Usage statistics show that RCS's delta storage method is -space and time efficient. -The paper concludes with a detailed survey of version control tools. -.sp -\fBKeywords\fR: configuration management, history management, -version control, revisions, deltas. -.AE -.FS -An earlier version of this paper was published in -.I "Software\*-Practice & Experience" -.B 15 , -7 (July 1985), 637-654. -.FE -.nr VS 18p -.LP -.NH -Introduction -.PP -Version control is the task of keeping software -systems consisting of many versions and configurations well organized. -The Revision Control System (RCS) is a set of UNIX -commands that assist with that task. -.PP -RCS' primary function is to manage \fIrevision groups\fR. -A revision group is a set of text documents, called \fIrevisions\fR, -that evolved from each other. A new revision is -created by manually editing an existing one. -RCS organizes the revisions into an ancestral tree. The initial revision -is the root of the tree, and the tree edges indicate -from which revision a given one evolved. -Besides managing individual revision groups, RCS provides -flexible selection functions for composing configurations. -RCS may be combined with MAKE\u1\d, -resulting in a powerful package for version control. -.PP -RCS also offers facilities for -merging updates with customer modifications, -for distributed software development, and -for automatic identification. -Identification is the `stamping' -of revisions and configurations with unique markers. -These markers are akin to serial numbers, -telling software maintainers unambiguously which configuration -is before them. -.PP -RCS is designed for both production and experimental -environments. -In production environments, -access controls detect update conflicts and prevent overlapping changes. -In experimental environments, where strong controls are -counterproductive, it is possible to loosen the controls. -.PP -Although RCS was originally intended for programs, it is useful for any -text that is revised frequently and whose previous revisions must be -preserved. RCS has been applied successfully to store the source -text for drawings, VLSI layouts, documentation, specifications, -test data, form letters and articles. -.PP -This paper discusses the practice of -version control using RCS. -It also introduces basic version control concepts, -useful for clarifying current practice and designing similar systems. -Revision groups of individual components are treated in the next three sections, -and the extensions to configurations follow. -Because of its size, a survey of version control tools -appears at the end of the paper. -.NH -Getting started with RCS -.PP -Suppose a text file \fIf.c\fR is to be placed under control of RCS. -Invoking the check-in command -.D( -ci f.c -.D) -creates a new revision group with the contents of -\fIf.c\fR as the initial -revision (numbered 1.1) -and stores the group into the file \fIf.c,v\fR. -Unless told otherwise, the command deletes \fIf.c\fR. -It also asks for a description of the group. -The description should state the common purpose of all revisions in the group, -and becomes part of the group's documentation. -All later check-in commands will ask for a log entry, -which should summarize the changes made. -(The first revision is assigned a default log message, -which just records the fact that it is the initial revision.) -.PP -Files ending in \fI,v\fR -are called \fIRCS files\fR (\fIv\fR stands for \fIv\fRersions); -the others are called working files. -To get back the working file \fIf.c\fR in the previous example, -execute the check-out command: -.D( -co f.c -.D) -.R -This command extracts the latest revision from -the revision group \fIf.c,v\fR and writes -it into \fIf.c\fR. -The file \fIf.c\fR can now be edited and, when finished, -checked back in with \fIci\fR: -.D( -ci f.c -.D) -\fICi\fR assigns number 1.2 to -the new revision. -If \fIci\fR complains with the message -.D( -ci error: no lock set by -.D) -then the system administrator has decided to configure RCS for a -production environment by enabling the `strict locking feature'. -If this feature is enabled, all RCS files are initialized -such that check-in operations require a lock on the previous revision -(the one from which the current one evolved). -Locking prevents overlapping modifications if several people work on the same file. -If locking is required, the revision should -have been locked during the check-out by using -the option \fI\-l\fR: -.D( -co \-l f.c -.D) -Of course it is too late now for the check-out with locking, because -\fIf.c\fR has already been changed; checking out the file again -would overwrite the modifications. -(To prevent accidental overwrites, \fIco\fR senses the presence -of a working file and asks whether the user really intended to overwrite it. -The overwriting check-out is sometimes useful for -backing up to the previous revision.) -To be able to proceed with the check-in in the present case, first execute -.D( -rcs \-l f.c -.D) -This command retroactively locks the latest revision, unless someone -else locked it in the meantime. In this case, the two programmers -involved have to negotiate whose -modifications should take precedence. -.PP -If an RCS file is private, i.e., if only the owner of the file is expected -to deposit revisions into it, the strict locking feature is unnecessary and -may be disabled. -If strict locking is disabled, -the owner of the RCS file need not have a lock for check-in. -For safety reasons, all others -still do. Turning strict locking off and on is done with the commands: -.D( -rcs \-U f.c \fRand\fP rcs \-L f.c -.D) -These commands enable or disable the strict locking feature for each RCS file -individually. -The system administrator only decides whether strict locking is -enabled initially. -.PP -To reduce the clutter in a working directory, all RCS files can be moved -to a subdirectory with the name \fIRCS\fR. -RCS commands look first into that directory for RCS files. -All the commands presented above work -with the \fIRCS\fR subdirectory without change.\(dg -.FS \(dg -Pairs of RCS and working files can actually be specified in 3 ways: -a) both are given, b) only the working file is given, c) only the -RCS file is given. -If a pair is given, both files may have arbitrary path prefixes; -RCS commands pair them up intelligently. -.FE -.PP -It may be undesirable that \fIci\fR deletes the working file. -For instance, sometimes one would like to save the current revision, -but continue editing. -Invoking -.D( -ci \-l f.c -.D) -checks in \fIf.c\fR as usual, but performs an additional -check-out with locking afterwards. Thus, the working file does -not disappear after the check-in. -Similarly, the option -\fI\-u\fR does a check-in followed by a check-out without -locking. This option is useful if the file is needed for compilation after the check-in. -Both options update the identification markers in the working file -(see below). -.PP -Besides the operations \fIci\fR and \fIco\fR, RCS provides the following -commands: -.sp 0 -.nr VS 12p -.vs 12p -.TS -tab(%); -li l. -ident%extract identification markers -rcs%change RCS file attributes -rcsclean%remove unchanged working files (optional) -rcsdiff%compare revisions -rcsfreeze%record a configuration (optional) -rcsmerge%merge revisions -rlog%read log messages and other information in RCS files -.TE -A synopsis of these commands appears in the Appendix. -.NH 2 -Automatic Identification -.PP -RCS can stamp source and object code with special identification strings, -similar to product and serial numbers. -To obtain such identification, place the marker -.D( -\*sId\*s -.D) -into the text of a revision, for instance inside a comment. -The check-out operation will replace this marker with a string of the form -.D( -\*sId: filename revisionnumber date time author state locker \*s -.D) -This string need never be touched, because \fIco\fR keeps it -up to date automatically. -To propagate the marker into object code, simply put -it into a literal character string. In C, this is done as follows: -.D( -static char rcsid[] = \&"\*sId\*s\&"; -.D) -The command \fIident\fR extracts such markers from any file, in particular from -object code. -\fIIdent\fR helps to find out -which revisions of which modules were used in a given program. -It returns a complete and unambiguous component list, -from which a copy of the program can be reconstructed. -This facility is invaluable for program maintenance. -.PP -There are several additional identification markers, one for each component -of \*sId\*s. -The marker -.D( -\*sLog\*s -.D) -has a similar function. It accumulates -the log messages that are requested during check-in. -Thus, one can maintain the complete history of a revision directly inside it, -by enclosing it in a comment. -Figure 1 is an edited version of a log contained in revision 4.1 of -the file \fIci.c\fR. The log appears at the beginning of the file, -and makes it easy to determine what the recent modifications were. -.sp -.nr VS 12p -.vs 12p -.ne 18 -.nf -.in +0.5i -/* -.in +\w'/'u -* \*sLog: ci.c,v \*s -* Revision 4.1 1983/05/10 17:03:06 wft -* Added option \-d and \-w, and updated assignment of date, etc. to new delta. -* Added handling of default branches. -* -* Revision 3.9 1983/02/15 15:25:44 wft -* Added call to fastcopy() to copy remainder of RCS file. -* -* Revision 3.8 1983/01/14 15:34:05 wft -* Added ignoring of interrupts while new RCS file is renamed; -* avoids deletion of RCS files by interrupts. -* -* Revision 3.7 1982/12/10 16:09:20 wft -* Corrected checking of return code from diff. -* An RCS file now inherits its mode during the first ci from the working file, -* except that write permission is removed. -*/ -.in 0 -.ce 1 -Figure 1. Log entries produced by the marker \*sLog\*s. -.fi -.nr VS 18p -.vs 18p -.sp 0 -.LP -Since revisions are stored in the form of differences, -each log message is -physically stored once, -independent of the number of revisions present. -Thus, the \*sLog\*s marker incurs negligible space overhead. -.NH -The RCS Revision Tree -.PP -RCS arranges revisions in an ancestral tree. -The \fIci\fR command builds this tree; the auxiliary command \fIrcs\fR -prunes it. -The tree has a root revision, normally numbered 1.1, and successive revisions -are numbered 1.2, 1.3, etc. The first field of a revision number -is called the \fIrelease number\fR and the second one -the \fIlevel number\fR. Unless given explicitly, -the \fIci\fR command assigns a new revision number -by incrementing the level number of the previous revision. -The release number must be incremented explicitly, using the -\fI\-r\fR option of \fIci\fR. -Assuming there are revisions 1.1, 1.2, and 1.3 in the RCS file f.c,v, the command -.D( -ci \-r2.1 f.c \fRor\fP ci \-r2 f.c -.D) -assigns the number 2.1 to the new revision. -Later check-ins without the \fI\-r\fR option will assign the numbers 2.2, 2.3, -and so on. -The release number should be incremented only at major transition points -in the development, for instance when a new release of a software product has -been completed. -.NH 2 -When are branches needed? -.PP -A young revision tree is slender: -It consists of only one branch, called the trunk. -As the tree ages, side branches may form. -Branches are needed in the following 4 situations. -.IP "\fITemporary fixes\fR" -.sp 0 -Suppose a tree has 5 revisions grouped in 2 releases, -as illustrated in Figure 2. -Revision 1.3, the last one of release 1, is in operation at customer sites, -while release 2 is in active development. -.ne 4 -.PS 4i -.ps -2 -box "1.1" -arrow -box "1.2" -arrow -box "1.3" -arrow -box "2.1" -arrow -box "2.2" -arrow dashed -.ps +2 -.PE -.ce 1 -Figure 2. A slender revision tree. -.sp 0 -Now imagine a customer requesting a fix of -a problem in revision 1.3, although actual development has moved on -to release 2. RCS does not permit an extra -revision to be spliced in between 1.3 and 2.1, since that would not reflect -the actual development history. Instead, create a branch -at revision 1.3, and check in the fix on that branch. -The first branch starting at 1.3 has number 1.3.1, and -the revisions on that branch are numbered 1.3.1.1, 1.3.1.2, etc. -The double numbering is needed to allow for another -branch at 1.3, say 1.3.2. -Revisions on the second branch would be numbered -1.3.2.1, 1.3.2.2, and so on. -The following steps create -branch 1.3.1 and add revision 1.3.1.1: -.sp 0 -.I -.nr VS 12p -.vs 12p -.TS -tab(%); -l l l. - %co \-r1.3 f.c% \*- check out revision 1.3 - %edit f.c% \*- change it - %ci \-r1.3.1 f.c% \*- check it in on branch 1.3.1 -.TE -.nr VS 18p -.vs 18p -.R -This sequence of commands transforms the tree of Figure 2 into -the one in Figure 3. -Note that it may be necessary to incorporate the differences -between 1.3 and 1.3.1.1 -into a revision at level 2. The operation \fIrcsmerge\fR automates this -process (see the Appendix). -.ne 7 -.PS 4i -.ps -2 - box "1.1" - arrow - box "1.2" - arrow -R13: box "1.3" - arrow -R21: box "2.1" - arrow -R22: box "2.2" - arrow dashed - line invis down from R21.s -RB1: box "1.3.1.1" - arrow dashed right from RB1.e - arrow from R13.s to RB1.w -.ps +2 -.PE -.ce 1 -Figure 3. A revision tree with one side branch -.sp -.IP "\fIDistributed development and customer modifications\fR" -.sp 0 -Assume a situation as in Figure 2, where revision 1.3 is in operation -at several customer sites, -while release 2 is in development. -Customer sites should use RCS to store the distributed software. -However, customer modifications should not be placed on the same branch -as the distributed source; instead, they should be placed on a side branch. -When the next software distribution arrives, -it should be appended to the trunk of -the customer's RCS file, and the customer -can then merge the local modifications back into the new release. -In the above example, a -customer's RCS file would contain the following tree, assuming -that the customer has received revision 1.3, added his local modifications -as revision 1.3.1.1, then received revision 2.4, and merged -2.4 and 1.3.1.1, resulting in 2.4.1.1. -.ne 7 -.PS 4i -.ps -2 -R13: box "1.3" - line invis -R21: box invis - line invis -R22: box invis - line invis -R24: box "2.4" - line invis -R25: box invis - line invis - arrow from R13.e to R24.w - line invis down from R21.s -RB1: box "1.3.1.1" - arrow from R13.s to RB1.w - right - line invis down from R25.s -RB2: box "2.4.1.1" - arrow from R24.s to RB2.w -.ps +2 -.PE -.ce 1 -Figure 4. A customer's revision tree with local modifications. -.sp 1 -This approach is actually practiced in the CSNET project, -where several universities and a company cooperate -in developing a national computer network. -.IP "\fIParallel development\fR" -.sp 0 -Sometimes it is desirable to explore an alternate design or -a different implementation technique in parallel with the -main line development. Such development -should be carried out on a side branch. -The experimental changes may later be moved into the main line, or abandoned. -.IP "\fIConflicting updates\fR" -.sp 0 -A common occurrence is that one programmer -has checked out a revision, but cannot complete the assignment -for some reason. In the meantime, another person -must perform another modification -immediately. In that case, the second person should check-out the same revision, -modify it, and check it in on a side branch, for later merging. -.PP -Every node in a revision tree consists of the following attributes: -a revision number, a check-in date and time, the author's identification, -a log entry, a state and the actual text. All these attributes -are determined at the time the revision is checked in. -The state attribute indicates the status of a revision. -It is set automatically to `experimental' during check-in. -A revision can later be promoted to a higher status, for example -`stable' or `released'. The set of states is user-defined. -.NH 2 -Revisions are represented as deltas -.PP -For conserving space, RCS stores revisions in the form -of deltas, i.e., as differences between revisions. -The user interface completely hides this fact. -.PP -A delta is a sequence of edit commands that transforms one string -into another. The deltas employed by RCS are line-based, which means -that the only edit commands allowed are insertion and deletion of lines. -If a single character in a line is changed, the -edit scripts consider the entire line changed. -The program \fIdiff\fR\u2\d -produces a small, line-based delta between pairs of text files. -A character-based edit script would take much longer to compute, -and would not be significantly shorter. -.PP -Using deltas is a classical space-time tradeoff: deltas reduce the -space consumed, but increase access time. -However, a version control tool should impose as little delay -as possible on programmers. -Excessive delays discourage the use of version controls, -or induce programmers to take shortcuts that compromise system integrity. -To gain reasonably fast access time for both editing and compiling, -RCS arranges deltas in the following way. -The most recent revision on the trunk is stored intact. -All other revisions on the trunk are stored as reverse deltas. -A reverse delta describes how to go backward in the development history: -it produces the desired revision if applied to the successor of that revision. -This implementation has the advantage -that extraction of the latest revision is a simple and fast copy -operation. -Adding a new revision to the trunk is also fast: \fIci\fR simply -adds the new revision intact, replaces the previous -revision with a reverse delta, and keeps the rest of the old deltas. -Thus, \fIci\fR requires the computation -of only one new delta. -.PP -Branches need special treatment. The naive solution would be to -store complete copies for the tips of all branches. -Clearly, this approach would cost too much space. Instead, -RCS uses \fIforward\fR deltas for branches. Regenerating a revision -on a side branch proceeds as follows. First, extract the latest revision -on the trunk; secondly, apply reverse deltas until the fork revision for -the branch is obtained; thirdly, apply forward deltas until the desired -branch revision is reached. Figure 5 illustrates a tree with -one side branch. Triangles pointing to the left and right represent -reverse and forward deltas, respectively. -.ne 8 -.PS 4i -.ps -2 -define BD X [line invis $1 right .5; -line up .3 then left .5 down .3 then right .5 down .3 then up .3] X - -define FD X [line invis $1 right .5; -line left .5 down .3 then up .6 then right .5 down .3;] X - -right -D11: BD(" 1.1") - arrow right from D11.e -D12: BD(" 1.2") - arrow right from D12.e -D13: BD(" 1.3") - arrow right from D13.e -D21: BD(" 2.1") - arrow right from D21.e -D22: box "2.2" - line invis down from D21.s -F1: FD("1.3.1.1 ") - arrow from D13.se to F1.w - arrow from F1.e right - right -F2: FD("1.3.1.2 ") -.ps +2 -.PE -.ce 1 -Figure 5. A revision tree with reverse and forward deltas. -.sp 0 -.PP -Although implementing fast check-out for the latest trunk revision, -this arrangement has the disadvantage that generation of other revisions -takes time proportional to the number of deltas applied. For example, -regenerating the branch tip in Figure 5 requires application of five -deltas (including the initial one). Since usage statistics show that -the latest trunk revision is the one that is retrieved in 95 per cent -of all cases (see the section on usage statistics), biasing check-out time -in favor of that revision results in significant savings. -However, careful implementation of the delta application process is -necessary to provide low retrieval overhead for other revisions, in -particular for branch tips. -.PP -There are several techniques for delta application. -The naive one is to pass each delta to a general-purpose text editor. -A prototype of RCS invoked the UNIX editor \fIed\fR both -for applying deltas and for expanding the identification markers. -Although easy to implement, performance was poor, owing to the -high start-up costs and excess generality of \fIed\fR. An intermediate -version of RCS used a special-purpose, stream-oriented editor. -This technique reduced the cost of applying a delta to the cost of -checking out the latest trunk revision. The reason for this behavior -is that each delta application involves a complete pass over -the preceding revision. -.PP -However, there is a much better algorithm. Note that the deltas are -line oriented and that most of the work of a stream editor involves -copying unchanged lines from one revision to the next. A faster -algorithm avoids unnecessary copying of character strings by using -a \fIpiece table\fR. -A piece table is a one-dimensional array, specifying how a given -revision is `pieced together' from lines in the RCS file. -Suppose piece table \fIPT\dr\u\fR represents revision \fIr\fR. -Then \fIPT\dr\u[i]\fR contains the starting position of line \fIi\fR -of revision \fIr\fR. -Application of the next delta transforms piece table \fIPT\dr\u\fR -into \fIPT\dr+1\u\fR. For instance, a delete command removes a -series of entries from the piece table. An insertion command inserts -new entries, moving the entries following the insertion point further down the -array. The inserted entries point to the text lines in the delta. -Thus, no I/O is involved except for reading the delta itself. When all -deltas have been applied to the piece table, a sequential pass -through the table looks up each line in the RCS file and copies it to -the output file, updating identification markers at the same time. -Of course, the RCS file must permit random access, since the copied -lines are scattered throughout that file. Figure 6 illustrates an -RCS file with two revisions and the corresponding piece tables. -.ne 13 -.sp 6 -.ce 1 -\fIFigure 6 is not available.\fP -.sp 5 -.ce 1 -Figure 6. An RCS file and its piece tables -.sp 0 -.PP -The piece table approach has the property that the time for applying a single -delta is roughly determined by the size of the delta, and not by the -size of the revision. For example, if a delta is -10 per cent of the size of a revision, then applying it takes only -10 per cent of the time to generate the latest trunk revision. (The stream -editor would take 100 per cent.) -.PP -There is an important alternative for representing deltas that affects -performance. SCCS\u3\d, -a precursor of RCS, uses \fIinterleaved\fR deltas. -A file containing interleaved deltas is partitioned into blocks of lines. -Each block has a header that specifies to which revision(s) the block -belongs. The blocks are sorted out in such a way that a single -pass over the file can pick up all the lines belonging to a given -revision. Thus, the regeneration time for all revisions is the same: -all headers must be inspected, and the associated blocks either copied -or skipped. As the number of revisions increases, the cost of retrieving -any revision is much higher than the cost of checking out the -latest trunk revision with reverse deltas. A detailed comparison -of SCCS's interleaved deltas and RCS's reverse deltas can be found -in Reference 4. -This reference considers the version of RCS with the -stream editor only. The piece table method improves performance -further, so that RCS is always faster than SCCS, except if 10 -or more deltas are applied. -.PP -Additional speed-up for both delta methods can be obtained by caching -the most recently generated revision, as has been implemented in DSEE.\u5\d -With caching, access time to frequently used revisions can approach normal file -access time, at the cost of some additional space. -.NH -Locking: A Controversial Issue -.PP -The locking mechanism for RCS was difficult to design. -The problem and its solution are first presented in their `pure' form, -followed by a discussion of the complications -caused by `real-world' considerations. -.PP -RCS must prevent two or more persons from depositing competing changes of the -same revision. -Suppose two programmers check out revision 2.4 and -modify it. Programmer A checks in a revision before programmer B\&. -Unfortunately, programmer B has not seen A's -changes, so the effect is that A's changes are covered up by B's deposit. -A's changes are not lost since all revisions -are saved, but they are confined to a single revision.\(dd -.FS \(dd -Note that this problem is entirely different from the atomicity problem. -Atomicity means that -concurrent update operations on the same RCS file cannot be permitted, -because that may result in inconsistent data. -Atomic updates are essential (and implemented in RCS), -but do not solve the conflict discussed here. -.FE -.PP -This conflict is prevented in RCS by locking. -Whenever someone intends to edit a revision (as opposed -to reading or compiling it), the revision should be checked out -and locked, -using the \fI\-l\fR option on \fIco\fR. On subsequent check-in, -\fIci\fR tests the lock and then removes it. -At most one programmer at a time may -lock a particular revision, and only this programmer may check in -the succeeding revision. -Thus, while a revision is locked, it is the exclusive responsibility -of the locker. -.PP -An important maxim for software tools like RCS is that they must -not stand in the way of making progress with a project. -This consideration leads to several weakenings of the locking mechanism. -First of all, even if a revision is locked, it can -still be checked out. This is necessary if other people -wish to compile or inspect the locked revision -while the next one is in preparation. The only operations they -cannot do are to lock the revision or to check in the succeeding one. Secondly, -check-in operations on other branches in the RCS file are still possible; the -locking of one revision does not affect any other revision. -Thirdly, revisions are occasionally locked for a long period of time -because a programmer is absent or otherwise unable to complete -the assignment. If another programmer has to make a pressing change, -there are the following three alternatives for making progress: -a) find out who is holding the lock and ask that person to release it; -b) check out the locked revision, modify it, check it -in on a branch, and merge the changes later; -c) break the lock. Breaking a lock leaves a highly visible -trace, namely an electronic mail message that is sent automatically to the -holder of the lock, recording the breaker and a commentary requested from him. -Thus, breaking locks is tolerated under certain circumstances, -but will not go unnoticed. -Experience has shown that the automatic mail message attaches a high enough -stigma to lock breaking, -such that programmers break locks only in real emergencies, -or when a co-worker resigns and leaves locked revisions behind. -.PP -If an RCS file is private, i.e., when a programmer owns an RCS file -and does not expect anyone else to perform check-in operations, -locking is an unnecessary nuisance. -In this case, -the `strict locking feature' discussed earlier may be disabled, -provided that file protection -is set such that only the owner may write the RCS file. -This has the effect that only the owner can check-in revisions, -and that no lock is needed for doing so. -.PP -As added protection, -each RCS file contains an access list that specifies the users -who may execute update operations. If an access list is empty, -only normal UNIX file protection applies. Thus, the access list is -useful for restricting the set of people who would otherwise have update -permission. Just as with locking, the access list -has no effect on read-only operations such as \fIco\fR. This approach -is consistent with the UNIX philosophy of openness, which contributes -to a productive software development environment. -.NH -Configuration Management -.PP -The preceding sections described how RCS deals with revisions of individual -components; this section discusses how to handle configurations. -A configuration is a set of revisions, where each revision comes -from a different revision group, and the revisions are selected -according to a certain criterion. -For example, -in order to build a functioning compiler, the `right' -revisions from the scanner, the parser, the optimizer -and the code generator must be combined. -RCS, in conjunction with MAKE, -provides a number of facilities to effect a smooth selection. -.NH 2 -RCS Selection Functions -.PP -.IP "\fIDefault selection\fR" -.sp 0 -During development, the usual selection criterion is to choose -the latest revision of all components. The \fIco\fR command -makes this selection by default. For example, the command -.D( -co *,v -.D) -retrieves the latest revision on the default branch of each RCS file -in the current directory. -The default branch is usually the trunk, but may be -set to be a side branch. -Side branches as defaults are needed in distributed software development, -as discussed in the section on the RCS revision tree. -.sp -.IP "\fIRelease based selection\fR" -.sp 0 -Specifying a release or branch number selects the latest revision in -that release or branch. -For instance, -.D( -co \-r2 *,v -.D) -retrieves the latest revision with release number 2 from each RCS file. -This selection is convenient if a release has been completed and -development has moved on to the next release. -.sp -.IP "\fIState and author based selection\fR" -.sp 0 -If the highest level number within a given release number -is not the desired one, -the state attribute can help. For example, -.D( -co \-r2 \-sReleased *,v -.D) -retrieves the latest revision with release number 2 whose state attribute -is `Released'. -Of course, the state attribute has to be set appropriately, using the -\fIci\fR or \fIrcs\fR commands. -Another alternative is to select a revision by its author, -using the \fI\-w\fR option. -.sp -.IP "\fIDate based selection\fR" -.sp 0 -Revisions may also be selected by date. -Suppose a release of an entire system was -completed and current on March 4, at 1:00 p.m. local time. Then the command -.D( -co \-d'March 4, 1:00 pm LT' *,v -.D) -checks out all the components of that release, independent of the numbering. -The \fI\-d\fR option specifies a `cutoff date', i.e., -the revision selected has a check-in date that -is closest to, but not after the date given. -.IP "\fIName based selection\fR" -.sp 0 -The most powerful selection function is based on assigning symbolic -names to revisions and branches. -In large systems, a single release number or date is not sufficient -to collect the appropriate revisions from all groups. -For example, suppose one wishes to combine release 2 -of one subsystem and release 15 of another. -Most likely, the creation dates of those releases differ also. -Thus, a single revision number or date passed to the \fIco\fR command -will not suffice to select the right revisions. -Symbolic revision numbers solve this problem. -Each RCS file may contain a set of symbolic names that are mapped -to numeric revision numbers. For example, assume -the symbol \fIV3\fR is bound to release number 2 in file \fIs,v\fR, and to -revision number 15.9 in \fIt,v\fR. -Then the single command -.D( -co \-rV3 s,v t,v -.D) -retrieves the latest revision of release 2 from \fIs,v\fR, -and revision 15.9 from \fIt,v\fR. -In a large system with many modules, checking out all -revisions with one command greatly simplifies configuration management. -.PP -Judicious use of symbolic revision numbers helps with organizing -large configurations. -A special command, \fIrcsfreeze\fR, -assigns a symbolic revision number to a selected revision -in every RCS file. -\fIRcsfreeze\fR effectively freezes a configuration. -The assigned symbolic revision number selects all components -of the configuration. -If necessary, symbolic numbers -may even be intermixed with numeric ones. Thus, \fIV3.5\fR in the -above example -would select revision 2.5 in \fIs,v\fR and branch 15.9.5 in \fIt,v\fR. -.PP -The options \fI\-r\fR, \fI\-s\fR, \fI\-w\fR and \fI\-d\fR -may be combined. If a branch is given, the latest revision -on that branch satisfying all conditions is retrieved; -otherwise, the default branch is used. -.NH 2 -Combining MAKE and RCS -.PP -MAKE\u1\d -is a program that processes configurations. -It is driven by configuration specifications -recorded in a special file, called a `Makefile'. -MAKE avoids redundant processing steps -by comparing creation dates of source and processed objects. -For example, when instructed to compile all -modules of a given system, it only recompiles -those source modules that were changed -since they were processed last. -.PP -MAKE has been extended with an auto-checkout feature for RCS.* -.FS * -This auto-checkout extension is available only in some versions of MAKE, -e.g. GNU MAKE. -.FE -When a certain file to be processed is not present, -MAKE attempts a check-out operation. -If successful, MAKE performs the required processing, and then deletes -the checked out file to conserve space. -The selection parameters discussed above can be passed to MAKE -either as parameters, or directly embedded in the Makefile. -MAKE has also been extended to search the subdirectory named \fIRCS\fR -for needed files, rather than just the current working directory. -However, if a working file is present, MAKE totally ignores the corresponding -RCS file and uses the working file. -(In newer versions of MAKE distributed by AT&T and others, -auto-checkout can be -achieved with the rule DEFAULT, instead of a special extension of MAKE. -However, a file checked out by the rule DEFAULT -will not be deleted after processing. \fIRcsclean\fR can be -used for that purpose.) -.PP -With auto-checkout, RCS/MAKE can effect a selection rule -especially tuned for multi-person software development and maintenance. -In these situations, -programmers should obtain configurations that consist of -the revisions they have personally checked out plus the latest -checked in revision of all other revision groups. -This schema can be set up as follows. -.PP -Each programmer chooses a working directory -and places into it a symbolic link, named \fIRCS\fR, -to the directory containing the relevant RCS files. -The symbolic link makes sure that \fIco\fR and \fIci\fR -operations need only specify the working files, and that -the Makefile need not be changed. -The programmer then checks out the needed files and modifies them. -If MAKE is invoked, -it composes configurations by selecting those -revisions that are checked out, and the rest from the -subdirectory \fIRCS\fR. -The latter selection may be controlled by a symbolic -revision number or any of the other selection criteria. -If there are several programmers editing in separate working directories, -they are insulated from each other's changes until checking in their -modifications. -.PP -Similarly, a maintainer can recreate an older configuration -by starting to work in an empty working directory. -During the initial MAKE invocation, all revisions are selected from RCS files. -As the maintainer checks out files and modifies them, -a new configuration is gradually built up. -Every time MAKE is invoked, it substitutes the modified revisions -into the configuration being manipulated. -.PP -A final application of RCS is to use it for storing Makefiles. -Revision groups of Makefiles represent -multiple versions of configurations. -Whenever a configuration is baselined or distributed, -the best approach is to unambiguously fix -the configuration with a symbolic revision number by calling -\fIrcsfreeze\fR, -to embed that symbol into the Makefile, and to -check in the Makefile (using the same symbolic revision number). -With this approach, old configurations -can be regenerated easily and reliably. -.NH -Usage Statistics -.PP -The following usage statistics were collected on two DEC VAX-11/780 -computers of the Purdue Computer Science Department. Both machines -are mainly used for research purposes. Thus, the data -reflect an environment in which the majority of projects -involve prototyping and advanced software development, -but relatively little long-term maintenance. -.PP -For the first experiment, -the \fIci\fR and \fIco\fR operations were instrumented -to log the number of backward and forward deltas applied. -The data were collected during a 13 month period -from Dec. 1982 to Dec. 1983. -Table I summarizes the results. -.sp 0 -.nr VS 12p -.vs 12p -.TS -center,box,tab(#); -c|c|c|c|c s|c s -c|c|c|c|c s|c s -l|n|n|n|n n|n n. -Operation#Total#Total deltas#Mean deltas#Operations#Branch - #operations #applied#applied#with >1 delta#operations -_ -co # 7867# 9320#1.18#509#(6%)#203#(3%) -ci # 3468# 2207#0.64# 85#(2%)# 75#(2%) -ci & co#11335#11527#1.02#594#(5%)#278#(2%) -.TE -.ce 1 -Table I. Statistics for \fIco\fR and \fIci\fR operations. -.nr VS 18p -.vs 18p -.PP -The first two lines show statistics for check-out and check-in; -the third line shows the combination. -Recall that \fIci\fR performs an implicit check-out to obtain -a revision for computing the delta. -In all measures presented, the most recent revision (stored intact) -counts as one delta. The number of deltas applied represents -the number of passes necessary, where the first `pass' is a copying step. -.PP -Note that the check-out operation is executed more than -twice as frequently as the check-in operation. -The fourth column gives the mean number of deltas -applied in all three cases. -For \fIci\fR, the mean number of deltas applied is less -than one. -The reasons are that the initial check-in requires no delta at all, and that -the only time \fIci\fR requires more than one delta is for branches. -Column 5 shows the actual number of operations that applied more than one -delta. -The last column indicates that branches were not used often. -.PP -The last three columns demonstrate that the most recent trunk revision -is by far the most frequently accessed. -For RCS, check-out of -this revision is a simple copy operation, which is the absolute minimum -given the copy-semantics of \fIco\fR. -Access to older revisions and branches -is more common in non-academic environments, -yet even if access to older deltas were an order -of magnitude more frequent, -the combined average number of deltas applied would still be below 1.2. -Since RCS is faster than SCCS until up to 10 delta applications, -reverse deltas are clearly the method of choice. -.PP -The second experiment, conducted in March of 1984, -involved surveying the existing RCS files -on our two machines. The goal was to determine the mean number of -revisions per RCS file, as well as the space consumed by them. -Table II shows the results. (Tables I and II were produced at different -times and are unrelated.) -.sp 0 -.nr VS 12p -.vs 12p -.TS -center,box,tab(#); -c | c | c | c | c | c | c -c | c | c | c | c | c | c -l | n | n | n | n | n | n. - #Total RCS#Total#Mean#Mean size of#Mean size of#Overhead - #files#revisions#revisions#RCS files#revisions -_ -All files #8033#11133#1.39#6156#5585#1.10 -Files with#1477# 4578#3.10#8074#6041#1.34 -\(>= 2 deltas -.TE -.ce 1 -Table II. Statistics for RCS files. -.nr VS 18p -.vs 18p -.PP -The mean number of revisions per RCS file is 1.39. -Columns 5 and 6 show the mean sizes (in bytes) of an RCS file -and of the latest revision of each RCS file, respectively. -The `overhead' column contains the ratio of the mean sizes. -Assuming that all revisions in an RCS file are approximately the same size, -this ratio gives a measure of the space consumed by the extra revisions. -.PP -In our sample, over 80 per cent of the RCS files contained only a single revision. -The reason is that our -systems programmers routinely check in all source files -on the distribution tapes, even though they may never touch them again. -To get a better indication of how much space savings are possible -with deltas, all measures with those files -that contained 2 or more revisions were recomputed. Only for those files -is RCS necessary. -As shown in the second line, the average number of revisions for those files is -3.10, with an overhead of 1.34. This means that the extra 2.10 deltas -require 34 per cent extra space, or -16 per cent per extra revision. -Rochkind\u3\d -measured the space consumed by SCCS, and -reported an average of 5 revisions per group -and an overhead of 1.37 (or about 9 per cent per extra revision). -In a later paper, Glasser\u6\d -observed an average of 7 revisions per group in a single, large project, -but provided no overhead figure. -In his paper on DSEE\u5\d, -Leblang reported that delta storage combined with blank compression -results in an overhead of a mere 1\-2 per cent per revision. -Since leading blanks accounted for about 20 per cent of the surveyed Pascal -programs, a revision group with 5\-10 members was smaller -than a single cleartext copy. -.PP -The above observations demonstrate clearly that the space needed -for extra revisions is small. With delta storage, the luxury of -keeping multiple revisions online is certainly affordable. -In fact, introducing a system with delta storage may reduce -storage requirements, because programmers often save back-up copies -anyway. Since back-up copies are stored much more efficiently with deltas, -introducing a system such as RCS may -actually free a considerable amount of space. -.NH -Survey of Version Control Tools -.PP -The need to keep back-up copies of software arose when -programs and data were no longer stored on paper media, but were entered -from terminals and stored on disk. -Back-up copies are desirable for reliability, and many modern editors -automatically save a back-up copy for every file touched. -This strategy -is valuable for short-term back-ups, but not suitable for long-term -version control, since an existing back-up copy is overwritten whenever the -corresponding file is edited. -.PP -Tape archives are suitable for long-term, offline storage. -If all changed files are dumped on a back-up tape once per day, old revisions -remain accessible. However, tape archives are unsatisfactory -for version control in several ways. First, backing up the file -system every 24 hours does not capture intermediate revisions. -Secondly, the old revisions are not online, -and accessing them is tedious and time-consuming. -In particular, it is impractical to -compare several old revisions of a group, -because that may require mounting and searching several tapes. -Tape archives are important fail-safe tools in the -event of catastrophic disk failures or accidental deletions, -but they are ill-suited for version control. -Conversely, version control tools do not obviate the -need for tape archives. -.PP -A natural technique for keeping several old revisions online is -to never delete a file. -Editing a file -simply creates a new file with the same -name, but with a different sequence number. -This technique, available as an option in DEC's VMS operating system, -turns out to be inadequate for version control. -First, it is prohibitively expensive in terms of storage costs, -especially since no data compression techniques are employed. -Secondly, indiscriminately storing every change produces too many -revisions, and programmers have difficulties distinguishing them. -The proliferation of revisions forces programmers to spend much time on -finding and deleting useless files. -Thirdly, most of the support functions like locking, logging, -revision selection, -and identification described in this paper are not available. -.PP -An alternative approach is to separate editing from revision control. -The user may repeatedly edit a given revision, -until freezing it with an explicit command. -Once a revision is frozen, it is stored permanently and can no longer be modified. -(In RCS, freezing a revisions is done with \fIci\fR.) -Editing a frozen revision implicitly creates a new one, which -can again be changed repeatedly until it is frozen itself. -This approach saves exactly those revisions that the user -considers important, and keeps the number of revisions manageable. -IBM's CLEAR/CASTER\u7\d, -AT&T's SCCS\u3\d, -CMU's SDC\u8\d -and DEC's CMS\u9\d, -are examples of version control systems using this approach. -CLEAR/CASTER maintains a data base of programs, specifications, -documentation and messages, using deltas. -Its goal is to provide control over the development process from a -management viewpoint. -SCCS stores multiple revisions of source text in an ancestral tree, -records a log entry for each revision, -provides access control, and has facilities -for uniquely identifying each revision. -An efficient delta technique -reduces the space consumed by each revision group. -SDC is much simpler than SCCS because it stores not more than -two revisions. However, it maintains a complete log for all old -revisions, some of which may be on back-up tape. -CMS, like SCCS, manages tree-structured revision groups, -but offers no identification mechanism. -.PP -Tools for dealing with configurations are still in a state of flux. -SCCS, SDC and CMS can be combined with MAKE or MAKE-like programs. -Since flexible selection rules are missing from all these tools, -it is sometimes difficult -to specify precisely which revision of each group -should be passed to MAKE for building a desired configuration. -The Xerox Cedar system\u10\d -provides a `System Modeller' that can rebuild -a configuration from an arbitrary set of module revisions. -The revisions of a module are only distinguished by creation time, -and there is no tool for managing groups. -Since the selection rules are primitive, -the System Modeller appears to be somewhat tedious to use. -Apollo's DSEE\u5\d -is a sophisticated software engineering environment. -It manages revision groups in a way similar to SCCS and CMS. Configurations -are built using `configuration threads'. -A configuration thread states which revision of each group -named in a configuration should be chosen. -A configuration thread may contain dynamic specifiers -(e.g., `choose the revisions I am currently working on, -and the most recent revisions otherwise'), which are bound -automatically at build time. -It also provides a notification mechanism for alerting -maintainers about the need to rebuild a system after a change. -.PP -RCS is based on a general model for describing -multi-version/multi-configuration systems\u11\d. -The model describes systems using AND/OR graphs, where AND nodes represent -configurations, and OR nodes represent version groups. -The model gives rise to a suit of selection rules for -composing configurations, almost all of which are implemented in RCS. -The revisions selected by RCS are passed to MAKE for configuration building. -Revision group management is modelled after SCCS. -RCS retains SCCS's best features, -but offers a significantly simpler user interface, -flexible selection rules, adequate integration with MAKE -and improved identification. -A detailed comparison of RCS and SCCS appears in Reference 4. -.PP -An important component of all revision control systems -is a program for computing deltas. -SCCS and RCS use the program \fIdiff\fR\u2\d, -which first computes the longest common substring of two -revisions, and then produces the delta from that substring. -The delta is simply an edit script consisting of deletion and -insertion commands that generate one revision from the other. -.PP -A delta based on a longest common substring is not necessarily minimal, -because it does not take advantage of crossing block moves. -Crossing block moves arise if two or more blocks of lines -(e.g., procedures) -appear in a different order in two revisions. -An edit script derived from a longest common substring -first deletes the shorter of the two blocks, and then reinserts it. -Heckel\u12\d -proposed an algorithm for detecting block moves, but -since the algorithm is based on heuristics, -there are conditions -under which the generated delta is far from minimal. -DSEE uses this algorithm combined with blank compression, -apparently with satisfactory overall results. -A new algorithm that is guaranteed to produce a minimal delta based on -block moves appears in Reference 13. -A future release of RCS will use this algorithm. -.PP -\fIAcknowledgements\fR: -Many people have helped make RCS a success by contributed criticisms, suggestions, -corrections, and even whole new commands (including manual pages). -The list of people is too long to be -reproduced here, but my sincere thanks for their help and -goodwill goes to all of them. -.sp -.nr VS 12p -.vs 12p -.SH -Appendix: Synopsis of RCS Operations -.LP -.IP "\fIci\fP \fB\- check in revisions\fP" -.sp 0 -\fICi\fR stores the contents of a working file into the -corresponding RCS file as a new revision. -If the RCS file doesn't exist, \fIci\fR creates it. -\fICi\fR removes the working file, unless one of the options -\fI\-u\fR or \fI\-l\fR is present. -For each check-in, \fIci\fR asks for a commentary -describing the changes relative to the previous revision. -.sp 1 -\fICi\fR assigns the revision number given by the \fI\-r\fR option; -if that option is missing, it derives the number from the -lock held by the user; if there is no lock and locking is not strict, -\fIci\fR increments the number of the latest revision on the trunk. -A side branch can only be started by explicitly specifying its -number with the \fI\-r\fR option during check-in. -.sp 1 -\fICi\fR also determines -whether the revision to be checked in is different from the -previous one, and asks whether to proceed if not. -This facility simplifies check-in operations for large systems, -because one need not remember which files were changed. -.sp 1 -The option \fI\-k\fR searches the checked in file for identification -markers containing -the attributes -revision number, check-in date, author and state, and assigns these -to the new revision rather than computing them. This option is -useful for software distribution: Recipients of distributed software -using RCS should check in updates with the \fI\-k\fR option. -This convention guarantees that revision numbers, check-in dates, -etc., are the same at all sites. -.IP "\fIco\fP \fB\- check out revisions\fP" -.sp 0 -\fICo\fR retrieves revisions according to revision number, -date, author and state attributes. It either places the revision -into the working file, or prints it on the standard output. -\fICo\fR always expands the identification markers. -.IP "\fIident\fP \fB\- extract identification markers\fP" -.sp 0 -\fIIdent\fR extracts the identification markers expanded by \fIco\fR -from any file and prints them. -.IP "\fIrcs\fP \fB\- change RCS file attributes\fP" -.sp 0 -\fIRcs\fR is an administrative operation that changes access lists, -locks, unlocks, breaks locks, toggles the strict-locking feature, -sets state attributes and symbolic revision numbers, changes the -description, and deletes revisions. A revision can -only be deleted if it is not the fork of a side branch. -.br -.ne 10 -.IP "\fIrcsclean\fP \fB\- clean working directory\fP" -.sp 0 -\fIRcsclean\fR removes working files that were checked out but never changed.* -.FS * -The \fIrcsclean\fP and \fIrcsfreeze\fP commands -are optional and are not always installed. -.FE -.IP "\fIrcsdiff\fP \fB\- compare revisions\fP" -.sp 0 -\fIRcsdiff\fR compares two revisions and prints their -difference, using the UNIX tool \fIdiff\fR. -One of the revisions compared may be checked out. -This command is useful for finding out about changes. -.IP "\fIrcsfreeze\fP \fB\- freeze a configuration\fP" -.sp 0 -\fIRcsfreeze\fR assigns the same symbolic revision number -to a given revision in all RCS files. -This command is useful for accurately recording a configuration.* -.IP "\fIrcsmerge\fP \fB\- merge revisions\fP" -.sp 0 -\fIRcsmerge\fR merges two revisions, \fIrev1\fR and \fIrev2\fR, -with respect to a common ancestor. -A 3-way file comparison determines the segments of lines that -are (a) the same in all three revisions, or (b) the same in 2 revisions, -or (c) different in all three. For all segments of type (b) where -\fIrev1\fR is the differing revision, -the segment in \fIrev1\fR replaces the corresponding segment of \fIrev2\fR. -Type (c) indicates an overlapping change, is flagged as an error, and requires user -intervention to select the correct alternative. -.IP "\fIrlog\fP \fB\- read log messages\fP" -.sp 0 -\fIRlog\fR prints the log messages and other information in an RCS file. -.bp -.LP -.nr VS 12p -.vs 12p -.]< -.ds [F 1 -.]- -.ds [K FELD02 -.ds [K MakeArticle -.ds [A Feldman, Stuart I. -.ds [D March 1979 -.ds [T Make\*-A Program for Maintaining Computer Programs -.ds [J Software\*-Practice & Experience -.ds [V 9 -.ds [N 3 -.ds [P 255-265 -.nr [P 1 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 1 journal-article -.ds [F 2 -.]- -.ds [K HUNT01 -.ds [T An Algorithm for Differential File Comparison -.ds [A Hunt, James W. -.as [A " and McIlroy, M. D. -.ds [I Computing Science Technical Report, Bell Laboratories -.ds [R 41 -.ds [D June 1976 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 4 tech-report -.ds [F 3 -.]- -.ds [K SCCS -.ds [A Rochkind, Marc J. -.ds [D Dec. 1975 -.ds [T The Source Code Control System -.ds [J IEEE Transactions on Software Engineering -.ds [V SE-1 -.ds [N 4 -.ds [P 364-370 -.nr [P 1 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 1 journal-article -.ds [F 4 -.]- -.ds [K TICH08 -.ds [T Design, Implementation, and Evaluation of a Revision Control System -.ds [A Tichy, Walter F. -.ds [B Proceedings of the 6th International Conference on Software Engineering -.ds [I ACM, IEEE, IPS, NBS -.ds [D September 1982 -.ds [P 58-67 -.nr [P 1 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 3 article-in-book -.ds [F 5 -.]- -.ds [K LEBL01 -.ds [A Leblang, David B. -.as [A " and Chase, Robert P. -.ds [T Computer-Aided Software Engineering in a Distributed Workstation Environment -.ds [O Proceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium -.as [O " on Practical Software Development Environments. -.ds [J SIGPLAN Notices -.ds [V 19 -.ds [N 5 -.ds [D May 1984 -.ds [P 104-112 -.nr [P 1 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 1 journal-article -.ds [F 1 -.ds [F 3 -.ds [F 6 -.]- -.ds [K SCCSEval -.ds [A Glasser, Alan L. -.ds [D Nov. 1978 -.ds [T The Evolution of a Source Code Control System -.ds [J Software Engineering Notes -.ds [V 3 -.ds [N 5 -.ds [P 122-125 -.nr [P 1 -.ds [O Proceedings of the Software Quality and Assurance Workshop. -.nr [T 0 -.nr [A 1 -.nr [O 1 -.][ 1 journal-article -.ds [F 5 -.ds [F 7 -.]- -.ds [K IBMClearCaster -.ds [A Brown, H.B. -.ds [D 1970 -.ds [T The Clear/Caster System -.ds [J Nato Conference on Software Engineering, Rome -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 1 journal-article -.ds [F 3 -.ds [F 8 -.]- -.ds [K HabermannSDC -.ds [A Habermann, A. Nico -.ds [D Jan. 1979 -.ds [T A Software Development Control System -.ds [I Technical Report, Carnegie-Mellon University, Department of Computer Science -.nr [T 0 -.nr [A 0 -.nr [O 0 -.][ 2 book -.ds [F 9 -.]- -.ds [K CMS -.ds [A DEC -.ds [T Code Management System -.ds [I Digital Equipment Corporation -.ds [O Document No.\ EA-23134-82 -.ds [D 1982 -.nr [T 0 -.nr [A 0 -.nr [O 0 -.][ 2 book -.ds [F 10 -.]- -.ds [K LAMP01 -.ds [A Lampson, Butler W. -.as [A " and Schmidt, Eric E. -.ds [T Practical Use of a Polymorphic Applicative Language -.ds [B Proceedings of the 10th Symposium on Principles of Programming Languages -.ds [I ACM -.ds [P 237-255 -.nr [P 1 -.ds [D January 1983 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 3 article-in-book -.ds [F 5 -.ds [F 11 -.]- -.ds [K TICH07 -.ds [T A Data Model for Programming Support Environments and its Application -.ds [A Tichy, Walter F. -.ds [B Automated Tools for Information System Design and Development -.ds [E Hans-Jochen Schneider and Anthony I. Wasserman -.ds [C Amsterdam -.ds [I North-Holland Publishing Company -.ds [D 1982 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 3 article-in-book -.ds [F 4 -.ds [F 2 -.ds [F 12 -.]- -.ds [K HECK01 -.ds [T A Technique for Isolating Differences Between Files -.ds [A Heckel, Paul -.ds [J Communications of the ACM -.ds [D April 1978 -.ds [V 21 -.ds [N 4 -.ds [P 264-268 -.nr [P 1 -.nr [T 0 -.nr [A 0 -.nr [O 0 -.][ 1 journal-article -.ds [F 13 -.]- -.ds [K TICH11 -.ds [T The String-to-String Correction Problem with Block Moves -.ds [A Tichy, Walter F. -.ds [D Nov. 1984 -.ds [J ACM Transactions on Computer Systems -.ds [V 2 -.ds [N 4 -.ds [P 309-321 -.nr [P 1 -.nr [T 0 -.nr [A 1 -.nr [O 0 -.][ 1 journal-article -.]> diff --git a/gnu/usr.bin/rcs/doc/rcs_func.ms b/gnu/usr.bin/rcs/doc/rcs_func.ms deleted file mode 100644 index 9818086c3de4..000000000000 --- a/gnu/usr.bin/rcs/doc/rcs_func.ms +++ /dev/null @@ -1,95 +0,0 @@ -.SH -Functions of RCS (Revision Control System) -.PP -RCS manages software libraries. It greatly increases programmer productivity -by providing the following functions. -.IP 1. -RCS stores and retrieves multiple revisions of program and other text. -Thus, one can maintain one or more releases while developing the next -release, with a minimum of space overhead. Changes no longer destroy the -original -- previous revisions remain accessible. -.RS -.IP a. -Maintains each module as a tree of revisions. -.IP b. -Project libraries can -be organized centrally, decentralized, or any way you like. -.IP c. -RCS works for any type of text: programs, documentation, memos, papers, -graphics, VLSI layouts, form letters, etc. -.RE -.IP 2. -RCS maintains a complete history of changes. -Thus, one can find out what happened to a module easily -and quickly, without having to compare source listings or -having to track down colleagues. -.RS -.IP a. -RCS performs automatic record keeping. -.IP b. -RCS logs all changes automatically. -.IP c. -RCS guarantees project continuity. -.RE -.IP 3. -RCS manages multiple lines of development. -.IP 4. -RCS can merge multiple lines of development. -Thus, when several parallel lines of development must be consolidated -into one line, the merging of changes is automatic. -.IP 5. -RCS flags coding conflicts. -If two or more lines of development modify the same section of code, -RCS can alert programmers about overlapping changes. -.IP 6. -RCS resolves access conflicts. -When two or more programmers wish to modify the same revision, -RCS alerts the programmers and makes sure that one modification won't wipe -out the other one. -.IP 7. -RCS provides high-level retrieval functions. -Revisions can be retrieved according to ranges of revision numbers, -symbolic names, dates, authors, and states. -.IP 8. -RCS provides release and configuration control. -Revisions can be marked as released, stable, experimental, etc. -Configurations of modules can be described simply and directly. -.IP 9. -RCS performs automatic identification of modules with name, revision -number, creation time, author, etc. -Thus, it is always possible to determine which revisions of which -modules make up a given configuration. -.IP 10. -Provides high-level management visibility. -Thus, it is easy to track the status of a software project. -.RS -.IP a. -RCS provides a complete change history. -.IP b. -RCS records who did what when to which revision of which module. -.RE -.IP 11. -RCS is fully compatible with existing software development tools. -RCS is unobtrusive -- its interface to the file system is such that -all your existing software tools can be used as before. -.IP 12. -RCS' basic user interface is extremely simple. The novice need to learn -only two commands. Its more sophisticated features have been -tuned towards advanced software development environments and the -experienced software professional. -.IP 13. -RCS simplifies software distribution if customers -maintain sources with RCS also. This technique assures proper -identification of versions and configurations, and tracking of customer -modifications. Customer modifications can be merged into distributed -versions locally or by the development group. -.IP 14. -RCS needs little extra space for the revisions (only the differences). -If intermediate revisions are deleted, the corresponding -differences are compressed into the shortest possible form. -.IP 15. -RCS is implemented with reverse deltas. This means that -the latest revision, which is the one that is accessed most often, -is stored intact. All others are regenerated from the latest one -by applying reverse deltas (backward differences). This -results in fast access time for the revision needed most often. diff --git a/gnu/usr.bin/rcs/lib/Makefile b/gnu/usr.bin/rcs/lib/Makefile deleted file mode 100644 index f21fda1e8100..000000000000 --- a/gnu/usr.bin/rcs/lib/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ - -# Define FSYNC_ALL to get slower but safer writes in case of crashes in -# the middle of CVS/RCS changes -#CFLAGS += -DFSYNC_ALL - -LIB = rcs -SRCS = maketime.c partime.c rcsedit.c rcsfcmp.c rcsfnms.c rcsgen.c \ - rcskeep.c rcskeys.c rcslex.c rcsmap.c rcsrev.c rcssyn.c rcstime.c \ - rcsutil.c merger.c version.c - -INTERNALLIB= - -.include diff --git a/gnu/usr.bin/rcs/lib/Makefile.depend b/gnu/usr.bin/rcs/lib/Makefile.depend deleted file mode 100644 index 18be76b0cb6f..000000000000 --- a/gnu/usr.bin/rcs/lib/Makefile.depend +++ /dev/null @@ -1,13 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - include/xlocale \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/lib/conf.h b/gnu/usr.bin/rcs/lib/conf.h deleted file mode 100644 index 96ec07d6c875..000000000000 --- a/gnu/usr.bin/rcs/lib/conf.h +++ /dev/null @@ -1,400 +0,0 @@ -/* RCS compile-time configuration */ - - /* $FreeBSD$ */ - -/* - * This file is generated automatically. - * If you edit it by hand your changes may be lost. - * Instead, please try to fix conf.sh, - * and send your fixes to rcs-bugs@cs.purdue.edu. - */ - -#define exitmain(n) return n /* how to exit from main() */ -/* #define _POSIX_C_SOURCE 2147483647L */ /* if strict C + Posix 1003.1b-1993 or later */ -/* #define _POSIX_SOURCE */ /* if strict C + Posix 1003.1-1990 */ - -#include -#include -#include - -/* Comment out #include lines below that do not work. */ -#include -#include -#include -#include -#include -/* #include */ -/* #include */ -#include -/* #include */ -#include -#include -#include -#include -#include -/* #include */ -#include -#include -/* #include */ - -/* Define boolean symbols to be 0 (false, the default), or 1 (true). */ -#define has_sys_param_h 1 /* Does #include work? */ -/* extern int errno; */ /* Uncomment if doesn't declare errno. */ -#define has_readlink 1 /* Does readlink() work? */ -#define readlink_isreg_errno EINVAL /* errno after readlink on regular file */ - -#if has_readlink && !defined(MAXSYMLINKS) -# if has_sys_param_h -# include -# endif -# ifndef MAXSYMLINKS -# define MAXSYMLINKS 20 /* BSD; not standard yet */ -# endif -#endif - -/* Comment out the typedefs below if the types are already declared. */ -/* Fix any uncommented typedefs that are wrong. */ -/* typedef int mode_t; */ -/* typedef long off_t; */ -/* typedef int pid_t; */ -/* typedef int sig_atomic_t; */ -/* typedef unsigned size_t; */ -/* typedef int ssize_t; */ -/* typedef long time_t; */ -/* typedef int uid_t; */ - -/* Comment out the keyword definitions below if the keywords work. */ -/* #define const */ -/* #define volatile */ - -/* Define boolean symbols to be 0 (false, the default), or 1 (true). */ -#define has_prototypes 1 /* Do function prototypes work? */ -#define has_stdarg 1 /* Does work? */ -/* #define has_varargs ? */ /* Does work? */ -#define va_start_args 2 /* How many args does va_start() take? */ - -#if O_BINARY - /* Text and binary i/o behave differently. */ - /* This is incompatible with Posix and Unix. */ -# define FOPEN_RB "rb" -# define FOPEN_R_WORK (Expand==BINARY_EXPAND ? "r" : "rb") -# define FOPEN_WB "wb" -# define FOPEN_W_WORK (Expand==BINARY_EXPAND ? "w" : "wb") -# define FOPEN_WPLUS_WORK (Expand==BINARY_EXPAND ? "w+" : "w+b") -# define OPEN_O_BINARY O_BINARY -#else - /* - * Text and binary i/o behave the same. - * Omit "b", since some nonstandard hosts reject it. - */ -# define FOPEN_RB "r" -# define FOPEN_R_WORK "r" -# define FOPEN_WB "w" -# define FOPEN_W_WORK "w" -# define FOPEN_WPLUS_WORK "w+" -# define OPEN_O_BINARY 0 -#endif - -/* This may need changing on non-Unix systems (notably DOS). */ -#define OPEN_CREAT_READONLY (S_IRUSR|S_IRGRP|S_IROTH) /* lock file mode */ -#define OPEN_O_LOCK 0 /* extra open flags for creating lock file */ -#define OPEN_O_WRONLY O_WRONLY /* main open flag for creating a lock file */ - -/* Define or comment out the following symbols as needed. */ -#if has_prototypes -# define P(params) params -#else -# define P(params) () -#endif -#if has_stdarg -# include -#else -# if has_varargs -# include -# else - typedef char *va_list; -# define va_dcl int va_alist; -# define va_start(ap) ((ap) = (va_list)&va_alist) -# define va_arg(ap,t) (((t*) ((ap)+=sizeof(t))) [-1]) -# define va_end(ap) -# endif -#endif -#if va_start_args == 2 -# define vararg_start va_start -#else -# define vararg_start(ap,p) va_start(ap) -#endif -#define bad_chmod_close 0 /* Can chmod() close file descriptors? */ -#define bad_creat0 0 /* Do writes fail after creat(f,0)? */ -#define bad_fopen_wplus 0 /* Does fopen(f,"w+") fail to truncate f? */ -#define getlogin_is_secure 0 /* Is getlogin() secure? Usually it's not. */ -#define has_attribute_noreturn 1 /* Does __attribute__((noreturn)) work? */ -#if has_attribute_noreturn -# define exiting __attribute__((noreturn)) -#else -# define exiting -#endif -#define has_dirent 1 /* Do opendir(), readdir(), closedir() work? */ -#define void_closedir 0 /* Does closedir() yield void? */ -#define has_fchmod 1 /* Does fchmod() work? */ -#define has_fflush_input 0 /* Does fflush() work on input files? */ -#define has_fputs 1 /* Does fputs() work? */ -#define has_ftruncate 1 /* Does ftruncate() work? */ -#define has_getuid 1 /* Does getuid() work? */ -#define has_getpwuid 1 /* Does getpwuid() work? */ -#define has_memcmp 1 /* Does memcmp() work? */ -#define has_memcpy 1 /* Does memcpy() work? */ -#define has_memmove 1 /* Does memmove() work? */ -#define has_map_fd 0 /* Does map_fd() work? */ -#define has_mmap 1 /* Does mmap() work on regular files? */ -#define has_madvise 0 /* Does madvise() work? */ -#define mmap_signal SIGBUS /* signal received if you reference nonexistent part of mmapped file */ -#define has_rename 1 /* Does rename() work? */ -#define bad_a_rename 0 /* Does rename(A,B) fail if A is unwritable? */ -#define bad_b_rename 0 /* Does rename(A,B) fail if B is unwritable? */ -#define bad_NFS_rename 0 /* Can rename(A,B) falsely report success? */ -/* typedef int void; */ /* Some ancient compilers need this. */ -#define VOID (void) /* 'VOID e;' discards the value of an expression 'e'. */ -#define has_seteuid 1 /* Does seteuid() work? See ../INSTALL.RCS. */ -#define has_setreuid 0 /* Does setreuid() work? See ../INSTALL.RCS. */ -#define has_setuid 1 /* Does setuid() exist? */ -#define has_sigaction 1 /* Does struct sigaction work? */ -#define has_sa_sigaction 1 /* Does struct sigaction have sa_sigaction? */ -#define has_signal 1 /* Does signal() work? */ -#define signal_type void /* type returned by signal handlers */ -#define sig_zaps_handler 0 /* Must a signal handler reinvoke signal()? */ -/* #define has_sigblock ? */ /* Does sigblock() work? */ -/* #define sigmask(s) (1 << ((s)-1)) */ /* Yield mask for signal number. */ -typedef size_t fread_type; /* type returned by fread() and fwrite() */ -typedef size_t freadarg_type; /* type of their size arguments */ -typedef void *malloc_type; /* type returned by malloc() */ -#define has_getcwd 1 /* Does getcwd() work? */ -/* #define has_getwd ? */ /* Does getwd() work? */ -#define needs_getabsname 0 /* Must we define getabsname? */ -#define has_mktemp 1 /* Does mktemp() work? */ -#define has_mkstemp 1 /* Does mkstemp() work? */ -#define has_NFS 1 /* Might NFS be used? */ -#define has_psiginfo 0 /* Does psiginfo() work? */ -#define has_psignal 1 /* Does psignal() work? */ -/* #define has_si_errno ? */ /* Does siginfo_t have si_errno? */ -/* #define has_sys_siglist ? */ /* Does sys_siglist[] work? */ -/* #define strchr index */ /* Use old-fashioned name for strchr()? */ -/* #define strrchr rindex */ /* Use old-fashioned name for strrchr()? */ -#define bad_unlink 0 /* Does unlink() fail on unwritable files? */ -#define has_vfork 1 /* Does vfork() work? */ -#define has_fork 1 /* Does fork() work? */ -#define has_spawn 0 /* Does spawn*() work? */ -#define has_waitpid 1 /* Does waitpid() work? */ -#define bad_wait_if_SIGCHLD_ignored 0 /* Does ignoring SIGCHLD break wait()? */ -#define RCS_SHELL "/bin/sh" /* shell to run RCS subprograms */ -#define has_printf_dot 1 /* Does "%.2d" print leading 0? */ -#define has_vfprintf 1 /* Does vfprintf() work? */ -#define has_attribute_format_printf 1 /* Does __attribute__((format(printf,N,N+1))) work? */ -#if has_attribute_format_printf -# define printf_string(m, n) __attribute__((format(printf, m, n))) -#else -# define printf_string(m, n) -#endif -#if has_attribute_format_printf && has_attribute_noreturn - /* Work around a bug in GCC 2.5.x. */ -# define printf_string_exiting(m, n) __attribute__((format(printf, m, n), noreturn)) -#else -# define printf_string_exiting(m, n) printf_string(m, n) exiting -#endif -/* #define has__doprintf ? */ /* Does _doprintf() work? */ -/* #define has__doprnt ? */ /* Does _doprnt() work? */ -/* #undef EXIT_FAILURE */ /* Uncomment this if EXIT_FAILURE is broken. */ -#define large_memory 1 /* Can main memory hold entire RCS files? */ -#ifndef LONG_MAX -#define LONG_MAX 2147483647L /* long maximum */ -#endif -/* Do struct stat s and t describe the same file? Answer d if unknown. */ -#define same_file(s,t,d) ((s).st_ino==(t).st_ino && (s).st_dev==(t).st_dev) -#define has_utimbuf 1 /* Does struct utimbuf work? */ -#define CO "/usr/bin/co" /* name of 'co' program */ -#define COMPAT2 0 /* Are version 2 files supported? */ -#define DIFF "/usr/bin/diff" /* name of 'diff' program */ -#define DIFF3 "/usr/bin/diff3" /* name of 'diff3' program */ -#define DIFF3_BIN 1 /* Is diff3 user-visible (not the /usr/lib auxiliary)? */ -#define DIFFFLAGS "-an" /* Make diff output suitable for RCS. */ -#define DIFF_L 1 /* Does diff -L work? */ -#define DIFF_SUCCESS 0 /* DIFF status if no differences are found */ -#define DIFF_FAILURE 1 /* DIFF status if differences are found */ -#define DIFF_TROUBLE 2 /* DIFF status if trouble */ -#define ED "/bin/ed" /* name of 'ed' program (used only if !DIFF3_BIN) */ -#define MERGE "/usr/bin/merge" /* name of 'merge' program */ -#define TMPDIR "/tmp" /* default directory for temporary files */ -#define SLASH '/' /* principal filename separator */ -#define SLASHes '/' /* `case SLASHes:' labels all filename separators */ -#define isSLASH(c) ((c) == SLASH) /* Is arg a filename separator? */ -#define ROOTPATH(p) isSLASH((p)[0]) /* Is p an absolute pathname? */ -#define X_DEFAULT ",v/" /* default value for -x option */ -#define SLASHSLASH_is_SLASH 1 /* Are // and / the same directory? */ -#define ALL_ABSOLUTE 1 /* Do all subprograms satisfy ROOTPATH? */ -#define DIFF_ABSOLUTE 1 /* Is ROOTPATH(DIFF) true? */ -#define SENDMAIL "/usr/sbin/sendmail" /* how to send mail */ -#define TZ_must_be_set 0 /* Must TZ be set for gmtime() to work? */ - - - -/* Adjust the following declarations as needed. */ - - -/* The rest is for the benefit of non-standard, traditional hosts. */ -/* Don't bother to declare functions that in traditional hosts do not appear, */ -/* or are declared in .h files, or return int or void. */ - - -/* traditional BSD */ - -#if has_sys_siglist && !defined(sys_siglist) - extern char const * const sys_siglist[]; -#endif - - -/* Posix (ISO/IEC 9945-1: 1990 / IEEE Std 1003.1-1990) */ - -/* */ -#ifdef O_CREAT -# define open_can_creat 1 -#else -# define open_can_creat 0 -# define O_RDONLY 0 -# define O_WRONLY 1 -# define O_RDWR 2 -# define O_CREAT 01000 -# define O_TRUNC 02000 -#endif -#ifndef O_EXCL -#define O_EXCL 0 -#endif - -/* */ -#ifndef S_IRUSR -# ifdef S_IREAD -# define S_IRUSR S_IREAD -# else -# define S_IRUSR 0400 -# endif -# ifdef S_IWRITE -# define S_IWUSR S_IWRITE -# else -# define S_IWUSR (S_IRUSR/2) -# endif -#endif -#ifndef S_IRGRP -# if has_getuid -# define S_IRGRP (S_IRUSR / 0010) -# define S_IWGRP (S_IWUSR / 0010) -# define S_IROTH (S_IRUSR / 0100) -# define S_IWOTH (S_IWUSR / 0100) -# else - /* single user OS -- not Posix or Unix */ -# define S_IRGRP 0 -# define S_IWGRP 0 -# define S_IROTH 0 -# define S_IWOTH 0 -# endif -#endif -#ifndef S_ISREG -#define S_ISREG(n) (((n) & S_IFMT) == S_IFREG) -#endif - -/* */ -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */ -#endif -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 0377) == 0) -#endif -#ifndef WTERMSIG -#define WTERMSIG(stat_val) ((stat_val) & 0177) -#undef WIFSIGNALED /* Avoid 4.3BSD incompatibility with Posix. */ -#endif -#ifndef WIFSIGNALED -#define WIFSIGNALED(stat_val) ((unsigned)(stat_val) - 1 < 0377) -#endif - -/* */ -char *getlogin P((void)); -#ifndef STDIN_FILENO -# define STDIN_FILENO 0 -# define STDOUT_FILENO 1 -# define STDERR_FILENO 2 -#endif -#if has_fork && !has_vfork -# undef vfork -# define vfork fork -#endif -#if has_getcwd || !has_getwd - char *getcwd P((char*,size_t)); -#else - char *getwd P((char*)); -#endif -#if has_setuid && !has_seteuid -# undef seteuid -# define seteuid setuid -#endif -#if has_spawn -# if ALL_ABSOLUTE -# define spawn_RCS spawnv -# else -# define spawn_RCS spawnvp -# endif -#else -# if ALL_ABSOLUTE -# define exec_RCS execv -# else -# define exec_RCS execvp -# endif -#endif - -/* utime.h */ -#if !has_utimbuf - struct utimbuf { time_t actime, modtime; }; -#endif - - -/* Standard C library */ - -/* */ -#ifndef L_tmpnam -#define L_tmpnam 32 /* power of 2 > sizeof("/usr/tmp/xxxxxxxxxxxxxxx") */ -#endif -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif -#if has_mktemp - char *mktemp P((char*)); /* traditional */ -#else - char *tmpnam P((char*)); -#endif - -/* */ -char *getenv P((char const*)); -void _exit P((int)) exiting; -void exit P((int)) exiting; -malloc_type malloc P((size_t)); -malloc_type realloc P((malloc_type,size_t)); -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif - -/* */ -char *strcpy P((char*,char const*)); -char *strchr P((char const*,int)); -char *strrchr P((char const*,int)); -void *memcpy P((void*,void const*,size_t)); -#if has_memmove - void *memmove P((void*,void const*,size_t)); -#endif - -/* */ -time_t time P((time_t*)); diff --git a/gnu/usr.bin/rcs/lib/maketime.c b/gnu/usr.bin/rcs/lib/maketime.c deleted file mode 100644 index 0f83bf5690d6..000000000000 --- a/gnu/usr.bin/rcs/lib/maketime.c +++ /dev/null @@ -1,344 +0,0 @@ -/* Convert struct partime into time_t. */ - -/* Copyright 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if has_conf_h -# include "conf.h" -#else -# ifdef __STDC__ -# define P(x) x -# else -# define const -# define P(x) () -# endif -# include -# include -#endif - -#include "partime.h" -#include "maketime.h" - -char const maketId[] - = "$FreeBSD$"; - -static int isleap P((int)); -static int month_days P((struct tm const*)); -static time_t maketime P((struct partime const*,time_t)); - -/* -* For maximum portability, use only localtime and gmtime. -* Make no assumptions about the time_t epoch or the range of time_t values. -* Avoid mktime because it's not universal and because there's no easy, -* portable way for mktime to yield the inverse of gmtime. -*/ - -#define TM_YEAR_ORIGIN 1900 - - static int -isleap(y) - int y; -{ - return (y&3) == 0 && (y%100 != 0 || y%400 == 0); -} - -static int const month_yday[] = { - /* days in year before start of months 0-12 */ - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 -}; - -/* Yield the number of days in TM's month. */ - static int -month_days(tm) - struct tm const *tm; -{ - int m = tm->tm_mon; - return month_yday[m+1] - month_yday[m] - + (m==1 && isleap(tm->tm_year + TM_YEAR_ORIGIN)); -} - -/* -* Convert UNIXTIME to struct tm form. -* Use gmtime if available and if !LOCALZONE, localtime otherwise. -*/ - struct tm * -time2tm(unixtime, localzone) - time_t unixtime; - int localzone; -{ - struct tm *tm; -# if TZ_must_be_set - static char const *TZ; - if (!TZ && !(TZ = getenv("TZ"))) - faterror("The TZ environment variable is not set; please set it to your timezone"); -# endif - if (localzone || !(tm = gmtime(&unixtime))) - tm = localtime(&unixtime); - return tm; -} - -/* Yield A - B, measured in seconds. */ - time_t -difftm(a, b) - struct tm const *a, *b; -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int difference_in_day_of_year = a->tm_yday - b->tm_yday; - int intervening_leap_days = ( - ((ay >> 2) - (by >> 2)) - - (ay/100 - by/100) - + ((ay/100 >> 2) - (by/100 >> 2)) - ); - time_t difference_in_years = ay - by; - time_t difference_in_days = ( - difference_in_years*365 - + (intervening_leap_days + difference_in_day_of_year) - ); - return - ( - ( - 24*difference_in_days - + (a->tm_hour - b->tm_hour) - )*60 + (a->tm_min - b->tm_min) - )*60 + (a->tm_sec - b->tm_sec); -} - -/* -* Adjust time T by adding SECONDS. SECONDS must be at most 24 hours' worth. -* Adjust only T's year, mon, mday, hour, min and sec members; -* plus adjust wday if it is defined. -*/ - void -adjzone(t, seconds) - register struct tm *t; - long seconds; -{ - /* - * This code can be off by a second if SECONDS is not a multiple of 60, - * if T is local time, and if a leap second happens during this minute. - * But this bug has never occurred, and most likely will not ever occur. - * Liberia, the last country for which SECONDS % 60 was nonzero, - * switched to UTC in May 1972; the first leap second was in June 1972. - */ - int leap_second = t->tm_sec == 60; - long sec = seconds + (t->tm_sec - leap_second); - if (sec < 0) { - if ((t->tm_min -= (59-sec)/60) < 0) { - if ((t->tm_hour -= (59-t->tm_min)/60) < 0) { - t->tm_hour += 24; - if (TM_DEFINED(t->tm_wday) && --t->tm_wday < 0) - t->tm_wday = 6; - if (--t->tm_mday <= 0) { - if (--t->tm_mon < 0) { - --t->tm_year; - t->tm_mon = 11; - } - t->tm_mday = month_days(t); - } - } - t->tm_min += 24 * 60; - } - sec += 24L * 60 * 60; - } else - if (60 <= (t->tm_min += sec/60)) - if (24 <= (t->tm_hour += t->tm_min/60)) { - t->tm_hour -= 24; - if (TM_DEFINED(t->tm_wday) && ++t->tm_wday == 7) - t->tm_wday = 0; - if (month_days(t) < ++t->tm_mday) { - if (11 < ++t->tm_mon) { - ++t->tm_year; - t->tm_mon = 0; - } - t->tm_mday = 1; - } - } - t->tm_min %= 60; - t->tm_sec = (int) (sec%60) + leap_second; -} - -/* -* Convert TM to time_t, using localtime if LOCALZONE and gmtime otherwise. -* Use only TM's year, mon, mday, hour, min, and sec members. -* Ignore TM's old tm_yday and tm_wday, but fill in their correct values. -* Yield -1 on failure (e.g. a member out of range). -* Posix 1003.1-1990 doesn't allow leap seconds, but some implementations -* have them anyway, so allow them if localtime/gmtime does. -*/ - time_t -tm2time(tm, localzone) - struct tm *tm; - int localzone; -{ - /* Cache the most recent t,tm pairs; 1 for gmtime, 1 for localtime. */ - static time_t t_cache[2]; - static struct tm tm_cache[2]; - - time_t d, gt; - struct tm const *gtm; - /* - * The maximum number of iterations should be enough to handle any - * combinations of leap seconds, time zone rule changes, and solar time. - * 4 is probably enough; we use a bigger number just to be safe. - */ - int remaining_tries = 8; - - /* Avoid subscript errors. */ - if (12 <= (unsigned)tm->tm_mon) - return -1; - - tm->tm_yday = month_yday[tm->tm_mon] + tm->tm_mday - - (tm->tm_mon<2 || ! isleap(tm->tm_year + TM_YEAR_ORIGIN)); - - /* Make a first guess. */ - gt = t_cache[localzone]; - gtm = gt ? &tm_cache[localzone] : time2tm(gt,localzone); - - /* Repeatedly use the error from the guess to improve the guess. */ - while ((d = difftm(tm, gtm)) != 0) { - if (--remaining_tries == 0) - return -1; - gt += d; - gtm = time2tm(gt,localzone); - } - t_cache[localzone] = gt; - tm_cache[localzone] = *gtm; - - /* - * Check that the guess actually matches; - * overflow can cause difftm to yield 0 even on differing times, - * or tm may have members out of range (e.g. bad leap seconds). - */ - if ( (tm->tm_year ^ gtm->tm_year) - | (tm->tm_mon ^ gtm->tm_mon) - | (tm->tm_mday ^ gtm->tm_mday) - | (tm->tm_hour ^ gtm->tm_hour) - | (tm->tm_min ^ gtm->tm_min) - | (tm->tm_sec ^ gtm->tm_sec)) - return -1; - - tm->tm_wday = gtm->tm_wday; - return gt; -} - -/* -* Check *PT and convert it to time_t. -* If it is incompletely specified, use DEFAULT_TIME to fill it out. -* Use localtime if PT->zone is the special value TM_LOCAL_ZONE. -* Yield -1 on failure. -* ISO 8601 day-of-year and week numbers are not yet supported. -*/ - static time_t -maketime(pt, default_time) - struct partime const *pt; - time_t default_time; -{ - int localzone, wday; - struct tm tm; - struct tm *tm0 = 0; - time_t r; - - tm0 = 0; /* Keep gcc -Wall happy. */ - localzone = pt->zone==TM_LOCAL_ZONE; - - tm = pt->tm; - - if (TM_DEFINED(pt->ymodulus) || !TM_DEFINED(tm.tm_year)) { - /* Get tm corresponding to current time. */ - tm0 = time2tm(default_time, localzone); - if (!localzone) - adjzone(tm0, pt->zone); - } - - if (TM_DEFINED(pt->ymodulus)) - tm.tm_year += - (tm0->tm_year + TM_YEAR_ORIGIN)/pt->ymodulus * pt->ymodulus; - else if (!TM_DEFINED(tm.tm_year)) { - /* Set default year, month, day from current time. */ - tm.tm_year = tm0->tm_year + TM_YEAR_ORIGIN; - if (!TM_DEFINED(tm.tm_mon)) { - tm.tm_mon = tm0->tm_mon; - if (!TM_DEFINED(tm.tm_mday)) - tm.tm_mday = tm0->tm_mday; - } - } - - /* Convert from partime year (Gregorian) to Posix year. */ - tm.tm_year -= TM_YEAR_ORIGIN; - - /* Set remaining default fields to be their minimum values. */ - if (!TM_DEFINED(tm.tm_mon)) tm.tm_mon = 0; - if (!TM_DEFINED(tm.tm_mday)) tm.tm_mday = 1; - if (!TM_DEFINED(tm.tm_hour)) tm.tm_hour = 0; - if (!TM_DEFINED(tm.tm_min)) tm.tm_min = 0; - if (!TM_DEFINED(tm.tm_sec)) tm.tm_sec = 0; - - if (!localzone) - adjzone(&tm, -pt->zone); - wday = tm.tm_wday; - - /* Convert and fill in the rest of the tm. */ - r = tm2time(&tm, localzone); - - /* Check weekday. */ - if (r != -1 && TM_DEFINED(wday) && wday != tm.tm_wday) - return -1; - - return r; -} - -/* Parse a free-format date in SOURCE, yielding a Unix format time. */ - time_t -str2time(source, default_time, default_zone) - char const *source; - time_t default_time; - long default_zone; -{ - struct partime pt; - - if (*partime(source, &pt)) - return -1; - if (pt.zone == TM_UNDEFINED_ZONE) - pt.zone = default_zone; - return maketime(&pt, default_time); -} - -#if TEST -#include - int -main(argc, argv) int argc; char **argv; -{ - time_t default_time = time((time_t *)0); - long default_zone = argv[1] ? atol(argv[1]) : 0; - char buf[1000]; - while (fgets(buf, 1000, stdin)) { - time_t t = str2time(buf, default_time, default_zone); - printf("%s", asctime(gmtime(&t))); - } - return 0; -} -#endif diff --git a/gnu/usr.bin/rcs/lib/maketime.h b/gnu/usr.bin/rcs/lib/maketime.h deleted file mode 100644 index fbe12562051d..000000000000 --- a/gnu/usr.bin/rcs/lib/maketime.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Yield time_t from struct partime yielded by partime. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if defined(__STDC__) || has_prototypes -# define __MAKETIME_P(x) x -#else -# define __MAKETIME_P(x) () -#endif - -struct tm *time2tm __MAKETIME_P((time_t,int)); -time_t difftm __MAKETIME_P((struct tm const *, struct tm const *)); -time_t str2time __MAKETIME_P((char const *, time_t, long)); -time_t tm2time __MAKETIME_P((struct tm *, int)); -void adjzone __MAKETIME_P((struct tm *, long)); diff --git a/gnu/usr.bin/rcs/lib/merger.c b/gnu/usr.bin/rcs/lib/merger.c deleted file mode 100644 index 8f1d610d5f56..000000000000 --- a/gnu/usr.bin/rcs/lib/merger.c +++ /dev/null @@ -1,148 +0,0 @@ -/* three-way file merge internals */ - -/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -libId(mergerId, "$FreeBSD$") - - static char const *normalize_arg P((char const*,char**)); - static char const * -normalize_arg(s, b) - char const *s; - char **b; -/* - * If S looks like an option, prepend ./ to it. Yield the result. - * Set *B to the address of any storage that was allocated. - */ -{ - char *t; - if (*s == '-') { - *b = t = testalloc(strlen(s) + 3); - VOID sprintf(t, ".%c%s", SLASH, s); - return t; - } else { - *b = 0; - return s; - } -} - - int -merge(tostdout, edarg, label, argv) - int tostdout; - char const *edarg; - char const *const label[3]; - char const *const argv[3]; -/* - * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2', - * where TOSTDOUT specifies whether -p is present, - * EDARG gives the editing type (e.g. "-A", or null for the default), - * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2. - * Yield DIFF_SUCCESS or DIFF_FAILURE. - */ -{ - register int i; - FILE *f; - RILE *rt; - char const *a[3], *t; - char *b[3]; - int s; -#if !DIFF3_BIN - char const *d[2]; -#endif - - for (i=3; 0<=--i; ) - a[i] = normalize_arg(argv[i], &b[i]); - - if (!edarg) - edarg = "-E"; - -#if DIFF3_BIN - t = 0; - if (!tostdout) - t = maketemp(0); - s = run( - -1, t, - DIFF3, edarg, "-am", - "-L", label[0], - "-L", label[1], - "-L", label[2], - a[0], a[1], a[2], (char*)0 - ); - switch (s) { - case DIFF_SUCCESS: - break; - case DIFF_FAILURE: - warn("conflicts during merge"); - break; - default: - exiterr(); - } - if (t) { - if (!(f = fopenSafer(argv[0], "w"))) - efaterror(argv[0]); - if (!(rt = Iopen(t, "r", (struct stat*)0))) - efaterror(t); - fastcopy(rt, f); - Ifclose(rt); - Ofclose(f); - } -#else - for (i=0; i<2; i++) - switch (run( - -1, d[i]=maketemp(i), - DIFF, a[i], a[2], (char*)0 - )) { - case DIFF_FAILURE: case DIFF_SUCCESS: break; - default: faterror("diff failed"); - } - t = maketemp(2); - s = run( - -1, t, - DIFF3, edarg, d[0], d[1], a[0], a[1], a[2], - label[0], label[2], (char*)0 - ); - if (s != DIFF_SUCCESS) { - s = DIFF_FAILURE; - warn("overlaps or other problems during merge"); - } - if (!(f = fopenSafer(t, "a+"))) - efaterror(t); - aputs(tostdout ? "1,$p\n" : "w\n", f); - Orewind(f); - aflush(f); - if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0)) - exiterr(); - Ofclose(f); -#endif - - tempunlink(); - for (i=3; 0<=--i; ) - if (b[i]) - tfree(b[i]); - return s; -} diff --git a/gnu/usr.bin/rcs/lib/partime.c b/gnu/usr.bin/rcs/lib/partime.c deleted file mode 100644 index 05b010854950..000000000000 --- a/gnu/usr.bin/rcs/lib/partime.c +++ /dev/null @@ -1,701 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#if has_conf_h -# include "conf.h" -#else -# ifdef __STDC__ -# define P(x) x -# else -# define const -# define P(x) () -# endif -# include -# include -#endif - -#include -#undef isdigit -#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than stock */ - -#include "partime.h" - -char const partimeId[] - = "$FreeBSD$"; - - -/* Lookup tables for names of months, weekdays, time zones. */ - -#define NAME_LENGTH_MAXIMUM 4 - -struct name_val { - char name[NAME_LENGTH_MAXIMUM]; - int val; -}; - - -static char const *parse_decimal P((char const*,int,int,int,int,int*,int*)); -static char const *parse_fixed P((char const*,int,int*)); -static char const *parse_pattern_letter P((char const*,int,struct partime*)); -static char const *parse_prefix P((char const*,struct partime*,int*)); -static char const *parse_ranged P((char const*,int,int,int,int*)); -static int lookup P((char const*,struct name_val const[])); -static int merge_partime P((struct partime*, struct partime const*)); -static void undefine P((struct partime*)); - - -static struct name_val const month_names[] = { - {"jan",0}, {"feb",1}, {"mar",2}, {"apr",3}, {"may",4}, {"jun",5}, - {"jul",6}, {"aug",7}, {"sep",8}, {"oct",9}, {"nov",10}, {"dec",11}, - {"", TM_UNDEFINED} -}; - -static struct name_val const weekday_names[] = { - {"sun",0}, {"mon",1}, {"tue",2}, {"wed",3}, {"thu",4}, {"fri",5}, {"sat",6}, - {"", TM_UNDEFINED} -}; - -#define hr60nonnegative(t) ((t)/100 * 60 + (t)%100) -#define hr60(t) ((t)<0 ? -hr60nonnegative(-(t)) : hr60nonnegative(t)) -#define zs(t,s) {s, hr60(t)} -#define zd(t,s,d) zs(t, s), zs((t)+100, d) - -static struct name_val const zone_names[] = { - zs(-1000, "hst"), /* Hawaii */ - zd(-1000,"hast","hadt"),/* Hawaii-Aleutian */ - zd(- 900,"akst","akdt"),/* Alaska */ - zd(- 800, "pst", "pdt"),/* Pacific */ - zd(- 700, "mst", "mdt"),/* Mountain */ - zd(- 600, "cst", "cdt"),/* Central */ - zd(- 500, "est", "edt"),/* Eastern */ - zd(- 400, "ast", "adt"),/* Atlantic */ - zd(- 330, "nst", "ndt"),/* Newfoundland */ - zs( 000, "utc"), /* Coordinated Universal */ - zs( 000, "cut"), /* " */ - zs( 000, "ut"), /* Universal */ - zs( 000, "z"), /* Zulu (required by ISO 8601) */ - zd( 000, "gmt", "bst"),/* Greenwich Mean, British Summer */ - zs( 000, "wet"), /* Western Europe */ - zs( 100, "met"), /* Middle Europe */ - zs( 100, "cet"), /* Central Europe */ - zs( 200, "eet"), /* Eastern Europe */ - zs( 530, "ist"), /* India */ - zd( 900, "jst", "jdt"),/* Japan */ - zd( 900, "kst", "kdt"),/* Korea */ - zd( 1200,"nzst","nzdt"),/* New Zealand */ - { "lt", 1 }, -#if 0 - /* The following names are duplicates or are not well attested. */ - zs(-1100, "sst"), /* Samoa */ - zs(-1000, "tht"), /* Tahiti */ - zs(- 930, "mqt"), /* Marquesas */ - zs(- 900, "gbt"), /* Gambier */ - zd(- 900, "yst", "ydt"),/* Yukon - name is no longer used */ - zs(- 830, "pit"), /* Pitcairn */ - zd(- 500, "cst", "cdt"),/* Cuba */ - zd(- 500, "ast", "adt"),/* Acre */ - zd(- 400, "wst", "wdt"),/* Western Brazil */ - zd(- 400, "ast", "adt"),/* Andes */ - zd(- 400, "cst", "cdt"),/* Chile */ - zs(- 300, "wgt"), /* Western Greenland */ - zd(- 300, "est", "edt"),/* Eastern South America */ - zs(- 300, "mgt"), /* Middle Greenland */ - zd(- 200, "fst", "fdt"),/* Fernando de Noronha */ - zs(- 100, "egt"), /* Eastern Greenland */ - zs(- 100, "aat"), /* Atlantic Africa */ - zs(- 100, "act"), /* Azores and Canaries */ - zs( 000, "wat"), /* West Africa */ - zs( 100, "cat"), /* Central Africa */ - zd( 100, "mez","mesz"),/* Mittel-Europaeische Zeit */ - zs( 200, "sat"), /* South Africa */ - zd( 200, "ist", "idt"),/* Israel */ - zs( 300, "eat"), /* East Africa */ - zd( 300, "ast", "adt"),/* Arabia */ - zd( 300, "msk", "msd"),/* Moscow */ - zd( 330, "ist", "idt"),/* Iran */ - zs( 400, "gst"), /* Gulf */ - zs( 400, "smt"), /* Seychelles & Mascarene */ - zd( 400, "esk", "esd"),/* Yekaterinburg */ - zd( 400, "bsk", "bsd"),/* Baku */ - zs( 430, "aft"), /* Afghanistan */ - zd( 500, "osk", "osd"),/* Omsk */ - zs( 500, "pkt"), /* Pakistan */ - zd( 500, "tsk", "tsd"),/* Tashkent */ - zs( 545, "npt"), /* Nepal */ - zs( 600, "bgt"), /* Bangladesh */ - zd( 600, "nsk", "nsd"),/* Novosibirsk */ - zs( 630, "bmt"), /* Burma */ - zs( 630, "cct"), /* Cocos */ - zs( 700, "ict"), /* Indochina */ - zs( 700, "jvt"), /* Java */ - zd( 700, "isk", "isd"),/* Irkutsk */ - zs( 800, "hkt"), /* Hong Kong */ - zs( 800, "pst"), /* Philippines */ - zs( 800, "sgt"), /* Singapore */ - zd( 800, "cst", "cdt"),/* China */ - zd( 800, "ust", "udt"),/* Ulan Bator */ - zd( 800, "wst", "wst"),/* Western Australia */ - zd( 800, "ysk", "ysd"),/* Yakutsk */ - zs( 900, "blt"), /* Belau */ - zs( 900, "mlt"), /* Moluccas */ - zd( 900, "vsk", "vsd"),/* Vladivostok */ - zd( 930, "cst", "cst"),/* Central Australia */ - zs( 1000, "gst"), /* Guam */ - zd( 1000, "gsk", "gsd"),/* Magadan */ - zd( 1000, "est", "est"),/* Eastern Australia */ - zd( 1100,"lhst","lhst"),/* Lord Howe */ - zd( 1100, "psk", "psd"),/* Petropavlovsk-Kamchatski */ - zs( 1100,"ncst"), /* New Caledonia */ - zs( 1130,"nrft"), /* Norfolk */ - zd( 1200, "ask", "asd"),/* Anadyr */ - zs( 1245,"nz-chat"), /* Chatham */ - zs( 1300, "tgt"), /* Tongatapu */ -#endif - {"", -1} -}; - - static int -lookup (s, table) - char const *s; - struct name_val const table[]; -/* Look for a prefix of S in TABLE, returning val for first matching entry. */ -{ - int j; - char buf[NAME_LENGTH_MAXIMUM]; - - for (j = 0; j < NAME_LENGTH_MAXIMUM; j++) { - unsigned char c = *s++; - buf[j] = isupper (c) ? tolower (c) : c; - if (!isalpha (c)) - break; - } - for (; table[0].name[0]; table++) - for (j = 0; buf[j] == table[0].name[j]; ) - if (++j == NAME_LENGTH_MAXIMUM || !table[0].name[j]) - goto done; - done: - return table[0].val; -} - - - static void -undefine (t) struct partime *t; -/* Set *T to ``undefined'' values. */ -{ - t->tm.tm_sec = t->tm.tm_min = t->tm.tm_hour = t->tm.tm_mday = t->tm.tm_mon - = t->tm.tm_year = t->tm.tm_wday = t->tm.tm_yday - = t->ymodulus = t->yweek - = TM_UNDEFINED; - t->zone = TM_UNDEFINED_ZONE; -} - -/* -* Array of patterns to look for in a date string. -* Order is important: we look for the first matching pattern -* whose values do not contradict values that we already know about. -* See `parse_pattern_letter' below for the meaning of the pattern codes. -*/ -static char const * const patterns[] = { - /* - * These traditional patterns must come first, - * to prevent an ISO 8601 format from misinterpreting their prefixes. - */ - "E_n_y", "x", /* RFC 822 */ - "E_n", "n_E", "n", "t:m:s_A", "t:m_A", "t_A", /* traditional */ - "y/N/D$", /* traditional RCS */ - - /* ISO 8601:1988 formats, generalized a bit. */ - "y-N-D$", "4ND$", "Y-N$", - "RND$", "-R=N$", "-R$", "--N=D$", "N=DT", - "--N$", "---D$", "DT", - "Y-d$", "4d$", "R=d$", "-d$", "dT", - "y-W-X", "yWX", "y=W", - "-r-W-X", "r-W-XT", "-rWX", "rWXT", "-W=X", "W=XT", "-W", - "-w-X", "w-XT", "---X$", "XT", "4$", - "T", - "h:m:s$", "hms$", "h:m$", "hm$", "h$", "-m:s$", "-ms$", "-m$", "--s$", - "Y", "Z", - - 0 -}; - - static char const * -parse_prefix (str, t, pi) char const *str; struct partime *t; int *pi; -/* -* Parse an initial prefix of STR, setting *T accordingly. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -* Start with pattern *PI; if success, set *PI to the next pattern to try. -* Set *PI to -1 if we know there are no more patterns to try; -* if *PI is initially negative, give up immediately. -*/ -{ - int i = *pi; - char const *pat; - unsigned char c; - - if (i < 0) - return 0; - - /* Remove initial noise. */ - while (!isalnum (c = *str) && c != '-' && c != '+') { - if (!c) { - undefine (t); - *pi = -1; - return str; - } - str++; - } - - /* Try a pattern until one succeeds. */ - while ((pat = patterns[i++]) != 0) { - char const *s = str; - undefine (t); - do { - if (!(c = *pat++)) { - *pi = i; - return s; - } - } while ((s = parse_pattern_letter (s, c, t)) != 0); - } - - return 0; -} - - static char const * -parse_fixed (s, digits, res) char const *s; int digits, *res; -/* -* Parse an initial prefix of S of length DIGITS; it must be a number. -* Store the parsed number into *RES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - int n = 0; - char const *lim = s + digits; - while (s < lim) { - unsigned d = *s++ - '0'; - if (9 < d) - return 0; - n = 10*n + d; - } - *res = n; - return s; -} - - static char const * -parse_ranged (s, digits, lo, hi, res) char const *s; int digits, lo, hi, *res; -/* -* Parse an initial prefix of S of length DIGITS; -* it must be a number in the range LO through HI. -* Store the parsed number into *RES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - s = parse_fixed (s, digits, res); - return s && lo<=*res && *res<=hi ? s : 0; -} - - static char const * -parse_decimal (s, digits, lo, hi, resolution, res, fres) - char const *s; - int digits, lo, hi, resolution, *res, *fres; -/* -* Parse an initial prefix of S of length DIGITS; -* it must be a number in the range LO through HI -* and it may be followed by a fraction that is to be computed using RESOLUTION. -* Store the parsed number into *RES; store the fraction times RESOLUTION, -* rounded to the nearest integer, into *FRES. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - s = parse_fixed (s, digits, res); - if (s && lo<=*res && *res<=hi) { - int f = 0; - if ((s[0]==',' || s[0]=='.') && isdigit ((unsigned char) s[1])) { - char const *s1 = ++s; - int num10 = 0, denom10 = 10, product; - while (isdigit ((unsigned char) *++s)) - denom10 *= 10; - s = parse_fixed (s1, s - s1, &num10); - product = num10*resolution; - f = (product + (denom10>>1)) / denom10; - f -= f & (product%denom10 == denom10>>1); /* round to even */ - if (f < 0 || product/resolution != num10) - return 0; /* overflow */ - } - *fres = f; - return s; - } - return 0; -} - - char * -parzone (s, zone) char const *s; long *zone; -/* -* Parse an initial prefix of S; it must denote a time zone. -* Set *ZONE to the number of seconds east of GMT, -* or to TM_LOCAL_ZONE if it is the local time zone. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - char sign; - int hh, mm, ss; - int minutesEastOfUTC; - long offset, z; - - /* - * The formats are LT, n, n DST, nDST, no, o - * where n is a time zone name - * and o is a time zone offset of the form [-+]hh[:mm[:ss]]. - */ - switch (*s) { - case '-': case '+': - z = 0; - break; - - default: - minutesEastOfUTC = lookup (s, zone_names); - if (minutesEastOfUTC == -1) - return 0; - - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - - /* Don't modify LT. */ - if (minutesEastOfUTC == 1) { - *zone = TM_LOCAL_ZONE; - return (char *) s; - } - - z = minutesEastOfUTC * 60L; - - /* Look for trailing " DST". */ - if ( - (s[-1]=='T' || s[-1]=='t') && - (s[-2]=='S' || s[-2]=='s') && - (s[-3]=='D' || s[-3]=='t') - ) - goto trailing_dst; - while (isspace ((unsigned char) *s)) - s++; - if ( - (s[0]=='D' || s[0]=='d') && - (s[1]=='S' || s[1]=='s') && - (s[2]=='T' || s[2]=='t') - ) { - s += 3; - trailing_dst: - *zone = z + 60*60; - return (char *) s; - } - - switch (*s) { - case '-': case '+': break; - default: return (char *) s; - } - } - sign = *s++; - - if (!(s = parse_ranged (s, 2, 0, 23, &hh))) - return 0; - mm = ss = 0; - if (*s == ':') - s++; - if (isdigit ((unsigned char) *s)) { - if (!(s = parse_ranged (s, 2, 0, 59, &mm))) - return 0; - if (*s==':' && s[-3]==':' && isdigit ((unsigned char) s[1])) { - if (!(s = parse_ranged (s + 1, 2, 0, 59, &ss))) - return 0; - } - } - if (isdigit ((unsigned char) *s)) - return 0; - offset = (hh*60 + mm)*60L + ss; - *zone = z + (sign=='-' ? -offset : offset); - /* - * ?? Are fractions allowed here? - * If so, they're not implemented. - */ - return (char *) s; -} - - static char const * -parse_pattern_letter (s, c, t) char const *s; int c; struct partime *t; -/* -* Parse an initial prefix of S, matching the pattern whose code is C. -* Set *T accordingly. -* Return the first character after the prefix, or 0 if it couldn't be parsed. -*/ -{ - switch (c) { - case '$': /* The next character must be a non-digit. */ - if (isdigit ((unsigned char) *s)) - return 0; - break; - - case '-': case '/': case ':': - /* These characters stand for themselves. */ - if (*s++ != c) - return 0; - break; - - case '4': /* 4-digit year */ - s = parse_fixed (s, 4, &t->tm.tm_year); - break; - - case '=': /* optional '-' */ - s += *s == '-'; - break; - - case 'A': /* AM or PM */ - /* - * This matches the regular expression [AaPp][Mm]?. - * It must not be followed by a letter or digit; - * otherwise it would match prefixes of strings like "PST". - */ - switch (*s++) { - case 'A': case 'a': - if (t->tm.tm_hour == 12) - t->tm.tm_hour = 0; - break; - - case 'P': case 'p': - if (t->tm.tm_hour != 12) - t->tm.tm_hour += 12; - break; - - default: return 0; - } - switch (*s) { - case 'M': case 'm': s++; break; - } - if (isalnum (*s)) - return 0; - break; - - case 'D': /* day of month [01-31] */ - s = parse_ranged (s, 2, 1, 31, &t->tm.tm_mday); - break; - - case 'd': /* day of year [001-366] */ - s = parse_ranged (s, 3, 1, 366, &t->tm.tm_yday); - t->tm.tm_yday--; - break; - - case 'E': /* extended day of month [1-9, 01-31] */ - s = parse_ranged (s, ( - isdigit ((unsigned char) s[0]) && - isdigit ((unsigned char) s[1]) - ) + 1, 1, 31, &t->tm.tm_mday); - break; - - case 'h': /* hour [00-23 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 23, 60*60, &t->tm.tm_hour, &frac); - t->tm.tm_min = frac / 60; - t->tm.tm_sec = frac % 60; - } - break; - - case 'm': /* minute [00-59 followed by optional fraction] */ - s = parse_decimal (s, 2, 0, 59, 60, &t->tm.tm_min, &t->tm.tm_sec); - break; - - case 'n': /* month name [e.g. "Jan"] */ - if (!TM_DEFINED (t->tm.tm_mon = lookup (s, month_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - break; - - case 'N': /* month [01-12] */ - s = parse_ranged (s, 2, 1, 12, &t->tm.tm_mon); - t->tm.tm_mon--; - break; - - case 'r': /* year % 10 (remainder in origin-0 decade) [0-9] */ - s = parse_fixed (s, 1, &t->tm.tm_year); - t->ymodulus = 10; - break; - - case_R: - case 'R': /* year % 100 (remainder in origin-0 century) [00-99] */ - s = parse_fixed (s, 2, &t->tm.tm_year); - t->ymodulus = 100; - break; - - case 's': /* second [00-60 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 60, 1, &t->tm.tm_sec, &frac); - t->tm.tm_sec += frac; - } - break; - - case 'T': /* 'T' or 't' */ - switch (*s++) { - case 'T': case 't': break; - default: return 0; - } - break; - - case 't': /* traditional hour [1-9 or 01-12] */ - s = parse_ranged (s, ( - isdigit ((unsigned char) s[0]) && isdigit ((unsigned char) s[1]) - ) + 1, 1, 12, &t->tm.tm_hour); - break; - - case 'w': /* 'W' or 'w' only (stands for current week) */ - switch (*s++) { - case 'W': case 'w': break; - default: return 0; - } - break; - - case 'W': /* 'W' or 'w', followed by a week of year [00-53] */ - switch (*s++) { - case 'W': case 'w': break; - default: return 0; - } - s = parse_ranged (s, 2, 0, 53, &t->yweek); - break; - - case 'X': /* weekday (1=Mon ... 7=Sun) [1-7] */ - s = parse_ranged (s, 1, 1, 7, &t->tm.tm_wday); - t->tm.tm_wday--; - break; - - case 'x': /* weekday name [e.g. "Sun"] */ - if (!TM_DEFINED (t->tm.tm_wday = lookup (s, weekday_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (isalpha ((unsigned char) *s)) - s++; - break; - - case 'y': /* either R or Y */ - if ( - isdigit ((unsigned char) s[0]) && - isdigit ((unsigned char) s[1]) && - !isdigit ((unsigned char) s[2]) - ) - goto case_R; - /* fall into */ - case 'Y': /* year in full [4 or more digits] */ - { - int len = 0; - while (isdigit ((unsigned char) s[len])) - len++; - if (len < 4) - return 0; - s = parse_fixed (s, len, &t->tm.tm_year); - } - break; - - case 'Z': /* time zone */ - s = parzone (s, &t->zone); - break; - - case '_': /* possibly empty sequence of non-alphanumerics */ - while (!isalnum (*s) && *s) - s++; - break; - - default: /* bad pattern */ - return 0; - } - return s; -} - - static int -merge_partime (t, u) struct partime *t; struct partime const *u; -/* -* If there is no conflict, merge into *T the additional information in *U -* and return 0. Otherwise do nothing and return -1. -*/ -{ -# define conflict(a,b) ((a) != (b) && TM_DEFINED (a) && TM_DEFINED (b)) - if ( - conflict (t->tm.tm_sec, u->tm.tm_sec) || - conflict (t->tm.tm_min, u->tm.tm_min) || - conflict (t->tm.tm_hour, u->tm.tm_hour) || - conflict (t->tm.tm_mday, u->tm.tm_mday) || - conflict (t->tm.tm_mon, u->tm.tm_mon) || - conflict (t->tm.tm_year, u->tm.tm_year) || - conflict (t->tm.tm_wday, u->tm.tm_yday) || - conflict (t->ymodulus, u->ymodulus) || - conflict (t->yweek, u->yweek) || - ( - t->zone != u->zone && - t->zone != TM_UNDEFINED_ZONE && - u->zone != TM_UNDEFINED_ZONE - ) - ) - return -1; -# undef conflict -# define merge_(a,b) if (TM_DEFINED (b)) (a) = (b); - merge_ (t->tm.tm_sec, u->tm.tm_sec) - merge_ (t->tm.tm_min, u->tm.tm_min) - merge_ (t->tm.tm_hour, u->tm.tm_hour) - merge_ (t->tm.tm_mday, u->tm.tm_mday) - merge_ (t->tm.tm_mon, u->tm.tm_mon) - merge_ (t->tm.tm_year, u->tm.tm_year) - merge_ (t->tm.tm_wday, u->tm.tm_yday) - merge_ (t->ymodulus, u->ymodulus) - merge_ (t->yweek, u->yweek) -# undef merge_ - if (u->zone != TM_UNDEFINED_ZONE) t->zone = u->zone; - return 0; -} - - char * -partime (s, t) char const *s; struct partime *t; -/* -* Parse a date/time prefix of S, putting the parsed result into *T. -* Return the first character after the prefix. -* The prefix may contain no useful information; -* in that case, *T will contain only undefined values. -*/ -{ - struct partime p; - - undefine (t); - while (*s) { - int i = 0; - char const *s1; - do { - if (!(s1 = parse_prefix (s, &p, &i))) - return (char *) s; - } while (merge_partime (t, &p) != 0); - s = s1; - } - return (char *) s; -} diff --git a/gnu/usr.bin/rcs/lib/partime.h b/gnu/usr.bin/rcs/lib/partime.h deleted file mode 100644 index 5d3983fbb048..000000000000 --- a/gnu/usr.bin/rcs/lib/partime.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#define TM_UNDEFINED (-1) -#define TM_DEFINED(x) (0 <= (x)) - -#define TM_UNDEFINED_ZONE ((long) -24 * 60 * 60) -#define TM_LOCAL_ZONE (TM_UNDEFINED_ZONE - 1) - -struct partime { - /* - * This structure describes the parsed time. - * Only the following tm_* values in it are used: - * sec, min, hour, mday, mon, year, wday, yday. - * If TM_UNDEFINED(value), the parser never found the value. - * The tm_year field is the actual year, not the year - 1900; - * but see ymodulus below. - */ - struct tm tm; - - /* - * If !TM_UNDEFINED(ymodulus), - * then tm.tm_year is actually modulo ymodulus. - */ - int ymodulus; - - /* - * Week of year, ISO 8601 style. - * If TM_UNDEFINED(yweek), the parser never found yweek. - * Weeks start on Mondays. - * Week 1 includes Jan 4. - */ - int yweek; - - /* Seconds east of UTC; or TM_LOCAL_ZONE or TM_UNDEFINED_ZONE. */ - long zone; -}; - -#if defined(__STDC__) || has_prototypes -# define __PARTIME_P(x) x -#else -# define __PARTIME_P(x) () -#endif - -char *partime __PARTIME_P((char const *, struct partime *)); -char *parzone __PARTIME_P((char const *, long *)); diff --git a/gnu/usr.bin/rcs/lib/rcsbase.h b/gnu/usr.bin/rcs/lib/rcsbase.h deleted file mode 100644 index 9f2f68cc8b6b..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsbase.h +++ /dev/null @@ -1,762 +0,0 @@ -/* RCS common definitions and data structures */ - -#define RCSBASE "$FreeBSD$" - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.20 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.19 1995/06/01 16:23:43 eggert - * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring. - * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros. - * (maps_memory): New macro; replaces many instances of `has_mmap'. - * (cacheptr): Renamed from cachetell. - * (struct RILE): New alternate name for RILE; the type is now recursive. - * (deallocate): New member for RILE, used for generic buffer deallocation. - * (cacheunget_): No longer take a failure arg; just call Ierror on failure. - * (struct rcslock): Renamed from struct lock, to avoid collisions with - * system headers on some hosts. All users changed. - * (basefilename): Renamed from basename, likewise. - * (dirtpname): Remove; no longer external. - * (dirlen, dateform): Remove; no longer used. - * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions. - * (zonelenmax): Increase to 9 for full ISO 8601 format. - * (catchmmapints): Depend on has_NFS. - * - * Revision 5.18 1994/03/17 14:05:48 eggert - * Add primitives for reading backwards from a RILE; - * this is needed to go back and find the $Log prefix. - * Specify subprocess input via file descriptor, not file name. Remove lint. - * - * Revision 5.17 1993/11/09 17:40:15 eggert - * Move RCS-specific time handling into rcstime.c. - * printf_string now takes two arguments, alas. - * - * Revision 5.16 1993/11/03 17:42:27 eggert - * Don't arbitrarily limit the number of joins. Remove `nil'. - * Add Name keyword. Don't discard ignored phrases. - * Add support for merge -A vs -E, and allow up to three labels. - * Improve quality of diagnostics and prototypes. - * - * Revision 5.15 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.14 1992/02/17 23:02:22 eggert - * Add -T support. Work around NFS mmap SIGBUS problem. - * - * Revision 5.13 1992/01/24 18:44:19 eggert - * Add support for bad_creat0. lint -> RCS_lint - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * while (E) ; -> while (E) continue; - * - * Revision 5.11 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.10 1991/09/24 00:28:39 eggert - * Remove unexported functions. - * - * Revision 5.9 1991/08/19 03:13:55 eggert - * Add piece tables and other tuneups, and NFS workarounds. - * - * Revision 5.8 1991/04/21 11:58:20 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.7 1991/02/28 19:18:50 eggert - * Try setuid() if seteuid() doesn't work. - * - * Revision 5.6 1991/02/26 17:48:37 eggert - * Support new link behavior. Move ANSI C / Posix declarations into conf.sh. - * - * Revision 5.5 1990/12/04 05:18:43 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:35 eggert - * Don't assume that builtins are functions; they may be macros. - * Permit arbitrary data in logs. - * - * Revision 5.3 1990/09/26 23:36:58 eggert - * Port wait() to non-Posix ANSI C hosts. - * - * Revision 5.2 1990/09/04 08:02:20 eggert - * Don't redefine NAME_MAX, PATH_MAX. - * Improve incomplete line handling. Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:13:53 eggert - * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:44 eggert - * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access(). - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. Add support for ISO 8859. - * Remove snoop and v2 support. - * - * Revision 4.9 89/05/01 15:17:14 narten - * botched previous USG fix - * - * Revision 4.8 89/05/01 14:53:05 narten - * changed #include -> string.h for USG systems. - * - * Revision 4.7 88/11/08 15:58:45 narten - * removed defs for functions loaded from libraries - * - * Revision 4.6 88/08/09 19:12:36 eggert - * Shrink stdio code size; remove lint; permit -Dhshsize=nn. - * - * Revision 4.5 87/12/18 17:06:41 narten - * made removed BSD ifdef, now uses V4_2BSD - * - * Revision 4.4 87/10/18 10:29:49 narten - * Updating version numbers - * Changes relative to 1.1 are actually relative to 4.2 - * - * Revision 1.3 87/09/24 14:02:25 narten - * changes for lint - * - * Revision 1.2 87/03/27 14:22:02 jenkins - * Port to suns - * - * Revision 4.2 83/12/20 16:04:20 wft - * merged 3.6.1.1 and 4.1 (SMALLOG, logsize). - * moved setting of STRICT_LOCKING to Makefile. - * changed DOLLAR to UNKN (conflict with KDELIM). - * - * Revision 4.1 83/05/04 09:12:41 wft - * Added markers Id and RCSfile. - * Added Dbranch for default branches. - * - * Revision 3.6.1.1 83/12/02 21:56:22 wft - * Increased logsize, added macro SMALLOG. - * - * Revision 3.6 83/01/15 16:43:28 wft - * 4.2 prerelease - * - * Revision 3.6 83/01/15 16:43:28 wft - * Replaced dbm.h with BYTESIZ, fixed definition of rindex(). - * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD. - * Added macro DELNUMFORM to have uniform format for printing delta text nodes. - * Added macro DELETE to mark deleted deltas. - * - * Revision 3.5 82/12/10 12:16:56 wft - * Added two forms of DATEFORM, one using %02d, the other %.2d. - * - * Revision 3.4 82/12/04 20:01:25 wft - * added LOCKER, Locker, and USG (redefinition of rindex). - * - * Revision 3.3 82/12/03 12:22:04 wft - * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3, - * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength - * using NCPPN. Changed putc() to abort on write error. - * - * Revision 3.2 82/10/18 15:03:52 wft - * added macro STRICT_LOCKING, removed RCSUMASK. - * renamed JOINFILE[1,2] to JOINFIL[1,2]. - * - * Revision 3.1 82/10/11 19:41:17 wft - * removed NBPW, NBPC, NCPW. - * added typdef int void to aid compiling - */ - - -#include "conf.h" - - -#define EXIT_TROUBLE DIFF_TROUBLE - -#ifdef _POSIX_PATH_MAX -# define SIZEABLE_PATH _POSIX_PATH_MAX -#else -# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */ -#endif - -/* for traditional C hosts with unusual size arguments */ -#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f) -#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f) - - -/* - * Parameters - */ - -/* backwards compatibility with old versions of RCS */ -#define VERSION_min 3 /* old output RCS format supported */ -#define VERSION_max 5 /* newest output RCS format supported */ -#ifndef VERSION_DEFAULT /* default RCS output format */ -# define VERSION_DEFAULT VERSION_max -#endif -#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */ - -#ifndef STRICT_LOCKING -#define STRICT_LOCKING 1 -#endif - /* 0 sets the default locking to non-strict; */ - /* used in experimental environments. */ - /* 1 sets the default locking to strict; */ - /* used in production environments. */ - -#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */ -#define datesize (yearlength+16) /* size of output of time2date */ -#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */ -#define KDELIM '$' /* delimiter for keywords */ -#define VDELIM ':' /* separates keywords from values */ -#define DEFAULTSTATE "Exp" /* default state of revisions */ - - - -#define true 1 -#define false 0 - - -/* - * RILE - readonly file - * declarecache; - declares local cache for RILE variable(s) - * setupcache - sets up the local RILE cache, but does not initialize it - * cache, uncache - caches and uncaches the local RILE; - * (uncache,cache) is needed around functions that advance the RILE pointer - * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF - * cachegeteof_(c,s) - Igeteof_ applied to the local RILE - * Iget_(f,c) - like Igeteof_, except EOF is an error - * cacheget_(c) - Iget_ applied to the local RILE - * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF - * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines - * - * By conventions, macros whose names end in _ are statements, not expressions. - * Following such macros with `; else' results in a syntax error. - */ - -#define maps_memory (has_map_fd || has_mmap) - -#if large_memory - typedef unsigned char const *Iptr_type; - typedef struct RILE { - Iptr_type ptr, lim; - unsigned char *base; /* not Iptr_type for lint's sake */ - unsigned char *readlim; - int fd; -# if maps_memory - void (*deallocate) P((struct RILE *)); -# else - FILE *stream; -# endif - } RILE; -# if maps_memory -# define declarecache register Iptr_type ptr, lim -# define setupcache(f) (lim = (f)->lim) -# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++; -# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++; -# else - int Igetmore P((RILE*)); -# define declarecache register Iptr_type ptr; register RILE *rRILE -# define setupcache(f) (rRILE = (f)) -# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++; -# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++; -# endif -# define uncache(f) ((f)->ptr = ptr) -# define cache(f) (ptr = (f)->ptr) -# define Iget_(f,c) Igeteof_(f,c,Ieof();) -# define cacheget_(c) cachegeteof_(c,Ieof();) -# define cacheunget_(f,c) (c)=(--ptr)[-1]; -# define Ioffset_type size_t -# define Itell(f) ((f)->ptr - (f)->base) -# define Irewind(f) ((f)->ptr = (f)->base) -# define cacheptr() ptr -# define Ifileno(f) ((f)->fd) -#else -# define RILE FILE -# define declarecache register FILE *ptr -# define setupcache(f) (ptr = (f)) -# define uncache(f) -# define cache(f) -# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}} -# define cachegeteof_(c,s) Igeteof_(ptr,c,s) -# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); } -# define cacheget_(c) Iget_(ptr,c) -# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c) -# define Ioffset_type long -# define Itell(f) ftell(f) -# define Ifileno(f) fileno(f) -#endif - -/* Print a char, but abort on write error. */ -#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); } - -/* Get a character from an RCS file, perhaps copying to a new RCS file. */ -#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) } -#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) } - - -#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0)) -/* computes mode of working file: same as RCSmode, but write permission */ -/* determined by writable */ - - -/* character classes and token codes */ -enum tokens { -/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter, - PERIOD, SBEGIN, SPACE, UNKN, -/* tokens */ COLON, ID, NUM, SEMI, STRING -}; - -#define SDELIM '@' /* the actual character is needed for string handling*/ -/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN. - * there should be no overlap among SDELIM, KDELIM, and VDELIM - */ - -#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */ - - - - - -/*************************************** - * Data structures for the symbol table - ***************************************/ - -/* Buffer of arbitrary data */ -struct buf { - char *string; - size_t size; -}; -struct cbuf { - char const *string; - size_t size; -}; - -/* Hash table entry */ -struct hshentry { - char const * num; /* pointer to revision number (ASCIZ) */ - char const * date; /* pointer to date of checkin */ - char const * author; /* login of person checking in */ - char const * lockedby; /* who locks the revision */ - char const * state; /* state of revision (Exp by default) */ - char const * name; /* name (if any) by which retrieved */ - struct cbuf log; /* log message requested at checkin */ - struct branchhead * branches; /* list of first revisions on branches*/ - struct cbuf ig; /* ignored phrases in admin part */ - struct cbuf igtext; /* ignored phrases in deltatext part */ - struct hshentry * next; /* next revision on same branch */ - struct hshentry * nexthsh; /* next revision with same hash value */ - long insertlns;/* lines inserted (computed by rlog) */ - long deletelns;/* lines deleted (computed by rlog) */ - char selector; /* true if selected, false if deleted */ -}; - -/* list of hash entries */ -struct hshentries { - struct hshentries *rest; - struct hshentry *first; -}; - -/* list element for branch lists */ -struct branchhead { - struct hshentry * hsh; - struct branchhead * nextbranch; -}; - -/* accesslist element */ -struct access { - char const * login; - struct access * nextaccess; -}; - -/* list element for locks */ -struct rcslock { - char const * login; - struct hshentry * delta; - struct rcslock * nextlock; -}; - -/* list element for symbolic names */ -struct assoc { - char const * symbol; - char const * num; - struct assoc * nextassoc; -}; - - -#define mainArgs (argc,argv) int argc; char **argv; - -#if RCS_lint -# define libId(name,rcsid) -# define mainProg(name,cmd,rcsid) int name mainArgs -#else -# define libId(name,rcsid) char const name[] = rcsid; -# define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs -#endif - -/* - * Markers for keyword expansion (used in co and ident) - * Every byte must have class LETTER or Letter. - */ -#define AUTHOR "Author" -#define DATE "Date" -#define HEADER "Header" -#define IDH "Id" -#define LOCKER "Locker" -#define LOG "Log" -#define NAME "Name" -#define RCSFILE "RCSfile" -#define REVISION "Revision" -#define SOURCE "Source" -#define STATE "State" -#define CVSHEADER "CVSHeader" -#define keylength 9 /* max length of any of the above keywords */ - -enum markers { Nomatch, Author, Date, Header, Id, - Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader, - LocalId }; - /* This must be in the same order as rcskeys.c's Keyword[] array. */ - -#define DELNUMFORM "\n\n%s\n%s\n" -/* used by putdtext and scanlogtext */ - -#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */ - -/* main program */ -extern char const cmdid[]; -void exiterr P((void)) exiting; - -/* merge */ -int merge P((int,char const*,char const*const[3],char const*const[3])); - -/* rcsedit */ -#define ciklogsize 23 /* sizeof("checked in with -k by ") */ -extern FILE *fcopy; -extern char const *resultname; -extern char const ciklog[ciklogsize]; -extern int locker_expansion; -RILE *rcswriteopen P((struct buf*,struct stat*,int)); -char const *makedirtemp P((int)); -char const *getcaller P((void)); -int addlock P((struct hshentry*,int)); -int addsymbol P((char const*,char const*,int)); -int checkaccesslist P((void)); -int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t)); -int donerewrite P((int,time_t)); -int dorewrite P((int,int)); -int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int)); -int findlock P((int,struct hshentry**)); -int setmtime P((char const*,time_t)); -void ORCSclose P((void)); -void ORCSerror P((void)); -void copystring P((void)); -void dirtempunlink P((void)); -void enterstring P((void)); -void finishedit P((struct hshentry const*,FILE*,int)); -void keepdirtemp P((char const*)); -void openfcopy P((FILE*)); -void snapshotedit P((FILE*)); -void xpandstring P((struct hshentry const*)); -#if has_NFS || bad_unlink - int un_link P((char const*)); -#else -# define un_link(s) unlink(s) -#endif -#if large_memory - void edit_string P((void)); -# define editstring(delta) edit_string() -#else - void editstring P((struct hshentry const*)); -#endif - -/* rcsfcmp */ -int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*)); - -/* rcsfnms */ -#define bufautobegin(b) clear_buf(b) -#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0)) -extern FILE *workstdout; -extern char *workname; -extern char const *RCSname; -extern char const *suffixes; -extern int fdlock; -extern struct stat RCSstat; -RILE *rcsreadopen P((struct buf*,struct stat*,int)); -char *bufenlarge P((struct buf*,char const**)); -char const *basefilename P((char const*)); -char const *getfullRCSname P((void)); -char const *getfullCVSname P((void)); -char const *maketemp P((int)); -char const *rcssuffix P((char const*)); -int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int)); -struct cbuf bufremember P((struct buf*,size_t)); -void bufalloc P((struct buf*,size_t)); -void bufautoend P((struct buf*)); -void bufrealloc P((struct buf*,size_t)); -void bufscat P((struct buf*,char const*)); -void bufscpy P((struct buf*,char const*)); -void tempunlink P((void)); - -/* rcsgen */ -extern int interactiveflag; -extern struct buf curlogbuf; -char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int)); -int getcstdin P((void)); -int putdtext P((struct hshentry const*,char const*,FILE*,int)); -int ttystdin P((void)); -int yesorno P((int,char const*,...)) printf_string(2,3); -struct cbuf cleanlogmsg P((char*,size_t)); -struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*)); -void putdesc P((int,char*)); -void putdftext P((struct hshentry const*,RILE*,FILE*,int)); - -/* rcskeep */ -extern int prevkeys; -extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate; -int getoldkeys P((RILE*)); - -/* rcskeys */ -extern char const *Keyword[]; -extern enum markers LocalIdMode; -enum markers trymatch P((char const*)); -void setRCSLocalId(char const *); -void setIncExc(char const *); - -/* rcslex */ -extern FILE *foutptr; -extern FILE *frewrite; -extern RILE *finptr; -extern char const *NextString; -extern enum tokens nexttok; -extern int hshenter; -extern int nerror; -extern int nextc; -extern int quietflag; -extern long rcsline; -char const *getid P((void)); -void efaterror P((char const*)) exiting; -void enfaterror P((int,char const*)) exiting; -void fatcleanup P((int)) exiting; -void faterror P((char const*,...)) printf_string_exiting(1,2); -void fatserror P((char const*,...)) printf_string_exiting(1,2); -void rcsfaterror P((char const*,...)) printf_string_exiting(1,2); -void Ieof P((void)) exiting; -void Ierror P((void)) exiting; -void Oerror P((void)) exiting; -char *checkid P((char*,int)); -char *checksym P((char*,int)); -int eoflex P((void)); -int getkeyopt P((char const*)); -int getlex P((enum tokens)); -struct cbuf getphrases P((char const*)); -struct cbuf savestring P((struct buf*)); -struct hshentry *getnum P((void)); -void Ifclose P((RILE*)); -void Izclose P((RILE**)); -void Lexinit P((void)); -void Ofclose P((FILE*)); -void Orewind P((FILE*)); -void Ozclose P((FILE**)); -void aflush P((FILE*)); -void afputc P((int,FILE*)); -void aprintf P((FILE*,char const*,...)) printf_string(2,3); -void aputs P((char const*,FILE*)); -void checksid P((char*)); -void checkssym P((char*)); -void diagnose P((char const*,...)) printf_string(1,2); -void eerror P((char const*)); -void eflush P((void)); -void enerror P((int,char const*)); -void error P((char const*,...)) printf_string(1,2); -void fvfprintf P((FILE*,char const*,va_list)); -void getkey P((char const*)); -void getkeystring P((char const*)); -void nextlex P((void)); -void oflush P((void)); -void printstring P((void)); -void readstring P((void)); -void redefined P((int)); -void rcserror P((char const*,...)) printf_string(1,2); -void rcswarn P((char const*,...)) printf_string(1,2); -void testIerror P((FILE*)); -void testOerror P((FILE*)); -void warn P((char const*,...)) printf_string(1,2); -void warnignore P((void)); -void workerror P((char const*,...)) printf_string(1,2); -void workwarn P((char const*,...)) printf_string(1,2); -#if has_madvise && has_mmap && large_memory - void advise_access P((RILE*,int)); -# define if_advise_access(p,f,advice) if (p) advise_access(f,advice) -#else -# define advise_access(f,advice) -# define if_advise_access(p,f,advice) -#endif -#if large_memory && maps_memory - RILE *I_open P((char const*,struct stat*)); -# define Iopen(f,m,s) I_open(f,s) -#else - RILE *Iopen P((char const*,char const*,struct stat*)); -#endif -#if !large_memory - void testIeof P((FILE*)); - void Irewind P((RILE*)); -#endif - -/* rcsmap */ -extern enum tokens const ctab[]; - -/* rcsrev */ -char *partialno P((struct buf*,char const*,int)); -char const *namedrev P((char const*,struct hshentry*)); -char const *tiprev P((void)); -int cmpdate P((char const*,char const*)); -int cmpnum P((char const*,char const*)); -int cmpnumfld P((char const*,char const*,int)); -int compartial P((char const*,char const*,int)); -int expandsym P((char const*,struct buf*)); -int fexpandsym P((char const*,struct buf*,RILE*)); -struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**)); -int countnumflds P((char const*)); -void getbranchno P((char const*,struct buf*)); - -/* rcssyn */ -/* These expand modes must agree with Expand_names[] in rcssyn.c. */ -#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */ -#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */ -#define KEY_EXPAND 2 /* -kk `$Keyword$' */ -#define VAL_EXPAND 3 /* -kv `value' */ -#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */ -#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */ -#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */ -#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND) - /* min value guaranteed to yield an identical file */ -struct diffcmd { - long - line1, /* number of first line */ - nlines, /* number of lines affected */ - adprev, /* previous 'a' line1+1 or 'd' line1 */ - dafter; /* sum of previous 'd' line1 and previous 'd' nlines */ -}; -extern char const * Dbranch; -extern struct access * AccessList; -extern struct assoc * Symbols; -extern struct cbuf Comment; -extern struct cbuf Ignored; -extern struct rcslock *Locks; -extern struct hshentry * Head; -extern int Expand; -extern int StrictLocks; -extern int TotalDeltas; -extern char const *const expand_names[]; -extern char const - Kaccess[], Kauthor[], Kbranch[], Kcomment[], - Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[], - Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[]; -void unexpected_EOF P((void)) exiting; -int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*)); -int str2expmode P((char const*)); -void getadmin P((void)); -void getdesc P((int)); -void gettree P((void)); -void ignorephrases P((char const*)); -void initdiffcmd P((struct diffcmd*)); -void putadmin P((void)); -void putstring P((FILE*,int,struct cbuf,int)); -void puttree P((struct hshentry const*,FILE*)); - -/* rcstime */ -#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */ -char const *date2str P((char const[datesize],char[datesize + zonelenmax])); -time_t date2time P((char const[datesize])); -void str2date P((char const*,char[datesize])); -void time2date P((time_t,char[datesize])); -void zone_set P((char const*)); - -/* rcsutil */ -extern int RCSversion; -FILE *fopenSafer P((char const*,char const*)); -char *cgetenv P((char const*)); -char *fstr_save P((char const*)); -char *str_save P((char const*)); -char const *getusername P((int)); -int fdSafer P((int)); -int getRCSINIT P((int,char**,char***)); -int run P((int,char const*,...)); -int runv P((int,char const*,char const**)); -malloc_type fremember P((malloc_type)); -malloc_type ftestalloc P((size_t)); -malloc_type testalloc P((size_t)); -malloc_type testrealloc P((malloc_type,size_t)); -#define ftalloc(T) ftnalloc(T,1) -#define talloc(T) tnalloc(T,1) -#if RCS_lint - extern malloc_type lintalloc; -# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0) -# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0) -# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p) -# define tfree(p) -#else -# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n))) -# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n))) -# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n))) -# define tfree(p) free((malloc_type)(p)) -#endif -time_t now P((void)); -void awrite P((char const*,size_t,FILE*)); -void fastcopy P((RILE*,FILE*)); -void ffree P((void)); -void ffree1 P((char const*)); -void setRCSversion P((char const*)); -#if has_signal - void catchints P((void)); - void ignoreints P((void)); - void restoreints P((void)); -#else -# define catchints() -# define ignoreints() -# define restoreints() -#endif -#if has_mmap && large_memory -# if has_NFS && mmap_signal - void catchmmapints P((void)); - void readAccessFilenameBuffer P((char const*,unsigned char const*)); -# else -# define catchmmapints() -# endif -#endif -#if has_getuid - uid_t ruid P((void)); -# define myself(u) ((u) == ruid()) -#else -# define myself(u) true -#endif -#if has_setuid - uid_t euid P((void)); - void nosetid P((void)); - void seteid P((void)); - void setrid P((void)); -#else -# define nosetid() -# define seteid() -# define setrid() -#endif - -/* version */ -extern char const RCS_version_string[]; diff --git a/gnu/usr.bin/rcs/lib/rcsedit.c b/gnu/usr.bin/rcs/lib/rcsedit.c deleted file mode 100644 index dc9dd307de6a..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsedit.c +++ /dev/null @@ -1,1958 +0,0 @@ -/* RCS stream editor */ - -/****************************************************************************** - * edits the input file according to a - * script from stdin, generated by diff -n - * performs keyword expansion - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.19 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (dirtpname): No longer external. - * (do_link): Simplify logic. - * (finisheditline, finishedit): Replace Iseek/Itell with what they stand for. - * (fopen_update_truncate): Replace `#if' with `if'. - * (keyreplace, makedirtemp): dirlen(x) -> basefilename(x)-x. - * - * (edit_string): Fix bug: if !large_memory, a bogus trailing `@' was output - * at the end of incomplete lines. - * - * (keyreplace): Do not assume that seeking backwards - * at the start of a file will fail; on some systems it succeeds. - * Convert C- and Pascal-style comment starts to ` *' in comment leader. - * - * (rcswriteopen): Use fdSafer to get safer file descriptor. - * Open RCS file with FOPEN_RB. - * - * (chnamemod): Work around bad_NFS_rename bug; don't ignore un_link result. - * Fall back on chmod if fchmod fails, since it might be ENOSYS. - * - * (aflush): Move to rcslex.c. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Normally calculate the $Log prefix from context, not from RCS file. - * Move setmtime here from rcsutil.c. Add ORCSerror. Remove lint. - * - * Revision 5.16 1993/11/03 17:42:27 eggert - * Add -z. Add Name keyword. If bad_unlink, ignore errno when unlink fails. - * Escape white space, $, and \ in keyword string file names. - * Don't output 2 spaces between date and time after Log. - * - * Revision 5.15 1992/07/28 16:12:44 eggert - * Some hosts have readlink but not ELOOP. Avoid `unsigned'. - * Preserve dates more systematically. Statement macro names now end in _. - * - * Revision 5.14 1992/02/17 23:02:24 eggert - * Add -T support. - * - * Revision 5.13 1992/01/24 18:44:19 eggert - * Add support for bad_chmod_close, bad_creat0. - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * Add setmode parameter to chnamemod. addsymbol now reports changes. - * while (E) ; -> while (E) continue; - * - * Revision 5.11 1991/11/03 01:11:44 eggert - * Move the warning about link breaking to where they're actually being broken. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. Fix rare NFS bugs. - * - * Revision 5.9 1991/09/17 19:07:40 eggert - * SGI readlink() yields ENXIO, not EINVAL, for nonlinks. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add piece tables, NFS bug workarounds. Catch odd filenames. Tune. - * - * Revision 5.7 1991/04/21 11:58:21 eggert - * Fix errno bugs. Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.6 1991/02/25 07:12:40 eggert - * Fix setuid bug. Support new link behavior. Work around broken "w+" fopen. - * - * Revision 5.5 1990/12/30 05:07:35 eggert - * Fix report of busy RCS files when !defined(O_CREAT) | !defined(O_EXCL). - * - * Revision 5.4 1990/11/01 05:03:40 eggert - * Permit arbitrary data in comment leaders. - * - * Revision 5.3 1990/09/11 02:41:13 eggert - * Tune expandline(). - * - * Revision 5.2 1990/09/04 08:02:21 eggert - * Count RCS lines better. Improve incomplete line handling. - * - * Revision 5.1 1990/08/29 07:13:56 eggert - * Add -kkvl. - * Fix bug when getting revisions to files ending in incomplete lines. - * Fix bug in comment leader expansion. - * - * Revision 5.0 1990/08/22 08:12:47 eggert - * Don't require final newline. - * Don't append "checked in with -k by " to logs, - * so that checking in a program with -k doesn't change it. - * Don't generate trailing white space for empty comment leader. - * Remove compile-time limits; use malloc instead. Add -k, -V. - * Permit dates past 1999/12/31. Make lock and temp files faster and safer. - * Ansify and Posixate. Check diff's output. - * - * Revision 4.8 89/05/01 15:12:35 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.7 88/11/08 13:54:14 narten - * misplaced semicolon caused infinite loop - * - * Revision 4.6 88/08/09 19:12:45 eggert - * Shrink stdio code size; allow cc -R. - * - * Revision 4.5 87/12/18 11:38:46 narten - * Changes from the 43. version. Don't know the significance of the - * first change involving "rewind". Also, additional "lint" cleanup. - * (Guy Harris) - * - * Revision 4.4 87/10/18 10:32:21 narten - * Updating version numbers. Changes relative to version 1.1 actually - * relative to 4.1 - * - * Revision 1.4 87/09/24 13:59:29 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.3 87/09/15 16:39:39 shepler - * added an initializatin of the variables editline and linecorr - * this will be done each time a file is processed. - * (there was an obscure bug where if co was used to retrieve multiple files - * it would dump) - * fix attributed to Roy Morris @FileNet Corp ...!felix!roy - * - * Revision 1.2 87/03/27 14:22:17 jenkins - * Port to suns - * - * Revision 4.1 83/05/12 13:10:30 wft - * Added new markers Id and RCSfile; added locker to Header and Id. - * Overhauled expandline completely() (problem with $01234567890123456789@). - * Moved trymatch() and marker table to rcskeys.c. - * - * Revision 3.7 83/05/12 13:04:39 wft - * Added retry to expandline to resume after failed match which ended in $. - * Fixed truncation problem for $19chars followed by@@. - * Log no longer expands full path of RCS file. - * - * Revision 3.6 83/05/11 16:06:30 wft - * added retry to expandline to resume after failed match which ended in $. - * Fixed truncation problem for $19chars followed by@@. - * - * Revision 3.5 82/12/04 13:20:56 wft - * Added expansion of keyword Locker. - * - * Revision 3.4 82/12/03 12:26:54 wft - * Added line number correction in case editing does not start at the - * beginning of the file. - * Changed keyword expansion to always print a space before closing KDELIM; - * Expansion for Header shortened. - * - * Revision 3.3 82/11/14 14:49:30 wft - * removed Suffix from keyword expansion. Replaced fclose with ffclose. - * keyreplace() gets log message from delta, not from curlogmsg. - * fixed expression overflow in while(c=putc(GETC.... - * checked nil printing. - * - * Revision 3.2 82/10/18 21:13:39 wft - * I added checks for write errors during the co process, and renamed - * expandstring() to xpandstring(). - * - * Revision 3.1 82/10/13 15:52:55 wft - * changed type of result of getc() from char to int. - * made keyword expansion loop in expandline() portable to machines - * without sign-extension. - */ - - -#include "rcsbase.h" - -libId(editId, "$FreeBSD$") - -static void editEndsPrematurely P((void)) exiting; -static void editLineNumberOverflow P((void)) exiting; -static void escape_string P((FILE*,char const*)); -static void keyreplace P((enum markers,struct hshentry const*,int,RILE*,FILE*,int)); - -FILE *fcopy; /* result file descriptor */ -char const *resultname; /* result pathname */ -int locker_expansion; /* should the locker name be appended to Id val? */ -#if !large_memory - static RILE *fedit; /* edit file descriptor */ - static char const *editname; /* edit pathname */ -#endif -static long editline; /* edit line counter; #lines before cursor */ -static long linecorr; /* #adds - #deletes in each edit run. */ - /*used to correct editline in case file is not rewound after */ - /* applying one delta */ - -/* indexes into dirtpname */ -#define lockdirtp_index 0 -#define newRCSdirtp_index bad_creat0 -#define newworkdirtp_index (newRCSdirtp_index+1) -#define DIRTEMPNAMES (newworkdirtp_index + 1) - -enum maker {notmade, real, effective}; -static struct buf dirtpname[DIRTEMPNAMES]; /* unlink these when done */ -static enum maker volatile dirtpmaker[DIRTEMPNAMES]; /* if these are set */ -#define lockname (dirtpname[lockdirtp_index].string) -#define newRCSname (dirtpname[newRCSdirtp_index].string) - - -#if has_NFS || bad_unlink - int -un_link(s) - char const *s; -/* - * Remove S, even if it is unwritable. - * Ignore unlink() ENOENT failures; NFS generates bogus ones. - */ -{ -# if bad_unlink - if (unlink(s) == 0) - return 0; - else { - int e = errno; - /* - * Forge ahead even if errno == ENOENT; some completely - * brain-damaged hosts (e.g. PCTCP 2.2) yield ENOENT - * even for existing unwritable files. - */ - if (chmod(s, S_IWUSR) != 0) { - errno = e; - return -1; - } - } -# endif -# if has_NFS - return unlink(s)==0 || errno==ENOENT ? 0 : -1; -# else - return unlink(s); -# endif -} -#endif - -#if !has_rename -# if !has_NFS -# define do_link(s,t) link(s,t) -# else - static int do_link P((char const*,char const*)); - static int -do_link(s, t) - char const *s, *t; -/* Link S to T, ignoring bogus EEXIST problems due to NFS failures. */ -{ - int r = link(s, t); - - if (r != 0 && errno == EEXIST) { - struct stat sb, tb; - if ( - stat(s, &sb) == 0 && - stat(t, &tb) == 0 && - same_file(sb, tb, 0) - ) - r = 0; - errno = EEXIST; - } - return r; -} -# endif -#endif - - - static void -editEndsPrematurely() -{ - fatserror("edit script ends prematurely"); -} - - static void -editLineNumberOverflow() -{ - fatserror("edit script refers to line past end of file"); -} - - -#if large_memory - -#if has_memmove -# define movelines(s1, s2, n) VOID memmove(s1, s2, (n)*sizeof(Iptr_type)) -#else - static void movelines P((Iptr_type*,Iptr_type const*,long)); - static void -movelines(s1, s2, n) - register Iptr_type *s1; - register Iptr_type const *s2; - register long n; -{ - if (s1 < s2) - do { - *s1++ = *s2++; - } while (--n); - else { - s1 += n; - s2 += n; - do { - *--s1 = *--s2; - } while (--n); - } -} -#endif - -static void deletelines P((long,long)); -static void finisheditline P((RILE*,FILE*,Iptr_type,struct hshentry const*)); -static void insertline P((long,Iptr_type)); -static void snapshotline P((FILE*,Iptr_type)); - -/* - * `line' contains pointers to the lines in the currently `edited' file. - * It is a 0-origin array that represents linelim-gapsize lines. - * line[0 .. gap-1] and line[gap+gapsize .. linelim-1] hold pointers to lines. - * line[gap .. gap+gapsize-1] contains garbage. - * - * Any @s in lines are duplicated. - * Lines are terminated by \n, or (for a last partial line only) by single @. - */ -static Iptr_type *line; -static size_t gap, gapsize, linelim; - - static void -insertline(n, l) - long n; - Iptr_type l; -/* Before line N, insert line L. N is 0-origin. */ -{ - if (linelim-gapsize < n) - editLineNumberOverflow(); - if (!gapsize) - line = - !linelim ? - tnalloc(Iptr_type, linelim = gapsize = 1024) - : ( - gap = gapsize = linelim, - trealloc(Iptr_type, line, linelim <<= 1) - ); - if (n < gap) - movelines(line+n+gapsize, line+n, gap-n); - else if (gap < n) - movelines(line+gap, line+gap+gapsize, n-gap); - - line[n] = l; - gap = n + 1; - gapsize--; -} - - static void -deletelines(n, nlines) - long n, nlines; -/* Delete lines N through N+NLINES-1. N is 0-origin. */ -{ - long l = n + nlines; - if (linelim-gapsize < l || l < n) - editLineNumberOverflow(); - if (l < gap) - movelines(line+l+gapsize, line+l, gap-l); - else if (gap < n) - movelines(line+gap, line+gap+gapsize, n-gap); - - gap = n; - gapsize += nlines; -} - - static void -snapshotline(f, l) - register FILE *f; - register Iptr_type l; -{ - register int c; - do { - if ((c = *l++) == SDELIM && *l++ != SDELIM) - return; - aputc_(c, f) - } while (c != '\n'); -} - - void -snapshotedit(f) - FILE *f; -/* Copy the current state of the edits to F. */ -{ - register Iptr_type *p, *lim, *l=line; - for (p=l, lim=l+gap; pptr = l; - if (expandline(fin, fout, delta, true, (FILE*)0, true) < 0) - faterror("finisheditline internal error"); -} - - void -finishedit(delta, outfile, done) - struct hshentry const *delta; - FILE *outfile; - int done; -/* - * Doing expansion if DELTA is set, output the state of the edits to OUTFILE. - * But do nothing unless DONE is set (which means we are on the last pass). - */ -{ - if (done) { - openfcopy(outfile); - outfile = fcopy; - if (!delta) - snapshotedit(outfile); - else { - register Iptr_type *p, *lim, *l = line; - register RILE *fin = finptr; - Iptr_type here = fin->ptr; - for (p=l, lim=l+gap; pptr = here; - } - } -} - -/* Open a temporary NAME for output, truncating any previous contents. */ -# define fopen_update_truncate(name) fopenSafer(name, FOPEN_W_WORK) -#else /* !large_memory */ - static FILE * fopen_update_truncate P((char const*)); - static FILE * -fopen_update_truncate(name) - char const *name; -{ - if (bad_fopen_wplus && un_link(name) != 0) - efaterror(name); - return fopenSafer(name, FOPEN_WPLUS_WORK); -} -#endif - - - void -openfcopy(f) - FILE *f; -{ - if (!(fcopy = f)) { - if (!resultname) - resultname = maketemp(2); - if (!(fcopy = fopen_update_truncate(resultname))) - efaterror(resultname); - } -} - - -#if !large_memory - - static void swapeditfiles P((FILE*)); - static void -swapeditfiles(outfile) - FILE *outfile; -/* Function: swaps resultname and editname, assigns fedit=fcopy, - * and rewinds fedit for reading. Set fcopy to outfile if nonnull; - * otherwise, set fcopy to be resultname opened for reading and writing. - */ -{ - char const *tmpptr; - - editline = 0; linecorr = 0; - Orewind(fcopy); - fedit = fcopy; - tmpptr=editname; editname=resultname; resultname=tmpptr; - openfcopy(outfile); -} - - void -snapshotedit(f) - FILE *f; -/* Copy the current state of the edits to F. */ -{ - finishedit((struct hshentry *)0, (FILE*)0, false); - fastcopy(fedit, f); - Irewind(fedit); -} - - void -finishedit(delta, outfile, done) - struct hshentry const *delta; - FILE *outfile; - int done; -/* copy the rest of the edit file and close it (if it exists). - * if delta, perform keyword substitution at the same time. - * If DONE is set, we are finishing the last pass. - */ -{ - register RILE *fe; - register FILE *fc; - - fe = fedit; - if (fe) { - fc = fcopy; - if (delta) { - while (1 < expandline(fe,fc,delta,false,(FILE*)0,true)) - ; - } else { - fastcopy(fe,fc); - } - Ifclose(fe); - } - if (!done) - swapeditfiles(outfile); -} -#endif - - - -#if large_memory -# define copylines(upto,delta) (editline = (upto)) -#else - static void copylines P((long,struct hshentry const*)); - static void -copylines(upto, delta) - register long upto; - struct hshentry const *delta; -/* - * Copy input lines editline+1..upto from fedit to fcopy. - * If delta, keyword expansion is done simultaneously. - * editline is updated. Rewinds a file only if necessary. - */ -{ - register int c; - declarecache; - register FILE *fc; - register RILE *fe; - - if (upto < editline) { - /* swap files */ - finishedit((struct hshentry *)0, (FILE*)0, false); - /* assumes edit only during last pass, from the beginning*/ - } - fe = fedit; - fc = fcopy; - if (editline < upto) - if (delta) - do { - if (expandline(fe,fc,delta,false,(FILE*)0,true) <= 1) - editLineNumberOverflow(); - } while (++editline < upto); - else { - setupcache(fe); cache(fe); - do { - do { - cachegeteof_(c, editLineNumberOverflow();) - aputc_(c, fc) - } while (c != '\n'); - } while (++editline < upto); - uncache(fe); - } -} -#endif - - - - void -xpandstring(delta) - struct hshentry const *delta; -/* Function: Reads a string terminated by SDELIM from finptr and writes it - * to fcopy. Double SDELIM is replaced with single SDELIM. - * Keyword expansion is performed with data from delta. - * If foutptr is nonnull, the string is also copied unchanged to foutptr. - */ -{ - while (1 < expandline(finptr,fcopy,delta,true,foutptr,true)) - continue; -} - - - void -copystring() -/* Function: copies a string terminated with a single SDELIM from finptr to - * fcopy, replacing all double SDELIM with a single SDELIM. - * If foutptr is nonnull, the string also copied unchanged to foutptr. - * editline is incremented by the number of lines copied. - * Assumption: next character read is first string character. - */ -{ register c; - declarecache; - register FILE *frew, *fcop; - register int amidline; - register RILE *fin; - - fin = finptr; - setupcache(fin); cache(fin); - frew = foutptr; - fcop = fcopy; - amidline = false; - for (;;) { - GETC_(frew,c) - switch (c) { - case '\n': - ++editline; - ++rcsline; - amidline = false; - break; - case SDELIM: - GETC_(frew,c) - if (c != SDELIM) { - /* end of string */ - nextc = c; - editline += amidline; - uncache(fin); - return; - } - /* fall into */ - default: - amidline = true; - break; - } - aputc_(c,fcop) - } -} - - - void -enterstring() -/* Like copystring, except the string is put into the edit data structure. */ -{ -#if !large_memory - editname = 0; - fedit = 0; - editline = linecorr = 0; - resultname = maketemp(1); - if (!(fcopy = fopen_update_truncate(resultname))) - efaterror(resultname); - copystring(); -#else - register int c; - declarecache; - register FILE *frew; - register long e, oe; - register int amidline, oamidline; - register Iptr_type optr; - register RILE *fin; - - e = 0; - gap = 0; - gapsize = linelim; - fin = finptr; - setupcache(fin); cache(fin); - advise_access(fin, MADV_NORMAL); - frew = foutptr; - amidline = false; - for (;;) { - optr = cacheptr(); - GETC_(frew,c) - oamidline = amidline; - oe = e; - switch (c) { - case '\n': - ++e; - ++rcsline; - amidline = false; - break; - case SDELIM: - GETC_(frew,c) - if (c != SDELIM) { - /* end of string */ - nextc = c; - editline = e + amidline; - linecorr = 0; - uncache(fin); - return; - } - /* fall into */ - default: - amidline = true; - break; - } - if (!oamidline) - insertline(oe, optr); - } -#endif -} - - - - - void -#if large_memory -edit_string() -#else - editstring(delta) - struct hshentry const *delta; -#endif -/* - * Read an edit script from finptr and applies it to the edit file. -#if !large_memory - * The result is written to fcopy. - * If delta, keyword expansion is performed simultaneously. - * If running out of lines in fedit, fedit and fcopy are swapped. - * editname is the name of the file that goes with fedit. -#endif - * If foutptr is set, the edit script is also copied verbatim to foutptr. - * Assumes that all these files are open. - * resultname is the name of the file that goes with fcopy. - * Assumes the next input character from finptr is the first character of - * the edit script. Resets nextc on exit. - */ -{ - int ed; /* editor command */ - register int c; - declarecache; - register FILE *frew; -# if !large_memory - register FILE *f; - long line_lim = LONG_MAX; - register RILE *fe; -# endif - register long i; - register RILE *fin; -# if large_memory - register long j; -# endif - struct diffcmd dc; - - editline += linecorr; linecorr=0; /*correct line number*/ - frew = foutptr; - fin = finptr; - setupcache(fin); - initdiffcmd(&dc); - while (0 <= (ed = getdiffcmd(fin,true,frew,&dc))) -#if !large_memory - if (line_lim <= dc.line1) - editLineNumberOverflow(); - else -#endif - if (!ed) { - copylines(dc.line1-1, delta); - /* skip over unwanted lines */ - i = dc.nlines; - linecorr -= i; - editline += i; -# if large_memory - deletelines(editline+linecorr, i); -# else - fe = fedit; - do { - /*skip next line*/ - do { - Igeteof_(fe, c, { if (i!=1) editLineNumberOverflow(); line_lim = dc.dafter; break; } ) - } while (c != '\n'); - } while (--i); -# endif - } else { - /* Copy lines without deleting any. */ - copylines(dc.line1, delta); - i = dc.nlines; -# if large_memory - j = editline+linecorr; -# endif - linecorr += i; -#if !large_memory - f = fcopy; - if (delta) - do { - switch (expandline(fin,f,delta,true,frew,true)){ - case 0: case 1: - if (i==1) - return; - /* fall into */ - case -1: - editEndsPrematurely(); - } - } while (--i); - else -#endif - { - cache(fin); - do { -# if large_memory - insertline(j++, cacheptr()); -# endif - for (;;) { - GETC_(frew, c) - if (c==SDELIM) { - GETC_(frew, c) - if (c!=SDELIM) { - if (--i) - editEndsPrematurely(); - nextc = c; - uncache(fin); - return; - } - } -# if !large_memory - aputc_(c, f) -# endif - if (c == '\n') - break; - } - ++rcsline; - } while (--i); - uncache(fin); - } - } -} - - - -/* The rest is for keyword expansion */ - - - - int -expandline(infile, outfile, delta, delimstuffed, frewfile, dolog) - RILE *infile; - FILE *outfile, *frewfile; - struct hshentry const *delta; - int delimstuffed, dolog; -/* - * Read a line from INFILE and write it to OUTFILE. - * Do keyword expansion with data from DELTA. - * If DELIMSTUFFED is true, double SDELIM is replaced with single SDELIM. - * If FREWFILE is set, copy the line unchanged to FREWFILE. - * DELIMSTUFFED must be true if FREWFILE is set. - * Append revision history to log only if DOLOG is set. - * Yields -1 if no data is copied, 0 if an incomplete line is copied, - * 2 if a complete line is copied; adds 1 to yield if expansion occurred. - */ -{ - register c; - declarecache; - register FILE *out, *frew; - register char * tp; - register int e, ds, r; - char const *tlim; - static struct buf keyval; - enum markers matchresult; - - setupcache(infile); cache(infile); - out = outfile; - frew = frewfile; - ds = delimstuffed; - bufalloc(&keyval, keylength+3); - e = 0; - r = -1; - - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto uncache_exit;) - for (;;) { - switch (c) { - case SDELIM: - if (ds) { - GETC_(frew, c) - if (c != SDELIM) { - /* end of string */ - nextc=c; - goto uncache_exit; - } - } - /* fall into */ - default: - aputc_(c,out) - r = 0; - break; - - case '\n': - rcsline += ds; - aputc_(c,out) - r = 2; - goto uncache_exit; - - case KDELIM: - r = 0; - /* check for keyword */ - /* first, copy a long enough string into keystring */ - tp = keyval.string; - *tp++ = KDELIM; - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto keystring_eof;) - if (tp <= &keyval.string[keylength]) - switch (ctab[c]) { - case LETTER: case Letter: - *tp++ = c; - continue; - default: - break; - } - break; - } - *tp++ = c; *tp = '\0'; - matchresult = trymatch(keyval.string+1); - if (matchresult==Nomatch) { - tp[-1] = 0; - aputs(keyval.string, out); - continue; /* last c handled properly */ - } - - /* Now we have a keyword terminated with a K/VDELIM */ - if (c==VDELIM) { - /* try to find closing KDELIM, and replace value */ - tlim = keyval.string + keyval.size; - for (;;) { - if (ds) - GETC_(frew, c) - else - cachegeteof_(c, goto keystring_eof;) - if (c=='\n' || c==KDELIM) - break; - *tp++ =c; - if (tlim <= tp) - tp = bufenlarge(&keyval, &tlim); - if (c==SDELIM && ds) { /*skip next SDELIM */ - GETC_(frew, c) - if (c != SDELIM) { - /* end of string before closing KDELIM or newline */ - nextc = c; - goto keystring_eof; - } - } - } - if (c!=KDELIM) { - /* couldn't find closing KDELIM -- give up */ - *tp = 0; - aputs(keyval.string, out); - continue; /* last c handled properly */ - } - } - /* now put out the new keyword value */ - uncache(infile); - keyreplace(matchresult, delta, ds, infile, out, dolog); - cache(infile); - e = 1; - break; - } - break; - } - } - - keystring_eof: - *tp = 0; - aputs(keyval.string, out); - uncache_exit: - uncache(infile); - return r + e; -} - - - static void -escape_string(out, s) - register FILE *out; - register char const *s; -/* Output to OUT the string S, escaping chars that would break `ci -k'. */ -{ - register char c; - for (;;) - switch ((c = *s++)) { - case 0: return; - case '\t': aputs("\\t", out); break; - case '\n': aputs("\\n", out); break; - case ' ': aputs("\\040", out); break; - case KDELIM: aputs("\\044", out); break; - case '\\': if (VERSION(5)<=RCSversion) {aputs("\\\\", out); break;} - /* fall into */ - default: aputc_(c, out) break; - } -} - -char const ciklog[ciklogsize] = "checked in with -k by "; - - static void -keyreplace(marker, delta, delimstuffed, infile, out, dolog) - enum markers marker; - register struct hshentry const *delta; - int delimstuffed; - RILE *infile; - register FILE *out; - int dolog; -/* function: outputs the keyword value(s) corresponding to marker. - * Attributes are derived from delta. - */ -{ - register char const *sp, *cp, *date; - register int c; - register size_t cs, cw, ls; - char const *sp1; - char datebuf[datesize + zonelenmax]; - int RCSv; - int exp; - - sp = Keyword[(int)marker]; - exp = Expand; - date = delta->date; - RCSv = RCSversion; - - if (exp != VAL_EXPAND) - aprintf(out, "%c%s", KDELIM, sp); - if (exp != KEY_EXPAND) { - - if (exp != VAL_EXPAND) - aprintf(out, "%c%c", VDELIM, - marker==Log && RCSvauthor, out); - break; - case Date: - aputs(date2str(date,datebuf), out); - break; - case Id: - case LocalId: - case Header: - case CVSHeader: - if (marker == Id || RCSv < VERSION(4) || - (marker == LocalId && LocalIdMode == Id)) - escape_string(out, basefilename(RCSname)); - else if (marker == CVSHeader || - (marker == LocalId && LocalIdMode == CVSHeader)) - escape_string(out, getfullCVSname()); - else - escape_string(out, getfullRCSname()); - aprintf(out, " %s %s %s %s", - delta->num, - date2str(date, datebuf), - delta->author, - RCSv==VERSION(3) && delta->lockedby ? "Locked" - : delta->state - ); - if (delta->lockedby) - if (VERSION(5) <= RCSv) { - if (locker_expansion || exp==KEYVALLOCK_EXPAND) - aprintf(out, " %s", delta->lockedby); - } else if (RCSv == VERSION(4)) - aprintf(out, " Locker: %s", delta->lockedby); - break; - case Locker: - if (delta->lockedby) - if ( - locker_expansion - || exp == KEYVALLOCK_EXPAND - || RCSv <= VERSION(4) - ) - aputs(delta->lockedby, out); - break; - case Log: - case RCSfile: - escape_string(out, basefilename(RCSname)); - break; - case Name: - if (delta->name) - aputs(delta->name, out); - break; - case Revision: - aputs(delta->num, out); - break; - case Source: - escape_string(out, getfullRCSname()); - break; - case State: - aputs(delta->state, out); - break; - default: - break; - } - if (exp != VAL_EXPAND) - afputc(' ', out); - } - if (exp != VAL_EXPAND) - afputc(KDELIM, out); - - if (marker == Log && dolog) { - struct buf leader; - - sp = delta->log.string; - ls = delta->log.size; - if (sizeof(ciklog)-1<=ls && !memcmp(sp,ciklog,sizeof(ciklog)-1)) - return; - bufautobegin(&leader); - if (RCSversion < VERSION(5)) { - cp = Comment.string; - cs = Comment.size; - } else { - int kdelim_found = 0; - Ioffset_type chars_read = Itell(infile); - declarecache; - setupcache(infile); cache(infile); - - c = 0; /* Pacify `gcc -Wall'. */ - - /* - * Back up to the start of the current input line, - * setting CS to the number of characters before `$Log'. - */ - cs = 0; - for (;;) { - if (!--chars_read) - goto done_backing_up; - cacheunget_(infile, c) - if (c == '\n') - break; - if (c == SDELIM && delimstuffed) { - if (!--chars_read) - break; - cacheunget_(infile, c) - if (c != SDELIM) { - cacheget_(c) - break; - } - } - cs += kdelim_found; - kdelim_found |= c==KDELIM; - } - cacheget_(c) - done_backing_up:; - - /* Copy characters before `$Log' into LEADER. */ - bufalloc(&leader, cs); - cp = leader.string; - for (cw = 0; cw < cs; cw++) { - leader.string[cw] = c; - if (c == SDELIM && delimstuffed) - cacheget_(c) - cacheget_(c) - } - - /* Convert traditional C or Pascal leader to ` *'. */ - for (cw = 0; cw < cs; cw++) - if (ctab[(unsigned char) cp[cw]] != SPACE) - break; - if ( - cw+1 < cs - && cp[cw+1] == '*' - && (cp[cw] == '/' || cp[cw] == '(') - ) { - size_t i = cw+1; - for (;;) - if (++i == cs) { - warn( - "`%c* $Log' is obsolescent; use ` * $Log'.", - cp[cw] - ); - leader.string[cw] = ' '; - break; - } else if (ctab[(unsigned char) cp[i]] != SPACE) - break; - } - - /* Skip `$Log ... $' string. */ - do { - cacheget_(c) - } while (c != KDELIM); - uncache(infile); - } - afputc('\n', out); - awrite(cp, cs, out); - sp1 = date2str(date, datebuf); - if (VERSION(5) <= RCSv) { - aprintf(out, "Revision %s %s %s", - delta->num, sp1, delta->author - ); - } else { - /* oddity: 2 spaces between date and time, not 1 as usual */ - sp1 = strchr(sp1, ' '); - aprintf(out, "Revision %s %.*s %s %s", - delta->num, (int)(sp1-datebuf), datebuf, sp1, - delta->author - ); - } - /* Do not include state: it may change and is not updated. */ - cw = cs; - if (VERSION(5) <= RCSv) - for (; cw && (cp[cw-1]==' ' || cp[cw-1]=='\t'); --cw) - continue; - for (;;) { - afputc('\n', out); - awrite(cp, cw, out); - if (!ls) - break; - --ls; - c = *sp++; - if (c != '\n') { - awrite(cp+cw, cs-cw, out); - do { - afputc(c,out); - if (!ls) - break; - --ls; - c = *sp++; - } while (c != '\n'); - } - } - bufautoend(&leader); - } -} - -#if has_readlink - static int resolve_symlink P((struct buf*)); - static int -resolve_symlink(L) - struct buf *L; -/* - * If L is a symbolic link, resolve it to the name that it points to. - * If unsuccessful, set errno and yield -1. - * If it points to an existing file, yield 1. - * Otherwise, set errno=ENOENT and yield 0. - */ -{ - char *b, a[SIZEABLE_PATH]; - int e; - size_t s; - ssize_t r; - struct buf bigbuf; - int linkcount = MAXSYMLINKS; - - b = a; - s = sizeof(a); - bufautobegin(&bigbuf); - while ((r = readlink(L->string,b,s)) != -1) - if (r == s) { - bufalloc(&bigbuf, s<<1); - b = bigbuf.string; - s = bigbuf.size; - } else if (!linkcount--) { -# ifndef ELOOP - /* - * Some pedantic Posix 1003.1-1990 hosts have readlink - * but not ELOOP. Approximate ELOOP with EMLINK. - */ -# define ELOOP EMLINK -# endif - errno = ELOOP; - return -1; - } else { - /* Splice symbolic link into L. */ - b[r] = '\0'; - L->string[ - ROOTPATH(b) ? 0 : basefilename(L->string) - L->string - ] = '\0'; - bufscat(L, b); - } - e = errno; - bufautoend(&bigbuf); - errno = e; - switch (e) { - case readlink_isreg_errno: return 1; - case ENOENT: return 0; - default: return -1; - } -} -#endif - - RILE * -rcswriteopen(RCSbuf, status, mustread) - struct buf *RCSbuf; - struct stat *status; - int mustread; -/* - * Create the lock file corresponding to RCSBUF. - * Then try to open RCSBUF for reading and yield its RILE* descriptor. - * Put its status into *STATUS too. - * MUSTREAD is true if the file must already exist, too. - * If all goes well, discard any previously acquired locks, - * and set fdlock to the file descriptor of the RCS lockfile. - */ -{ - register char *tp; - register char const *sp, *RCSpath, *x; - RILE *f; - size_t l; - int e, exists, fdesc, fdescSafer, r, waslocked; - struct buf *dirt; - struct stat statbuf; - - waslocked = 0 <= fdlock; - exists = -# if has_readlink - resolve_symlink(RCSbuf); -# else - stat(RCSbuf->string, &statbuf) == 0 ? 1 - : errno==ENOENT ? 0 : -1; -# endif - if (exists < (mustread|waslocked)) - /* - * There's an unusual problem with the RCS file; - * or the RCS file doesn't exist, - * and we must read or we already have a lock elsewhere. - */ - return 0; - - RCSpath = RCSbuf->string; - sp = basefilename(RCSpath); - l = sp - RCSpath; - dirt = &dirtpname[waslocked]; - bufscpy(dirt, RCSpath); - tp = dirt->string + l; - x = rcssuffix(RCSpath); -# if has_readlink - if (!x) { - error("symbolic link to non RCS file `%s'", RCSpath); - errno = EINVAL; - return 0; - } -# endif - if (*sp == *x) { - error("RCS pathname `%s' incompatible with suffix `%s'", sp, x); - errno = EINVAL; - return 0; - } - /* Create a lock filename that is a function of the RCS filename. */ - if (*x) { - /* - * The suffix is nonempty. - * The lock filename is the first char of of the suffix, - * followed by the RCS filename with last char removed. E.g.: - * foo,v RCS filename with suffix ,v - * ,foo, lock filename - */ - *tp++ = *x; - while (*sp) - *tp++ = *sp++; - *--tp = 0; - } else { - /* - * The suffix is empty. - * The lock filename is the RCS filename - * with last char replaced by '_'. - */ - while ((*tp++ = *sp++)) - continue; - tp -= 2; - if (*tp == '_') { - error("RCS pathname `%s' ends with `%c'", RCSpath, *tp); - errno = EINVAL; - return 0; - } - *tp = '_'; - } - - sp = dirt->string; - - f = 0; - - /* - * good news: - * open(f, O_CREAT|O_EXCL|O_TRUNC|..., OPEN_CREAT_READONLY) - * is atomic according to Posix 1003.1-1990. - * bad news: - * NFS ignores O_EXCL and doesn't comply with Posix 1003.1-1990. - * good news: - * (O_TRUNC,OPEN_CREAT_READONLY) normally guarantees atomicity - * even with NFS. - * bad news: - * If you're root, (O_TRUNC,OPEN_CREAT_READONLY) doesn't - * guarantee atomicity. - * good news: - * Root-over-the-wire NFS access is rare for security reasons. - * This bug has never been reported in practice with RCS. - * So we don't worry about this bug. - * - * An even rarer NFS bug can occur when clients retry requests. - * This can happen in the usual case of NFS over UDP. - * Suppose client A releases a lock by renaming ",f," to "f,v" at - * about the same time that client B obtains a lock by creating ",f,", - * and suppose A's first rename request is delayed, so A reissues it. - * The sequence of events might be: - * A sends rename(",f,", "f,v") - * B sends create(",f,") - * A sends retry of rename(",f,", "f,v") - * server receives, does, and acknowledges A's first rename() - * A receives acknowledgment, and its RCS program exits - * server receives, does, and acknowledges B's create() - * server receives, does, and acknowledges A's retry of rename() - * This not only wrongly deletes B's lock, it removes the RCS file! - * Most NFS implementations have idempotency caches that usually prevent - * this scenario, but such caches are finite and can be overrun. - * This problem afflicts not only RCS, which uses open() and rename() - * to get and release locks; it also afflicts the traditional - * Unix method of using link() and unlink() to get and release locks, - * and the less traditional method of using mkdir() and rmdir(). - * There is no easy workaround. - * Any new method based on lockf() seemingly would be incompatible with - * the old methods; besides, lockf() is notoriously buggy under NFS. - * Since this problem afflicts scads of Unix programs, but is so rare - * that nobody seems to be worried about it, we won't worry either. - */ -# if !open_can_creat -# define create(f) creat(f, OPEN_CREAT_READONLY) -# else -# define create(f) open(f, OPEN_O_BINARY|OPEN_O_LOCK|OPEN_O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, OPEN_CREAT_READONLY) -# endif - - catchints(); - ignoreints(); - - /* - * Create a lock file for an RCS file. This should be atomic, i.e. - * if two processes try it simultaneously, at most one should succeed. - */ - seteid(); - fdesc = create(sp); - fdescSafer = fdSafer(fdesc); /* Do it now; setrid might use stderr. */ - e = errno; - setrid(); - - if (0 <= fdesc) - dirtpmaker[0] = effective; - - if (fdescSafer < 0) { - if (e == EACCES && stat(sp,&statbuf) == 0) - /* The RCS file is busy. */ - e = EEXIST; - } else { - e = ENOENT; - if (exists) { - f = Iopen(RCSpath, FOPEN_RB, status); - e = errno; - if (f && waslocked) { - /* Discard the previous lock in favor of this one. */ - ORCSclose(); - seteid(); - r = un_link(lockname); - e = errno; - setrid(); - if (r != 0) - enfaterror(e, lockname); - bufscpy(&dirtpname[lockdirtp_index], sp); - } - } - fdlock = fdescSafer; - } - - restoreints(); - - errno = e; - return f; -} - - void -keepdirtemp(name) - char const *name; -/* Do not unlink name, either because it's not there any more, - * or because it has already been unlinked. - */ -{ - register int i; - for (i=DIRTEMPNAMES; 0<=--i; ) - if (dirtpname[i].string == name) { - dirtpmaker[i] = notmade; - return; - } - faterror("keepdirtemp"); -} - - char const * -makedirtemp(isworkfile) - int isworkfile; -/* - * Create a unique pathname and store it into dirtpname. - * Because of storage in tpnames, dirtempunlink() can unlink the file later. - * Return a pointer to the pathname created. - * If ISWORKFILE is 1, put it into the working file's directory; - * if 0, put the unique file in RCSfile's directory. - */ -{ - register char *tp, *np; - register size_t dl; - register struct buf *bn; - register char const *name = isworkfile ? workname : RCSname; -# if has_mktemp - int fd; -# endif - - dl = basefilename(name) - name; - bn = &dirtpname[newRCSdirtp_index + isworkfile]; - bufalloc(bn, -# if has_mktemp - dl + 9 -# else - strlen(name) + 3 -# endif - ); - bufscpy(bn, name); - np = tp = bn->string; - tp += dl; - *tp++ = '_'; - *tp++ = '0'+isworkfile; - catchints(); -# if has_mktemp - VOID strcpy(tp, "XXXXXX"); - fd = mkstemp(np); - if (fd < 0 || !*np) - faterror("can't make temporary pathname `%.*s_%cXXXXXX'", - (int)dl, name, '0'+isworkfile - ); - close(fd); -# else - /* - * Posix 1003.1-1990 has no reliable way - * to create a unique file in a named directory. - * We fudge here. If the filename is abcde, - * the temp filename is _Ncde where N is a digit. - */ - name += dl; - if (*name) name++; - if (*name) name++; - VOID strcpy(tp, name); -# endif - dirtpmaker[newRCSdirtp_index + isworkfile] = real; - return np; -} - - void -dirtempunlink() -/* Clean up makedirtemp() files. May be invoked by signal handler. */ -{ - register int i; - enum maker m; - - for (i = DIRTEMPNAMES; 0 <= --i; ) - if ((m = dirtpmaker[i]) != notmade) { - if (m == effective) - seteid(); - VOID un_link(dirtpname[i].string); - if (m == effective) - setrid(); - dirtpmaker[i] = notmade; - } -} - - - int -#if has_prototypes -chnamemod( - FILE **fromp, char const *from, char const *to, - int set_mode, mode_t mode, time_t mtime -) - /* The `#if has_prototypes' is needed because mode_t might promote to int. */ -#else - chnamemod(fromp, from, to, set_mode, mode, mtime) - FILE **fromp; char const *from,*to; - int set_mode; mode_t mode; time_t mtime; -#endif -/* - * Rename a file (with stream pointer *FROMP) from FROM to TO. - * FROM already exists. - * If 0 < SET_MODE, change the mode to MODE, before renaming if possible. - * If MTIME is not -1, change its mtime to MTIME before renaming. - * Close and clear *FROMP before renaming it. - * Unlink TO if it already exists. - * Return -1 on error (setting errno), 0 otherwise. - */ -{ - mode_t mode_while_renaming = mode; - int fchmod_set_mode = 0; - -# if bad_a_rename || bad_NFS_rename - struct stat st; - if (bad_NFS_rename || (bad_a_rename && set_mode <= 0)) { - if (fstat(fileno(*fromp), &st) != 0) - return -1; - if (bad_a_rename && set_mode <= 0) - mode = st.st_mode; - } -# endif - -# if bad_a_rename - /* - * There's a short window of inconsistency - * during which the lock file is writable. - */ - mode_while_renaming = mode|S_IWUSR; - if (mode != mode_while_renaming) - set_mode = 1; -# endif - -# if has_fchmod - if (0nextlock) - if (strcmp(getcaller(), next->login) == 0) { - if (found) { - rcserror("multiple revisions locked by %s; please specify one", getcaller()); - return 2; - } - found = trail; - } - if (!found) - return 0; - next = *found; - *target = next->delta; - if (delete) { - next->delta->lockedby = 0; - *found = next->nextlock; - } - return 1; -} - - int -addlock(delta, verbose) - struct hshentry * delta; - int verbose; -/* - * Add a lock held by caller to DELTA and yield 1 if successful. - * Print an error message if verbose and yield -1 if no lock is added because - * DELTA is locked by somebody other than caller. - * Return 0 if the caller already holds the lock. - */ -{ - register struct rcslock *next; - - for (next = Locks; next; next = next->nextlock) - if (cmpnum(delta->num, next->delta->num) == 0) - if (strcmp(getcaller(), next->login) == 0) - return 0; - else { - if (verbose) - rcserror("Revision %s is already locked by %s.", - delta->num, next->login - ); - return -1; - } - next = ftalloc(struct rcslock); - delta->lockedby = next->login = getcaller(); - next->delta = delta; - next->nextlock = Locks; - Locks = next; - return 1; -} - - - int -addsymbol(num, name, rebind) - char const *num, *name; - int rebind; -/* - * Associate with revision NUM the new symbolic NAME. - * If NAME already exists and REBIND is set, associate NAME with NUM; - * otherwise, print an error message and return false; - * Return -1 if unsuccessful, 0 if no change, 1 if change. - */ -{ - register struct assoc *next; - - for (next = Symbols; next; next = next->nextassoc) - if (strcmp(name, next->symbol) == 0) - if (strcmp(next->num,num) == 0) - return 0; - else if (rebind) { - next->num = num; - return 1; - } else { - rcserror("symbolic name %s already bound to %s", - name, next->num - ); - return -1; - } - next = ftalloc(struct assoc); - next->symbol = name; - next->num = num; - next->nextassoc = Symbols; - Symbols = next; - return 1; -} - - - - char const * -getcaller() -/* Get the caller's login name. */ -{ -# if has_setuid - return getusername(euid()!=ruid()); -# else - return getusername(false); -# endif -} - - - int -checkaccesslist() -/* - * Return true if caller is the superuser, the owner of the - * file, the access list is empty, or caller is on the access list. - * Otherwise, print an error message and return false. - */ -{ - register struct access const *next; - - if (!AccessList || myself(RCSstat.st_uid) || strcmp(getcaller(),"root")==0) - return true; - - next = AccessList; - do { - if (strcmp(getcaller(), next->login) == 0) - return true; - } while ((next = next->nextaccess)); - - rcserror("user %s not on the access list", getcaller()); - return false; -} - - - int -dorewrite(lockflag, changed) - int lockflag, changed; -/* - * Do nothing if LOCKFLAG is zero. - * Prepare to rewrite an RCS file if CHANGED is positive. - * Stop rewriting if CHANGED is zero, because there won't be any changes. - * Fail if CHANGED is negative. - * Return 0 on success, -1 on failure. - */ -{ - int r = 0, e; - - if (lockflag) - if (changed) { - if (changed < 0) - return -1; - putadmin(); - puttree(Head, frewrite); - aprintf(frewrite, "\n\n%s%c", Kdesc, nextc); - foutptr = frewrite; - } else { -# if bad_creat0 - int nr = !!frewrite, ne = 0; -# endif - ORCSclose(); - seteid(); - ignoreints(); -# if bad_creat0 - if (nr) { - nr = un_link(newRCSname); - ne = errno; - keepdirtemp(newRCSname); - } -# endif - r = un_link(lockname); - e = errno; - keepdirtemp(lockname); - restoreints(); - setrid(); - if (r != 0) - enerror(e, lockname); -# if bad_creat0 - if (nr != 0) { - enerror(ne, newRCSname); - r = -1; - } -# endif - } - return r; -} - - int -donerewrite(changed, newRCStime) - int changed; - time_t newRCStime; -/* - * Finish rewriting an RCS file if CHANGED is nonzero. - * Set its mode if CHANGED is positive. - * Set its modification time to NEWRCSTIME unless it is -1. - * Return 0 on success, -1 on failure. - */ -{ - int r = 0, e = 0; -# if bad_creat0 - int lr, le; -# endif - - if (changed && !nerror) { - if (finptr) { - fastcopy(finptr, frewrite); - Izclose(&finptr); - } - if (1 < RCSstat.st_nlink) - rcswarn("breaking hard link"); - aflush(frewrite); - seteid(); - ignoreints(); - r = chnamemod( - &frewrite, newRCSname, RCSname, changed, - RCSstat.st_mode & (mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH), - newRCStime - ); - e = errno; - keepdirtemp(newRCSname); -# if bad_creat0 - lr = un_link(lockname); - le = errno; - keepdirtemp(lockname); -# endif - restoreints(); - setrid(); - if (r != 0) { - enerror(e, RCSname); - error("saved in %s", newRCSname); - } -# if bad_creat0 - if (lr != 0) { - enerror(le, lockname); - r = -1; - } -# endif - } - return r; -} - - void -ORCSclose() -{ - if (0 <= fdlock) { - if (close(fdlock) != 0) - efaterror(lockname); - fdlock = -1; - } - Ozclose(&frewrite); -} - - void -ORCSerror() -/* -* Like ORCSclose, except we are cleaning up after an interrupt or fatal error. -* Do not report errors, since this may loop. This is needed only because -* some brain-damaged hosts (e.g. OS/2) cannot unlink files that are open, and -* some nearly-Posix hosts (e.g. NFS) work better if the files are closed first. -* This isn't a completely reliable away to work around brain-damaged hosts, -* because of the gap between actual file opening and setting frewrite etc., -* but it's better than nothing. -*/ -{ - if (0 <= fdlock) - VOID close(fdlock); - if (frewrite) - /* Avoid fclose, since stdio may not be reentrant. */ - VOID close(fileno(frewrite)); -} diff --git a/gnu/usr.bin/rcs/lib/rcsfcmp.c b/gnu/usr.bin/rcs/lib/rcsfcmp.c deleted file mode 100644 index ef0529001b87..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsfcmp.c +++ /dev/null @@ -1,354 +0,0 @@ -/* Compare working files, ignoring RCS keyword strings. */ - -/***************************************************************************** - * rcsfcmp() - * Testprogram: define FCMPTEST - ***************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - - - -/* - * Revision 5.14 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.13 1995/06/01 16:23:43 eggert - * (rcsfcmp): Add -kb support. - * - * Revision 5.12 1994/03/17 14:05:48 eggert - * Normally calculate the $Log prefix from context, not from RCS file. - * Calculate line numbers correctly even if the $Log prefix contains newlines. - * Remove lint. - * - * Revision 5.11 1993/11/03 17:42:27 eggert - * Fix yet another off-by-one error when comparing Log string expansions. - * - * Revision 5.10 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.9 1991/10/07 17:32:46 eggert - * Count log lines correctly. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.7 1991/04/21 11:58:22 eggert - * Fix errno bug. Add MS-DOS support. - * - * Revision 5.6 1991/02/28 19:18:47 eggert - * Open work file at most once. - * - * Revision 5.5 1990/11/27 09:26:05 eggert - * Fix comment leader bug. - * - * Revision 5.4 1990/11/01 05:03:42 eggert - * Permit arbitrary data in logs and comment leaders. - * - * Revision 5.3 1990/09/11 02:41:15 eggert - * Don't ignore differences inside keyword strings if -ko is set. - * - * Revision 5.1 1990/08/29 07:13:58 eggert - * Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:49 eggert - * Don't append "checked in with -k by " log to logs, - * so that checking in a program with -k doesn't change it. - * Ansify and Posixate. Remove lint. - * - * Revision 4.5 89/05/01 15:12:42 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.4 88/08/09 19:12:50 eggert - * Shrink stdio code size. - * - * Revision 4.3 87/12/18 11:40:02 narten - * lint cleanups (Guy Harris) - * - * Revision 4.2 87/10/18 10:33:06 narten - * updting version number. Changes relative to 1.1 actually relative to - * 4.1 - * - * Revision 1.2 87/03/27 14:22:19 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 16:24:04 wft - * Marker matching now uses trymatch(). Marker pattern is now - * checked precisely. - * - * Revision 3.1 82/12/04 13:21:40 wft - * Initial revision. - * - */ - -/* -#define FCMPTEST -*/ -/* Testprogram; prints out whether two files are identical, - * except for keywords - */ - -#include "rcsbase.h" - -libId(fcmpId, "$FreeBSD$") - - static int discardkeyval P((int,RILE*)); - static int -discardkeyval(c, f) - register int c; - register RILE *f; -{ - for (;;) - switch (c) { - case KDELIM: - case '\n': - return c; - default: - Igeteof_(f, c, return EOF;) - break; - } -} - - int -rcsfcmp(xfp, xstatp, uname, delta) - register RILE *xfp; - struct stat const *xstatp; - char const *uname; - struct hshentry const *delta; -/* Compare the files xfp and uname. Return zero - * if xfp has the same contents as uname and neither has keywords, - * otherwise -1 if they are the same ignoring keyword values, - * and 1 if they differ even ignoring - * keyword values. For the LOG-keyword, rcsfcmp skips the log message - * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive - * if xfp contains the same as uname, with the keywords expanded. - * Implementation: character-by-character comparison until $ is found. - * If a $ is found, read in the marker keywords; if they are real keywords - * and identical, read in keyword value. If value is terminated properly, - * disregard it and optionally skip log message; otherwise, compare value. - */ -{ - register int xc, uc; - char xkeyword[keylength+2]; - int eqkeyvals; - register RILE *ufp; - register int xeof, ueof; - register char * tp; - register char const *sp; - register size_t leaderlen; - int result; - enum markers match1; - struct stat ustat; - - if (!(ufp = Iopen(uname, FOPEN_R_WORK, &ustat))) { - efaterror(uname); - } - xeof = ueof = false; - if (MIN_UNEXPAND <= Expand) { - if (!(result = xstatp->st_size!=ustat.st_size)) { -# if large_memory && maps_memory - result = !!memcmp(xfp->base,ufp->base,(size_t)xstatp->st_size); -# else - for (;;) { - /* get the next characters */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - if (xc != uc) - goto return1; - } -# endif - } - } else { - xc = 0; - uc = 0; /* Keep lint happy. */ - leaderlen = 0; - result = 0; - - for (;;) { - if (xc != KDELIM) { - /* get the next characters */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - } else { - /* try to get both keywords */ - tp = xkeyword; - for (;;) { - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - if (xc != uc) - break; - switch (xc) { - default: - if (xkeyword+keylength <= tp) - break; - *tp++ = xc; - continue; - case '\n': case KDELIM: case VDELIM: - break; - } - break; - } - if ( - (xc==KDELIM || xc==VDELIM) && (uc==KDELIM || uc==VDELIM) && - (*tp = xc, (match1 = trymatch(xkeyword)) != Nomatch) - ) { -#ifdef FCMPTEST - VOID printf("found common keyword %s\n",xkeyword); -#endif - result = -1; - for (;;) { - if (xc != uc) { - xc = discardkeyval(xc, xfp); - uc = discardkeyval(uc, ufp); - if ((xeof = xc==EOF) | (ueof = uc==EOF)) - goto eof; - eqkeyvals = false; - break; - } - switch (xc) { - default: - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - continue; - - case '\n': case KDELIM: - eqkeyvals = true; - break; - } - break; - } - if (xc != uc) - goto return1; - if (xc==KDELIM) { - /* Skip closing KDELIM. */ - Igeteof_(xfp, xc, xeof=true;) - Igeteof_(ufp, uc, ueof=true;) - if (xeof | ueof) - goto eof; - /* if the keyword is LOG, also skip the log message in xfp*/ - if (match1==Log) { - /* first, compute the number of line feeds in log msg */ - int lncnt; - size_t ls, ccnt; - sp = delta->log.string; - ls = delta->log.size; - if (ls31 chars) name. - * while (E) ; -> while (E) continue; - * - * Revision 5.8 1991/09/24 00:28:40 eggert - * Don't export bindex(). - * - * Revision 5.7 1991/08/19 03:13:55 eggert - * Fix messages when rcswriteopen fails. - * Look in $TMP and $TEMP if $TMPDIR isn't set. Tune. - * - * Revision 5.6 1991/04/21 11:58:23 eggert - * Fix errno bugs. Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.5 1991/02/26 17:48:38 eggert - * Fix setuid bug. Support new link behavior. - * Define more portable getcwd(). - * - * Revision 5.4 1990/11/01 05:03:43 eggert - * Permit arbitrary data in comment leaders. - * - * Revision 5.3 1990/09/14 22:56:16 hammer - * added more filename extensions and their comment leaders - * - * Revision 5.2 1990/09/04 08:02:23 eggert - * Fix typo when !RCSSEP. - * - * Revision 5.1 1990/08/29 07:13:59 eggert - * Work around buggy compilers with defective argument promotion. - * - * Revision 5.0 1990/08/22 08:12:50 eggert - * Ignore signals when manipulating the semaphore file. - * Modernize list of filename extensions. - * Permit paths of arbitrary length. Beware filenames beginning with "-". - * Remove compile-time limits; use malloc instead. - * Permit dates past 1999/12/31. Make lock and temp files faster and safer. - * Ansify and Posixate. - * Don't use access(). Fix test for non-regular files. Tune. - * - * Revision 4.8 89/05/01 15:09:41 narten - * changed getwd to not stat empty directories. - * - * Revision 4.7 88/08/09 19:12:53 eggert - * Fix troff macro comment leader bug; add Prolog; allow cc -R; remove lint. - * - * Revision 4.6 87/12/18 11:40:23 narten - * additional file types added from 4.3 BSD version, and SPARC assembler - * comment character added. Also, more lint cleanups. (Guy Harris) - * - * Revision 4.5 87/10/18 10:34:16 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to verion 4.3 - * - * Revision 1.3 87/03/27 14:22:21 jenkins - * Port to suns - * - * Revision 1.2 85/06/26 07:34:28 svb - * Comment leader '% ' for '*.tex' files added. - * - * Revision 4.3 83/12/15 12:26:48 wft - * Added check for KDELIM in filenames to pairfilenames(). - * - * Revision 4.2 83/12/02 22:47:45 wft - * Added csh, red, and sl filename suffixes. - * - * Revision 4.1 83/05/11 16:23:39 wft - * Added initialization of Dbranch to InitAdmin(). Canged pairfilenames(): - * 1. added copying of path from workfile to RCS file, if RCS file is omitted; - * 2. added getting the file status of RCS and working files; - * 3. added ignoring of directories. - * - * Revision 3.7 83/05/11 15:01:58 wft - * Added comtable[] which pairs filename suffixes with comment leaders; - * updated InitAdmin() accordingly. - * - * Revision 3.6 83/04/05 14:47:36 wft - * fixed Suffix in InitAdmin(). - * - * Revision 3.5 83/01/17 18:01:04 wft - * Added getwd() and rename(); these can be removed by defining - * V4_2BSD, since they are not needed in 4.2 bsd. - * Changed sys/param.h to sys/types.h. - * - * Revision 3.4 82/12/08 21:55:20 wft - * removed unused variable. - * - * Revision 3.3 82/11/28 20:31:37 wft - * Changed mktempfile() to store the generated filenames. - * Changed getfullRCSname() to store the file and pathname, and to - * delete leading "../" and "./". - * - * Revision 3.2 82/11/12 14:29:40 wft - * changed pairfilenames() to handle file.sfx,v; also deleted checkpathnosfx(), - * checksuffix(), checkfullpath(). Semaphore name generation updated. - * mktempfile() now checks for nil path; freefilename initialized properly. - * Added Suffix .h to InitAdmin. Added testprogram PAIRTEST. - * Moved rmsema, trysema, trydiraccess, getfullRCSname from rcsutil.c to here. - * - * Revision 3.1 82/10/18 14:51:28 wft - * InitAdmin() now initializes StrictLocks=STRICT_LOCKING (def. in rcsbase.h). - * renamed checkpath() to checkfullpath(). - */ - - -#include "rcsbase.h" - -libId(fnmsId, "$FreeBSD$") - -static char const *bindex P((char const*,int)); -static int fin2open P((char const*, size_t, char const*, size_t, char const*, size_t, RILE*(*)P((struct buf*,struct stat*,int)), int)); -static int finopen P((RILE*(*)P((struct buf*,struct stat*,int)), int)); -static int suffix_matches P((char const*,char const*)); -static size_t dir_useful_len P((char const*)); -static size_t suffixlen P((char const*)); -static void InitAdmin P((void)); - -char const *RCSname; -char *workname; -int fdlock; -FILE *workstdout; -struct stat RCSstat; -char const *suffixes; - -static char const rcsdir[] = "RCS"; -#define rcslen (sizeof(rcsdir)-1) - -static struct buf RCSbuf, RCSb; -static int RCSerrno; - - -/* Temp names to be unlinked when done, if they are not 0. */ -#define TEMPNAMES 5 /* must be at least DIRTEMPNAMES (see rcsedit.c) */ -static char *volatile tpnames[TEMPNAMES]; - - -struct compair { - char const *suffix, *comlead; -}; - -/* -* This table is present only for backwards compatibility. -* Normally we ignore this table, and use the prefix of the `$Log' line instead. -*/ -static struct compair const comtable[] = { - { "a" , "-- " }, /* Ada */ - { "ada" , "-- " }, - { "adb" , "-- " }, - { "ads" , "-- " }, - { "asm" , ";; " }, /* assembler (MS-DOS) */ - { "bat" , ":: " }, /* batch (MS-DOS) */ - { "body", "-- " }, /* Ada */ - { "c" , " * " }, /* C */ - { "c++" , "// " }, /* C++ in all its infinite guises */ - { "cc" , "// " }, - { "cpp" , "// " }, - { "cxx" , "// " }, - { "cl" , ";;; "}, /* Common Lisp */ - { "cmd" , ":: " }, /* command (OS/2) */ - { "cmf" , "c " }, /* CM Fortran */ - { "cs" , " * " }, /* C* */ - { "el" , "; " }, /* Emacs Lisp */ - { "f" , "c " }, /* Fortran */ - { "for" , "c " }, - { "h" , " * " }, /* C-header */ - { "hpp" , "// " }, /* C++ header */ - { "hxx" , "// " }, - { "l" , " * " }, /* lex (NOTE: franzlisp disagrees) */ - { "lisp", ";;; "}, /* Lucid Lisp */ - { "lsp" , ";; " }, /* Microsoft Lisp */ - { "m" , "// " }, /* Objective C */ - { "mac" , ";; " }, /* macro (DEC-10, MS-DOS, PDP-11, VMS, etc) */ - { "me" , ".\\\" "}, /* troff -me */ - { "ml" , "; " }, /* mocklisp */ - { "mm" , ".\\\" "}, /* troff -mm */ - { "ms" , ".\\\" "}, /* troff -ms */ - { "p" , " * " }, /* Pascal */ - { "pas" , " * " }, - { "ps" , "% " }, /* PostScript */ - { "spec", "-- " }, /* Ada */ - { "sty" , "% " }, /* LaTeX style */ - { "tex" , "% " }, /* TeX */ - { "y" , " * " }, /* yacc */ - { 0 , "# " } /* default for unknown suffix; must be last */ -}; - -#if has_mktemp - static char const *tmp P((void)); - static char const * -tmp() -/* Yield the name of the tmp directory. */ -{ - static char const *s; - if (!s - && !(s = cgetenv("TMPDIR")) /* Unix tradition */ - && !(s = cgetenv("TMP")) /* DOS tradition */ - && !(s = cgetenv("TEMP")) /* another DOS tradition */ - ) - s = TMPDIR; - return s; -} -#endif - - char const * -maketemp(n) - int n; -/* Create a unique pathname using n and the process id and store it - * into the nth slot in tpnames. - * Because of storage in tpnames, tempunlink() can unlink the file later. - * Return a pointer to the pathname created. - */ -{ - char *p; - char const *t = tpnames[n]; -# if has_mktemp - int fd; -# endif - - if (t) - return t; - - catchints(); - { -# if has_mktemp - char const *tp = tmp(); - size_t tplen = dir_useful_len(tp); - p = testalloc(tplen + 10); - VOID sprintf(p, "%.*s%cT%cXXXXXX", (int)tplen, tp, SLASH, '0'+n); - fd = mkstemp(p); - if (fd < 0 || !*p) - faterror("can't make temporary pathname `%.*s%cT%cXXXXXX'", - (int)tplen, tp, SLASH, '0'+n - ); - close(fd); -# else - static char tpnamebuf[TEMPNAMES][L_tmpnam]; - p = tpnamebuf[n]; - if (!tmpnam(p) || !*p) -# ifdef P_tmpdir - faterror("can't make temporary pathname `%s...'",P_tmpdir); -# else - faterror("can't make temporary pathname"); -# endif -# endif - } - - tpnames[n] = p; - return p; -} - - void -tempunlink() -/* Clean up maketemp() files. May be invoked by signal handler. - */ -{ - register int i; - register char *p; - - for (i = TEMPNAMES; 0 <= --i; ) - if ((p = tpnames[i])) { - VOID unlink(p); - /* - * We would tfree(p) here, - * but this might dump core if we're handing a signal. - * We're about to exit anyway, so we won't bother. - */ - tpnames[i] = 0; - } -} - - - static char const * -bindex(sp, c) - register char const *sp; - register int c; -/* Function: Finds the last occurrence of character c in string sp - * and returns a pointer to the character just beyond it. If the - * character doesn't occur in the string, sp is returned. - */ -{ - register char const *r; - r = sp; - while (*sp) { - if (*sp++ == c) r=sp; - } - return r; -} - - - - static int -suffix_matches(suffix, pattern) - register char const *suffix, *pattern; -{ - register int c; - if (!pattern) - return true; - for (;;) - switch (*suffix++ - (c = *pattern++)) { - case 0: - if (!c) - return true; - break; - - case 'A'-'a': - if (ctab[c] == Letter) - break; - /* fall into */ - default: - return false; - } -} - - - static void -InitAdmin() -/* function: initializes an admin node */ -{ - register char const *Suffix; - register int i; - - Head=0; Dbranch=0; AccessList=0; Symbols=0; Locks=0; - StrictLocks=STRICT_LOCKING; - - /* guess the comment leader from the suffix*/ - Suffix = bindex(workname, '.'); - if (Suffix==workname) Suffix= ""; /* empty suffix; will get default*/ - for (i=0; !suffix_matches(Suffix,comtable[i].suffix); i++) - continue; - Comment.string = comtable[i].comlead; - Comment.size = strlen(comtable[i].comlead); - Expand = KEYVAL_EXPAND; - clear_buf(&Ignored); - Lexinit(); /* note: if !finptr, reads nothing; only initializes */ -} - - - - void -bufalloc(b, size) - register struct buf *b; - size_t size; -/* Ensure *B is a name buffer of at least SIZE bytes. - * *B's old contents can be freed; *B's new contents are undefined. - */ -{ - if (b->size < size) { - if (b->size) - tfree(b->string); - else - b->size = sizeof(malloc_type); - while (b->size < size) - b->size <<= 1; - b->string = tnalloc(char, b->size); - } -} - - void -bufrealloc(b, size) - register struct buf *b; - size_t size; -/* like bufalloc, except *B's old contents, if any, are preserved */ -{ - if (b->size < size) { - if (!b->size) - bufalloc(b, size); - else { - while ((b->size <<= 1) < size) - continue; - b->string = trealloc(char, b->string, b->size); - } - } -} - - void -bufautoend(b) - struct buf *b; -/* Free an auto buffer at block exit. */ -{ - if (b->size) - tfree(b->string); -} - - struct cbuf -bufremember(b, s) - struct buf *b; - size_t s; -/* - * Free the buffer B with used size S. - * Yield a cbuf with identical contents. - * The cbuf will be reclaimed when this input file is finished. - */ -{ - struct cbuf cb; - - if ((cb.size = s)) - cb.string = fremember(trealloc(char, b->string, s)); - else { - bufautoend(b); /* not really auto */ - cb.string = ""; - } - return cb; -} - - char * -bufenlarge(b, alim) - register struct buf *b; - char const **alim; -/* Make *B larger. Set *ALIM to its new limit, and yield the relocated value - * of its old limit. - */ -{ - size_t s = b->size; - bufrealloc(b, s + 1); - *alim = b->string + b->size; - return b->string + s; -} - - void -bufscat(b, s) - struct buf *b; - char const *s; -/* Concatenate S to B's end. */ -{ - size_t blen = b->string ? strlen(b->string) : 0; - bufrealloc(b, blen+strlen(s)+1); - VOID strcpy(b->string+blen, s); -} - - void -bufscpy(b, s) - struct buf *b; - char const *s; -/* Copy S into B. */ -{ - bufalloc(b, strlen(s)+1); - VOID strcpy(b->string, s); -} - - - char const * -basefilename(p) - char const *p; -/* Yield the address of the base filename of the pathname P. */ -{ - register char const *b = p, *q = p; - for (;;) - switch (*q++) { - case SLASHes: b = q; break; - case 0: return b; - } -} - - - static size_t -suffixlen(x) - char const *x; -/* Yield the length of X, an RCS pathname suffix. */ -{ - register char const *p; - - p = x; - for (;;) - switch (*p) { - case 0: case SLASHes: - return p - x; - - default: - ++p; - continue; - } -} - - char const * -rcssuffix(name) - char const *name; -/* Yield the suffix of NAME if it is an RCS pathname, 0 otherwise. */ -{ - char const *x, *p, *nz; - size_t nl, xl; - - nl = strlen(name); - nz = name + nl; - x = suffixes; - do { - if ((xl = suffixlen(x))) { - if (xl <= nl && memcmp(p = nz-xl, x, xl) == 0) - return p; - } else - for (p = name; p < nz - rcslen; p++) - if ( - isSLASH(p[rcslen]) - && (p==name || isSLASH(p[-1])) - && memcmp(p, rcsdir, rcslen) == 0 - ) - return nz; - x += xl; - } while (*x++); - return 0; -} - - /*ARGSUSED*/ RILE * -rcsreadopen(RCSpath, status, mustread) - struct buf *RCSpath; - struct stat *status; - int mustread; -/* Open RCSPATH for reading and yield its FILE* descriptor. - * If successful, set *STATUS to its status. - * Pass this routine to pairnames() for read-only access to the file. */ -{ - return Iopen(RCSpath->string, FOPEN_RB, status); -} - - static int -finopen(rcsopen, mustread) - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread; -/* - * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. - * Set finptr to the result and yield true if successful. - * RCSb holds the file's name. - * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. - * Yield true if successful or if an unusual failure. - */ -{ - int interesting, preferold; - - /* - * We prefer an old name to that of a nonexisting new RCS file, - * unless we tried locking the old name and failed. - */ - preferold = RCSbuf.string[0] && (mustread||0<=fdlock); - - finptr = (*rcsopen)(&RCSb, &RCSstat, mustread); - interesting = finptr || errno!=ENOENT; - if (interesting || !preferold) { - /* Use the new name. */ - RCSerrno = errno; - bufscpy(&RCSbuf, RCSb.string); - } - return interesting; -} - - static int -fin2open(d, dlen, base, baselen, x, xlen, rcsopen, mustread) - char const *d, *base, *x; - size_t dlen, baselen, xlen; - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread; -/* - * D is a directory name with length DLEN (including trailing slash). - * BASE is a filename with length BASELEN. - * X is an RCS pathname suffix with length XLEN. - * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read. - * Yield true if successful. - * Try dRCS/basex first; if that fails and x is nonempty, try dbasex. - * Put these potential names in RCSb. - * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno. - * Yield true if successful or if an unusual failure. - */ -{ - register char *p; - - bufalloc(&RCSb, dlen + rcslen + 1 + baselen + xlen + 1); - - /* Try dRCS/basex. */ - VOID memcpy(p = RCSb.string, d, dlen); - VOID memcpy(p += dlen, rcsdir, rcslen); - p += rcslen; - *p++ = SLASH; - VOID memcpy(p, base, baselen); - VOID memcpy(p += baselen, x, xlen); - p[xlen] = 0; - if (xlen) { - if (finopen(rcsopen, mustread)) - return true; - - /* Try dbasex. */ - /* Start from scratch, because finopen() may have changed RCSb. */ - VOID memcpy(p = RCSb.string, d, dlen); - VOID memcpy(p += dlen, base, baselen); - VOID memcpy(p += baselen, x, xlen); - p[xlen] = 0; - } - return finopen(rcsopen, mustread); -} - - int -pairnames(argc, argv, rcsopen, mustread, quiet) - int argc; - char **argv; - RILE *(*rcsopen)P((struct buf*,struct stat*,int)); - int mustread, quiet; -/* - * Pair the pathnames pointed to by argv; argc indicates - * how many there are. - * Place a pointer to the RCS pathname into RCSname, - * and a pointer to the pathname of the working file into workname. - * If both are given, and workstdout - * is set, a warning is printed. - * - * If the RCS file exists, places its status into RCSstat. - * - * If the RCS file exists, it is RCSOPENed for reading, the file pointer - * is placed into finptr, and the admin-node is read in; returns 1. - * If the RCS file does not exist and MUSTREAD, - * print an error unless QUIET and return 0. - * Otherwise, initialize the admin node and return -1. - * - * 0 is returned on all errors, e.g. files that are not regular files. - */ -{ - static struct buf tempbuf; - - register char *p, *arg, *RCS1; - char const *base, *RCSbase, *x; - int paired; - size_t arglen, dlen, baselen, xlen; - - fdlock = -1; - - if (!(arg = *argv)) return 0; /* already paired pathname */ - if (*arg == '-') { - error("%s option is ignored after pathnames", arg); - return 0; - } - - base = basefilename(arg); - paired = false; - - /* first check suffix to see whether it is an RCS file or not */ - if ((x = rcssuffix(arg))) - { - /* RCS pathname given */ - RCS1 = arg; - RCSbase = base; - baselen = x - base; - if ( - 1 < argc && - !rcssuffix(workname = p = argv[1]) && - baselen <= (arglen = strlen(p)) && - ((p+=arglen-baselen) == workname || isSLASH(p[-1])) && - memcmp(base, p, baselen) == 0 - ) { - argv[1] = 0; - paired = true; - } else { - bufscpy(&tempbuf, base); - workname = p = tempbuf.string; - p[baselen] = 0; - } - } else { - /* working file given; now try to find RCS file */ - workname = arg; - baselen = strlen(base); - /* Derive RCS pathname. */ - if ( - 1 < argc && - (x = rcssuffix(RCS1 = argv[1])) && - baselen <= x - RCS1 && - ((RCSbase=x-baselen)==RCS1 || isSLASH(RCSbase[-1])) && - memcmp(base, RCSbase, baselen) == 0 - ) { - argv[1] = 0; - paired = true; - } else - RCSbase = RCS1 = 0; - } - /* Now we have a (tentative) RCS pathname in RCS1 and workname. */ - /* Second, try to find the right RCS file */ - if (RCSbase!=RCS1) { - /* a path for RCSfile is given; single RCS file to look for */ - bufscpy(&RCSbuf, RCS1); - finptr = (*rcsopen)(&RCSbuf, &RCSstat, mustread); - RCSerrno = errno; - } else { - bufscpy(&RCSbuf, ""); - if (RCS1) - /* RCS filename was given without path. */ - VOID fin2open(arg, (size_t)0, RCSbase, baselen, - x, strlen(x), rcsopen, mustread - ); - else { - /* No RCS pathname was given. */ - /* Try each suffix in turn. */ - dlen = base-arg; - x = suffixes; - while (! fin2open(arg, dlen, base, baselen, - x, xlen=suffixlen(x), rcsopen, mustread - )) { - x += xlen; - if (!*x++) - break; - } - } - } - RCSname = p = RCSbuf.string; - if (finptr) { - if (!S_ISREG(RCSstat.st_mode)) { - error("%s isn't a regular file -- ignored", p); - return 0; - } - Lexinit(); getadmin(); - } else { - if (RCSerrno!=ENOENT || mustread || fdlock<0) { - if (RCSerrno == EEXIST) - error("RCS file %s is in use", p); - else if (!quiet || RCSerrno!=ENOENT) - enerror(RCSerrno, p); - return 0; - } - InitAdmin(); - }; - - if (paired && workstdout) - workwarn("Working file ignored due to -p option"); - - prevkeys = false; - return finptr ? 1 : -1; -} - - - char const * -getfullRCSname() -/* - * Return a pointer to the full pathname of the RCS file. - * Remove leading `./'. - */ -{ - if (ROOTPATH(RCSname)) { - return RCSname; - } else { - static struct buf rcsbuf; -# if needs_getabsname - bufalloc(&rcsbuf, SIZEABLE_PATH + 1); - while (getabsname(RCSname, rcsbuf.string, rcsbuf.size) != 0) - if (errno == ERANGE) - bufalloc(&rcsbuf, rcsbuf.size<<1); - else - efaterror("getabsname"); -# else - static char const *wdptr; - static struct buf wdbuf; - static size_t wdlen; - - register char const *r; - register size_t dlen; - register char *d; - register char const *wd; - - if (!(wd = wdptr)) { - /* Get working directory for the first time. */ - char *PWD = cgetenv("PWD"); - struct stat PWDstat, dotstat; - if (! ( - (d = PWD) && - ROOTPATH(PWD) && - stat(PWD, &PWDstat) == 0 && - stat(".", &dotstat) == 0 && - same_file(PWDstat, dotstat, 1) - )) { - bufalloc(&wdbuf, SIZEABLE_PATH + 1); -# if has_getcwd || !has_getwd - while (!(d = getcwd(wdbuf.string, wdbuf.size))) - if (errno == ERANGE) - bufalloc(&wdbuf, wdbuf.size<<1); - else if ((d = PWD)) - break; - else - efaterror("getcwd"); -# else - d = getwd(wdbuf.string); - if (!d && !(d = PWD)) - efaterror("getwd"); -# endif - } - wdlen = dir_useful_len(d); - d[wdlen] = 0; - wdptr = wd = d; - } - /* - * Remove leading `./'s from RCSname. - * Do not try to handle `../', since removing it may yield - * the wrong answer in the presence of symbolic links. - */ - for (r = RCSname; r[0]=='.' && isSLASH(r[1]); r += 2) - /* `.////' is equivalent to `./'. */ - while (isSLASH(r[2])) - r++; - /* Build full pathname. */ - dlen = wdlen; - bufalloc(&rcsbuf, dlen + strlen(r) + 2); - d = rcsbuf.string; - VOID memcpy(d, wd, dlen); - d += dlen; - *d++ = SLASH; - VOID strcpy(d, r); -# endif - return rcsbuf.string; - } -} - -/* Derived from code from the XFree86 project */ - char const * -getfullCVSname() -/* Function: returns a pointer to the path name of the RCS file with the - * CVSROOT part stripped off, and with 'Attic/' stripped off (if present). - */ -{ - -#define ATTICDIR "/Attic" - - char const *namebuf = getfullRCSname(); - char *cvsroot = cgetenv("CVSROOT"); - int cvsrootlen; - char *c = NULL; - int alen = strlen(ATTICDIR); - - if ((c = strrchr(namebuf, '/')) != NULL) { - if (namebuf - c >= alen) { - if (!strncmp(c - alen, ATTICDIR, alen)) { - while(*c != '\0') { - *(c - alen) = *c; - c++; - } - *(c - alen) = '\0'; - } - } - } - - if (!cvsroot) - return(namebuf); - else - { - cvsrootlen = strlen(cvsroot); - if (!strncmp(namebuf, cvsroot, cvsrootlen) && - namebuf[cvsrootlen] == '/') - return(namebuf + cvsrootlen + 1); - else - return(namebuf); - } -} - - static size_t -dir_useful_len(d) - char const *d; -/* -* D names a directory; yield the number of characters of D's useful part. -* To create a file in D, append a SLASH and a file name to D's useful part. -* Ignore trailing slashes if possible; not only are they ugly, -* but some non-Posix systems misbehave unless the slashes are omitted. -*/ -{ -# ifndef SLASHSLASH_is_SLASH -# define SLASHSLASH_is_SLASH 0 -# endif - size_t dlen = strlen(d); - if (!SLASHSLASH_is_SLASH && dlen==2 && isSLASH(d[0]) && isSLASH(d[1])) - --dlen; - else - while (dlen && isSLASH(d[dlen-1])) - --dlen; - return dlen; -} - -#ifndef isSLASH - int -isSLASH(c) - int c; -{ - switch (c) { - case SLASHes: - return true; - default: - return false; - } -} -#endif - - -#if !has_getcwd && !has_getwd - - char * -getcwd(path, size) - char *path; - size_t size; -{ - static char const usrbinpwd[] = "/usr/bin/pwd"; -# define binpwd (usrbinpwd+4) - - register FILE *fp; - register int c; - register char *p, *lim; - int closeerrno, closeerror, e, fd[2], readerror, toolong, wstatus; - pid_t child; - - if (!size) { - errno = EINVAL; - return 0; - } - if (pipe(fd) != 0) - return 0; -# if bad_wait_if_SIGCHLD_ignored -# ifndef SIGCHLD -# define SIGCHLD SIGCLD -# endif - VOID signal(SIGCHLD, SIG_DFL); -# endif - if (!(child = vfork())) { - if ( - close(fd[0]) == 0 && - (fd[1] == STDOUT_FILENO || -# ifdef F_DUPFD - (VOID close(STDOUT_FILENO), - fcntl(fd[1], F_DUPFD, STDOUT_FILENO)) -# else - dup2(fd[1], STDOUT_FILENO) -# endif - == STDOUT_FILENO && - close(fd[1]) == 0 - ) - ) { - VOID close(STDERR_FILENO); - VOID execl(binpwd, binpwd, (char *)0); - VOID execl(usrbinpwd, usrbinpwd, (char *)0); - } - _exit(EXIT_FAILURE); - } - e = errno; - closeerror = close(fd[1]); - closeerrno = errno; - fp = 0; - readerror = toolong = wstatus = 0; - p = path; - if (0 <= child) { - fp = fdopen(fd[0], "r"); - e = errno; - if (fp) { - lim = p + size; - for (p = path; ; *p++ = c) { - if ((c=getc(fp)) < 0) { - if (feof(fp)) - break; - if (ferror(fp)) { - readerror = 1; - e = errno; - break; - } - } - if (p == lim) { - toolong = 1; - break; - } - } - } -# if has_waitpid - if (waitpid(child, &wstatus, 0) < 0) - wstatus = 1; -# else - { - pid_t w; - do { - if ((w = wait(&wstatus)) < 0) { - wstatus = 1; - break; - } - } while (w != child); - } -# endif - } - if (!fp) { - VOID close(fd[0]); - errno = e; - return 0; - } - if (fclose(fp) != 0) - return 0; - if (readerror) { - errno = e; - return 0; - } - if (closeerror) { - errno = closeerrno; - return 0; - } - if (toolong) { - errno = ERANGE; - return 0; - } - if (wstatus || p == path || *--p != '\n') { - errno = EACCES; - return 0; - } - *p = '\0'; - return path; -} -#endif - - -#ifdef PAIRTEST -/* test program for pairnames() and getfullRCSname() */ - -char const cmdid[] = "pair"; - -main(argc, argv) -int argc; char *argv[]; -{ - int result; - int initflag; - quietflag = initflag = false; - - while(--argc, ++argv, argc>=1 && ((*argv)[0] == '-')) { - switch ((*argv)[1]) { - - case 'p': workstdout = stdout; - break; - case 'i': initflag=true; - break; - case 'q': quietflag=true; - break; - default: error("unknown option: %s", *argv); - break; - } - } - - do { - RCSname = workname = 0; - result = pairnames(argc,argv,rcsreadopen,!initflag,quietflag); - if (result!=0) { - diagnose("RCS pathname: %s; working pathname: %s\nFull RCS pathname: %s\n", - RCSname, workname, getfullRCSname() - ); - } - switch (result) { - case 0: continue; /* already paired file */ - - case 1: if (initflag) { - rcserror("already exists"); - } else { - diagnose("RCS file %s exists\n", RCSname); - } - Ifclose(finptr); - break; - - case -1:diagnose("RCS file doesn't exist\n"); - break; - } - - } while (++argv, --argc>=1); - -} - - void -exiterr() -{ - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} -#endif diff --git a/gnu/usr.bin/rcs/lib/rcsgen.c b/gnu/usr.bin/rcs/lib/rcsgen.c deleted file mode 100644 index 35d8702a34f8..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsgen.c +++ /dev/null @@ -1,681 +0,0 @@ -/* Generate RCS revisions. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.16 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.15 1995/06/01 16:23:43 eggert - * (putadmin): Open RCS file with FOPEN_WB. - * - * Revision 5.14 1994/03/17 14:05:48 eggert - * Work around SVR4 stdio performance bug. - * Flush stderr after prompt. Remove lint. - * - * Revision 5.13 1993/11/03 17:42:27 eggert - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.12 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * Be consistent about pathnames vs filenames. - * - * Revision 5.11 1992/01/24 18:44:19 eggert - * Move put routines here from rcssyn.c. - * Add support for bad_creat0. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Fix log bugs, e.g. ci -t/dev/null when has_mmap. - * - * Revision 5.9 1991/09/10 22:15:46 eggert - * Fix test for redirected stdin. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add piece tables. Tune. - * - * Revision 5.7 1991/04/21 11:58:24 eggert - * Add MS-DOS support. - * - * Revision 5.6 1990/12/27 19:54:26 eggert - * Fix bug: rcs -t inserted \n, making RCS file grow. - * - * Revision 5.5 1990/12/04 05:18:45 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:47 eggert - * Add -I and new -t behavior. Permit arbitrary data in logs. - * - * Revision 5.3 1990/09/21 06:12:43 hammer - * made putdesc() treat stdin the same whether or not it was from a terminal - * by making it recognize that a single '.' was then end of the - * description always - * - * Revision 5.2 1990/09/04 08:02:25 eggert - * Fix `co -p1.1 -ko' bug. Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:14:01 eggert - * Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:52 eggert - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. - * - * Revision 4.7 89/05/01 15:12:49 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.6 88/08/28 14:59:10 eggert - * Shrink stdio code size; allow cc -R; remove lint; isatty() -> ttystdin() - * - * Revision 4.5 87/12/18 11:43:25 narten - * additional lint cleanups, and a bug fix from the 4.3BSD version that - * keeps "ci" from sticking a '\377' into the description if you run it - * with a zero-length file as the description. (Guy Harris) - * - * Revision 4.4 87/10/18 10:35:10 narten - * Updating version numbers. Changes relative to 1.1 actually relative to - * 4.2 - * - * Revision 1.3 87/09/24 13:59:51 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:27 jenkins - * Port to suns - * - * Revision 4.2 83/12/02 23:01:39 wft - * merged 4.1 and 3.3.1.1 (clearerr(stdin)). - * - * Revision 4.1 83/05/10 16:03:33 wft - * Changed putamin() to abort if trying to reread redirected stdin. - * Fixed getdesc() to output a prompt on initial newline. - * - * Revision 3.3.1.1 83/10/19 04:21:51 lepreau - * Added clearerr(stdin) for re-reading description from stdin. - * - * Revision 3.3 82/11/28 21:36:49 wft - * 4.2 prerelease - * - * Revision 3.3 82/11/28 21:36:49 wft - * Replaced ferror() followed by fclose() with ffclose(). - * Putdesc() now suppresses the prompts if stdin - * is not a terminal. A pointer to the current log message is now - * inserted into the corresponding delta, rather than leaving it in a - * global variable. - * - * Revision 3.2 82/10/18 21:11:26 wft - * I added checks for write errors during editing, and improved - * the prompt on putdesc(). - * - * Revision 3.1 82/10/13 15:55:09 wft - * corrected type of variables assigned to by getc (char --> int) - */ - - - - -#include "rcsbase.h" - -libId(genId, "$FreeBSD$") - -int interactiveflag; /* Should we act as if stdin is a tty? */ -struct buf curlogbuf; /* buffer for current log message */ - -enum stringwork { enter, copy, edit, expand, edit_expand }; - -static void putdelta P((struct hshentry const*,FILE*)); -static void scandeltatext P((struct hshentry*,enum stringwork,int)); - - - - - char const * -buildrevision(deltas, target, outfile, expandflag) - struct hshentries const *deltas; - struct hshentry *target; - FILE *outfile; - int expandflag; -/* Function: Generates the revision given by target - * by retrieving all deltas given by parameter deltas and combining them. - * If outfile is set, the revision is output to it, - * otherwise written into a temporary file. - * Temporary files are allocated by maketemp(). - * if expandflag is set, keyword expansion is performed. - * Return 0 if outfile is set, the name of the temporary file otherwise. - * - * Algorithm: Copy initial revision unchanged. Then edit all revisions but - * the last one into it, alternating input and output files (resultname and - * editname). The last revision is then edited in, performing simultaneous - * keyword substitution (this saves one extra pass). - * All this simplifies if only one revision needs to be generated, - * or no keyword expansion is necessary, or if output goes to stdout. - */ -{ - if (deltas->first == target) { - /* only latest revision to generate */ - openfcopy(outfile); - scandeltatext(target, expandflag?expand:copy, true); - if (outfile) - return 0; - else { - Ozclose(&fcopy); - return resultname; - } - } else { - /* several revisions to generate */ - /* Get initial revision without keyword expansion. */ - scandeltatext(deltas->first, enter, false); - while ((deltas=deltas->rest)->rest) { - /* do all deltas except last one */ - scandeltatext(deltas->first, edit, false); - } - if (expandflag || outfile) { - /* first, get to beginning of file*/ - finishedit((struct hshentry*)0, outfile, false); - } - scandeltatext(target, expandflag?edit_expand:edit, true); - finishedit( - expandflag ? target : (struct hshentry*)0, - outfile, true - ); - if (outfile) - return 0; - Ozclose(&fcopy); - return resultname; - } -} - - - - static void -scandeltatext(delta, func, needlog) - struct hshentry *delta; - enum stringwork func; - int needlog; -/* Function: Scans delta text nodes up to and including the one given - * by delta. For the one given by delta, the log message is saved into - * delta->log if needlog is set; func specifies how to handle the text. - * Similarly, if needlog, delta->igtext is set to the ignored phrases. - * Assumes the initial lexeme must be read in first. - * Does not advance nexttok after it is finished. - */ -{ - struct hshentry const *nextdelta; - struct cbuf cb; - - for (;;) { - if (eoflex()) - fatserror("can't find delta for revision %s", delta->num); - nextlex(); - if (!(nextdelta=getnum())) { - fatserror("delta number corrupted"); - } - getkeystring(Klog); - if (needlog && delta==nextdelta) { - cb = savestring(&curlogbuf); - delta->log = cleanlogmsg(curlogbuf.string, cb.size); - nextlex(); - delta->igtext = getphrases(Ktext); - } else {readstring(); - ignorephrases(Ktext); - } - getkeystring(Ktext); - - if (delta==nextdelta) - break; - readstring(); /* skip over it */ - - } - switch (func) { - case enter: enterstring(); break; - case copy: copystring(); break; - case expand: xpandstring(delta); break; - case edit: editstring((struct hshentry *)0); break; - case edit_expand: editstring(delta); break; - } -} - - struct cbuf -cleanlogmsg(m, s) - char *m; - size_t s; -{ - register char *t = m; - register char const *f = t; - struct cbuf r; - while (s) { - --s; - if ((*t++ = *f++) == '\n') - while (m < --t) - if (t[-1]!=' ' && t[-1]!='\t') { - *t++ = '\n'; - break; - } - } - while (m < t && (t[-1]==' ' || t[-1]=='\t' || t[-1]=='\n')) - --t; - r.string = m; - r.size = t - m; - return r; -} - - -int ttystdin() -{ - static int initialized; - if (!initialized) { - if (!interactiveflag) - interactiveflag = isatty(STDIN_FILENO); - initialized = true; - } - return interactiveflag; -} - - int -getcstdin() -{ - register FILE *in; - register int c; - - in = stdin; - if (feof(in) && ttystdin()) - clearerr(in); - c = getc(in); - if (c == EOF) { - testIerror(in); - if (feof(in) && ttystdin()) - afputc('\n',stderr); - } - return c; -} - -#if has_prototypes - int -yesorno(int default_answer, char const *question, ...) -#else - /*VARARGS2*/ int - yesorno(default_answer, question, va_alist) - int default_answer; char const *question; va_dcl -#endif -{ - va_list args; - register int c, r; - if (!quietflag && ttystdin()) { - oflush(); - vararg_start(args, question); - fvfprintf(stderr, question, args); - va_end(args); - eflush(); - r = c = getcstdin(); - while (c!='\n' && !feof(stdin)) - c = getcstdin(); - if (r=='y' || r=='Y') - return true; - if (r=='n' || r=='N') - return false; - } - return default_answer; -} - - - void -putdesc(textflag, textfile) - int textflag; - char *textfile; -/* Function: puts the descriptive text into file frewrite. - * if finptr && !textflag, the text is copied from the old description. - * Otherwise, if textfile, the text is read from that - * file, or from stdin, if !textfile. - * A textfile with a leading '-' is treated as a string, not a pathname. - * If finptr, the old descriptive text is discarded. - * Always clears foutptr. - */ -{ - static struct buf desc; - static struct cbuf desclean; - - register FILE *txt; - register int c; - register FILE * frew; - register char *p; - register size_t s; - char const *plim; - - frew = frewrite; - if (finptr && !textflag) { - /* copy old description */ - aprintf(frew, "\n\n%s%c", Kdesc, nextc); - foutptr = frewrite; - getdesc(false); - foutptr = 0; - } else { - foutptr = 0; - /* get new description */ - if (finptr) { - /*skip old description*/ - getdesc(false); - } - aprintf(frew,"\n\n%s\n%c",Kdesc,SDELIM); - if (!textfile) - desclean = getsstdin( - "t-", "description", - "NOTE: This is NOT the log message!\n", &desc - ); - else if (!desclean.string) { - if (*textfile == '-') { - p = textfile + 1; - s = strlen(p); - } else { - if (!(txt = fopenSafer(textfile, "r"))) - efaterror(textfile); - bufalloc(&desc, 1); - p = desc.string; - plim = p + desc.size; - for (;;) { - if ((c=getc(txt)) == EOF) { - testIerror(txt); - if (feof(txt)) - break; - } - if (plim <= p) - p = bufenlarge(&desc, &plim); - *p++ = c; - } - if (fclose(txt) != 0) - Ierror(); - s = p - desc.string; - p = desc.string; - } - desclean = cleanlogmsg(p, s); - } - putstring(frew, false, desclean, true); - aputc_('\n', frew) - } -} - - struct cbuf -getsstdin(option, name, note, buf) - char const *option, *name, *note; - struct buf *buf; -{ - register int c; - register char *p; - register size_t i; - register int tty = ttystdin(); - - if (tty) { - aprintf(stderr, - "enter %s, terminated with single '.' or end of file:\n%s>> ", - name, note - ); - eflush(); - } else if (feof(stdin)) - rcsfaterror("can't reread redirected stdin for %s; use -%s<%s>", - name, option, name - ); - - for ( - i = 0, p = 0; - c = getcstdin(), !feof(stdin); - bufrealloc(buf, i+1), p = buf->string, p[i++] = c - ) - if (c == '\n') - if (i && p[i-1]=='.' && (i==1 || p[i-2]=='\n')) { - /* Remove trailing '.'. */ - --i; - break; - } else if (tty) { - aputs(">> ", stderr); - eflush(); - } - return cleanlogmsg(p, i); -} - - - void -putadmin() -/* Output the admin node. */ -{ - register FILE *fout; - struct assoc const *curassoc; - struct rcslock const *curlock; - struct access const *curaccess; - - if (!(fout = frewrite)) { -# if bad_creat0 - ORCSclose(); - fout = fopenSafer(makedirtemp(0), FOPEN_WB); -# else - int fo = fdlock; - fdlock = -1; - fout = fdopen(fo, FOPEN_WB); -# endif - - if (!(frewrite = fout)) - efaterror(RCSname); - } - - /* - * Output the first character with putc, not printf. - * Otherwise, an SVR4 stdio bug buffers output inefficiently. - */ - aputc_(*Khead, fout) - aprintf(fout, "%s\t%s;\n", Khead + 1, Head?Head->num:""); - if (Dbranch && VERSION(4)<=RCSversion) - aprintf(fout, "%s\t%s;\n", Kbranch, Dbranch); - - aputs(Kaccess, fout); - curaccess = AccessList; - while (curaccess) { - aprintf(fout, "\n\t%s", curaccess->login); - curaccess = curaccess->nextaccess; - } - aprintf(fout, ";\n%s", Ksymbols); - curassoc = Symbols; - while (curassoc) { - aprintf(fout, "\n\t%s:%s", curassoc->symbol, curassoc->num); - curassoc = curassoc->nextassoc; - } - aprintf(fout, ";\n%s", Klocks); - curlock = Locks; - while (curlock) { - aprintf(fout, "\n\t%s:%s", curlock->login, curlock->delta->num); - curlock = curlock->nextlock; - } - if (StrictLocks) aprintf(fout, "; %s", Kstrict); - aprintf(fout, ";\n"); - if (Comment.size) { - aprintf(fout, "%s\t", Kcomment); - putstring(fout, true, Comment, false); - aprintf(fout, ";\n"); - } - if (Expand != KEYVAL_EXPAND) - aprintf(fout, "%s\t%c%s%c;\n", - Kexpand, SDELIM, expand_names[Expand], SDELIM - ); - awrite(Ignored.string, Ignored.size, fout); - aputc_('\n', fout) -} - - - static void -putdelta(node, fout) - register struct hshentry const *node; - register FILE * fout; -/* Output the delta NODE to FOUT. */ -{ - struct branchhead const *nextbranch; - - if (!node) return; - - aprintf(fout, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches", - node->num, - Kdate, node->date, - Kauthor, node->author, - Kstate, node->state?node->state:"" - ); - nextbranch = node->branches; - while (nextbranch) { - aprintf(fout, "\n\t%s", nextbranch->hsh->num); - nextbranch = nextbranch->nextbranch; - } - - aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:""); - awrite(node->ig.string, node->ig.size, fout); -} - - - void -puttree(root, fout) - struct hshentry const *root; - register FILE *fout; -/* Output the delta tree with base ROOT in preorder to FOUT. */ -{ - struct branchhead const *nextbranch; - - if (!root) return; - - if (root->selector) - putdelta(root, fout); - - puttree(root->next, fout); - - nextbranch = root->branches; - while (nextbranch) { - puttree(nextbranch->hsh, fout); - nextbranch = nextbranch->nextbranch; - } -} - - - int -putdtext(delta, srcname, fout, diffmt) - struct hshentry const *delta; - char const *srcname; - FILE *fout; - int diffmt; -/* - * Output a deltatext node with delta number DELTA->num, log message DELTA->log, - * ignored phrases DELTA->igtext and text SRCNAME to FOUT. - * Double up all SDELIMs in both the log and the text. - * Make sure the log message ends in \n. - * Return false on error. - * If DIFFMT, also check that the text is valid diff -n output. - */ -{ - RILE *fin; - if (!(fin = Iopen(srcname, "r", (struct stat*)0))) { - eerror(srcname); - return false; - } - putdftext(delta, fin, fout, diffmt); - Ifclose(fin); - return true; -} - - void -putstring(out, delim, s, log) - register FILE *out; - struct cbuf s; - int delim, log; -/* - * Output to OUT one SDELIM if DELIM, then the string S with SDELIMs doubled. - * If LOG is set then S is a log string; append a newline if S is nonempty. - */ -{ - register char const *sp; - register size_t ss; - - if (delim) - aputc_(SDELIM, out) - sp = s.string; - for (ss = s.size; ss; --ss) { - if (*sp == SDELIM) - aputc_(SDELIM, out) - aputc_(*sp++, out) - } - if (s.size && log) - aputc_('\n', out) - aputc_(SDELIM, out) -} - - void -putdftext(delta, finfile, foutfile, diffmt) - struct hshentry const *delta; - RILE *finfile; - FILE *foutfile; - int diffmt; -/* like putdtext(), except the source file is already open */ -{ - declarecache; - register FILE *fout; - register int c; - register RILE *fin; - int ed; - struct diffcmd dc; - - fout = foutfile; - aprintf(fout, DELNUMFORM, delta->num, Klog); - - /* put log */ - putstring(fout, true, delta->log, true); - aputc_('\n', fout) - - /* put ignored phrases */ - awrite(delta->igtext.string, delta->igtext.size, fout); - - /* put text */ - aprintf(fout, "%s\n%c", Ktext, SDELIM); - - fin = finfile; - setupcache(fin); - if (!diffmt) { - /* Copy the file */ - cache(fin); - for (;;) { - cachegeteof_(c, break;) - if (c==SDELIM) aputc_(SDELIM, fout) /*double up SDELIM*/ - aputc_(c, fout) - } - } else { - initdiffcmd(&dc); - while (0 <= (ed = getdiffcmd(fin, false, fout, &dc))) - if (ed) { - cache(fin); - while (dc.nlines--) - do { - cachegeteof_(c, { if (!dc.nlines) goto OK_EOF; unexpected_EOF(); }) - if (c == SDELIM) - aputc_(SDELIM, fout) - aputc_(c, fout) - } while (c != '\n'); - uncache(fin); - } - } - OK_EOF: - aprintf(fout, "%c\n", SDELIM); -} diff --git a/gnu/usr.bin/rcs/lib/rcskeep.c b/gnu/usr.bin/rcs/lib/rcskeep.c deleted file mode 100644 index 4a90f851e615..000000000000 --- a/gnu/usr.bin/rcs/lib/rcskeep.c +++ /dev/null @@ -1,452 +0,0 @@ -/* Extract RCS keyword string values from working files. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.10 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.9 1995/06/01 16:23:43 eggert - * (getoldkeys): Don't panic if a Name: is empty. - * - * Revision 5.8 1994/03/17 14:05:48 eggert - * Remove lint. - * - * Revision 5.7 1993/11/09 17:40:15 eggert - * Use simpler timezone parsing strategy now that we're using ISO 8601 format. - * - * Revision 5.6 1993/11/03 17:42:27 eggert - * Scan for Name keyword. Improve quality of diagnostics. - * - * Revision 5.5 1992/07/28 16:12:44 eggert - * Statement macro names now end in _. - * - * Revision 5.4 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.3 1991/04/21 11:58:25 eggert - * Shorten names to keep them distinct on shortname hosts. - * - * Revision 5.2 1990/10/04 06:30:20 eggert - * Parse time zone offsets; future RCS versions may output them. - * - * Revision 5.1 1990/09/20 02:38:56 eggert - * ci -k now checks dates more thoroughly. - * - * Revision 5.0 1990/08/22 08:12:53 eggert - * Retrieve old log message if there is one. - * Don't require final newline. - * Remove compile-time limits; use malloc instead. Tune. - * Permit dates past 1999/12/31. Ansify and Posixate. - * - * Revision 4.6 89/05/01 15:12:56 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/09 19:13:03 eggert - * Remove lint and speed up by making FILE *fp local, not global. - * - * Revision 4.4 87/12/18 11:44:21 narten - * more lint cleanups (Guy Harris) - * - * Revision 4.3 87/10/18 10:35:50 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to 4.1 - * - * Revision 1.3 87/09/24 14:00:00 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:29 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 16:26:44 wft - * Added new markers Id and RCSfile; extraction added. - * Marker matching with trymatch(). - * - * Revision 3.2 82/12/24 12:08:26 wft - * added missing #endif. - * - * Revision 3.1 82/12/04 13:22:41 wft - * Initial revision. - * - */ - -#include "rcsbase.h" - -libId(keepId, "$FreeBSD$") - -static int badly_terminated P((void)); -static int checknum P((char const*)); -static int get0val P((int,RILE*,struct buf*,int)); -static int getval P((RILE*,struct buf*,int)); -static int keepdate P((RILE*)); -static int keepid P((int,RILE*,struct buf*)); -static int keeprev P((RILE*)); - -int prevkeys; -struct buf prevauthor, prevdate, prevname, prevrev, prevstate; - - int -getoldkeys(fp) - register RILE *fp; -/* Function: Tries to read keyword values for author, date, - * revision number, and state out of the file fp. - * If fp is null, workname is opened and closed instead of using fp. - * The results are placed into - * prevauthor, prevdate, prevname, prevrev, prevstate. - * Aborts immediately if it finds an error and returns false. - * If it returns true, it doesn't mean that any of the - * values were found; instead, check to see whether the corresponding arrays - * contain the empty string. - */ -{ - register int c; - char keyword[keylength+1]; - register char * tp; - int needs_closing; - int prevname_found; - - if (prevkeys) - return true; - - needs_closing = false; - if (!fp) { - if (!(fp = Iopen(workname, FOPEN_R_WORK, (struct stat*)0))) { - eerror(workname); - return false; - } - needs_closing = true; - } - - /* initialize to empty */ - bufscpy(&prevauthor, ""); - bufscpy(&prevdate, ""); - bufscpy(&prevname, ""); prevname_found = 0; - bufscpy(&prevrev, ""); - bufscpy(&prevstate, ""); - - c = '\0'; /* anything but KDELIM */ - for (;;) { - if ( c==KDELIM) { - do { - /* try to get keyword */ - tp = keyword; - for (;;) { - Igeteof_(fp, c, goto ok;) - switch (c) { - default: - if (keyword+keylength <= tp) - break; - *tp++ = c; - continue; - - case '\n': case KDELIM: case VDELIM: - break; - } - break; - } - } while (c==KDELIM); - if (c!=VDELIM) continue; - *tp = c; - Igeteof_(fp, c, break;) - switch (c) { - case ' ': case '\t': break; - default: continue; - } - - switch (trymatch(keyword)) { - case Author: - if (!keepid(0, fp, &prevauthor)) - return false; - c = 0; - break; - case Date: - if (!(c = keepdate(fp))) - return false; - break; - case Header: - case Id: - case LocalId: - if (!( - getval(fp, (struct buf*)0, false) && - keeprev(fp) && - (c = keepdate(fp)) && - keepid(c, fp, &prevauthor) && - keepid(0, fp, &prevstate) - )) - return false; - /* Skip either ``who'' (new form) or ``Locker: who'' (old). */ - if (getval(fp, (struct buf*)0, true) && - getval(fp, (struct buf*)0, true)) - c = 0; - else if (nerror) - return false; - else - c = KDELIM; - break; - case Locker: - (void) getval(fp, (struct buf*)0, false); - c = 0; - break; - case Log: - case RCSfile: - case Source: - if (!getval(fp, (struct buf*)0, false)) - return false; - c = 0; - break; - case Name: - if (getval(fp, &prevname, false)) { - if (*prevname.string) - checkssym(prevname.string); - prevname_found = 1; - } - c = 0; - break; - case Revision: - if (!keeprev(fp)) - return false; - c = 0; - break; - case State: - if (!keepid(0, fp, &prevstate)) - return false; - c = 0; - break; - default: - continue; - } - if (!c) - Igeteof_(fp, c, c=0;) - if (c != KDELIM) { - workerror("closing %c missing on keyword", KDELIM); - return false; - } - if (prevname_found && - *prevauthor.string && *prevdate.string && - *prevrev.string && *prevstate.string - ) - break; - } - Igeteof_(fp, c, break;) - } - - ok: - if (needs_closing) - Ifclose(fp); - else - Irewind(fp); - prevkeys = true; - return true; -} - - static int -badly_terminated() -{ - workerror("badly terminated keyword value"); - return false; -} - - static int -getval(fp, target, optional) - register RILE *fp; - struct buf *target; - int optional; -/* Reads a keyword value from FP into TARGET. - * Returns true if one is found, false otherwise. - * Does not modify target if it is 0. - * Do not report an error if OPTIONAL is set and KDELIM is found instead. - */ -{ - int c; - Igeteof_(fp, c, return badly_terminated();) - return get0val(c, fp, target, optional); -} - - static int -get0val(c, fp, target, optional) - register int c; - register RILE *fp; - struct buf *target; - int optional; -/* Reads a keyword value from C+FP into TARGET, perhaps OPTIONALly. - * Same as getval, except C is the lookahead character. - */ -{ register char * tp; - char const *tlim; - register int got1; - - if (target) { - bufalloc(target, 1); - tp = target->string; - tlim = tp + target->size; - } else - tlim = tp = 0; - got1 = false; - for (;;) { - switch (c) { - default: - got1 = true; - if (tp) { - *tp++ = c; - if (tlim <= tp) - tp = bufenlarge(target, &tlim); - } - break; - - case ' ': - case '\t': - if (tp) { - *tp = 0; -# ifdef KEEPTEST - VOID printf("getval: %s\n", target); -# endif - } - return got1; - - case KDELIM: - if (!got1 && optional) - return false; - /* fall into */ - case '\n': - case 0: - return badly_terminated(); - } - Igeteof_(fp, c, return badly_terminated();) - } -} - - - static int -keepdate(fp) - RILE *fp; -/* Function: reads a date prevdate; checks format - * Return 0 on error, lookahead character otherwise. - */ -{ - struct buf prevday, prevtime; - register int c; - - c = 0; - bufautobegin(&prevday); - if (getval(fp,&prevday,false)) { - bufautobegin(&prevtime); - if (getval(fp,&prevtime,false)) { - Igeteof_(fp, c, c=0;) - if (c) { - register char const *d = prevday.string, *t = prevtime.string; - bufalloc(&prevdate, strlen(d) + strlen(t) + 9); - VOID sprintf(prevdate.string, "%s%s %s%s", - /* Parse dates put out by old versions of RCS. */ - isdigit(d[0]) && isdigit(d[1]) && !isdigit(d[2]) - ? "19" : "", - d, t, - strchr(t,'-') || strchr(t,'+') ? "" : "+0000" - ); - } - } - bufautoend(&prevtime); - } - bufautoend(&prevday); - return c; -} - - static int -keepid(c, fp, b) - int c; - RILE *fp; - struct buf *b; -/* Get previous identifier from C+FP into B. */ -{ - if (!c) - Igeteof_(fp, c, return false;) - if (!get0val(c, fp, b, false)) - return false; - checksid(b->string); - return !nerror; -} - - static int -keeprev(fp) - RILE *fp; -/* Get previous revision from FP into prevrev. */ -{ - return getval(fp,&prevrev,false) && checknum(prevrev.string); -} - - - static int -checknum(s) - char const *s; -{ - register char const *sp; - register int dotcount = 0; - for (sp=s; ; sp++) { - switch (*sp) { - case 0: - if (dotcount & 1) - return true; - else - break; - - case '.': - dotcount++; - continue; - - default: - if (isdigit(*sp)) - continue; - break; - } - break; - } - workerror("%s is not a revision number", s); - return false; -} - - - -#ifdef KEEPTEST - -/* Print the keyword values found. */ - -char const cmdid[] ="keeptest"; - - int -main(argc, argv) -int argc; char *argv[]; -{ - while (*(++argv)) { - workname = *argv; - getoldkeys((RILE*)0); - VOID printf("%s: revision: %s, date: %s, author: %s, name: %s, state: %s\n", - *argv, prevrev.string, prevdate.string, prevauthor.string, prevname.string, prevstate.string); - } - exitmain(EXIT_SUCCESS); -} -#endif diff --git a/gnu/usr.bin/rcs/lib/rcskeys.c b/gnu/usr.bin/rcs/lib/rcskeys.c deleted file mode 100644 index 378f57dd0f77..000000000000 --- a/gnu/usr.bin/rcs/lib/rcskeys.c +++ /dev/null @@ -1,186 +0,0 @@ -/* RCS keyword table and match operation */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.4 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.3 1993/11/03 17:42:27 eggert - * Add Name keyword. - * - * Revision 5.2 1991/08/19 03:13:55 eggert - * Say `T const' instead of `const T'; it's less confusing for pointer types. - * (This change was made in other source files too.) - * - * Revision 5.1 1991/04/21 11:58:25 eggert - * Don't put , just before } in initializer. - * - * Revision 5.0 1990/08/22 08:12:54 eggert - * Add -k. Ansify and Posixate. - * - * Revision 4.3 89/05/01 15:13:02 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.2 87/10/18 10:36:33 narten - * Updating version numbers. Changes relative to 1.1 actuallyt - * relative to 4.1 - * - * Revision 1.2 87/09/24 14:00:10 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 4.1 83/05/04 10:06:53 wft - * Initial revision. - * - */ - - -#include "rcsbase.h" - -libId(keysId, "$FreeBSD$") - - -char const *Keyword[] = { - /* This must be in the same order as rcsbase.h's enum markers type. */ - 0, - AUTHOR, DATE, HEADER, IDH, - LOCKER, LOG, NAME, RCSFILE, REVISION, SOURCE, STATE, CVSHEADER, - NULL -}; - -/* Expand all keywords by default */ -static int ExpandKeyword[] = { - false, - true, true, true, true, - true, true, true, true, true, true, true, true, - true -}; -enum markers LocalIdMode = Id; - - enum markers -trymatch(string) - char const *string; -/* function: Checks whether string starts with a keyword followed - * by a KDELIM or a VDELIM. - * If successful, returns the appropriate marker, otherwise Nomatch. - */ -{ - register int j; - register char const *p, *s; - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) { - if (!ExpandKeyword[j]) - continue; - /* try next keyword */ - p = Keyword[j]; - if (p == NULL) - continue; - s = string; - while (*p++ == *s++) { - if (!*p) - switch (*s) { - case KDELIM: - case VDELIM: - return (enum markers)j; - default: - return Nomatch; - } - } - } - return(Nomatch); -} - - void -setIncExc(arg) - char const *arg; -/* Sets up the ExpandKeyword table according to command-line flags */ -{ - char *key; - char *copy, *next; - int include = 0, j; - - copy = strdup(arg); - next = copy; - switch (*next++) { - case 'e': - include = false; - break; - case 'i': - include = true; - break; - default: - free(copy); - return; - } - if (include) - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) - ExpandKeyword[j] = false; - key = strtok(next, ","); - while (key) { - for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) { - if (Keyword[j] == NULL) - continue; - if (!strcmp(key, Keyword[j])) - ExpandKeyword[j] = include; - } - key = strtok(NULL, ","); - } - free(copy); - return; -} - - void -setRCSLocalId(string) - char const *string; -/* function: sets local RCS id and RCSLOCALID envariable */ -{ - static char local_id[keylength+1]; - char *copy, *next, *key; - int j; - - copy = strdup(string); - next = copy; - key = strtok(next, "="); - if (strlen(key) > keylength) - faterror("LocalId is too long"); - VOID strcpy(local_id, key); - Keyword[LocalId] = local_id; - - /* options? */ - while (key = strtok(NULL, ",")) { - if (!strcmp(key, Keyword[Id])) - LocalIdMode=Id; - else if (!strcmp(key, Keyword[Header])) - LocalIdMode=Header; - else if (!strcmp(key, Keyword[CVSHeader])) - LocalIdMode=CVSHeader; - else - error("Unknown LocalId mode"); - } - free(copy); -} diff --git a/gnu/usr.bin/rcs/lib/rcslex.c b/gnu/usr.bin/rcs/lib/rcslex.c deleted file mode 100644 index 7a11f79b46c8..000000000000 --- a/gnu/usr.bin/rcs/lib/rcslex.c +++ /dev/null @@ -1,1568 +0,0 @@ -/* lexical analysis of RCS files */ - -/****************************************************************************** - * Lexical Analysis. - * hashtable, Lexinit, nextlex, getlex, getkey, - * getid, getnum, readstring, printstring, savestring, - * checkid, fatserror, error, faterror, warn, diagnose - * Testprogram: define LEXDB - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - -/* - * Revision 5.19 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (map_fd_deallocate,mmap_deallocate,read_deallocate,nothing_to_deallocate): - * New functions. - * (Iclose): If large_memory and maps_memory, use them to deallocate mapping. - * (fd2RILE): Use map_fd if available. - * If one mapping method fails, try the next instead of giving up; - * if they all fail, fall back on ordinary read. - * Work around bug: root mmap over NFS succeeds, but accessing dumps core. - * Use MAP_FAILED macro for mmap failure, and `char *' instead of caddr_t. - * (advise_access): Use madvise only if this instance used mmap. - * (Iopen): Use fdSafer to get safer file descriptor. - * (aflush): Moved here from rcsedit.c. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Don't worry if madvise fails. Add Orewind. Remove lint. - * - * Revision 5.16 1993/11/09 17:55:29 eggert - * Fix `label: }' typo. - * - * Revision 5.15 1993/11/03 17:42:27 eggert - * Improve quality of diagnostics by putting file names in them more often. - * Don't discard ignored phrases. - * - * Revision 5.14 1992/07/28 16:12:44 eggert - * Identifiers may now start with a digit and (unless they are symbolic names) - * may contain `.'. Avoid `unsigned'. Statement macro names now end in _. - * - * Revision 5.13 1992/02/17 23:02:27 eggert - * Work around NFS mmap SIGBUS problem. - * - * Revision 5.12 1992/01/06 02:42:34 eggert - * Use OPEN_O_BINARY if mode contains 'b'. - * - * Revision 5.11 1991/11/03 03:30:44 eggert - * Fix porting bug to ancient hosts lacking vfprintf. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.9 1991/09/24 00:28:42 eggert - * Don't export errsay(). - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Add eoflex(), mmap support. Tune. - * - * Revision 5.7 1991/04/21 11:58:26 eggert - * Add MS-DOS support. - * - * Revision 5.6 1991/02/25 07:12:42 eggert - * Work around fputs bug. strsave -> str_save (DG/UX name clash) - * - * Revision 5.5 1990/12/04 05:18:47 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/19 20:05:28 hammer - * no longer gives warning about unknown keywords if -q is specified - * - * Revision 5.3 1990/11/01 05:03:48 eggert - * When ignoring unknown phrases, copy them to the output RCS file. - * - * Revision 5.2 1990/09/04 08:02:27 eggert - * Count RCS lines better. - * - * Revision 5.1 1990/08/29 07:14:03 eggert - * Work around buggy compilers with defective argument promotion. - * - * Revision 5.0 1990/08/22 08:12:55 eggert - * Remove compile-time limits; use malloc instead. - * Report errno-related errors with perror(). - * Ansify and Posixate. Add support for ISO 8859. - * Use better hash function. - * - * Revision 4.6 89/05/01 15:13:07 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/28 15:01:12 eggert - * Don't loop when writing error messages to a full filesystem. - * Flush stderr/stdout when mixing output. - * Yield exit status compatible with diff(1). - * Shrink stdio code size; allow cc -R; remove lint. - * - * Revision 4.4 87/12/18 11:44:47 narten - * fixed to use "varargs" in "fprintf"; this is required if it is to - * work on a SPARC machine such as a Sun-4 - * - * Revision 4.3 87/10/18 10:37:18 narten - * Updating version numbers. Changes relative to 1.1 actually relative - * to version 4.1 - * - * Revision 1.3 87/09/24 14:00:17 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:33 jenkins - * Port to suns - * - * Revision 4.1 83/03/25 18:12:51 wft - * Only changed $Header to $Id. - * - * Revision 3.3 82/12/10 16:22:37 wft - * Improved error messages, changed exit status on error to 1. - * - * Revision 3.2 82/11/28 21:27:10 wft - * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h. - * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations - * properly in case there is an IO-error (e.g., file system full). - * - * Revision 3.1 82/10/11 19:43:56 wft - * removed unused label out:; - * made sure all calls to getc() return into an integer, not a char. - */ - - -/* -#define LEXDB -*/ -/* version LEXDB is for testing the lexical analyzer. The testprogram - * reads a stream of lexemes, enters the revision numbers into the - * hashtable, and prints the recognized tokens. Keywords are recognized - * as identifiers. - */ - - - -#include "rcsbase.h" - -libId(lexId, "$FreeBSD$") - -static char *checkidentifier P((char*,int,int)); -static void errsay P((char const*)); -static void fatsay P((char const*)); -static void lookup P((char const*)); -static void startsay P((const char*,const char*)); -static void warnsay P((char const*)); - -static struct hshentry *nexthsh; /*pointer to next hash entry, set by lookup*/ - -enum tokens nexttok; /*next token, set by nextlex */ - -int hshenter; /*if true, next suitable lexeme will be entered */ - /*into the symbol table. Handle with care. */ -int nextc; /*next input character, initialized by Lexinit */ - -long rcsline; /*current line-number of input */ -int nerror; /*counter for errors */ -int quietflag; /*indicates quiet mode */ -RILE * finptr; /*input file descriptor */ - -FILE * frewrite; /*file descriptor for echoing input */ - -FILE * foutptr; /* copy of frewrite, but 0 to suppress echo */ - -static struct buf tokbuf; /* token buffer */ - -char const * NextString; /* next token */ - -/* - * Our hash algorithm is h[0] = 0, h[i+1] = 4*h[i] + c, - * so hshsize should be odd. - * See B J McKenzie, R Harries & T Bell, Selecting a hashing algorithm, - * Software--practice & experience 20, 2 (Feb 1990), 209-224. - */ -#ifndef hshsize -# define hshsize 511 -#endif - -static struct hshentry *hshtab[hshsize]; /*hashtable */ - -static int ignored_phrases; /* have we ignored phrases in this RCS file? */ - - void -warnignore() -{ - if (!ignored_phrases) { - ignored_phrases = true; - rcswarn("Unknown phrases like `%s ...;' are present.", NextString); - } -} - - - - static void -lookup(str) - char const *str; -/* Function: Looks up the character string pointed to by str in the - * hashtable. If the string is not present, a new entry for it is created. - * In any case, the address of the corresponding hashtable entry is placed - * into nexthsh. - */ -{ - register unsigned ihash; /* index into hashtable */ - register char const *sp; - register struct hshentry *n, **p; - - /* calculate hash code */ - sp = str; - ihash = 0; - while (*sp) - ihash = (ihash<<2) + *sp++; - ihash %= hshsize; - - for (p = &hshtab[ihash]; ; p = &n->nexthsh) - if (!(n = *p)) { - /* empty slot found */ - *p = n = ftalloc(struct hshentry); - n->num = fstr_save(str); - n->nexthsh = 0; -# ifdef LEXDB - VOID printf("\nEntered: %s at %u ", str, ihash); -# endif - break; - } else if (strcmp(str, n->num) == 0) - /* match found */ - break; - nexthsh = n; - NextString = n->num; -} - - - - - - - void -Lexinit() -/* Function: Initialization of lexical analyzer: - * initializes the hashtable, - * initializes nextc, nexttok if finptr != 0 - */ -{ register int c; - - for (c = hshsize; 0 <= --c; ) { - hshtab[c] = 0; - } - - nerror = 0; - if (finptr) { - foutptr = 0; - hshenter = true; - ignored_phrases = false; - rcsline = 1; - bufrealloc(&tokbuf, 2); - Iget_(finptr, nextc) - nextlex(); /*initial token*/ - } -} - - - - - - - - void -nextlex() - -/* Function: Reads the next token and sets nexttok to the next token code. - * Only if hshenter is set, a revision number is entered into the - * hashtable and a pointer to it is placed into nexthsh. - * This is useful for avoiding that dates are placed into the hashtable. - * For ID's and NUM's, NextString is set to the character string. - * Assumption: nextc contains the next character. - */ -{ register c; - declarecache; - register FILE *frew; - register char * sp; - char const *limit; - register enum tokens d; - register RILE *fin; - - fin=finptr; frew=foutptr; - setupcache(fin); cache(fin); - c = nextc; - - for (;;) { switch ((d = ctab[c])) { - - default: - fatserror("unknown character `%c'", c); - /*NOTREACHED*/ - - case NEWLN: - ++rcsline; -# ifdef LEXDB - afputc('\n',stdout); -# endif - /* Note: falls into next case */ - - case SPACE: - GETC_(frew, c) - continue; - - case IDCHAR: - case LETTER: - case Letter: - d = ID; - /* fall into */ - case DIGIT: - case PERIOD: - sp = tokbuf.string; - limit = sp + tokbuf.size; - *sp++ = c; - for (;;) { - GETC_(frew, c) - switch (ctab[c]) { - case IDCHAR: - case LETTER: - case Letter: - d = ID; - /* fall into */ - case DIGIT: - case PERIOD: - *sp++ = c; - if (limit <= sp) - sp = bufenlarge(&tokbuf, &limit); - continue; - - default: - break; - } - break; - } - *sp = 0; - if (d == DIGIT || d == PERIOD) { - d = NUM; - if (hshenter) { - lookup(tokbuf.string); - break; - } - } - NextString = fstr_save(tokbuf.string); - break; - - case SBEGIN: /* long string */ - d = STRING; - /* note: only the initial SBEGIN has been read*/ - /* read the string, and reset nextc afterwards*/ - break; - - case COLON: - case SEMI: - GETC_(frew, c) - break; - } break; } - nextc = c; - nexttok = d; - uncache(fin); -} - - int -eoflex() -/* - * Yield true if we look ahead to the end of the input, false otherwise. - * nextc becomes undefined at end of file. - */ -{ - register int c; - declarecache; - register FILE *fout; - register RILE *fin; - - c = nextc; - fin = finptr; - fout = foutptr; - setupcache(fin); cache(fin); - - for (;;) { - switch (ctab[c]) { - default: - nextc = c; - uncache(fin); - return false; - - case NEWLN: - ++rcsline; - /* fall into */ - case SPACE: - cachegeteof_(c, {uncache(fin);return true;}) - break; - } - if (fout) - aputc_(c, fout) - } -} - - -int getlex(token) -enum tokens token; -/* Function: Checks if nexttok is the same as token. If so, - * advances the input by calling nextlex and returns true. - * otherwise returns false. - * Doesn't work for strings and keywords; loses the character string for ids. - */ -{ - if (nexttok==token) { - nextlex(); - return(true); - } else return(false); -} - - int -getkeyopt(key) - char const *key; -/* Function: If the current token is a keyword identical to key, - * advances the input by calling nextlex and returns true; - * otherwise returns false. - */ -{ - if (nexttok==ID && strcmp(key,NextString) == 0) { - /* match found */ - ffree1(NextString); - nextlex(); - return(true); - } - return(false); -} - - void -getkey(key) - char const *key; -/* Check that the current input token is a keyword identical to key, - * and advance the input by calling nextlex. - */ -{ - if (!getkeyopt(key)) - fatserror("missing '%s' keyword", key); -} - - void -getkeystring(key) - char const *key; -/* Check that the current input token is a keyword identical to key, - * and advance the input by calling nextlex; then look ahead for a string. - */ -{ - getkey(key); - if (nexttok != STRING) - fatserror("missing string after '%s' keyword", key); -} - - - char const * -getid() -/* Function: Checks if nexttok is an identifier. If so, - * advances the input by calling nextlex and returns a pointer - * to the identifier; otherwise returns 0. - * Treats keywords as identifiers. - */ -{ - register char const *name; - if (nexttok==ID) { - name = NextString; - nextlex(); - return name; - } else - return 0; -} - - -struct hshentry * getnum() -/* Function: Checks if nexttok is a number. If so, - * advances the input by calling nextlex and returns a pointer - * to the hashtable entry. Otherwise returns 0. - * Doesn't work if hshenter is false. - */ -{ - register struct hshentry * num; - if (nexttok==NUM) { - num=nexthsh; - nextlex(); - return num; - } else - return 0; -} - - struct cbuf -getphrases(key) - char const *key; -/* -* Get a series of phrases that do not start with KEY. Yield resulting buffer. -* Stop when the next phrase starts with a token that is not an identifier, -* or is KEY. Copy input to foutptr if it is set. Unlike ignorephrases(), -* this routine assumes nextlex() has already been invoked before we start. -*/ -{ - declarecache; - register int c; - register char const *kn; - struct cbuf r; - register RILE *fin; - register FILE *frew; -# if large_memory -# define savech_(c) ; -# else - register char *p; - char const *limit; - struct buf b; -# define savech_(c) {if (limit<=p)p=bufenlarge(&b,&limit); *p++ =(c);} -# endif - - if (nexttok!=ID || strcmp(NextString,key) == 0) - clear_buf(&r); - else { - warnignore(); - fin = finptr; - frew = foutptr; - setupcache(fin); cache(fin); -# if large_memory - r.string = (char const*)cacheptr() - strlen(NextString) - 1; -# else - bufautobegin(&b); - bufscpy(&b, NextString); - p = b.string + strlen(b.string); - limit = b.string + b.size; -# endif - ffree1(NextString); - c = nextc; - for (;;) { - for (;;) { - savech_(c) - switch (ctab[c]) { - default: - fatserror("unknown character `%c'", c); - /*NOTREACHED*/ - case NEWLN: - ++rcsline; - /* fall into */ - case COLON: case DIGIT: case LETTER: case Letter: - case PERIOD: case SPACE: - GETC_(frew, c) - continue; - case SBEGIN: /* long string */ - for (;;) { - for (;;) { - GETC_(frew, c) - savech_(c) - switch (c) { - case '\n': - ++rcsline; - /* fall into */ - default: - continue; - - case SDELIM: - break; - } - break; - } - GETC_(frew, c) - if (c != SDELIM) - break; - savech_(c) - } - continue; - case SEMI: - cacheget_(c) - if (ctab[c] == NEWLN) { - if (frew) - aputc_(c, frew) - ++rcsline; - savech_(c) - cacheget_(c) - } -# if large_memory - r.size = (char const*)cacheptr() - 1 - r.string; -# endif - for (;;) { - switch (ctab[c]) { - case NEWLN: - ++rcsline; - /* fall into */ - case SPACE: - cacheget_(c) - continue; - - default: break; - } - break; - } - if (frew) - aputc_(c, frew) - break; - } - break; - } - if (ctab[c] == Letter) { - for (kn = key; c && *kn==c; kn++) - GETC_(frew, c) - if (!*kn) - switch (ctab[c]) { - case DIGIT: case LETTER: case Letter: - case IDCHAR: case PERIOD: - break; - default: - nextc = c; - NextString = fstr_save(key); - nexttok = ID; - uncache(fin); - goto returnit; - } -# if !large_memory - { - register char const *ki; - for (ki=key; kistring; limit = tp + target->size; - for (;;) { - GETC_(frew, c) - switch (c) { - case '\n': - ++rcsline; - break; - case SDELIM: - GETC_(frew, c) - if (c != SDELIM) { - /* end of string */ - nextc=c; - r.string = target->string; - r.size = tp - r.string; - uncache(fin); - return r; - } - break; - } - if (tp == limit) - tp = bufenlarge(target, &limit); - *tp++ = c; - } -} - - - static char * -checkidentifier(id, delimiter, dotok) - register char *id; - int delimiter; - register int dotok; -/* Function: check whether the string starting at id is an */ -/* identifier and return a pointer to the delimiter*/ -/* after the identifier. White space, delim and 0 */ -/* are legal delimiters. Aborts the program if not*/ -/* a legal identifier. Useful for checking commands*/ -/* If !delim, the only delimiter is 0. */ -/* Allow '.' in identifier only if DOTOK is set. */ -{ - register char *temp; - register char c; - register char delim = delimiter; - int isid = false; - - temp = id; - for (;; id++) { - switch (ctab[(unsigned char)(c = *id)]) { - case IDCHAR: - case LETTER: - case Letter: - isid = true; - continue; - - case DIGIT: - continue; - - case PERIOD: - if (dotok) - continue; - break; - - default: - break; - } - break; - } - if ( ! isid - || (c && (!delim || (c!=delim && c!=' ' && c!='\t' && c!='\n'))) - ) { - /* append \0 to end of id before error message */ - while ((c = *id) && c!=' ' && c!='\t' && c!='\n' && c!=delim) - id++; - *id = '\0'; - faterror("invalid %s `%s'", - dotok ? "identifier" : "symbol", temp - ); - } - return id; -} - - char * -checkid(id, delimiter) - char *id; - int delimiter; -{ - return checkidentifier(id, delimiter, true); -} - - char * -checksym(sym, delimiter) - char *sym; - int delimiter; -{ - return checkidentifier(sym, delimiter, false); -} - - void -checksid(id) - char *id; -/* Check whether the string ID is an identifier. */ -{ - VOID checkid(id, 0); -} - - void -checkssym(sym) - char *sym; -{ - VOID checksym(sym, 0); -} - - -#if !large_memory -# define Iclose(f) fclose(f) -#else -# if !maps_memory - static int Iclose P((RILE *)); - static int - Iclose(f) - register RILE *f; - { - tfree(f->base); - f->base = 0; - return fclose(f->stream); - } -# else - static int Iclose P((RILE *)); - static int - Iclose(f) - register RILE *f; - { - (* f->deallocate) (f); - f->base = 0; - return close(f->fd); - } - -# if has_map_fd - static void map_fd_deallocate P((RILE *)); - static void - map_fd_deallocate(f) - register RILE *f; - { - if (vm_deallocate( - task_self(), - (vm_address_t) f->base, - (vm_size_t) (f->lim - f->base) - ) != KERN_SUCCESS) - efaterror("vm_deallocate"); - } -# endif -# if has_mmap - static void mmap_deallocate P((RILE *)); - static void - mmap_deallocate(f) - register RILE *f; - { - if (munmap((char *) f->base, (size_t) (f->lim - f->base)) != 0) - efaterror("munmap"); - } -# endif - static void read_deallocate P((RILE *)); - static void - read_deallocate(f) - RILE *f; - { - tfree(f->base); - } - - static void nothing_to_deallocate P((RILE *)); - static void - nothing_to_deallocate(f) - RILE *f; - { - } -# endif -#endif - - -#if large_memory && maps_memory - static RILE *fd2_RILE P((int,char const*,struct stat*)); - static RILE * -fd2_RILE(fd, name, status) -#else - static RILE *fd2RILE P((int,char const*,char const*,struct stat*)); - static RILE * -fd2RILE(fd, name, type, status) - char const *type; -#endif - int fd; - char const *name; - register struct stat *status; -{ - struct stat st; - - if (!status) - status = &st; - if (fstat(fd, status) != 0) - efaterror(name); - if (!S_ISREG(status->st_mode)) { - error("`%s' is not a regular file", name); - VOID close(fd); - errno = EINVAL; - return 0; - } else { - -# if !(large_memory && maps_memory) - FILE *stream; - if (!(stream = fdopen(fd, type))) - efaterror(name); -# endif - -# if !large_memory - return stream; -# else -# define RILES 3 - { - static RILE rilebuf[RILES]; - - register RILE *f; - size_t s = status->st_size; - - if (s != status->st_size) - faterror("%s: too large", name); - for (f = rilebuf; f->base; f++) - if (f == rilebuf+RILES) - faterror("too many RILEs"); -# if maps_memory - f->deallocate = nothing_to_deallocate; -# endif - if (!s) { - static unsigned char nothing; - f->base = ¬hing; /* Any nonzero address will do. */ - } else { - f->base = 0; -# if has_map_fd - map_fd( - fd, (vm_offset_t)0, (vm_address_t*) &f->base, - TRUE, (vm_size_t)s - ); - f->deallocate = map_fd_deallocate; -# endif -# if has_mmap - if (!f->base) { - catchmmapints(); - f->base = (unsigned char *) mmap( - (char *)0, s, PROT_READ, MAP_SHARED, - fd, (off_t)0 - ); -# ifndef MAP_FAILED -# define MAP_FAILED (-1) -# endif - if (f->base == (unsigned char *) MAP_FAILED) - f->base = 0; - else { -# if has_NFS && mmap_signal - /* - * On many hosts, the superuser - * can mmap an NFS file it can't read. - * So access the first page now, and print - * a nice message if a bus error occurs. - */ - readAccessFilenameBuffer(name, f->base); -# endif - } - f->deallocate = mmap_deallocate; - } -# endif - if (!f->base) { - f->base = tnalloc(unsigned char, s); -# if maps_memory - { - /* - * We can't map the file into memory for some reason. - * Read it into main memory all at once; this is - * the simplest substitute for memory mapping. - */ - char *bufptr = (char *) f->base; - size_t bufsiz = s; - do { - ssize_t r = read(fd, bufptr, bufsiz); - switch (r) { - case -1: - efaterror(name); - - case 0: - /* The file must have shrunk! */ - status->st_size = s -= bufsiz; - bufsiz = 0; - break; - - default: - bufptr += r; - bufsiz -= r; - break; - } - } while (bufsiz); - if (lseek(fd, (off_t)0, SEEK_SET) == -1) - efaterror(name); - f->deallocate = read_deallocate; - } -# endif - } - } - f->ptr = f->base; - f->lim = f->base + s; - f->fd = fd; -# if !maps_memory - f->readlim = f->base; - f->stream = stream; -# endif - if_advise_access(s, f, MADV_SEQUENTIAL); - return f; - } -# endif - } -} - -#if !maps_memory && large_memory - int -Igetmore(f) - register RILE *f; -{ - register fread_type r; - register size_t s = f->lim - f->readlim; - - if (BUFSIZ < s) - s = BUFSIZ; - if (!(r = Fread(f->readlim, sizeof(*f->readlim), s, f->stream))) { - testIerror(f->stream); - f->lim = f->readlim; /* The file might have shrunk! */ - return 0; - } - f->readlim += r; - return 1; -} -#endif - -#if has_madvise && has_mmap && large_memory - void -advise_access(f, advice) - register RILE *f; - int advice; -{ - if (f->deallocate == mmap_deallocate) - VOID madvise((char *)f->base, (size_t)(f->lim - f->base), advice); - /* Don't worry if madvise fails; it's only advisory. */ -} -#endif - - RILE * -#if large_memory && maps_memory -I_open(name, status) -#else -Iopen(name, type, status) - char const *type; -#endif - char const *name; - struct stat *status; -/* Open NAME for reading, yield its descriptor, and set *STATUS. */ -{ - int fd = fdSafer(open(name, O_RDONLY -# if OPEN_O_BINARY - | (strchr(type,'b') ? OPEN_O_BINARY : 0) -# endif - )); - - if (fd < 0) - return 0; -# if large_memory && maps_memory - return fd2_RILE(fd, name, status); -# else - return fd2RILE(fd, name, type, status); -# endif -} - - -static int Oerrloop; - - void -Oerror() -{ - if (Oerrloop) - exiterr(); - Oerrloop = true; - efaterror("output error"); -} - -void Ieof() { fatserror("unexpected end of file"); } -void Ierror() { efaterror("input error"); } -void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); } -void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); } - -void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); } -void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); } -void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; } -void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; } - -#if !large_memory - void -testIeof(f) - FILE *f; -{ - testIerror(f); - if (feof(f)) - Ieof(); -} -void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); } -#endif - -void Orewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Oerror(); } - -void aflush(f) FILE *f; { if (fflush(f) != 0) Oerror(); } -void eflush() { if (fflush(stderr)!=0 && !Oerrloop) Oerror(); } -void oflush() -{ - if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop) - Oerror(); -} - - void -fatcleanup(already_newline) - int already_newline; -{ - VOID fprintf(stderr, already_newline+"\n%s aborted\n", cmdid); - exiterr(); -} - - static void -startsay(s, t) - const char *s, *t; -{ - oflush(); - if (s) - aprintf(stderr, "%s: %s: %s", cmdid, s, t); - else - aprintf(stderr, "%s: %s", cmdid, t); -} - - static void -fatsay(s) - char const *s; -{ - startsay(s, ""); -} - - static void -errsay(s) - char const *s; -{ - fatsay(s); - nerror++; -} - - static void -warnsay(s) - char const *s; -{ - startsay(s, "warning: "); -} - -void eerror(s) char const *s; { enerror(errno,s); } - - void -enerror(e,s) - int e; - char const *s; -{ - errsay((char const*)0); - errno = e; - perror(s); - eflush(); -} - -void efaterror(s) char const *s; { enfaterror(errno,s); } - - void -enfaterror(e,s) - int e; - char const *s; -{ - fatsay((char const*)0); - errno = e; - perror(s); - fatcleanup(true); -} - -#if has_prototypes - void -error(char const *format,...) -#else - /*VARARGS1*/ void error(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal error */ -{ - va_list args; - errsay((char const*)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -rcserror(char const *format,...) -#else - /*VARARGS1*/ void rcserror(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal RCS file error */ -{ - va_list args; - errsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -workerror(char const *format,...) -#else - /*VARARGS1*/ void workerror(format, va_alist) char const *format; va_dcl -#endif -/* non-fatal working file error */ -{ - va_list args; - errsay(workname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n',stderr); - eflush(); -} - -#if has_prototypes - void -fatserror(char const *format,...) -#else - /*VARARGS1*/ void - fatserror(format, va_alist) char const *format; va_dcl -#endif -/* fatal RCS file syntax error */ -{ - va_list args; - oflush(); - VOID fprintf(stderr, "%s: %s:%ld: ", cmdid, RCSname, rcsline); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -faterror(char const *format,...) -#else - /*VARARGS1*/ void faterror(format, va_alist) - char const *format; va_dcl -#endif -/* fatal error, terminates program after cleanup */ -{ - va_list args; - fatsay((char const*)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -rcsfaterror(char const *format,...) -#else - /*VARARGS1*/ void rcsfaterror(format, va_alist) - char const *format; va_dcl -#endif -/* fatal RCS file error, terminates program after cleanup */ -{ - va_list args; - fatsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - fatcleanup(false); -} - -#if has_prototypes - void -warn(char const *format,...) -#else - /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl -#endif -/* warning */ -{ - va_list args; - if (!quietflag) { - warnsay((char *)0); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - -#if has_prototypes - void -rcswarn(char const *format,...) -#else - /*VARARGS1*/ void rcswarn(format, va_alist) char const *format; va_dcl -#endif -/* RCS file warning */ -{ - va_list args; - if (!quietflag) { - warnsay(RCSname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - -#if has_prototypes - void -workwarn(char const *format,...) -#else - /*VARARGS1*/ void workwarn(format, va_alist) char const *format; va_dcl -#endif -/* working file warning */ -{ - va_list args; - if (!quietflag) { - warnsay(workname); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - afputc('\n', stderr); - eflush(); - } -} - - void -redefined(c) - int c; -{ - warn("redefinition of -%c option", c); -} - -#if has_prototypes - void -diagnose(char const *format,...) -#else - /*VARARGS1*/ void diagnose(format, va_alist) char const *format; va_dcl -#endif -/* prints a diagnostic message */ -/* Unlike the other routines, it does not append a newline. */ -/* This lets some callers suppress the newline, and is faster */ -/* in implementations that flush stderr just at the end of each printf. */ -{ - va_list args; - if (!quietflag) { - oflush(); - vararg_start(args, format); - fvfprintf(stderr, format, args); - va_end(args); - eflush(); - } -} - - - - void -afputc(c, f) -/* afputc(c,f); acts like aputc_(c,f) but is smaller and slower. */ - int c; - register FILE *f; -{ - aputc_(c,f) -} - - - void -aputs(s, iop) - char const *s; - FILE *iop; -/* Function: Put string s on file iop, abort on error. - */ -{ -#if has_fputs - if (fputs(s, iop) < 0) - Oerror(); -#else - awrite(s, strlen(s), iop); -#endif -} - - - - void -#if has_prototypes -fvfprintf(FILE *stream, char const *format, va_list args) -#else - fvfprintf(stream,format,args) FILE *stream; char *format; va_list args; -#endif -/* like vfprintf, except abort program on error */ -{ -#if has_vfprintf - if (vfprintf(stream, format, args) < 0) - Oerror(); -#else -# if has__doprintf - _doprintf(stream, format, args); -# else -# if has__doprnt - _doprnt(format, args, stream); -# else - int *a = (int *)args; - VOID fprintf(stream, format, - a[0], a[1], a[2], a[3], a[4], - a[5], a[6], a[7], a[8], a[9] - ); -# endif -# endif - if (ferror(stream)) - Oerror(); -#endif -} - -#if has_prototypes - void -aprintf(FILE *iop, char const *fmt, ...) -#else - /*VARARGS2*/ void -aprintf(iop, fmt, va_alist) -FILE *iop; -char const *fmt; -va_dcl -#endif -/* Function: formatted output. Same as fprintf in stdio, - * but aborts program on error - */ -{ - va_list ap; - vararg_start(ap, fmt); - fvfprintf(iop, fmt, ap); - va_end(ap); -} - - - -#ifdef LEXDB -/* test program reading a stream of lexemes and printing the tokens. - */ - - - - int -main(argc,argv) -int argc; char * argv[]; -{ - cmdid="lextest"; - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s",argv[1]); - } - Lexinit(); - while (!eoflex()) { - switch (nexttok) { - - case ID: - VOID printf("ID: %s",NextString); - break; - - case NUM: - if (hshenter) - VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab); - else - VOID printf("NUM, unentered: %s",NextString); - hshenter = !hshenter; /*alternate between dates and numbers*/ - break; - - case COLON: - VOID printf("COLON"); break; - - case SEMI: - VOID printf("SEMI"); break; - - case STRING: - readstring(); - VOID printf("STRING"); break; - - case UNKN: - VOID printf("UNKN"); break; - - default: - VOID printf("DEFAULT"); break; - } - VOID printf(" | "); - nextlex(); - } - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcsmap.c b/gnu/usr.bin/rcs/lib/rcsmap.c deleted file mode 100644 index 89fb08daf364..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsmap.c +++ /dev/null @@ -1,69 +0,0 @@ -/* RCS map of character types */ - -/* Copyright (C) 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1995 by Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -libId(mapId, "$FreeBSD$") - -/* map of character types */ -/* ISO 8859/1 (Latin-1) */ -enum tokens const ctab[] = { - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - SPACE, SPACE, NEWLN, SPACE, SPACE, SPACE, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - SPACE, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, PERIOD, IDCHAR, - DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, - DIGIT, DIGIT, COLON, SEMI, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - SBEGIN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, IDCHAR, IDCHAR, IDCHAR, IDCHAR, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, IDCHAR, - LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, IDCHAR, - Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter -}; diff --git a/gnu/usr.bin/rcs/lib/rcsrev.c b/gnu/usr.bin/rcs/lib/rcsrev.c deleted file mode 100644 index 12c6c43006ac..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsrev.c +++ /dev/null @@ -1,911 +0,0 @@ -/* Handle RCS revision numbers. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.10 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.9 1995/06/01 16:23:43 eggert - * (cmpdate, normalizeyear): New functions work around MKS RCS incompatibility. - * (cmpnum, compartial): s[d] -> *(s+d) to work around Cray compiler bug. - * (genrevs, genbranch): cmpnum -> cmpdate - * - * Revision 5.8 1994/03/17 14:05:48 eggert - * Remove lint. - * - * Revision 5.7 1993/11/09 17:40:15 eggert - * Fix format string typos. - * - * Revision 5.6 1993/11/03 17:42:27 eggert - * Revision number `.N' now stands for `D.N', where D is the default branch. - * Add -z. Improve quality of diagnostics. Add `namedrev' for Name support. - * - * Revision 5.5 1992/07/28 16:12:44 eggert - * Identifiers may now start with a digit. Avoid `unsigned'. - * - * Revision 5.4 1992/01/06 02:42:34 eggert - * while (E) ; -> while (E) continue; - * - * Revision 5.3 1991/08/19 03:13:55 eggert - * Add `-r$', `-rB.'. Remove botches like `' from messages. Tune. - * - * Revision 5.2 1991/04/21 11:58:28 eggert - * Add tiprev(). - * - * Revision 5.1 1991/02/25 07:12:43 eggert - * Avoid overflow when comparing revision numbers. - * - * Revision 5.0 1990/08/22 08:13:43 eggert - * Remove compile-time limits; use malloc instead. - * Ansify and Posixate. Tune. - * Remove possibility of an internal error. Remove lint. - * - * Revision 4.5 89/05/01 15:13:22 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.4 87/12/18 11:45:22 narten - * more lint cleanups. Also, the NOTREACHED comment is no longer necessary, - * since there's now a return value there with a value. (Guy Harris) - * - * Revision 4.3 87/10/18 10:38:42 narten - * Updating version numbers. Changes relative to version 1.1 actually - * relative to 4.1 - * - * Revision 1.3 87/09/24 14:00:37 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:37 jenkins - * Port to suns - * - * Revision 4.1 83/03/25 21:10:45 wft - * Only changed $Header to $Id. - * - * Revision 3.4 82/12/04 13:24:08 wft - * Replaced getdelta() with gettree(). - * - * Revision 3.3 82/11/28 21:33:15 wft - * fixed compartial() and compnum() for nil-parameters; fixed nils - * in error messages. Testprogram output shortenend. - * - * Revision 3.2 82/10/18 21:19:47 wft - * renamed compnum->cmpnum, compnumfld->cmpnumfld, - * numericrevno->numricrevno. - * - * Revision 3.1 82/10/11 19:46:09 wft - * changed expandsym() to check for source==nil; returns zero length string - * in that case. - */ - -#include "rcsbase.h" - -libId(revId, "$FreeBSD$") - -static char const *branchtip P((char const*)); -static char const *lookupsym P((char const*)); -static char const *normalizeyear P((char const*,char[5])); -static struct hshentry *genbranch P((struct hshentry const*,char const*,int,char const*,char const*,char const*,struct hshentries**)); -static void absent P((char const*,int)); -static void cantfindbranch P((char const*,char const[datesize],char const*,char const*)); -static void store1 P((struct hshentries***,struct hshentry*)); - - - - int -countnumflds(s) - char const *s; -/* Given a pointer s to a dotted number (date or revision number), - * countnumflds returns the number of digitfields in s. - */ -{ - register char const *sp; - register int count; - if (!(sp=s) || !*sp) - return 0; - count = 1; - do { - if (*sp++ == '.') count++; - } while (*sp); - return(count); -} - - void -getbranchno(revno,branchno) - char const *revno; - struct buf *branchno; -/* Given a revision number revno, getbranchno copies the number of the branch - * on which revno is into branchno. If revno itself is a branch number, - * it is copied unchanged. - */ -{ - register int numflds; - register char *tp; - - bufscpy(branchno, revno); - numflds=countnumflds(revno); - if (!(numflds & 1)) { - tp = branchno->string; - while (--numflds) - while (*tp++ != '.') - continue; - *(tp-1)='\0'; - } -} - - - -int cmpnum(num1, num2) - char const *num1, *num2; -/* compares the two dotted numbers num1 and num2 lexicographically - * by field. Individual fields are compared numerically. - * returns <0, 0, >0 if num1num2, resp. - * omitted fields are assumed to be higher than the existing ones. -*/ -{ - register char const *s1, *s2; - register size_t d1, d2; - register int r; - - s1 = num1 ? num1 : ""; - s2 = num2 ? num2 : ""; - - for (;;) { - /* Give precedence to shorter one. */ - if (!*s1) - return (unsigned char)*s2; - if (!*s2) - return -1; - - /* Strip leading zeros, then find number of digits. */ - while (*s1=='0') ++s1; - while (*s2=='0') ++s2; - for (d1=0; isdigit(*(s1+d1)); d1++) continue; - for (d2=0; isdigit(*(s2+d2)); d2++) continue; - - /* Do not convert to integer; it might overflow! */ - if (d1 != d2) - return d1string; - while (length) { - while (*r1!='.' && *r1) - ++r1; - ++r1; - length--; - } - /* eliminate last '.'*/ - *(r1-1)='\0'; - return rev1->string; -} - - - - - static void -store1(store, next) - struct hshentries ***store; - struct hshentry *next; -/* - * Allocate a new list node that addresses NEXT. - * Append it to the list that **STORE is the end pointer of. - */ -{ - register struct hshentries *p; - - p = ftalloc(struct hshentries); - p->first = next; - **store = p; - *store = &p->rest; -} - -struct hshentry * genrevs(revno,date,author,state,store) - char const *revno, *date, *author, *state; - struct hshentries **store; -/* Function: finds the deltas needed for reconstructing the - * revision given by revno, date, author, and state, and stores pointers - * to these deltas into a list whose starting address is given by store. - * The last delta (target delta) is returned. - * If the proper delta could not be found, 0 is returned. - */ -{ - int length; - register struct hshentry * next; - int result; - char const *branchnum; - struct buf t; - char datebuf[datesize + zonelenmax]; - - bufautobegin(&t); - - if (!(next = Head)) { - rcserror("RCS file empty"); - goto norev; - } - - length = countnumflds(revno); - - if (length >= 1) { - /* at least one field; find branch exactly */ - while ((result=cmpnumfld(revno,next->num,1)) < 0) { - store1(&store, next); - next = next->next; - if (!next) { - rcserror("branch number %s too low", partialno(&t,revno,1)); - goto norev; - } - } - - if (result>0) { - absent(revno, 1); - goto norev; - } - } - if (length<=1){ - /* pick latest one on given branch */ - branchnum = next->num; /* works even for empty revno*/ - while (next && - cmpnumfld(branchnum,next->num,1) == 0 && - ( - (date && cmpdate(date,next->date) < 0) || - (author && strcmp(author,next->author) != 0) || - (state && strcmp(state,next->state) != 0) - ) - ) - { - store1(&store, next); - next=next->next; - } - if (!next || - (cmpnumfld(branchnum,next->num,1)!=0))/*overshot*/ { - cantfindbranch( - length ? revno : partialno(&t,branchnum,1), - date, author, state - ); - goto norev; - } else { - store1(&store, next); - } - *store = 0; - return next; - } - - /* length >=2 */ - /* find revision; may go low if length==2*/ - while ((result=cmpnumfld(revno,next->num,2)) < 0 && - (cmpnumfld(revno,next->num,1)==0) ) { - store1(&store, next); - next = next->next; - if (!next) - break; - } - - if (!next || cmpnumfld(revno,next->num,1) != 0) { - rcserror("revision number %s too low", partialno(&t,revno,2)); - goto norev; - } - if ((length>2) && (result!=0)) { - absent(revno, 2); - goto norev; - } - - /* print last one */ - store1(&store, next); - - if (length>2) - return genbranch(next,revno,length,date,author,state,store); - else { /* length == 2*/ - if (date && cmpdate(date,next->date)<0) { - rcserror("Revision %s has date %s.", - next->num, - date2str(next->date, datebuf) - ); - return 0; - } - if (author && strcmp(author,next->author)!=0) { - rcserror("Revision %s has author %s.", - next->num, next->author - ); - return 0; - } - if (state && strcmp(state,next->state)!=0) { - rcserror("Revision %s has state %s.", - next->num, - next->state ? next->state : "" - ); - return 0; - } - *store = 0; - return next; - } - - norev: - bufautoend(&t); - return 0; -} - - - - - static struct hshentry * -genbranch(bpoint, revno, length, date, author, state, store) - struct hshentry const *bpoint; - char const *revno; - int length; - char const *date, *author, *state; - struct hshentries **store; -/* Function: given a branchpoint, a revision number, date, author, and state, - * genbranch finds the deltas necessary to reconstruct the given revision - * from the branch point on. - * Pointers to the found deltas are stored in a list beginning with store. - * revno must be on a side branch. - * Return 0 on error. - */ -{ - int field; - register struct hshentry * next, * trail; - register struct branchhead const *bhead; - int result; - struct buf t; - char datebuf[datesize + zonelenmax]; - - field = 3; - bhead = bpoint->branches; - - do { - if (!bhead) { - bufautobegin(&t); - rcserror("no side branches present for %s", - partialno(&t,revno,field-1) - ); - bufautoend(&t); - return 0; - } - - /*find branch head*/ - /*branches are arranged in increasing order*/ - while (0 < (result=cmpnumfld(revno,bhead->hsh->num,field))) { - bhead = bhead->nextbranch; - if (!bhead) { - bufautobegin(&t); - rcserror("branch number %s too high", - partialno(&t,revno,field) - ); - bufautoend(&t); - return 0; - } - } - - if (result<0) { - absent(revno, field); - return 0; - } - - next = bhead->hsh; - if (length==field) { - /* pick latest one on that branch */ - trail = 0; - do { if ((!date || cmpdate(date,next->date)>=0) && - (!author || strcmp(author,next->author)==0) && - (!state || strcmp(state,next->state)==0) - ) trail = next; - next=next->next; - } while (next); - - if (!trail) { - cantfindbranch(revno, date, author, state); - return 0; - } else { /* print up to last one suitable */ - next = bhead->hsh; - while (next!=trail) { - store1(&store, next); - next=next->next; - } - store1(&store, next); - } - *store = 0; - return next; - } - - /* length > field */ - /* find revision */ - /* check low */ - if (cmpnumfld(revno,next->num,field+1)<0) { - bufautobegin(&t); - rcserror("revision number %s too low", - partialno(&t,revno,field+1) - ); - bufautoend(&t); - return 0; - } - do { - store1(&store, next); - trail = next; - next = next->next; - } while (next && cmpnumfld(revno,next->num,field+1)>=0); - - if ((length>field+1) && /*need exact hit */ - (cmpnumfld(revno,trail->num,field+1) !=0)){ - absent(revno, field+1); - return 0; - } - if (length == field+1) { - if (date && cmpdate(date,trail->date)<0) { - rcserror("Revision %s has date %s.", - trail->num, - date2str(trail->date, datebuf) - ); - return 0; - } - if (author && strcmp(author,trail->author)!=0) { - rcserror("Revision %s has author %s.", - trail->num, trail->author - ); - return 0; - } - if (state && strcmp(state,trail->state)!=0) { - rcserror("Revision %s has state %s.", - trail->num, - trail->state ? trail->state : "" - ); - return 0; - } - } - bhead = trail->branches; - - } while ((field+=2) <= length); - *store = 0; - return trail; -} - - - static char const * -lookupsym(id) - char const *id; -/* Function: looks up id in the list of symbolic names starting - * with pointer SYMBOLS, and returns a pointer to the corresponding - * revision number. Return 0 if not present. - */ -{ - register struct assoc const *next; - for (next = Symbols; next; next = next->nextassoc) - if (strcmp(id, next->symbol)==0) - return next->num; - return 0; -} - -int expandsym(source, target) - char const *source; - struct buf *target; -/* Function: Source points to a revision number. Expandsym copies - * the number to target, but replaces all symbolic fields in the - * source number with their numeric values. - * Expand a branch followed by `.' to the latest revision on that branch. - * Ignore `.' after a revision. Remove leading zeros. - * returns false on error; - */ -{ - return fexpandsym(source, target, (RILE*)0); -} - - int -fexpandsym(source, target, fp) - char const *source; - struct buf *target; - RILE *fp; -/* Same as expandsym, except if FP is nonzero, it is used to expand KDELIM. */ -{ - register char const *sp, *bp; - register char *tp; - char const *tlim; - int dots; - - sp = source; - bufalloc(target, 1); - tp = target->string; - if (!sp || !*sp) { /* Accept 0 pointer as a legal value. */ - *tp='\0'; - return true; - } - if (sp[0] == KDELIM && !sp[1]) { - if (!getoldkeys(fp)) - return false; - if (!*prevrev.string) { - workerror("working file lacks revision number"); - return false; - } - bufscpy(target, prevrev.string); - return true; - } - tlim = tp + target->size; - dots = 0; - - for (;;) { - register char *p = tp; - size_t s = tp - target->string; - int id = false; - for (;;) { - switch (ctab[(unsigned char)*sp]) { - case IDCHAR: - case LETTER: - case Letter: - id = true; - /* fall into */ - case DIGIT: - if (tlim <= p) - p = bufenlarge(target, &tlim); - *p++ = *sp++; - continue; - - default: - break; - } - break; - } - if (tlim <= p) - p = bufenlarge(target, &tlim); - *p = 0; - tp = target->string + s; - - if (id) { - bp = lookupsym(tp); - if (!bp) { - rcserror("Symbolic name `%s' is undefined.",tp); - return false; - } - } else { - /* skip leading zeros */ - for (bp = tp; *bp=='0' && isdigit(bp[1]); bp++) - continue; - - if (!*bp) - if (s || *sp!='.') - break; - else { - /* Insert default branch before initial `.'. */ - char const *b; - if (Dbranch) - b = Dbranch; - else if (Head) - b = Head->num; - else - break; - getbranchno(b, target); - bp = tp = target->string; - tlim = tp + target->size; - } - } - - while ((*tp++ = *bp++)) - if (tlim <= tp) - tp = bufenlarge(target, &tlim); - - switch (*sp++) { - case '\0': - return true; - - case '.': - if (!*sp) { - if (dots & 1) - break; - if (!(bp = branchtip(target->string))) - return false; - bufscpy(target, bp); - return true; - } - ++dots; - tp[-1] = '.'; - continue; - } - break; - } - - rcserror("improper revision number: %s", source); - return false; -} - - char const * -namedrev(name, delta) - char const *name; - struct hshentry *delta; -/* Yield NAME if it names DELTA, 0 otherwise. */ -{ - if (name) { - char const *id = 0, *p, *val; - for (p = name; ; p++) - switch (ctab[(unsigned char)*p]) { - case IDCHAR: - case LETTER: - case Letter: - id = name; - break; - - case DIGIT: - break; - - case UNKN: - if (!*p && id && - (val = lookupsym(id)) && - strcmp(val, delta->num) == 0 - ) - return id; - /* fall into */ - default: - return 0; - } - } - return 0; -} - - static char const * -branchtip(branch) - char const *branch; -{ - struct hshentry *h; - struct hshentries *hs; - - h = genrevs(branch, (char*)0, (char*)0, (char*)0, &hs); - return h ? h->num : (char const*)0; -} - - char const * -tiprev() -{ - return Dbranch ? branchtip(Dbranch) : Head ? Head->num : (char const*)0; -} - - - -#ifdef REVTEST - -/* -* Test the routines that generate a sequence of delta numbers -* needed to regenerate a given delta. -*/ - -char const cmdid[] = "revtest"; - - int -main(argc,argv) -int argc; char * argv[]; -{ - static struct buf numricrevno; - char symrevno[100]; /* used for input of revision numbers */ - char author[20]; - char state[20]; - char date[20]; - struct hshentries *gendeltas; - struct hshentry * target; - int i; - - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s", argv[1]); - } - Lexinit(); - getadmin(); - - gettree(); - - getdesc(false); - - do { - /* all output goes to stderr, to have diagnostics and */ - /* errors in sequence. */ - aputs("\nEnter revision number or or '.': ",stderr); - if (!fgets(symrevno, 100, stdin)) break; - if (*symrevno == '.') break; - aprintf(stderr,"%s;\n",symrevno); - expandsym(symrevno,&numricrevno); - aprintf(stderr,"expanded number: %s; ",numricrevno.string); - aprintf(stderr,"Date: "); - fgets(date, 20, stdin); aprintf(stderr,"%s; ",date); - aprintf(stderr,"Author: "); - fgets(author, 20, stdin); aprintf(stderr,"%s; ",author); - aprintf(stderr,"State: "); - fgets(state, 20, stdin); aprintf(stderr, "%s;\n", state); - target = genrevs(numricrevno.string, *date?date:(char *)0, *author?author:(char *)0, - *state?state:(char*)0, &gendeltas); - if (target) { - while (gendeltas) { - aprintf(stderr,"%s\n",gendeltas->first->num); - gendeltas = gendeltas->next; - } - } - } while (true); - aprintf(stderr,"done\n"); - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcssyn.c b/gnu/usr.bin/rcs/lib/rcssyn.c deleted file mode 100644 index 07f155bfb8ea..000000000000 --- a/gnu/usr.bin/rcs/lib/rcssyn.c +++ /dev/null @@ -1,681 +0,0 @@ -/* RCS file syntactic analysis */ - -/****************************************************************************** - * Syntax Analysis. - * Keyword table - * Testprogram: define SYNTEST - * Compatibility with Release 2: define COMPAT2=1 - ****************************************************************************** - */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.15 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.14 1995/06/01 16:23:43 eggert - * (expand_names): Add "b" for -kb. - * (getdelta): Don't strip leading "19" from MKS RCS dates; see cmpdate. - * - * Revision 5.13 1994/03/20 04:52:58 eggert - * Remove lint. - * - * Revision 5.12 1993/11/03 17:42:27 eggert - * Parse MKS RCS dates; ignore \r in diff control lines. - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.11 1992/07/28 16:12:44 eggert - * Avoid `unsigned'. Statement macro names now end in _. - * - * Revision 5.10 1992/01/24 18:44:19 eggert - * Move put routines to rcsgen.c. - * - * Revision 5.9 1992/01/06 02:42:34 eggert - * ULONG_MAX/10 -> ULONG_MAX_OVER_10 - * while (E) ; -> while (E) continue; - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Tune. - * - * Revision 5.7 1991/04/21 11:58:29 eggert - * Disambiguate names on shortname hosts. - * Fix errno bug. Add MS-DOS support. - * - * Revision 5.6 1991/02/28 19:18:51 eggert - * Fix null termination bug in reporting keyword expansion. - * - * Revision 5.5 1991/02/25 07:12:44 eggert - * Check diff output more carefully; avoid overflow. - * - * Revision 5.4 1990/11/01 05:28:48 eggert - * When ignoring unknown phrases, copy them to the output RCS file. - * Permit arbitrary data in logs and comment leaders. - * Don't check for nontext on initial checkin. - * - * Revision 5.3 1990/09/20 07:58:32 eggert - * Remove the test for non-text bytes; it caused more pain than it cured. - * - * Revision 5.2 1990/09/04 08:02:30 eggert - * Parse RCS files with no revisions. - * Don't strip leading white space from diff commands. Count RCS lines better. - * - * Revision 5.1 1990/08/29 07:14:06 eggert - * Add -kkvl. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:13:44 eggert - * Try to parse future RCS formats without barfing. - * Add -k. Don't require final newline. - * Remove compile-time limits; use malloc instead. - * Don't output branch keyword if there's no default branch, - * because RCS version 3 doesn't understand it. - * Tune. Remove lint. - * Add support for ISO 8859. Ansify and Posixate. - * Check that a newly checked-in file is acceptable as input to 'diff'. - * Check diff's output. - * - * Revision 4.6 89/05/01 15:13:32 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/09 19:13:21 eggert - * Allow cc -R; remove lint. - * - * Revision 4.4 87/12/18 11:46:16 narten - * more lint cleanups (Guy Harris) - * - * Revision 4.3 87/10/18 10:39:36 narten - * Updating version numbers. Changes relative to 1.1 actually relative to - * 4.1 - * - * Revision 1.3 87/09/24 14:00:49 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:40 jenkins - * Port to suns - * - * Revision 4.1 83/03/28 11:38:49 wft - * Added parsing and printing of default branch. - * - * Revision 3.6 83/01/15 17:46:50 wft - * Changed readdelta() to initialize selector and log-pointer. - * Changed puttree to check for selector==DELETE; putdtext() uses DELNUMFORM. - * - * Revision 3.5 82/12/08 21:58:58 wft - * renamed Commentleader to Commleader. - * - * Revision 3.4 82/12/04 13:24:40 wft - * Added routine gettree(), which updates keeplock after reading the - * delta tree. - * - * Revision 3.3 82/11/28 21:30:11 wft - * Reading and printing of Suffix removed; version COMPAT2 skips the - * Suffix for files of release 2 format. Fixed problems with printing nil. - * - * Revision 3.2 82/10/18 21:18:25 wft - * renamed putdeltatext to putdtext. - * - * Revision 3.1 82/10/11 19:45:11 wft - * made sure getc() returns into an integer. - */ - - - -/* version COMPAT2 reads files of the format of release 2 and 3, but - * generates files of release 3 format. Need not be defined if no - * old RCS files generated with release 2 exist. - */ - -#include "rcsbase.h" - -libId(synId, "$FreeBSD$") - -static char const *getkeyval P((char const*,enum tokens,int)); -static int getdelta P((void)); -static int strn2expmode P((char const*,size_t)); -static struct hshentry *getdnum P((void)); -static void badDiffOutput P((char const*)) exiting; -static void diffLineNumberTooLarge P((char const*)) exiting; -static void getsemi P((char const*)); - -/* keyword table */ - -char const - Kaccess[] = "access", - Kauthor[] = "author", - Kbranch[] = "branch", - Kcomment[] = "comment", - Kdate[] = "date", - Kdesc[] = "desc", - Kexpand[] = "expand", - Khead[] = "head", - Klocks[] = "locks", - Klog[] = "log", - Knext[] = "next", - Kstate[] = "state", - Kstrict[] = "strict", - Ksymbols[] = "symbols", - Ktext[] = "text"; - -static char const -#if COMPAT2 - Ksuffix[] = "suffix", -#endif - K_branches[]= "branches"; - -static struct buf Commleader; -struct cbuf Comment; -struct cbuf Ignored; -struct access * AccessList; -struct assoc * Symbols; -struct rcslock *Locks; -int Expand; -int StrictLocks; -struct hshentry * Head; -char const * Dbranch; -int TotalDeltas; - - - static void -getsemi(key) - char const *key; -/* Get a semicolon to finish off a phrase started by KEY. */ -{ - if (!getlex(SEMI)) - fatserror("missing ';' after '%s'", key); -} - - static struct hshentry * -getdnum() -/* Get a delta number. */ -{ - register struct hshentry *delta = getnum(); - if (delta && countnumflds(delta->num)&1) - fatserror("%s isn't a delta number", delta->num); - return delta; -} - - - void -getadmin() -/* Read an and initialize the appropriate global variables. */ -{ - register char const *id; - struct access * newaccess; - struct assoc * newassoc; - struct rcslock *newlock; - struct hshentry * delta; - struct access **LastAccess; - struct assoc **LastSymbol; - struct rcslock **LastLock; - struct buf b; - struct cbuf cb; - - TotalDeltas=0; - - getkey(Khead); - Head = getdnum(); - getsemi(Khead); - - Dbranch = 0; - if (getkeyopt(Kbranch)) { - if ((delta = getnum())) - Dbranch = delta->num; - getsemi(Kbranch); - } - - -#if COMPAT2 - /* read suffix. Only in release 2 format */ - if (getkeyopt(Ksuffix)) { - if (nexttok==STRING) { - readstring(); nextlex(); /* Throw away the suffix. */ - } else if (nexttok==ID) { - nextlex(); - } - getsemi(Ksuffix); - } -#endif - - getkey(Kaccess); - LastAccess = &AccessList; - while ((id = getid())) { - newaccess = ftalloc(struct access); - newaccess->login = id; - *LastAccess = newaccess; - LastAccess = &newaccess->nextaccess; - } - *LastAccess = 0; - getsemi(Kaccess); - - getkey(Ksymbols); - LastSymbol = &Symbols; - while ((id = getid())) { - if (!getlex(COLON)) - fatserror("missing ':' in symbolic name definition"); - if (!(delta=getnum())) { - fatserror("missing number in symbolic name definition"); - } else { /*add new pair to association list*/ - newassoc = ftalloc(struct assoc); - newassoc->symbol=id; - newassoc->num = delta->num; - *LastSymbol = newassoc; - LastSymbol = &newassoc->nextassoc; - } - } - *LastSymbol = 0; - getsemi(Ksymbols); - - getkey(Klocks); - LastLock = &Locks; - while ((id = getid())) { - if (!getlex(COLON)) - fatserror("missing ':' in lock"); - if (!(delta=getdnum())) { - fatserror("missing number in lock"); - } else { /*add new pair to lock list*/ - newlock = ftalloc(struct rcslock); - newlock->login=id; - newlock->delta=delta; - *LastLock = newlock; - LastLock = &newlock->nextlock; - } - } - *LastLock = 0; - getsemi(Klocks); - - if ((StrictLocks = getkeyopt(Kstrict))) - getsemi(Kstrict); - - clear_buf(&Comment); - if (getkeyopt(Kcomment)) { - if (nexttok==STRING) { - Comment = savestring(&Commleader); - nextlex(); - } - getsemi(Kcomment); - } - - Expand = KEYVAL_EXPAND; - if (getkeyopt(Kexpand)) { - if (nexttok==STRING) { - bufautobegin(&b); - cb = savestring(&b); - if ((Expand = strn2expmode(cb.string,cb.size)) < 0) - fatserror("unknown expand mode %.*s", - (int)cb.size, cb.string - ); - bufautoend(&b); - nextlex(); - } - getsemi(Kexpand); - } - Ignored = getphrases(Kdesc); -} - -char const *const expand_names[] = { - /* These must agree with *_EXPAND in rcsbase.h. */ - "kv", "kvl", "k", "v", "o", "b", - 0 -}; - - int -str2expmode(s) - char const *s; -/* Yield expand mode corresponding to S, or -1 if bad. */ -{ - return strn2expmode(s, strlen(s)); -} - - static int -strn2expmode(s, n) - char const *s; - size_t n; -{ - char const *const *p; - - for (p = expand_names; *p; ++p) - if (memcmp(*p,s,n) == 0 && !(*p)[n]) - return p - expand_names; - return -1; -} - - - void -ignorephrases(key) - const char *key; -/* -* Ignore a series of phrases that do not start with KEY. -* Stop when the next phrase starts with a token that is not an identifier, -* or is KEY. -*/ -{ - for (;;) { - nextlex(); - if (nexttok != ID || strcmp(NextString,key) == 0) - break; - warnignore(); - hshenter=false; - for (;; nextlex()) { - switch (nexttok) { - case SEMI: hshenter=true; break; - case ID: - case NUM: ffree1(NextString); continue; - case STRING: readstring(); continue; - default: continue; - } - break; - } - } -} - - - static int -getdelta() -/* Function: reads a delta block. - * returns false if the current block does not start with a number. - */ -{ - register struct hshentry * Delta, * num; - struct branchhead **LastBranch, *NewBranch; - - if (!(Delta = getdnum())) - return false; - - hshenter = false; /*Don't enter dates into hashtable*/ - Delta->date = getkeyval(Kdate, NUM, false); - hshenter=true; /*reset hshenter for revision numbers.*/ - - Delta->author = getkeyval(Kauthor, ID, false); - - Delta->state = getkeyval(Kstate, ID, true); - - getkey(K_branches); - LastBranch = &Delta->branches; - while ((num = getdnum())) { - NewBranch = ftalloc(struct branchhead); - NewBranch->hsh = num; - *LastBranch = NewBranch; - LastBranch = &NewBranch->nextbranch; - } - *LastBranch = 0; - getsemi(K_branches); - - getkey(Knext); - Delta->next = num = getdnum(); - getsemi(Knext); - Delta->lockedby = 0; - Delta->log.string = 0; - Delta->selector = true; - Delta->ig = getphrases(Kdesc); - TotalDeltas++; - return (true); -} - - - void -gettree() -/* Function: Reads in the delta tree with getdelta(), then - * updates the lockedby fields. - */ -{ - struct rcslock const *currlock; - - while (getdelta()) - continue; - currlock=Locks; - while (currlock) { - currlock->delta->lockedby = currlock->login; - currlock = currlock->nextlock; - } -} - - - void -getdesc(prdesc) -int prdesc; -/* Function: read in descriptive text - * nexttok is not advanced afterwards. - * If prdesc is set, the text is printed to stdout. - */ -{ - - getkeystring(Kdesc); - if (prdesc) - printstring(); /*echo string*/ - else readstring(); /*skip string*/ -} - - - - - - - static char const * -getkeyval(keyword, token, optional) - char const *keyword; - enum tokens token; - int optional; -/* reads a pair of the form - * ; - * where token is one of or . optional indicates whether - * is optional. A pointer to - * the actual character string of or is returned. - */ -{ - register char const *val = 0; - - getkey(keyword); - if (nexttok==token) { - val = NextString; - nextlex(); - } else { - if (!optional) - fatserror("missing %s", keyword); - } - getsemi(keyword); - return(val); -} - - - void -unexpected_EOF() -{ - rcsfaterror("unexpected EOF in diff output"); -} - - void -initdiffcmd(dc) - register struct diffcmd *dc; -/* Initialize *dc suitably for getdiffcmd(). */ -{ - dc->adprev = 0; - dc->dafter = 0; -} - - static void -badDiffOutput(buf) - char const *buf; -{ - rcsfaterror("bad diff output line: %s", buf); -} - - static void -diffLineNumberTooLarge(buf) - char const *buf; -{ - rcsfaterror("diff line number too large: %s", buf); -} - - int -getdiffcmd(finfile, delimiter, foutfile, dc) - RILE *finfile; - FILE *foutfile; - int delimiter; - struct diffcmd *dc; -/* Get a editing command output by 'diff -n' from fin. - * The input is delimited by SDELIM if delimiter is set, EOF otherwise. - * Copy a clean version of the command to fout (if nonnull). - * Yield 0 for 'd', 1 for 'a', and -1 for EOF. - * Store the command's line number and length into dc->line1 and dc->nlines. - * Keep dc->adprev and dc->dafter up to date. - */ -{ - register int c; - declarecache; - register FILE *fout; - register char *p; - register RILE *fin; - long line1, nlines, t; - char buf[BUFSIZ]; - - fin = finfile; - fout = foutfile; - setupcache(fin); cache(fin); - cachegeteof_(c, { if (delimiter) unexpected_EOF(); return -1; } ) - if (delimiter) { - if (c==SDELIM) { - cacheget_(c) - if (c==SDELIM) { - buf[0] = c; - buf[1] = 0; - badDiffOutput(buf); - } - uncache(fin); - nextc = c; - if (fout) - aprintf(fout, "%c%c", SDELIM, c); - return -1; - } - } - p = buf; - do { - if (buf+BUFSIZ-2 <= p) { - rcsfaterror("diff output command line too long"); - } - *p++ = c; - cachegeteof_(c, unexpected_EOF();) - } while (c != '\n'); - uncache(fin); - if (delimiter) - ++rcsline; - *p = '\0'; - for (p = buf+1; (c = *p++) == ' '; ) - continue; - line1 = 0; - while (isdigit(c)) { - if ( - LONG_MAX/10 < line1 || - (t = line1 * 10, (line1 = t + (c - '0')) < t) - ) - diffLineNumberTooLarge(buf); - c = *p++; - } - while (c == ' ') - c = *p++; - nlines = 0; - while (isdigit(c)) { - if ( - LONG_MAX/10 < nlines || - (t = nlines * 10, (nlines = t + (c - '0')) < t) - ) - diffLineNumberTooLarge(buf); - c = *p++; - } - if (c == '\r') - c = *p++; - if (c || !nlines) { - badDiffOutput(buf); - } - if (line1+nlines < line1) - diffLineNumberTooLarge(buf); - switch (buf[0]) { - case 'a': - if (line1 < dc->adprev) { - rcsfaterror("backward insertion in diff output: %s", buf); - } - dc->adprev = line1 + 1; - break; - case 'd': - if (line1 < dc->adprev || line1 < dc->dafter) { - rcsfaterror("backward deletion in diff output: %s", buf); - } - dc->adprev = line1; - dc->dafter = line1 + nlines; - break; - default: - badDiffOutput(buf); - } - if (fout) { - aprintf(fout, "%s\n", buf); - } - dc->line1 = line1; - dc->nlines = nlines; - return buf[0] == 'a'; -} - - - -#ifdef SYNTEST - -/* Input an RCS file and print its internal data structures. */ - -char const cmdid[] = "syntest"; - - int -main(argc,argv) -int argc; char * argv[]; -{ - - if (argc<2) { - aputs("No input file\n",stderr); - exitmain(EXIT_FAILURE); - } - if (!(finptr = Iopen(argv[1], FOPEN_R, (struct stat*)0))) { - faterror("can't open input file %s", argv[1]); - } - Lexinit(); - getadmin(); - fdlock = STDOUT_FILENO; - putadmin(); - - gettree(); - - getdesc(true); - - nextlex(); - - if (!eoflex()) { - fatserror("expecting EOF"); - } - exitmain(EXIT_SUCCESS); -} - -void exiterr() { _exit(EXIT_FAILURE); } - -#endif diff --git a/gnu/usr.bin/rcs/lib/rcstime.c b/gnu/usr.bin/rcs/lib/rcstime.c deleted file mode 100644 index cfd466096ff7..000000000000 --- a/gnu/usr.bin/rcs/lib/rcstime.c +++ /dev/null @@ -1,191 +0,0 @@ -/* Convert between RCS time format and Posix and/or C formats. */ - -/* Copyright 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" -#include "partime.h" -#include "maketime.h" - -libId(rcstimeId, "$FreeBSD$") - -static long zone_offset; /* seconds east of UTC, or TM_LOCAL_ZONE */ -static int use_zone_offset; /* if zero, use UTC without zone indication */ - -/* -* Convert Unix time to RCS format. -* For compatibility with older versions of RCS, -* dates from 1900 through 1999 are stored without the leading "19". -*/ - void -time2date(unixtime,date) - time_t unixtime; - char date[datesize]; -{ - register struct tm const *tm = time2tm(unixtime, RCSversiontm_year + ((unsigned)tm->tm_year < 100 ? 0 : 1900), - tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec - ); -} - -/* Like str2time, except die if an error was found. */ -static time_t str2time_checked P((char const*,time_t,long)); - static time_t -str2time_checked(source, default_time, default_zone) - char const *source; - time_t default_time; - long default_zone; -{ - time_t t = str2time(source, default_time, default_zone); - if (t == -1) - faterror("unknown date/time: %s", source); - return t; -} - -/* -* Parse a free-format date in SOURCE, convert it -* into RCS internal format, and store the result into TARGET. -*/ - void -str2date(source, target) - char const *source; - char target[datesize]; -{ - time2date( - str2time_checked(source, now(), - use_zone_offset ? zone_offset - : RCSversiontm_year + 1900, - z->tm_mon + 1, z->tm_mday, z->tm_hour, z->tm_min, z->tm_sec, - c, (int) (zone / (60*60)) - ); - if ((non_hour = zone % (60*60))) { -# if has_printf_dot - static char const fmt[] = ":%.2d"; -# else - static char const fmt[] = ":%02d"; -# endif - VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour / 60); - if ((non_hour %= 60)) - VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour); - } - } - return datebuf; -} diff --git a/gnu/usr.bin/rcs/lib/rcsutil.c b/gnu/usr.bin/rcs/lib/rcsutil.c deleted file mode 100644 index e10afff6c20d..000000000000 --- a/gnu/usr.bin/rcs/lib/rcsutil.c +++ /dev/null @@ -1,1398 +0,0 @@ -/* RCS utility functions */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - - - - -/* - * Revision 5.20 1995/06/16 06:19:24 eggert - * (catchsig): Remove `return'. - * Update FSF address. - * - * Revision 5.19 1995/06/02 18:19:00 eggert - * (catchsigaction): New name for `catchsig', for sa_sigaction signature. - * Use nRCS even if !has_psiginfo, to remove unused variable warning. - * (setup_catchsig): Use sa_sigaction only if has_sa_sigaction. - * Use ENOTSUP only if defined. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (catchsig, restoreints, setup_catchsig): Use SA_SIGINFO, not has_psiginfo, - * to determine whether to use SA_SIGINFO feature, - * but also check at runtime whether the feature works. - * (catchsig): If an mmap_signal occurs, report the affected file name. - * (unsupported_SA_SIGINFO, accessName): New variables. - * (setup_catchsig): If using SA_SIGINFO, use sa_sigaction, not sa_handler. - * If SA_SIGINFO fails, fall back on sa_handler method. - * - * (readAccessFilenameBuffer, dupSafer, fdSafer, fopenSafer): New functions. - * (concatenate): Remove. - * - * (runv): Work around bad_wait_if_SIGCHLD_ignored bug. - * Remove reference to OPEN_O_WORK. - * - * Revision 5.17 1994/03/20 04:52:58 eggert - * Specify subprocess input via file descriptor, not file name. - * Avoid messing with I/O buffers in the child process. - * Define dup in terms of F_DUPFD if it exists. - * Move setmtime to rcsedit.c. Remove lint. - * - * Revision 5.16 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. - * - * Revision 5.15 1993/11/03 17:42:27 eggert - * Use psiginfo and setreuid if available. Move date2str to maketime.c. - * - * Revision 5.14 1992/07/28 16:12:44 eggert - * Add -V. has_sigaction overrides sig_zaps_handler. Fix -M bug. - * Add mmap_signal, which minimizes signal handling for non-mmap hosts. - * - * Revision 5.13 1992/02/17 23:02:28 eggert - * Work around NFS mmap SIGBUS problem. Add -T support. - * - * Revision 5.12 1992/01/24 18:44:19 eggert - * Work around NFS mmap bug that leads to SIGBUS core dumps. lint -> RCS_lint - * - * Revision 5.11 1992/01/06 02:42:34 eggert - * O_BINARY -> OPEN_O_WORK - * while (E) ; -> while (E) continue; - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Support piece tables even if !has_mmap. - * - * Revision 5.9 1991/08/19 03:13:55 eggert - * Add spawn() support. Explicate assumptions about getting invoker's name. - * Standardize user-visible dates. Tune. - * - * Revision 5.8 1991/04/21 11:58:30 eggert - * Plug setuid security hole. - * - * Revision 5.6 1991/02/26 17:48:39 eggert - * Fix setuid bug. Use fread, fwrite more portably. - * Support waitpid. Don't assume -1 is acceptable to W* macros. - * strsave -> str_save (DG/UX name clash) - * - * Revision 5.5 1990/12/04 05:18:49 eggert - * Don't output a blank line after a signal diagnostic. - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.4 1990/11/01 05:03:53 eggert - * Remove unneeded setid check. Add awrite(), fremember(). - * - * Revision 5.3 1990/10/06 00:16:45 eggert - * Don't fread F if feof(F). - * - * Revision 5.2 1990/09/04 08:02:31 eggert - * Store fread()'s result in an fread_type object. - * - * Revision 5.1 1990/08/29 07:14:07 eggert - * Declare getpwuid() more carefully. - * - * Revision 5.0 1990/08/22 08:13:46 eggert - * Add setuid support. Permit multiple locks per user. - * Remove compile-time limits; use malloc instead. - * Switch to GMT. Permit dates past 1999/12/31. - * Add -V. Remove snooping. Ansify and Posixate. - * Tune. Some USG hosts define NSIG but not sys_siglist. - * Don't run /bin/sh if it's hopeless. - * Don't leave garbage behind if the output is an empty pipe. - * Clean up after SIGXCPU or SIGXFSZ. Print name of signal that caused cleanup. - * - * Revision 4.6 89/05/01 15:13:40 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/11/08 16:01:02 narten - * corrected use of varargs routines - * - * Revision 4.4 88/08/09 19:13:24 eggert - * Check for memory exhaustion. - * Permit signal handlers to yield either 'void' or 'int'; fix oldSIGINT botch. - * Use execv(), not system(); yield exit status like diff(1)'s. - * - * Revision 4.3 87/10/18 10:40:22 narten - * Updating version numbers. Changes relative to 1.1 actually - * relative to 4.1 - * - * Revision 1.3 87/09/24 14:01:01 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:43 jenkins - * Port to suns - * - * Revision 4.1 83/05/10 15:53:13 wft - * Added getcaller() and findlock(). - * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal - * (needed for background jobs in older shells). Added restoreints(). - * Removed printing of full RCS path from logcommand(). - * - * Revision 3.8 83/02/15 15:41:49 wft - * Added routine fastcopy() to copy remainder of a file in blocks. - * - * Revision 3.7 82/12/24 15:25:19 wft - * added catchints(), ignoreints() for catching and ingnoring interrupts; - * fixed catchsig(). - * - * Revision 3.6 82/12/08 21:52:05 wft - * Using DATEFORM to format dates. - * - * Revision 3.5 82/12/04 18:20:49 wft - * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update - * lockedby-field. - * - * Revision 3.4 82/12/03 17:17:43 wft - * Added check to addlock() ensuring only one lock per person. - * Addlock also returns a pointer to the lock created. Deleted fancydate(). - * - * Revision 3.3 82/11/27 12:24:37 wft - * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c. - * Introduced macro SNOOP so that snoop can be placed in directory other than - * TARGETDIR. Changed %02d to %.2d for compatibility reasons. - * - * Revision 3.2 82/10/18 21:15:11 wft - * added function getfullRCSname(). - * - * Revision 3.1 82/10/13 16:17:37 wft - * Cleanup message is now suppressed in quiet mode. - */ - - - - -#include "rcsbase.h" - -libId(utilId, "$FreeBSD$") - -#if !has_memcmp - int -memcmp(s1, s2, n) - void const *s1, *s2; - size_t n; -{ - register unsigned char const - *p1 = (unsigned char const*)s1, - *p2 = (unsigned char const*)s2; - register size_t i = n; - register int r = 0; - while (i-- && !(r = (*p1++ - *p2++))) - ; - return r; -} -#endif - -#if !has_memcpy - void * -memcpy(s1, s2, n) - void *s1; - void const *s2; - size_t n; -{ - register char *p1 = (char*)s1; - register char const *p2 = (char const*)s2; - while (n--) - *p1++ = *p2++; - return s1; -} -#endif - -#if RCS_lint - malloc_type lintalloc; -#endif - -/* - * list of blocks allocated with ftestalloc() - * These blocks can be freed by ffree when we're done with the current file. - * We could put the free block inside struct alloclist, rather than a pointer - * to the free block, but that would be less portable. - */ -struct alloclist { - malloc_type alloc; - struct alloclist *nextalloc; -}; -static struct alloclist *alloced; - - - static malloc_type okalloc P((malloc_type)); - static malloc_type -okalloc(p) - malloc_type p; -{ - if (!p) - faterror("out of memory"); - return p; -} - - malloc_type -testalloc(size) - size_t size; -/* Allocate a block, testing that the allocation succeeded. */ -{ - return okalloc(malloc(size)); -} - - malloc_type -testrealloc(ptr, size) - malloc_type ptr; - size_t size; -/* Reallocate a block, testing that the allocation succeeded. */ -{ - return okalloc(realloc(ptr, size)); -} - - malloc_type -fremember(ptr) - malloc_type ptr; -/* Remember PTR in 'alloced' so that it can be freed later. Yield PTR. */ -{ - register struct alloclist *q = talloc(struct alloclist); - q->nextalloc = alloced; - alloced = q; - return q->alloc = ptr; -} - - malloc_type -ftestalloc(size) - size_t size; -/* Allocate a block, putting it in 'alloced' so it can be freed later. */ -{ - return fremember(testalloc(size)); -} - - void -ffree() -/* Free all blocks allocated with ftestalloc(). */ -{ - register struct alloclist *p, *q; - for (p = alloced; p; p = q) { - q = p->nextalloc; - tfree(p->alloc); - tfree(p); - } - alloced = 0; -} - - void -ffree1(f) - register char const *f; -/* Free the block f, which was allocated by ftestalloc. */ -{ - register struct alloclist *p, **a = &alloced; - - while ((p = *a)->alloc != f) - a = &p->nextalloc; - *a = p->nextalloc; - tfree(p->alloc); - tfree(p); -} - - char * -str_save(s) - char const *s; -/* Save s in permanently allocated storage. */ -{ - return strcpy(tnalloc(char, strlen(s)+1), s); -} - - char * -fstr_save(s) - char const *s; -/* Save s in storage that will be deallocated when we're done with this file. */ -{ - return strcpy(ftnalloc(char, strlen(s)+1), s); -} - - char * -cgetenv(name) - char const *name; -/* Like getenv(), but yield a copy; getenv() can overwrite old results. */ -{ - register char *p; - - return (p=getenv(name)) ? str_save(p) : p; -} - - char const * -getusername(suspicious) - int suspicious; -/* Get the caller's login name. Trust only getwpuid if SUSPICIOUS. */ -{ - static char *name; - - if (!name) { - if ( - /* Prefer getenv() unless suspicious; it's much faster. */ -# if getlogin_is_secure - (suspicious - || ( - !(name = cgetenv("LOGNAME")) - && !(name = cgetenv("USER")) - )) - && !(name = getlogin()) -# else - suspicious - || ( - !(name = cgetenv("LOGNAME")) - && !(name = cgetenv("USER")) - && !(name = getlogin()) - ) -# endif - ) { -#if has_getuid && has_getpwuid - struct passwd const *pw = getpwuid(ruid()); - if (!pw) - faterror("no password entry for userid %lu", - (unsigned long)ruid() - ); - name = pw->pw_name; -#else -#if has_setuid - faterror("setuid not supported"); -#else - faterror("Who are you? Please setenv LOGNAME."); -#endif -#endif - } - checksid(name); - } - return name; -} - - - - -#if has_signal - -/* - * Signal handling - * - * Standard C places too many restrictions on signal handlers. - * We obey as many of them as we can. - * Posix places fewer restrictions, and we are Posix-compatible here. - */ - -static sig_atomic_t volatile heldsignal, holdlevel; -#ifdef SA_SIGINFO - static int unsupported_SA_SIGINFO; - static siginfo_t bufsiginfo; - static siginfo_t *volatile heldsiginfo; -#endif - - -#if has_NFS && has_mmap && large_memory && mmap_signal - static char const *accessName; - - void - readAccessFilenameBuffer(filename, p) - char const *filename; - unsigned char const *p; - { - unsigned char volatile t; - accessName = filename; - t = *p; - accessName = 0; - } -#else -# define accessName ((char const *) 0) -#endif - - -#if !has_psignal - -# define psignal my_psignal - static void my_psignal P((int,char const*)); - static void -my_psignal(sig, s) - int sig; - char const *s; -{ - char const *sname = "Unknown signal"; -# if has_sys_siglist && defined(NSIG) - if ((unsigned)sig < NSIG) - sname = sys_siglist[sig]; -# else - switch (sig) { -# ifdef SIGHUP - case SIGHUP: sname = "Hangup"; break; -# endif -# ifdef SIGINT - case SIGINT: sname = "Interrupt"; break; -# endif -# ifdef SIGPIPE - case SIGPIPE: sname = "Broken pipe"; break; -# endif -# ifdef SIGQUIT - case SIGQUIT: sname = "Quit"; break; -# endif -# ifdef SIGTERM - case SIGTERM: sname = "Terminated"; break; -# endif -# ifdef SIGXCPU - case SIGXCPU: sname = "Cputime limit exceeded"; break; -# endif -# ifdef SIGXFSZ - case SIGXFSZ: sname = "Filesize limit exceeded"; break; -# endif -# if has_mmap && large_memory -# if defined(SIGBUS) && mmap_signal==SIGBUS - case SIGBUS: sname = "Bus error"; break; -# endif -# if defined(SIGSEGV) && mmap_signal==SIGSEGV - case SIGSEGV: sname = "Segmentation fault"; break; -# endif -# endif - } -# endif - - /* Avoid calling sprintf etc., in case they're not reentrant. */ - { - char const *p; - char buf[BUFSIZ], *b = buf; - for (p = s; *p; *b++ = *p++) - continue; - *b++ = ':'; - *b++ = ' '; - for (p = sname; *p; *b++ = *p++) - continue; - *b++ = '\n'; - VOID write(STDERR_FILENO, buf, b - buf); - } -} -#endif - -static signal_type catchsig P((int)); -#ifdef SA_SIGINFO - static signal_type catchsigaction P((int,siginfo_t*,void*)); -#endif - - static signal_type -catchsig(s) - int s; -#ifdef SA_SIGINFO -{ - catchsigaction(s, (siginfo_t *)0, (void *)0); -} - static signal_type -catchsigaction(s, i, c) - int s; - siginfo_t *i; - void *c; -#endif -{ -# if sig_zaps_handler - /* If a signal arrives before we reset the handler, we lose. */ - VOID signal(s, SIG_IGN); -# endif - -# ifdef SA_SIGINFO - if (!unsupported_SA_SIGINFO) - i = 0; -# endif - - if (holdlevel) { - heldsignal = s; -# ifdef SA_SIGINFO - if (i) { - bufsiginfo = *i; - heldsiginfo = &bufsiginfo; - } -# endif - return; - } - - ignoreints(); - setrid(); - if (!quietflag) { - /* Avoid calling sprintf etc., in case they're not reentrant. */ - char const *p; - char buf[BUFSIZ], *b = buf; - - if ( ! ( -# if has_mmap && large_memory && mmap_signal - /* Check whether this signal was planned. */ - s == mmap_signal && accessName -# else - 0 -# endif - )) { - char const *nRCS = "\nRCS"; -# if defined(SA_SIGINFO) && has_si_errno && has_mmap && large_memory && mmap_signal - if (s == mmap_signal && i && i->si_errno) { - errno = i->si_errno; - perror(nRCS++); - } -# endif -# if defined(SA_SIGINFO) && has_psiginfo - if (i) - psiginfo(i, nRCS); - else - psignal(s, nRCS); -# else - psignal(s, nRCS); -# endif - } - - for (p = "RCS: "; *p; *b++ = *p++) - continue; -# if has_mmap && large_memory && mmap_signal - if (s == mmap_signal) { - p = accessName; - if (!p) - p = "Was a file changed by some other process? "; - else { - char const *p1; - for (p1 = p; *p1; p1++) - continue; - VOID write(STDERR_FILENO, buf, b - buf); - VOID write(STDERR_FILENO, p, p1 - p); - b = buf; - p = ": Permission denied. "; - } - while (*p) - *b++ = *p++; - } -# endif - for (p = "Cleaning up.\n"; *p; *b++ = *p++) - continue; - VOID write(STDERR_FILENO, buf, b - buf); - } - exiterr(); -} - - void -ignoreints() -{ - ++holdlevel; -} - - void -restoreints() -{ - if (!--holdlevel && heldsignal) -# ifdef SA_SIGINFO - VOID catchsigaction(heldsignal, heldsiginfo, (void *)0); -# else - VOID catchsig(heldsignal); -# endif -} - - -static void setup_catchsig P((int const*,int)); - -#if has_sigaction - - static void check_sig P((int)); - static void - check_sig(r) - int r; - { - if (r != 0) - efaterror("signal handling"); - } - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register int i, j; - struct sigaction act; - - for (i=sigs; 0<=--i; ) { - check_sig(sigaction(sig[i], (struct sigaction*)0, &act)); - if (act.sa_handler != SIG_IGN) { - act.sa_handler = catchsig; -# ifdef SA_SIGINFO - if (!unsupported_SA_SIGINFO) { -# if has_sa_sigaction - act.sa_sigaction = catchsigaction; -# else - act.sa_handler = catchsigaction; -# endif - act.sa_flags |= SA_SIGINFO; - } -# endif - for (j=sigs; 0<=--j; ) - check_sig(sigaddset(&act.sa_mask, sig[j])); - if (sigaction(sig[i], &act, (struct sigaction*)0) != 0) { -# if defined(SA_SIGINFO) && defined(ENOTSUP) - if (errno == ENOTSUP && !unsupported_SA_SIGINFO) { - /* Turn off use of SA_SIGINFO and try again. */ - unsupported_SA_SIGINFO = 1; - i++; - continue; - } -# endif - check_sig(-1); - } - } - } - } - -#else -#if has_sigblock - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register int i; - int mask; - - mask = 0; - for (i=sigs; 0<=--i; ) - mask |= sigmask(sig[i]); - mask = sigblock(mask); - for (i=sigs; 0<=--i; ) - if ( - signal(sig[i], catchsig) == SIG_IGN && - signal(sig[i], SIG_IGN) != catchsig - ) - faterror("signal catcher failure"); - VOID sigsetmask(mask); - } - -#else - - static void - setup_catchsig(sig, sigs) - int const *sig; - int sigs; - { - register i; - - for (i=sigs; 0<=--i; ) - if ( - signal(sig[i], SIG_IGN) != SIG_IGN && - signal(sig[i], catchsig) != SIG_IGN - ) - faterror("signal catcher failure"); - } - -#endif -#endif - - -static int const regsigs[] = { -# ifdef SIGHUP - SIGHUP, -# endif -# ifdef SIGINT - SIGINT, -# endif -# ifdef SIGPIPE - SIGPIPE, -# endif -# ifdef SIGQUIT - SIGQUIT, -# endif -# ifdef SIGTERM - SIGTERM, -# endif -# ifdef SIGXCPU - SIGXCPU, -# endif -# ifdef SIGXFSZ - SIGXFSZ, -# endif -}; - - void -catchints() -{ - static int catching_ints; - if (!catching_ints) { - catching_ints = true; - setup_catchsig(regsigs, (int) (sizeof(regsigs)/sizeof(*regsigs))); - } -} - -#if has_mmap && large_memory && mmap_signal - - /* - * If you mmap an NFS file, and someone on another client removes the last - * link to that file, and you later reference an uncached part of that file, - * you'll get a SIGBUS or SIGSEGV (depending on the operating system). - * Catch the signal and report the problem to the user. - * Unfortunately, there's no portable way to differentiate between this - * problem and actual bugs in the program. - * This NFS problem is rare, thank goodness. - * - * This can also occur if someone truncates the file, even without NFS. - */ - - static int const mmapsigs[] = { mmap_signal }; - - void - catchmmapints() - { - static int catching_mmap_ints; - if (!catching_mmap_ints) { - catching_mmap_ints = true; - setup_catchsig(mmapsigs, (int)(sizeof(mmapsigs)/sizeof(*mmapsigs))); - } - } -#endif - -#endif /* has_signal */ - - - void -fastcopy(inf,outf) - register RILE *inf; - FILE *outf; -/* Function: copies the remainder of file inf to outf. - */ -{ -#if large_memory -# if maps_memory - awrite((char const*)inf->ptr, (size_t)(inf->lim - inf->ptr), outf); - inf->ptr = inf->lim; -# else - for (;;) { - awrite((char const*)inf->ptr, (size_t)(inf->readlim - inf->ptr), outf); - inf->ptr = inf->readlim; - if (inf->ptr == inf->lim) - break; - VOID Igetmore(inf); - } -# endif -#else - char buf[BUFSIZ*8]; - register fread_type rcount; - - /*now read the rest of the file in blocks*/ - while (!feof(inf)) { - if (!(rcount = Fread(buf,sizeof(*buf),sizeof(buf),inf))) { - testIerror(inf); - return; - } - awrite(buf, (size_t)rcount, outf); - } -#endif -} - -#ifndef SSIZE_MAX - /* This does not work in #ifs, but it's good enough for us. */ - /* Underestimating SSIZE_MAX may slow us down, but it won't break us. */ -# define SSIZE_MAX ((unsigned)-1 >> 1) -#endif - - void -awrite(buf, chars, f) - char const *buf; - size_t chars; - FILE *f; -{ - /* Posix 1003.1-1990 ssize_t hack */ - while (SSIZE_MAX < chars) { - if (Fwrite(buf, sizeof(*buf), SSIZE_MAX, f) != SSIZE_MAX) - Oerror(); - buf += SSIZE_MAX; - chars -= SSIZE_MAX; - } - - if (Fwrite(buf, sizeof(*buf), chars, f) != chars) - Oerror(); -} - -/* dup a file descriptor; the result must not be stdin, stdout, or stderr. */ - static int dupSafer P((int)); - static int -dupSafer(fd) - int fd; -{ -# ifdef F_DUPFD - return fcntl(fd, F_DUPFD, STDERR_FILENO + 1); -# else - int e, f, i, used = 0; - while (STDIN_FILENO <= (f = dup(fd)) && f <= STDERR_FILENO) - used |= 1<string); - bufrealloc(b, bl + sl + 4); - p = b->string + bl; - *p++ = c; - *p++ = '\''; - while (*s) { - if (*s == '\'') { - *p++ = '\''; - *p++ = '\\'; - *p++ = '\''; - } - *p++ = *s++; - } - *p++ = '\''; - *p = 0; -} - -#endif - -#if !has_spawn && has_fork -/* -* Output the string S to stderr, without touching any I/O buffers. -* This is useful if you are a child process, whose buffers are usually wrong. -* Exit immediately if the write does not completely succeed. -*/ -static void write_stderr P((char const *)); - static void -write_stderr(s) - char const *s; -{ - size_t slen = strlen(s); - if (write(STDERR_FILENO, s, slen) != slen) - _exit(EXIT_TROUBLE); -} -#endif - -/* -* Run a command. -* infd, if not -1, is the input file descriptor. -* outname, if nonzero, is the name of the output file. -* args[1..] form the command to be run; args[0] might be modified. -*/ - int -runv(infd, outname, args) - int infd; - char const *outname, **args; -{ - int wstatus; - -#if bad_wait_if_SIGCHLD_ignored - static int fixed_SIGCHLD; - if (!fixed_SIGCHLD) { - fixed_SIGCHLD = true; -# ifndef SIGCHLD -# define SIGCHLD SIGCLD -# endif - VOID signal(SIGCHLD, SIG_DFL); - } -#endif - - oflush(); - eflush(); - { -#if has_spawn - int in, out; - char const *file; - - in = -1; - if (infd != -1 && infd != STDIN_FILENO) { - if ((in = dup(STDIN_FILENO)) < 0) { - if (errno != EBADF) - efaterror("spawn input setup"); - in = -2; - } else { -# ifdef F_DUPFD - if (close(STDIN_FILENO) != 0) - efaterror("spawn input close"); -# endif - } - if ( -# ifdef F_DUPFD - fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO -# else - dup2(infd, STDIN_FILENO) != STDIN_FILENO -# endif - ) - efaterror("spawn input redirection"); - } - - out = -1; - if (outname) { - if ((out = dup(STDOUT_FILENO)) < 0) { - if (errno != EBADF) - efaterror("spawn output setup"); - out = -2; - } - if (fdreopen( - STDOUT_FILENO, outname, - O_CREAT | O_TRUNC | O_WRONLY - ) < 0) - efaterror(outname); - } - - wstatus = spawn_RCS(0, args[1], (char**)(args + 1)); -# ifdef RCS_SHELL - if (wstatus == -1 && errno == ENOEXEC) { - args[0] = RCS_SHELL; - wstatus = spawnv(0, args[0], (char**)args); - } -# endif - redirect(in, STDIN_FILENO); - redirect(out, STDOUT_FILENO); -#else -#if has_fork - pid_t pid; - if (!(pid = vfork())) { - char const *notfound; - if (infd != -1 && infd != STDIN_FILENO && ( -# ifdef F_DUPFD - (VOID close(STDIN_FILENO), - fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO) -# else - dup2(infd, STDIN_FILENO) != STDIN_FILENO -# endif - )) { - /* Avoid perror since it may misuse buffers. */ - write_stderr(args[1]); - write_stderr(": I/O redirection failed\n"); - _exit(EXIT_TROUBLE); - } - - if (outname) - if (fdreopen( - STDOUT_FILENO, outname, - O_CREAT | O_TRUNC | O_WRONLY - ) < 0) { - /* Avoid perror since it may misuse buffers. */ - write_stderr(args[1]); - write_stderr(": "); - write_stderr(outname); - write_stderr(": cannot create\n"); - _exit(EXIT_TROUBLE); - } - VOID exec_RCS(args[1], (char**)(args + 1)); - notfound = args[1]; -# ifdef RCS_SHELL - if (errno == ENOEXEC) { - args[0] = notfound = RCS_SHELL; - VOID execv(args[0], (char**)args); - } -# endif - - /* Avoid perror since it may misuse buffers. */ - write_stderr(notfound); - write_stderr(": not found\n"); - _exit(EXIT_TROUBLE); - } - if (pid < 0) - efaterror("fork"); -# if has_waitpid - if (waitpid(pid, &wstatus, 0) < 0) - efaterror("waitpid"); -# else - { - pid_t w; - do { - if ((w = wait(&wstatus)) < 0) - efaterror("wait"); - } while (w != pid); - } -# endif -#else - static struct buf b; - char const *p; - - /* Use system(). On many hosts system() discards signals. Yuck! */ - p = args + 1; - bufscpy(&b, *p); - while (*++p) - bufargcat(&b, ' ', *p); - if (infd != -1 && infd != STDIN_FILENO) { - char redirection[32]; - VOID sprintf(redirection, "<&%d", infd); - bufscat(&b, redirection); - } - if (outname) - bufargcat(&b, '>', outname); - wstatus = system(b.string); -#endif -#endif - } - if (!WIFEXITED(wstatus)) { - if (WIFSIGNALED(wstatus)) { - psignal(WTERMSIG(wstatus), args[1]); - fatcleanup(1); - } - faterror("%s failed for unknown reason", args[1]); - } - return WEXITSTATUS(wstatus); -} - -#define CARGSMAX 20 -/* -* Run a command. -* infd, if not -1, is the input file descriptor. -* outname, if nonzero, is the name of the output file. -* The remaining arguments specify the command and its arguments. -*/ - int -#if has_prototypes -run(int infd, char const *outname, ...) -#else - /*VARARGS2*/ -run(infd, outname, va_alist) - int infd; - char const *outname; - va_dcl -#endif -{ - va_list ap; - char const *rgargs[CARGSMAX]; - register int i; - vararg_start(ap, outname); - for (i = 1; (rgargs[i++] = va_arg(ap, char const*)); ) - if (CARGSMAX <= i) - faterror("too many command arguments"); - va_end(ap); - return runv(infd, outname, rgargs); -} - - -int RCSversion; - - void -setRCSversion(str) - char const *str; -{ - static int oldversion; - - register char const *s = str + 2; - - if (*s) { - int v = VERSION_DEFAULT; - - if (oldversion) - redefined('V'); - oldversion = true; - v = 0; - while (isdigit(*s)) - v = 10*v + *s++ - '0'; - if (*s) - error("%s isn't a number", str); - else if (v < VERSION_min || VERSION_max < v) - error("%s out of range %d..%d", - str, VERSION_min, VERSION_max - ); - - RCSversion = VERSION(v); - } else { - printf("RCS version %s\n", RCS_version_string); - exit(0); - } -} - - int -getRCSINIT(argc, argv, newargv) - int argc; - char **argv, ***newargv; -{ - register char *p, *q, **pp; - char const *ev; - size_t n; - - if ((ev = cgetenv("RCSLOCALID"))) - setRCSLocalId(ev); - - if ((ev = cgetenv("RCSINCEXC"))) - setIncExc(ev); - - if (!(q = cgetenv("RCSINIT"))) - *newargv = argv; - else { - n = argc + 2; - /* - * Count spaces in RCSINIT to allocate a new arg vector. - * This is an upper bound, but it's OK even if too large. - */ - for (p = q; ; ) { - switch (*p++) { - default: - continue; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - n++; - continue; - - case '\0': - break; - } - break; - } - *newargv = pp = tnalloc(char*, n); - *pp++ = *argv++; /* copy program name */ - for (p = q; ; ) { - for (;;) { - switch (*q) { - case '\0': - goto copyrest; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - q++; - continue; - } - break; - } - *pp++ = p; - ++argc; - for (;;) { - switch ((*p++ = *q++)) { - case '\0': - goto copyrest; - - case '\\': - if (!*q) - goto copyrest; - p[-1] = *q++; - continue; - - default: - continue; - - case ' ': - case '\b': case '\f': case '\n': - case '\r': case '\t': case '\v': - break; - } - break; - } - p[-1] = '\0'; - } - copyrest: - while ((*pp++ = *argv++)) - continue; - } - return argc; -} - - -#define cacheid(E) static uid_t i; static int s; if (!s){ s=1; i=(E); } return i - -#if has_getuid - uid_t ruid() { cacheid(getuid()); } -#endif -#if has_setuid - uid_t euid() { cacheid(geteuid()); } -#endif - - -#if has_setuid - -/* - * Setuid execution really works only with Posix 1003.1a Draft 5 seteuid(), - * because it lets us switch back and forth between arbitrary users. - * If seteuid() doesn't work, we fall back on setuid(), - * which works if saved setuid is supported, - * unless the real or effective user is root. - * This area is such a mess that we always check switches at runtime. - */ - - static void -#if has_prototypes -set_uid_to(uid_t u) -#else - set_uid_to(u) uid_t u; -#endif -/* Become user u. */ -{ - static int looping; - - if (euid() == ruid()) - return; -#if (has_fork||has_spawn) && DIFF_ABSOLUTE -# if has_setreuid - if (setreuid(u==euid() ? ruid() : euid(), u) != 0) - efaterror("setuid"); -# else - if (seteuid(u) != 0) - efaterror("setuid"); -# endif -#endif - if (geteuid() != u) { - if (looping) - return; - looping = true; - faterror("root setuid not supported" + (u?5:0)); - } -} - -static int stick_with_euid; - - void -/* Ignore all calls to seteid() and setrid(). */ -nosetid() -{ - stick_with_euid = true; -} - - void -seteid() -/* Become effective user. */ -{ - if (!stick_with_euid) - set_uid_to(euid()); -} - - void -setrid() -/* Become real user. */ -{ - if (!stick_with_euid) - set_uid_to(ruid()); -} -#endif - - time_t -now() -{ - static time_t t; - if (!t && time(&t) == -1) - efaterror("time"); - return t; -} diff --git a/gnu/usr.bin/rcs/lib/version.c b/gnu/usr.bin/rcs/lib/version.c deleted file mode 100644 index 81f5585b9d1d..000000000000 --- a/gnu/usr.bin/rcs/lib/version.c +++ /dev/null @@ -1,2 +0,0 @@ -#include "rcsbase.h" -char const RCS_version_string[] = "5.7"; diff --git a/gnu/usr.bin/rcs/merge/Makefile b/gnu/usr.bin/rcs/merge/Makefile deleted file mode 100644 index 9022bc4bf6e5..000000000000 --- a/gnu/usr.bin/rcs/merge/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= merge -SRCS= merge.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/merge/Makefile.depend b/gnu/usr.bin/rcs/merge/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/merge/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/merge/merge.1 b/gnu/usr.bin/rcs/merge/merge.1 deleted file mode 100644 index a4fd35b7986a..000000000000 --- a/gnu/usr.bin/rcs/merge/merge.1 +++ /dev/null @@ -1,137 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.TH MERGE 1 \*(Dt GNU -.SH NAME -merge \- three-way file merge -.SH SYNOPSIS -.B merge -[ -.I "options" -] -.I "file1 file2 file3" -.SH DESCRIPTION -.B merge -incorporates all changes that lead from -.I file2 -to -.I file3 -into -.IR file1 . -The result ordinarily goes into -.IR file1 . -.B merge -is useful for combining separate changes to an original. Suppose -.I file2 -is the original, and both -.I file1 -and -.I file3 -are modifications of -.IR file2 . -Then -.B merge -combines both changes. -.PP -A conflict occurs if both -.I file1 -and -.I file3 -have changes in a common segment of lines. -If a conflict is found, -.B merge -normally outputs a warning and brackets the conflict with -.B <<<<<<< -and -.B >>>>>>> -lines. -A typical conflict will look like this: -.LP -.RS -.nf -.BI <<<<<<< " file A" -.I "lines in file A" -.B "=======" -.I "lines in file B" -.BI >>>>>>> " file B" -.RE -.fi -.LP -If there are conflicts, the user should edit the result and delete one of the -alternatives. -.SH OPTIONS -.TP -.B \-A -Output conflicts using the -.B \-A -style of -.BR diff3 (1), -if supported by -.BR diff3 . -This merges all changes leading from -.I file2 -to -.I file3 -into -.IR file1 , -and generates the most verbose output. -.TP -\f3\-E\fP, \f3\-e\fP -These options specify conflict styles that generate less information -than -.BR \-A . -See -.BR diff3 (1) -for details. -The default is -.BR \-E . -With -.BR \-e , -.B merge -does not warn about conflicts. -.TP -.BI \-L " label" -This option may be given up to three times, and specifies labels -to be used in place of the corresponding file names in conflict reports. -That is, -.B "merge\ \-L\ x\ \-L\ y\ \-L\ z\ a\ b\ c" -generates output that looks like it came from files -.BR x , -.B y -and -.B z -instead of from files -.BR a , -.B b -and -.BR c . -.TP -.BI \-p -Send results to standard output instead of overwriting -.IR file1 . -.TP -.BI \-q -Quiet; do not warn about conflicts. -.TP -.BI \-V -Print \*r's version number. -.SH DIAGNOSTICS -Exit status is 0 for no conflicts, 1 for some conflicts, 2 for trouble. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH SEE ALSO -diff3(1), diff(1), rcsmerge(1), co(1). -.SH BUGS -It normally does not make sense to merge binary files as if they were text, but -.B merge -tries to do it anyway. -.br diff --git a/gnu/usr.bin/rcs/merge/merge.c b/gnu/usr.bin/rcs/merge/merge.c deleted file mode 100644 index aa127bf1c8ec..000000000000 --- a/gnu/usr.bin/rcs/merge/merge.c +++ /dev/null @@ -1,113 +0,0 @@ -/* merge - three-way file merge */ - -/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -static void badoption P((char const*)); - -static char const usage[] = - "\nmerge: usage: merge [-AeEpqxX3] [-L lab [-L lab [-L lab]]] file1 file2 file3"; - - static void -badoption(a) - char const *a; -{ - error("unknown option: %s%s", a, usage); -} - - -mainProg(mergeId, "merge", "$FreeBSD$") -{ - register char const *a; - char const *arg[3], *label[3], *edarg = 0; - int labels, tostdout; - - labels = 0; - tostdout = false; - - for (; (a = *++argv) && *a++ == '-'; --argc) { - switch (*a++) { - case 'A': case 'E': case 'e': - if (edarg && edarg[1] != (*argv)[1]) - error("%s and %s are incompatible", - edarg, *argv - ); - edarg = *argv; - break; - - case 'p': tostdout = true; break; - case 'q': quietflag = true; break; - - case 'L': - if (3 <= labels) - faterror("too many -L options"); - if (!(label[labels++] = *++argv)) - faterror("-L needs following argument"); - --argc; - break; - - case 'V': - printf("RCS version %s\n", RCS_version_string); - exitmain(0); - - default: - badoption(a - 2); - continue; - } - if (*a) - badoption(a - 2); - } - - if (argc != 4) - faterror("%s arguments%s", - argc<4 ? "not enough" : "too many", usage - ); - - /* This copy keeps us `const'-clean. */ - arg[0] = argv[0]; - arg[1] = argv[1]; - arg[2] = argv[2]; - - for (; labels < 3; labels++) - label[labels] = arg[labels]; - - if (nerror) - exiterr(); - exitmain(merge(tostdout, edarg, label, arg)); -} - - -#if RCS_lint -# define exiterr mergeExit -#endif - void -exiterr() -{ - tempunlink(); - _exit(DIFF_TROUBLE); -} diff --git a/gnu/usr.bin/rcs/rcs/Makefile b/gnu/usr.bin/rcs/rcs/Makefile deleted file mode 100644 index aa7cc5fb315d..000000000000 --- a/gnu/usr.bin/rcs/rcs/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -PROG= rcs -MAN= rcs.1 rcsintro.1 rcsfile.5 -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/rcs/Makefile.depend b/gnu/usr.bin/rcs/rcs/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/rcs/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rcs/rcs.1 b/gnu/usr.bin/rcs/rcs/rcs.1 deleted file mode 100644 index 37fb59fea068..000000000000 --- a/gnu/usr.bin/rcs/rcs/rcs.1 +++ /dev/null @@ -1,454 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.if !\n(.g \{\ -. if !\w|\*(lq| \{\ -. ds lq `` -. if \w'\(lq' .ds lq "\(lq -. \} -. if !\w|\*(rq| \{\ -. ds rq '' -. if \w'\(rq' .ds rq "\(rq -. \} -.\} -.TH RCS 1 \*(Dt GNU -.SH NAME -rcs \- change RCS file attributes -.SH SYNOPSIS -.B rcs -.IR "options file " .\|.\|. -.SH DESCRIPTION -.B rcs -creates new \*r files or changes attributes of existing ones. -An \*r file contains multiple revisions of text, -an access list, a change log, -descriptive text, -and some control attributes. -For -.B rcs -to work, the caller's login name must be on the access list, -except if the access list is empty, the caller is the owner of the file -or the superuser, or -the -.B \-i -option is present. -.PP -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -Names are paired as explained in -.BR ci (1). -Revision numbers use the syntax described in -.BR ci (1). -.SH OPTIONS -.TP -.B \-i -Create and initialize a new \*r file, but do not deposit any revision. -If the \*r file has no path prefix, try to place it -first into the subdirectory -.BR ./RCS , -and then into the current directory. -If the \*r file -already exists, print an error message. -.TP -.BI \-a "logins" -Append the login names appearing in the comma-separated list -.I logins -to the access list of the \*r file. -.TP -.BI \-A "oldfile" -Append the access list of -.I oldfile -to the access list of the \*r file. -.TP -.BR \-e [\f2logins\fP] -Erase the login names appearing in the comma-separated list -.I logins -from the access list of the \*r file. -If -.I logins -is omitted, erase the entire access list. -.TP -.BR \-b [\f2rev\fP] -Set the default branch to -.IR rev . -If -.I rev -is omitted, the default -branch is reset to the (dynamically) highest branch on the trunk. -.TP -.BI \-c string -Set the comment leader to -.IR string . -An initial -.BR ci , -or an -.B "rcs\ \-i" -without -.BR \-c , -guesses the comment leader from the suffix of the working filename. -.RS -.PP -This option is obsolescent, since \*r normally uses the preceding -.B $\&Log$ -line's prefix when inserting log lines during checkout (see -.BR co (1)). -However, older versions of \*r use the comment leader instead of the -.B $\&Log$ -line's prefix, so -if you plan to access a file with both old and new versions of \*r, -make sure its comment leader matches its -.B $\&Log$ -line prefix. -.RE -.TP -.BI \-k subst -Set the default keyword substitution to -.IR subst . -The effect of keyword substitution is described in -.BR co (1). -Giving an explicit -.B \-k -option to -.BR co , -.BR rcsdiff , -and -.B rcsmerge -overrides this default. -Beware -.BR "rcs\ \-kv", -because -.B \-kv -is incompatible with -.BR "co\ \-l". -Use -.B "rcs\ \-kkv" -to restore the normal default keyword substitution. -.TP -.BR \-l [\f2rev\fP] -Lock the revision with number -.IR rev . -If a branch is given, lock the latest revision on that branch. -If -.I rev -is omitted, lock the latest revision on the default branch. -Locking prevents overlapping changes. -If someone else already holds the lock, the lock is broken as with -.B "rcs\ \-u" -(see below). -.TP -.BR \-u [\f2rev\fP] -Unlock the revision with number -.IR rev . -If a branch is given, unlock the latest revision on that branch. -If -.I rev -is omitted, remove the latest lock held by the caller. -Normally, only the locker of a revision can unlock it. -Somebody else unlocking a revision breaks the lock. -This causes a mail message to be sent to the original locker. -The message contains a commentary solicited from the breaker. -The commentary is terminated by end-of-file or by a line containing -.BR \&. "\ by" -itself. -.TP -.B \-L -Set locking to -.IR strict . -Strict locking means that the owner -of an \*r file is not exempt from locking for checkin. -This option should be used for files that are shared. -.TP -.B \-U -Set locking to non-strict. Non-strict locking means that the owner of -a file need not lock a revision for checkin. -This option should -.I not -be used for files that are shared. -Whether default locking is strict is determined by your system administrator, -but it is normally strict. -.TP -\f3\-m\fP\f2rev\fP\f3:\fP\f2msg\fP -Replace revision -.IR rev 's -log message with -.IR msg . -.TP -.B \-M -Do not send mail when breaking somebody else's lock. -This option is not meant for casual use; -it is meant for programs that warn users by other means, and invoke -.B "rcs\ \-u" -only as a low-level lock-breaking operation. -.TP -\f3\-n\fP\f2name\fP[\f3:\fP[\f2rev\fP]] -Associate the symbolic name -.I name -with the branch or -revision -.IR rev . -Delete the symbolic name if both -.B : -and -.I rev -are omitted; otherwise, print an error message if -.I name -is already associated with -another number. -If -.I rev -is symbolic, it is expanded before association. -A -.I rev -consisting of a branch number followed by a -.B .\& -stands for the current latest revision in the branch. -A -.B : -with an empty -.I rev -stands for the current latest revision on the default branch, -normally the trunk. -For example, -.BI "rcs\ \-n" name ":\ RCS/*" -associates -.I name -with the current latest revision of all the named \*r files; -this contrasts with -.BI "rcs\ \-n" name ":$\ RCS/*" -which associates -.I name -with the revision numbers extracted from keyword strings -in the corresponding working files. -.TP -\f3\-N\fP\f2name\fP[\f3:\fP[\f2rev\fP]] -Act like -.BR \-n , -except override any previous assignment of -.IR name . -.TP -.BI \-o range -deletes (\*(lqoutdates\*(rq) the revisions given by -.IR range . -A range consisting of a single revision number means that revision. -A range consisting of a branch number means the latest revision on that -branch. -A range of the form -.IB rev1 : rev2 -means -revisions -.I rev1 -to -.I rev2 -on the same branch, -.BI : rev -means from the beginning of the branch containing -.I rev -up to and including -.IR rev , -and -.IB rev : -means -from revision -.I rev -to the end of the branch containing -.IR rev . -None of the outdated revisions can have branches or locks. -.TP -.B \-q -Run quietly; do not print diagnostics. -.TP -.B \-I -Run interactively, even if the standard input is not a terminal. -.TP -.B \-s\f2state\fP\f1[\fP:\f2rev\fP\f1]\fP -Set the state attribute of the revision -.I rev -to -.IR state . -If -.I rev -is a branch number, assume the latest revision on that branch. -If -.I rev -is omitted, assume the latest revision on the default branch. -Any identifier is acceptable for -.IR state . -A useful set of states -is -.B Exp -(for experimental), -.B Stab -(for stable), and -.B Rel -(for -released). -By default, -.BR ci (1) -sets the state of a revision to -.BR Exp . -.TP -.BR \-t [\f2file\fP] -Write descriptive text from the contents of the named -.I file -into the \*r file, deleting the existing text. -The -.IR file -pathname cannot begin with -.BR \- . -If -.I file -is omitted, obtain the text from standard input, -terminated by end-of-file or by a line containing -.BR \&. "\ by" -itself. -Prompt for the text if interaction is possible; see -.BR \-I . -With -.BR \-i , -descriptive text is obtained -even if -.B \-t -is not given. -.TP -.BI \-t\- string -Write descriptive text from the -.I string -into the \*r file, deleting the existing text. -.TP -.B \-T -Preserve the modification time on the \*r file -unless a revision is removed. -This option can suppress extensive recompilation caused by a -.BR make (1) -dependency of some copy of the working file on the \*r file. -Use this option with care; it can suppress recompilation even when it is needed, -i.e. when a change to the \*r file -would mean a change to keyword strings in the working file. -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.IR n . -See -.BR co (1) -for details. -.TP -.BI \-x "suffixes" -Use -.I suffixes -to characterize \*r files. -See -.BR ci (1) -for details. -.TP -.BI \-z zone -Use -.I zone -as the default time zone. -This option has no effect; -it is present for compatibility with other \*r commands. -.PP -At least one explicit option must be given, -to ensure compatibility with future planned extensions -to the -.B rcs -command. -.SH COMPATIBILITY -The -.BI \-b rev -option generates an \*r file that cannot be parsed by \*r version 3 or earlier. -.PP -The -.BI \-k subst -options (except -.BR \-kkv ) -generate an \*r file that cannot be parsed by \*r version 4 or earlier. -.PP -Use -.BI "rcs \-V" n -to make an \*r file acceptable to \*r version -.I n -by discarding information that would confuse version -.IR n . -.PP -\*r version 5.5 and earlier does not support the -.B \-x -option, and requires a -.B ,v -suffix on an \*r pathname. -.SH FILES -.B rcs -accesses files much as -.BR ci (1) -does, -except that it uses the effective user for all accesses, -it does not write the working file or its directory, -and it does not even read the working file unless a revision number of -.B $ -is specified. -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -See -.BR ci (1) -for details. -.SH DIAGNOSTICS -The \*r pathname and the revisions outdated are written to -the diagnostic output. -The exit status is zero if and only if all operations were successful. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH "SEE ALSO" -rcsintro(1), co(1), ci(1), ident(1), rcsclean(1), rcsdiff(1), -rcsmerge(1), rlog(1), rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.SH BUGS -A catastrophe (e.g. a system crash) can cause \*r to leave behind -a semaphore file that causes later invocations of \*r to claim -that the \*r file is in use. -To fix this, remove the semaphore file. -A semaphore file's name typically begins with -.B , -or ends with -.BR _ . -.PP -The separator for revision ranges in the -.B \-o -option used to be -.B \- -instead of -.BR : , -but this leads to confusion when symbolic names contain -.BR \- . -For backwards compatibility -.B "rcs \-o" -still supports the old -.B \- -separator, but it warns about this obsolete use. -.PP -Symbolic names need not refer to existing revisions or branches. -For example, the -.B \-o -option does not remove symbolic names for the outdated revisions; you must use -.B \-n -to remove the names. -.br diff --git a/gnu/usr.bin/rcs/rcs/rcs.c b/gnu/usr.bin/rcs/rcs/rcs.c deleted file mode 100644 index dfb622a6f808..000000000000 --- a/gnu/usr.bin/rcs/rcs/rcs.c +++ /dev/null @@ -1,1629 +0,0 @@ -/* Change RCS file attributes. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.21 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.20 1995/06/01 16:23:43 eggert - * (main): Warn if no options were given. Punctuate messages properly. - * - * (sendmail): Rewind mailmess before flushing it. - * Output another warning if mail should work but fails. - * - * (buildeltatext): Pass "--binary" if -kb and if --binary makes a difference. - * - * Revision 5.19 1994/03/17 14:05:48 eggert - * Use ORCSerror to clean up after a fatal error. Remove lint. - * Specify subprocess input via file descriptor, not file name. Remove lint. - * Flush stderr after prompt. - * - * Revision 5.18 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. Don't print usage twice. - * - * Revision 5.17 1993/11/03 17:42:27 eggert - * Add -z. Don't lose track of -m or -t when there are no other changes. - * Don't discard ignored phrases. Improve quality of diagnostics. - * - * Revision 5.16 1992/07/28 16:12:44 eggert - * rcs -l now asks whether you want to break the lock. - * Add -V. Set RCS file's mode and time at right moment. - * - * Revision 5.15 1992/02/17 23:02:20 eggert - * Add -T. - * - * Revision 5.14 1992/01/27 16:42:53 eggert - * Add -M. Avoid invoking umask(); it's one less thing to configure. - * Add support for bad_creat0. lint -> RCS_lint - * - * Revision 5.13 1992/01/06 02:42:34 eggert - * Avoid changing RCS file in common cases where no change can occur. - * - * Revision 5.12 1991/11/20 17:58:08 eggert - * Don't read the delta tree from a nonexistent RCS file. - * - * Revision 5.11 1991/10/07 17:32:46 eggert - * Remove lint. - * - * Revision 5.10 1991/08/19 23:17:54 eggert - * Add -m, -r$, piece tables. Revision separator is `:', not `-'. Tune. - * - * Revision 5.9 1991/04/21 11:58:18 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.8 1991/02/25 07:12:38 eggert - * strsave -> str_save (DG/UX name clash) - * 0444 -> S_IRUSR|S_IRGRP|S_IROTH for portability - * - * Revision 5.7 1990/12/18 17:19:21 eggert - * Fix bug with multiple -n and -N options. - * - * Revision 5.6 1990/12/04 05:18:40 eggert - * Use -I for prompts and -q for diagnostics. - * - * Revision 5.5 1990/11/11 00:06:35 eggert - * Fix `rcs -e' core dump. - * - * Revision 5.4 1990/11/01 05:03:33 eggert - * Add -I and new -t behavior. Permit arbitrary data in logs. - * - * Revision 5.3 1990/10/04 06:30:16 eggert - * Accumulate exit status across files. - * - * Revision 5.2 1990/09/04 08:02:17 eggert - * Standardize yes-or-no procedure. - * - * Revision 5.1 1990/08/29 07:13:51 eggert - * Remove unused setuid support. Clean old log messages too. - * - * Revision 5.0 1990/08/22 08:12:42 eggert - * Don't lose names when applying -a option to multiple files. - * Remove compile-time limits; use malloc instead. Add setuid support. - * Permit dates past 1999/12/31. Make lock and temp files faster and safer. - * Ansify and Posixate. Add -V. Fix umask bug. Make linting easier. Tune. - * Yield proper exit status. Check diff's output. - * - * Revision 4.11 89/05/01 15:12:06 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.10 88/11/08 16:01:54 narten - * didn't install previous patch correctly - * - * Revision 4.9 88/11/08 13:56:01 narten - * removed include (not needed) - * minor fix for -A option - * - * Revision 4.8 88/08/09 19:12:27 eggert - * Don't access freed storage. - * Use execv(), not system(); yield proper exit status; remove lint. - * - * Revision 4.7 87/12/18 11:37:17 narten - * lint cleanups (Guy Harris) - * - * Revision 4.6 87/10/18 10:28:48 narten - * Updating verison numbers. Changes relative to 1.1 are actually - * relative to 4.3 - * - * Revision 1.4 87/09/24 13:58:52 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.3 87/03/27 14:21:55 jenkins - * Port to suns - * - * Revision 1.2 85/12/17 13:59:09 albitz - * Changed setstate to rcs_setstate because of conflict with random.o. - * - * Revision 4.3 83/12/15 12:27:33 wft - * rcs -u now breaks most recent lock if it can't find a lock by the caller. - * - * Revision 4.2 83/12/05 10:18:20 wft - * Added conditional compilation for sending mail. - * Alternatives: V4_2BSD, V6, USG, and other. - * - * Revision 4.1 83/05/10 16:43:02 wft - * Simplified breaklock(); added calls to findlock() and getcaller(). - * Added option -b (default branch). Updated -s and -w for -b. - * Removed calls to stat(); now done by pairfilenames(). - * Replaced most catchints() calls with restoreints(). - * Removed check for exit status of delivermail(). - * Directed all interactive output to stderr. - * - * Revision 3.9.1.1 83/12/02 22:08:51 wft - * Added conditional compilation for 4.2 sendmail and 4.1 delivermail. - * - * Revision 3.9 83/02/15 15:38:39 wft - * Added call to fastcopy() to copy remainder of RCS file. - * - * Revision 3.8 83/01/18 17:37:51 wft - * Changed sendmail(): now uses delivermail, and asks whether to break the lock. - * - * Revision 3.7 83/01/15 18:04:25 wft - * Removed putree(); replaced with puttree() in rcssyn.c. - * Combined putdellog() and scanlogtext(); deleted putdellog(). - * Cleaned up diagnostics and error messages. Fixed problem with - * mutilated files in case of deletions in 2 files in a single command. - * Changed marking of selector from 'D' to DELETE. - * - * Revision 3.6 83/01/14 15:37:31 wft - * Added ignoring of interrupts while new RCS file is renamed; - * Avoids deletion of RCS files by interrupts. - * - * Revision 3.5 82/12/10 21:11:39 wft - * Removed unused variables, fixed checking of return code from diff, - * introduced variant COMPAT2 for skipping Suffix on -A files. - * - * Revision 3.4 82/12/04 13:18:20 wft - * Replaced getdelta() with gettree(), changed breaklock to update - * field lockedby, added some diagnostics. - * - * Revision 3.3 82/12/03 17:08:04 wft - * Replaced getlogin() with getpwuid(), flcose() with ffclose(), - * /usr/ucb/Mail with macro MAIL. Removed handling of Suffix (-x). - * fixed -u for missing revno. Disambiguated structure members. - * - * Revision 3.2 82/10/18 21:05:07 wft - * rcs -i now generates a file mode given by the umask minus write permission; - * otherwise, rcs keeps the mode, but removes write permission. - * I added a check for write error, fixed call to getlogin(), replaced - * curdir() with getfullRCSname(), cleaned up handling -U/L, and changed - * conflicting, long identifiers. - * - * Revision 3.1 82/10/13 16:11:07 wft - * fixed type of variables receiving from getc() (char -> int). - */ - - -#include "rcsbase.h" - -struct Lockrev { - char const *revno; - struct Lockrev * nextrev; -}; - -struct Symrev { - char const *revno; - char const *ssymbol; - int override; - struct Symrev * nextsym; -}; - -struct Message { - char const *revno; - struct cbuf message; - struct Message *nextmessage; -}; - -struct Status { - char const *revno; - char const *status; - struct Status * nextstatus; -}; - -enum changeaccess {append, erase}; -struct chaccess { - char const *login; - enum changeaccess command; - struct chaccess *nextchaccess; -}; - -struct delrevpair { - char const *strt; - char const *end; - int code; -}; - -static int branchpoint P((struct hshentry*,struct hshentry*)); -static int breaklock P((struct hshentry const*)); -static int buildeltatext P((struct hshentries const*)); -static int doaccess P((void)); -static int doassoc P((void)); -static int dolocks P((void)); -static int domessages P((void)); -static int rcs_setstate P((char const*,char const*)); -static int removerevs P((void)); -static int sendmail P((char const*,char const*)); -static int setlock P((char const*)); -static struct Lockrev **rmnewlocklst P((char const*)); -static struct hshentry *searchcutpt P((char const*,int,struct hshentries*)); -static void buildtree P((void)); -static void cleanup P((void)); -static void getaccessor P((char*,enum changeaccess)); -static void getassoclst P((int,char*)); -static void getchaccess P((char const*,enum changeaccess)); -static void getdelrev P((char*)); -static void getmessage P((char*)); -static void getstates P((char*)); -static void scanlogtext P((struct hshentry*,int)); - -static struct buf numrev; -static char const *headstate; -static int chgheadstate, exitstatus, lockhead, unlockcaller; -static int suppress_mail; -static struct Lockrev *newlocklst, *rmvlocklst; -static struct Message *messagelst, **nextmessage; -static struct Status *statelst, **nextstate; -static struct Symrev *assoclst, **nextassoc; -static struct chaccess *chaccess, **nextchaccess; -static struct delrevpair delrev; -static struct hshentry *cuthead, *cuttail, *delstrt; -static struct hshentries *gendeltas; - -mainProg(rcsId, "rcs", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nrcs usage: rcs -{ae}logins -Afile -{blu}[rev] -cstring -{iILqTU} -ksubst -mrev:msg -{nN}name[:[rev]] -orange -sstate[:rev] -t[text] -Vn -xsuff -zzone file ..."; - - char *a, **newargv, *textfile; - char const *branchsym, *commsyml; - int branchflag, changed, expmode, initflag; - int strictlock, strict_selected, textflag; - int keepRCStime, Ttimeflag; - size_t commsymlen; - struct buf branchnum; - struct Lockrev *lockpt; - struct Lockrev **curlock, **rmvlock; - struct Status * curstate; - - nosetid(); - - nextassoc = &assoclst; - nextchaccess = &chaccess; - nextmessage = &messagelst; - nextstate = &statelst; - branchsym = commsyml = textfile = 0; - branchflag = strictlock = false; - bufautobegin(&branchnum); - commsymlen = 0; - curlock = &newlocklst; - rmvlock = &rmvlocklst; - expmode = -1; - suffixes = X_DEFAULT; - initflag= textflag = false; - strict_selected = 0; - Ttimeflag = false; - - /* preprocessing command options */ - if (1 < argc && argv[1][0] != '-') - warn("No options were given; this usage is obsolescent."); - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - switch (*a++) { - - case 'i': /* initial version */ - initflag = true; - break; - - case 'b': /* change default branch */ - if (branchflag) redefined('b'); - branchflag= true; - branchsym = a; - break; - - case 'c': /* change comment symbol */ - if (commsyml) redefined('c'); - commsyml = a; - commsymlen = strlen(a); - break; - - case 'a': /* add new accessor */ - getaccessor(*argv+1, append); - break; - - case 'A': /* append access list according to accessfile */ - if (!*a) { - error("missing pathname after -A"); - break; - } - *argv = a; - if (0 < pairnames(1,argv,rcsreadopen,true,false)) { - while (AccessList) { - getchaccess(str_save(AccessList->login),append); - AccessList = AccessList->nextaccess; - } - Izclose(&finptr); - } - break; - - case 'e': /* remove accessors */ - getaccessor(*argv+1, erase); - break; - - case 'l': /* lock a revision if it is unlocked */ - if (!*a) { - /* Lock head or default branch. */ - lockhead = true; - break; - } - *curlock = lockpt = talloc(struct Lockrev); - lockpt->revno = a; - lockpt->nextrev = 0; - curlock = &lockpt->nextrev; - break; - - case 'u': /* release lock of a locked revision */ - if (!*a) { - unlockcaller=true; - break; - } - *rmvlock = lockpt = talloc(struct Lockrev); - lockpt->revno = a; - lockpt->nextrev = 0; - rmvlock = &lockpt->nextrev; - curlock = rmnewlocklst(lockpt->revno); - break; - - case 'L': /* set strict locking */ - if (strict_selected) { - if (!strictlock) /* Already selected -U? */ - warn("-U overridden by -L"); - } - strictlock = true; - strict_selected = true; - break; - - case 'U': /* release strict locking */ - if (strict_selected) { - if (strictlock) /* Already selected -L? */ - warn("-L overridden by -U"); - } - strict_selected = true; - break; - - case 'n': /* add new association: error, if name exists */ - if (!*a) { - error("missing symbolic name after -n"); - break; - } - getassoclst(false, (*argv)+1); - break; - - case 'N': /* add or change association */ - if (!*a) { - error("missing symbolic name after -N"); - break; - } - getassoclst(true, (*argv)+1); - break; - - case 'm': /* change log message */ - getmessage(a); - break; - - case 'M': /* do not send mail */ - suppress_mail = true; - break; - - case 'o': /* delete revisions */ - if (delrev.strt) redefined('o'); - if (!*a) { - error("missing revision range after -o"); - break; - } - getdelrev( (*argv)+1 ); - break; - - case 's': /* change state attribute of a revision */ - if (!*a) { - error("state missing after -s"); - break; - } - getstates( (*argv)+1); - break; - - case 't': /* change descriptive text */ - textflag=true; - if (*a) { - if (textfile) redefined('t'); - textfile = a; - } - break; - - case 'T': /* do not update last-mod time for minor changes */ - if (*a) - goto unknown; - Ttimeflag = true; - break; - - case 'I': - interactiveflag = true; - break; - - case 'q': - quietflag = true; - break; - - case 'x': - suffixes = a; - break; - - case 'V': - setRCSversion(*argv); - break; - - case 'z': - zone_set(a); - break; - - case 'k': /* set keyword expand mode */ - if (0 <= expmode) redefined('k'); - if (0 <= (expmode = str2expmode(a))) - break; - /* fall into */ - default: - unknown: - error("unknown option: %s%s", *argv, cmdusage); - }; - } /* end processing of options */ - - /* Now handle all pathnames. */ - if (nerror) cleanup(); - else if (argc < 1) faterror("no input file%s", cmdusage); - else for (; 0 < argc; cleanup(), ++argv, --argc) { - - ffree(); - - if ( initflag ) { - switch (pairnames(argc, argv, rcswriteopen, false, false)) { - case -1: break; /* not exist; ok */ - case 0: continue; /* error */ - case 1: rcserror("already exists"); - continue; - } - } - else { - switch (pairnames(argc, argv, rcswriteopen, true, false)) { - case -1: continue; /* not exist */ - case 0: continue; /* errors */ - case 1: break; /* file exists; ok*/ - } - } - - - /* - * RCSname contains the name of the RCS file, and - * workname contains the name of the working file. - * if !initflag, finptr contains the file descriptor for the - * RCS file. The admin node is initialized. - */ - - diagnose("RCS file: %s\n", RCSname); - - changed = initflag | textflag; - keepRCStime = Ttimeflag; - if (!initflag) { - if (!checkaccesslist()) continue; - gettree(); /* Read the delta tree. */ - } - - /* update admin. node */ - if (strict_selected) { - changed |= StrictLocks ^ strictlock; - StrictLocks = strictlock; - } - if ( - commsyml && - ( - commsymlen != Comment.size || - memcmp(commsyml, Comment.string, commsymlen) != 0 - ) - ) { - Comment.string = commsyml; - Comment.size = strlen(commsyml); - changed = true; - } - if (0 <= expmode && Expand != expmode) { - Expand = expmode; - changed = true; - } - - /* update default branch */ - if (branchflag && expandsym(branchsym, &branchnum)) { - if (countnumflds(branchnum.string)) { - if (cmpnum(Dbranch, branchnum.string) != 0) { - Dbranch = branchnum.string; - changed = true; - } - } else - if (Dbranch) { - Dbranch = 0; - changed = true; - } - } - - changed |= doaccess(); /* Update access list. */ - - changed |= doassoc(); /* Update association list. */ - - changed |= dolocks(); /* Update locks. */ - - changed |= domessages(); /* Update log messages. */ - - /* update state attribution */ - if (chgheadstate) { - /* change state of default branch or head */ - if (!Dbranch) { - if (!Head) - rcswarn("can't change states in an empty tree"); - else if (strcmp(Head->state, headstate) != 0) { - Head->state = headstate; - changed = true; - } - } else - changed |= rcs_setstate(Dbranch,headstate); - } - for (curstate = statelst; curstate; curstate = curstate->nextstatus) - changed |= rcs_setstate(curstate->revno,curstate->status); - - cuthead = cuttail = 0; - if (delrev.strt && removerevs()) { - /* rebuild delta tree if some deltas are deleted */ - if ( cuttail ) - VOID genrevs( - cuttail->num, (char *)0, (char *)0, (char *)0, - &gendeltas - ); - buildtree(); - changed = true; - keepRCStime = false; - } - - if (nerror) - continue; - - putadmin(); - if ( Head ) - puttree(Head, frewrite); - putdesc(textflag,textfile); - - if ( Head) { - if (delrev.strt || messagelst) { - if (!cuttail || buildeltatext(gendeltas)) { - advise_access(finptr, MADV_SEQUENTIAL); - scanlogtext((struct hshentry *)0, false); - /* copy rest of delta text nodes that are not deleted */ - changed = true; - } - } - } - - if (initflag) { - /* Adjust things for donerewrite's sake. */ - if (stat(workname, &RCSstat) != 0) { -# if bad_creat0 - mode_t m = umask(0); - (void) umask(m); - RCSstat.st_mode = (S_IRUSR|S_IRGRP|S_IROTH) & ~m; -# else - changed = -1; -# endif - } - RCSstat.st_nlink = 0; - keepRCStime = false; - } - if (donerewrite(changed, - keepRCStime ? RCSstat.st_mtime : (time_t)-1 - ) != 0) - break; - - diagnose("done\n"); - } - - tempunlink(); - exitmain(exitstatus); -} /* end of main (rcs) */ - - static void -cleanup() -{ - if (nerror) exitstatus = EXIT_FAILURE; - Izclose(&finptr); - Ozclose(&fcopy); - ORCSclose(); - dirtempunlink(); -} - - void -exiterr() -{ - ORCSerror(); - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} - - - static void -getassoclst(flag, sp) -int flag; -char * sp; -/* Function: associate a symbolic name to a revision or branch, */ -/* and store in assoclst */ - -{ - struct Symrev * pt; - char const *temp; - int c; - - while ((c = *++sp) == ' ' || c == '\t' || c =='\n') - continue; - temp = sp; - sp = checksym(sp, ':'); /* check for invalid symbolic name */ - c = *sp; *sp = '\0'; - while( c == ' ' || c == '\t' || c == '\n') c = *++sp; - - if ( c != ':' && c != '\0') { - error("invalid string %s after option -n or -N",sp); - return; - } - - pt = talloc(struct Symrev); - pt->ssymbol = temp; - pt->override = flag; - if (c == '\0') /* delete symbol */ - pt->revno = 0; - else { - while ((c = *++sp) == ' ' || c == '\n' || c == '\t') - continue; - pt->revno = sp; - } - pt->nextsym = 0; - *nextassoc = pt; - nextassoc = &pt->nextsym; -} - - - static void -getchaccess(login, command) - char const *login; - enum changeaccess command; -{ - register struct chaccess *pt; - - pt = talloc(struct chaccess); - pt->login = login; - pt->command = command; - pt->nextchaccess = 0; - *nextchaccess = pt; - nextchaccess = &pt->nextchaccess; -} - - - - static void -getaccessor(opt, command) - char *opt; - enum changeaccess command; -/* Function: get the accessor list of options -e and -a, */ -/* and store in chaccess */ - - -{ - register c; - register char *sp; - - sp = opt; - while ((c = *++sp) == ' ' || c == '\n' || c == '\t' || c == ',') - continue; - if ( c == '\0') { - if (command == erase && sp-opt == 1) { - getchaccess((char*)0, command); - return; - } - error("missing login name after option -a or -e"); - return; - } - - while( c != '\0') { - getchaccess(sp, command); - sp = checkid(sp,','); - c = *sp; *sp = '\0'; - while( c == ' ' || c == '\n' || c == '\t'|| c == ',')c =(*++sp); - } -} - - - static void -getmessage(option) - char *option; -{ - struct Message *pt; - struct cbuf cb; - char *m; - - if (!(m = strchr(option, ':'))) { - error("-m option lacks revision number"); - return; - } - *m++ = 0; - cb = cleanlogmsg(m, strlen(m)); - if (!cb.size) { - error("-m option lacks log message"); - return; - } - pt = talloc(struct Message); - pt->revno = option; - pt->message = cb; - pt->nextmessage = 0; - *nextmessage = pt; - nextmessage = &pt->nextmessage; -} - - - static void -getstates(sp) -char *sp; -/* Function: get one state attribute and the corresponding */ -/* revision and store in statelst */ - -{ - char const *temp; - struct Status *pt; - register c; - - while ((c = *++sp) ==' ' || c == '\t' || c == '\n') - continue; - temp = sp; - sp = checkid(sp,':'); /* check for invalid state attribute */ - c = *sp; *sp = '\0'; - while( c == ' ' || c == '\t' || c == '\n' ) c = *++sp; - - if ( c == '\0' ) { /* change state of def. branch or Head */ - chgheadstate = true; - headstate = temp; - return; - } - else if ( c != ':' ) { - error("missing ':' after state in option -s"); - return; - } - - while ((c = *++sp) == ' ' || c == '\t' || c == '\n') - continue; - pt = talloc(struct Status); - pt->status = temp; - pt->revno = sp; - pt->nextstatus = 0; - *nextstate = pt; - nextstate = &pt->nextstatus; -} - - - - static void -getdelrev(sp) -char *sp; -/* Function: get revision range or branch to be deleted, */ -/* and place in delrev */ -{ - int c; - struct delrevpair *pt; - int separator; - - pt = &delrev; - while ((c = (*++sp)) == ' ' || c == '\n' || c == '\t') - continue; - - /* Support old ambiguous '-' syntax; this will go away. */ - if (strchr(sp,':')) - separator = ':'; - else { - if (strchr(sp,'-') && VERSION(5) <= RCSversion) - warn("`-' is obsolete in `-o%s'; use `:' instead", sp); - separator = '-'; - } - - if (c == separator) { /* -o:rev */ - while ((c = (*++sp)) == ' ' || c == '\n' || c == '\t') - continue; - pt->strt = sp; pt->code = 1; - while( c != ' ' && c != '\n' && c != '\t' && c != '\0') c =(*++sp); - *sp = '\0'; - pt->end = 0; - return; - } - else { - pt->strt = sp; - while( c != ' ' && c != '\n' && c != '\t' && c != '\0' - && c != separator ) c = *++sp; - *sp = '\0'; - while( c == ' ' || c == '\n' || c == '\t' ) c = *++sp; - if ( c == '\0' ) { /* -o rev or branch */ - pt->code = 0; - pt->end = 0; - return; - } - if (c != separator) { - error("invalid range %s %s after -o", pt->strt, sp); - } - while ((c = *++sp) == ' ' || c == '\n' || c == '\t') - continue; - if (!c) { /* -orev: */ - pt->code = 2; - pt->end = 0; - return; - } - } - /* -orev1:rev2 */ - pt->end = sp; pt->code = 3; - while( c!= ' ' && c != '\n' && c != '\t' && c != '\0') c = *++sp; - *sp = '\0'; -} - - - - - static void -scanlogtext(delta,edit) - struct hshentry *delta; - int edit; -/* Function: Scans delta text nodes up to and including the one given - * by delta, or up to last one present, if !delta. - * For the one given by delta (if delta), the log message is saved into - * delta->log if delta==cuttail; the text is edited if EDIT is set, else copied. - * Assumes the initial lexeme must be read in first. - * Does not advance nexttok after it is finished, except if !delta. - */ -{ - struct hshentry const *nextdelta; - struct cbuf cb; - - for (;;) { - foutptr = 0; - if (eoflex()) { - if(delta) - rcsfaterror("can't find delta for revision %s", - delta->num - ); - return; /* no more delta text nodes */ - } - nextlex(); - if (!(nextdelta=getnum())) - fatserror("delta number corrupted"); - if (nextdelta->selector) { - foutptr = frewrite; - aprintf(frewrite,DELNUMFORM,nextdelta->num,Klog); - } - getkeystring(Klog); - if (nextdelta == cuttail) { - cb = savestring(&curlogbuf); - if (!delta->log.string) - delta->log = cleanlogmsg(curlogbuf.string, cb.size); - nextlex(); - delta->igtext = getphrases(Ktext); - } else { - if (nextdelta->log.string && nextdelta->selector) { - foutptr = 0; - readstring(); - foutptr = frewrite; - putstring(foutptr, false, nextdelta->log, true); - afputc(nextc, foutptr); - } else - readstring(); - ignorephrases(Ktext); - } - getkeystring(Ktext); - - if (delta==nextdelta) - break; - readstring(); /* skip over it */ - - } - /* got the one we're looking for */ - if (edit) - editstring((struct hshentry*)0); - else - enterstring(); -} - - - - static struct Lockrev ** -rmnewlocklst(which) - char const *which; -/* Remove lock to revision WHICH from newlocklst. */ -{ - struct Lockrev *pt, **pre; - - pre = &newlocklst; - while ((pt = *pre)) - if (strcmp(pt->revno, which) != 0) - pre = &pt->nextrev; - else { - *pre = pt->nextrev; - tfree(pt); - } - return pre; -} - - - - static int -doaccess() -{ - register struct chaccess *ch; - register struct access **p, *t; - register int changed = false; - - for (ch = chaccess; ch; ch = ch->nextchaccess) { - switch (ch->command) { - case erase: - if (!ch->login) { - if (AccessList) { - AccessList = 0; - changed = true; - } - } else - for (p = &AccessList; (t = *p); p = &t->nextaccess) - if (strcmp(ch->login, t->login) == 0) { - *p = t->nextaccess; - changed = true; - break; - } - break; - case append: - for (p = &AccessList; ; p = &t->nextaccess) - if (!(t = *p)) { - *p = t = ftalloc(struct access); - t->login = ch->login; - t->nextaccess = 0; - changed = true; - break; - } else if (strcmp(ch->login, t->login) == 0) - break; - break; - } - } - return changed; -} - - - static int -sendmail(Delta, who) - char const *Delta, *who; -/* Function: mail to who, informing him that his lock on delta was - * broken by caller. Ask first whether to go ahead. Return false on - * error or if user decides not to break the lock. - */ -{ -#ifdef SENDMAIL - char const *messagefile; - int old1, old2, c, status; - FILE * mailmess; -#endif - - - aprintf(stderr, "Revision %s is already locked by %s.\n", Delta, who); - if (suppress_mail) - return true; - if (!yesorno(false, "Do you want to break the lock? [ny](n): ")) - return false; - - /* go ahead with breaking */ -#ifdef SENDMAIL - messagefile = maketemp(0); - if (!(mailmess = fopenSafer(messagefile, "w+"))) { - efaterror(messagefile); - } - - aprintf(mailmess, "Subject: Broken lock on %s\n\nYour lock on revision %s of file %s\nhas been broken by %s for the following reason:\n", - basefilename(RCSname), Delta, getfullRCSname(), getcaller() - ); - aputs("State the reason for breaking the lock:\n(terminate with single '.' or end of file)\n>> ", stderr); - eflush(); - - old1 = '\n'; old2 = ' '; - for (; ;) { - c = getcstdin(); - if (feof(stdin)) { - aprintf(mailmess, "%c\n", old1); - break; - } - else if ( c == '\n' && old1 == '.' && old2 == '\n') - break; - else { - afputc(old1, mailmess); - old2 = old1; old1 = c; - if (c == '\n') { - aputs(">> ", stderr); - eflush(); - } - } - } - Orewind(mailmess); - aflush(mailmess); - status = run(fileno(mailmess), (char*)0, SENDMAIL, who, (char*)0); - Ozclose(&mailmess); - if (status == 0) - return true; - warn("Mail failed."); -#endif - warn("Mail notification of broken locks is not available."); - warn("Please tell `%s' why you broke the lock.", who); - return(true); -} - - - - static int -breaklock(delta) - struct hshentry const *delta; -/* function: Finds the lock held by caller on delta, - * and removes it. - * Sends mail if a lock different from the caller's is broken. - * Prints an error message if there is no such lock or error. - */ -{ - register struct rcslock *next, **trail; - char const *num; - - num=delta->num; - for (trail = &Locks; (next = *trail); trail = &next->nextlock) - if (strcmp(num, next->delta->num) == 0) { - if ( - strcmp(getcaller(),next->login) != 0 - && !sendmail(num, next->login) - ) { - rcserror("revision %s still locked by %s", - num, next->login - ); - return false; - } - diagnose("%s unlocked\n", next->delta->num); - *trail = next->nextlock; - next->delta->lockedby = 0; - return true; - } - rcserror("no lock set on revision %s", num); - return false; -} - - - - static struct hshentry * -searchcutpt(object, length, store) - char const *object; - int length; - struct hshentries *store; -/* Function: Search store and return entry with number being object. */ -/* cuttail = 0, if the entry is Head; otherwise, cuttail */ -/* is the entry point to the one with number being object */ - -{ - cuthead = 0; - while (compartial(store->first->num, object, length)) { - cuthead = store->first; - store = store->rest; - } - return store->first; -} - - - - static int -branchpoint(strt, tail) -struct hshentry *strt, *tail; -/* Function: check whether the deltas between strt and tail */ -/* are locked or branch point, return 1 if any is */ -/* locked or branch point; otherwise, return 0 and */ -/* mark deleted */ - -{ - struct hshentry *pt; - struct rcslock const *lockpt; - - for (pt = strt; pt != tail; pt = pt->next) { - if ( pt->branches ){ /* a branch point */ - rcserror("can't remove branch point %s", pt->num); - return true; - } - for (lockpt = Locks; lockpt; lockpt = lockpt->nextlock) - if (lockpt->delta == pt) { - rcserror("can't remove locked revision %s", pt->num); - return true; - } - pt->selector = false; - diagnose("deleting revision %s\n",pt->num); - } - return false; -} - - - - static int -removerevs() -/* Function: get the revision range to be removed, and place the */ -/* first revision removed in delstrt, the revision before */ -/* delstrt in cuthead (0, if delstrt is head), and the */ -/* revision after the last removed revision in cuttail (0 */ -/* if the last is a leaf */ - -{ - struct hshentry *target, *target2, *temp; - int length; - int cmp; - - if (!expandsym(delrev.strt, &numrev)) return 0; - target = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&gendeltas); - if ( ! target ) return 0; - cmp = cmpnum(target->num, numrev.string); - length = countnumflds(numrev.string); - - if (delrev.code == 0) { /* -o rev or -o branch */ - if (length & 1) - temp=searchcutpt(target->num,length+1,gendeltas); - else if (cmp) { - rcserror("Revision %s doesn't exist.", numrev.string); - return 0; - } - else - temp = searchcutpt(numrev.string, length, gendeltas); - cuttail = target->next; - if ( branchpoint(temp, cuttail) ) { - cuttail = 0; - return 0; - } - delstrt = temp; /* first revision to be removed */ - return 1; - } - - if (length & 1) { /* invalid branch after -o */ - rcserror("invalid branch range %s after -o", numrev.string); - return 0; - } - - if (delrev.code == 1) { /* -o -rev */ - if ( length > 2 ) { - temp = searchcutpt( target->num, length-1, gendeltas); - cuttail = target->next; - } - else { - temp = searchcutpt(target->num, length, gendeltas); - cuttail = target; - while( cuttail && ! cmpnumfld(target->num,cuttail->num,1) ) - cuttail = cuttail->next; - } - if ( branchpoint(temp, cuttail) ){ - cuttail = 0; - return 0; - } - delstrt = temp; - return 1; - } - - if (delrev.code == 2) { /* -o rev- */ - if ( length == 2 ) { - temp = searchcutpt(target->num, 1,gendeltas); - if (cmp) - cuttail = target; - else - cuttail = target->next; - } - else { - if (cmp) { - cuthead = target; - if ( !(temp = target->next) ) return 0; - } - else - temp = searchcutpt(target->num, length, gendeltas); - getbranchno(temp->num, &numrev); /* get branch number */ - VOID genrevs(numrev.string, (char*)0, (char*)0, (char*)0, &gendeltas); - } - if ( branchpoint( temp, cuttail ) ) { - cuttail = 0; - return 0; - } - delstrt = temp; - return 1; - } - - /* -o rev1-rev2 */ - if (!expandsym(delrev.end, &numrev)) return 0; - if ( - length != countnumflds(numrev.string) - || (length>2 && compartial(numrev.string, target->num, length-1)) - ) { - rcserror("invalid revision range %s-%s", - target->num, numrev.string - ); - return 0; - } - - target2 = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&gendeltas); - if ( ! target2 ) return 0; - - if ( length > 2) { /* delete revisions on branches */ - if ( cmpnum(target->num, target2->num) > 0) { - cmp = cmpnum(target2->num, numrev.string); - temp = target; - target = target2; - target2 = temp; - } - if (cmp) { - if ( ! cmpnum(target->num, target2->num) ) { - rcserror("Revisions %s-%s don't exist.", - delrev.strt, delrev.end - ); - return 0; - } - cuthead = target; - temp = target->next; - } - else - temp = searchcutpt(target->num, length, gendeltas); - cuttail = target2->next; - } - else { /* delete revisions on trunk */ - if ( cmpnum( target->num, target2->num) < 0 ) { - temp = target; - target = target2; - target2 = temp; - } - else - cmp = cmpnum(target2->num, numrev.string); - if (cmp) { - if ( ! cmpnum(target->num, target2->num) ) { - rcserror("Revisions %s-%s don't exist.", - delrev.strt, delrev.end - ); - return 0; - } - cuttail = target2; - } - else - cuttail = target2->next; - temp = searchcutpt(target->num, length, gendeltas); - } - if ( branchpoint(temp, cuttail) ) { - cuttail = 0; - return 0; - } - delstrt = temp; - return 1; -} - - - - static int -doassoc() -/* Add or delete (if !revno) association that is stored in assoclst. */ -{ - char const *p; - int changed = false; - struct Symrev const *curassoc; - struct assoc **pre, *pt; - - /* add new associations */ - for (curassoc = assoclst; curassoc; curassoc = curassoc->nextsym) { - char const *ssymbol = curassoc->ssymbol; - - if (!curassoc->revno) { /* delete symbol */ - for (pre = &Symbols; ; pre = &pt->nextassoc) - if (!(pt = *pre)) { - rcswarn("can't delete nonexisting symbol %s", ssymbol); - break; - } else if (strcmp(pt->symbol, ssymbol) == 0) { - *pre = pt->nextassoc; - changed = true; - break; - } - } - else { - if (curassoc->revno[0]) { - p = 0; - if (expandsym(curassoc->revno, &numrev)) - p = fstr_save(numrev.string); - } else if (!(p = tiprev())) - rcserror("no latest revision to associate with symbol %s", - ssymbol - ); - if (p) - changed |= addsymbol(p, ssymbol, curassoc->override); - } - } - return changed; -} - - - - static int -dolocks() -/* Function: remove lock for caller or first lock if unlockcaller is set; - * remove locks which are stored in rmvlocklst, - * add new locks which are stored in newlocklst, - * add lock for Dbranch or Head if lockhead is set. - */ -{ - struct Lockrev const *lockpt; - struct hshentry *target; - int changed = false; - - if (unlockcaller) { /* find lock for caller */ - if ( Head ) { - if (Locks) { - switch (findlock(true, &target)) { - case 0: - /* remove most recent lock */ - changed |= breaklock(Locks->delta); - break; - case 1: - diagnose("%s unlocked\n",target->num); - changed = true; - break; - } - } else { - rcswarn("No locks are set."); - } - } else { - rcswarn("can't unlock an empty tree"); - } - } - - /* remove locks which are stored in rmvlocklst */ - for (lockpt = rmvlocklst; lockpt; lockpt = lockpt->nextrev) - if (expandsym(lockpt->revno, &numrev)) { - target = genrevs(numrev.string, (char *)0, (char *)0, (char *)0, &gendeltas); - if ( target ) - if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string)) - rcserror("can't unlock nonexisting revision %s", - lockpt->revno - ); - else - changed |= breaklock(target); - /* breaklock does its own diagnose */ - } - - /* add new locks which stored in newlocklst */ - for (lockpt = newlocklst; lockpt; lockpt = lockpt->nextrev) - changed |= setlock(lockpt->revno); - - if (lockhead) /* lock default branch or head */ - if (Dbranch) - changed |= setlock(Dbranch); - else if (Head) - changed |= setlock(Head->num); - else - rcswarn("can't lock an empty tree"); - return changed; -} - - - - static int -setlock(rev) - char const *rev; -/* Function: Given a revision or branch number, finds the corresponding - * delta and locks it for caller. - */ -{ - struct hshentry *target; - int r; - - if (expandsym(rev, &numrev)) { - target = genrevs(numrev.string, (char*)0, (char*)0, - (char*)0, &gendeltas); - if ( target ) - if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string)) - rcserror("can't lock nonexisting revision %s", - numrev.string - ); - else { - if ((r = addlock(target, false)) < 0 && breaklock(target)) - r = addlock(target, true); - if (0 <= r) { - if (r) - diagnose("%s locked\n", target->num); - return r; - } - } - } - return 0; -} - - - static int -domessages() -{ - struct hshentry *target; - struct Message *p; - int changed = false; - - for (p = messagelst; p; p = p->nextmessage) - if ( - expandsym(p->revno, &numrev) && - (target = genrevs( - numrev.string, (char*)0, (char*)0, (char*)0, &gendeltas - )) - ) { - /* - * We can't check the old log -- it's much later in the file. - * We pessimistically assume that it changed. - */ - target->log = p->message; - changed = true; - } - return changed; -} - - - static int -rcs_setstate(rev,status) - char const *rev, *status; -/* Function: Given a revision or branch number, finds the corresponding delta - * and sets its state to status. - */ -{ - struct hshentry *target; - - if (expandsym(rev, &numrev)) { - target = genrevs(numrev.string, (char*)0, (char*)0, - (char*)0, &gendeltas); - if ( target ) - if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string)) - rcserror("can't set state of nonexisting revision %s", - numrev.string - ); - else if (strcmp(target->state, status) != 0) { - target->state = status; - return true; - } - } - return false; -} - - - - - - static int -buildeltatext(deltas) - struct hshentries const *deltas; -/* Function: put the delta text on frewrite and make necessary */ -/* change to delta text */ -{ - register FILE *fcut; /* temporary file to rebuild delta tree */ - char const *cutname; - - fcut = 0; - cuttail->selector = false; - scanlogtext(deltas->first, false); - if ( cuthead ) { - cutname = maketemp(3); - if (!(fcut = fopenSafer(cutname, FOPEN_WPLUS_WORK))) { - efaterror(cutname); - } - - while (deltas->first != cuthead) { - deltas = deltas->rest; - scanlogtext(deltas->first, true); - } - - snapshotedit(fcut); - Orewind(fcut); - aflush(fcut); - } - - while (deltas->first != cuttail) - scanlogtext((deltas = deltas->rest)->first, true); - finishedit((struct hshentry*)0, (FILE*)0, true); - Ozclose(&fcopy); - - if (fcut) { - char const *diffname = maketemp(0); - char const *diffv[6 + !!OPEN_O_BINARY]; - char const **diffp = diffv; - *++diffp = DIFF; - *++diffp = DIFFFLAGS; -# if OPEN_O_BINARY - if (Expand == BINARY_EXPAND) - *++diffp == "--binary"; -# endif - *++diffp = "-"; - *++diffp = resultname; - *++diffp = 0; - switch (runv(fileno(fcut), diffname, diffv)) { - case DIFF_FAILURE: case DIFF_SUCCESS: break; - default: rcsfaterror("diff failed"); - } - Ofclose(fcut); - return putdtext(cuttail,diffname,frewrite,true); - } else - return putdtext(cuttail,resultname,frewrite,false); -} - - - - static void -buildtree() -/* Function: actually removes revisions whose selector field */ -/* is false, and rebuilds the linkage of deltas. */ -/* asks for reconfirmation if deleting last revision*/ -{ - struct hshentry * Delta; - struct branchhead *pt, *pre; - - if ( cuthead ) - if ( cuthead->next == delstrt ) - cuthead->next = cuttail; - else { - pre = pt = cuthead->branches; - while( pt && pt->hsh != delstrt ) { - pre = pt; - pt = pt->nextbranch; - } - if ( cuttail ) - pt->hsh = cuttail; - else if ( pt == pre ) - cuthead->branches = pt->nextbranch; - else - pre->nextbranch = pt->nextbranch; - } - else { - if (!cuttail && !quietflag) { - if (!yesorno(false, "Do you really want to delete all revisions? [ny](n): ")) { - rcserror("No revision deleted"); - Delta = delstrt; - while( Delta) { - Delta->selector = true; - Delta = Delta->next; - } - return; - } - } - Head = cuttail; - } - return; -} - -#if RCS_lint -/* This lets us lint everything all at once. */ - -char const cmdid[] = ""; - -#define go(p,e) {int p P((int,char**)); void e P((void)); if(*argv)return p(argc,argv);if(*argv[1])e();} - - int -main(argc, argv) - int argc; - char **argv; -{ - go(ciId, ciExit); - go(coId, coExit); - go(identId, identExit); - go(mergeId, mergeExit); - go(rcsId, exiterr); - go(rcscleanId, rcscleanExit); - go(rcsdiffId, rdiffExit); - go(rcsmergeId, rmergeExit); - go(rlogId, rlogExit); - return 0; -} -#endif diff --git a/gnu/usr.bin/rcs/rcs/rcsfile.5 b/gnu/usr.bin/rcs/rcs/rcsfile.5 deleted file mode 100644 index 0d8aac874d45..000000000000 --- a/gnu/usr.bin/rcs/rcs/rcsfile.5 +++ /dev/null @@ -1,425 +0,0 @@ -.lf 1 ./rcsfile.5in -.\" Set p to 1 if your formatter can handle pic output. -.if t .nr p 1 -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH RCSFILE 5 \*(Dt GNU -.SH NAME -rcsfile \- format of RCS file -.SH DESCRIPTION -An \*r file's -contents are described by the grammar -below. -.PP -The text is free format: space, backspace, tab, newline, vertical -tab, form feed, and carriage return (collectively, -.IR "white space") -have no significance except in strings. -However, white space cannot appear within an id, num, or sym, -and an \*r file must end with a newline. -.PP -Strings are enclosed by -.BR @ . -If a string contains a -.BR @ , -it must be doubled; -otherwise, strings can contain arbitrary binary data. -.PP -The meta syntax uses the following conventions: `|' (bar) separates -alternatives; `{' and `}' enclose optional phrases; `{' and `}*' enclose -phrases that can be repeated zero or more times; -`{' and '}+' enclose phrases that must appear at least once and can be -repeated; -Terminal symbols are in -.BR boldface ; -nonterminal symbols are in -.IR italics . -.LP -.nr w \w'\f3deltatext\fP ' -.nr y \w'\f3newphrase\fP ' -.if \nw<\ny .nr w \ny -.nr x \w'\f3branches\fP' -.nr y \w'{ \f3comment\fP' -.if \nx<\ny .nr x \ny -.nr y \w'\f3{ branch\fP' -.if \nx<\ny .nr x \ny -.ta \nwu +\w'::= 'u +\nxu+\w' 'u -.fc # -.nf -\f2rcstext\fP ::= \f2admin\fP {\f2delta\fP}* \f2desc\fP {\f2deltatext\fP}* -.LP -\f2admin\fP ::= \f3head\fP {\f2num\fP}\f3;\fP - { \f3branch\fP {\f2num\fP}\f3;\fP } - \f3access\fP {\f2id\fP}*\f3;\fP - \f3symbols\fP {\f2sym\fP \f3:\fP \f2num\fP}*\f3;\fP - \f3locks\fP {\f2id\fP \f3:\fP \f2num\fP}*\f3;\fP {\f3strict ;\fP} - { \f3comment\fP {\f2string\fP}\f3;\fP } - { \f3expand\fP {\f2string\fP}\f3;\fP } - { \f2newphrase\fP }* -.LP -\f2delta\fP ::= \f2num\fP - \f3date\fP \f2num\fP\f3;\fP - \f3author\fP \f2id\fP\f3;\fP - \f3state\fP {\f2id\fP}\f3;\fP - \f3branches\fP {\f2num\fP}*\f3;\fP - \f3next\fP {\f2num\fP}\f3;\fP - { \f2newphrase\fP }* -.LP -\f2desc\fP ::= \f3desc\fP \f2string\fP -.LP -\f2deltatext\fP ::= \f2num\fP - \f3log\fP \f2string\fP - { \f2newphrase\fP }* - \f3text\fP \f2string\fP -.LP -\f2num\fP ::= {\f2digit\fP | \f3.\fP}+ -.LP -\f2digit\fP ::= \f30\fP | \f31\fP | \f32\fP | \f33\fP | \f34\fP | \f35\fP | \f36\fP | \f37\fP | \f38\fP | \f39\fP -.LP -\f2id\fP ::= {\f2num\fP} \f2idchar\fP {\f2idchar\fP | \f2num\fP}* -.LP -\f2sym\fP ::= {\f2digit\fP}* \f2idchar\fP {\f2idchar\fP | \f2digit\fP}* -.LP -\f2idchar\fP ::= any visible graphic character except \f2special\fP -.LP -\f2special\fP ::= \f3$\fP | \f3,\fP | \f3.\fP | \f3:\fP | \f3;\fP | \f3@\fP -.LP -\f2string\fP ::= \f3@\fP{any character, with \f3@\fP doubled}*\f3@\fP -.LP -\f2newphrase\fP ::= \f2id\fP \f2word\fP* \f3;\fP -.LP -\f2word\fP ::= \f2id\fP | \f2num\fP | \f2string\fP | \f3:\fP -.fi -.PP -Identifiers are case sensitive. Keywords are in lower case only. -The sets of keywords and identifiers can overlap. -In most environments \*r uses the \s-1ISO\s0 8859/1 encoding: -visible graphic characters are codes 041\-176 and 240\-377, -and white space characters are codes 010\-015 and 040. -.PP -Dates, which appear after the -.B date -keyword, are of the form -\f2Y\fP\f3.\fP\f2mm\fP\f3.\fP\f2dd\fP\f3.\fP\f2hh\fP\f3.\fP\f2mm\fP\f3.\fP\f2ss\fP, -where -.I Y -is the year, -.I mm -the month (01\-12), -.I dd -the day (01\-31), -.I hh -the hour (00\-23), -.I mm -the minute (00\-59), -and -.I ss -the second (00\-60). -.I Y -contains just the last two digits of the year -for years from 1900 through 1999, -and all the digits of years thereafter. -Dates use the Gregorian calendar; times use UTC. -.PP -The -.I newphrase -productions in the grammar are reserved for future extensions -to the format of \*r files. -No -.I newphrase -will begin with any keyword already in use. -.PP -The -.I delta -nodes form a tree. All nodes whose numbers -consist of a single pair -(e.g., 2.3, 2.1, 1.3, etc.) -are on the trunk, and are linked through the -.B next -field in order of decreasing numbers. -The -.B head -field in the -.I admin -node points to the head of that sequence (i.e., contains -the highest pair). -The -.B branch -node in the admin node indicates the default -branch (or revision) for most \*r operations. -If empty, the default -branch is the highest branch on the trunk. -.PP -All -.I delta -nodes whose numbers consist of -.RI 2 n -fields -.RI ( n \(>=2) -(e.g., 3.1.1.1, 2.1.2.2, etc.) -are linked as follows. -All nodes whose first -.RI 2 n \-1 -number fields are identical are linked through the -.B next -field in order of increasing numbers. -For each such sequence, -the -.I delta -node whose number is identical to the first -.RI 2 n \-2 -number fields of the deltas on that sequence is called the branchpoint. -The -.B branches -field of a node contains a list of the -numbers of the first nodes of all sequences for which it is a branchpoint. -This list is ordered in increasing numbers. -.LP -The following diagram shows an example of an \*r file's organization. -.if !\np \{\ -.nf -.vs 12 -.ne 36 -.cs 1 20 -.eo - - Head - | - | - v / \ - --------- / \ - / \ / \ | | / \ / \ - / \ / \ | 2.1 | / \ / \ - / \ / \ | | / \ / \ -/1.2.1.3\ /1.3.1.1\ | | /1.2.2.2\ /1.2.2.1.1.1\ ---------- --------- --------- --------- ------------- - ^ ^ | ^ ^ - | | | | | - | | v | | - / \ | --------- / \ | - / \ | \ 1.3 / / \ | - / \ ---------\ / / \----------- -/1.2.1.1\ \ / /1.2.2.1\ ---------- \ / --------- - ^ | ^ - | | | - | v | - | --------- | - | \ 1.2 / | - ----------------------\ /--------- - \ / - \ / - | - | - v - --------- - \ 1.1 / - \ / - \ / - \ / - -.ec -.cs 1 -.vs -.fi -.\} -.if \np \{\ -.lf 232 -.PS 4.250i 3.812i -.\" -2.0625 -4.25 1.75 0 -.\" 0.000i 4.250i 3.812i 0.000i -.nr 00 \n(.u -.nf -.nr 0x 1 -\h'3.812i' -.sp -1 -.lf 242 -\h'2.062i-(\w'Head'u/2u)'\v'0.125i-(0v/2u)+0v+0.22m'Head -.sp -1 -\h'2.062i'\v'0.250i'\D'l0.000i 0.500i' -.sp -1 -\h'2.087i'\v'0.650i'\D'l-0.025i 0.100i' -.sp -1 -\h'2.062i'\v'0.750i'\D'l-0.025i -0.100i' -.sp -1 -\h'1.688i'\v'1.250i'\D'l0.750i 0.000i' -.sp -1 -\h'2.438i'\v'1.250i'\D'l0.000i -0.500i' -.sp -1 -\h'2.438i'\v'0.750i'\D'l-0.750i 0.000i' -.sp -1 -\h'1.688i'\v'0.750i'\D'l0.000i 0.500i' -.sp -1 -.lf 244 -\h'2.062i-(\w'2.1'u/2u)'\v'1.000i-(0v/2u)+0v+0.22m'2.1 -.sp -1 -\h'2.062i'\v'1.250i'\D'l0.000i 0.500i' -.sp -1 -\h'2.087i'\v'1.650i'\D'l-0.025i 0.100i' -.sp -1 -\h'2.062i'\v'1.750i'\D'l-0.025i -0.100i' -.sp -1 -.lf 246 -\h'2.062i-(\w'1.3'u/2u)'\v'2.000i-(1v/2u)+0v+0.22m'1.3 -.sp -1 -\h'2.062i'\v'2.250i'\D'l-0.375i -0.500i' -.sp -1 -\h'1.688i'\v'1.750i'\D'l0.750i 0.000i' -.sp -1 -\h'2.438i'\v'1.750i'\D'l-0.375i 0.500i' -.sp -1 -\h'1.875i'\v'2.000i'\D'~-0.500i 0.000i 0.000i -0.500i' -.sp -1 -\h'1.350i'\v'1.600i'\D'l0.025i -0.100i' -.sp -1 -\h'1.375i'\v'1.500i'\D'l0.025i 0.100i' -.sp -1 -.lf 249 -\h'1.375i-(\w'1.3.1.1'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.3.1.1 -.sp -1 -\h'1.375i'\v'1.000i'\D'l-0.375i 0.500i' -.sp -1 -\h'1.000i'\v'1.500i'\D'l0.750i 0.000i' -.sp -1 -\h'1.750i'\v'1.500i'\D'l-0.375i -0.500i' -.sp -1 -\h'2.062i'\v'2.250i'\D'l0.000i 0.500i' -.sp -1 -\h'2.087i'\v'2.650i'\D'l-0.025i 0.100i' -.sp -1 -\h'2.062i'\v'2.750i'\D'l-0.025i -0.100i' -.sp -1 -.lf 252 -\h'2.062i-(\w'1.2'u/2u)'\v'3.000i-(1v/2u)+0v+0.22m'1.2 -.sp -1 -\h'2.062i'\v'3.250i'\D'l-0.375i -0.500i' -.sp -1 -\h'1.688i'\v'2.750i'\D'l0.750i 0.000i' -.sp -1 -\h'2.438i'\v'2.750i'\D'l-0.375i 0.500i' -.sp -1 -\h'1.875i'\v'3.000i'\D'~-0.500i 0.000i -0.500i 0.000i -0.500i 0.000i 0.000i -0.500i' -.sp -1 -\h'0.350i'\v'2.600i'\D'l0.025i -0.100i' -.sp -1 -\h'0.375i'\v'2.500i'\D'l0.025i 0.100i' -.sp -1 -.lf 255 -\h'0.375i-(\w'1.2.1.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.1.1 -.sp -1 -\h'0.375i'\v'2.000i'\D'l-0.375i 0.500i' -.sp -1 -\h'0.000i'\v'2.500i'\D'l0.750i 0.000i' -.sp -1 -\h'0.750i'\v'2.500i'\D'l-0.375i -0.500i' -.sp -1 -\h'0.375i'\v'2.000i'\D'l0.000i -0.500i' -.sp -1 -\h'0.350i'\v'1.600i'\D'l0.025i -0.100i' -.sp -1 -\h'0.375i'\v'1.500i'\D'l0.025i 0.100i' -.sp -1 -.lf 257 -\h'0.375i-(\w'1.2.1.3'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.1.3 -.sp -1 -\h'0.375i'\v'1.000i'\D'l-0.375i 0.500i' -.sp -1 -\h'0.000i'\v'1.500i'\D'l0.750i 0.000i' -.sp -1 -\h'0.750i'\v'1.500i'\D'l-0.375i -0.500i' -.sp -1 -\h'2.250i'\v'3.000i'\D'~0.500i 0.000i 0.000i -0.500i' -.sp -1 -\h'2.725i'\v'2.600i'\D'l0.025i -0.100i' -.sp -1 -\h'2.750i'\v'2.500i'\D'l0.025i 0.100i' -.sp -1 -.lf 261 -\h'2.750i-(\w'1.2.2.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.2.1 -.sp -1 -\h'2.750i'\v'2.000i'\D'l-0.375i 0.500i' -.sp -1 -\h'2.375i'\v'2.500i'\D'l0.750i 0.000i' -.sp -1 -\h'3.125i'\v'2.500i'\D'l-0.375i -0.500i' -.sp -1 -\h'2.938i'\v'2.250i'\D'~0.500i 0.000i 0.000i -0.500i 0.000i -0.500i' -.sp -1 -\h'3.413i'\v'1.350i'\D'l0.025i -0.100i' -.sp -1 -\h'3.438i'\v'1.250i'\D'l0.025i 0.100i' -.sp -1 -.lf 264 -\h'3.438i-(\w'\s-21.2.2.1.1.1\s0'u/2u)'\v'1.000i-(1v/2u)+1v+0.22m'\s-21.2.2.1.1.1\s0 -.sp -1 -\h'3.438i'\v'0.750i'\D'l-0.375i 0.500i' -.sp -1 -\h'3.062i'\v'1.250i'\D'l0.750i 0.000i' -.sp -1 -\h'3.812i'\v'1.250i'\D'l-0.375i -0.500i' -.sp -1 -\h'2.750i'\v'2.000i'\D'l0.000i -0.500i' -.sp -1 -\h'2.725i'\v'1.600i'\D'l0.025i -0.100i' -.sp -1 -\h'2.750i'\v'1.500i'\D'l0.025i 0.100i' -.sp -1 -.lf 267 -\h'2.750i-(\w'1.2.2.2'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.2.2 -.sp -1 -\h'2.750i'\v'1.000i'\D'l-0.375i 0.500i' -.sp -1 -\h'2.375i'\v'1.500i'\D'l0.750i 0.000i' -.sp -1 -\h'3.125i'\v'1.500i'\D'l-0.375i -0.500i' -.sp -1 -\h'2.062i'\v'3.250i'\D'l0.000i 0.500i' -.sp -1 -\h'2.087i'\v'3.650i'\D'l-0.025i 0.100i' -.sp -1 -\h'2.062i'\v'3.750i'\D'l-0.025i -0.100i' -.sp -1 -.lf 270 -\h'2.062i-(\w'1.1'u/2u)'\v'4.000i-(1v/2u)+0v+0.22m'1.1 -.sp -1 -\h'2.062i'\v'4.250i'\D'l-0.375i -0.500i' -.sp -1 -\h'1.688i'\v'3.750i'\D'l0.750i 0.000i' -.sp -1 -\h'2.438i'\v'3.750i'\D'l-0.375i 0.500i' -.sp -1 -.sp 4.250i+1 -.if \n(00 .fi -.br -.nr 0x 0 -.lf 271 -.PE -.lf 272 -.\} -.SH IDENTIFICATION -.de VL -\\$2 -.. -Author: Walter F. Tichy, -Purdue University, West Lafayette, IN, 47907. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH SEE ALSO -rcsintro(1), ci(1), co(1), ident(1), rcs(1), rcsclean(1), rcsdiff(1), -rcsmerge(1), rlog(1) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. diff --git a/gnu/usr.bin/rcs/rcs/rcsintro.1 b/gnu/usr.bin/rcs/rcs/rcsintro.1 deleted file mode 100644 index edcd9ee9389d..000000000000 --- a/gnu/usr.bin/rcs/rcs/rcsintro.1 +++ /dev/null @@ -1,302 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.if !\n(.g \{\ -. if !\w|\*(lq| \{\ -. ds lq `` -. if \w'\(lq' .ds lq "\(lq -. \} -. if !\w|\*(rq| \{\ -. ds rq '' -. if \w'\(rq' .ds rq "\(rq -. \} -.\} -.am SS -.LP -.. -.TH RCSINTRO 1 \*(Dt GNU -.SH NAME -rcsintro \- introduction to RCS commands -.SH DESCRIPTION -The Revision Control System (\*r) manages multiple revisions of files. -\*r automates the storing, retrieval, logging, identification, and merging -of revisions. \*r is useful for text that is revised frequently, for example -programs, documentation, graphics, papers, and form letters. -.PP -The basic user interface is extremely simple. The novice only needs -to learn two commands: -.BR ci (1) -and -.BR co (1). -.BR ci , -short for \*(lqcheck in\*(rq, deposits the contents of a -file into an archival file called an \*r file. An \*r file -contains all revisions of a particular file. -.BR co , -short for \*(lqcheck out\*(rq, retrieves revisions from an \*r file. -.SS "Functions of \*r" -.IP \(bu -Store and retrieve multiple revisions of text. \*r saves all old -revisions in a space efficient way. -Changes no longer destroy the original, because the -previous revisions remain accessible. Revisions can be retrieved according to -ranges of revision numbers, symbolic names, dates, authors, and -states. -.IP \(bu -Maintain a complete history of changes. -\*r logs all changes automatically. -Besides the text of each revision, \*r stores the author, the date and time of -check-in, and a log message summarizing the change. -The logging makes it easy to find out -what happened to a module, without having to compare -source listings or having to track down colleagues. -.IP \(bu -Resolve access conflicts. When two or more programmers wish to -modify the same revision, \*r alerts the programmers and prevents one -modification from corrupting the other. -.IP \(bu -Maintain a tree of revisions. \*r can maintain separate lines of development -for each module. It stores a tree structure that represents the -ancestral relationships among revisions. -.IP \(bu -Merge revisions and resolve conflicts. -Two separate lines of development of a module can be coalesced by merging. -If the revisions to be merged affect the same sections of code, \*r alerts the -user about the overlapping changes. -.IP \(bu -Control releases and configurations. -Revisions can be assigned symbolic names -and marked as released, stable, experimental, etc. -With these facilities, configurations of modules can be -described simply and directly. -.IP \(bu -Automatically identify each revision with name, revision number, -creation time, author, etc. -The identification is like a stamp that can be embedded at an appropriate place -in the text of a revision. -The identification makes it simple to determine which -revisions of which modules make up a given configuration. -.IP \(bu -Minimize secondary storage. \*r needs little extra space for -the revisions (only the differences). If intermediate revisions are -deleted, the corresponding deltas are compressed accordingly. -.SS "Getting Started with \*r" -Suppose you have a file -.B f.c -that you wish to put under control of \*r. -If you have not already done so, make an \*r directory with the command -.IP -.B "mkdir RCS" -.LP -Then invoke the check-in command -.IP -.B "ci f.c" -.LP -This command creates an \*r file in the -.B RCS -directory, -stores -.B f.c -into it as revision 1.1, and -deletes -.BR f.c . -It also asks you for a description. The description -should be a synopsis of the contents of the file. All later check-in -commands will ask you for a log entry, which should summarize the -changes that you made. -.PP -Files in the \*r directory are called \*r files; -the others are called working files. -To get back the working file -.B f.c -in the previous example, use the check-out -command -.IP -.B "co f.c" -.LP -This command extracts the latest revision from the \*r file -and writes -it into -.BR f.c . -If you want to edit -.BR f.c , -you must lock it as you check it out with the command -.IP -.B "co \-l f.c" -.LP -You can now edit -.BR f.c . -.PP -Suppose after some editing you want to know what changes that you have made. -The command -.IP -.B "rcsdiff f.c" -.LP -tells you the difference between the most recently checked-in version -and the working file. -You can check the file back in by invoking -.IP -.B "ci f.c" -.LP -This increments the revision number properly. -.PP -If -.B ci -complains with the message -.IP -.BI "ci error: no lock set by " "your name" -.LP -then you have tried to check in a file even though you did not -lock it when you checked it out. -Of course, it is too late now to do the check-out with locking, because -another check-out would -overwrite your modifications. Instead, invoke -.IP -.B "rcs \-l f.c" -.LP -This command will lock the latest revision for you, unless somebody -else got ahead of you already. In this case, you'll have to negotiate with -that person. -.PP -Locking assures that you, and only you, can check in the next update, and -avoids nasty problems if several people work on the same file. -Even if a revision is locked, it can still be checked out for -reading, compiling, etc. All that locking -prevents is a -.I "check-in" -by anybody but the locker. -.PP -If your \*r file is private, i.e., if you are the only person who is going -to deposit revisions into it, strict locking is not needed and you -can turn it off. -If strict locking is turned off, -the owner of the \*r file need not have a lock for check-in; all others -still do. Turning strict locking off and on is done with the commands -.IP -.BR "rcs \-U f.c" " and " "rcs \-L f.c" -.LP -If you don't want to clutter your working directory with \*r files, create -a subdirectory called -.B RCS -in your working directory, and move all your \*r -files there. \*r commands will look first into that directory to find -needed files. All the commands discussed above will still work, without any -modification. -(Actually, pairs of \*r and working files can be specified in three ways: -(a) both are given, (b) only the working file is given, (c) only the -\*r file is given. Both \*r and working files may have arbitrary path prefixes; -\*r commands pair them up intelligently.) -.PP -To avoid the deletion of the working file during check-in (in case you want to -continue editing or compiling), invoke -.IP -.BR "ci \-l f.c" " or " "ci \-u f.c" -.LP -These commands check in -.B f.c -as usual, but perform an implicit -check-out. The first form also locks the checked in revision, the second one -doesn't. Thus, these options save you one check-out operation. -The first form is useful if you want to continue editing, -the second one if you just want to read the file. -Both update the identification markers in your working file (see below). -.PP -You can give -.B ci -the number you want assigned to a checked in -revision. Assume all your revisions were numbered 1.1, 1.2, 1.3, etc., -and you would like to start release 2. -The command -.IP -.BR "ci \-r2 f.c" " or " "ci \-r2.1 f.c" -.LP -assigns the number 2.1 to the new revision. -From then on, -.B ci -will number the subsequent revisions -with 2.2, 2.3, etc. The corresponding -.B co -commands -.IP -.BR "co \-r2 f.c" " and " "co \-r2.1 f.c" -.PP -retrieve the latest revision numbered -.RI 2. x -and the revision 2.1, -respectively. -.B co -without a revision number selects -the latest revision on the -.IR trunk , -i.e. the highest -revision with a number consisting of two fields. Numbers with more than two -fields are needed for branches. -For example, to start a branch at revision 1.3, invoke -.IP -.B "ci \-r1.3.1 f.c" -.LP -This command starts a branch numbered 1 at revision 1.3, and assigns -the number 1.3.1.1 to the new revision. For more information about -branches, see -.BR rcsfile (5). -.SS "Automatic Identification" -\*r can put special strings for identification into your source and object -code. To obtain such identification, place the marker -.IP -.B "$\&Id$" -.LP -into your text, for instance inside a comment. -\*r will replace this marker with a string of the form -.IP -.BI $\&Id: " filename revision date time author state " $ -.LP -With such a marker on the first page of each module, you can -always see with which revision you are working. -\*r keeps the markers up to date automatically. -To propagate the markers into your object code, simply put -them into literal character strings. In C, this is done as follows: -.IP -.ft 3 -static char rcsid[] = \&"$\&Id$\&"; -.ft -.LP -The command -.B ident -extracts such markers from any file, even object code -and dumps. -Thus, -.B ident -lets you find out -which revisions of which modules were used in a given program. -.PP -You may also find it useful to put the marker -.B $\&Log$ -into your text, inside a comment. This marker accumulates -the log messages that are requested during check-in. -Thus, you can maintain the complete history of your file directly inside it. -There are several additional identification markers; see -.BR co (1) -for -details. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert. -.SH "SEE ALSO" -ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.br diff --git a/gnu/usr.bin/rcs/rcsclean/Makefile b/gnu/usr.bin/rcs/rcsclean/Makefile deleted file mode 100644 index fe538a0a41f1..000000000000 --- a/gnu/usr.bin/rcs/rcsclean/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= rcsclean -SRCS= rcsclean.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/rcsclean/Makefile.depend b/gnu/usr.bin/rcs/rcsclean/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/rcsclean/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rcsclean/rcsclean.1 b/gnu/usr.bin/rcs/rcsclean/rcsclean.1 deleted file mode 100644 index 3111915455a6..000000000000 --- a/gnu/usr.bin/rcs/rcsclean/rcsclean.1 +++ /dev/null @@ -1,203 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH RCSCLEAN 1 \*(Dt GNU -.SH NAME -rcsclean \- clean up working files -.SH SYNOPSIS -.B rcsclean -.RI [ options "] [ " file " .\|.\|. ]" -.SH DESCRIPTION -.B rcsclean -removes files that are not being worked on. -.B "rcsclean \-u" -also unlocks and removes files that are being worked on -but have not changed. -.PP -For each -.I file -given, -.B rcsclean -compares the working file and a revision in the corresponding -\*r file. If it finds a difference, it does nothing. -Otherwise, it first unlocks the revision if the -.B \-u -option is given, -and then removes the working file -unless the working file is writable and the revision is locked. -It logs its actions by outputting the corresponding -.B "rcs \-u" -and -.B "rm \-f" -commands on the standard output. -.PP -Files are paired as explained in -.BR ci (1). -If no -.I file -is given, all working files in the current directory are cleaned. -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -.PP -The number of the revision to which the working file is compared -may be attached to any of the options -.BR \-n , -.BR \-q , -.BR \-r , -or -.BR \-u . -If no revision number is specified, then if the -.B \-u -option is given and the caller has one revision locked, -.B rcsclean -uses that revision; otherwise -.B rcsclean -uses the latest revision on the default branch, normally the root. -.PP -.B rcsclean -is useful for -.B clean -targets in makefiles. -See also -.BR rcsdiff (1), -which prints out the differences, -and -.BR ci (1), -which -normally reverts to the previous revision -if a file was not changed. -.SH OPTIONS -.TP -.BI \-k subst -Use -.I subst -style keyword substitution when retrieving the revision for comparison. -See -.BR co (1) -for details. -.TP -.BR \-n [\f2rev\fP] -Do not actually remove any files or unlock any revisions. -Using this option will tell you what -.B rcsclean -would do without actually doing it. -.TP -.BR \-q [\f2rev\fP] -Do not log the actions taken on standard output. -.TP -.BR \-r [\f2rev\fP] -This option has no effect other than specifying the revision for comparison. -.TP -.B \-T -Preserve the modification time on the \*r file -even if the \*r file changes because a lock is removed. -This option can suppress extensive recompilation caused by a -.BR make (1) -dependency of some other copy of the working file on the \*r file. -Use this option with care; it can suppress recompilation even when it is needed, -i.e. when the lock removal -would mean a change to keyword strings in the other working file. -.TP -.BR \-u [\f2rev\fP] -Unlock the revision if it is locked and no difference is found. -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.IR n . -See -.BR co (1) -for details. -.TP -.BI \-x "suffixes" -Use -.I suffixes -to characterize \*r files. -See -.BR ci (1) -for details. -.TP -.BI \-z zone -Use -.I zone -as the time zone for keyword substitution; -see -.BR co (1) -for details. -.SH EXAMPLES -.LP -.RS -.ft 3 -rcsclean *.c *.h -.ft -.RE -.LP -removes all working files ending in -.B .c -or -.B .h -that were not changed -since their checkout. -.LP -.RS -.ft 3 -rcsclean -.ft -.RE -.LP -removes all working files in the current directory -that were not changed since their checkout. -.SH FILES -.B rcsclean -accesses files much as -.BR ci (1) -does. -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -A backslash escapes spaces within an option. -The -.B \s-1RCSINIT\s0 -options are prepended to the argument lists of most \*r commands. -Useful -.B \s-1RCSINIT\s0 -options include -.BR \-q , -.BR \-V , -.BR \-x , -and -.BR \-z . -.SH DIAGNOSTICS -The exit status is zero if and only if all operations were successful. -Missing working files and \*r files are silently ignored. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert. -.SH "SEE ALSO" -ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1), -rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.SH BUGS -At least one -.I file -must be given in older Unix versions that -do not provide the needed directory scanning operations. -.br diff --git a/gnu/usr.bin/rcs/rcsclean/rcsclean.c b/gnu/usr.bin/rcs/rcsclean/rcsclean.c deleted file mode 100644 index 32c8e7dfbc63..000000000000 --- a/gnu/usr.bin/rcs/rcsclean/rcsclean.c +++ /dev/null @@ -1,333 +0,0 @@ -/* Clean up working files. */ - -/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -#include "rcsbase.h" - -#if has_dirent - static int get_directory P((char const*,char***)); -#endif - -static int unlock P((struct hshentry *)); -static void cleanup P((void)); - -static RILE *workptr; -static int exitstatus; - -mainProg(rcscleanId, "rcsclean", "$FreeBSD$") -{ - static char const usage[] = - "\nrcsclean: usage: rcsclean -ksubst -{nqru}[rev] -T -Vn -xsuff -zzone file ..."; - - static struct buf revision; - - char *a, **newargv; - char const *rev, *p; - int dounlock, expmode, perform, unlocked, unlockflag, waslocked; - int Ttimeflag; - struct hshentries *deltas; - struct hshentry *delta; - struct stat workstat; - - setrid(); - - expmode = -1; - rev = 0; - suffixes = X_DEFAULT; - perform = true; - unlockflag = false; - Ttimeflag = false; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - for (;;) { - if (--argc < 1) { -# if has_dirent - argc = get_directory(".", &newargv); - argv = newargv; - break; -# else - faterror("no pathnames specified"); -# endif - } - a = *++argv; - if (!*a || *a++ != '-') - break; - switch (*a++) { - case 'k': - if (0 <= expmode) - redefined('k'); - if ((expmode = str2expmode(a)) < 0) - goto unknown; - break; - - case 'n': - perform = false; - goto handle_revision; - - case 'q': - quietflag = true; - /* fall into */ - case 'r': - handle_revision: - if (*a) { - if (rev) - warn("redefinition of revision number"); - rev = a; - } - break; - - case 'T': - if (*a) - goto unknown; - Ttimeflag = true; - break; - - case 'u': - unlockflag = true; - goto handle_revision; - - case 'V': - setRCSversion(*argv); - break; - - case 'x': - suffixes = a; - break; - - case 'z': - zone_set(a); - break; - - default: - unknown: - error("unknown option: %s%s", *argv, usage); - } - } - - dounlock = perform & unlockflag; - - if (nerror) - cleanup(); - else - for (; 0 < argc; cleanup(), ++argv, --argc) { - - ffree(); - - if (!( - 0 < pairnames( - argc, argv, - dounlock ? rcswriteopen : rcsreadopen, - true, true - ) && - (workptr = Iopen(workname, FOPEN_R_WORK, &workstat)) - )) - continue; - - if (same_file(RCSstat, workstat, 0)) { - rcserror("RCS file is the same as working file %s.", - workname - ); - continue; - } - - gettree(); - - p = 0; - if (rev) { - if (!fexpandsym(rev, &revision, workptr)) - continue; - p = revision.string; - } else if (Head) - switch (unlockflag ? findlock(false,&delta) : 0) { - default: - continue; - case 0: - p = Dbranch ? Dbranch : ""; - break; - case 1: - p = delta->num; - break; - } - delta = 0; - deltas = 0; /* Keep lint happy. */ - if (p && !(delta = genrevs(p,(char*)0,(char*)0,(char*)0,&deltas))) - continue; - - waslocked = delta && delta->lockedby; - locker_expansion = unlock(delta); - unlocked = locker_expansion & unlockflag; - if (unlockednum, RCSname); - - if (perform & unlocked) { - if_advise_access(deltas->first != delta, finptr, MADV_SEQUENTIAL); - if (donerewrite(true, - Ttimeflag ? RCSstat.st_mtime : (time_t)-1 - ) != 0) - continue; - } - - if (!quietflag) - aprintf(stdout, "rm -f %s\n", workname); - Izclose(&workptr); - if (perform && un_link(workname) != 0) - eerror(workname); - - } - - tempunlink(); - if (!quietflag) - Ofclose(stdout); - exitmain(exitstatus); -} - - static void -cleanup() -{ - if (nerror) exitstatus = EXIT_FAILURE; - Izclose(&finptr); - Izclose(&workptr); - Ozclose(&fcopy); - ORCSclose(); - dirtempunlink(); -} - -#if RCS_lint -# define exiterr rcscleanExit -#endif - void -exiterr() -{ - ORCSerror(); - dirtempunlink(); - tempunlink(); - _exit(EXIT_FAILURE); -} - - static int -unlock(delta) - struct hshentry *delta; -{ - register struct rcslock **al, *l; - - if (delta && delta->lockedby && strcmp(getcaller(),delta->lockedby)==0) - for (al = &Locks; (l = *al); al = &l->nextlock) - if (l->delta == delta) { - *al = l->nextlock; - delta->lockedby = 0; - return true; - } - return false; -} - -#if has_dirent - static int -get_directory(dirname, aargv) - char const *dirname; - char ***aargv; -/* - * Put a vector of all DIRNAME's directory entries names into *AARGV. - * Ignore names of RCS files. - * Yield the number of entries found. Terminate the vector with 0. - * Allocate the storage for the vector and entry names. - * Do not sort the names. Do not include '.' and '..'. - */ -{ - int i, entries = 0, entries_max = 64; - size_t chars = 0, chars_max = 1024; - size_t *offset = tnalloc(size_t, entries_max); - char *a = tnalloc(char, chars_max), **p; - DIR *d; - struct dirent *e; - - if (!(d = opendir(dirname))) - efaterror(dirname); - while ((errno = 0, e = readdir(d))) { - char const *en = e->d_name; - size_t s = strlen(en) + 1; - if (en[0]=='.' && (!en[1] || (en[1]=='.' && !en[2]))) - continue; - if (rcssuffix(en)) - continue; - while (chars_max < s + chars) - a = trealloc(char, a, chars_max<<=1); - if (entries == entries_max) - offset = trealloc(size_t, offset, entries_max<<=1); - offset[entries++] = chars; - VOID strcpy(a+chars, en); - chars += s; - } -# if void_closedir -# define close_directory(d) (closedir(d), 0) -# else -# define close_directory(d) closedir(d) -# endif - if (errno || close_directory(d) != 0) - efaterror(dirname); - if (chars) - a = trealloc(char, a, chars); - else - tfree(a); - *aargv = p = tnalloc(char*, entries+1); - for (i=0; i diff --git a/gnu/usr.bin/rcs/rcsdiff/Makefile.depend b/gnu/usr.bin/rcs/rcsdiff/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/rcsdiff/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1 b/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1 deleted file mode 100644 index 74117c270e6c..000000000000 --- a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1 +++ /dev/null @@ -1,158 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH RCSDIFF 1 \*(Dt GNU -.SH NAME -rcsdiff \- compare RCS revisions -.SH SYNOPSIS -.B rcsdiff -[ -.BI \-k subst -] [ -.B \-q -] [ -.BI \-r rev1 -[ -.BI \-r rev2 -] ] [ -.B \-T -] [ -.RI "\f3\-V\fP[" n ] -] [ -.BI \-x suffixes -] [ -.BI \-z zone -] [ -.I "diff options" -] -.I "file .\|.\|." -.SH DESCRIPTION -.B rcsdiff -runs -.BR diff (1) -to compare two revisions of each \*r file given. -.PP -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -Names are paired as explained in -.BR ci (1). -.PP -The option -.B \-q -suppresses diagnostic output. -Zero, one, or two revisions may be specified with -.BR \-r . -The option -.BI \-k subst -affects keyword substitution when extracting -revisions, as described in -.BR co (1); -for example, -.B "\-kk\ \-r1.1\ \-r1.2" -ignores differences in keyword values when comparing revisions -.B 1.1 -and -.BR 1.2 . -To avoid excess output from locker name substitution, -.B \-kkvl -is assumed if (1) at most one revision option is given, -(2) no -.B \-k -option is given, (3) -.B \-kkv -is the default keyword substitution, and -(4) the working file's mode would be produced by -.BR "co\ \-l". -See -.BR co (1) -for details -about -.BR \-T , -.BR \-V , -.B \-x -and -.BR \-z . -Otherwise, all options of -.BR diff (1) -that apply to regular files are accepted, with the same meaning as for -.BR diff . -.PP -If both -.I rev1 -and -.I rev2 -are omitted, -.B rcsdiff -compares the latest revision on the -default branch (by default the trunk) -with the contents of the corresponding working file. This is useful -for determining what you changed since the last checkin. -.PP -If -.I rev1 -is given, but -.I rev2 -is omitted, -.B rcsdiff -compares revision -.I rev1 -of the \*r file with -the contents of the corresponding working file. -.PP -If both -.I rev1 -and -.I rev2 -are given, -.B rcsdiff -compares revisions -.I rev1 -and -.I rev2 -of the \*r file. -.PP -Both -.I rev1 -and -.I rev2 -may be given numerically or symbolically. -.SH EXAMPLE -The command -.LP -.B " rcsdiff f.c" -.LP -compares the latest revision on the default branch of the \*r file -to the contents of the working file -.BR f.c . -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -See -.BR ci (1) -for details. -.SH DIAGNOSTICS -Exit status is 0 for no differences during any comparison, -1 for some differences, 2 for trouble. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert. -.SH "SEE ALSO" -ci(1), co(1), diff(1), ident(1), rcs(1), rcsintro(1), rcsmerge(1), rlog(1) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.br diff --git a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c b/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c deleted file mode 100644 index 7d3c0a37f66a..000000000000 --- a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c +++ /dev/null @@ -1,480 +0,0 @@ -/* Compare RCS revisions. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.19 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.18 1995/06/01 16:23:43 eggert - * (main): Pass "--binary" if -kb and if --binary makes a difference. - * Don't treat + options specially. - * - * Revision 5.17 1994/03/17 14:05:48 eggert - * Specify subprocess input via file descriptor, not file name. Remove lint. - * - * Revision 5.16 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. Don't print usage twice. - * - * Revision 5.15 1993/11/03 17:42:27 eggert - * Add -z. Ignore -T. Pass -Vn to `co'. Add Name keyword. - * Put revision numbers in -c output. Improve quality of diagnostics. - * - * Revision 5.14 1992/07/28 16:12:44 eggert - * Add -V. Use co -M for better dates with traditional diff -c. - * - * Revision 5.13 1992/02/17 23:02:23 eggert - * Output more readable context diff headers. - * Suppress needless checkout and comparison of identical revisions. - * - * Revision 5.12 1992/01/24 18:44:19 eggert - * Add GNU diff 1.15.2's new options. lint -> RCS_lint - * - * Revision 5.11 1992/01/06 02:42:34 eggert - * Update usage string. - * - * Revision 5.10 1991/10/07 17:32:46 eggert - * Remove lint. - * - * Revision 5.9 1991/08/19 03:13:55 eggert - * Add RCSINIT, -r$. Tune. - * - * Revision 5.8 1991/04/21 11:58:21 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.7 1990/12/13 06:54:07 eggert - * GNU diff 1.15 has -u. - * - * Revision 5.6 1990/11/01 05:03:39 eggert - * Remove unneeded setid check. - * - * Revision 5.5 1990/10/04 06:30:19 eggert - * Accumulate exit status across files. - * - * Revision 5.4 1990/09/27 01:31:43 eggert - * Yield 1, not EXIT_FAILURE, when diffs are found. - * - * Revision 5.3 1990/09/11 02:41:11 eggert - * Simplify -kkvl test. - * - * Revision 5.2 1990/09/04 17:07:19 eggert - * Diff's argv was too small by 1. - * - * Revision 5.1 1990/08/29 07:13:55 eggert - * Add -kkvl. - * - * Revision 5.0 1990/08/22 08:12:46 eggert - * Add -k, -V. Don't use access(). Add setuid support. - * Remove compile-time limits; use malloc instead. - * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options. - * Add GNU diff's flags. Make lock and temp files faster and safer. - * Ansify and Posixate. - * - * Revision 4.6 89/05/01 15:12:27 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.5 88/08/09 19:12:41 eggert - * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R. - * - * Revision 4.4 87/12/18 11:37:46 narten - * changes Jay Lepreau made in the 4.3 BSD version, to add support for - * "-i", "-w", and "-t" flags and to permit flags to be bundled together, - * merged in. - * - * Revision 4.3 87/10/18 10:31:42 narten - * Updating version numbers. Changes relative to 1.1 actually - * relative to 4.1 - * - * Revision 1.3 87/09/24 13:59:21 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:15 jenkins - * Port to suns - * - * Revision 4.1 83/05/03 22:13:19 wft - * Added default branch, option -q, exit status like diff. - * Added fterror() to replace faterror(). - * - * Revision 3.6 83/01/15 17:52:40 wft - * Expanded mainprogram to handle multiple RCS files. - * - * Revision 3.5 83/01/06 09:33:45 wft - * Fixed passing of -c (context) option to diff. - * - * Revision 3.4 82/12/24 15:28:38 wft - * Added call to catchsig(). - * - * Revision 3.3 82/12/10 16:08:17 wft - * Corrected checking of return code from diff; improved error msgs. - * - * Revision 3.2 82/12/04 13:20:09 wft - * replaced getdelta() with gettree(). Changed diagnostics. - * - * Revision 3.1 82/11/28 19:25:04 wft - * Initial revision. - * - */ -#include "rcsbase.h" - -#if DIFF_L -static char const *setup_label P((struct buf*,char const*,char const[datesize])); -#endif -static void cleanup P((void)); - -static int exitstatus; -static RILE *workptr; -static struct stat workstat; - -mainProg(rcsdiffId, "rcsdiff", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nrcsdiff usage: rcsdiff -ksubst -q -rrev1 [-rrev2] -Vn -xsuff -zzone [diff options] file ..."; - - int revnums; /* counter for revision numbers given */ - char const *rev1, *rev2; /* revision numbers from command line */ - char const *xrev1, *xrev2; /* expanded revision numbers */ - char const *expandarg, *lexpandarg, *suffixarg, *versionarg, *zonearg; -#if DIFF_L - static struct buf labelbuf[2]; - int file_labels; - char const **diff_label1, **diff_label2; - char date2[datesize]; -#endif - char const *cov[10 + !DIFF_L]; - char const **diffv, **diffp, **diffpend; /* argv for subsidiary diff */ - char const **pp, *p, *diffvstr; - struct buf commarg; - struct buf numericrev; /* expanded revision number */ - struct hshentries *gendeltas; /* deltas to be generated */ - struct hshentry * target; - char *a, *dcp, **newargv; - int no_diff_means_no_output; - register c; - - exitstatus = DIFF_SUCCESS; - - bufautobegin(&commarg); - bufautobegin(&numericrev); - revnums = 0; - rev1 = rev2 = xrev2 = 0; -#if DIFF_L - file_labels = 0; -#endif - expandarg = suffixarg = versionarg = zonearg = 0; - no_diff_means_no_output = true; - suffixes = X_DEFAULT; - - /* - * Room for runv extra + args [+ --binary] [+ 2 labels] - * + 1 file + 1 trailing null. - */ - diffv = tnalloc(char const*, 1 + argc + !!OPEN_O_BINARY + 2*DIFF_L + 2); - diffp = diffv + 1; - *diffp++ = DIFF; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - dcp = a; - while ((c = *a++)) switch (c) { - case 'r': - switch (++revnums) { - case 1: rev1=a; break; - case 2: rev2=a; break; - default: error("too many revision numbers"); - } - goto option_handled; - case '-': case 'D': - no_diff_means_no_output = false; - /* fall into */ - case 'C': case 'F': case 'I': case 'L': case 'W': -#if DIFF_L - if (c == 'L' && file_labels++ == 2) - faterror("too many -L options"); -#endif - *dcp++ = c; - if (*a) - do *dcp++ = *a++; - while (*a); - else { - if (!--argc) - faterror("-%c needs following argument%s", - c, cmdusage - ); - *diffp++ = *argv++; - } - break; - case 'y': - no_diff_means_no_output = false; - /* fall into */ - case 'B': case 'H': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - case 'h': case 'i': case 'n': case 'p': - case 't': case 'u': case 'w': - *dcp++ = c; - break; - case 'q': - quietflag=true; - break; - case 'x': - suffixarg = *argv; - suffixes = *argv + 2; - goto option_handled; - case 'z': - zonearg = *argv; - zone_set(*argv + 2); - goto option_handled; - case 'T': - /* Ignore -T, so that RCSINIT can contain -T. */ - if (*a) - goto unknown; - break; - case 'V': - versionarg = *argv; - setRCSversion(versionarg); - goto option_handled; - case 'k': - expandarg = *argv; - if (0 <= str2expmode(expandarg+2)) - goto option_handled; - /* fall into */ - default: - unknown: - error("unknown option: %s%s", *argv, cmdusage); - }; - option_handled: - if (dcp != *argv+1) { - *dcp = 0; - *diffp++ = *argv; - } - } /* end of option processing */ - - for (pp = diffv+2, c = 0; ppnum; - - if (!fexpandsym(rev1, &numericrev, workptr)) continue; - if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue; - xrev1=target->num; -#if DIFF_L - if (diff_label1) - *diff_label1 = setup_label(&labelbuf[0], target->num, target->date); -#endif - - lexpandarg = expandarg; - if (revnums==2) { - if (!fexpandsym( - *rev2 ? rev2 : Dbranch ? Dbranch : Head->num, - &numericrev, - workptr - )) - continue; - if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue; - xrev2=target->num; - if (no_diff_means_no_output && xrev1 == xrev2) - continue; - } else if ( - target->lockedby - && !lexpandarg - && Expand == KEYVAL_EXPAND - && WORKMODE(RCSstat.st_mode,true) == workstat.st_mode - ) - lexpandarg = "-kkvl"; - Izclose(&workptr); -#if DIFF_L - if (diff_label2) - if (revnums == 2) - *diff_label2 = setup_label(&labelbuf[1], target->num, target->date); - else { - time2date(workstat.st_mtime, date2); - *diff_label2 = setup_label(&labelbuf[1], (char*)0, date2); - } -#endif - - diagnose("retrieving revision %s\n", xrev1); - bufscpy(&commarg, "-p"); - bufscat(&commarg, rev1); /* not xrev1, for $Name's sake */ - - pp = &cov[3 + !DIFF_L]; - *pp++ = commarg.string; - if (lexpandarg) *pp++ = lexpandarg; - if (suffixarg) *pp++ = suffixarg; - if (versionarg) *pp++ = versionarg; - if (zonearg) *pp++ = zonearg; - *pp++ = RCSname; - *pp = 0; - - diffp = diffpend; -# if OPEN_O_BINARY - if (Expand == BINARY_EXPAND) - *diffp++ = "--binary"; -# endif - diffp[0] = maketemp(0); - if (runv(-1, diffp[0], cov)) { - rcserror("co failed"); - continue; - } - if (!rev2) { - diffp[1] = workname; - if (*workname == '-') { - char *dp = ftnalloc(char, strlen(workname)+3); - diffp[1] = dp; - *dp++ = '.'; - *dp++ = SLASH; - VOID strcpy(dp, workname); - } - } else { - diagnose("retrieving revision %s\n",xrev2); - bufscpy(&commarg, "-p"); - bufscat(&commarg, rev2); /* not xrev2, for $Name's sake */ - cov[3 + !DIFF_L] = commarg.string; - diffp[1] = maketemp(1); - if (runv(-1, diffp[1], cov)) { - rcserror("co failed"); - continue; - } - } - if (!rev2) - diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workname); - else - diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2); - - diffp[2] = 0; - switch (runv(-1, (char*)0, diffv)) { - case DIFF_SUCCESS: - break; - case DIFF_FAILURE: - if (exitstatus == DIFF_SUCCESS) - exitstatus = DIFF_FAILURE; - break; - default: - workerror("diff failed"); - } - } - - tempunlink(); - exitmain(exitstatus); -} - - static void -cleanup() -{ - if (nerror) exitstatus = DIFF_TROUBLE; - Izclose(&finptr); - Izclose(&workptr); -} - -#if RCS_lint -# define exiterr rdiffExit -#endif - void -exiterr() -{ - tempunlink(); - _exit(DIFF_TROUBLE); -} - -#if DIFF_L - static char const * -setup_label(b, num, date) - struct buf *b; - char const *num; - char const date[datesize]; -{ - char *p; - char datestr[datesize + zonelenmax]; - VOID date2str(date, datestr); - bufalloc(b, - strlen(workname) - + sizeof datestr + 4 - + (num ? strlen(num) : 0) - ); - p = b->string; - if (num) - VOID sprintf(p, "-L%s\t%s\t%s", workname, datestr, num); - else - VOID sprintf(p, "-L%s\t%s", workname, datestr); - return p; -} -#endif diff --git a/gnu/usr.bin/rcs/rcsfreeze/Makefile b/gnu/usr.bin/rcs/rcsfreeze/Makefile deleted file mode 100644 index 1b249c737f17..000000000000 --- a/gnu/usr.bin/rcs/rcsfreeze/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ - -SCRIPTS= rcsfreeze.sh -MAN= rcsfreeze.1 - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend b/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend deleted file mode 100644 index f80275d86ab1..000000000000 --- a/gnu/usr.bin/rcs/rcsfreeze/Makefile.depend +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1 b/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1 deleted file mode 100644 index 3f513c4d65ad..000000000000 --- a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1 +++ /dev/null @@ -1,68 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \s-1RCS\s0 -.TH RCSFREEZE 1 \*(Dt GNU -.SH NAME -rcsfreeze \- freeze a configuration of sources checked in under RCS -.SH SYNOPSIS -.B rcsfreeze -.RI [ "name" ] -.SH DESCRIPTION -.B rcsfreeze -assigns a symbolic revision -number to a set of \*r files that form a valid configuration. -.PP -The idea is to run -.B rcsfreeze -each time a new version is checked -in. A unique symbolic name (\c -.BI C_ number, -where -.I number -is increased each time -.B rcsfreeze -is run) is then assigned to the most -recent revision of each \*r file of the main trunk. -.PP -An optional -.I name -argument to -.B rcsfreeze -gives a symbolic name to the configuration. -The unique identifier is still generated -and is listed in the log file but it will not appear as -part of the symbolic revision name in the actual \*r files. -.PP -A log message is requested from the user for future reference. -.PP -The shell script works only on all \*r files at one time. -All changed files must be checked in already. -Run -.IR rcsclean (1) -first and see whether any sources remain in the current directory. -.SH FILES -.TP -.B RCS/.rcsfreeze.ver -version number -.TP -.B RCS/.rcsfreeze.log -log messages, most recent first -.SH AUTHOR -Stephan v. Bechtolsheim -.SH "SEE ALSO" -co(1), rcs(1), rcsclean(1), rlog(1) -.SH BUGS -.B rcsfreeze -does not check whether any sources are checked out and modified. -.PP -Although both source file names and RCS file names are accepted, -they are not paired as usual with RCS commands. -.PP -Error checking is rudimentary. -.PP -.B rcsfreeze -is just an optional example shell script, and should not be taken too seriously. -See \s-1CVS\s0 for a more complete solution. diff --git a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh b/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh deleted file mode 100644 index be79406fe0c1..000000000000 --- a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh +++ /dev/null @@ -1,99 +0,0 @@ -#! /bin/sh - -# rcsfreeze - assign a symbolic revision number to a configuration of RCS files - -# $FreeBSD$ - -# The idea is to run rcsfreeze each time a new version is checked -# in. A unique symbolic revision number (C_[number], where number -# is increased each time rcsfreeze is run) is then assigned to the most -# recent revision of each RCS file of the main trunk. -# -# If the command is invoked with an argument, then this -# argument is used as the symbolic name to freeze a configuration. -# The unique identifier is still generated -# and is listed in the log file but it will not appear as -# part of the symbolic revision name in the actual RCS file. -# -# A log message is requested from the user which is saved for future -# references. -# -# The shell script works only on all RCS files at one time. -# It is important that all changed files are checked in (there are -# no precautions against any error in this respect). -# file names: -# {RCS/}.rcsfreeze.ver version number -# {RCS/}.rscfreeze.log log messages, most recent first - -PATH=/bin:/usr/bin:$PATH -export PATH - -DATE=`LC_ALL=C date` || exit -# Check whether we have an RCS subdirectory, so we can have the right -# prefix for our paths. -if test -d RCS -then RCSDIR=RCS/ EXT= -else RCSDIR= EXT=,v -fi - -# Version number stuff, log message file -VERSIONFILE=${RCSDIR}.rcsfreeze.ver -LOGFILE=${RCSDIR}.rcsfreeze.log -# Initialize, rcsfreeze never run before in the current directory -test -r $VERSIONFILE || { echo 0 >$VERSIONFILE && >>$LOGFILE; } || exit - -# Get Version number, increase it, write back to file. -VERSIONNUMBER=`cat $VERSIONFILE` && -VERSIONNUMBER=`expr $VERSIONNUMBER + 1` && -echo $VERSIONNUMBER >$VERSIONFILE || exit - -# Symbolic Revision Number -SYMREV=C_$VERSIONNUMBER -# Allow the user to give a meaningful symbolic name to the revision. -SYMREVNAME=${1-$SYMREV} -echo >&2 "rcsfreeze: symbolic revision number computed: \"${SYMREV}\" -rcsfreeze: symbolic revision number used: \"${SYMREVNAME}\" -rcsfreeze: the two differ only when rcsfreeze invoked with argument -rcsfreeze: give log message, summarizing changes (end with EOF or single '.')" \ - || exit - -# Stamp the logfile. Because we order the logfile the most recent -# first we will have to save everything right now in a temporary file. -TMPLOG=/tmp/rcsfrz$$ -trap 'rm -f $TMPLOG; exit 1' 1 2 13 15 -# Now ask for a log message, continously add to the log file -( - echo "Version: $SYMREVNAME($SYMREV), Date: $DATE ------------" || exit - while read MESS - do - case $MESS in - .) break - esac - echo " $MESS" || exit - done - echo "----------- -" && - cat $LOGFILE -) >$TMPLOG && - -# combine old and new logfiles -cp $TMPLOG $LOGFILE && -rm -f $TMPLOG && - -# Now the real work begins by assigning a symbolic revision number -# to each rcs file. Take the most recent version on the default branch. - -# If there are any .*,v files, throw them in too. -# But ignore RCS/.* files that do not end in ,v. -DOTFILES= -for DOTFILE in ${RCSDIR}.*,v -do - if test -f "$DOTFILE" - then - DOTFILES="${RCSDIR}.*,v" - break - fi -done - -exec rcs -q -n$SYMREVNAME: ${RCSDIR}*$EXT $DOTFILES diff --git a/gnu/usr.bin/rcs/rcsmerge/Makefile b/gnu/usr.bin/rcs/rcsmerge/Makefile deleted file mode 100644 index 9fd8afaab020..000000000000 --- a/gnu/usr.bin/rcs/rcsmerge/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PROG= rcsmerge -SRCS= rcsmerge.c -CFLAGS+= -I${.CURDIR}/../lib -LDADD= ${LIBRCS} -DPADD= ${LIBRCS} - -.include "../../Makefile.inc" -.include diff --git a/gnu/usr.bin/rcs/rcsmerge/Makefile.depend b/gnu/usr.bin/rcs/rcsmerge/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/rcsmerge/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1 b/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1 deleted file mode 100644 index aff6f666dabb..000000000000 --- a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1 +++ /dev/null @@ -1,189 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds r \&\s-1RCS\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH RCSMERGE 1 \*(Dt GNU -.SH NAME -rcsmerge \- merge RCS revisions -.SH SYNOPSIS -.B rcsmerge -.RI [ options ] " file" -.SH DESCRIPTION -.B rcsmerge -incorporates the changes between two revisions -of an \*r file into the corresponding working file. -.PP -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -Names are paired as explained in -.BR ci (1). -.PP -At least one revision must be specified with one of the options -described below, usually -.BR \-r . -At most two revisions may be specified. -If only one revision is specified, the latest -revision on the default branch (normally the highest branch on the trunk) -is assumed for the second revision. -Revisions may be specified numerically or symbolically. -.PP -.B rcsmerge -prints a warning if there are overlaps, and delimits -the overlapping regions as explained in -.BR merge (1). -The command is useful for incorporating changes into a checked-out revision. -.SH OPTIONS -.TP -.B \-A -Output conflicts using the -.B \-A -style of -.BR diff3 (1), -if supported by -.BR diff3 . -This merges all changes leading from -.I file2 -to -.I file3 -into -.IR file1 , -and generates the most verbose output. -.TP -\f3\-E\fP, \f3\-e\fP -These options specify conflict styles that generate less information -than -.BR \-A . -See -.BR diff3 (1) -for details. -The default is -.BR \-E . -With -.BR \-e , -.B rcsmerge -does not warn about conflicts. -.TP -.BI \-k subst -Use -.I subst -style keyword substitution. -See -.BR co (1) -for details. -For example, -.B "\-kk\ \-r1.1\ \-r1.2" -ignores differences in keyword values when merging the changes from -.B 1.1 -to -.BR 1.2 . -It normally does not make sense to merge binary files as if they were text, so -.B rcsmerge -refuses to merge files if -.B \-kb -expansion is used. -.TP -.BR \-p [\f2rev\fP] -Send the result to standard output instead of overwriting the working file. -.TP -.BR \-q [\f2rev\fP] -Run quietly; do not print diagnostics. -.TP -.BR \-r [\f2rev\fP] -Merge with respect to revision -.IR rev . -Here an empty -.I rev -stands for the latest revision on the default branch, normally the head. -.TP -.B \-T -This option has no effect; -it is present for compatibility with other \*r commands. -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.IR n . -See -.BR co (1) -for details. -.TP -.BI \-x "suffixes" -Use -.I suffixes -to characterize \*r files. -See -.BR ci (1) -for details. -.TP -.BI \-z zone -Use -.I zone -as the time zone for keyword substitution. -See -.BR co (1) -for details. -.SH EXAMPLES -Suppose you have released revision 2.8 of -.BR f.c . -Assume -furthermore that after you complete an unreleased revision 3.4, you receive -updates to release 2.8 from someone else. -To combine the updates to 2.8 and your changes between 2.8 and 3.4, -put the updates to 2.8 into file f.c and execute -.LP -.B " rcsmerge \-p \-r2.8 \-r3.4 f.c >f.merged.c" -.PP -Then examine -.BR f.merged.c . -Alternatively, if you want to save the updates to 2.8 in the \*r file, -check them in as revision 2.8.1.1 and execute -.BR "co \-j": -.LP -.B " ci \-r2.8.1.1 f.c" -.br -.B " co \-r3.4 \-j2.8:2.8.1.1 f.c" -.PP -As another example, the following command undoes the changes -between revision 2.4 and 2.8 in your currently checked out revision -in -.BR f.c . -.LP -.B " rcsmerge \-r2.8 \-r2.4 f.c" -.PP -Note the order of the arguments, and that -.B f.c -will be -overwritten. -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -See -.BR ci (1) -for details. -.SH DIAGNOSTICS -Exit status is 0 for no overlaps, 1 for some overlaps, 2 for trouble. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH "SEE ALSO" -ci(1), co(1), ident(1), merge(1), rcs(1), rcsdiff(1), rcsintro(1), rlog(1), -rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.br diff --git a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c b/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c deleted file mode 100644 index e09dc2469867..000000000000 --- a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c +++ /dev/null @@ -1,286 +0,0 @@ -/* Merge RCS revisions. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.15 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.14 1995/06/01 16:23:43 eggert - * (main): Report an error if -kb, so don't worry about binary stdout. - * Punctuate messages properly. Rewrite to avoid `goto end'. - * - * Revision 5.13 1994/03/17 14:05:48 eggert - * Specify subprocess input via file descriptor, not file name. Remove lint. - * - * Revision 5.12 1993/11/09 17:40:15 eggert - * -V now prints version on stdout and exits. Don't print usage twice. - * - * Revision 5.11 1993/11/03 17:42:27 eggert - * Add -A, -E, -e, -z. Ignore -T. Allow up to three file labels. - * Pass -Vn to `co'. Pass unexpanded revision name to `co', so that Name works. - * - * Revision 5.10 1992/07/28 16:12:44 eggert - * Add -V. - * - * Revision 5.9 1992/01/24 18:44:19 eggert - * lint -> RCS_lint - * - * Revision 5.8 1992/01/06 02:42:34 eggert - * Update usage string. - * - * Revision 5.7 1991/11/20 17:58:09 eggert - * Don't Iopen(f, "r+"); it's not portable. - * - * Revision 5.6 1991/08/19 03:13:55 eggert - * Add -r$. Tune. - * - * Revision 5.5 1991/04/21 11:58:27 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.4 1991/02/25 07:12:43 eggert - * Merging a revision to itself is no longer an error. - * - * Revision 5.3 1990/11/01 05:03:50 eggert - * Remove unneeded setid check. - * - * Revision 5.2 1990/09/04 08:02:28 eggert - * Check for I/O error when reading working file. - * - * Revision 5.1 1990/08/29 07:14:04 eggert - * Add -q. Pass -L options to merge. - * - * Revision 5.0 1990/08/22 08:13:41 eggert - * Propagate merge's exit status. - * Remove compile-time limits; use malloc instead. - * Make lock and temp files faster and safer. Ansify and Posixate. Add -V. - * Don't use access(). Tune. - * - * Revision 4.5 89/05/01 15:13:16 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.4 88/08/09 19:13:13 eggert - * Beware merging into a readonly file. - * Beware merging a revision to itself (no change). - * Use execv(), not system(); yield exit status like diff(1)'s. - * - * Revision 4.3 87/10/18 10:38:02 narten - * Updating version numbers. Changes relative to version 1.1 - * actually relative to 4.1 - * - * Revision 1.3 87/09/24 14:00:31 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:36 jenkins - * Port to suns - * - * Revision 4.1 83/03/28 11:14:57 wft - * Added handling of default branch. - * - * Revision 3.3 82/12/24 15:29:00 wft - * Added call to catchsig(). - * - * Revision 3.2 82/12/10 21:32:02 wft - * Replaced getdelta() with gettree(); improved error messages. - * - * Revision 3.1 82/11/28 19:27:44 wft - * Initial revision. - * - */ -#include "rcsbase.h" - -static char const co[] = CO; - -mainProg(rcsmergeId, "rcsmerge", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nrcsmerge usage: rcsmerge -rrev1 [-rrev2] -ksubst -{pq}[rev] -Vn -xsuff -zzone file"; - static char const quietarg[] = "-q"; - - register int i; - char *a, **newargv; - char const *arg[3]; - char const *rev[3], *xrev[3]; /*revision numbers*/ - char const *edarg, *expandarg, *suffixarg, *versionarg, *zonearg; - int tostdout; - int status; - RILE *workptr; - struct buf commarg; - struct buf numericrev; /* holds expanded revision number */ - struct hshentries *gendeltas; /* deltas to be generated */ - struct hshentry * target; - - bufautobegin(&commarg); - bufautobegin(&numericrev); - edarg = rev[1] = rev[2] = 0; - status = 0; /* Keep lint happy. */ - tostdout = false; - expandarg = suffixarg = versionarg = zonearg = quietarg; /* no-op */ - suffixes = X_DEFAULT; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - switch (*a++) { - case 'p': - tostdout=true; - goto revno; - - case 'q': - quietflag = true; - revno: - if (!*a) - break; - /* falls into -r */ - case 'r': - if (!rev[1]) - rev[1] = a; - else if (!rev[2]) - rev[2] = a; - else - error("too many revision numbers"); - break; - - case 'A': case 'E': case 'e': - if (*a) - goto unknown; - edarg = *argv; - break; - - case 'x': - suffixarg = *argv; - suffixes = a; - break; - case 'z': - zonearg = *argv; - zone_set(a); - break; - case 'T': - /* Ignore -T, so that RCSINIT can contain -T. */ - if (*a) - goto unknown; - break; - case 'V': - versionarg = *argv; - setRCSversion(versionarg); - break; - - case 'k': - expandarg = *argv; - if (0 <= str2expmode(expandarg+2)) - break; - /* fall into */ - default: - unknown: - error("unknown option: %s%s", *argv, cmdusage); - }; - } /* end of option processing */ - - if (!rev[1]) faterror("no base revision number given"); - - /* Now handle all pathnames. */ - - if (!nerror) { - if (argc < 1) - faterror("no input file%s", cmdusage); - if (0 < pairnames(argc, argv, rcsreadopen, true, false)) { - - if (argc>2 || (argc==2 && argv[1])) - warn("excess arguments ignored"); - if (Expand == BINARY_EXPAND) - workerror("merging binary files"); - diagnose("RCS file: %s\n", RCSname); - if (!(workptr = Iopen(workname, FOPEN_R_WORK, (struct stat*)0))) - efaterror(workname); - - gettree(); /* reads in the delta tree */ - - if (!Head) rcsfaterror("no revisions present"); - - if (!*rev[1]) - rev[1] = Dbranch ? Dbranch : Head->num; - if (fexpandsym(rev[1], &numericrev, workptr) - && (target=genrevs(numericrev.string, (char *)0, (char *)0, (char*)0, &gendeltas)) - ) { - xrev[1] = target->num; - if (!rev[2] || !*rev[2]) - rev[2] = Dbranch ? Dbranch : Head->num; - if (fexpandsym(rev[2], &numericrev, workptr) - && (target=genrevs(numericrev.string, (char *)0, (char *)0, (char *)0, &gendeltas)) - ) { - xrev[2] = target->num; - - if (strcmp(xrev[1],xrev[2]) == 0) { - if (tostdout) { - fastcopy(workptr, stdout); - Ofclose(stdout); - } - } else { - Izclose(&workptr); - - for (i=1; i<=2; i++) { - diagnose("retrieving revision %s\n", xrev[i]); - bufscpy(&commarg, "-p"); - bufscat(&commarg, rev[i]); /* not xrev[i], for $Name's sake */ - if (run( - -1, - /* Do not collide with merger.c maketemp(). */ - arg[i] = maketemp(i+2), - co, quietarg, commarg.string, - expandarg, suffixarg, versionarg, zonearg, - RCSname, (char*)0 - )) - rcsfaterror("co failed"); - } - diagnose("Merging differences between %s and %s into %s%s\n", - xrev[1], xrev[2], workname, - tostdout?"; result to stdout":""); - - arg[0] = xrev[0] = workname; - status = merge(tostdout, edarg, xrev, arg); - } - } - } - - Izclose(&workptr); - } - } - tempunlink(); - exitmain(nerror ? DIFF_TROUBLE : status); -} - -#if RCS_lint -# define exiterr rmergeExit -#endif - void -exiterr() -{ - tempunlink(); - _exit(DIFF_TROUBLE); -} diff --git a/gnu/usr.bin/rcs/rcstest b/gnu/usr.bin/rcs/rcstest deleted file mode 100755 index 75165f1bbd59..000000000000 --- a/gnu/usr.bin/rcs/rcstest +++ /dev/null @@ -1,454 +0,0 @@ -#! /bin/sh - -# Test RCS's functions. -# The RCS commands are searched for in the PATH as usual; -# to test the working directory's commands, prepend . to your PATH. - -# Test RCS by creating files RCS/a.* and RCS/a.c. -# If all goes well, output nothing, and remove the temporary files. -# Otherwise, send a message to standard output. -# Exit status is 0 if OK, 1 if an RCS bug is found, and 2 if scaffolding fails. -# With the -v option, output more debugging info. - -# If diff outputs `No differences encountered' when comparing identical files, -# then rcstest may also output these noise lines; ignore them. - -# The current directory and ./RCS must be readable, writable, and searchable. - -# $FreeBSD$ - - -# Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert -# Distributed under license by the Free Software Foundation, Inc. -# -# This file is part of RCS. -# -# RCS is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# RCS is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with RCS; see the file COPYING. -# If not, write to the Free Software Foundation, -# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# Report problems and direct all questions to: -# -# rcs-bugs@cs.purdue.edu - -# The Makefile overrides the following defaults. -: ${ALL_CFLAGS=-Dhas_conf_h} -: ${CC=cc} -: ${DIFF=diff} -# : ${LDFLAGS=} ${LIBS=} tickles old shell bug - -CL="$CC $ALL_CFLAGS $LDFLAGS -o a.out" -L=$LIBS - -RCSINIT=-x -export RCSINIT - -SLASH=/ -RCSfile=RCS${SLASH}a.c -RCS_alt=RCS${SLASH}a.d -lockfile=RCS${SLASH}a._ - -case $1 in --v) q=; set -x;; -'') q=-q;; -*) echo >&2 "$0: usage: $0 [-v]"; exit 2 -esac - -if test -d RCS -then rmdir=: -else rmdir=rmdir; mkdir RCS || exit -fi - -rm -f a.* $RCSfile $RCS_alt $lockfile && -echo 1.1 >a.11 && -echo 1.1.1.1 >a.3x1 && -echo 1.2 >a.12 || { echo "#initialization failed"; exit 2; } - -case "`$DIFF -c a.11 a.3x1`" in -*!\ 1.1.1.1) - diff="$DIFF -c";; -*) - echo "#warning: $DIFF -c does not work, so diagnostics may be cryptic" - diff=$DIFF -esac - -rcs -i -L -ta.11 $q a.c && -test -r $RCSfile || { - echo "#rcs -i -L failed; perhaps RCS is not properly installed." - exit 1 -} - -rlog a.c >/dev/null || { echo "#rlog failed on empty RCS file"; exit 1; } -rm -f $RCSfile || exit 2 - -cp a.11 a.c && -ci -ta.11 -mm $q a.c && -test -r $RCSfile && -rcs -L $q a.c || { echo "#ci+rcs -L failed"; exit 1; } -test ! -f a.c || { echo "#ci did not remove working file"; exit 1; } -for l in '' '-l' -do - co $l $q a.c && - test -f a.c || { echo '#co' $l did not create working file; exit 1; } - $diff a.11 a.c || { echo '#ci' followed by co $l is not a no-op; exit 1; } -done - -cp a.12 a.c && -ci -mm $q a.c && -co $q a.c && -$diff a.12 a.c || { echo "#ci+co failed"; exit 1; } - -rm -f a.c && -co -r1.1 $q a.c && -$diff a.11 a.c || { echo "#can't retrieve first revision"; exit 1; } - -rm -f a.c && -cp a.3x1 a.c && -ci -r1.1.1 -mm $q a.c && -co -r1.1.1.1 $q a.c && -$diff a.3x1 a.c || { echo "#branches failed"; exit 1; } - -rm -f a.c && -co -l $q a.c && -ci -f -mm $q a.c && -co -r1.3 $q a.c && -$diff a.12 a.c || { echo "#(co -l; ci -f) failed"; exit 1; } - -rm -f a.c && -co -l $q a.c && -echo 1.4 >a.c && -ci -l -mm $q a.c && -echo error >a.c && -ci -mm $q a.c || { echo "#ci -l failed"; exit 1; } - -rm -f a.c && -co -l $q a.c && -echo 1.5 >a.c && -ci -u -mm $q a.c && -test -r a.c || { echo "#ci -u didn't create a working file"; exit 1; } -rm -f a.c && -echo error >a.c || exit 2 -ci -mm $q a.c 2>/dev/null && { echo "#ci -u didn't unlock the file"; exit 1; } - -rm -f a.c && -rcs -l $q a.c && -co -u $q a.c || { echo "#rcs -l + co -u failed"; exit 1; } -rm -f a.c && -echo error >a.c || exit 2 -ci -mm $q a.c 2>/dev/null && { echo "#co -u didn't unlock the file"; exit 1; } - -rm -f a.c && -cp a.11 a.c && -co -f $q a.c || { echo "#co -f failed"; exit 1; } -$diff a.11 a.c >/dev/null && { echo "#co -f had no effect"; exit 1; } - -co -p1.1 $q a.c >a.t && -$diff a.11 a.t || { echo "#co -p failed"; exit 1; } - -for n in n N -do - rm -f a.c && - co -l $q a.c && - echo $n >a.$n && - cp a.$n a.c && - ci -${n}n -mm $q a.c && - co -rn $q a.c && - $diff a.$n a.c || { echo "#ci -$n failed"; exit 1; } -done - -case $LOGNAME in -?*) me=$LOGNAME;; -*) - case $USER in - ?*) me=$USER;; - *) - me=`who am i` || exit 2 - me=`echo "$me" | sed -e 's/ .*//' -e 's/.*!//'` - case $me in - '') echo >&2 "$0: cannot deduce user name"; exit 2 - esac - esac -esac - - -# Get the date of the previous revision in UTC. -date=`rlog -r a.c | sed -n '/^date: /{ s///; s/;.*//; p; q; }'` || exit -case $date in -[0-9][0-9][0-9]*[0-9]/[0-1][0-9]/[0-3][0-9]\ [0-2][0-9]:[0-5][0-9]:[0-6][0-9]);; -*) echo >&2 "$0: $date: bad rlog date output"; exit 1 -esac -PWD=`pwd` && export PWD && -rm -f a.c && -co -l $q a.c && -sed 's/@/$/g' >a.kv <a.k && -sed -e 's/w s [$]/w s '"$me"' $/' -e 's/[$]Locker: /&'"$me/" a.kv >a.kvl && -sed s/Oz//g a.kv >a.e && -sed s/Oz/N/g a.kv >a.N && -sed -e '/\$/!d' -e 's/\$$/: old $/' a.k >a.o && -sed -e 's/\$[^ ]*: //' -e 's/ \$//' a.kv >a.v && -cp a.o a.c && -ci -d"$date" -nOz -ss -ww -u2.1 -mm $q a.c && -$diff a.kv a.c || { echo "#keyword expansion failed"; exit 1; } -co -pOz -ko $q a.c >a.oo && -$diff a.o a.oo || { echo "#co -p -ko failed"; exit 1; } -cp a.kv a.o && cp a.o a.b || exit 2 -rcs -oOz $q a.c && -rcs -l $q a.c && -ci -k -u $q a.c && -$diff a.kv a.c || { echo "#ci -k failed"; exit 1; } -sed -n 's/^[^$]*\$/$/p' a.kv >a.i && -ident a.c >a.i1 && -sed -e 1d -e 's/^[ ]*//' a.i1 >a.i2 && -$diff a.i a.i2 || { echo "#ident failed"; exit 1; } - -rcs -i $q a.c 2>/dev/null && { echo "#rcs -i permitted existing file"; exit 1; } - -rm -f a.c && -co -l $q a.c && -echo 2.2 >a.c && -ci -mm $q a.c && -echo 1.1.1.2 >a.c && -rcs -l1.1.1 $q a.c && -ci -r1.1.1.2 -mm $q a.c && -rcs -b1.1.1 $q a.c && -test " `co -p $q a.c`" = ' 1.1.1.2' || { echo "#rcs -b1.1.1 failed"; exit 1; } -rcs -b $q a.c && -test " `co -p $q a.c`" = ' 2.2' || { echo "#rcs -b failed"; exit 1; } - -echo 2.3 >a.c || exit 2 -rcs -U $q a.c || { echo "#rcs -U failed"; exit 1; } -ci -mm $q a.c || { echo "#rcs -U didn't unset strict locking"; exit 1; } -rcs -L $q a.c || { echo "#rcs -L failed"; exit 1; } -echo error >a.c || exit 2 -ci -mm $q a.c 2>/dev/null && { echo "#ci retest failed"; exit 1; } - -rm -f a.c && -log0=`rlog -h a.c` && -co -l $q a.c && -ci -mm $q a.c && -log1=`rlog -h a.c` && -test " $log0" = " $log1" || { echo "#unchanged ci didn't revert"; exit 1; } - -rm -f a.c && -rcs -nN:1.1 $q a.c && -co -rN $q a.c && -$diff a.11 a.c || { echo "#rcs -n failed"; exit 1; } - -rm -f a.c && -rcs -NN:2.1 $q a.c && -co -rN $q a.c && -$diff a.N a.c || { echo "#rcs -N failed"; exit 1; } - -rm -f a.c && -co -l $q a.c && -echo ':::$''Log$' >a.c && -ci -u -mm $q a.c && -test " `sed '$!d' a.c`" = ' :::' || { echo "#comment leader failed"; exit 1; } - -rm -f a.c && -rcs -o2.2: $q a.c && -co $q a.c && -$diff a.e a.c || { echo "#rcs -o failed"; exit 1; } - -rcsdiff -r1.1 -rOz $q a.c >a.0 -case $? in -1) ;; -*) echo "#rcsdiff bad status"; exit 1 -esac -$DIFF a.11 a.kv >a.1 -$diff a.0 a.1 || { echo "#rcsdiff failed"; exit 1; } - -rcs -l2.1 $q a.c || { echo "#rcs -l2.1 failed"; exit 1; } -for i in b k kv kvl o v -do - rm -f a.c && - cp a.$i a.c && - rcsdiff -k$i -rOz $q a.c || { echo "#rcsdiff -k$i failed"; exit 1; } -done -co -p1.1 -ko $q a.c >a.t && -$diff a.11 a.t || { echo "#co -p1.1 -ko failed"; exit 1; } -rcs -u2.1 $q a.c || { echo "#rcs -u2.1 failed"; exit 1; } - -rm -f a.c && -rcsclean $q a.c && -rcsclean -u $q a.c || { echo "#rcsclean botched a nonexistent file"; exit 1; } - -rm -f a.c && -co $q a.c && -rcsclean -n $q a.c && -rcsclean -n -u $q a.c && -test -f a.c || { echo "#rcsclean -n removed a file"; exit 1; } - -rm -f a.c && -co $q a.c && -rcsclean $q a.c && -test ! -f a.c || { echo "#rcsclean missed an unlocked file"; exit 1; } - -rm -f a.c && -co -l $q a.c && -rcsclean $q a.c && -test -f a.c || { echo "#rcsclean removed a locked file"; exit 1; } -rcsclean -u $q a.c && -test ! -f a.c || { - echo "#rcsclean -u missed an unchanged locked file"; exit 1; -} - -rm -f a.c && -co -l $q a.c && -echo change >>a.c && -rcsclean $q a.c && -rcsclean $q -u a.c && -test -f a.c || { echo "#rcsclean removed a changed file"; exit 1; } - -rm -f a.c && -co -l $q a.c && -cat >a.c <<'EOF' -2.2 -a -b -c -d -EOF -test $? = 0 && -ci -l -mm $q a.c && -co -p2.2 $q a.c | sed -e s/2.2/2.3/ -e s/b/b1/ >a.c && -ci -l -mm $q a.c && -co -p2.2 $q a.c | sed -e s/2.2/new/ -e s/d/d1/ >a.c || exit 2 -cat >a.0 <<'EOF' -2.3 -a -b1 -c -d1 -EOF -cat >a.1 <<'EOF' -<<<<<<< a.c -new -======= -2.3 ->>>>>>> 2.3 -a -b1 -c -d1 -EOF -rcsmerge -E -r2.2 -r2.3 $q a.c -case $? in -0) - if $diff a.0 a.c >/dev/null - then echo "#warning: diff3 -E does not work, " \ - "so merge and rcsmerge ignore overlaps and suppress overlap lines." - else - $diff a.1 a.c || { echo "#rcsmerge failed (status 0)"; exit 1; } - echo "#warning: The diff3 lib program exit status ignores overlaps," \ - "so rcsmerge does not warn about overlap lines that it generates." - fi - ;; -1) - $diff a.1 a.c || { echo "#rcsmerge failed (status 1)"; exit 1; } - ;; -*) - echo "#rcsmerge bad status"; exit 1 -esac - -# Avoid `tr' if possible; it's not portable, and it can't handle null bytes. -# Our substitute exclusive-ORs with '\n'; -# this ensures null bytes on output, which is even better than `tr', -# since some diffs think a file is binary only if it contains null bytes. -cat >a.c <<'EOF' -#include -int main() { - int c; - while ((c=getchar()) != EOF) - putchar(c ^ '\n'); - return 0; -} -EOF -tr=tr -if (rm -f a.exe a.out && $CL a.c $L >&2) >/dev/null 2>&1 -then - if test -s a.out - then tr=./a.out - elif test -s a.exe - then tr=./a.exe - fi -fi -{ - co -p $q a.c | $tr '\012' '\200' >a.24 && - cp a.24 a.c && - ciOut=`(ci -l -mm $q a.c 2>&1)` && - case $ciOut in - ?*) echo >&2 "$ciOut" - esac && - co -p $q a.c | $tr '\200' '\012' >a.c && - rcsdiff -r2.3 $q a.c >/dev/null && - - echo 2.5 >a.c && - ci -l -mm $q a.c && - cp a.24 a.c && - rcsdiff -r2.4 $q a.c >/dev/null -} || echo "#warning: Traditional diff is used, so RCS is limited to text files." - -rcs -u -o2.4: $q a.c || { echo "#rcs -u -o failed"; exit 1; } - -rcs -i -Aa.c -t- $q a.d || { echo "#rcs -i -A failed"; exit 1; } - -rlog -r2.1 a.c >a.t && -grep '^checked in with -k' a.t >/dev/null && -sed '/^checked in with -k/d' a.t >a.u && -$diff - a.u < diff --git a/gnu/usr.bin/rcs/rlog/Makefile.depend b/gnu/usr.bin/rcs/rlog/Makefile.depend deleted file mode 100644 index cab8f8fe15db..000000000000 --- a/gnu/usr.bin/rcs/rlog/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - gnu/usr.bin/rcs/lib \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/gnu/usr.bin/rcs/rlog/rlog.1 b/gnu/usr.bin/rcs/rlog/rlog.1 deleted file mode 100644 index 26bf08a2bcb0..000000000000 --- a/gnu/usr.bin/rcs/rlog/rlog.1 +++ /dev/null @@ -1,318 +0,0 @@ -.de Id -.ds Rv \\$3 -.ds Dt \\$4 -.. -.Id $FreeBSD$ -.ds i \&\s-1ISO\s0 -.ds r \&\s-1RCS\s0 -.ds u \&\s-1UTC\s0 -.if n .ds - \%-- -.if t .ds - \(em -.TH RLOG 1 \*(Dt GNU -.SH NAME -rlog \- print log messages and other information about RCS files -.SH SYNOPSIS -.B rlog -.RI [ " options " ] " file " .\|.\|. -.SH DESCRIPTION -.B rlog -prints information about \*r files. -.PP -Pathnames matching an \*r suffix denote \*r files; -all others denote working files. -Names are paired as explained in -.BR ci (1). -.PP -.B rlog -prints the following information for each -\*r file: \*r pathname, working pathname, head (i.e., the number -of the latest revision on the trunk), default branch, access list, locks, -symbolic names, suffix, total number of revisions, -number of revisions selected for printing, and -descriptive text. This is followed by entries for the selected revisions in -reverse chronological order for each branch. For each revision, -.B rlog -prints revision number, author, date/time, state, number of -lines added/deleted (with respect to the previous revision), -locker of the revision (if any), and log message. -All times are displayed in Coordinated Universal Time (\*u) by default; -this can be overridden with -.BR \-z . -Without options, -.B rlog -prints complete information. -The options below restrict this output. -.nr n \w'\f3\-V\fP\f2n\fP'+2n-1/1n -.ds n \nn -.if \n(.g .if r an-tag-sep .ds n \w'\f3\-V\fP\f2n\fP'u+\n[an-tag-sep]u -.TP \*n -.B \-L -Ignore \*r files that have no locks set. -This is convenient in combination with -.BR \-h , -.BR \-l , -and -.BR \-R . -.TP -.B \-R -Print only the name of the \*r file. -This is convenient for translating a -working pathname into an \*r pathname. -.TP -.BI \-v "[string]" -Print only the working pathname and tip-revision. -The optional string is prepended to the outputline. -.TP -.B \-h -Print only the \*r pathname, working pathname, head, -default branch, access list, locks, -symbolic names, and suffix. -.TP -.B \-t -Print the same as -.BR \-h , -plus the descriptive text. -.TP -.B \-N -Do not print the symbolic names. -.TP -.B \-b -Print information about the revisions on the default branch, normally -the highest branch on the trunk. -.TP -.BI \-d "dates" -Print information about revisions with a checkin date/time in the ranges given by -the semicolon-separated list of -.IR dates . -A range of the form -.IB d1 < d2 -or -.IB d2 > d1 -selects the revisions that were deposited between -.I d1 -and -.I d2 -exclusive. -A range of the form -.BI < d -or -.IB d > -selects -all revisions earlier than -.IR d . -A range of the form -.IB d < -or -.BI > d -selects -all revisions dated later than -.IR d . -If -.B < -or -.B > -is followed by -.B = -then the ranges are inclusive, not exclusive. -A range of the form -.I d -selects the single, latest revision dated -.I d -or earlier. -The date/time strings -.IR d , -.IR d1 , -and -.I d2 -are in the free format explained in -.BR co (1). -Quoting is normally necessary, especially for -.B < -and -.BR > . -Note that the separator is -a semicolon. -.TP -.BR \-l [\f2lockers\fP] -Print information about locked revisions only. -In addition, if the comma-separated list -.I lockers -of login names is given, -ignore all locks other than those held by the -.IR lockers . -For example, -.B "rlog\ \-L\ \-R\ \-lwft\ RCS/*" -prints the name of \*r files locked by the user -.BR wft . -.TP -.BR \-r [\f2revisions\fP] -prints information about revisions given in the comma-separated list -.I revisions -of revisions and ranges. -A range -.IB rev1 : rev2 -means revisions -.I rev1 -to -.I rev2 -on the same branch, -.BI : rev -means revisions from the beginning of the branch up to and including -.IR rev , -and -.IB rev : -means revisions starting with -.I rev -to the end of the branch containing -.IR rev . -An argument that is a branch means all -revisions on that branch. -A range of branches means all revisions -on the branches in that range. -A branch followed by a -.B .\& -means the latest revision in that branch. -A bare -.B \-r -with no -.I revisions -means the latest revision on the default branch, normally the trunk. -.TP -.BI \-s states -prints information about revisions whose state attributes match one of the -states given in the comma-separated list -.IR states . -.TP -.BR \-w [\f2logins\fP] -prints information about revisions checked in by users with -login names appearing in the comma-separated list -.IR logins . -If -.I logins -is omitted, the user's login is assumed. -.TP -.B \-T -This option has no effect; -it is present for compatibility with other \*r commands. -.TP -.BI \-V -Print \*r's version number. -.TP -.BI \-V n -Emulate \*r version -.I n -when generating logs. -See -.BR co (1) -for more. -.TP -.BI \-x "suffixes" -Use -.I suffixes -to characterize \*r files. -See -.BR ci (1) -for details. -.PP -.B rlog -prints the intersection of the revisions selected with -the options -.BR \-d , -.BR \-l , -.BR \-s , -and -.BR \-w , -intersected -with the union of the revisions selected by -.B \-b -and -.BR \-r . -.TP -.BI \-z zone -specifies the date output format, -and specifies the default time zone for -.I date -in the -.BI \-d dates -option. -The -.I zone -should be empty, a numeric \*u offset, or the special string -.B LT -for local time. -The default is an empty -.IR zone , -which uses the traditional \*r format of \*u without any time zone indication -and with slashes separating the parts of the date; -otherwise, times are output in \*i 8601 format with time zone indication. -For example, if local time is January 11, 1990, 8pm Pacific Standard Time, -eight hours west of \*u, -then the time is output as follows: -.RS -.LP -.RS -.nf -.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u -.ne 4 -\f2option\fP \f2time output\fP -\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP -\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP -\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP -.ta 4n +4n +4n +4n -.fi -.RE -.SH EXAMPLES -.LP -.nf -.B " rlog \-L \-R RCS/*" -.B " rlog \-L \-h RCS/*" -.B " rlog \-L \-l RCS/*" -.B " rlog RCS/*" -.fi -.LP -The first command prints the names of all \*r files in the subdirectory -.B RCS -that have locks. The second command prints the headers of those files, -and the third prints the headers plus the log messages of the locked revisions. -The last command prints complete information. -.SH ENVIRONMENT -.TP -.B \s-1RCSINIT\s0 -options prepended to the argument list, separated by spaces. -See -.BR ci (1) -for details. -.SH DIAGNOSTICS -The exit status is zero if and only if all operations were successful. -.SH IDENTIFICATION -Author: Walter F. Tichy. -.br -Manual Page Revision: \*(Rv; Release Date: \*(Dt. -.br -Copyright \(co 1982, 1988, 1989 Walter F. Tichy. -.br -Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert. -.SH "SEE ALSO" -ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), -rcsfile(5) -.br -Walter F. Tichy, -\*r\*-A System for Version Control, -.I "Software\*-Practice & Experience" -.BR 15 , -7 (July 1985), 637-654. -.SH BUGS -The separator for revision ranges in the -.B \-r -option used to be -.B \- -instead of -.BR : , -but this leads to confusion when symbolic names contain -.BR \- . -For backwards compatibility -.B "rlog \-r" -still supports the old -.B \- -separator, but it warns about this obsolete use. -.br diff --git a/gnu/usr.bin/rcs/rlog/rlog.c b/gnu/usr.bin/rcs/rlog/rlog.c deleted file mode 100644 index f8872febb971..000000000000 --- a/gnu/usr.bin/rcs/rlog/rlog.c +++ /dev/null @@ -1,1290 +0,0 @@ -/* Print log messages and other information about RCS files. */ - -/* Copyright 1982, 1988, 1989 Walter Tichy - Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - -This file is part of RCS. - -RCS is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -RCS is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with RCS; see the file COPYING. -If not, write to the Free Software Foundation, -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - -*/ - -/* - * Revision 5.18 1995/06/16 06:19:24 eggert - * Update FSF address. - * - * Revision 5.17 1995/06/01 16:23:43 eggert - * (struct rcslockers): Renamed from `struct lockers'. - * (getnumericrev): Return error indication instead of ignoring errors. - * (main): Check it. Don't use dateform. - * (recentdate, extdate): cmpnum -> cmpdate - * - * Revision 5.16 1994/04/13 16:30:34 eggert - * Fix bug; `rlog -lxxx' inverted the sense of -l. - * - * Revision 5.15 1994/03/17 14:05:48 eggert - * -d' RCS_lint - * - * Revision 5.10 1992/01/06 02:42:34 eggert - * Update usage string. - * while (E) ; -> while (E) continue; - * - * Revision 5.9 1991/09/17 19:07:40 eggert - * Getscript() didn't uncache partial lines. - * - * Revision 5.8 1991/08/19 03:13:55 eggert - * Revision separator is `:', not `-'. - * Check for missing and duplicate logs. Tune. - * Permit log messages that do not end in newline (including empty logs). - * - * Revision 5.7 1991/04/21 11:58:31 eggert - * Add -x, RCSINIT, MS-DOS support. - * - * Revision 5.6 1991/02/26 17:07:17 eggert - * Survive RCS files with missing logs. - * strsave -> str_save (DG/UX name clash) - * - * Revision 5.5 1990/11/01 05:03:55 eggert - * Permit arbitrary data in logs and comment leaders. - * - * Revision 5.4 1990/10/04 06:30:22 eggert - * Accumulate exit status across files. - * - * Revision 5.3 1990/09/11 02:41:16 eggert - * Plug memory leak. - * - * Revision 5.2 1990/09/04 08:02:33 eggert - * Count RCS lines better. - * - * Revision 5.0 1990/08/22 08:13:48 eggert - * Remove compile-time limits; use malloc instead. Add setuid support. - * Switch to GMT. - * Report dates in long form, to warn about dates past 1999/12/31. - * Change "added/del" message to make room for the longer dates. - * Don't generate trailing white space. Add -V. Ansify and Posixate. - * - * Revision 4.7 89/05/01 15:13:48 narten - * changed copyright header to reflect current distribution rules - * - * Revision 4.6 88/08/09 19:13:28 eggert - * Check for memory exhaustion; don't access freed storage. - * Shrink stdio code size; remove lint. - * - * Revision 4.5 87/12/18 11:46:38 narten - * more lint cleanups (Guy Harris) - * - * Revision 4.4 87/10/18 10:41:12 narten - * Updating version numbers - * Changes relative to 1.1 actually relative to 4.2 - * - * Revision 1.3 87/09/24 14:01:10 narten - * Sources now pass through lint (if you ignore printf/sprintf/fprintf - * warnings) - * - * Revision 1.2 87/03/27 14:22:45 jenkins - * Port to suns - * - * Revision 4.2 83/12/05 09:18:09 wft - * changed rewriteflag to external. - * - * Revision 4.1 83/05/11 16:16:55 wft - * Added -b, updated getnumericrev() accordingly. - * Replaced getpwuid() with getcaller(). - * - * Revision 3.7 83/05/11 14:24:13 wft - * Added options -L and -R; - * Fixed selection bug with -l on multiple files. - * Fixed error on dates of the form -d'>date' (rewrote getdatepair()). - * - * Revision 3.6 82/12/24 15:57:53 wft - * shortened output format. - * - * Revision 3.5 82/12/08 21:45:26 wft - * removed call to checkaccesslist(); used DATEFORM to format all dates; - * removed unused variables. - * - * Revision 3.4 82/12/04 13:26:25 wft - * Replaced getdelta() with gettree(); removed updating of field lockedby. - * - * Revision 3.3 82/12/03 14:08:20 wft - * Replaced getlogin with getpwuid(), %02d with %.2d, fancydate with PRINTDATE. - * Fixed printing of nil, removed printing of Suffix, - * added shortcut if no revisions are printed, disambiguated struct members. - * - * Revision 3.2 82/10/18 21:09:06 wft - * call to curdir replaced with getfullRCSname(), - * fixed call to getlogin(), cosmetic changes on output, - * changed conflicting long identifiers. - * - * Revision 3.1 82/10/13 16:07:56 wft - * fixed type of variables receiving from getc() (char -> int). - */ - - - -#include "rcsbase.h" - -struct rcslockers { /* lockers in locker option; stored */ - char const * login; /* lockerlist */ - struct rcslockers * lockerlink; - } ; - -struct stateattri { /* states in state option; stored in */ - char const * status; /* statelist */ - struct stateattri * nextstate; - } ; - -struct authors { /* login names in author option; */ - char const * login; /* stored in authorlist */ - struct authors * nextauthor; - } ; - -struct Revpairs{ /* revision or branch range in -r */ - int numfld; /* option; stored in revlist */ - char const * strtrev; - char const * endrev; - struct Revpairs * rnext; - } ; - -struct Datepairs{ /* date range in -d option; stored in */ - struct Datepairs *dnext; - char strtdate[datesize]; /* duelst and datelist */ - char enddate[datesize]; - char ne_date; /* datelist only; distinguishes < from <= */ - }; - -static char extractdelta P((struct hshentry const*)); -static int checkrevpair P((char const*,char const*)); -static int extdate P((struct hshentry*)); -static int getnumericrev P((void)); -static struct hshentry const *readdeltalog P((void)); -static void cleanup P((void)); -static void exttree P((struct hshentry*)); -static void getauthor P((char*)); -static void getdatepair P((char*)); -static void getlocker P((char*)); -static void getrevpairs P((char*)); -static void getscript P((struct hshentry*)); -static void getstate P((char*)); -static void putabranch P((struct hshentry const*)); -static void putadelta P((struct hshentry const*,struct hshentry const*,int)); -static void putforest P((struct branchhead const*)); -static void putree P((struct hshentry const*)); -static void putrunk P((void)); -static void recentdate P((struct hshentry const*,struct Datepairs*)); -static void trunclocks P((void)); - -static char const *insDelFormat; -static int branchflag; /*set on -b */ -static int exitstatus; -static int lockflag; -static struct Datepairs *datelist, *duelst; -static struct Revpairs *revlist, *Revlst; -static struct authors *authorlist; -static struct rcslockers *lockerlist; -static struct stateattri *statelist; - - -mainProg(rlogId, "rlog", "$FreeBSD$") -{ - static char const cmdusage[] = - "\nrlog usage: rlog -{bhLNRt} -v[string] -ddates -l[lockers] -r[revs] -sstates -Vn -w[logins] -xsuff -zzone file ..."; - - register FILE *out; - char *a, **newargv; - struct Datepairs *currdate; - char const *accessListString, *accessFormat; - char const *headFormat, *symbolFormat; - struct access const *curaccess; - struct assoc const *curassoc; - struct hshentry const *delta; - struct rcslock const *currlock; - int descflag, selectflag; - int onlylockflag; /* print only files with locks */ - int onlyRCSflag; /* print only RCS pathname */ - int pre5; - int shownames; - int revno; - int versionlist; - char *vstring; - - descflag = selectflag = shownames = true; - versionlist = onlylockflag = onlyRCSflag = false; - vstring=0; - out = stdout; - suffixes = X_DEFAULT; - - argc = getRCSINIT(argc, argv, &newargv); - argv = newargv; - while (a = *++argv, 0<--argc && *a++=='-') { - switch (*a++) { - - case 'L': - onlylockflag = true; - break; - - case 'N': - shownames = false; - break; - - case 'R': - onlyRCSflag =true; - break; - - case 'l': - lockflag = true; - getlocker(a); - break; - - case 'b': - branchflag = true; - break; - - case 'r': - getrevpairs(a); - break; - - case 'd': - getdatepair(a); - break; - - case 's': - getstate(a); - break; - - case 'w': - getauthor(a); - break; - - case 'h': - descflag = false; - break; - - case 't': - selectflag = false; - break; - - case 'q': - /* This has no effect; it's here for consistency. */ - quietflag = true; - break; - - case 'x': - suffixes = a; - break; - - case 'z': - zone_set(a); - break; - - case 'T': - /* Ignore -T, so that RCSINIT can contain -T. */ - if (*a) - goto unknown; - break; - - case 'V': - setRCSversion(*argv); - break; - - case 'v': - versionlist = true; - vstring = a; - break; - - default: - unknown: - error("unknown option: %s%s", *argv, cmdusage); - - }; - } /* end of option processing */ - - if (! (descflag|selectflag)) { - warn("-t overrides -h."); - descflag = true; - } - - pre5 = RCSversion < VERSION(5); - if (pre5) { - accessListString = "\naccess list: "; - accessFormat = " %s"; - headFormat = "RCS file: %s; Working file: %s\nhead: %s%s\nbranch: %s%s\nlocks: "; - insDelFormat = " lines added/del: %ld/%ld"; - symbolFormat = " %s: %s;"; - } else { - accessListString = "\naccess list:"; - accessFormat = "\n\t%s"; - headFormat = "RCS file: %s\nWorking file: %s\nhead:%s%s\nbranch:%s%s\nlocks:%s"; - insDelFormat = " lines: +%ld -%ld"; - symbolFormat = "\n\t%s: %s"; - } - - /* Now handle all pathnames. */ - if (nerror) - cleanup(); - else if (argc < 1) - faterror("no input file%s", cmdusage); - else - for (; 0 < argc; cleanup(), ++argv, --argc) { - ffree(); - - if (pairnames(argc, argv, rcsreadopen, true, false) <= 0) - continue; - - /* - * RCSname contains the name of the RCS file, - * and finptr the file descriptor; - * workname contains the name of the working file. - */ - - /* Keep only those locks given by -l. */ - if (lockflag) - trunclocks(); - - /* do nothing if -L is given and there are no locks*/ - if (onlylockflag && !Locks) - continue; - - if ( versionlist ) { - gettree(); - aprintf(out, "%s%s %s\n", vstring, workname, tiprev()); - continue; - } - - if ( onlyRCSflag ) { - aprintf(out, "%s\n", RCSname); - continue; - } - - gettree(); - - if (!getnumericrev()) - continue; - - /* - * Output the first character with putc, not printf. - * Otherwise, an SVR4 stdio bug buffers output inefficiently. - */ - aputc_('\n', out) - - /* print RCS pathname, working pathname and optional - administrative information */ - /* could use getfullRCSname() here, but that is very slow */ - aprintf(out, headFormat, RCSname, workname, - Head ? " " : "", Head ? Head->num : "", - Dbranch ? " " : "", Dbranch ? Dbranch : "", - StrictLocks ? " strict" : "" - ); - currlock = Locks; - while( currlock ) { - aprintf(out, symbolFormat, currlock->login, - currlock->delta->num); - currlock = currlock->nextlock; - } - if (StrictLocks && pre5) - aputs(" ; strict" + (Locks?3:0), out); - - aputs(accessListString, out); /* print access list */ - curaccess = AccessList; - while(curaccess) { - aprintf(out, accessFormat, curaccess->login); - curaccess = curaccess->nextaccess; - } - - if (shownames) { - aputs("\nsymbolic names:", out); /* print symbolic names */ - for (curassoc=Symbols; curassoc; curassoc=curassoc->nextassoc) - aprintf(out, symbolFormat, curassoc->symbol, curassoc->num); - } - if (pre5) { - aputs("\ncomment leader: \"", out); - awrite(Comment.string, Comment.size, out); - afputc('\"', out); - } - if (!pre5 || Expand != KEYVAL_EXPAND) - aprintf(out, "\nkeyword substitution: %s", - expand_names[Expand] - ); - - aprintf(out, "\ntotal revisions: %d", TotalDeltas); - - revno = 0; - - if (Head && selectflag & descflag) { - - exttree(Head); - - /* get most recently date of the dates pointed by duelst */ - currdate = duelst; - while( currdate) { - VOID strcpy(currdate->strtdate, "0.0.0.0.0.0"); - recentdate(Head, currdate); - currdate = currdate->dnext; - } - - revno = extdate(Head); - - aprintf(out, ";\tselected revisions: %d", revno); - } - - afputc('\n',out); - if (descflag) { - aputs("description:\n", out); - getdesc(true); - } - if (revno) { - while (! (delta = readdeltalog())->selector || --revno) - continue; - if (delta->next && countnumflds(delta->num)==2) - /* Read through delta->next to get its insertlns. */ - while (readdeltalog() != delta->next) - continue; - putrunk(); - putree(Head); - } - aputs("----------------------------\n", out); - aputs("=============================================================================\n",out); - } - Ofclose(out); - exitmain(exitstatus); -} - - static void -cleanup() -{ - if (nerror) exitstatus = EXIT_FAILURE; - Izclose(&finptr); -} - -#if RCS_lint -# define exiterr rlogExit -#endif - void -exiterr() -{ - _exit(EXIT_FAILURE); -} - - - - static void -putrunk() -/* function: print revisions chosen, which are in trunk */ - -{ - register struct hshentry const *ptr; - - for (ptr = Head; ptr; ptr = ptr->next) - putadelta(ptr, ptr->next, true); -} - - - - static void -putree(root) - struct hshentry const *root; -/* function: print delta tree (not including trunk) in reverse - order on each branch */ - -{ - if (!root) return; - - putree(root->next); - - putforest(root->branches); -} - - - - - static void -putforest(branchroot) - struct branchhead const *branchroot; -/* function: print branches that has the same direct ancestor */ -{ - if (!branchroot) return; - - putforest(branchroot->nextbranch); - - putabranch(branchroot->hsh); - putree(branchroot->hsh); -} - - - - - static void -putabranch(root) - struct hshentry const *root; -/* function : print one branch */ - -{ - if (!root) return; - - putabranch(root->next); - - putadelta(root, root, false); -} - - - - - - static void -putadelta(node,editscript,trunk) - register struct hshentry const *node, *editscript; - int trunk; -/* function: Print delta node if node->selector is set. */ -/* editscript indicates where the editscript is stored */ -/* trunk indicated whether this node is in trunk */ -{ - static char emptych[] = EMPTYLOG; - - register FILE *out; - char const *s; - size_t n; - struct branchhead const *newbranch; - struct buf branchnum; - char datebuf[datesize + zonelenmax]; - int pre5 = RCSversion < VERSION(5); - - if (!node->selector) - return; - - out = stdout; - aprintf(out, - "----------------------------\nrevision %s%s", - node->num, pre5 ? " " : "" - ); - if ( node->lockedby ) - aprintf(out, pre5+"\tlocked by: %s;", node->lockedby); - - aprintf(out, "\ndate: %s; author: %s; state: %s;", - date2str(node->date, datebuf), - node->author, node->state - ); - - if ( editscript ) - if(trunk) - aprintf(out, insDelFormat, - editscript->deletelns, editscript->insertlns); - else - aprintf(out, insDelFormat, - editscript->insertlns, editscript->deletelns); - - newbranch = node->branches; - if ( newbranch ) { - bufautobegin(&branchnum); - aputs("\nbranches:", out); - while( newbranch ) { - getbranchno(newbranch->hsh->num, &branchnum); - aprintf(out, " %s;", branchnum.string); - newbranch = newbranch->nextbranch; - } - bufautoend(&branchnum); - } - - afputc('\n', out); - s = node->log.string; - if (!(n = node->log.size)) { - s = emptych; - n = sizeof(emptych)-1; - } - awrite(s, n, out); - if (s[n-1] != '\n') - afputc('\n', out); -} - - - static struct hshentry const * -readdeltalog() -/* Function : get the log message and skip the text of a deltatext node. - * Return the delta found. - * Assumes the current lexeme is not yet in nexttok; does not - * advance nexttok. - */ -{ - register struct hshentry * Delta; - struct buf logbuf; - struct cbuf cb; - - if (eoflex()) - fatserror("missing delta log"); - nextlex(); - if (!(Delta = getnum())) - fatserror("delta number corrupted"); - getkeystring(Klog); - if (Delta->log.string) - fatserror("duplicate delta log"); - bufautobegin(&logbuf); - cb = savestring(&logbuf); - Delta->log = bufremember(&logbuf, cb.size); - - ignorephrases(Ktext); - getkeystring(Ktext); - Delta->insertlns = Delta->deletelns = 0; - if ( Delta != Head) - getscript(Delta); - else - readstring(); - return Delta; -} - - - static void -getscript(Delta) -struct hshentry * Delta; -/* function: read edit script of Delta and count how many lines added */ -/* and deleted in the script */ - -{ - int ed; /* editor command */ - declarecache; - register RILE *fin; - register int c; - register long i; - struct diffcmd dc; - - fin = finptr; - setupcache(fin); - initdiffcmd(&dc); - while (0 <= (ed = getdiffcmd(fin,true,(FILE *)0,&dc))) - if (!ed) - Delta->deletelns += dc.nlines; - else { - /* skip scripted lines */ - i = dc.nlines; - Delta->insertlns += i; - cache(fin); - do { - for (;;) { - cacheget_(c) - switch (c) { - default: - continue; - case SDELIM: - cacheget_(c) - if (c == SDELIM) - continue; - if (--i) - unexpected_EOF(); - nextc = c; - uncache(fin); - return; - case '\n': - break; - } - break; - } - ++rcsline; - } while (--i); - uncache(fin); - } -} - - - - - - - - static void -exttree(root) -struct hshentry *root; -/* function: select revisions , starting with root */ - -{ - struct branchhead const *newbranch; - - if (!root) return; - - root->selector = extractdelta(root); - root->log.string = 0; - exttree(root->next); - - newbranch = root->branches; - while( newbranch ) { - exttree(newbranch->hsh); - newbranch = newbranch->nextbranch; - } -} - - - - - static void -getlocker(argv) -char * argv; -/* function : get the login names of lockers from command line */ -/* and store in lockerlist. */ - -{ - register char c; - struct rcslockers *newlocker; - argv--; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - if ( c == '\0') { - lockerlist = 0; - return; - } - - while( c != '\0' ) { - newlocker = talloc(struct rcslockers); - newlocker->lockerlink = lockerlist; - newlocker->login = argv; - lockerlist = newlocker; - while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';') - continue; - *argv = '\0'; - if ( c == '\0' ) return; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - } -} - - - - static void -getauthor(argv) -char *argv; -/* function: get the author's name from command line */ -/* and store in authorlist */ - -{ - register c; - struct authors * newauthor; - - argv--; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - if ( c == '\0' ) { - authorlist = talloc(struct authors); - authorlist->login = getusername(false); - authorlist->nextauthor = 0; - return; - } - - while( c != '\0' ) { - newauthor = talloc(struct authors); - newauthor->nextauthor = authorlist; - newauthor->login = argv; - authorlist = newauthor; - while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';') - continue; - * argv = '\0'; - if ( c == '\0') return; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - } -} - - - - - static void -getstate(argv) -char * argv; -/* function : get the states of revisions from command line */ -/* and store in statelist */ - -{ - register char c; - struct stateattri *newstate; - - argv--; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - if ( c == '\0'){ - error("missing state attributes after -s options"); - return; - } - - while( c != '\0' ) { - newstate = talloc(struct stateattri); - newstate->nextstate = statelist; - newstate->status = argv; - statelist = newstate; - while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';') - continue; - *argv = '\0'; - if ( c == '\0' ) return; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - } -} - - - - static void -trunclocks() -/* Function: Truncate the list of locks to those that are held by the */ -/* id's on lockerlist. Do not truncate if lockerlist empty. */ - -{ - struct rcslockers const *plocker; - struct rcslock *p, **pp; - - if (!lockerlist) return; - - /* shorten Locks to those contained in lockerlist */ - for (pp = &Locks; (p = *pp); ) - for (plocker = lockerlist; ; ) - if (strcmp(plocker->login, p->login) == 0) { - pp = &p->nextlock; - break; - } else if (!(plocker = plocker->lockerlink)) { - *pp = p->nextlock; - break; - } -} - - - - static void -recentdate(root, pd) - struct hshentry const *root; - struct Datepairs *pd; -/* function: Finds the delta that is closest to the cutoff date given by */ -/* pd among the revisions selected by exttree. */ -/* Successively narrows down the interval given by pd, */ -/* and sets the strtdate of pd to the date of the selected delta */ -{ - struct branchhead const *newbranch; - - if (!root) return; - if (root->selector) { - if ( cmpdate(root->date, pd->strtdate) >= 0 && - cmpdate(root->date, pd->enddate) <= 0) - VOID strcpy(pd->strtdate, root->date); - } - - recentdate(root->next, pd); - newbranch = root->branches; - while( newbranch) { - recentdate(newbranch->hsh, pd); - newbranch = newbranch->nextbranch; - } -} - - - - - - - static int -extdate(root) -struct hshentry * root; -/* function: select revisions which are in the date range specified */ -/* in duelst and datelist, start at root */ -/* Yield number of revisions selected, including those already selected. */ -{ - struct branchhead const *newbranch; - struct Datepairs const *pdate; - int revno, ne; - - if (!root) - return 0; - - if ( datelist || duelst) { - pdate = datelist; - while( pdate ) { - ne = pdate->ne_date; - if ( - (!pdate->strtdate[0] - || ne <= cmpdate(root->date, pdate->strtdate)) - && - (!pdate->enddate[0] - || ne <= cmpdate(pdate->enddate, root->date)) - ) - break; - pdate = pdate->dnext; - } - if (!pdate) { - pdate = duelst; - for (;;) { - if (!pdate) { - root->selector = false; - break; - } - if (cmpdate(root->date, pdate->strtdate) == 0) - break; - pdate = pdate->dnext; - } - } - } - revno = root->selector + extdate(root->next); - - newbranch = root->branches; - while( newbranch ) { - revno += extdate(newbranch->hsh); - newbranch = newbranch->nextbranch; - } - return revno; -} - - - - static char -extractdelta(pdelta) - struct hshentry const *pdelta; -/* function: compare information of pdelta to the authorlist, lockerlist,*/ -/* statelist, revlist and yield true if pdelta is selected. */ - -{ - struct rcslock const *plock; - struct stateattri const *pstate; - struct authors const *pauthor; - struct Revpairs const *prevision; - int length; - - if ((pauthor = authorlist)) /* only certain authors wanted */ - while (strcmp(pauthor->login, pdelta->author) != 0) - if (!(pauthor = pauthor->nextauthor)) - return false; - if ((pstate = statelist)) /* only certain states wanted */ - while (strcmp(pstate->status, pdelta->state) != 0) - if (!(pstate = pstate->nextstate)) - return false; - if (lockflag) /* only locked revisions wanted */ - for (plock = Locks; ; plock = plock->nextlock) - if (!plock) - return false; - else if (plock->delta == pdelta) - break; - if ((prevision = Revlst)) /* only certain revs or branches wanted */ - for (;;) { - length = prevision->numfld; - if ( - countnumflds(pdelta->num) == length+(length&1) && - 0 <= compartial(pdelta->num, prevision->strtrev, length) && - 0 <= compartial(prevision->endrev, pdelta->num, length) - ) - break; - if (!(prevision = prevision->rnext)) - return false; - } - return true; -} - - - - static void -getdatepair(argv) - char * argv; -/* function: get time range from command line and store in datelist if */ -/* a time range specified or in duelst if a time spot specified */ - -{ - register char c; - struct Datepairs * nextdate; - char const * rawdate; - int switchflag; - - argv--; - while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';') - continue; - if ( c == '\0' ) { - error("missing date/time after -d"); - return; - } - - while( c != '\0' ) { - switchflag = false; - nextdate = talloc(struct Datepairs); - if ( c == '<' ) { /* case: -d ne_date = c!='=')) - c = *++argv; - (nextdate->strtdate)[0] = '\0'; - } else if (c == '>') { /* case: -d'>date' */ - c = *++argv; - if (!(nextdate->ne_date = c!='=')) - c = *++argv; - (nextdate->enddate)[0] = '\0'; - switchflag = true; - } else { - rawdate = argv; - while( c != '<' && c != '>' && c != ';' && c != '\0') - c = *++argv; - *argv = '\0'; - if ( c == '>' ) switchflag=true; - str2date(rawdate, - switchflag ? nextdate->enddate : nextdate->strtdate); - if ( c == ';' || c == '\0') { /* case: -d date */ - VOID strcpy(nextdate->enddate,nextdate->strtdate); - nextdate->dnext = duelst; - duelst = nextdate; - goto end; - } else { - /* case: -d date< or -d date>; see switchflag */ - int eq = argv[1]=='='; - nextdate->ne_date = !eq; - argv += eq; - while ((c = *++argv) == ' ' || c=='\t' || c=='\n') - continue; - if ( c == ';' || c == '\0') { - /* second date missing */ - if (switchflag) - *nextdate->strtdate= '\0'; - else - *nextdate->enddate= '\0'; - nextdate->dnext = datelist; - datelist = nextdate; - goto end; - } - } - } - rawdate = argv; - while( c != '>' && c != '<' && c != ';' && c != '\0') - c = *++argv; - *argv = '\0'; - str2date(rawdate, - switchflag ? nextdate->strtdate : nextdate->enddate); - nextdate->dnext = datelist; - datelist = nextdate; - end: - if (RCSversion < VERSION(5)) - nextdate->ne_date = 0; - if ( c == '\0') return; - while ((c = *++argv) == ';' || c == ' ' || c == '\t' || c =='\n') - continue; - } -} - - - - static int -getnumericrev() -/* function: get the numeric name of revisions which stored in revlist */ -/* and then stored the numeric names in Revlst */ -/* if branchflag, also add default branch */ - -{ - struct Revpairs * ptr, *pt; - int n; - struct buf s, e; - char const *lrev; - struct buf const *rstart, *rend; - - Revlst = 0; - ptr = revlist; - bufautobegin(&s); - bufautobegin(&e); - while( ptr ) { - n = 0; - rstart = &s; - rend = &e; - - switch (ptr->numfld) { - - case 1: /* -rREV */ - if (!expandsym(ptr->strtrev, &s)) - goto freebufs; - rend = &s; - n = countnumflds(s.string); - if (!n && (lrev = tiprev())) { - bufscpy(&s, lrev); - n = countnumflds(lrev); - } - break; - - case 2: /* -rREV: */ - if (!expandsym(ptr->strtrev, &s)) - goto freebufs; - bufscpy(&e, s.string); - n = countnumflds(s.string); - (n<2 ? e.string : strrchr(e.string,'.'))[0] = 0; - break; - - case 3: /* -r:REV */ - if (!expandsym(ptr->endrev, &e)) - goto freebufs; - if ((n = countnumflds(e.string)) < 2) - bufscpy(&s, ".0"); - else { - bufscpy(&s, e.string); - VOID strcpy(strrchr(s.string,'.'), ".0"); - } - break; - - default: /* -rREV1:REV2 */ - if (!( - expandsym(ptr->strtrev, &s) - && expandsym(ptr->endrev, &e) - && checkrevpair(s.string, e.string) - )) - goto freebufs; - n = countnumflds(s.string); - /* Swap if out of order. */ - if (compartial(s.string,e.string,n) > 0) { - rstart = &e; - rend = &s; - } - break; - } - - if (n) { - pt = ftalloc(struct Revpairs); - pt->numfld = n; - pt->strtrev = fstr_save(rstart->string); - pt->endrev = fstr_save(rend->string); - pt->rnext = Revlst; - Revlst = pt; - } - ptr = ptr->rnext; - } - /* Now take care of branchflag */ - if (branchflag && (Dbranch||Head)) { - pt = ftalloc(struct Revpairs); - pt->strtrev = pt->endrev = - Dbranch ? Dbranch : fstr_save(partialno(&s,Head->num,1)); - pt->rnext=Revlst; Revlst=pt; - pt->numfld = countnumflds(pt->strtrev); - } - - freebufs: - bufautoend(&s); - bufautoend(&e); - return !ptr; -} - - - - static int -checkrevpair(num1,num2) - char const *num1, *num2; -/* function: check whether num1, num2 are legal pair,i.e. - only the last field are different and have same number of - fields( if length <= 2, may be different if first field) */ - -{ - int length = countnumflds(num1); - - if ( - countnumflds(num2) != length - || (2 < length && compartial(num1, num2, length-1) != 0) - ) { - rcserror("invalid branch or revision pair %s : %s", num1, num2); - return false; - } - - return true; -} - - - - static void -getrevpairs(argv) -register char * argv; -/* function: get revision or branch range from command line, and */ -/* store in revlist */ - -{ - register char c; - struct Revpairs * nextrevpair; - int separator; - - c = *argv; - - /* Support old ambiguous '-' syntax; this will go away. */ - if (strchr(argv,':')) - separator = ':'; - else { - if (strchr(argv,'-') && VERSION(5) <= RCSversion) - warn("`-' is obsolete in `-r%s'; use `:' instead", argv); - separator = '-'; - } - - for (;;) { - while (c==' ' || c=='\t' || c=='\n') - c = *++argv; - nextrevpair = talloc(struct Revpairs); - nextrevpair->rnext = revlist; - revlist = nextrevpair; - nextrevpair->numfld = 1; - nextrevpair->strtrev = argv; - for (;; c = *++argv) { - switch (c) { - default: - continue; - case '\0': case ' ': case '\t': case '\n': - case ',': case ';': - break; - case ':': case '-': - if (c == separator) - break; - continue; - } - break; - } - *argv = '\0'; - while (c==' ' || c=='\t' || c=='\n') - c = *++argv; - if (c == separator) { - while ((c = *++argv) == ' ' || c == '\t' || c =='\n') - continue; - nextrevpair->endrev = argv; - for (;; c = *++argv) { - switch (c) { - default: - continue; - case '\0': case ' ': case '\t': case '\n': - case ',': case ';': - break; - case ':': case '-': - if (c == separator) - break; - continue; - } - break; - } - *argv = '\0'; - while (c==' ' || c=='\t' || c =='\n') - c = *++argv; - nextrevpair->numfld = - !nextrevpair->endrev[0] ? 2 /* -rREV: */ : - !nextrevpair->strtrev[0] ? 3 /* -r:REV */ : - 4 /* -rREV1:REV2 */; - } - if (!c) - break; - else if (c==',' || c==';') - c = *++argv; - else - error("missing `,' near `%c%s'", c, argv+1); - } -} diff --git a/include/Makefile b/include/Makefile index 44c3ff1bdc6c..f2d76b6af06d 100644 --- a/include/Makefile +++ b/include/Makefile @@ -237,6 +237,17 @@ copies: .PHONY .META cd ${.CURDIR}/../sys/teken; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \ ${DESTDIR}${INCLUDEDIR}/teken +.if ${MK_CDDL} != "no" + cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libzfs_core/common; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libzfs_core.h \ + ${DESTDIR}${INCLUDEDIR} + cd ${.CURDIR}/../cddl/contrib/opensolaris/lib/libnvpair; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 libnvpair.h \ + ${DESTDIR}${INCLUDEDIR} + cd ${.CURDIR}/../sys/cddl/contrib/opensolaris/uts/common/sys; \ + ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nvpair.h \ + ${DESTDIR}${INCLUDEDIR}/sys +.endif symlinks: .PHONY .META @${ECHO} "Setting up symlinks to kernel source tree..." diff --git a/include/search.h b/include/search.h index 4c1f534c667a..068446fdcb88 100644 --- a/include/search.h +++ b/include/search.h @@ -34,16 +34,18 @@ typedef enum { } VISIT; #ifdef _SEARCH_PRIVATE -typedef struct node { - void *key; - struct node *llink, *rlink; - signed char balance; -} node_t; +typedef struct __posix_tnode { + void *key; + struct __posix_tnode *llink, *rlink; + signed char balance; +} posix_tnode; struct que_elem { struct que_elem *next; struct que_elem *prev; }; +#else +typedef void posix_tnode; #endif #if __BSD_VISIBLE @@ -62,12 +64,15 @@ void *lfind(const void *, const void *, size_t *, size_t, void *lsearch(const void *, void *, size_t *, size_t, int (*)(const void *, const void *)); void remque(void *); -void *tdelete(const void * __restrict, void ** __restrict, +void *tdelete(const void * __restrict, posix_tnode ** __restrict, int (*)(const void *, const void *)); -void *tfind(const void *, void * const *, +posix_tnode * + tfind(const void *, posix_tnode * const *, int (*)(const void *, const void *)); -void *tsearch(const void *, void **, int (*)(const void *, const void *)); -void twalk(const void *, void (*)(const void *, VISIT, int)); +posix_tnode * + tsearch(const void *, posix_tnode **, + int (*)(const void *, const void *)); +void twalk(const posix_tnode *, void (*)(const posix_tnode *, VISIT, int)); #if __BSD_VISIBLE int hcreate_r(size_t, struct hsearch_data *); diff --git a/lib/Makefile b/lib/Makefile index 486034e2f0c9..3dc1258051fd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -26,114 +26,76 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \ .WAIT \ libalias \ libarchive \ - ${_libatm} \ libauditd \ libbegemot \ - ${_libblacklist} \ libblocksruntime \ - ${_libbluetooth} \ - ${_libbsnmp} \ libbsdstat \ libbsm \ libbz2 \ libcalendar \ libcam \ libcapsicum \ - ${_libcasper} \ - ${_libcom_err} \ libcompat \ libcrypt \ libdevctl \ - ${_libdevdctl} \ libdevinfo \ libdevstat \ libdwarf \ libedit \ - ${_libelftc} \ libevent \ libexecinfo \ libexpat \ libfetch \ libfigpar \ libgeom \ - ${_libgpio} \ - ${_libgssapi} \ - ${_librpcsec_gss} \ - ${_libiconv_modules} \ libifconfig \ libipsec \ libjail \ libkiconv \ libkvm \ - ${_libldns} \ liblzma \ - ${_libmagic} \ libmemstat \ libmd \ - ${_libmilter} \ - ${_libmp} \ libmt \ - ${_libnandfs} \ lib80211 \ libnetbsd \ - ${_libnetgraph} \ - ${_libngatm} \ libnv \ libopenbsd \ libopie \ libpam \ libpcap \ - ${_libpe} \ libpjdlog \ - ${_libpmc} \ ${_libproc} \ libprocstat \ - ${_libradius} \ librpcsvc \ librss \ librt \ ${_librtld_db} \ libsbuf \ - ${_libsdp} \ - ${_libsm} \ libsmb \ - ${_libsmdb} \ - ${_libsmutil} \ libsqlite3 \ libstand \ libstdbuf \ libstdthreads \ libsysdecode \ libtacplus \ - ${_libtelnet} \ - ${_libthr} \ libthread_db \ libucl \ libufs \ libugidfw \ libulog \ - ${_libunbound} \ - ${_libusbhid} \ - ${_libusb} \ libutil \ ${_libvgl} \ - ${_libvmmapi} \ libwrap \ libxo \ liby \ - ${_libypclnt} \ libz \ - ncurses \ - ${_atf} \ - ${_clang} \ - ${_cuse} \ - ${_tests} + ncurses # Inter-library dependencies. When the makefile for a library contains LDADD # libraries, those libraries should be listed as build order dependencies here. SUBDIR_DEPEND_libarchive= libz libbz2 libexpat liblzma libmd -SUBDIR_DEPEND_libatm= libmd SUBDIR_DEPEND_libauditdm= libbsm SUBDIR_DEPEND_libbsnmp= ${_libnetgraph} SUBDIR_DEPEND_libc++:= libcxxrt @@ -160,70 +122,26 @@ SUBDIR_DEPEND_liblzma= ${_libthr} # NB: keep these sorted by MK_* knobs -.if ${MK_ATM} != "no" -_libngatm= libngatm -.endif - -.if ${MK_BLACKLIST} != "no" -_libblacklist= libblacklist -.endif - -.if ${MK_BLUETOOTH} != "no" -_libbluetooth= libbluetooth -_libsdp= libsdp -.endif - -.if ${MK_BSNMP} != "no" -_libbsnmp= libbsnmp -.endif - -.if ${MK_CASPER} != "no" -_libcasper= libcasper -.endif - -.if ${MK_CLANG} != "no" && !defined(COMPAT_32BIT) && !defined(COMPAT_SOFTFP) -_clang= clang -.endif - -.if ${MK_CUSE} != "no" -_cuse= libcuse -.endif - -.if ${MK_CXX} != "no" -_libdevdctl= libdevdctl -.endif - -.if ${MK_TOOLCHAIN} != "no" -_libelftc= libelftc -_libpe= libpe +SUBDIR.${MK_ATM}+= libngatm +SUBDIR.${MK_BLACKLIST}+=libblacklist +SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp +SUBDIR.${MK_BSNMP}+= libbsnmp +SUBDIR.${MK_CASPER}+= libcasper + +.if !defined(COMPAT_32BIT) && !defined(COMPAT_SOFTFP) +SUBDIR.${MK_CLANG}+= clang .endif +SUBDIR.${MK_CUSE}+= libcuse +SUBDIR.${MK_CXX}+= libdevdctl +SUBDIR.${MK_TOOLCHAIN}+=libelftc libpe SUBDIR.${MK_DIALOG}+= libdpv - -.if ${MK_FILE} != "no" -_libmagic= libmagic -.endif - -.if ${MK_GPIO} != "no" -_libgpio= libgpio -.endif - -.if ${MK_GSSAPI} != "no" -_libgssapi= libgssapi -_librpcsec_gss= librpcsec_gss -.endif - -.if ${MK_ICONV} != "no" -_libiconv_modules= libiconv_modules -.endif - -.if ${MK_KERBEROS_SUPPORT} != "no" -_libcom_err= libcom_err -.endif - -.if ${MK_LDNS} != "no" -_libldns= libldns -.endif +SUBDIR.${MK_FILE}+= libmagic +SUBDIR.${MK_GPIO}+= libgpio +SUBDIR.${MK_GSSAPI}+= libgssapi librpcsec_gss +SUBDIR.${MK_ICONV}+= libiconv_modules +SUBDIR.${MK_KERBEROS_SUPPORT}+= libcom_err +SUBDIR.${MK_LDNS}+= libldns # The libraries under libclang_rt can only be built by clang, and only make # sense to build when clang is enabled at all. Furthermore, they can only be @@ -240,88 +158,34 @@ _libcxxrt= libcxxrt _libcplusplus= libc++ .endif -.if ${MK_LIBTHR} != "no" -_libthr= libthr -.endif - -.if ${MK_NAND} != "no" -_libnandfs= libnandfs -.endif - -.if ${MK_NETGRAPH} != "no" -_libnetgraph= libnetgraph -.endif - -.if ${MK_NIS} != "no" -_libypclnt= libypclnt -.endif +SUBDIR.${MK_EFI}+= libefivar +SUBDIR.${MK_LIBTHR}+= libthr +SUBDIR.${MK_NAND}+= libnandfs +SUBDIR.${MK_NETGRAPH}+= libnetgraph +SUBDIR.${MK_NIS}+= libypclnt .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _libvgl= libvgl -_libproc= libproc -_librtld_db= librtld_db .endif .if ${MACHINE_CPUARCH} == "amd64" -.if ${MK_BHYVE} != "no" -_libvmmapi= libvmmapi -.endif +SUBDIR.${MK_BHYVE}+= libvmmapi .endif -.if ${MACHINE_CPUARCH} == "mips" +.if ${MACHINE_CPUARCH} != "sparc64" _libproc= libproc _librtld_db= librtld_db .endif -.if ${MACHINE_CPUARCH} == "powerpc" -_libproc= libproc -_librtld_db= librtld_db -.endif - -.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" || \ - ${MACHINE_CPUARCH} == "riscv" -_libproc= libproc -_librtld_db= librtld_db -.endif - -.if ${MK_OPENSSL} != "no" -_libmp= libmp -.endif - -.if ${MK_PMC} != "no" -_libpmc= libpmc -.endif - -.if ${MK_RADIUS_SUPPORT} != "no" -_libradius= libradius -.endif - -.if ${MK_SENDMAIL} != "no" -_libmilter= libmilter -_libsm= libsm -_libsmdb= libsmdb -_libsmutil= libsmutil -.endif - -.if ${MK_TELNET} != "no" -_libtelnet= libtelnet -.endif - -.if ${MK_TESTS_SUPPORT} != "no" -_atf= atf -.endif -.if ${MK_TESTS} != "no" -_tests= tests -.endif - -.if ${MK_UNBOUND} != "no" -_libunbound= libunbound -.endif - -.if ${MK_USB} != "no" -_libusbhid= libusbhid -_libusb= libusb -.endif +SUBDIR.${MK_OPENSSL}+= libmp +SUBDIR.${MK_PMC}+= libpmc +SUBDIR.${MK_RADIUS_SUPPORT}+= libradius +SUBDIR.${MK_SENDMAIL}+= libmilter libsm libsmdb libsmutil +SUBDIR.${MK_TELNET}+= libtelnet +SUBDIR.${MK_TESTS_SUPPORT}+= atf +SUBDIR.${MK_TESTS}+= tests +SUBDIR.${MK_UNBOUND}+= libunbound +SUBDIR.${MK_USB}+= libusbhid libusb .if !make(install) SUBDIR_PARALLEL= diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 2e17ec425d3b..a97b6fcdedb4 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -29,7 +29,11 @@ LIBC_ARCH=${MACHINE_CPUARCH} # to CFLAGS below. -DSYSLIBC_SCCS affects just the system call stubs. LIB=c SHLIB_MAJOR= 7 +.if ${MK_SSP} != "no" SHLIB_LDSCRIPT=libc.ldscript +.else +SHLIB_LDSCRIPT=libc_nossp.ldscript +.endif SHLIB_LDSCRIPT_LINKS=libxnet.so WARNS?= 2 CFLAGS+=-I${LIBC_SRCTOP}/include -I${LIBC_SRCTOP}/../../include diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index 0fa3dff75cc9..becc17bc2711 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -144,8 +144,15 @@ arc4_stir(void) arc4_init(); rs_initialized = 1; } - if (arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) - abort(); /* Random sysctl cannot fail. */ + if (arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) { + /* + * The sysctl cannot fail. If it does fail on some FreeBSD + * derivative or after some future change, just abort so that + * the problem will be found and fixed. abort is not normally + * suitable for a library but makes sense here. + */ + abort(); + } arc4_addrandom(rdat, KEYSIZE); diff --git a/lib/libc/gen/recvmmsg.c b/lib/libc/gen/recvmmsg.c index 0db9e1acab17..7c5c289569ee 100644 --- a/lib/libc/gen/recvmmsg.c +++ b/lib/libc/gen/recvmmsg.c @@ -69,6 +69,8 @@ recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags, if (ret == -1) return (ret); + msgvec[0].msg_len = ret; + /* * Do non-blocking receive for second and later messages if * WAITFORONE is set. @@ -81,10 +83,9 @@ recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags, ret = __sys_recvmsg(s, &msgvec[i].msg_hdr, flags); if (ret == -1) { /* We have received messages. Let caller know - * about the data received, socket - * error is returned on next - * invocation. - */ + * about the data received, socket error is + * returned on next invocation. + */ return (rcvd); } diff --git a/lib/libc/libc_nossp.ldscript b/lib/libc/libc_nossp.ldscript new file mode 100644 index 000000000000..c610cc21e018 --- /dev/null +++ b/lib/libc/libc_nossp.ldscript @@ -0,0 +1,2 @@ +/* $FreeBSD$ */ +GROUP ( @@SHLIB@@ @@LIBDIR@@/libc_nonshared.a ) diff --git a/lib/libc/mips/string/strchr.S b/lib/libc/mips/string/strchr.S index 198366f87a69..19dae58415e2 100644 --- a/lib/libc/mips/string/strchr.S +++ b/lib/libc/mips/string/strchr.S @@ -44,7 +44,12 @@ __FBSDID("$FreeBSD$"); .abicalls #endif +/* + * char * + * strchr(const char *s, int c); + */ LEAF(strchr) + and a1, a1, 0xff 1: lbu a2, 0(a0) # get a byte PTR_ADDU a0, a0, 1 diff --git a/lib/libc/mips/string/strrchr.S b/lib/libc/mips/string/strrchr.S index 5a88a42c8e17..c0dcef049d6e 100644 --- a/lib/libc/mips/string/strrchr.S +++ b/lib/libc/mips/string/strrchr.S @@ -44,8 +44,13 @@ __FBSDID("$FreeBSD$"); .abicalls #endif +/* + * char * + * strrchr(const char *s, int c); + */ LEAF(strrchr) move v0, zero # default if not found + and a1, a1, 0xff 1: lbu a3, 0(a0) # get a byte PTR_ADDU a0, a0, 1 diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c index f096aecb8335..48b120578698 100644 --- a/lib/libc/stdlib/random.c +++ b/lib/libc/stdlib/random.c @@ -279,8 +279,15 @@ srandomdev(void) mib[0] = CTL_KERN; mib[1] = KERN_ARND; - if (sysctl(mib, 2, state, &len, NULL, 0) == -1 || len != expected) + if (sysctl(mib, 2, state, &len, NULL, 0) == -1 || len != expected) { + /* + * The sysctl cannot fail. If it does fail on some FreeBSD + * derivative or after some future change, just abort so that + * the problem will be found and fixed. abort is not normally + * suitable for a library but makes sense here. + */ abort(); + } if (rand_type != TYPE_0) { fptr = &state[rand_sep]; diff --git a/lib/libc/stdlib/tdelete.c b/lib/libc/stdlib/tdelete.c index ff63576a1bf5..38b2bd739170 100644 --- a/lib/libc/stdlib/tdelete.c +++ b/lib/libc/stdlib/tdelete.c @@ -46,9 +46,9 @@ __FBSDID("$FreeBSD$"); * that we won't need to perform any rotations above \ * this point. In this case rotations are always \ * capable of keeping the subtree in balance. Make \ - * this the base node and reset the path. \ + * this the root node and reset the path. \ */ \ - base = leaf; \ + rootp = leaf; \ path_init(&path); \ } \ path_taking_left(&path); \ @@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$"); #define GO_RIGHT() do { \ if ((*leaf)->balance == 0 || \ ((*leaf)->balance > 0 && (*leaf)->llink->balance == 0)) { \ - base = leaf; \ + rootp = leaf; \ path_init(&path); \ } \ path_taking_right(&path); \ @@ -67,18 +67,16 @@ __FBSDID("$FreeBSD$"); } while (0) void * -tdelete(const void *restrict key, void **restrict rootp, +tdelete(const void *restrict key, posix_tnode **restrict rootp, int (*compar)(const void *, const void *)) { struct path path; - node_t *root, **base, **leaf, *old, **n, *x, *y, *z; - void *result; + posix_tnode **leaf, *old, **n, *x, *y, *z, *result; int cmp; /* POSIX requires that tdelete() returns NULL if rootp is NULL. */ if (rootp == NULL) return (NULL); - root = *rootp; /* * Find the leaf that needs to be removed. Return if we cannot @@ -86,19 +84,18 @@ tdelete(const void *restrict key, void **restrict rootp, * to get to the node, as we will need it to adjust the * balances. */ - result = (void *)1; + result = (posix_tnode *)1; path_init(&path); - base = &root; - leaf = &root; + leaf = rootp; for (;;) { if (*leaf == NULL) return (NULL); cmp = compar(key, (*leaf)->key); if (cmp < 0) { - result = &(*leaf)->key; + result = *leaf; GO_LEFT(); } else if (cmp > 0) { - result = &(*leaf)->key; + result = *leaf; GO_RIGHT(); } else { break; @@ -134,7 +131,7 @@ tdelete(const void *restrict key, void **restrict rootp, * and left-left case that only exists when deleting. Hence the * duplication of code. */ - for (n = base; n != leaf;) { + for (n = rootp; n != leaf;) { if (path_took_left(&path)) { x = *n; if (x->balance < 0) { @@ -207,6 +204,5 @@ tdelete(const void *restrict key, void **restrict rootp, } /* Return the parent of the old entry. */ - *rootp = root; return (result); } diff --git a/lib/libc/stdlib/tfind.c b/lib/libc/stdlib/tfind.c index 0ad391e79981..afcbc16cd2d4 100644 --- a/lib/libc/stdlib/tfind.c +++ b/lib/libc/stdlib/tfind.c @@ -4,8 +4,6 @@ * Tree search generalized from Knuth (6.2.2) Algorithm T just like * the AT&T man page says. * - * The node_t structure is for internal use only, lint doesn't grok it. - * * Written by reading the System V Interface Definition, not the code. * * Totally public domain. @@ -29,11 +27,10 @@ __FBSDID("$FreeBSD$"); * vkey - key to be found * vrootp - address of the tree root */ -void * -tfind(const void *vkey, void * const *vrootp, +posix_tnode * +tfind(const void *vkey, posix_tnode * const *rootp, int (*compar)(const void *, const void *)) { - node_t **rootp = (node_t **)vrootp; if (rootp == NULL) return NULL; diff --git a/lib/libc/stdlib/tsearch.3 b/lib/libc/stdlib/tsearch.3 index 2205f7e5aa85..493eff25deda 100644 --- a/lib/libc/stdlib/tsearch.3 +++ b/lib/libc/stdlib/tsearch.3 @@ -27,7 +27,7 @@ .\" OpenBSD: tsearch.3,v 1.2 1998/06/21 22:13:49 millert Exp .\" $FreeBSD$ .\" -.Dd December 6, 2015 +.Dd October 9, 2016 .Dt TSEARCH 3 .Os .Sh NAME @@ -36,13 +36,13 @@ .Sh SYNOPSIS .In search.h .Ft void * -.Fn tdelete "const void * restrict key" "void ** restrict rootp" "int (*compar) (const void *, const void *)" -.Ft void * -.Fn tfind "const void *key" "void * const *rootp" "int (*compar) (const void *, const void *)" -.Ft void * -.Fn tsearch "const void *key" "void **rootp" "int (*compar) (const void *, const void *)" +.Fn tdelete "const void * restrict key" "posix_tnode ** restrict rootp" "int (*compar) (const void *, const void *)" +.Ft posix_tnode * +.Fn tfind "const void *key" "posix_tnode * const *rootp" "int (*compar) (const void *, const void *)" +.Ft posix_tnode * +.Fn tsearch "const void *key" "posix_tnode **rootp" "int (*compar) (const void *, const void *)" .Ft void -.Fn twalk "const void *root" "void (*action) (const void *, VISIT, int)" +.Fn twalk "const posix_tnode *root" "void (*action) (const posix_tnode *, VISIT, int)" .Sh DESCRIPTION The .Fn tdelete , @@ -134,3 +134,18 @@ function returns no value. .Xr bsearch 3 , .Xr hsearch 3 , .Xr lsearch 3 +.Sh STANDARDS +These functions conform to +.St -p1003.1-2008 . +.Pp +The +.Fa posix_tnode +type is not part of +.St -p1003.1-2008 , +but is expected to be standardized by future versions of the standard. +It is defined as +.Fa void +for source-level compatibility. +Using +.Fa posix_tnode +makes distinguishing between nodes and keys easier. diff --git a/lib/libc/stdlib/tsearch.c b/lib/libc/stdlib/tsearch.c index b96a27562670..a15c2c20517b 100644 --- a/lib/libc/stdlib/tsearch.c +++ b/lib/libc/stdlib/tsearch.c @@ -32,18 +32,17 @@ __FBSDID("$FreeBSD$"); #include "tsearch_path.h" -void * -tsearch(const void *key, void **rootp, +posix_tnode * +tsearch(const void *key, posix_tnode **rootp, int (*compar)(const void *, const void *)) { struct path path; - node_t *root, **base, **leaf, *result, *n, *x, *y, *z; + posix_tnode **leaf, *result, *n, *x, *y, *z; int cmp; /* POSIX requires that tsearch() returns NULL if rootp is NULL. */ if (rootp == NULL) - return (NULL); - root = *rootp; + return (NULL); /* * Find the leaf where the new key needs to be inserted. Return @@ -52,8 +51,7 @@ tsearch(const void *key, void **rootp, * balances. */ path_init(&path); - base = &root; - leaf = &root; + leaf = rootp; while (*leaf != NULL) { if ((*leaf)->balance != 0) { /* @@ -62,9 +60,9 @@ tsearch(const void *key, void **rootp, * need to perform any rotations above this * point. In this case rotations are always * capable of keeping the subtree in balance. - * Make this the base node and reset the path. + * Make this the root node and reset the path. */ - base = leaf; + rootp = leaf; path_init(&path); } cmp = compar(key, (*leaf)->key); @@ -75,7 +73,7 @@ tsearch(const void *key, void **rootp, path_taking_right(&path); leaf = &(*leaf)->rlink; } else { - return (&(*leaf)->key); + return (*leaf); } } @@ -94,7 +92,7 @@ tsearch(const void *key, void **rootp, * have a balance of zero, meaning that these nodes will not get * out of balance. */ - for (n = *base; n != *leaf;) { + for (n = *rootp; n != *leaf;) { if (path_took_left(&path)) { n->balance += 1; n = n->llink; @@ -106,10 +104,10 @@ tsearch(const void *key, void **rootp, /* * Adjusting the balances may have pushed the balance of the - * base node out of range. Perform a rotation to bring the + * root node out of range. Perform a rotation to bring the * balance back in range. */ - x = *base; + x = *rootp; if (x->balance > 1) { y = x->llink; if (y->balance < 0) { @@ -129,7 +127,7 @@ tsearch(const void *key, void **rootp, z->llink = y; x->llink = z->rlink; z->rlink = x; - *base = z; + *rootp = z; x->balance = z->balance > 0 ? -1 : 0; y->balance = z->balance < 0 ? 1 : 0; @@ -146,7 +144,7 @@ tsearch(const void *key, void **rootp, */ x->llink = y->rlink; y->rlink = x; - *base = y; + *rootp = y; x->balance = 0; y->balance = 0; @@ -165,12 +163,12 @@ tsearch(const void *key, void **rootp, * / \ A B C D * B C */ - node_t *z = y->llink; + posix_tnode *z = y->llink; x->rlink = z->llink; z->llink = x; y->llink = z->rlink; z->rlink = y; - *base = z; + *rootp = z; x->balance = z->balance < 0 ? 1 : 0; y->balance = z->balance > 0 ? -1 : 0; @@ -187,7 +185,7 @@ tsearch(const void *key, void **rootp, */ x->rlink = y->llink; y->llink = x; - *base = y; + *rootp = y; x->balance = 0; y->balance = 0; @@ -195,6 +193,5 @@ tsearch(const void *key, void **rootp, } /* Return the new entry. */ - *rootp = root; - return (&result->key); + return (result); } diff --git a/lib/libc/stdlib/twalk.c b/lib/libc/stdlib/twalk.c index 7acee414d11f..4f999b4c0a48 100644 --- a/lib/libc/stdlib/twalk.c +++ b/lib/libc/stdlib/twalk.c @@ -4,8 +4,6 @@ * Tree search generalized from Knuth (6.2.2) Algorithm T just like * the AT&T man page says. * - * The node_t structure is for internal use only, lint doesn't grok it. - * * Written by reading the System V Interface Definition, not the code. * * Totally public domain. @@ -23,12 +21,11 @@ __FBSDID("$FreeBSD$"); #include #include -typedef void (*cmp_fn_t)(const void *, VISIT, int); +typedef void (*cmp_fn_t)(const posix_tnode *, VISIT, int); /* Walk the nodes of a tree */ static void -trecurse(const node_t *root, /* Root of the tree to be walked */ - cmp_fn_t action, int level) +trecurse(const posix_tnode *root, cmp_fn_t action, int level) { if (root->llink == NULL && root->rlink == NULL) @@ -46,7 +43,7 @@ trecurse(const node_t *root, /* Root of the tree to be walked */ /* Walk the nodes of a tree */ void -twalk(const void *vroot, cmp_fn_t action) /* Root of the tree to be walked */ +twalk(const posix_tnode *vroot, cmp_fn_t action) { if (vroot != NULL && action != NULL) trecurse(vroot, action, 0); diff --git a/lib/libc/tests/stdio/printbasic_test.c b/lib/libc/tests/stdio/printbasic_test.c index bebb73427bb3..7f7c6cbbd65c 100644 --- a/lib/libc/tests/stdio/printbasic_test.c +++ b/lib/libc/tests/stdio/printbasic_test.c @@ -124,10 +124,10 @@ ATF_TC_BODY(int_within_limits, tc) testfmt(S_ULONGMAX, "%lu", ULONG_MAX); testfmt("-1", "%lld", (long long)-1); - testfmt(S_ULONGMAX, "%lu", ULLONG_MAX); + testfmt(S_ULLONGMAX, "%llu", ULLONG_MAX); testfmt("-1", "%d", -1); - testfmt(S_UINT32MAX, "%lu", UINT32_MAX); + testfmt(S_UINT32MAX, "%u", UINT32_MAX); testfmt("-1", "%hd", -1); testfmt("65535", "%hu", USHRT_MAX); diff --git a/lib/libc/tests/stdlib/tsearch_test.c b/lib/libc/tests/stdlib/tsearch_test.c index b08fd94bc63e..88c62f580336 100644 --- a/lib/libc/tests/stdlib/tsearch_test.c +++ b/lib/libc/tests/stdlib/tsearch_test.c @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); /* Validates the integrity of an AVL tree. */ static inline unsigned int -tnode_assert(const node_t *n) +tnode_assert(const posix_tnode *n) { unsigned int height_left, height_right; int balance; @@ -79,7 +79,7 @@ ATF_TC_BODY(tsearch_test, tc) keys[i] = i; /* Apply random operations on a binary tree and check the results. */ - void *root = NULL; + posix_tnode *root = NULL; bool present[NKEYS] = {}; for (int i = 0; i < NKEYS * 10; ++i) { int key = nrand48(random_state) % NKEYS; diff --git a/lib/libdevdctl/consumer.cc b/lib/libdevdctl/consumer.cc index e76989473599..a9949a6f269a 100644 --- a/lib/libdevdctl/consumer.cc +++ b/lib/libdevdctl/consumer.cc @@ -108,11 +108,9 @@ Consumer::ConnectToDevd() strlcpy(devdAddr.sun_path, s_devdSockPath, sizeof(devdAddr.sun_path)); sLen = SUN_LEN(&devdAddr); - m_devdSockFD = socket(AF_UNIX, SOCK_SEQPACKET, 0); + m_devdSockFD = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0); if (m_devdSockFD == -1) err(1, "Unable to create socket"); - if (fcntl(m_devdSockFD, F_SETFL, O_NONBLOCK) < 0) - err(1, "fcntl"); result = connect(m_devdSockFD, reinterpret_cast(&devdAddr), sLen); diff --git a/lib/libefi/Makefile b/lib/libefi/Makefile deleted file mode 100644 index d9862f061899..000000000000 --- a/lib/libefi/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# $FreeBSD$ - -.include - -PACKAGE=lib${LIB} -LIB= efi -SHLIB_MAJOR= 1 - -SRCS= libefi.c \ - efi_getvar.c \ - efi_nextvarname.c \ - efi_setvar.c - -CFLAGS+= -I${.CURDIR} - -INCS= libefi.h - -MAN+= libefi.3 -MLINKS+=libefi.3 efi_getvar.3 \ - libefi.3 efi_nextvarname.3 \ - libefi.3 efi_setvar.3 - -.include diff --git a/lib/libefi/efi_getvar.c b/lib/libefi/efi_getvar.c deleted file mode 100644 index 97e842e7d526..000000000000 --- a/lib/libefi/efi_getvar.c +++ /dev/null @@ -1,68 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include "libefi_int.h" - -/* - * EFI_STATUS - * GetVariable( - * IN CHAR16 *VariableName, - * IN EFI_GUID *VendorGuid, - * OUT UINT32 *Attributes OPTIONAL, - * IN OUT UINTN *DataSize, - * OUT VOID *Data - * ); - */ - -int -efi_getvar(char *name, uuid_t *vendor, uint32_t *attrib, size_t *datasize, - void *data) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = 0; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.datasize = *datasize; - req.data = data; - req.access = IODEV_EFIVAR_GETVAR; - error = libefi_efivar(&req); - *datasize = req.datasize; - if (!error && attrib != NULL) - *attrib = req.attrib; - free(req.name); - return (error); -} diff --git a/lib/libefi/efi_nextvarname.c b/lib/libefi/efi_nextvarname.c deleted file mode 100644 index e07659fd74f5..000000000000 --- a/lib/libefi/efi_nextvarname.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include "libefi_int.h" - -/* - * EFI_STATUS - * GetNextVariableName( - * IN OUT UINTN *VariableNameSize, - * IN OUT CHAR16 *VariableName, - * IN OUT EFI_GUID *VendorGuid - * ); - */ - -int -efi_nextvarname(size_t *namesize, char *name, uuid_t *vendor) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = *namesize; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.access = IODEV_EFIVAR_NEXTNAME; - error = libefi_efivar(&req); - *namesize = req.namesize; - if (!error) { - error = libefi_ucs2_to_utf8(req.name, namesize, name); - if (!error) - *vendor = req.vendor; - } - free(req.name); - return (error); -} diff --git a/lib/libefi/efi_setvar.c b/lib/libefi/efi_setvar.c deleted file mode 100644 index be43694f2104..000000000000 --- a/lib/libefi/efi_setvar.c +++ /dev/null @@ -1,66 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include "libefi_int.h" - -/* - * EFI_STATUS - * SetVariable( - * IN CHAR16 *VariableName, - * IN EFI_GUID *VendorGuid, - * IN UINT32 Attributes, - * IN UINTN DataSize, - * IN VOID *Data - * ); - */ - -int -efi_setvar(char *name, uuid_t *vendor, uint32_t attrib, size_t datasize, - void *data) -{ - struct iodev_efivar_req req; - int error; - - req.namesize = 0; - error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name); - if (error) - return (error); - - req.vendor = *vendor; - req.attrib = attrib; - req.datasize = datasize; - req.data = data; - req.access = IODEV_EFIVAR_SETVAR; - error = libefi_efivar(&req); - free(req.name); - return (error); -} diff --git a/lib/libefi/libefi.3 b/lib/libefi/libefi.3 deleted file mode 100644 index e090fd6e711f..000000000000 --- a/lib/libefi/libefi.3 +++ /dev/null @@ -1,143 +0,0 @@ -.\"- -.\" Copyright (c) 2010 Marcel Moolenaar -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 29, 2010 -.Dt LIBEFI 3 -.Os -.Sh NAME -.Nm efi_getvar , efi_nextvarname , efi_setvar -.Nd "interface for accessing the EFI variable services" -.Sh LIBRARY -.Lb libefi -.Sh SYNOPSIS -.In libefi.h -.Ft int -.Fo efi_getvar -.Fa "char *name" "uuid_t *vendor" "uint32_t *attrib" -.Fa "size_t *datasize" "void *data" -.Fc -.Ft int -.Fn efi_nextvarname "size_t *namesize" "char *name" "uuid_t *vendor" -.Ft int -.Fo efi_setvar -.Fa "char *name" "uuid_t *vendor" "uint32_t attrib" -.Fa "size_t datasize" "void *data" -.Fc -.Sh DESCRIPTION -The -.Nm libefi -library provides access to a select set of the runtime services of the -Extensible Firmware Interface (EFI). -.Pp -The -.Fn efi_nextvarname -function is used to enumerate the variables. -The -.Fa namesize -parameter needs to be set to the size of the buffer pointed to by -.Fa name . -On return, -.Fa namesize -is set to the length of the variable name (including the terminating -.Ql \e0 ) -irrespective of whether the buffer was big enough. -The buffer pointed to by -.Fa name -contains the full or partial variable name on return. -Only on successful completion of the request is the -.Fa vendor -updated. -The values returned should be passed to successive calls to -.Fn efi_nextvarname -until all variables have been enumerated. -.Pp -The variable name and vendor as returned by -.Fn efi_nextvarname -can be passed to -.Fn efi_getvar -to obtain the value and attribute of the variable. -The buffer that is to contain the value is specified by -.Fa data -and the size of the buffer is given by -.Fa datasize . -The attribute pointed to by -.Fa attrib -consists of the bit values defined by the EFI specification. -.Pp -Variables can be created, modified and deleted using the -.Fn efi_setvar -function. -All new variables must be non-volatile and runtime accessible in -order for the request to succeed. -Note that for runtime accessable variables the boottime accessable bit must -be set as well. -To delete a variable, set -.Fa datasize -to 0. -.Pp -The vendor UUID is used to avoid collisions between variable names of -different vendors. -Variables created for use by -.Fx -should use the -.Dv EFI_FREEBSD_VARIABLE -UUID as defined in the -.In libefi.h -header file. -.Sh RETURN VALUES -Upon successful completion, these functions return 0. -Otherwise, the error number is returned. -These functions will fail if: -.Bl -tag -width Er -.It Bq Er EACCES -Insufficient permissions to access the EFI services. -.It Bq Er EILSEQ -The variable name is not in UTF-8. -.It Bq Er EINVAL -The request has invalid parameters. -.It Bq Er ENOENT -The variable does not exist or no more variables exist. -.It Bq Er ENOMEM -Temporary storage could not be allocated. -.It Bq Er EOVERFLOW -The variable name is too long or the data is too big to fit in -the buffer provided. -.El -.Sh SEE ALSO -.Xr errno 2 , -.Xr uuid 3 -.Sh HISTORY -The -.Nm libefi -library first appeared in -.Fx 9.0 -for the ia64 architecture. -.Sh AUTHORS -The -.Nm libefi -library and this manual page were written by -.An Marcel Moolenaar Aq Mt marcel@FreeBSD.org . diff --git a/lib/libefi/libefi.h b/lib/libefi/libefi.h deleted file mode 100644 index 56d18ac9074a..000000000000 --- a/lib/libefi/libefi.h +++ /dev/null @@ -1,57 +0,0 @@ -/*- - * Copyright (c) 2010 Marcel Moolenaar - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LIBEFI_H_ -#define _LIBEFI_H_ - -#include -#include -#include - -/* Attributes. */ -#define EFI_ATTR_NV 0x0001 /* Variable stored in NVRAM. */ -#define EFI_ATTR_BS 0x0002 /* Boot services accessable. */ -#define EFI_ATTR_RT 0x0004 /* Runtime accessable. */ -#define EFI_ATTR_HR 0x0008 /* Hardware error record. */ -#define EFI_ATTR_WR 0x0010 /* Authenticated write access. */ - -/* Vendor for architecturally defined variables. */ -#define EFI_GLOBAL_VARIABLE \ - {0x8be4df61,0x93ca,0x11d2,0xaa,0x0d,{0x00,0xe0,0x98,0x03,0x2b,0x8c}} - -/* Vendor for FreeBSD-specific variables. */ -#define EFI_FREEBSD_VARIABLE \ - {0x13c32014,0x0c9c,0x11df,0xa2,0x38,{0x00,0x17,0xa4,0xab,0x91,0x2d}} - -__BEGIN_DECLS -int efi_getvar (char *, uuid_t *, uint32_t *, size_t *, void *); -int efi_nextvarname (size_t *, char *, uuid_t *); -int efi_setvar (char *, uuid_t *, uint32_t, size_t, void *); -__END_DECLS - -#endif /* _LIBEFI_H_ */ diff --git a/lib/libefivar/Makefile b/lib/libefivar/Makefile new file mode 100644 index 000000000000..c3ad3615e9d6 --- /dev/null +++ b/lib/libefivar/Makefile @@ -0,0 +1,53 @@ +# Copyright 1998 Juniper Networks, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +.include + +PACKAGE=lib${LIB} +LIB= efivar +SRCS= efivar.c libefivar.c +INCS= efivar.h +SHLIB_MAJOR= 1 +MAN= efivar.3 + +MLINKS+=efivar.3 efi_set_variables_supported.3 \ + efivar.3 efi_del_variable.3 \ + efivar.3 efi_get_variable.3 \ + efivar.3 efi_get_variable_attributes.3 \ + efivar.3 efi_get_variable_size.3 \ + efivar.3 efi_append_variable.3 \ + efivar.3 efi_set_variable.3 \ + efivar.3 efi_get_next_variable_name.3 \ + efivar.3 efi_str_to_guid.3 \ + efivar.3 efi_guid_to_str.3 \ + efivar.3 efi_name_to_guid.3 \ + efivar.3 efi_guid_to_name.3 \ + efivar.3 efi_guid_to_symbol.3 \ + efivar.3 libefivar.3 + +WARNS?= 9 + +.include diff --git a/lib/libefivar/efivar.3 b/lib/libefivar/efivar.3 new file mode 100644 index 000000000000..4d1d50470467 --- /dev/null +++ b/lib/libefivar/efivar.3 @@ -0,0 +1,98 @@ +.\" Copyright 2016 Netflix, Inc. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 14, 2016 +.Dt LIBEFIVAR 3 +.Os +.Sh NAME +.Nm libefivar +.Nd EFI Non Volatile Variable Suppoert +.Sh SYNOPSIS +.In efivar.h +.Ft int +.Fn efi_append_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes" +.Ft int +.Fn efi_del_variable "efi_guid_t guid" "const char *name" +.Ft int +.Fn efi_get_variable "efi_guid_t guid" "const char *name" "void **data" "ssize_t *data_size" "uint32_t *attributes" +.Ft int +.Fn efi_get_variable_attributes "efi_guid_t guid" "const char *name" "uint32_t *attributes" +.Ft int +.Fn efi_get_variable_size "efi_guid_t guid" "const char *name" "size_t *size" +.Ft int +.Fn efi_get_next_variable_name "efi_guid_t **guid" "char **name" +.Ft int +.Fn efi_guid_to_name "efi_guid_t *guid" "char **name" +.Ft int +.Fn efi_guid_to_symbol "efi_guid_t *guid" "char **symbol" +.Ft int +.Fn efi_guid_to_str "const efi_guid_t *guid" "char **sp" +.Ft int +.Fn efi_name_to_guid "const char *name" "efi_guid_t *guid" +.Ft int +.Fn efi_set_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes" +.Ft int +.Fn efi_str_to_guid "const char *s" "efi_guid_t *guid"; +.Ft int +.Fn efi_variables_supported "void"; +.Sh DESCRIPTION +The +.Nm +library implements access to EFI Variables via the EFI Runtime +Serivces. +All char * strings are converted to 16-bit UTF strings before passing +them to EFI. +.Pp +.Fn efi_variables_supported +returns non-zero if the current machine supports setting of EFI firmware +variables and the kernel support for doing so is present. +Otherwise zero is returned. +.Pp +.Fn efi_del_variable +deletes the EFI variable selected by +.Dv guid +and +.Dv name . +.Pp +.Fn efi_get_variable +.Fn efi_get_variable_attributes +.Fn efi_get_variable_size +.Fn efi_append_variable +.Fn efi_set_variable +.Fn efi_get_next_variable_name +.Fn efi_str_to_guid +.Fn efi_guid_to_str +.Fn efi_name_to_guid +.Fn efi_guid_to_name +.Fn efi_guid_to_symbol +This function is not actually implemented. +.Sh BUGS +No facilities exist to process the strings as native UTF. +This is a limitation in the Linux libefivar library interface. +.Sh AUTHORS +.An -nosplit +This software was originally written by +.An Warner Losh . diff --git a/lib/libefivar/efivar.c b/lib/libefivar/efivar.c new file mode 100644 index 000000000000..4d485287a6d1 --- /dev/null +++ b/lib/libefivar/efivar.c @@ -0,0 +1,380 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libefivar_int.h" + +static int efi_fd = -2; + +#define Z { 0, 0, 0, 0, 0, { 0 } } + +const efi_guid_t efi_guid_empty = Z; + +static struct uuid_table +{ + const char *uuid_str; + const char *name; + efi_guid_t guid; +} guid_tbl [] = +{ + { "00000000-0000-0000-0000-000000000000", "zero", Z }, + { "093e0fae-a6c4-4f50-9f1b-d41e2b89c19a", "sha512", Z }, + { "0abba7dc-e516-4167-bbf5-4d9d1c739416", "redhat", Z }, + { "0b6e5233-a65c-44c9-9407-d9ab83bfc8bd", "sha224", Z }, + { "126a762d-5758-4fca-8531-201a7f57f850", "lenovo_boot_menu", Z }, + { "3bd2a492-96c0-4079-b420-fcf98ef103ed", "x509_sha256", Z }, + { "3c5766e8-269c-4e34-aa14-ed776e85b3b6", "rsa2048", Z }, + { "3CC24E96-22C7-41D8-8863-8E39DCDCC2CF", "lenovo", Z }, + { "3f7e615b-0d45-4f80-88dc-26b234958560", "lenovo_diag", Z }, + { "446dbf63-2502-4cda-bcfa-2465d2b0fe9d", "x509_sha512", Z }, + { "4aafd29d-68df-49ee-8aa9-347d375665a7", "pkcs7_cert", Z }, + { "605dab50-e046-4300-abb6-3dd810dd8b23", "shim", Z }, + { "665d3f60-ad3e-4cad-8e26-db46eee9f1b5", "lenovo_rescue", Z }, + { "67f8444f-8743-48f1-a328-1eaab8736080", "rsa2048_sha1", Z }, + { "7076876e-80c2-4ee6-aad2-28b349a6865b", "x509_sha384", Z }, + { "721c8b66-426c-4e86-8e99-3457c46ab0b9", "lenovo_setup", Z }, + { "77fa9abd-0359-4d32-bd60-28f4e78f784b", "microsoft", Z }, + { "7FACC7B6-127F-4E9C-9C5D-080F98994345", "lenovo_2", Z }, + { "826ca512-cf10-4ac9-b187-be01496631bd", "sha1", Z }, + { "82988420-7467-4490-9059-feb448dd1963", "lenovo_me_config", Z }, + { "8be4df61-93ca-11d2-aa0d-00e098032b8c", "global", Z }, + { "a5c059a1-94e4-4aa7-87b5-ab155c2bf072", "x509_cert", Z }, + { "a7717414-c616-4977-9420-844712a735bf", "rsa2048_sha256_cert", Z }, + { "a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380", "lenovo_diag_splash", Z }, + { "ade9e48f-9cb8-98e6-31af-b4e6009e2fe3", "redhat_2", Z }, + { "bc7838d2-0f82-4d60-8316-c068ee79d25b", "lenovo_msg", Z }, + { "c1c41626-504c-4092-aca9-41f936934328", "sha256", Z }, + { "c57ad6b7-0515-40a8-9d21-551652854e37", "shell", Z }, + { "d719b2cb-3d3a-4596-a3bc-dad00e67656f", "security", Z }, + { "e2b36190-879b-4a3d-ad8d-f2e7bba32784", "rsa2048_sha256", Z }, + { "ff3e5307-9fd0-48c9-85f1-8ad56c701e01", "sha384", Z }, + { "f46ee6f4-4785-43a3-923d-7f786c3c8479", "lenovo_startup_interrupt", Z }, + { "ffffffff-ffff-ffff-ffff-ffffffffffff", "zzignore-this-guid", Z }, +}; +#undef Z + +static void +efi_guid_tbl_compile(void) +{ + size_t i; + uint32_t status; + + for (i = 0; i < nitems(guid_tbl); i++) { + uuid_from_string(guid_tbl[i].uuid_str, &guid_tbl[i].guid, + &status); + /* all f's is a bad version, so ignore that error */ + if (status != uuid_s_ok && status != uuid_s_bad_version) + fprintf(stderr, "Can't convert %s to a uuid for %s: %d\n", + guid_tbl[i].uuid_str, guid_tbl[i].name, (int)status); + } +} + +static int +efi_open_dev(void) +{ + + if (efi_fd == -2) + efi_fd = open("/dev/efi", O_RDWR); + if (efi_fd < 0) + efi_fd = -1; + else + efi_guid_tbl_compile(); + return (efi_fd); +} + +static void +efi_var_reset(struct efi_var_ioc *var) +{ + var->name = NULL; + var->namesize = 0; + memset(&var->vendor, 0, sizeof(var->vendor)); + var->attrib = 0; + var->data = NULL; + var->datasize = 0; +} + +static int +rv_to_linux_rv(int rv) +{ + if (rv == 0) + rv = 1; + else if (errno == ENOENT) { + rv = 0; + errno = 0; + } else + rv = -errno; + return (rv); +} + +int +efi_append_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes) +{ + + return efi_set_variable(guid, name, data, data_size, + attributes | EFI_VARIABLE_APPEND_WRITE, 0); +} + +int +efi_del_variable(efi_guid_t guid, const char *name) +{ + + /* data_size of 0 deletes the variable */ + return efi_set_variable(guid, name, NULL, 0, 0, 0); +} + +int +efi_get_variable(efi_guid_t guid, const char *name, + uint8_t **data, size_t *data_size, uint32_t *attributes) +{ + struct efi_var_ioc var; + int rv; + static uint8_t buf[1024*32]; + + if (efi_open_dev() == -1) + return -1; + + efi_var_reset(&var); + rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize); + if (rv != 0) + goto errout; + var.vendor = guid; + var.data = buf; + var.datasize = sizeof(buf); + rv = ioctl(efi_fd, EFIIOC_VAR_GET, &var); + if (data_size != NULL) + *data_size = var.datasize; + if (data != NULL) + *data = buf; + if (attributes != NULL) + *attributes = var.attrib; +errout: + free(var.name); + + return rv_to_linux_rv(rv); +} + +int +efi_get_variable_attributes(efi_guid_t guid, const char *name, + uint32_t *attributes) +{ + /* Make sure this construct works -- I think it will fail */ + + return efi_get_variable(guid, name, NULL, NULL, attributes); +} + +int +efi_get_variable_size(efi_guid_t guid, const char *name, + size_t *size) +{ + + /* XXX check to make sure this matches the linux value */ + + *size = 0; + return efi_get_variable(guid, name, NULL, size, NULL); +} + +int +efi_get_next_variable_name(efi_guid_t **guid, char **name) +{ + struct efi_var_ioc var; + int rv; + static efi_char *buf; + static size_t buflen = 256 * sizeof(efi_char); + static efi_guid_t retguid; + size_t size; + + if (efi_open_dev() == -1) + return -1; + + if (buf == NULL) + buf = malloc(buflen); + +again: + efi_var_reset(&var); + var.name = buf; + var.namesize = buflen; + if (*name == NULL) { + *buf = 0; + /* GUID zeroed in var_reset */ + } else { + rv = libefi_utf8_to_ucs2(*name, &var.name, &size); + if (rv != 0) + goto errout; + var.vendor = **guid; + } + rv = ioctl(efi_fd, EFIIOC_VAR_NEXT, &var); + if (rv == 0 && var.name == NULL) { + /* + * oops, too little space. Try again. + */ + void *new = realloc(buf, buflen); + buflen = var.namesize; + if (new == NULL) { + rv = -1; + errno = ENOMEM; + goto done; + } + buf = new; + goto again; + } + + if (rv == 0) { + *name = NULL; /* XXX */ + var.name[var.namesize / sizeof(efi_char)] = 0; /* EFI doesn't NUL terminate */ + rv = libefi_ucs2_to_utf8(var.name, name); + if (rv != 0) + goto errout; + retguid = var.vendor; + *guid = &retguid; + } +errout: + + /* XXX The linux interface expects name to be a static buffer -- fix or leak memory? */ +done: + return (rv_to_linux_rv(rv)); +} + +int +efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2) +{ + uint32_t status; + + return uuid_compare(guid1, guid2, &status); +} + +int +efi_guid_is_zero(const efi_guid_t *guid) +{ + uint32_t status; + + return uuid_is_nil(guid, &status); +} + +int +efi_guid_to_name(efi_guid_t *guid, char **name) +{ + size_t i; + uint32_t status; + + for (i = 0; i < nitems(guid_tbl); i++) { + if (uuid_equal(guid, &guid_tbl[i].guid, &status)) { + *name = strdup(guid_tbl[i].name); + return (0); + } + } + return (efi_guid_to_str(guid, name)); +} + +int +efi_guid_to_symbol(efi_guid_t *guid __unused, char **symbol __unused) +{ + + /* + * Unsure what this is used for, efibootmgr doesn't use it. + * Leave unimplemented for now. + */ + return -1; +} + +int +efi_guid_to_str(const efi_guid_t *guid, char **sp) +{ + uint32_t status; + + /* knows efi_guid_t is a typedef of uuid_t */ + uuid_to_string(guid, sp, &status); + + return (status == uuid_s_ok ? 0 : -1); +} + +int +efi_name_to_guid(const char *name, efi_guid_t *guid) +{ + size_t i; + + for (i = 0; i < nitems(guid_tbl); i++) { + if (strcmp(name, guid_tbl[i].name) == 0) { + *guid = guid_tbl[i].guid; + return (0); + } + } + return (efi_str_to_guid(name, guid)); +} + +int +efi_set_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode __unused) +{ + struct efi_var_ioc var; + int rv; + + if (efi_open_dev() == -1) + return -1; + + efi_var_reset(&var); + rv = libefi_utf8_to_ucs2(name, &var.name, &var.namesize); + if (rv != 0) + goto errout; + var.vendor = guid; + var.data = data; + var.datasize = data_size; + var.attrib = attributes; + rv = ioctl(efi_fd, EFIIOC_VAR_SET, &var); +errout: + free(var.name); + + return rv; +} + +int +efi_str_to_guid(const char *s, efi_guid_t *guid) +{ + uint32_t status; + + /* knows efi_guid_t is a typedef of uuid_t */ + uuid_from_string(s, guid, &status); + + return (status == uuid_s_ok ? 0 : -1); +} + +int +efi_variables_supported(void) +{ + + return efi_open_dev() != -1; +} diff --git a/lib/libefivar/efivar.h b/lib/libefivar/efivar.h new file mode 100644 index 000000000000..84301f0878aa --- /dev/null +++ b/lib/libefivar/efivar.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _EFIVAR_H_ +#define _EFIVAR_H_ + +#include +#include +#include +#include + +/* Shoud these be elsewhere ? */ +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS \ + 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#if 0 /* todo */ +#define EFI_VARIABLE_HAS_AUTH_HEADER +#define EFI_VARIABLE_HAS_SIGNATURE +#endif + + +typedef uuid_t efi_guid_t; +#if BYTE_ORDER == LITTLE_ENDIAN +#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \ + ((efi_guid_t) {(a), (b), (c), (d) >> 8, (d) & 0xff, \ + { (e0), (e1), (e2), (e3), (e4), (e5) }}) +#else +#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \ + ((efi_guid_t) {(a), (b), (c), (d) & 0xff, (d) >> 8, \ + { (e0), (e1), (e2), (e3), (e4), (e5) }}) +#endif + +#define EFI_GLOBAL_GUID EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa0d, \ + 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c) + +int efi_append_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes); +int efi_del_variable(efi_guid_t guid, const char *name); +int efi_get_variable(efi_guid_t guid, const char *name, + uint8_t **data, size_t *data_size, uint32_t *attributes); +int efi_get_variable_attributes(efi_guid_t guid, const char *name, + uint32_t *attributes); +int efi_get_variable_size(efi_guid_t guid, const char *name, size_t *size); +int efi_get_next_variable_name(efi_guid_t **guid, char **name); +int efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2); +int efi_guid_is_zero(const efi_guid_t *guid1); +int efi_guid_to_name(efi_guid_t *guid, char **name); +int efi_guid_to_symbol(efi_guid_t *guid, char **symbol); +int efi_guid_to_str(const efi_guid_t *guid, char **sp); +int efi_name_to_guid(const char *name, efi_guid_t *guid); +int efi_set_variable(efi_guid_t guid, const char *name, + uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode); +int efi_str_to_guid(const char *s, efi_guid_t *guid); +int efi_variables_supported(void); + +extern const efi_guid_t efi_guid_empty; + +/* Stubs that are expected, but aren't really used */ +static inline int +efi_error_get(unsigned int n __unused, char ** const fn __unused, + char ** const func __unused, int *line __unused, + char ** const msg __unused, int *err __unused) +{ + return 0; +} + +static inline int +efi_error_set(const char *fn __unused, const char *func __unused, + int line __unused, int err __unused, const char *fmt __unused, ...) +{ + return 0; +} + +static inline void +efi_error_clear(void) +{ +} + +static inline int +efi_error(const char *fmt __unused, ...) +{ + return 0; +} + +static inline int +efi_error_val(int val __unused, const char *fmt __unused, ...) +{ + return 0; +} + +#endif /* _EFIVAR_H_ */ diff --git a/lib/libefi/libefi.c b/lib/libefivar/libefivar.c similarity index 65% rename from lib/libefi/libefi.c rename to lib/libefivar/libefivar.c index c65784f57132..951c484f5e3a 100644 --- a/lib/libefi/libefi.c +++ b/lib/libefivar/libefivar.c @@ -27,86 +27,105 @@ #include __FBSDID("$FreeBSD$"); -#include #include -#include +#include #include #include #include #include +#include +#include -#include "libefi_int.h" +#include "libefivar_int.h" -static int __iofd = -1; +#include -static void -iodev_fd_close(void) +/* + * If nm were converted to utf8, what what would strlen + * return on the resulting string? + */ +static size_t +utf8_len_of_ucs2(const efi_char *nm) { + size_t len; + efi_char c; - close(__iofd); -} + len = 0; + while (*nm) { + c = *nm++; + if (c > 0x7ff) + len += 3; + else if (c > 0x7f) + len += 2; + else + len++; + } -static int -iodev_fd(int *fd) -{ - - *fd = __iofd; - if (__iofd != -1) - return (0); - - __iofd = open("/dev/io", O_RDWR); - if (__iofd == -1) - return (errno); - - atexit(iodev_fd_close); - *fd = __iofd; - return (0); + return (len); } int -libefi_ucs2_to_utf8(u_short *nm, size_t *szp, char *name) +libefi_ucs2_to_utf8(const efi_char *nm, char **name) { size_t len, sz; - u_short c; + efi_char c; + char *cp; + int freeit = *name == NULL; + sz = utf8_len_of_ucs2(nm) + 1; len = 0; - sz = *szp; + if (*name != NULL) + cp = *name; + else + cp = *name = malloc(sz); + if (*name == NULL) + return (ENOMEM); + while (*nm) { c = *nm++; if (c > 0x7ff) { if (len++ < sz) - *name++ = 0xE0 | (c >> 12); + *cp++ = (char)(0xE0 | (c >> 12)); if (len++ < sz) - *name++ = 0x80 | ((c >> 6) & 0x3f); + *cp++ = (char)(0x80 | ((c >> 6) & 0x3f)); if (len++ < sz) - *name++ = 0x80 | (c & 0x3f); + *cp++ = (char)(0x80 | (c & 0x3f)); } else if (c > 0x7f) { if (len++ < sz) - *name++ = 0xC0 | ((c >> 6) & 0x1f); + *cp++ = (char)(0xC0 | ((c >> 6) & 0x1f)); if (len++ < sz) - *name++ = 0x80 | (c & 0x3f); + *cp++ = (char)(0x80 | (c & 0x3f)); } else { if (len++ < sz) - *name++ = (c & 0x7f); + *cp++ = (char)(c & 0x7f); } } - if (len++ < sz) - *name++ = 0; - *szp = len; - return ((len <= sz) ? 0 : EOVERFLOW); + if (len >= sz) { + /* Absent bugs, we'll never return EOVERFLOW */ + if (freeit) + free(*name); + return (EOVERFLOW); + } + *cp++ = '\0'; + + return (0); } int -libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) +libefi_utf8_to_ucs2(const char *name, efi_char **nmp, size_t *len) { - u_short *nm; + efi_char *nm; size_t sz; uint32_t ucs4; int c, bytes; + int freeit = *nmp == NULL; - *szp = sz = (*szp == 0) ? strlen(name) * 2 + 2 : *szp; - *nmp = nm = malloc(sz); + sz = strlen(name) * 2 + 2; + if (*nmp == NULL) + *nmp = malloc(sz); + nm = *nmp; + *len = sz; ucs4 = 0; bytes = 0; @@ -119,7 +138,8 @@ libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) if ((c & 0xc0) != 0x80) { /* Initial characters. */ if (bytes != 0) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } if ((c & 0xf8) == 0xf0) { @@ -141,36 +161,28 @@ libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp) ucs4 = (ucs4 << 6) + (c & 0x3f); bytes--; } else if (bytes == 0) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } } if (bytes == 0) { if (ucs4 > 0xffff) { - free(nm); + if (freeit) + free(nm); return (EILSEQ); } - *nm++ = (u_short)ucs4; + *nm++ = (efi_char)ucs4; sz -= 2; } } if (sz < 2) { - free(nm); + if (freeit) + free(nm); return (EDOOFUS); } + sz -= 2; *nm = 0; + *len -= sz; return (0); } - -int -libefi_efivar(struct iodev_efivar_req *req) -{ - int error, fd; - - error = iodev_fd(&fd); - if (!error) - error = (ioctl(fd, IODEV_EFIVAR, req) == -1) ? errno : 0; - if (!error) - error = req->result; - return (error); -} diff --git a/lib/libefi/libefi_int.h b/lib/libefivar/libefivar_int.h similarity index 87% rename from lib/libefi/libefi_int.h rename to lib/libefivar/libefivar_int.h index 28ee822bad47..276ab19dcffb 100644 --- a/lib/libefi/libefi_int.h +++ b/lib/libefivar/libefivar_int.h @@ -29,12 +29,7 @@ #ifndef _LIBEFI_INT_H_ #define _LIBEFI_INT_H_ -#include -#include - -int libefi_ucs2_to_utf8(u_short *, size_t *, char *); -int libefi_utf8_to_ucs2(char *, size_t *, u_short **); - -int libefi_efivar(struct iodev_efivar_req *); +int libefi_ucs2_to_utf8(const efi_char *, char **); +int libefi_utf8_to_ucs2(const char *, efi_char **, size_t *); #endif /* _LIBEFI_INT_H_ */ diff --git a/lib/libgcc_eh/Makefile b/lib/libgcc_eh/Makefile new file mode 100644 index 000000000000..04f99d9e85cf --- /dev/null +++ b/lib/libgcc_eh/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.include + +PACKAGE= clibs +LIB= gcc_eh +NO_PIC= +WARNS?= 2 + +.include "Makefile.inc" + +.include diff --git a/lib/libgcc_eh/Makefile.inc b/lib/libgcc_eh/Makefile.inc new file mode 100644 index 000000000000..7321fbea78f9 --- /dev/null +++ b/lib/libgcc_eh/Makefile.inc @@ -0,0 +1,30 @@ +# $FreeBSD$ + +COMPILERRTDIR= ${SRCTOP}/contrib/compiler-rt +UNWINDINCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/include +UNWINDSRCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/src + +CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN + +.PATH: ${COMPILERRTDIR}/lib/builtins +.PATH: ${UNWINDSRCDIR} +SRCS+= gcc_personality_v0.c +SRCS+= int_util.c +SRCS+= Unwind-EHABI.cpp +SRCS+= Unwind-sjlj.c +SRCS+= UnwindLevel1-gcc-ext.c +SRCS+= UnwindLevel1.c +SRCS+= UnwindRegistersRestore.S +SRCS+= UnwindRegistersSave.S +SRCS+= libunwind.cpp + +CFLAGS+= -I${UNWINDINCDIR} -I${.CURDIR} -D_LIBUNWIND_IS_NATIVE_ONLY +.if empty(CXXFLAGS:M-std=*) +CXXFLAGS+= -std=c++11 +.endif +CXXFLAGS+= -fno-rtti +STATIC_CXXFLAGS+= -fvisibility=hidden -fPIC +.if ${MK_DIRDEPS_BUILD} == "yes" +# Avoid dependency on lib/libc++ +CFLAGS+= -I${SRCTOP}/contrib/libc++/include +.endif diff --git a/lib/libgcc_s/Makefile b/lib/libgcc_s/Makefile new file mode 100644 index 000000000000..92fb8c3fb22d --- /dev/null +++ b/lib/libgcc_s/Makefile @@ -0,0 +1,32 @@ +# $FreeBSD$ + +PKG= clibs +SHLIB_NAME= libgcc_s.so.1 + +WARNS?= 2 + +LDFLAGS+= -nodefaultlibs +VERSION_MAP= ${.CURDIR}/Version.map + +.include "../libcompiler_rt/Makefile.inc" +.include "../libgcc_eh/Makefile.inc" + +LIBCSRCDIR= ${SRCTOP}/lib/libc +LIBMSRCDIR= ${SRCTOP}/lib/msun/src +CFLAGS+= -I${LIBCSRCDIR}/include -I${LIBCSRCDIR}/${MACHINE_CPUARCH} +CFLAGS+= -I${LIBMSRCDIR} +.PATH: ${LIBMSRCDIR} +SRCS+= s_fabs.c +SRCS+= s_fabsf.c +SRCS+= s_fabsl.c +SRCS+= s_fmax.c +SRCS+= s_fmaxf.c +SRCS+= s_fmaxl.c +SRCS+= s_logb.c +SRCS+= s_logbf.c +SRCS+= s_logbl.c +SRCS+= s_scalbn.c +SRCS+= s_scalbnf.c +SRCS+= s_scalbnl.c + +.include diff --git a/lib/libgcc_s/Version.map b/lib/libgcc_s/Version.map new file mode 100644 index 000000000000..b592c8746cdc --- /dev/null +++ b/lib/libgcc_s/Version.map @@ -0,0 +1,123 @@ +/* + * $FreeBSD$ + */ + +GCC_3.0 { + __absvdi2; + __absvsi2; + __addvdi3; + __addvsi3; + __ashlti3; + __ashrti3; + __clear_cache; + __cmpti2; + __deregister_frame; + __deregister_frame_info; + __deregister_frame_info_bases; + __divti3; + __ffsdi2; + __ffsti2; + __fixdfti; + __fixsfti; + __fixunsdfdi; + __fixunsdfti; + __fixunssfdi; + __fixunssfti; + __fixunsxfdi; + __fixunsxfti; + __fixxfti; + __floattidf; + __floattisf; + __floattixf; + __lshrti3; + __modti3; + __mulvdi3; + __mulvsi3; + __multi3; + __negti2; + __negvdi2; + __negvsi2; + __register_frame; + __register_frame_info; + __register_frame_info_bases; + __register_frame_info_table; + __register_frame_info_table_bases; + __register_frame_table; + __subvdi3; + __subvsi3; + __ucmpti2; + __udivmodti4; + __udivti3; + __umodti3; + _Unwind_DeleteException; + _Unwind_Find_FDE; + _Unwind_ForcedUnwind; + _Unwind_GetDataRelBase; + _Unwind_GetGR; + _Unwind_GetIP; + _Unwind_GetLanguageSpecificData; + _Unwind_GetRegionStart; + _Unwind_GetTextRelBase; + _Unwind_RaiseException; + _Unwind_Resume; + _Unwind_SetGR; + _Unwind_SetIP; +}; + +GCC_3.3 { + _Unwind_Backtrace; + _Unwind_FindEnclosingFunction; + _Unwind_GetCFA; + _Unwind_Resume_or_Rethrow; +} GCC_3.0; + +GCC_3.3.1 { + __gcc_personality_v0; +} GCC_3.3; + +GCC_3.4 { + __clzdi2; + __clzti2; + __ctzdi2; + __ctzti2; + __paritydi2; + __parityti2; + __popcountdi2; + __popcountti2; +} GCC_3.3.1; + +GCC_3.4.2 { + __enable_execute_stack; +} GCC_3.4; + +GCC_3.4.4 { + __absvti2; + __addvti3; + __mulvti3; + __negvti2; + __subvti3; +} GCC_3.4.2; + +GCC_4.0.0 { + __divdc3; + __divsc3; + __divxc3; + __muldc3; + __mulsc3; + __mulxc3; + __powidf2; + __powisf2; + __powixf2; +} GCC_3.4.4; + +GCC_4.2.0 { + __floatuntidf; + __floatuntisf; + __floatuntixf; + _Unwind_GetIPInfo; +} GCC_4.0.0; + +GCC_4.3.0 { + __bswapdi2; + __bswapsi2; +} GCC_4.2.0; diff --git a/lib/libucl/Makefile b/lib/libucl/Makefile index 1bb9fd2230ee..516b5261a5f5 100644 --- a/lib/libucl/Makefile +++ b/lib/libucl/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -LIBUCL= ${.CURDIR}/../../contrib/libucl +LIBUCL= ${SRCTOP}/contrib/libucl PACKAGE=lib${LIB} LIB= ucl diff --git a/lib/msun/Makefile b/lib/msun/Makefile index ce586d8afed4..69011345a0d6 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -63,8 +63,8 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabsf.c s_fdim.c \ s_finite.c s_finitef.c \ s_floor.c s_floorf.c s_fma.c s_fmaf.c \ - s_fmax.c s_fmaxf.c s_fmaxl.c s_fmin.c \ - s_fminf.c s_fminl.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ + s_fmax.c s_fmaxf.c s_fmin.c \ + s_fminf.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c \ s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_llroundl.c \ s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ @@ -101,9 +101,9 @@ COMMON_SRCS+= e_acoshl.c e_acosl.c e_asinl.c e_atan2l.c e_atanhl.c \ invtrig.c k_cosl.c k_sinl.c k_tanl.c \ s_asinhl.c s_atanl.c s_cbrtl.c s_ceill.c s_cosl.c s_cprojl.c \ s_csqrtl.c s_erfl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \ - s_frexpl.c s_logbl.c s_logl.c s_nanl.c s_nextafterl.c \ - s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c s_scalbnl.c \ - s_sinl.c s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c + s_fmaxl.c s_fminl.c s_frexpl.c s_logbl.c s_logl.c s_nanl.c \ + s_nextafterl.c s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c \ + s_scalbnl.c s_sinl.c s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c .endif # C99 complex functions diff --git a/lib/msun/src/s_fmax.c b/lib/msun/src/s_fmax.c index b51b8655eb8f..77e27bec9bf7 100644 --- a/lib/msun/src/s_fmax.c +++ b/lib/msun/src/s_fmax.c @@ -27,6 +27,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include "fpmath.h" @@ -51,3 +52,7 @@ fmax(double x, double y) return (x > y ? x : y); } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fmax, fmaxl); +#endif diff --git a/lib/msun/src/s_fmin.c b/lib/msun/src/s_fmin.c index 3500c84a1c84..5545ff2fa1c0 100644 --- a/lib/msun/src/s_fmin.c +++ b/lib/msun/src/s_fmin.c @@ -27,6 +27,7 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include "fpmath.h" @@ -51,3 +52,7 @@ fmin(double x, double y) return (x < y ? x : y); } + +#if (LDBL_MANT_DIG == 53) +__weak_reference(fmin, fminl); +#endif diff --git a/release/Makefile.vm b/release/Makefile.vm index 9de384650cbf..1c6a1936058b 100644 --- a/release/Makefile.vm +++ b/release/Makefile.vm @@ -8,6 +8,7 @@ VMTARGETS= vm-image VMFORMATS?= vhd vmdk qcow2 raw VMSIZE?= 20G +SWAPSIZE?= 1G VMBASE?= vm VHD_DESC= Azure, VirtualPC, Hyper-V, Xen disk image diff --git a/release/arm/BANANAPI.conf b/release/arm/BANANAPI.conf index 5da9f3842866..53ccedb54acd 100644 --- a/release/arm/BANANAPI.conf +++ b/release/arm/BANANAPI.conf @@ -7,7 +7,7 @@ EMBEDDEDBUILD=1 EMBEDDED_TARGET="arm" EMBEDDED_TARGET_ARCH="armv6" EMBEDDEDPORTS="sysutils/u-boot-bananapi" -KERNEL="ALLWINNER" +KERNEL="GENERIC" WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000" IMAGE_SIZE="1G" PART_SCHEME="MBR" diff --git a/release/arm/CUBIEBOARD2.conf b/release/arm/CUBIEBOARD2.conf index e7cfab669cf4..acb10f6f9060 100644 --- a/release/arm/CUBIEBOARD2.conf +++ b/release/arm/CUBIEBOARD2.conf @@ -7,7 +7,7 @@ EMBEDDEDBUILD=1 EMBEDDED_TARGET="arm" EMBEDDED_TARGET_ARCH="armv6" EMBEDDEDPORTS="sysutils/u-boot-cubieboard2" -KERNEL="ALLWINNER" +KERNEL="GENERIC" WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x42000000" IMAGE_SIZE="1G" PART_SCHEME="MBR" diff --git a/release/arm/RPI2.conf b/release/arm/RPI2.conf index 886a5aa1ae9e..9d5a64235858 100644 --- a/release/arm/RPI2.conf +++ b/release/arm/RPI2.conf @@ -7,7 +7,7 @@ EMBEDDEDBUILD=1 EMBEDDED_TARGET="arm" EMBEDDED_TARGET_ARCH="armv6" EMBEDDEDPORTS="sysutils/u-boot-rpi2" -KERNEL="RPI2" +KERNEL="GENERIC" WORLD_FLAGS="${WORLD_FLAGS} UBLDR_LOADADDR=0x2000000" IMAGE_SIZE="1G" PART_SCHEME="MBR" diff --git a/release/doc/en_US.ISO8859-1/hardware/article.xml b/release/doc/en_US.ISO8859-1/hardware/article.xml index 962b3e52b9f3..2334ad8b4856 100644 --- a/release/doc/en_US.ISO8859-1/hardware/article.xml +++ b/release/doc/en_US.ISO8859-1/hardware/article.xml @@ -149,7 +149,7 @@ &intel; EM64T is an extended version of IA-32 (x86) and - different from &intel; IA-64 (Itanium) architecture. Some + different from &intel; IA-64 (Itanium) architecture. Some of &intel;'s old documentation refers to &intel; EM64T as 64-bit extension technology or IA-32e. diff --git a/release/doc/share/xml/sponsor.ent b/release/doc/share/xml/sponsor.ent index a76ef8885d0f..c762d1900856 100644 --- a/release/doc/share/xml/sponsor.ent +++ b/release/doc/share/xml/sponsor.ent @@ -11,6 +11,7 @@ + diff --git a/release/picobsd/build/picobsd b/release/picobsd/build/picobsd index 7948351e93cc..807f9acd7242 100755 --- a/release/picobsd/build/picobsd +++ b/release/picobsd/build/picobsd @@ -8,6 +8,10 @@ # picobsd [options] image_type [site_name] # # CWARNFLAGS can be used to pass -Wall or similar options +#export CWARNFLAGS=-D______________sxasxa__________________________ +#export WARNS=2 +# EFIABI... unused attributes ? +export NO_WERROR=1 # # Where image_type is a directory with the picobsd config info, # and ${image_type}/floppy.tree.${site_name} contains @@ -165,7 +169,7 @@ create_includes_and_libraries2() { # opt_dir opt_target local no log "create_includes_and_libraries2() for ${SRC} $1" - no="-DNO_CLEAN -DNO_PROFILE -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1" + no="-DNO_CLEAN -DMK_PROFILE=no -DNO_GAMES -DNO_LIBC_R" # WITHOUT_CDDL=1" no="$no -DWITHOUT_CASPER" no="$no -DMALLOC_PRODUCTION" @@ -674,7 +678,7 @@ populate_mfs_tree() { ) || fail $? crunch log "Setting up host key for sshd:" - for K in rsa1 rsa dsa ; do + for K in rsa dsa ; do if [ $K = rsa1 ] ; then i=ssh_host_key else @@ -844,6 +848,7 @@ fill_floppy_image() { mkdir -p ${dst} ( cd ${BUILDDIR} + # old style mfs lookup, find markers in kernel set 0 0 # reset variables # $1 takes the offset of the MFS filesystem set `strings -at d kernel | grep "MFS Filesystem goes here"` @@ -852,6 +857,16 @@ fill_floppy_image() { set `strings -at d kernel | grep "MFS Filesystem had better"` mfs_end=$1 mfs_size="$((${mfs_end} - ${mfs_start}))" + if [ ${mfs_start} = 0 -o ${mfs_end} = 0 ] ; then + # similar to sys/tools/embed_mfs.sh + local x="`objdump -h kernel | grep oldmfs`" + mfs_size=`echo ${x} | awk '{printf("%d", "0x" $3)}' 2> /dev/null` + mfs_start=`echo ${x} | awk '{printf("%d", "0x" $6)}' 2> /dev/null` + if [ ${mfs_start} = 0 -o ${mfs_size} = 0 ] ; then + log "-- old style mfs location not found, have" + logverbose "$x" + fi + fi set -- `ls -l ${c_fs}`; imgsize="$5" if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then mfs_ofs=$((${mfs_start} + 8192)) @@ -953,9 +968,15 @@ set_build_parameters() { OSVERSION=$3 log "OSVERSION is ${OSVERSION}" - export MAKEOBJDIRPREFIX=${l_objtree} - export TARGET_ARCH=${o_arch} TARGET=${o_arch} - # XXX 20131001 see if CLANG fixes the build + export MAKEOBJDIRPREFIX=${l_objtree} + export TARGET_ARCH=${o_arch} TARGET=${o_arch} + # XXX 20131001 see if CLANG fixes the build + if true; then + echo "--- build with clang" + export WITHOUT_CLANG=yes + export WITHOUT_CLANG_BOOTSTRAP=yes + # export WITH_CLANG_BOOTSTRAP=yes + else export WITHOUT_CLANG_IS_CC=yes export WITHOUT_CLANG_BOOTSTRAP=yes export WITH_GCC=yes @@ -964,14 +985,15 @@ set_build_parameters() { export WITHOUT_CLANG=yes export WITHOUT_ICONV=yes export WITHOUT_TESTS=yes + fi - # XXX why change machine_arch ? - #-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m` - # export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers" - # XXX BINMAKE does not really exist anymore - eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\"" - [ "$BINMAKE" = "" ] && \ - eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\"" + # XXX why change machine_arch ? + #-- export MACHINE_ARCH=`uname -m` MACHINE=`uname -m` + # export CWARNFLAGS="-Wextra -Wno-sign-compare -Wno-missing-field-initializers" + # XXX BINMAKE does not really exist anymore + eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V BINMAKE`\"" + [ "$BINMAKE" = "" ] && \ + eval "export BINMAKE=\"`cd ${SRC}; make -f Makefile -V SUB_MAKE`\"" if [ "${o_init_src}" != "" ] ; then create_includes_and_libraries2 diff --git a/release/tools/vmimage.subr b/release/tools/vmimage.subr index b5a8bf7c6a53..14ef7f106e30 100644 --- a/release/tools/vmimage.subr +++ b/release/tools/vmimage.subr @@ -11,7 +11,7 @@ trap "cleanup" INT QUIT TRAP ABRT TERM write_partition_layout() { if [ -z "${NOSWAP}" ]; then - SWAPOPT="-p freebsd-swap/swapfs::1G" + SWAPOPT="-p freebsd-swap/swapfs::${SWAPSIZE}" fi _OBJDIR="$(make -C ${WORLDDIR} -V .OBJDIR)" diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 09f25821208f..77f2a0d4c45d 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -351,6 +351,8 @@ void decide_address_family(struct node_host *, sa_family_t *); void remove_invalid_hosts(struct node_host **, sa_family_t *); int invalid_redirect(struct node_host *, sa_family_t); u_int16_t parseicmpspec(char *, sa_family_t); +int kw_casecmp(const void *, const void *); +int map_tos(char *string, int *); static TAILQ_HEAD(loadanchorshead, loadanchors) loadanchorshead = TAILQ_HEAD_INITIALIZER(loadanchorshead); @@ -3584,15 +3586,17 @@ icmp6type : STRING { ; tos : STRING { - if (!strcmp($1, "lowdelay")) - $$ = IPTOS_LOWDELAY; - else if (!strcmp($1, "throughput")) - $$ = IPTOS_THROUGHPUT; - else if (!strcmp($1, "reliability")) - $$ = IPTOS_RELIABILITY; - else if ($1[0] == '0' && $1[1] == 'x') - $$ = strtoul($1, NULL, 16); - else + int val; + char *end; + + if (map_tos($1, &val)) + $$ = val; + else if ($1[0] == '0' && $1[1] == 'x') { + errno = 0; + $$ = strtoul($1, &end, 16); + if (errno || *end != '\0') + $$ = 256; + } else $$ = 256; /* flag bad argument */ if ($$ < 0 || $$ > 255) { yyerror("illegal tos value %s", $1); @@ -6249,6 +6253,57 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans) return (0); } +int +kw_casecmp(const void *k, const void *e) +{ + return (strcasecmp(k, ((const struct keywords *)e)->k_name)); +} + +int +map_tos(char *s, int *val) +{ + /* DiffServ Codepoints and other TOS mappings */ + const struct keywords toswords[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af21", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "critical", IPTOS_PREC_CRITIC_ECP }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, + { "lowdelay", IPTOS_LOWDELAY }, + { "netcontrol", IPTOS_PREC_NETCONTROL }, + { "reliability", IPTOS_RELIABILITY }, + { "throughput", IPTOS_THROUGHPUT } + }; + const struct keywords *p; + + p = bsearch(s, toswords, sizeof(toswords)/sizeof(toswords[0]), + sizeof(toswords[0]), kw_casecmp); + + if (p) { + *val = p->k_val; + return (1); + } + return (0); +} + int rt_tableid_max(void) { diff --git a/share/doc/psd/13.rcs/Makefile b/share/doc/psd/13.rcs/Makefile deleted file mode 100644 index ed497da4d8db..000000000000 --- a/share/doc/psd/13.rcs/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -SUBDIR= rcs rcs_func - -.include - diff --git a/share/doc/psd/13.rcs/Makefile.inc b/share/doc/psd/13.rcs/Makefile.inc deleted file mode 100644 index 666dbd862ff2..000000000000 --- a/share/doc/psd/13.rcs/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -VOLUME= psd/13.rcs -MACROS= -ms -SRCDIR= ${.CURDIR}/../../../../../gnu/usr.bin/rcs/doc diff --git a/share/doc/psd/13.rcs/rcs/Makefile b/share/doc/psd/13.rcs/rcs/Makefile deleted file mode 100644 index 6d94aed2bb44..000000000000 --- a/share/doc/psd/13.rcs/rcs/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# $FreeBSD$ - -SRCS= rcs.ms -USE_PIC= -USE_TBL= - -.include diff --git a/share/doc/psd/13.rcs/rcs_func/Makefile b/share/doc/psd/13.rcs/rcs_func/Makefile deleted file mode 100644 index 09e5a9b226c2..000000000000 --- a/share/doc/psd/13.rcs/rcs_func/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $FreeBSD$ - -DOC= rcs_func -SRCS= rcs_func.ms - -.include diff --git a/share/doc/psd/Makefile b/share/doc/psd/Makefile index 6b6d9cd727b2..9e0eed2082f5 100644 --- a/share/doc/psd/Makefile +++ b/share/doc/psd/Makefile @@ -20,7 +20,6 @@ SUBDIR= title \ 05.sysman \ 06.Clang \ 12.make \ - 13.rcs \ 15.yacc \ 16.lex \ 17.m4 \ diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index 96de0ad2abb9..e0e10e825027 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -28,7 +28,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd September 28, 2016 +.Dd October 6, 2016 .Dt PF.CONF 5 .Os .Sh NAME @@ -648,9 +648,16 @@ for matching IP packets. .Em TOS may be given as one of +.Ar critical , +.Ar inetcontrol , .Ar lowdelay , +.Ar netcontrol , .Ar throughput , .Ar reliability , +or one of the DiffServ Code Points: +.Ar ef , +.Ar af11 No ... Ar af43 , +.Ar cs0 No ... Ar cs7 ; or as either hex or decimal. .It Ar random-id Replaces the IP identification field with random values to compensate @@ -1697,9 +1704,16 @@ bits set. .Em TOS may be given as one of +.Ar critical , +.Ar inetcontrol , .Ar lowdelay , +.Ar netcontrol , .Ar throughput , .Ar reliability , +or one of the DiffServ Code Points: +.Ar ef , +.Ar af11 No ... Ar af43 , +.Ar cs0 No ... Ar cs7 ; or as either hex or decimal. .Pp For example, the following rules are identical: @@ -1803,7 +1817,6 @@ pass in proto tcp to port 25 set prio 2 pass in proto tcp to port 22 set prio (2, 5) .Ed .Pp - .It Ar tag Aq Ar string Packets matching this rule will be tagged with the specified string. diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 773d4cfa7d26..84c6a9fad4cf 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,7 +1,7 @@ .\" DO NOT EDIT-- this file is automatically generated. .\" from FreeBSD: head/tools/build/options/makeman 306729 2016-10-05 20:12:00Z emaste .\" $FreeBSD$ -.Dd October 5, 2016 +.Dd October 15, 2016 .Dt SRC.CONF 5 .Os .Sh NAME @@ -1075,12 +1075,15 @@ is set explicitly) Set to not to install compressed man pages. Only the uncompressed versions will be installed. .It Va WITHOUT_MANDOCDB -.\" from FreeBSD: head/tools/build/options/WITHOUT_MANDOCDB 283777 2015-05-30 17:41:37Z bapt -Use the -.Xr mandoc 1 -version of +.\" from FreeBSD: head/tools/build/options/WITHOUT_MANDOCDB 306966 2016-10-10 15:40:08Z emaste +Use the version of +.Xr makewhatis 1 +introduced in +.Fx 2.1 , +instead of the .Xr makewhatis 8 -database and utilities. +database and utilities from +.Xr mandoc 1 . .It Va WITHOUT_MAN_UTILS .\" from FreeBSD: head/tools/build/options/WITHOUT_MAN_UTILS 208322 2010-05-20 00:07:21Z jkim Set to not build utilities for manual pages, @@ -1319,11 +1322,6 @@ This includes .Xr rlogin 1 , .Xr rsh 1 , etc. -.It Va WITH_RCS -.\" from FreeBSD: head/tools/build/options/WITH_RCS 305931 2016-09-18 15:01:11Z bapt -Set to build -.Xr rcs 1 -and related utilities. .It Va WITHOUT_RESCUE .\" from FreeBSD: head/tools/build/options/WITHOUT_RESCUE 156932 2006-03-21 07:50:50Z ru Set to not build diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index c0116802bb03..dbf84947974d 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1138,7 +1138,6 @@ MLINKS+=\ mbuf.9 m_get2.9 \ mbuf.9 m_getjcl.9 \ mbuf.9 m_getcl.9 \ - mbuf.9 m_getclr.9 \ mbuf.9 MGETHDR.9 \ mbuf.9 m_gethdr.9 \ mbuf.9 m_getm.9 \ diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9 index 233caf086e66..a4fa70606a97 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 30, 2016 +.Dd October 10, 2016 .Dt MBUF 9 .Os .\" @@ -79,8 +79,6 @@ .Ft struct mbuf * .Fn m_getcl "int how" "short type" "int flags" .Ft struct mbuf * -.Fn m_getclr "int how" "short type" -.Ft struct mbuf * .Fn m_gethdr "int how" "short type" .Ft struct mbuf * .Fn m_free "struct mbuf *mbuf" @@ -107,7 +105,7 @@ .Ft struct mbuf * .Fn m_copypacket "struct mbuf *mbuf" "int how" .Ft struct mbuf * -.Fn m_dup "struct mbuf *mbuf" "int how" +.Fn m_dup "const struct mbuf *mbuf" "int how" .Ft void .Fn m_copydata "const struct mbuf *mbuf" "int offset" "int len" "caddr_t buf" .Ft void @@ -126,8 +124,8 @@ .Fn m_catpkt "struct mbuf *m" "struct mbuf *n" .Ft u_int .Fn m_fixhdr "struct mbuf *mbuf" -.Ft void -.Fn m_dup_pkthdr "struct mbuf *to" "struct mbuf *from" +.Ft int +.Fn m_dup_pkthdr "struct mbuf *to" "const struct mbuf *from" "int how" .Ft void .Fn m_move_pkthdr "struct mbuf *to" "struct mbuf *from" .Ft u_int @@ -602,10 +600,6 @@ This is like but it the size of the cluster allocated will be large enough for .Fa size bytes. -.It Fn m_getclr how type -Allocate an -.Vt mbuf -and zero out the data region. .It Fn m_free mbuf Frees .Vt mbuf . diff --git a/share/man/man9/mbuf_tags.9 b/share/man/man9/mbuf_tags.9 index c812a3f25bd7..66be8377b100 100644 --- a/share/man/man9/mbuf_tags.9 +++ b/share/man/man9/mbuf_tags.9 @@ -33,7 +33,7 @@ .Ft "struct m_tag *" .Fn m_tag_copy "struct m_tag *t" "int how" .Ft int -.Fn m_tag_copy_chain "struct mbuf *to" "struct mbuf *from" "int how" +.Fn m_tag_copy_chain "struct mbuf *to" "const struct mbuf *from" "int how" .Ft void .Fn m_tag_delete "struct mbuf *m" "struct m_tag *t" .Ft void diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree index 4441114ce1b3..ff36c6f9a140 100644 --- a/share/misc/bsd-family-tree +++ b/share/misc/bsd-family-tree @@ -703,6 +703,7 @@ FreeBSD 10.3 2016-04-04 [FBD] NetBSD 7.0.1 2016-05-22 [NBD] DragonFly 4.6.0 2016-08-02 [DFB] OpenBSD 6.0 2016-09-01 [OBD] +FreeBSD 11.0 2016-10-10 [FBD] Bibliography ------------------------ diff --git a/share/mk/Makefile b/share/mk/Makefile index b33ab27ac053..780e3b651238 100644 --- a/share/mk/Makefile +++ b/share/mk/Makefile @@ -49,6 +49,8 @@ FILES= \ bsd.progs.mk \ bsd.snmpmod.mk \ bsd.subdir.mk \ + bsd.suffixes-posix.mk \ + bsd.suffixes.mk \ bsd.symver.mk \ bsd.sys.mk \ bsd.test.mk \ diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index f3b9f146d282..aa8ed225c58d 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -78,7 +78,6 @@ CTFFLAGS+= -g # prefer .s to a .c, add .po, remove stuff not used in the BSD libraries # .pico used for PIC object files -.SUFFIXES: .SUFFIXES: .out .o .po .pico .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln .if !defined(PICFLAG) @@ -91,10 +90,6 @@ PICFLAG=-fpic PO_FLAG=-pg -.c.o: - ${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} - ${CTFCONVERT_CMD} - .c.po: ${CC} ${PO_FLAG} ${STATIC_CFLAGS} ${PO_CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CTFCONVERT_CMD} @@ -103,9 +98,6 @@ PO_FLAG=-pg ${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CTFCONVERT_CMD} -.cc.o .C.o .cpp.o .cxx.o: - ${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} - .cc.po .C.po .cpp.po .cxx.po: ${CXX} ${PO_FLAG} ${STATIC_CXXFLAGS} ${PO_CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index a3e6f2e0f622..971deb0ff03c 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -59,6 +59,7 @@ LIBDPV?= ${DESTDIR}${LIBDIR}/libdpv.a LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a LIBEDIT?= ${DESTDIR}${LIBDIR}/libedit.a +LIBEFIVAR?= ${DESTDIR}${LIBDIR}/libefivar.a LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a LIBEXECINFO?= ${DESTDIR}${LIBDIR}/libexecinfo.a LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a diff --git a/share/mk/bsd.suffixes-posix.mk b/share/mk/bsd.suffixes-posix.mk new file mode 100644 index 000000000000..90aec1d2f257 --- /dev/null +++ b/share/mk/bsd.suffixes-posix.mk @@ -0,0 +1,56 @@ +# $FreeBSD$ + +# Posix 1003.2 mandated rules +# +# Quoted directly from the Posix 1003.2 draft, only the macros +# $@, $< and $* have been replaced by ${.TARGET}, ${.IMPSRC}, and +# ${.PREFIX}, resp. + +# SINGLE SUFFIX RULES +.c: + ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC} + +.f: + ${FC} ${FFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC} + +.sh: + cp -f ${.IMPSRC} ${.TARGET} + chmod a+x ${.TARGET} + +# DOUBLE SUFFIX RULES + +.c.o: + ${CC} ${CFLAGS} -c ${.IMPSRC} + +.f.o: + ${FC} ${FFLAGS} -c ${.IMPSRC} + +.y.o: + ${YACC} ${YFLAGS} ${.IMPSRC} + ${CC} ${CFLAGS} -c y.tab.c + rm -f y.tab.c + mv y.tab.o ${.TARGET} + +.l.o: + ${LEX} ${LFLAGS} ${.IMPSRC} + ${CC} ${CFLAGS} -c lex.yy.c + rm -f lex.yy.c + mv lex.yy.o ${.TARGET} + +.y.c: + ${YACC} ${YFLAGS} ${.IMPSRC} + mv y.tab.c ${.TARGET} + +.l.c: + ${LEX} ${LFLAGS} ${.IMPSRC} + mv lex.yy.c ${.TARGET} + +.c.a: + ${CC} ${CFLAGS} -c ${.IMPSRC} + ${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o + rm -f ${.PREFIX}.o + +.f.a: + ${FC} ${FFLAGS} -c ${.IMPSRC} + ${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o + rm -f ${.PREFIX}.o diff --git a/share/mk/bsd.suffixes.mk b/share/mk/bsd.suffixes.mk new file mode 100644 index 000000000000..551356bc3020 --- /dev/null +++ b/share/mk/bsd.suffixes.mk @@ -0,0 +1,99 @@ +# $FreeBSD$ + +.sh: + cp -f ${.IMPSRC} ${.TARGET} + chmod a+x ${.TARGET} + +.c.ln: + ${LINT} ${LINTOBJFLAGS} ${CFLAGS:M-[DIU]*} ${.IMPSRC} || \ + touch ${.TARGET} + +.cc.ln .C.ln .cpp.ln .cxx.ln: + ${LINT} ${LINTOBJFLAGS} ${CXXFLAGS:M-[DIU]*} ${.IMPSRC} || \ + touch ${.TARGET} + +.c: + ${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.c.o: + ${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.cc .cpp .cxx .C: + ${CXX} ${CXXFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} + +.cc.o .cpp.o .cxx.o .C.o: + ${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} + +.m.o: + ${OBJC} ${OBJCFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.p.o: + ${PC} ${PFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.e .r .F .f: + ${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} \ + -o ${.TARGET} + +.e.o .r.o .F.o .f.o: + ${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} -c ${.IMPSRC} -o ${.TARGET} + +.S.o: + ${CC:N${CCACHE_BIN}} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.asm.o: + ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \ + -o ${.TARGET} + ${CTFCONVERT_CMD} + +.s.o: + ${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC} + ${CTFCONVERT_CMD} + +# XXX not -j safe +.y.o: + ${YACC} ${YFLAGS} ${.IMPSRC} + ${CC} ${CFLAGS} -c y.tab.c -o ${.TARGET} + rm -f y.tab.c + ${CTFCONVERT_CMD} + +.l.o: + ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c + ${CC} ${CFLAGS} -c ${.PREFIX}.tmp.c -o ${.TARGET} + rm -f ${.PREFIX}.tmp.c + ${CTFCONVERT_CMD} + +# XXX not -j safe +.y.c: + ${YACC} ${YFLAGS} ${.IMPSRC} + mv y.tab.c ${.TARGET} + +.l.c: + ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.TARGET} + +.s.out .c.out .o.out: + ${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} + ${CTFCONVERT_CMD} + +.f.out .F.out .r.out .e.out: + ${FC} ${EFLAGS} ${RFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} \ + ${LDLIBS} -o ${.TARGET} + rm -f ${.PREFIX}.o + ${CTFCONVERT_CMD} + +# XXX not -j safe +.y.out: + ${YACC} ${YFLAGS} ${.IMPSRC} + ${CC} ${CFLAGS} ${LDFLAGS} y.tab.c ${LDLIBS} -ly -o ${.TARGET} + rm -f y.tab.c + ${CTFCONVERT_CMD} + +.l.out: + ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c + ${CC} ${CFLAGS} ${LDFLAGS} ${.PREFIX}.tmp.c ${LDLIBS} -ll -o ${.TARGET} + rm -f ${.PREFIX}.tmp.c + ${CTFCONVERT_CMD} diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index f65ce01c0081..1765d4146ff3 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -91,6 +91,7 @@ _LIBRARIES= \ dtrace \ dwarf \ edit \ + efivar \ elf \ execinfo \ fetch \ diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 22f4da56ce27..d55319de1a99 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -82,6 +82,7 @@ __DEFAULT_YES_OPTIONS = \ DYNAMICROOT \ ED_CRYPTO \ EE \ + EFI \ ELFTOOLCHAIN_BOOTSTRAP \ EXAMPLES \ FDT \ @@ -263,6 +264,9 @@ BROKEN_OPTIONS+=LIBSOFT .if ${__T:Mmips*} BROKEN_OPTIONS+=SSP .endif +.if ${__T:Mmips*} || ${__T:Mpowerpc*} || ${__T:Msparc64} || ${__T:Mriscv*} +BROKEN_OPTIONS+=EFI +.endif .include diff --git a/share/mk/sys.mk b/share/mk/sys.mk index dbc2fd91e372..73350e71f5a6 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -259,162 +259,12 @@ YFLAGS ?= -d .if defined(%POSIX) -# Posix 1003.2 mandated rules -# -# Quoted directly from the Posix 1003.2 draft, only the macros -# $@, $< and $* have been replaced by ${.TARGET}, ${.IMPSRC}, and -# ${.PREFIX}, resp. - -# SINGLE SUFFIX RULES -.c: - ${CC} ${CFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC} - -.f: - ${FC} ${FFLAGS} ${LDFLAGS} -o ${.TARGET} ${.IMPSRC} - -.sh: - cp -f ${.IMPSRC} ${.TARGET} - chmod a+x ${.TARGET} - -# DOUBLE SUFFIX RULES - -.c.o: - ${CC} ${CFLAGS} -c ${.IMPSRC} - -.f.o: - ${FC} ${FFLAGS} -c ${.IMPSRC} - -.y.o: - ${YACC} ${YFLAGS} ${.IMPSRC} - ${CC} ${CFLAGS} -c y.tab.c - rm -f y.tab.c - mv y.tab.o ${.TARGET} - -.l.o: - ${LEX} ${LFLAGS} ${.IMPSRC} - ${CC} ${CFLAGS} -c lex.yy.c - rm -f lex.yy.c - mv lex.yy.o ${.TARGET} - -.y.c: - ${YACC} ${YFLAGS} ${.IMPSRC} - mv y.tab.c ${.TARGET} - -.l.c: - ${LEX} ${LFLAGS} ${.IMPSRC} - mv lex.yy.c ${.TARGET} - -.c.a: - ${CC} ${CFLAGS} -c ${.IMPSRC} - ${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o - rm -f ${.PREFIX}.o - -.f.a: - ${FC} ${FFLAGS} -c ${.IMPSRC} - ${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o - rm -f ${.PREFIX}.o +.include "bsd.suffixes-posix.mk" .else # non-Posix rule set - -.sh: - cp -f ${.IMPSRC} ${.TARGET} - chmod a+x ${.TARGET} - -.c.ln: - ${LINT} ${LINTOBJFLAGS} ${CFLAGS:M-[DIU]*} ${.IMPSRC} || \ - touch ${.TARGET} - -.cc.ln .C.ln .cpp.ln .cxx.ln: - ${LINT} ${LINTOBJFLAGS} ${CXXFLAGS:M-[DIU]*} ${.IMPSRC} || \ - touch ${.TARGET} - -.c: - ${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.c.o: - ${CC} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.cc .cpp .cxx .C: - ${CXX} ${CXXFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} - -.cc.o .cpp.o .cxx.o .C.o: - ${CXX} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} - -.m.o: - ${OBJC} ${OBJCFLAGS} -c ${.IMPSRC} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.p.o: - ${PC} ${PFLAGS} -c ${.IMPSRC} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.e .r .F .f: - ${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} \ - -o ${.TARGET} - -.e.o .r.o .F.o .f.o: - ${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} -c ${.IMPSRC} -o ${.TARGET} - -.S.o: - ${CC:N${CCACHE_BIN}} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.asm.o: - ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \ - -o ${.TARGET} - ${CTFCONVERT_CMD} - -.s.o: - ${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC} - ${CTFCONVERT_CMD} - -# XXX not -j safe -.y.o: - ${YACC} ${YFLAGS} ${.IMPSRC} - ${CC} ${CFLAGS} -c y.tab.c -o ${.TARGET} - rm -f y.tab.c - ${CTFCONVERT_CMD} - -.l.o: - ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c - ${CC} ${CFLAGS} -c ${.PREFIX}.tmp.c -o ${.TARGET} - rm -f ${.PREFIX}.tmp.c - ${CTFCONVERT_CMD} - -# XXX not -j safe -.y.c: - ${YACC} ${YFLAGS} ${.IMPSRC} - mv y.tab.c ${.TARGET} - -.l.c: - ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.TARGET} - -.s.out .c.out .o.out: - ${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET} - ${CTFCONVERT_CMD} - -.f.out .F.out .r.out .e.out: - ${FC} ${EFLAGS} ${RFLAGS} ${FFLAGS} ${LDFLAGS} ${.IMPSRC} \ - ${LDLIBS} -o ${.TARGET} - rm -f ${.PREFIX}.o - ${CTFCONVERT_CMD} - -# XXX not -j safe -.y.out: - ${YACC} ${YFLAGS} ${.IMPSRC} - ${CC} ${CFLAGS} ${LDFLAGS} y.tab.c ${LDLIBS} -ly -o ${.TARGET} - rm -f y.tab.c - ${CTFCONVERT_CMD} - -.l.out: - ${LEX} -t ${LFLAGS} ${.IMPSRC} > ${.PREFIX}.tmp.c - ${CC} ${CFLAGS} ${LDFLAGS} ${.PREFIX}.tmp.c ${LDLIBS} -ll -o ${.TARGET} - rm -f ${.PREFIX}.tmp.c - ${CTFCONVERT_CMD} +.include "bsd.suffixes.mk" # Pull in global settings. __MAKE_CONF?=/etc/make.conf diff --git a/sys/amd64/amd64/efirt.c b/sys/amd64/amd64/efirt.c index 8db768b9d619..4c0454c1f84e 100644 --- a/sys/amd64/amd64/efirt.c +++ b/sys/amd64/amd64/efirt.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); static struct efi_systbl *efi_systbl; static struct efi_cfgtbl *efi_cfgtbl; static struct efi_rt *efi_runtime; +static struct cdev *efi_cdev; static int efi_status2err[25] = { 0, /* EFI_SUCCESS */ @@ -402,13 +403,15 @@ efi_init(void) return (ENXIO); } - return (0); + return (efidev_init(&efi_cdev)); } static void efi_uninit(void) { + efidev_uninit(efi_cdev); + efi_destroy_1t1_map(); efi_systbl = NULL; diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c index 716fcfb118df..51f465074363 100644 --- a/sys/amd64/amd64/mem.c +++ b/sys/amd64/amd64/mem.c @@ -172,10 +172,9 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, if (offset >= (1ULL << cpu_maxphyaddr)) return (-1); *paddr = offset; - } else if (dev2unit(dev) == CDEV_MINOR_KMEM) - *paddr = vtophys(offset); - /* else panic! */ - return (0); + return (0); + } + return (-1); } /* diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 2859de5a45d1..d727d5349f00 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -30,6 +30,7 @@ options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security options TCP_OFFLOAD # TCP offload +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/allwinner/axp209.c b/sys/arm/allwinner/axp209.c index 2283fe31a77a..2c007424e9fb 100644 --- a/sys/arm/allwinner/axp209.c +++ b/sys/arm/allwinner/axp209.c @@ -50,14 +50,92 @@ __FBSDID("$FreeBSD$"); #include -#include #include #include +#include + #include #include "iicbus_if.h" #include "gpio_if.h" +#include "regdev_if.h" + +MALLOC_DEFINE(M_AXP209_REG, "Axp209 regulator", "Axp209 power regulator"); + +struct axp209_regdef { + intptr_t id; + char *name; + uint8_t enable_reg; + uint8_t enable_mask; + uint8_t voltage_reg; + uint8_t voltage_mask; + uint8_t voltage_shift; + int voltage_min; + int voltage_max; + int voltage_step; + int voltage_nstep; +}; + +static struct axp209_regdef axp209_regdefs[] = { + { + .id = AXP209_REG_ID_DCDC2, + .name = "dcdc2", + .enable_reg = AXP209_POWERCTL, + .enable_mask = AXP209_POWERCTL_DCDC2, + .voltage_reg = AXP209_REG_DCDC2_VOLTAGE, + .voltage_mask = 0x3f, + .voltage_min = 700, + .voltage_max = 2275, + .voltage_step = 25, + .voltage_nstep = 64, + }, + { + .id = AXP209_REG_ID_DCDC3, + .name = "dcdc3", + .enable_reg = AXP209_POWERCTL, + .enable_mask = AXP209_POWERCTL_DCDC3, + .voltage_reg = AXP209_REG_DCDC3_VOLTAGE, + .voltage_mask = 0x7f, + .voltage_min = 700, + .voltage_max = 3500, + .voltage_step = 25, + .voltage_nstep = 128, + }, + { + .id = AXP209_REG_ID_LDO2, + .name = "ldo2", + .enable_reg = AXP209_POWERCTL, + .enable_mask = AXP209_POWERCTL_LDO2, + .voltage_reg = AXP209_REG_LDO24_VOLTAGE, + .voltage_mask = 0xf0, + .voltage_shift = 4, + .voltage_min = 1800, + .voltage_max = 3300, + .voltage_step = 100, + .voltage_nstep = 16, + }, + { + .id = AXP209_REG_ID_LDO3, + .name = "ldo3", + .enable_reg = AXP209_POWERCTL, + .enable_mask = AXP209_POWERCTL_LDO3, + .voltage_reg = AXP209_REG_LDO3_VOLTAGE, + .voltage_mask = 0x7f, + .voltage_min = 700, + .voltage_max = 2275, + .voltage_step = 25, + .voltage_nstep = 128, + }, +}; + +struct axp209_reg_sc { + struct regnode *regnode; + device_t base_dev; + struct axp209_regdef *def; + phandle_t xref; + struct regnode_std_param *param; +}; struct axp209_softc { device_t dev; @@ -67,6 +145,10 @@ struct axp209_softc { struct intr_config_hook intr_hook; device_t gpiodev; struct mtx mtx; + + /* Regulators */ + struct axp209_reg_sc **regs; + int nregs; }; /* GPIO3 is different, don't expose it for now */ @@ -124,6 +206,115 @@ axp209_write(device_t dev, uint8_t reg, uint8_t data) return (iicbus_transfer(dev, &msg, 1)); } +static int +axp209_regnode_init(struct regnode *regnode) +{ + return (0); +} + +static int +axp209_regnode_enable(struct regnode *regnode, bool enable, int *udelay) +{ + struct axp209_reg_sc *sc; + uint8_t val; + + sc = regnode_get_softc(regnode); + + axp209_read(sc->base_dev, sc->def->enable_reg, &val, 1); + if (enable) + val |= sc->def->enable_mask; + else + val &= ~sc->def->enable_mask; + axp209_write(sc->base_dev, sc->def->enable_reg, val); + + *udelay = 0; + + return (0); +} + +static void +axp209_regnode_reg_to_voltage(struct axp209_reg_sc *sc, uint8_t val, int *uv) +{ + if (val < sc->def->voltage_nstep) + *uv = sc->def->voltage_min + val * sc->def->voltage_step; + else + *uv = sc->def->voltage_min + + (sc->def->voltage_nstep * sc->def->voltage_step); + *uv *= 1000; +} + +static int +axp209_regnode_voltage_to_reg(struct axp209_reg_sc *sc, int min_uvolt, + int max_uvolt, uint8_t *val) +{ + uint8_t nval; + int nstep, uvolt; + + nval = 0; + uvolt = sc->def->voltage_min * 1000; + + for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt; + nstep++) { + ++nval; + uvolt += (sc->def->voltage_step * 1000); + } + if (uvolt > max_uvolt) + return (EINVAL); + + *val = nval; + return (0); +} + +static int +axp209_regnode_set_voltage(struct regnode *regnode, int min_uvolt, + int max_uvolt, int *udelay) +{ + struct axp209_reg_sc *sc; + uint8_t val; + + sc = regnode_get_softc(regnode); + + if (!sc->def->voltage_step) + return (ENXIO); + + if (axp209_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0) + return (ERANGE); + + axp209_write(sc->base_dev, sc->def->voltage_reg, val); + + *udelay = 0; + + return (0); +} + +static int +axp209_regnode_get_voltage(struct regnode *regnode, int *uvolt) +{ + struct axp209_reg_sc *sc; + uint8_t val; + + sc = regnode_get_softc(regnode); + + if (!sc->def->voltage_step) + return (ENXIO); + + axp209_read(sc->base_dev, sc->def->voltage_reg, &val, 1); + axp209_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt); + + return (0); +} + +static regnode_method_t axp209_regnode_methods[] = { + /* Regulator interface */ + REGNODEMETHOD(regnode_init, axp209_regnode_init), + REGNODEMETHOD(regnode_enable, axp209_regnode_enable), + REGNODEMETHOD(regnode_set_voltage, axp209_regnode_set_voltage), + REGNODEMETHOD(regnode_get_voltage, axp209_regnode_get_voltage), + REGNODEMETHOD_END +}; +DEFINE_CLASS_1(axp209_regnode, axp209_regnode_class, axp209_regnode_methods, + sizeof(struct axp209_reg_sc), regnode_class); + static int axp209_sysctl(SYSCTL_HANDLER_ARGS) { @@ -517,6 +708,63 @@ axp209_get_node(device_t dev, device_t bus) return (ofw_bus_get_node(dev)); } +static struct axp209_reg_sc * +axp209_reg_attach(device_t dev, phandle_t node, + struct axp209_regdef *def) +{ + struct axp209_reg_sc *reg_sc; + struct regnode_init_def initdef; + struct regnode *regnode; + + memset(&initdef, 0, sizeof(initdef)); + if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) { + device_printf(dev, "cannot create regulator\n"); + return (NULL); + } + if (initdef.std_param.min_uvolt == 0) + initdef.std_param.min_uvolt = def->voltage_min * 1000; + if (initdef.std_param.max_uvolt == 0) + initdef.std_param.max_uvolt = def->voltage_max * 1000; + initdef.id = def->id; + initdef.ofw_node = node; + regnode = regnode_create(dev, &axp209_regnode_class, &initdef); + if (regnode == NULL) { + device_printf(dev, "cannot create regulator\n"); + return (NULL); + } + + reg_sc = regnode_get_softc(regnode); + reg_sc->regnode = regnode; + reg_sc->base_dev = dev; + reg_sc->def = def; + reg_sc->xref = OF_xref_from_node(node); + reg_sc->param = regnode_get_stdparam(regnode); + + regnode_register(regnode); + + return (reg_sc); +} + +static int +axp209_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells, + intptr_t *num) +{ + struct axp209_softc *sc; + int i; + + sc = device_get_softc(dev); + for (i = 0; i < sc->nregs; i++) { + if (sc->regs[i] == NULL) + continue; + if (sc->regs[i]->xref == xref) { + *num = sc->regs[i]->def->id; + return (0); + } + } + + return (ENXIO); +} + static void axp209_start(void *pdev) { @@ -654,6 +902,9 @@ static int axp209_attach(device_t dev) { struct axp209_softc *sc; + struct axp209_reg_sc *reg; + phandle_t rnode, child; + int i; sc = device_get_softc(dev); mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); @@ -669,6 +920,29 @@ axp209_attach(device_t dev) if (config_intrhook_establish(&sc->intr_hook) != 0) return (ENOMEM); + sc->nregs = nitems(axp209_regdefs); + sc->regs = malloc(sizeof(struct axp209_reg_sc *) * sc->nregs, + M_AXP209_REG, M_WAITOK | M_ZERO); + + /* Attach known regulators that exist in the DT */ + rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators"); + if (rnode > 0) { + for (i = 0; i < sc->nregs; i++) { + child = ofw_bus_find_child(rnode, + axp209_regdefs[i].name); + if (child == 0) + continue; + reg = axp209_reg_attach(dev, child, &axp209_regdefs[i]); + if (reg == NULL) { + device_printf(dev, + "cannot attach regulator %s\n", + axp209_regdefs[i].name); + continue; + } + sc->regs[i] = reg; + } + } + sc->gpiodev = gpiobus_attach_bus(dev); return (0); @@ -690,6 +964,9 @@ static device_method_t axp209_methods[] = { DEVMETHOD(gpio_pin_toggle, axp209_gpio_pin_toggle), DEVMETHOD(gpio_map_gpios, axp209_gpio_map_gpios), + /* Regdev interface */ + DEVMETHOD(regdev_map, axp209_regdev_map), + /* OFW bus interface */ DEVMETHOD(ofw_bus_get_node, axp209_get_node), diff --git a/sys/arm/allwinner/axp209reg.h b/sys/arm/allwinner/axp209reg.h index 941a72b69c2c..38e540145c54 100644 --- a/sys/arm/allwinner/axp209reg.h +++ b/sys/arm/allwinner/axp209reg.h @@ -146,6 +146,19 @@ #define AXP209_GPIO_DATA(x) (1 << (x + 4)) +/* Regulators registers */ +#define AXP209_POWERCTL 0x12 +#define AXP209_POWERCTL_DCDC3 (1 << 1) +#define AXP209_POWERCTL_LDO2 (1 << 2) +#define AXP209_POWERCTL_LDO4 (1 << 3) +#define AXP209_POWERCTL_DCDC2 (1 << 4) +#define AXP209_POWERCTL_LDO3 (1 << 6) + +#define AXP209_REG_DCDC2_VOLTAGE 0x23 +#define AXP209_REG_DCDC3_VOLTAGE 0x27 +#define AXP209_REG_LDO24_VOLTAGE 0x28 +#define AXP209_REG_LDO3_VOLTAGE 0x29 + enum axp209_sensor { AXP209_TEMP, AXP209_ACVOLT, @@ -157,4 +170,15 @@ enum axp209_sensor { AXP209_BATDISCHARGECURRENT, }; +enum axp209_regulators { + AXP209_REG_ID_DCDC2, + AXP209_REG_ID_DCDC3, + AXP209_REG_ID_LDO1, + AXP209_REG_ID_LDO2, + AXP209_REG_ID_LDO3, + /* LDO4 is weird, need to find a correct way to handle it */ + /* AXP209_REG_ID_LDO4, */ + AXP209_REG_ID_LDO5, +}; + #endif /* _AXP209REG_H_ */ diff --git a/sys/arm/allwinner/clk/aw_gate.c b/sys/arm/allwinner/clk/aw_gate.c index af56b388a924..f26b7c2d1b94 100644 --- a/sys/arm/allwinner/clk/aw_gate.c +++ b/sys/arm/allwinner/clk/aw_gate.c @@ -91,6 +91,8 @@ static struct ofw_compat_data compat_data[] = { { "allwinner,sun8i-h3-bus-gates-clk", (uintptr_t)"Allwinner Bus Clock Gates" }, + { "allwinner,sun8i-h3-apb0-gates-clk", + (uintptr_t)"Allwinner APB0 Clock Gates" }, { "allwinner,sun9i-a80-apbs-gates-clk", (uintptr_t)"Allwinner APBS Clock Gates" }, diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c index 7a17f0f1ceaf..b5ee409c95d3 100644 --- a/sys/arm/allwinner/clk/aw_pll.c +++ b/sys/arm/allwinner/clk/aw_pll.c @@ -193,12 +193,76 @@ struct aw_pll_factor { { .n = (_n), .k = (_k), .m = (_m), .p = (_p), .freq = (_freq) } static struct aw_pll_factor aw_a23_pll1_factors[] = { + PLLFACTOR(9, 0, 0, 2, 60000000), + PLLFACTOR(10, 0, 0, 2, 66000000), + PLLFACTOR(11, 0, 0, 2, 72000000), + PLLFACTOR(12, 0, 0, 2, 78000000), + PLLFACTOR(13, 0, 0, 2, 84000000), + PLLFACTOR(14, 0, 0, 2, 90000000), + PLLFACTOR(15, 0, 0, 2, 96000000), + PLLFACTOR(16, 0, 0, 2, 102000000), + PLLFACTOR(17, 0, 0, 2, 108000000), + PLLFACTOR(18, 0, 0, 2, 114000000), + PLLFACTOR(9, 0, 0, 1, 120000000), + PLLFACTOR(10, 0, 0, 1, 132000000), + PLLFACTOR(11, 0, 0, 1, 144000000), + PLLFACTOR(12, 0, 0, 1, 156000000), + PLLFACTOR(13, 0, 0, 1, 168000000), + PLLFACTOR(14, 0, 0, 1, 180000000), + PLLFACTOR(15, 0, 0, 1, 192000000), + PLLFACTOR(16, 0, 0, 1, 204000000), + PLLFACTOR(17, 0, 0, 1, 216000000), + PLLFACTOR(18, 0, 0, 1, 228000000), + PLLFACTOR(9, 0, 0, 0, 240000000), + PLLFACTOR(10, 0, 0, 0, 264000000), + PLLFACTOR(11, 0, 0, 0, 288000000), + PLLFACTOR(12, 0, 0, 0, 312000000), + PLLFACTOR(13, 0, 0, 0, 336000000), + PLLFACTOR(14, 0, 0, 0, 360000000), + PLLFACTOR(15, 0, 0, 0, 384000000), PLLFACTOR(16, 0, 0, 0, 408000000), + PLLFACTOR(17, 0, 0, 0, 432000000), + PLLFACTOR(18, 0, 0, 0, 456000000), + PLLFACTOR(19, 0, 0, 0, 480000000), + PLLFACTOR(20, 0, 0, 0, 504000000), + PLLFACTOR(21, 0, 0, 0, 528000000), + PLLFACTOR(22, 0, 0, 0, 552000000), + PLLFACTOR(23, 0, 0, 0, 576000000), + PLLFACTOR(24, 0, 0, 0, 600000000), + PLLFACTOR(25, 0, 0, 0, 624000000), PLLFACTOR(26, 0, 0, 0, 648000000), + PLLFACTOR(27, 0, 0, 0, 672000000), + PLLFACTOR(28, 0, 0, 0, 696000000), + PLLFACTOR(29, 0, 0, 0, 720000000), + PLLFACTOR(15, 1, 0, 0, 768000000), + PLLFACTOR(10, 2, 0, 0, 792000000), PLLFACTOR(16, 1, 0, 0, 816000000), + PLLFACTOR(17, 1, 0, 0, 864000000), + PLLFACTOR(18, 1, 0, 0, 912000000), + PLLFACTOR(12, 2, 0, 0, 936000000), + PLLFACTOR(19, 1, 0, 0, 960000000), PLLFACTOR(20, 1, 0, 0, 1008000000), + PLLFACTOR(21, 1, 0, 0, 1056000000), + PLLFACTOR(14, 2, 0, 0, 1080000000), + PLLFACTOR(22, 1, 0, 0, 1104000000), + PLLFACTOR(23, 1, 0, 0, 1152000000), PLLFACTOR(24, 1, 0, 0, 1200000000), + PLLFACTOR(16, 2, 0, 0, 1224000000), + PLLFACTOR(25, 1, 0, 0, 1248000000), PLLFACTOR(26, 1, 0, 0, 1296000000), + PLLFACTOR(27, 1, 0, 0, 1344000000), + PLLFACTOR(18, 2, 0, 0, 1368000000), + PLLFACTOR(28, 1, 0, 0, 1392000000), + PLLFACTOR(29, 1, 0, 0, 1440000000), + PLLFACTOR(20, 2, 0, 0, 1512000000), + PLLFACTOR(15, 3, 0, 0, 1536000000), + PLLFACTOR(21, 2, 0, 0, 1584000000), + PLLFACTOR(16, 3, 0, 0, 1632000000), + PLLFACTOR(22, 2, 0, 0, 1656000000), + PLLFACTOR(23, 2, 0, 0, 1728000000), + PLLFACTOR(24, 2, 0, 0, 1800000000), + PLLFACTOR(18, 3, 0, 0, 1824000000), + PLLFACTOR(25, 2, 0, 0, 1872000000), }; enum aw_pll_type { diff --git a/sys/arm/arm/mem.c b/sys/arm/arm/mem.c index 096988dc0b72..c2cf320b2b67 100644 --- a/sys/arm/arm/mem.c +++ b/sys/arm/arm/mem.c @@ -161,10 +161,9 @@ int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { - if (dev2unit(dev) == CDEV_MINOR_MEM) + if (dev2unit(dev) == CDEV_MINOR_MEM) { *paddr = offset; - else if (dev2unit(dev) == CDEV_MINOR_KMEM) - *paddr = vtophys(offset); - /* else panic! */ - return (0); + return (0); + } + return (-1); } diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c index 9bf1b4442431..879bc305b0ed 100644 --- a/sys/arm/arm/nexus.c +++ b/sys/arm/arm/nexus.c @@ -383,7 +383,11 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, return (0); } else if (type == SYS_RES_IRQ) { #ifdef INTRNG - intr_activate_irq(child, r); + err = intr_activate_irq(child, r); + if (err != 0) { + rman_deactivate_resource(r); + return (err); + } #endif } return (0); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c index debbf82cb2f1..706226999fde 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c @@ -52,6 +52,12 @@ __FBSDID("$FreeBSD$"); #include "iicbus_if.h" +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-bsc", 1}, + {"brcm,bcm2708-i2c", 1}, + {NULL, 0} +}; + static void bcm_bsc_intr(void *); static int bcm_bsc_detach(device_t); @@ -214,7 +220,7 @@ bcm_bsc_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-bsc")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "BCM2708/2835 BSC controller"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_common.c b/sys/arm/broadcom/bcm2835/bcm2835_common.c index 6f136f81da99..7d2ef761fa4a 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_common.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_common.c @@ -52,7 +52,8 @@ fdt_intc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, int *pol) { - if (fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic")) { + if (fdt_is_compatible(node, "broadcom,bcm2835-armctrl-ic") || + fdt_is_compatible(node, "brcm,bcm2836-armctrl-ic")) { *interrupt = fdt32_to_cpu(intr[0]); *trig = INTR_TRIGGER_CONFORM; *pol = INTR_POLARITY_CONFORM; diff --git a/sys/arm/broadcom/bcm2835/bcm2835_dma.c b/sys/arm/broadcom/bcm2835/bcm2835_dma.c index ace336cd5a00..3b6c03201fa1 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_dma.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_dma.c @@ -152,6 +152,12 @@ struct bcm_dma_softc { static struct bcm_dma_softc *bcm_dma_sc = NULL; static uint32_t bcm_dma_channel_mask; +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-dma", 1}, + {"brcm,bcm2835-dma", 1}, + {NULL, 0} +}; + static void bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) @@ -656,7 +662,7 @@ bcm_dma_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-dma")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "BCM2835 DMA Controller"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fb.c b/sys/arm/broadcom/bcm2835/bcm2835_fb.c index cb0fc72ab0b6..58caac2cd884 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_fb.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_fb.c @@ -111,6 +111,12 @@ struct bcmsc_softc { static struct bcmsc_softc bcmsc; +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-fb", 1}, + {"brcm,bcm2708-fb", 1}, + {NULL, 0} +}; + static int bcm_fb_probe(device_t); static int bcm_fb_attach(device_t); static void bcmfb_update_margins(video_adapter_t *adp); @@ -121,8 +127,9 @@ bcm_fb_probe(device_t dev) { int error; - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-fb")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); + device_set_desc(dev, "BCM2835 framebuffer device"); error = sc_probe_unit(device_get_unit(dev), device_get_flags(dev) | SC_AUTODETECT_KBD); @@ -196,6 +203,7 @@ static driver_t bcm_fb_driver = { }; DRIVER_MODULE(bcm2835fb, ofwbus, bcm_fb_driver, bcm_fb_devclass, 0, 0); +DRIVER_MODULE(bcm2835fb, simplebus, bcm_fb_driver, bcm_fb_devclass, 0, 0); /* * Video driver routines and glue. diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c index 1a7976275d22..04cc83a42c81 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c @@ -65,6 +65,12 @@ struct bcmsc_softc { device_t dev; }; +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-fb", 1}, + {"brcm,bcm2708-fb", 1}, + {NULL, 0} +}; + static int bcm_fb_probe(device_t); static int bcm_fb_attach(device_t); @@ -113,8 +119,10 @@ bcm_fb_setup_fbd(struct bcmsc_softc *sc) sc->info.fb_stride = fb.pitch; sc->info.fb_width = fb.xres; sc->info.fb_height = fb.yres; +#ifdef VM_MEMATTR_WRITE_COMBINING sc->info.fb_flags = FB_FLAG_MEMATTR; sc->info.fb_memattr = VM_MEMATTR_WRITE_COMBINING; +#endif if (sc->fbswap) { switch (sc->info.fb_bpp) { @@ -191,7 +199,8 @@ bcm_fb_sysctl_init(struct bcmsc_softc *sc) static int bcm_fb_probe(device_t dev) { - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-fb")) + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "BCM2835 VT framebuffer driver"); @@ -265,3 +274,4 @@ static driver_t bcm_fb_driver = { }; DRIVER_MODULE(bcm2835fb, ofwbus, bcm_fb_driver, bcm_fb_devclass, 0, 0); +DRIVER_MODULE(bcm2835fb, simplebus, bcm_fb_driver, bcm_fb_devclass, 0, 0); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index 0b59d5202b1f..ed3bbae998fe 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -82,8 +82,6 @@ static struct resource_spec bcm_gpio_res_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, { SYS_RES_IRQ, 0, RF_ACTIVE }, /* bank 0 interrupt */ { SYS_RES_IRQ, 1, RF_ACTIVE }, /* bank 1 interrupt */ - { SYS_RES_IRQ, 2, RF_ACTIVE }, /* bank 1 interrupt (mirrored) */ - { SYS_RES_IRQ, 3, RF_ACTIVE }, /* bank 0-1 interrupt (united) */ { -1, 0, 0 } }; @@ -159,6 +157,12 @@ enum bcm_gpio_pud { #define BCM_GPIO_GPPUD(_bank) (0x94) /* Pin Pull up/down */ #define BCM_GPIO_GPPUDCLK(_bank) (0x98 + _bank * 4) /* Pin Pull up clock */ +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-gpio", 1}, + {"brcm,bcm2835-gpio", 1}, + {NULL, 0} +}; + static struct bcm_gpio_softc *bcm_gpio_sc = NULL; #ifdef INTRNG @@ -672,11 +676,11 @@ bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc) phandle_t gpio, node, reserved; ssize_t len; - /* Get read-only pins. */ + /* Get read-only pins if they're provided */ gpio = ofw_bus_get_node(sc->sc_dev); if (bcm_gpio_get_ro_pins(sc, gpio, "broadcom,read-only", "read-only") != 0) - return (-1); + return (0); /* Traverse the GPIO subnodes to find the reserved pins node. */ reserved = 0; node = OF_child(gpio); @@ -742,7 +746,7 @@ bcm_gpio_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-gpio")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "BCM2708/2835 GPIO controller"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c index b6a74542bc68..9f7bd7f44d32 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c @@ -270,6 +270,7 @@ bcm_intc_map_intr(device_t dev, struct intr_map_data *data, u_int irq; struct intr_map_data_fdt *daf; struct bcm_intc_softc *sc; + bool valid; if (data->type != INTR_MAP_DATA_FDT) return (ENOTSUP); @@ -277,8 +278,36 @@ bcm_intc_map_intr(device_t dev, struct intr_map_data *data, daf = (struct intr_map_data_fdt *)data; if (daf->ncells == 1) irq = daf->cells[0]; - else if (daf->ncells == 2) - irq = daf->cells[0] * 32 + daf->cells[1]; + else if (daf->ncells == 2) { + valid = true; + switch (daf->cells[0]) { + case 0: + irq = daf->cells[1]; + if (irq >= BANK1_START) + valid = false; + break; + case 1: + irq = daf->cells[1] + BANK1_START; + if (irq > BANK1_END) + valid = false; + break; + case 2: + irq = daf->cells[1] + BANK2_START; + if (irq > BANK2_END) + valid = false; + break; + default: + valid = false; + break; + } + + if (!valid) { + device_printf(dev, + "invalid IRQ config: bank=%d, irq=%d\n", + daf->cells[0], daf->cells[1]); + return (EINVAL); + } + } else return (EINVAL); @@ -355,7 +384,8 @@ bcm_intc_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-armctrl-ic")) + if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-armctrl-ic") && + !ofw_bus_is_compatible(dev, "brcm,bcm2836-armctrl-ic")) return (ENXIO); device_set_desc(dev, "BCM2835 Interrupt Controller"); return (BUS_PROBE_DEFAULT); @@ -438,7 +468,8 @@ static driver_t bcm_intc_driver = { static devclass_t bcm_intc_devclass; -DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass, 0, 0); +EARLY_DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass, + 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE); #ifndef INTRNG int diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c index ce04596cb0ad..2fc0a9e70f08 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c @@ -92,6 +92,12 @@ struct bcm_mbox_softc { #define mbox_write_4(sc, reg, val) \ bus_space_write_4((sc)->bst, (sc)->bsh, reg, val) +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-mbox", 1}, + {"brcm,bcm2835-mbox", 1}, + {NULL, 0} +}; + static int bcm_mbox_read_msg(struct bcm_mbox_softc *sc, int *ochan) { @@ -138,12 +144,12 @@ bcm_mbox_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_is_compatible(dev, "broadcom,bcm2835-mbox")) { - device_set_desc(dev, "BCM2835 VideoCore Mailbox"); - return(BUS_PROBE_DEFAULT); - } + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); - return (ENXIO); + device_set_desc(dev, "BCM2835 VideoCore Mailbox"); + + return (BUS_PROBE_DEFAULT); } static int diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index 700edcc7bc35..b74fefd958e1 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -71,6 +71,12 @@ __FBSDID("$FreeBSD$"); static int bcm2835_sdhci_hs = 1; static int bcm2835_sdhci_pio_mode = 0; +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-sdhci", 1}, + {"brcm,bcm2835-mmc", 1}, + {NULL, 0} +}; + TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs); TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode); @@ -126,10 +132,11 @@ bcm_sdhci_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-sdhci")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "Broadcom 2708 SDHCI controller"); + return (BUS_PROBE_DEFAULT); } @@ -239,8 +246,9 @@ bcm_sdhci_attach(device_t dev) goto fail; } - sc->sc_sdhci_buffer_phys = BUS_SPACE_PHYSADDR(sc->sc_mem_res, - SDHCI_BUFFER); + /* FIXME: Fix along with other BUS_SPACE_PHYSADDR instances */ + sc->sc_sdhci_buffer_phys = rman_get_start(sc->sc_mem_res) + + SDHCI_BUFFER; bus_generic_probe(dev); bus_generic_attach(dev); @@ -545,7 +553,7 @@ bcm_sdhci_read_dma(device_t dev, struct sdhci_slot *slot) slot->curcmd->data->len - slot->offset); KASSERT((left & 3) == 0, - ("%s: len = %d, not word-aligned", __func__, left)); + ("%s: len = %zu, not word-aligned", __func__, left)); if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, (uint8_t *)slot->curcmd->data->data + slot->offset, left, @@ -574,7 +582,7 @@ bcm_sdhci_write_dma(device_t dev, struct sdhci_slot *slot) slot->curcmd->data->len - slot->offset); KASSERT((left & 3) == 0, - ("%s: len = %d, not word-aligned", __func__, left)); + ("%s: len = %zu, not word-aligned", __func__, left)); if (bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, (uint8_t *)slot->curcmd->data->data + slot->offset, left, diff --git a/sys/arm/broadcom/bcm2835/bcm2835_spi.c b/sys/arm/broadcom/bcm2835/bcm2835_spi.c index 857e43dcd1e2..b30fac7819c9 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_spi.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_spi.c @@ -56,6 +56,12 @@ __FBSDID("$FreeBSD$"); #include "spibus_if.h" +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-spi", 1}, + {"brcm,bcm2835-spi", 1}, + {NULL, 0} +}; + static void bcm_spi_intr(void *); #ifdef BCM_SPI_DEBUG @@ -231,7 +237,7 @@ bcm_spi_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-spi")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "BCM2708/2835 SPI controller"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h b/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h index e1d44b31f76d..1b540d9be10f 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h +++ b/sys/arm/broadcom/bcm2835/bcm2835_vcbus.h @@ -33,16 +33,23 @@ #ifndef _BCM2835_VCBUS_H_ #define _BCM2835_VCBUS_H_ +/* + * ARM64 define its SOC options in opt_soc.h + */ +#if defined(__aarch64__) +#include "opt_soc.h" +#endif + #define BCM2835_VCBUS_SDRAM_CACHED 0x40000000 #define BCM2835_VCBUS_IO_BASE 0x7E000000 #define BCM2835_VCBUS_SDRAM_UNCACHED 0xC0000000 -#ifdef SOC_BCM2836 -#define BCM2835_ARM_IO_BASE 0x3f000000 -#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED -#else +#if defined(SOC_BCM2835) #define BCM2835_ARM_IO_BASE 0x20000000 #define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_CACHED +#else +#define BCM2835_ARM_IO_BASE 0x3f000000 +#define BCM2835_VCBUS_SDRAM_BASE BCM2835_VCBUS_SDRAM_UNCACHED #endif #define BCM2835_ARM_IO_SIZE 0x01000000 diff --git a/sys/arm/broadcom/bcm2835/bcm2835_wdog.c b/sys/arm/broadcom/bcm2835/bcm2835_wdog.c index 04488db2b853..39b16e34c5c8 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_wdog.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_wdog.c @@ -52,8 +52,8 @@ __FBSDID("$FreeBSD$"); #define BCM2835_WDOG_TIME_MASK 0x000fffff #define BCM2835_WDOG_TIME_SHIFT 0 -#define READ(_sc, _r) bus_space_read_4((_sc)->bst, (_sc)->bsh, (_r)) -#define WRITE(_sc, _r, _v) bus_space_write_4((_sc)->bst, (_sc)->bsh, (_r), (_v)) +#define READ(_sc, _r) bus_space_read_4((_sc)->bst, (_sc)->bsh, (_r) + (_sc)->regs_offset) +#define WRITE(_sc, _r, _v) bus_space_write_4((_sc)->bst, (_sc)->bsh, (_r) + (_sc)->regs_offset, (_v)) #define BCM2835_RSTC_WRCFG_CLR 0xffffffcf #define BCM2835_RSTC_WRCFG_SET 0x00000030 @@ -75,6 +75,17 @@ struct bcmwd_softc { int wdog_period; char wdog_passwd; struct mtx mtx; + int regs_offset; +}; + +#define BSD_DTB 1 +#define UPSTREAM_DTB 2 +#define UPSTREAM_DTB_REGS_OFFSET 0x1c + +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-wdt", BSD_DTB}, + {"brcm,bcm2835-pm-wdt", UPSTREAM_DTB}, + {NULL, 0} }; static void bcmwd_watchdog_fn(void *private, u_int cmd, int *error); @@ -86,12 +97,12 @@ bcmwd_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_is_compatible(dev, "broadcom,bcm2835-wdt")) { - device_set_desc(dev, "BCM2708/2835 Watchdog"); - return (BUS_PROBE_DEFAULT); - } + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); - return (ENXIO); + device_set_desc(dev, "BCM2708/2835 Watchdog"); + + return (BUS_PROBE_DEFAULT); } static int @@ -119,6 +130,11 @@ bcmwd_attach(device_t dev) sc->bst = rman_get_bustag(sc->res); sc->bsh = rman_get_bushandle(sc->res); + /* compensate base address difference */ + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data + == UPSTREAM_DTB) + sc->regs_offset = UPSTREAM_DTB_REGS_OFFSET; + bcmwd_lsc = sc; mtx_init(&sc->mtx, "BCM2835 Watchdog", "bcmwd", MTX_DEF); EVENTHANDLER_REGISTER(watchdog_list, bcmwd_watchdog_fn, sc, 0); diff --git a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c index 75b505c8d82d..2fc25afe2cd5 100644 --- a/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c +++ b/sys/arm/broadcom/bcm2835/bcm283x_dwc_fdt.c @@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$"); #include +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-usb", 1}, + {"brcm,bcm2708-usb", 1}, + {NULL, 0} +}; + static device_probe_t bcm283x_dwc_otg_probe; static device_attach_t bcm283x_dwc_otg_attach; @@ -61,7 +67,7 @@ bcm283x_dwc_otg_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-usb")) + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) return (ENXIO); device_set_desc(dev, "DWC OTG 2.0 integrated USB controller (bcm283x)"); diff --git a/sys/arm/broadcom/bcm2835/files.bcm283x b/sys/arm/broadcom/bcm2835/files.bcm283x index a92a35422003..21c99c146065 100644 --- a/sys/arm/broadcom/bcm2835/files.bcm283x +++ b/sys/arm/broadcom/bcm2835/files.bcm283x @@ -9,7 +9,7 @@ arm/broadcom/bcm2835/bcm2835_fbd.c optional vt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio arm/broadcom/bcm2835/bcm2835_intr.c standard -arm/broadcom/bcm2835/bcm2835_machdep.c standard +arm/broadcom/bcm2835/bcm2835_machdep.c optional platform arm/broadcom/bcm2835/bcm2835_mbox.c standard arm/broadcom/bcm2835/bcm2835_rng.c optional random arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci diff --git a/sys/arm/conf/ATMEL b/sys/arm/conf/ATMEL index 52d2e13ed548..f8877e9e2472 100644 --- a/sys/arm/conf/ATMEL +++ b/sys/arm/conf/ATMEL @@ -35,6 +35,7 @@ options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA index c2a05fabb0c6..e9f71ccfe623 100644 --- a/sys/arm/conf/AVILA +++ b/sys/arm/conf/AVILA @@ -36,6 +36,7 @@ options DEVICE_POLLING options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT index fad7b2402a04..b06daebd3a85 100644 --- a/sys/arm/conf/BWCT +++ b/sys/arm/conf/BWCT @@ -33,6 +33,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA index 91f00e3c079a..8f1881d40a86 100644 --- a/sys/arm/conf/CAMBRIA +++ b/sys/arm/conf/CAMBRIA @@ -37,6 +37,7 @@ options DEVICE_POLLING options SCHED_4BSD # 4BSD scheduler #options PREEMPTION options INET # InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS index 2bf2cf540d16..d7cd496c071f 100644 --- a/sys/arm/conf/CNS11XXNAS +++ b/sys/arm/conf/CNS11XXNAS @@ -46,6 +46,7 @@ options GEOM_LABEL # Provides labelization options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB index c5d6cdf3a2ed..3970c551e78a 100644 --- a/sys/arm/conf/CRB +++ b/sys/arm/conf/CRB @@ -34,6 +34,7 @@ options HZ=100 options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX index 66ed195a68f4..aa474bcc43a1 100644 --- a/sys/arm/conf/DB-78XXX +++ b/sys/arm/conf/DB-78XXX @@ -15,6 +15,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX index d057d6fbf1a4..0199e8663336 100644 --- a/sys/arm/conf/DB-88F5XXX +++ b/sys/arm/conf/DB-88F5XXX @@ -15,6 +15,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX index e2786065e0a3..fa2810c97122 100644 --- a/sys/arm/conf/DB-88F6XXX +++ b/sys/arm/conf/DB-88F6XXX @@ -15,6 +15,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options NANDFS # NAND Filesystem options NFSCL # Network Filesystem Client diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index bf2d5516ef89..9af5ec34efdf 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -29,6 +29,7 @@ options SOC_MV_KIRKWOOD options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options NFSCL # Network Filesystem Client diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index 21e4f61e77dc..e7c32f923d0f 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -32,6 +32,7 @@ options SOC_MV_KIRKWOOD options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options NFSCL # Network Filesystem Client diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250 index 2557fab3eb98..649224e07c06 100644 --- a/sys/arm/conf/EA3250 +++ b/sys/arm/conf/EA3250 @@ -16,6 +16,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager diff --git a/sys/arm/conf/EB9200 b/sys/arm/conf/EB9200 index 888ab316c17a..9a6228c08ce6 100644 --- a/sys/arm/conf/EB9200 +++ b/sys/arm/conf/EB9200 @@ -26,6 +26,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5 index 65cd897f38af..9e84a623bddf 100644 --- a/sys/arm/conf/ETHERNUT5 +++ b/sys/arm/conf/ETHERNUT5 @@ -31,6 +31,7 @@ options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP #options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index b5102ddf2c3d..412b4d11d563 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -25,6 +25,7 @@ options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index fb396194b019..61b53ec35e18 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -112,6 +112,7 @@ device icee # GPIO device gpio device gpioled +device gpioregulator # SPI device spibus diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX index 4cc18e39e192..34e51e608e79 100644 --- a/sys/arm/conf/GUMSTIX +++ b/sys/arm/conf/GUMSTIX @@ -39,6 +39,7 @@ options HZ=100 options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200 index da1423101ffe..1b38af94f6cf 100644 --- a/sys/arm/conf/HL200 +++ b/sys/arm/conf/HL200 @@ -31,6 +31,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201 index e4c181fa40b1..cbf7cb00c981 100644 --- a/sys/arm/conf/HL201 +++ b/sys/arm/conf/HL201 @@ -29,6 +29,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X index 46b7e694f6b6..03301d4c4785 100644 --- a/sys/arm/conf/KB920X +++ b/sys/arm/conf/KB920X @@ -32,6 +32,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU index b1c9f2119cca..b6837d9a4c37 100644 --- a/sys/arm/conf/NSLU +++ b/sys/arm/conf/NSLU @@ -43,6 +43,7 @@ options DEVICE_POLLING options SCHED_ULE # ULE scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/QILA9G20 b/sys/arm/conf/QILA9G20 index 29618b96aaa6..97bde286effe 100644 --- a/sys/arm/conf/QILA9G20 +++ b/sys/arm/conf/QILA9G20 @@ -32,6 +32,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK index d3949381591a..fc65625855b5 100644 --- a/sys/arm/conf/SAM9260EK +++ b/sys/arm/conf/SAM9260EK @@ -42,6 +42,7 @@ options SCHED_4BSD # 4BSD scheduler #options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP #options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/conf/SAM9G20EK b/sys/arm/conf/SAM9G20EK index 2f23caef5305..e579f1d95b2a 100644 --- a/sys/arm/conf/SAM9G20EK +++ b/sys/arm/conf/SAM9G20EK @@ -38,6 +38,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options TMPFS # Efficient memory filesystem options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/arm/conf/SAM9X25EK b/sys/arm/conf/SAM9X25EK index 1d014a3d0e1e..ab69a2d6d871 100644 --- a/sys/arm/conf/SAM9X25EK +++ b/sys/arm/conf/SAM9X25EK @@ -31,6 +31,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/SHEEVAPLUG b/sys/arm/conf/SHEEVAPLUG index 2c6bda4695df..ff60f82bcf60 100644 --- a/sys/arm/conf/SHEEVAPLUG +++ b/sys/arm/conf/SHEEVAPLUG @@ -17,6 +17,7 @@ options HZ=1000 options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options NANDFS # NAND Filesystem options NFSCL # Network Filesystem Client diff --git a/sys/arm/conf/SN9G45 b/sys/arm/conf/SN9G45 index 33eece9216b4..21cb7a6c1e1b 100644 --- a/sys/arm/conf/SN9G45 +++ b/sys/arm/conf/SN9G45 @@ -31,6 +31,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking #options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support #options UFS_ACL # Support for access control lists diff --git a/sys/arm/conf/TS7800 b/sys/arm/conf/TS7800 index 1b6563274204..17b237af46dd 100644 --- a/sys/arm/conf/TS7800 +++ b/sys/arm/conf/TS7800 @@ -15,6 +15,7 @@ makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options NFSCL # Network Filesystem Client diff --git a/sys/arm/conf/std.armv6 b/sys/arm/conf/std.armv6 index fce8b6e6e975..81a8f6613758 100644 --- a/sys/arm/conf/std.armv6 +++ b/sys/arm/conf/std.armv6 @@ -7,6 +7,7 @@ options ARM_L2_PIPT # Only L2 PIPT is supported options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options IPSEC # IP (v4/v6) security options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem diff --git a/sys/arm/include/efi.h b/sys/arm/include/efi.h index 476e18428c4b..02e1e7e975ef 100644 --- a/sys/arm/include/efi.h +++ b/sys/arm/include/efi.h @@ -1,30 +1,5 @@ /*- - * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Konstantin Belousov - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * This file is in the public domain since it's just boilerplate. * * $FreeBSD$ */ diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index c047c5412db1..6dd548b30d40 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -33,7 +33,9 @@ __FBSDID("$FreeBSD$"); #include +#include #include +#include #include #include @@ -151,6 +153,17 @@ const struct cpu_implementers cpu_implementers[] = { CPU_IMPLEMENTER_NONE, }; +static void +identify_cpu_sysinit(void *dummy __unused) +{ + int cpu; + + CPU_FOREACH(cpu) { + print_cpu_features(cpu); + } +} +SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); + void print_cpu_features(u_int cpu) { diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index 215975f9770a..9da3575d6fc3 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -617,8 +617,10 @@ start_mmu: .align 3 mair: - /* Device Normal, no cache Normal, write-back */ - .quad MAIR_ATTR(0x00, 0) | MAIR_ATTR(0x44, 1) | MAIR_ATTR(0xff, 2) + .quad MAIR_ATTR(MAIR_DEVICE_nGnRnE, 0) | \ + MAIR_ATTR(MAIR_NORMAL_NC, 1) | \ + MAIR_ATTR(MAIR_NORMAL_WB, 2) | \ + MAIR_ATTR(MAIR_NORMAL_WT, 3) tcr: .quad (TCR_TxSZ(64 - VIRT_BITS) | TCR_ASID_16 | TCR_TG1_4K | \ TCR_CACHE_ATTRS | TCR_SMP_ATTRS) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 0826938436ca..9813fec4aca4 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -192,9 +192,12 @@ fill_fpregs(struct thread *td, struct fpreg *regs) */ vfp_save_state(td, pcb); - memcpy(regs->fp_q, pcb->pcb_vfp, sizeof(regs->fp_q)); - regs->fp_cr = pcb->pcb_fpcr; - regs->fp_sr = pcb->pcb_fpsr; + KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, + ("Called fill_fpregs while the kernel is using the VFP")); + memcpy(regs->fp_q, pcb->pcb_fpustate.vfp_regs, + sizeof(regs->fp_q)); + regs->fp_cr = pcb->pcb_fpustate.vfp_fpcr; + regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; } else #endif memset(regs->fp_q, 0, sizeof(regs->fp_q)); @@ -208,9 +211,11 @@ set_fpregs(struct thread *td, struct fpreg *regs) struct pcb *pcb; pcb = td->td_pcb; - memcpy(pcb->pcb_vfp, regs->fp_q, sizeof(regs->fp_q)); - pcb->pcb_fpcr = regs->fp_cr; - pcb->pcb_fpsr = regs->fp_sr; + KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, + ("Called set_fpregs while the kernel is using the VFP")); + memcpy(pcb->pcb_fpustate.vfp_regs, regs->fp_q, sizeof(regs->fp_q)); + pcb->pcb_fpustate.vfp_fpcr = regs->fp_cr; + pcb->pcb_fpustate.vfp_fpsr = regs->fp_sr; #endif return (0); } @@ -334,10 +339,12 @@ get_fpcontext(struct thread *td, mcontext_t *mcp) */ vfp_save_state(td, curpcb); - memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_vfp, + KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, + ("Called get_fpcontext while the kernel is using the VFP")); + memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_fpustate.vfp_regs, sizeof(mcp->mc_fpregs)); - mcp->mc_fpregs.fp_cr = curpcb->pcb_fpcr; - mcp->mc_fpregs.fp_sr = curpcb->pcb_fpsr; + mcp->mc_fpregs.fp_cr = curpcb->pcb_fpustate.vfp_fpcr; + mcp->mc_fpregs.fp_sr = curpcb->pcb_fpustate.vfp_fpsr; mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags; mcp->mc_flags |= _MC_FP_VALID; } @@ -363,10 +370,12 @@ set_fpcontext(struct thread *td, mcontext_t *mcp) */ vfp_discard(td); - memcpy(curpcb->pcb_vfp, mcp->mc_fpregs.fp_q, + KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, + ("Called set_fpcontext while the kernel is using the VFP")); + memcpy(curpcb->pcb_fpustate.vfp_regs, mcp->mc_fpregs.fp_q, sizeof(mcp->mc_fpregs)); - curpcb->pcb_fpcr = mcp->mc_fpregs.fp_cr; - curpcb->pcb_fpsr = mcp->mc_fpregs.fp_sr; + curpcb->pcb_fpustate.vfp_fpcr = mcp->mc_fpregs.fp_cr; + curpcb->pcb_fpustate.vfp_fpsr = mcp->mc_fpregs.fp_sr; curpcb->pcb_fpflags = mcp->mc_fpregs.fp_flags; } @@ -607,6 +616,7 @@ init_proc0(vm_offset_t kstack) thread0.td_kstack = kstack; thread0.td_pcb = (struct pcb *)(thread0.td_kstack) - 1; thread0.td_pcb->pcb_fpflags = 0; + thread0.td_pcb->pcb_fpusaved = &thread0.td_pcb->pcb_fpustate; thread0.td_pcb->pcb_vfpcpu = UINT_MAX; thread0.td_frame = &proc0_tf; pcpup->pc_curpcb = thread0.td_pcb; diff --git a/sys/arm64/arm64/mem.c b/sys/arm64/arm64/mem.c index 9044fb3ba7f5..e0ea4889cb5d 100644 --- a/sys/arm64/arm64/mem.c +++ b/sys/arm64/arm64/mem.c @@ -123,10 +123,9 @@ int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { - if (dev2unit(dev) == CDEV_MINOR_MEM) + if (dev2unit(dev) == CDEV_MINOR_MEM) { *paddr = offset; - else if (dev2unit(dev) == CDEV_MINOR_KMEM) - *paddr = vtophys(offset); - /* else panic! */ - return (0); + return (0); + } + return (-1); } diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index b0e182796461..6fbb610dd6c0 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -201,7 +201,7 @@ arm64_cpu_attach(device_t dev) static void release_aps(void *dummy __unused) { - int cpu, i; + int i; intr_pic_ipi_setup(IPI_AST, "ast", ipi_ast, NULL); intr_pic_ipi_setup(IPI_PREEMPT, "preempt", ipi_preempt, NULL); @@ -217,14 +217,8 @@ release_aps(void *dummy __unused) printf("Release APs\n"); for (i = 0; i < 2000; i++) { - if (smp_started) { - for (cpu = 0; cpu <= mp_maxid; cpu++) { - if (CPU_ABSENT(cpu)) - continue; - print_cpu_features(cpu); - } + if (smp_started) return; - } DELAY(1000); } diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 311853e9ac68..7ff9f537972a 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -347,7 +347,11 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, rman_set_virtual(r, (void *)vaddr); rman_set_bushandle(r, vaddr); } else if (type == SYS_RES_IRQ) { - intr_activate_irq(child, r); + err = intr_activate_irq(child, r); + if (err != 0) { + rman_deactivate_resource(r); + return (err); + } } return (0); } diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c index 8278f87bacd8..f1fbb56a3521 100644 --- a/sys/arm64/arm64/vfp.c +++ b/sys/arm64/arm64/vfp.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -42,7 +43,10 @@ __FBSDID("$FreeBSD$"); #include /* Sanity check we can store all the VFP registers */ -CTASSERT(sizeof(((struct pcb *)0)->pcb_vfp) == 16 * 32); +CTASSERT(sizeof(((struct pcb *)0)->pcb_fpustate.vfp_regs) == 16 * 32); + +static MALLOC_DEFINE(M_FPUKERN_CTX, "fpukern_ctx", + "Kernel contexts for VFP state"); static void vfp_enable(void) @@ -75,17 +79,83 @@ void vfp_discard(struct thread *td) { +#ifdef INVARIANTS + if (td != NULL) + CRITICAL_ASSERT(td); +#endif if (PCPU_GET(fpcurthread) == td) PCPU_SET(fpcurthread, NULL); vfp_disable(); } -void -vfp_save_state(struct thread *td, struct pcb *pcb) +static void +vfp_store(struct vfpstate *state) { __int128_t *vfp_state; uint64_t fpcr, fpsr; + + vfp_state = state->vfp_regs; + __asm __volatile( + "mrs %0, fpcr \n" + "mrs %1, fpsr \n" + "stp q0, q1, [%2, #16 * 0]\n" + "stp q2, q3, [%2, #16 * 2]\n" + "stp q4, q5, [%2, #16 * 4]\n" + "stp q6, q7, [%2, #16 * 6]\n" + "stp q8, q9, [%2, #16 * 8]\n" + "stp q10, q11, [%2, #16 * 10]\n" + "stp q12, q13, [%2, #16 * 12]\n" + "stp q14, q15, [%2, #16 * 14]\n" + "stp q16, q17, [%2, #16 * 16]\n" + "stp q18, q19, [%2, #16 * 18]\n" + "stp q20, q21, [%2, #16 * 20]\n" + "stp q22, q23, [%2, #16 * 22]\n" + "stp q24, q25, [%2, #16 * 24]\n" + "stp q26, q27, [%2, #16 * 26]\n" + "stp q28, q29, [%2, #16 * 28]\n" + "stp q30, q31, [%2, #16 * 30]\n" + : "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state)); + + state->vfp_fpcr = fpcr; + state->vfp_fpsr = fpsr; +} + +static void +vfp_restore(struct vfpstate *state) +{ + __int128_t *vfp_state; + uint64_t fpcr, fpsr; + + vfp_state = state->vfp_regs; + fpcr = state->vfp_fpcr; + fpsr = state->vfp_fpsr; + + __asm __volatile( + "ldp q0, q1, [%2, #16 * 0]\n" + "ldp q2, q3, [%2, #16 * 2]\n" + "ldp q4, q5, [%2, #16 * 4]\n" + "ldp q6, q7, [%2, #16 * 6]\n" + "ldp q8, q9, [%2, #16 * 8]\n" + "ldp q10, q11, [%2, #16 * 10]\n" + "ldp q12, q13, [%2, #16 * 12]\n" + "ldp q14, q15, [%2, #16 * 14]\n" + "ldp q16, q17, [%2, #16 * 16]\n" + "ldp q18, q19, [%2, #16 * 18]\n" + "ldp q20, q21, [%2, #16 * 20]\n" + "ldp q22, q23, [%2, #16 * 22]\n" + "ldp q24, q25, [%2, #16 * 24]\n" + "ldp q26, q27, [%2, #16 * 26]\n" + "ldp q28, q29, [%2, #16 * 28]\n" + "ldp q30, q31, [%2, #16 * 30]\n" + "msr fpcr, %0 \n" + "msr fpsr, %1 \n" + : : "r"(fpcr), "r"(fpsr), "r"(vfp_state)); +} + +void +vfp_save_state(struct thread *td, struct pcb *pcb) +{ uint32_t cpacr; KASSERT(pcb != NULL, ("NULL vfp pcb")); @@ -104,31 +174,7 @@ vfp_save_state(struct thread *td, struct pcb *pcb) KASSERT(PCPU_GET(fpcurthread) == td, ("Storing an invalid VFP state")); - vfp_state = pcb->pcb_vfp; - __asm __volatile( - "mrs %0, fpcr \n" - "mrs %1, fpsr \n" - "stp q0, q1, [%2, #16 * 0]\n" - "stp q2, q3, [%2, #16 * 2]\n" - "stp q4, q5, [%2, #16 * 4]\n" - "stp q6, q7, [%2, #16 * 6]\n" - "stp q8, q9, [%2, #16 * 8]\n" - "stp q10, q11, [%2, #16 * 10]\n" - "stp q12, q13, [%2, #16 * 12]\n" - "stp q14, q15, [%2, #16 * 14]\n" - "stp q16, q17, [%2, #16 * 16]\n" - "stp q18, q19, [%2, #16 * 18]\n" - "stp q20, q21, [%2, #16 * 20]\n" - "stp q22, q23, [%2, #16 * 22]\n" - "stp q24, q25, [%2, #16 * 24]\n" - "stp q26, q27, [%2, #16 * 26]\n" - "stp q28, q29, [%2, #16 * 28]\n" - "stp q30, q31, [%2, #16 * 30]\n" - : "=&r"(fpcr), "=&r"(fpsr) : "r"(vfp_state)); - - pcb->pcb_fpcr = fpcr; - pcb->pcb_fpsr = fpsr; - + vfp_store(pcb->pcb_fpusaved); dsb(ish); vfp_disable(); } @@ -138,8 +184,6 @@ vfp_save_state(struct thread *td, struct pcb *pcb) void vfp_restore_state(void) { - __int128_t *vfp_state; - uint64_t fpcr, fpsr; struct pcb *curpcb; u_int cpu; @@ -158,31 +202,7 @@ vfp_restore_state(void) */ if (PCPU_GET(fpcurthread) != curthread || cpu != curpcb->pcb_vfpcpu) { - vfp_state = curthread->td_pcb->pcb_vfp; - fpcr = curthread->td_pcb->pcb_fpcr; - fpsr = curthread->td_pcb->pcb_fpsr; - - __asm __volatile( - "ldp q0, q1, [%2, #16 * 0]\n" - "ldp q2, q3, [%2, #16 * 2]\n" - "ldp q4, q5, [%2, #16 * 4]\n" - "ldp q6, q7, [%2, #16 * 6]\n" - "ldp q8, q9, [%2, #16 * 8]\n" - "ldp q10, q11, [%2, #16 * 10]\n" - "ldp q12, q13, [%2, #16 * 12]\n" - "ldp q14, q15, [%2, #16 * 14]\n" - "ldp q16, q17, [%2, #16 * 16]\n" - "ldp q18, q19, [%2, #16 * 18]\n" - "ldp q20, q21, [%2, #16 * 20]\n" - "ldp q22, q23, [%2, #16 * 22]\n" - "ldp q24, q25, [%2, #16 * 24]\n" - "ldp q26, q27, [%2, #16 * 26]\n" - "ldp q28, q29, [%2, #16 * 28]\n" - "ldp q30, q31, [%2, #16 * 30]\n" - "msr fpcr, %0 \n" - "msr fpsr, %1 \n" - : : "r"(fpcr), "r"(fpsr), "r"(vfp_state)); - + vfp_restore(curthread->td_pcb->pcb_fpusaved); PCPU_SET(fpcurthread, curthread); curpcb->pcb_vfpcpu = cpu; } diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index 1f8466d29d96..26050e768ce8 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -101,6 +101,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) td2->td_pcb->pcb_x[9] = (uintptr_t)td2; td2->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; td2->td_pcb->pcb_sp = (uintptr_t)td2->td_frame; + td2->td_pcb->pcb_fpusaved = &td2->td_pcb->pcb_fpustate; td2->td_pcb->pcb_vfpcpu = UINT_MAX; /* Setup to release spin count in fork_exit(). */ @@ -169,6 +170,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0) td->td_pcb->pcb_x[9] = (uintptr_t)td; td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; + td->td_pcb->pcb_fpusaved = &td->td_pcb->pcb_fpustate; td->td_pcb->pcb_vfpcpu = UINT_MAX; /* Setup to release spin count in fork_exit(). */ @@ -246,6 +248,7 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg) td->td_pcb->pcb_x[9] = (uintptr_t)arg; td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; + td->td_pcb->pcb_fpusaved = &td->td_pcb->pcb_fpustate; td->td_pcb->pcb_vfpcpu = UINT_MAX; } diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index f2d0e34c280f..1c8b73bea458 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -29,6 +29,7 @@ options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem diff --git a/sys/arm64/conf/RPI3 b/sys/arm64/conf/RPI3 new file mode 100644 index 000000000000..0ae44b16367a --- /dev/null +++ b/sys/arm64/conf/RPI3 @@ -0,0 +1,157 @@ +# +# +# RPI3 -- Custom configuration for the Raspberry Pi 3 +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ + +cpu ARM64 +ident RPI3 + +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +#makeoptions WITH_CTF=1 # Run ctfconvert(1) for DTrace support + +options SCHED_ULE # ULE scheduler +options PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP +options TCP_OFFLOAD # TCP offload +options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options MD_ROOT # MD is a potential root device +options NFSCL # Network Filesystem Client +options NFSD # Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_RAID # Soft RAID functionality. +options GEOM_LABEL # Provides labelization +options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI +options KTRACE # ktrace(1) support +options STACK # stack(9) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options AUDIT # Security event auditing +options CAPABILITY_MODE # Capsicum capability mode +options CAPABILITIES # Capsicum capabilities +options MAC # TrustedBSD MAC Framework +options KDTRACE_FRAME # Ensure frames are compiled in +options KDTRACE_HOOKS # Kernel DTrace hooks +options VFP # Floating-point support +options RACCT # Resource accounting framework +options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default +options RCTL # Resource limits +# SMP is not there yet +# options SMP +options INTRNG + +# Debugging support. Always need this: +options KDB # Enable kernel debugger support. +options KDB_TRACE # Print a stack trace for a panic. +# For full debugger support use (turn off in stable branch): +options DDB # Support DDB. +#options GDB # Support remote GDB. +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones + +options SOC_BRCM_BCM2837 + +options ROOTDEVNAME=\"ufs:mmcsd0s2\" + +# SPI +device spibus +device bcm2835_spi + +# MMC/SD/SDIO Card slot support +device sdhci +device mmc # mmc/sd bus +device mmcsd # mmc/sd flash cards + +# Serial (COM) ports +device uart # Generic UART driver +device uart_ns8250 # ns8250-type UART driver +device pl011 + +# USB support +options USB_DEBUG # enable debug msgs +device usb # USB Bus (required) +device dwcotg # DWC OTG controller + +# USB storage support +device scbus +device da +device umass + +# USB ethernet support +device smcphy +device mii +device smsc + +# Comment following lines for boot console on serial port +device vt +device kbdmux +device ukbd # Keyboard + +# GPIO +device gpio +device fdt_pinctrl +device gpioled + +# I2C +device iicbus +device bcm2835_bsc + +# Not ready for ARM64 yet +# device vchiq +# device sound + +# Pseudo devices. +device bpf +device loop # Network loopback +device random # Entropy device +device ether # Ethernet support +device vlan # 802.1Q VLAN support +device tun # Packet tunnel. +device md # Memory "disks" +device gif # IPv6 and IPv4 tunneling +device firmware # firmware assist module +device psci # Support for ARM PSCI + +options FDT + +# The crypto framework is required by IPSEC +device crypto # Required by IPSEC diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index d812124f869d..0818ba41b256 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -357,6 +357,10 @@ /* MAIR_EL1 - Memory Attribute Indirection Register */ #define MAIR_ATTR_MASK(idx) (0xff << ((n)* 8)) #define MAIR_ATTR(attr, idx) ((attr) << ((idx) * 8)) +#define MAIR_DEVICE_nGnRnE 0x00 +#define MAIR_NORMAL_NC 0x44 +#define MAIR_NORMAL_WT 0x88 +#define MAIR_NORMAL_WB 0xff /* PAR_EL1 - Physical Address Register */ #define PAR_F_SHIFT 0 diff --git a/sys/arm64/include/efi.h b/sys/arm64/include/efi.h index 5b5a7c49b503..026a1822d9ed 100644 --- a/sys/arm64/include/efi.h +++ b/sys/arm64/include/efi.h @@ -1,30 +1,5 @@ /*- - * Copyright (c) 2016 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Konstantin Belousov - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * This file is in the public domain since it's just boilerplate. * * $FreeBSD$ */ diff --git a/sys/arm64/include/pcb.h b/sys/arm64/include/pcb.h index 4426226c38f7..e76183409ae0 100644 --- a/sys/arm64/include/pcb.h +++ b/sys/arm64/include/pcb.h @@ -31,6 +31,8 @@ #ifndef LOCORE +#include + struct trapframe; #define PCB_LR 30 @@ -49,13 +51,17 @@ struct pcb { #define PCB_SINGLE_STEP_SHIFT 0 #define PCB_SINGLE_STEP (1 << PCB_SINGLE_STEP_SHIFT) - /* Place last to simplify the asm to access the rest if the struct */ - __uint128_t pcb_vfp[32]; - uint32_t pcb_fpcr; - uint32_t pcb_fpsr; + struct vfpstate *pcb_fpusaved; int pcb_fpflags; #define PCB_FP_STARTED 0x01 u_int pcb_vfpcpu; /* Last cpu this thread ran VFP code */ + + /* + * The userspace VFP state. The pcb_fpusaved pointer will point to + * this unless the kernel has allocated a VFP context. + * Place last to simplify the asm to access the rest if the struct. + */ + struct vfpstate pcb_fpustate; }; #ifdef _KERNEL diff --git a/sys/arm64/include/vfp.h b/sys/arm64/include/vfp.h index 39adf4fb742b..e22640862f33 100644 --- a/sys/arm64/include/vfp.h +++ b/sys/arm64/include/vfp.h @@ -32,9 +32,15 @@ #ifndef _MACHINE_VFP_H_ #define _MACHINE_VFP_H_ -#ifdef _KERNEL #ifndef LOCORE +struct vfpstate { + __uint128_t vfp_regs[32]; + uint32_t vfp_fpcr; + uint32_t vfp_fpsr; +}; + +#ifdef _KERNEL void vfp_init(void); void vfp_discard(struct thread *); void vfp_restore_state(void); diff --git a/sys/boot/arm/uboot/Makefile b/sys/boot/arm/uboot/Makefile index 7f0fd2e6433d..8b4b8caea591 100644 --- a/sys/boot/arm/uboot/Makefile +++ b/sys/boot/arm/uboot/Makefile @@ -77,8 +77,6 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE - .if ${MK_FORTH} != "no" # Enable BootForth BOOT_FORTH= yes diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h index 1ce70bf4df65..6bc6e5b33400 100644 --- a/sys/boot/common/bootstrap.h +++ b/sys/boot/common/bootstrap.h @@ -142,8 +142,6 @@ struct pnpinfo STAILQ_HEAD(pnpinfo_stql, pnpinfo); -extern struct pnpinfo_stql pnp_devices; - extern struct pnphandler *pnphandlers[]; /* provided by MD code */ void pnp_addident(struct pnpinfo *pi, char *ident); diff --git a/sys/boot/common/dev_net.c b/sys/boot/common/dev_net.c index 09583d0c831c..fddb17eefb28 100644 --- a/sys/boot/common/dev_net.c +++ b/sys/boot/common/dev_net.c @@ -120,11 +120,9 @@ net_open(struct open_file *f, ...) devname = va_arg(args, char*); va_end(args); -#ifdef NETIF_OPEN_CLOSE_ONCE /* Before opening another interface, close the previous one first. */ if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0) net_cleanup(); -#endif /* On first open, do netif open, mount, etc. */ if (netdev_opens == 0) { @@ -198,21 +196,6 @@ net_close(struct open_file *f) f->f_devdata = NULL; -#ifndef NETIF_OPEN_CLOSE_ONCE - /* Extra close call? */ - if (netdev_opens <= 0) - return (0); - netdev_opens--; - /* Not last close? */ - if (netdev_opens > 0) - return (0); - /* On last close, do netif close, etc. */ -#ifdef NETIF_DEBUG - if (debug) - printf("net_close: calling net_cleanup()\n"); -#endif - net_cleanup(); -#endif return (0); } diff --git a/sys/boot/common/interp.c b/sys/boot/common/interp.c index a683847945ce..f4117b9b3e58 100644 --- a/sys/boot/common/interp.c +++ b/sys/boot/common/interp.c @@ -104,8 +104,7 @@ interact(const char *rc) if (rc == NULL) { /* Read our default configuration. */ - if (include("/boot/loader.rc") != CMD_OK) - include("/boot/boot.conf"); + include("/boot/loader.rc"); } else if (*rc != '\0') include(rc); diff --git a/sys/boot/common/interp_forth.c b/sys/boot/common/interp_forth.c index bd59e0dda096..8efd887b5fa1 100644 --- a/sys/boot/common/interp_forth.c +++ b/sys/boot/common/interp_forth.c @@ -63,7 +63,6 @@ extern char bootprog_rev[]; FICL_SYSTEM *bf_sys; FICL_VM *bf_vm; -FICL_WORD *pInterp; /* * Shim for taking commands from BF and passing them out to 'standard' @@ -281,8 +280,6 @@ bf_init(const char *rc) ficlSetEnv(bf_sys, "loader_version", (bootprog_rev[0] - '0') * 10 + (bootprog_rev[2] - '0')); - pInterp = ficlLookup(bf_sys, "interpret"); - /* try to load and run init file if present */ if (rc == NULL) rc = "/boot/boot.4th"; @@ -293,9 +290,6 @@ bf_init(const char *rc) close(fd); } } - - /* Do this again, so that interpret can be redefined. */ - pInterp = ficlLookup(bf_sys, "interpret"); } /* diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8 index 7dff914d6407..55cbad4b1dae 100644 --- a/sys/boot/common/loader.8 +++ b/sys/boot/common/loader.8 @@ -90,9 +90,7 @@ which is default. After that, .Pa /boot/loader.rc -is processed if available, and, failing that, -.Pa /boot/boot.conf -is read for historical reasons. +is processed if available. These files are processed through the .Ic include command, which reads all of them into memory before processing them, @@ -957,10 +955,6 @@ itself. Additional .Tn FICL initialization. -.It Pa /boot/boot.conf -.Nm -bootstrapping script. -Deprecated. .It Pa /boot/defaults/loader.conf .It Pa /boot/loader.conf .It Pa /boot/loader.conf.local diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c index 80485f04dfef..f7e1c23e5dfc 100644 --- a/sys/boot/common/pnp.c +++ b/sys/boot/common/pnp.c @@ -17,8 +17,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include "ficl.h" -struct pnpinfo_stql pnp_devices; +static struct pnpinfo_stql pnp_devices; static int pnp_devices_initted = 0; static void pnp_discard(void); @@ -185,3 +186,47 @@ pnp_eisaformat(u_int8_t *data) return(idbuf); } +void +ficlPnpdevices(FICL_VM *pVM) +{ + static int pnp_devices_initted = 0; +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + if(!pnp_devices_initted) { + STAILQ_INIT(&pnp_devices); + pnp_devices_initted = 1; + } + + stackPushPtr(pVM->pStack, &pnp_devices); + + return; +} + +void +ficlPnphandlers(FICL_VM *pVM) +{ +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 0, 1); +#endif + + stackPushPtr(pVM->pStack, pnphandlers); + + return; +} + +/* + * Glue function to add the appropriate forth words to access pnp BIOS + * functionality. + */ +static void ficlCompilePnp(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT); + dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT); +} + +FICL_COMPILE_SET(ficlCompilePnp); diff --git a/sys/boot/efi/loader/Makefile b/sys/boot/efi/loader/Makefile index 597c53ca9048..d9d3532014fd 100644 --- a/sys/boot/efi/loader/Makefile +++ b/sys/boot/efi/loader/Makefile @@ -145,6 +145,7 @@ loader.efi: ${PROG} ${OBJCOPY} -j .peheader -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ + -j set_Xficl_compile_set \ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} LIBEFI= ${.OBJDIR}/../libefi/libefi.a diff --git a/sys/boot/efi/loader/arch/amd64/ldscript.amd64 b/sys/boot/efi/loader/arch/amd64/ldscript.amd64 index 53d9d760e0d0..874df9b08f9e 100644 --- a/sys/boot/efi/loader/arch/amd64/ldscript.amd64 +++ b/sys/boot/efi/loader/arch/amd64/ldscript.amd64 @@ -40,6 +40,11 @@ SECTIONS *(set_Xcommand_set) __stop_set_Xcommand_set = .; } + set_Xficl_compile_set : { + __start_set_Xficl_compile_set = .; + *(set_Xficl_compile_set) + __stop_set_Xficl_compile_set = .; + } . = ALIGN(4096); __gp = .; .sdata : { diff --git a/sys/boot/efi/loader/arch/arm/ldscript.arm b/sys/boot/efi/loader/arch/arm/ldscript.arm index 8b4a6dc64b36..7ff4cc6a4cb2 100644 --- a/sys/boot/efi/loader/arch/arm/ldscript.arm +++ b/sys/boot/efi/loader/arch/arm/ldscript.arm @@ -47,6 +47,11 @@ SECTIONS *(set_Xcommand_set) __stop_set_Xcommand_set = .; } + set_Xficl_compile_set : { + __start_set_Xficl_compile_set = .; + *(set_Xficl_compile_set) + __stop_set_Xficl_compile_set = .; + } __gp = .; .plt : { *(.plt) } .dynamic : { *(.dynamic) } diff --git a/sys/boot/efi/loader/arch/arm64/ldscript.arm64 b/sys/boot/efi/loader/arch/arm64/ldscript.arm64 index 29b807b25078..685c0967840d 100644 --- a/sys/boot/efi/loader/arch/arm64/ldscript.arm64 +++ b/sys/boot/efi/loader/arch/arm64/ldscript.arm64 @@ -43,6 +43,11 @@ SECTIONS *(set_Xcommand_set) __stop_set_Xcommand_set = .; } + set_Xficl_compile_set : { + __start_set_Xficl_compile_set = .; + *(set_Xficl_compile_set) + __stop_set_Xficl_compile_set = .; + } . = ALIGN(16); __gp = .; .sdata : { diff --git a/sys/boot/efi/loader/arch/i386/efimd.c b/sys/boot/efi/loader/arch/i386/efimd.c index 01905e664fdd..8e1d850d82cc 100644 --- a/sys/boot/efi/loader/arch/i386/efimd.c +++ b/sys/boot/efi/loader/arch/i386/efimd.c @@ -48,7 +48,10 @@ static EFI_GUID hcdp_guid = HCDP_TABLE_GUID; static UINTN mapkey; -uint64_t +int ldr_bootinfo(struct bootinfo *, uint64_t *); +int ldr_enter(const char *); + +static uint64_t ldr_alloc(vm_offset_t va) { diff --git a/sys/boot/efi/loader/arch/i386/elf32_freebsd.c b/sys/boot/efi/loader/arch/i386/elf32_freebsd.c index b3a18d27d387..d3c42613108e 100644 --- a/sys/boot/efi/loader/arch/i386/elf32_freebsd.c +++ b/sys/boot/efi/loader/arch/i386/elf32_freebsd.c @@ -35,12 +35,16 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include + #include "bootstrap.h" #include "../libi386/libi386.h" #include "../btx/lib/btxv86.h" extern void __exec(caddr_t addr, ...); - +extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp); +extern int ldr_enter(const char *kernel); static int elf32_exec(struct preloaded_file *amp); static int elf32_obj_exec(struct preloaded_file *amp); @@ -72,14 +76,14 @@ elf32_exec(struct preloaded_file *fp) ehdr = (Elf_Ehdr *)&(md->md_data); efi_time_fini(); - err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend); + err = bi_load(fp->f_args, &modulep, &kernend); if (err != 0) { efi_time_init(); return(err); } entry = ehdr->e_entry & 0xffffff; - printf("Start @ 0x%lx ...\n", entry); + printf("Start @ 0x%x ...\n", entry); ldr_enter(fp->f_name); diff --git a/sys/boot/efi/loader/arch/i386/exec.c b/sys/boot/efi/loader/arch/i386/exec.c index 579f5593b24b..12a367cda5c2 100644 --- a/sys/boot/efi/loader/arch/i386/exec.c +++ b/sys/boot/efi/loader/arch/i386/exec.c @@ -36,6 +36,12 @@ __FBSDID("$FreeBSD$"); uint32_t __base; struct __v86 __v86; +/* XXX - Needed a definition here to implicitly define exit(); do not remove. */ +static void +exit(int x) +{ +} + void __v86int() { diff --git a/sys/boot/efi/loader/arch/i386/ldscript.i386 b/sys/boot/efi/loader/arch/i386/ldscript.i386 index 4b28c104a3fe..e17212a1bddd 100644 --- a/sys/boot/efi/loader/arch/i386/ldscript.i386 +++ b/sys/boot/efi/loader/arch/i386/ldscript.i386 @@ -35,6 +35,11 @@ SECTIONS *(set_Xcommand_set) __stop_set_Xcommand_set = .; } + set_Xficl_compile_set : { + __start_set_Xficl_compile_set = .; + *(set_Xficl_compile_set) + __stop_set_Xficl_compile_set = .; + } . = ALIGN(4096); __gp = .; .sdata : { diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index 18b0f3cfec27..b5f2fd6bcca1 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -235,6 +235,7 @@ main(int argc, CHAR16 *argv[]) uint64_t pool_guid; UINTN k; int has_kbd; + char buf[40]; archsw.arch_autoload = efi_autoload; archsw.arch_getdev = efi_getdev; @@ -447,6 +448,9 @@ main(int argc, CHAR16 *argv[]) for (k = 0; k < ST->NumberOfTableEntries; k++) { guid = &ST->ConfigurationTable[k].VendorGuid; if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { + snprintf(buf, sizeof(buf), "%p", + ST->ConfigurationTable[k].VendorTable); + setenv("hint.smbios.0.mem", buf, 1); smbios_detect(ST->ConfigurationTable[k].VendorTable); break; } @@ -603,7 +607,8 @@ command_configuration(int argc, char *argv[]) else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID))) printf("ACPI 2.0 Table"); else if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) - printf("SMBIOS Table"); + printf("SMBIOS Table %p", + ST->ConfigurationTable[i].VendorTable); else if (!memcmp(guid, &dxe, sizeof(EFI_GUID))) printf("DXE Table"); else if (!memcmp(guid, &hoblist, sizeof(EFI_GUID))) diff --git a/sys/boot/ficl/ficl.h b/sys/boot/ficl/ficl.h index 6fe9e10aba20..8829ccea9668 100644 --- a/sys/boot/ficl/ficl.h +++ b/sys/boot/ficl/ficl.h @@ -1150,6 +1150,13 @@ typedef struct ficlFILE } ficlFILE; #endif +#include + +typedef void ficlCompileFcn(FICL_SYSTEM *); +#define FICL_COMPILE_SET(func) \ + DATA_SET(Xficl_compile_set, func) +SET_DECLARE(Xficl_compile_set, ficlCompileFcn); + #ifdef __cplusplus } #endif diff --git a/sys/boot/ficl/i386/sysdep.c b/sys/boot/ficl/i386/sysdep.c index df0891ddd5d0..ea594e63808f 100644 --- a/sys/boot/ficl/i386/sysdep.c +++ b/sys/boot/ficl/i386/sysdep.c @@ -81,7 +81,6 @@ void ficlFree (void *p) } #ifndef TESTMAIN -#ifdef __i386__ /* * outb ( port# c -- ) * Store a byte to I/O port number port# @@ -111,7 +110,22 @@ ficlInb(FICL_VM *pVM) c=inb(port); stackPushINT(pVM->pStack,c); } -#endif + +/* + * Glue function to add the appropriate forth words to access x86 special cpu + * functionality. + */ +static void ficlCompileCpufunc(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); + dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); +} + +FICL_COMPILE_SET(ficlCompileCpufunc); + #endif /* diff --git a/sys/boot/ficl/loader.c b/sys/boot/ficl/loader.c index 04e555c32803..197f15bf38c3 100644 --- a/sys/boot/ficl/loader.c +++ b/sys/boot/ficl/loader.c @@ -287,43 +287,6 @@ ficlFindfile(FICL_VM *pVM) return; } -#ifndef TESTMAIN -#ifdef HAVE_PNP - -void -ficlPnpdevices(FICL_VM *pVM) -{ - static int pnp_devices_initted = 0; -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 0, 1); -#endif - - if(!pnp_devices_initted) { - STAILQ_INIT(&pnp_devices); - pnp_devices_initted = 1; - } - - stackPushPtr(pVM->pStack, &pnp_devices); - - return; -} - -void -ficlPnphandlers(FICL_VM *pVM) -{ -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 0, 1); -#endif - - stackPushPtr(pVM->pStack, pnphandlers); - - return; -} - -#endif - -#endif /* ndef TESTMAIN */ - void ficlCcall(FICL_VM *pVM) { @@ -800,141 +763,6 @@ static void fkey(FICL_VM *pVM) } -#ifdef __i386__ -/* - * pcibios-device-count (devid -- count) - * - * Returns the PCI BIOS' count of how many devices matching devid are in the system. - * devid is the 32-bit vendor + device. - */ -static void -ficlPciBiosCountDevices(FICL_VM *pVM) -{ - uint32_t devid; - int i; - - devid = stackPopINT(pVM->pStack); - - i = biospci_count_device_type(devid); - - stackPushINT(pVM->pStack, i); -} - -/* - * pcibios-write-config (locator offset width value -- ) - * - * Writes the specified config register. - * Locator is bus << 8 | device << 3 | fuction - * offset is the pci config register - * width is 0 for byte, 1 for word, 2 for dword - * value is the value to write - */ -static void -ficlPciBiosWriteConfig(FICL_VM *pVM) -{ - uint32_t value, width, offset, locator; - - value = stackPopINT(pVM->pStack); - width = stackPopINT(pVM->pStack); - offset = stackPopINT(pVM->pStack); - locator = stackPopINT(pVM->pStack); - - biospci_write_config(locator, offset, width, value); -} - -/* - * pcibios-read-config (locator offset width -- value) - * - * Reads the specified config register. - * Locator is bus << 8 | device << 3 | fuction - * offset is the pci config register - * width is 0 for byte, 1 for word, 2 for dword - * value is the value to read from the register - */ -static void -ficlPciBiosReadConfig(FICL_VM *pVM) -{ - uint32_t value, width, offset, locator; - - width = stackPopINT(pVM->pStack); - offset = stackPopINT(pVM->pStack); - locator = stackPopINT(pVM->pStack); - - biospci_read_config(locator, offset, width, &value); - - stackPushINT(pVM->pStack, value); -} - -/* - * pcibios-find-devclass (class index -- locator) - * - * Finds the index'th instance of class in the pci tree. - * must be an exact match. - * class is the class to search for. - * index 0..N (set to 0, increment until error) - * - * Locator is bus << 8 | device << 3 | fuction (or -1 on error) - */ -static void -ficlPciBiosFindDevclass(FICL_VM *pVM) -{ - uint32_t index, class, locator; - - index = stackPopINT(pVM->pStack); - class = stackPopINT(pVM->pStack); - - if (biospci_find_devclass(class, index, &locator)) - locator = 0xffffffff; - - stackPushINT(pVM->pStack, locator); -} - -/* - * pcibios-find-device(devid index -- locator) - * - * Finds the index'th instance of devid in the pci tree. - * must be an exact match. - * class is the class to search for. - * index 0..N (set to 0, increment until error) - * - * Locator is bus << 8 | device << 3 | fuction (or -1 on error) - */ -static void -ficlPciBiosFindDevice(FICL_VM *pVM) -{ - uint32_t index, devid, locator; - - index = stackPopINT(pVM->pStack); - devid = stackPopINT(pVM->pStack); - - if (biospci_find_device(devid, index, &locator)) - locator = 0xffffffff; - - stackPushINT(pVM->pStack, locator); -} - -/* - * pcibios-find-device(bus device function -- locator) - * - * converts bus, device, function to locator. - * - * Locator is bus << 8 | device << 3 | fuction - */ -static void -ficlPciBiosLocator(FICL_VM *pVM) -{ - uint32_t bus, device, function, locator; - - function = stackPopINT(pVM->pStack); - device = stackPopINT(pVM->pStack); - bus = stackPopINT(pVM->pStack); - - locator = biospci_locator(bus, device, function); - - stackPushINT(pVM->pStack, locator); -} -#endif - /* ** Retrieves free space remaining on the dictionary */ @@ -963,6 +791,7 @@ static void ficlDictIncrease(FICL_VM *pVM) **************************************************************************/ void ficlCompilePlatform(FICL_SYSTEM *pSys) { + ficlCompileFcn **fnpp; FICL_DICT *dp = pSys->dp; assert (dp); @@ -994,24 +823,10 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys) dictAppendWord(dp, "ccall", ficlCcall, FW_DEFAULT); dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT); dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT); -#ifndef TESTMAIN -#ifdef __i386__ - dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); - dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); -#endif -#ifdef HAVE_PNP - dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT); - dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT); -#endif -#endif -#ifdef __i386__ - dictAppendWord(dp, "pcibios-device-count", ficlPciBiosCountDevices, FW_DEFAULT); - dictAppendWord(dp, "pcibios-read-config", ficlPciBiosReadConfig, FW_DEFAULT); - dictAppendWord(dp, "pcibios-write-config", ficlPciBiosWriteConfig, FW_DEFAULT); - dictAppendWord(dp, "pcibios-find-devclass", ficlPciBiosFindDevclass, FW_DEFAULT); - dictAppendWord(dp, "pcibios-find-device", ficlPciBiosFindDevice, FW_DEFAULT); - dictAppendWord(dp, "pcibios-locator", ficlPciBiosLocator, FW_DEFAULT); -#endif + + SET_FOREACH(fnpp, Xficl_compile_set) { + (*fnpp)(pSys); + } #if defined(PC98) ficlSetEnv(pSys, "arch-pc98", FICL_TRUE); diff --git a/sys/boot/i386/libi386/Makefile b/sys/boot/i386/libi386/Makefile index f1c55f19beae..88c1c07ab486 100644 --- a/sys/boot/i386/libi386/Makefile +++ b/sys/boot/i386/libi386/Makefile @@ -54,7 +54,8 @@ CFLAGS+= -DTERM_EMU # XXX: make alloca() useable CFLAGS+= -Dalloca=__builtin_alloca -CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../common \ +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 \ + -I${.CURDIR}/../../common -I${.CURDIR}/../common \ -I${.CURDIR}/../btx/lib \ -I${.CURDIR}/../../../contrib/dev/acpica/include \ -I${.CURDIR}/../../.. -I. diff --git a/sys/boot/i386/libi386/biospci.c b/sys/boot/i386/libi386/biospci.c index 196590e1bf97..331f1526617e 100644 --- a/sys/boot/i386/libi386/biospci.c +++ b/sys/boot/i386/libi386/biospci.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 1998 Michael Smith + * Copyright (c) 2016 Netflix, Inc * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include "libi386.h" +#include "ficl.h" /* * Stupid PCI BIOS interface doesn't let you simply enumerate everything @@ -188,7 +190,6 @@ static struct pci_class {-1, NULL, NULL} }; - static void biospci_enumerate(void); static void biospci_addinfo(int devid, struct pci_class *pc, struct pci_subclass *psc, struct pci_progif *ppi); @@ -197,6 +198,7 @@ struct pnphandler biospcihandler = "PCI BIOS", biospci_enumerate }; +static int biospci_version; #define PCI_BIOS_PRESENT 0xb101 #define FIND_PCI_DEVICE 0xb102 @@ -252,7 +254,7 @@ biospci_detect(void) setenv("pcibios.config2", buf, 1); sprintf(buf, "%d", maxbus); setenv("pcibios.maxbus", buf, 1); - + biospci_version = bcd2bin((version >> 8) & 0xf) * 10 + bcd2bin(version & 0xf); } static void @@ -338,7 +340,7 @@ biospci_find_devclass(uint32_t class, int index, uint32_t *locator) return (0); } -int +static int biospci_find_device(uint32_t devid, int index, uint32_t *locator) { v86.ctl = V86_FLAGS; @@ -407,7 +409,7 @@ biospci_locator(int8_t bus, uint8_t device, uint8_t function) * Counts the number of instances of devid we have in the system, as least as * far as the PCI BIOS is able to tell. */ -int +static int biospci_count_device_type(uint32_t devid) { int i; @@ -426,3 +428,157 @@ biospci_count_device_type(uint32_t devid) } return i; } + +/* + * pcibios-device-count (devid -- count) + * + * Returns the PCI BIOS' count of how many devices matching devid are in the system. + * devid is the 32-bit vendor + device. + */ +static void +ficlPciBiosCountDevices(FICL_VM *pVM) +{ + uint32_t devid; + int i; + + devid = stackPopINT(pVM->pStack); + + i = biospci_count_device_type(devid); + + stackPushINT(pVM->pStack, i); +} + +/* + * pcibios-write-config (locator offset width value -- ) + * + * Writes the specified config register. + * Locator is bus << 8 | device << 3 | fuction + * offset is the pci config register + * width is 0 for byte, 1 for word, 2 for dword + * value is the value to write + */ +static void +ficlPciBiosWriteConfig(FICL_VM *pVM) +{ + uint32_t value, width, offset, locator; + + value = stackPopINT(pVM->pStack); + width = stackPopINT(pVM->pStack); + offset = stackPopINT(pVM->pStack); + locator = stackPopINT(pVM->pStack); + + biospci_write_config(locator, offset, width, value); +} + +/* + * pcibios-read-config (locator offset width -- value) + * + * Reads the specified config register. + * Locator is bus << 8 | device << 3 | fuction + * offset is the pci config register + * width is 0 for byte, 1 for word, 2 for dword + * value is the value to read from the register + */ +static void +ficlPciBiosReadConfig(FICL_VM *pVM) +{ + uint32_t value, width, offset, locator; + + width = stackPopINT(pVM->pStack); + offset = stackPopINT(pVM->pStack); + locator = stackPopINT(pVM->pStack); + + biospci_read_config(locator, offset, width, &value); + + stackPushINT(pVM->pStack, value); +} + +/* + * pcibios-find-devclass (class index -- locator) + * + * Finds the index'th instance of class in the pci tree. + * must be an exact match. + * class is the class to search for. + * index 0..N (set to 0, increment until error) + * + * Locator is bus << 8 | device << 3 | fuction (or -1 on error) + */ +static void +ficlPciBiosFindDevclass(FICL_VM *pVM) +{ + uint32_t index, class, locator; + + index = stackPopINT(pVM->pStack); + class = stackPopINT(pVM->pStack); + + if (biospci_find_devclass(class, index, &locator)) + locator = 0xffffffff; + + stackPushINT(pVM->pStack, locator); +} + +/* + * pcibios-find-device(devid index -- locator) + * + * Finds the index'th instance of devid in the pci tree. + * must be an exact match. + * class is the class to search for. + * index 0..N (set to 0, increment until error) + * + * Locator is bus << 8 | device << 3 | fuction (or -1 on error) + */ +static void +ficlPciBiosFindDevice(FICL_VM *pVM) +{ + uint32_t index, devid, locator; + + index = stackPopINT(pVM->pStack); + devid = stackPopINT(pVM->pStack); + + if (biospci_find_device(devid, index, &locator)) + locator = 0xffffffff; + + stackPushINT(pVM->pStack, locator); +} + +/* + * pcibios-find-device(bus device function -- locator) + * + * converts bus, device, function to locator. + * + * Locator is bus << 8 | device << 3 | fuction + */ +static void +ficlPciBiosLocator(FICL_VM *pVM) +{ + uint32_t bus, device, function, locator; + + function = stackPopINT(pVM->pStack); + device = stackPopINT(pVM->pStack); + bus = stackPopINT(pVM->pStack); + + locator = biospci_locator(bus, device, function); + + stackPushINT(pVM->pStack, locator); +} + +/* + * Glue function to add the appropriate forth words to access pci bios + * functionality. + */ +static void ficlCompilePciBios(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "pcibios-device-count", ficlPciBiosCountDevices, FW_DEFAULT); + dictAppendWord(dp, "pcibios-read-config", ficlPciBiosReadConfig, FW_DEFAULT); + dictAppendWord(dp, "pcibios-write-config", ficlPciBiosWriteConfig, FW_DEFAULT); + dictAppendWord(dp, "pcibios-find-devclass", ficlPciBiosFindDevclass, FW_DEFAULT); + dictAppendWord(dp, "pcibios-find-device", ficlPciBiosFindDevice, FW_DEFAULT); + dictAppendWord(dp, "pcibios-locator", ficlPciBiosLocator, FW_DEFAULT); + + ficlSetEnv(pSys, "pcibios-version", biospci_version); +} + +FICL_COMPILE_SET(ficlCompilePciBios); diff --git a/sys/boot/i386/libi386/libi386.h b/sys/boot/i386/libi386/libi386.h index 839745d67abd..76f02718ccdb 100644 --- a/sys/boot/i386/libi386/libi386.h +++ b/sys/boot/i386/libi386/libi386.h @@ -104,12 +104,10 @@ extern uint32_t high_heap_size; /* extended memory region available */ extern vm_offset_t high_heap_base; /* for use as the heap */ void biospci_detect(void); -int biospci_count_device_type(uint32_t devid); -int biospci_find_devclass(uint32_t class, int index, uint32_t *locator); -int biospci_find_device(uint32_t devid, int index, uint32_t *locator); -int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val); -int biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val); +int biospci_find_devclass(uint32_t class, int index, uint32_t *locator); +int biospci_read_config(uint32_t locator, int offset, int width, uint32_t *val); uint32_t biospci_locator(int8_t bus, uint8_t device, uint8_t function); +int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val); void biosacpi_detect(void); diff --git a/sys/boot/mips/beri/loader/loader.ldscript b/sys/boot/mips/beri/loader/loader.ldscript index b4e804738dc3..f3d286ae61e4 100644 --- a/sys/boot/mips/beri/loader/loader.ldscript +++ b/sys/boot/mips/beri/loader/loader.ldscript @@ -65,6 +65,10 @@ SECTIONS __start_set_Xcommand_set = .; KEEP(*(set_Xcommand_set)) __stop_set_Xcommand_set = .; + + __start_set_Xficl_compile_set = .; + KEEP(*(set_Xficl_compile_set)) + __stop_set_Xficl_compile_set = .; } .data ALIGN(0x10): { *(.data*)} .bss ALIGN(0x10): { *(.bss*) } diff --git a/sys/boot/mips/uboot/Makefile b/sys/boot/mips/uboot/Makefile index b350ae47386b..6be362c86564 100644 --- a/sys/boot/mips/uboot/Makefile +++ b/sys/boot/mips/uboot/Makefile @@ -81,8 +81,6 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE - .if ${MK_FORTH} != "no" # Enable BootForth BOOT_FORTH= yes diff --git a/sys/boot/pc98/libpc98/Makefile b/sys/boot/pc98/libpc98/Makefile index 6b11de9f6999..f3e27a4c679d 100644 --- a/sys/boot/pc98/libpc98/Makefile +++ b/sys/boot/pc98/libpc98/Makefile @@ -37,7 +37,8 @@ CFLAGS+= -DTERM_EMU # XXX: make alloca() useable CFLAGS+= -Dalloca=__builtin_alloca -CFLAGS+= -I${.CURDIR}/../../common \ +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 \ + -I${.CURDIR}/../../common \ -I${.CURDIR}/../btx/lib \ -I${.CURDIR}/../../i386/libi386 \ -I${.CURDIR}/../../.. -I. diff --git a/sys/boot/powerpc/kboot/Makefile b/sys/boot/powerpc/kboot/Makefile index 6218b7e4d7eb..c161a9cd2e73 100644 --- a/sys/boot/powerpc/kboot/Makefile +++ b/sys/boot/powerpc/kboot/Makefile @@ -68,10 +68,7 @@ CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .endif -# Avoid the open-close-dance for every file access as some firmwares perform -# an auto-negotiation on every open of the network interface and thus causes -# netbooting to take horribly long. -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE -mcpu=powerpc64 +CFLAGS+= -mcpu=powerpc64 # Always add MI sources .PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern diff --git a/sys/boot/powerpc/ofw/Makefile b/sys/boot/powerpc/ofw/Makefile index ab5720fb1f40..eccf3c5d3bea 100644 --- a/sys/boot/powerpc/ofw/Makefile +++ b/sys/boot/powerpc/ofw/Makefile @@ -67,11 +67,6 @@ CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .endif -# Avoid the open-close-dance for every file access as some firmwares perform -# an auto-negotiation on every open of the network interface and thus causes -# netbooting to take horribly long. -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE - # Always add MI sources .PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern .include "${.CURDIR}/../../common/Makefile.inc" diff --git a/sys/boot/powerpc/ps3/Makefile b/sys/boot/powerpc/ps3/Makefile index baf2507a6b51..0cbc166ff25e 100644 --- a/sys/boot/powerpc/ps3/Makefile +++ b/sys/boot/powerpc/ps3/Makefile @@ -68,10 +68,7 @@ CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .endif -# Avoid the open-close-dance for every file access as some firmwares perform -# an auto-negotiation on every open of the network interface and thus causes -# netbooting to take horribly long. -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE -mcpu=powerpc64 +CFLAGS+= -mcpu=powerpc64 # Always add MI sources .PATH: ${.CURDIR}/../../common ${.CURDIR}/../../../libkern diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile index 05d23ff19265..2884cf082cfa 100644 --- a/sys/boot/sparc64/loader/Makefile +++ b/sys/boot/sparc64/loader/Makefile @@ -69,10 +69,6 @@ LIBFICL= ${.OBJDIR}/../../ficl/libficl.a .include "${.CURDIR}/../../common/Makefile.inc" CFLAGS+= -I${.CURDIR}/../../common CFLAGS+= -I. -# Avoid the open-close-dance for every file access as some firmwares perform -# an auto-negotiation on every open of the network interface and thus causes -# netbooting to take horribly long. -CFLAGS+= -DNETIF_OPEN_CLOSE_ONCE CLEANFILES+= vers.c loader.help diff --git a/sys/boot/userboot/userboot/Makefile b/sys/boot/userboot/userboot/Makefile index cdc29d192d9d..8be9c972ca9e 100644 --- a/sys/boot/userboot/userboot/Makefile +++ b/sys/boot/userboot/userboot/Makefile @@ -51,9 +51,10 @@ BOOT_FORTH= yes CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/i386 CFLAGS+= -DBF_DICTSIZE=15000 LIBFICL= ${.OBJDIR}/../ficl/libficl.a -LIBSTAND= ${.OBJDIR}/../libstand/libstand.a .endif +LIBSTAND= ${.OBJDIR}/../libstand/libstand.a + .if ${MK_ZFS} != "no" CFLAGS+= -DUSERBOOT_ZFS_SUPPORT LIBZFSBOOT= ${.OBJDIR}/../zfs/libzfsboot.a diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c index b3d861931568..465b6d21cfc7 100644 --- a/sys/cam/cam_compat.c +++ b/sys/cam/cam_compat.c @@ -228,7 +228,7 @@ cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, cts = &ccb->cts; cts17 = (struct ccb_trans_settings_0x17 *)hdr17; - cts17->type = cts17->type; + cts17->type = cts->type; cts17->protocol = cts->protocol; cts17->protocol_version = cts->protocol_version; cts17->transport = cts->transport; @@ -335,7 +335,7 @@ cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag, cts = &ccb->cts; cts18 = (struct ccb_trans_settings_0x18 *)hdr18; - cts18->type = cts18->type; + cts18->type = cts->type; cts18->protocol = cts->protocol; cts18->protocol_version = cts->protocol_version; cts18->transport = cts->transport; diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 83e22895a485..89c1304c6b44 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -9903,6 +9903,7 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) { struct scsi_vpd_block_limits *bl_ptr; struct ctl_lun *lun; + uint64_t ival; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -9941,8 +9942,14 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) if (lun != NULL) { scsi_ulto4b(lun->be_lun->opttxferlen, bl_ptr->opt_txfer_len); if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { - scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); - scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt); + ival = 0xffffffff; + ctl_get_opt_number(&lun->be_lun->options, + "unmap_max_lba", &ival); + scsi_ulto4b(ival, bl_ptr->max_unmap_lba_cnt); + ival = 0xffffffff; + ctl_get_opt_number(&lun->be_lun->options, + "unmap_max_descr", &ival); + scsi_ulto4b(ival, bl_ptr->max_unmap_blk_cnt); if (lun->be_lun->ublockexp != 0) { scsi_ulto4b((1 << lun->be_lun->ublockexp), bl_ptr->opt_unmap_grain); @@ -9956,8 +9963,10 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) scsi_ulto4b(0, bl_ptr->atomic_transfer_length_granularity); scsi_ulto4b(0, bl_ptr->max_atomic_transfer_length_with_atomic_boundary); scsi_ulto4b(0, bl_ptr->max_atomic_boundary_size); + ival = UINT64_MAX; + ctl_get_opt_number(&lun->be_lun->options, "write_same_max_lba", &ival); + scsi_u64to8b(ival, bl_ptr->max_write_same_length); } - scsi_u64to8b(UINT64_MAX, bl_ptr->max_write_same_length); ctl_set_success(ctsio); ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -10031,6 +10040,7 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) { struct scsi_vpd_logical_block_prov *lbp_ptr; struct ctl_lun *lun; + const char *value; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -10068,7 +10078,14 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) if (lun != NULL && lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 | SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP; - lbp_ptr->prov_type = SVPD_LBP_THIN; + value = ctl_get_opt(&lun->be_lun->options, "provisioning_type"); + if (value != NULL) { + if (strcmp(value, "resource") == 0) + lbp_ptr->prov_type = SVPD_LBP_RESOURCE; + else if (strcmp(value, "thin") == 0) + lbp_ptr->prov_type = SVPD_LBP_THIN; + } else + lbp_ptr->prov_type = SVPD_LBP_THIN; } ctl_set_success(ctsio); diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index ba78ff0371ad..3c47a6f033de 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -217,6 +217,7 @@ void ctl_update_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args); void ctl_free_opts(ctl_options_t *opts); char * ctl_get_opt(ctl_options_t *opts, const char *name); +int ctl_get_opt_number(ctl_options_t *opts, const char *name, uint64_t *num); int ctl_expand_number(const char *buf, uint64_t *num); #endif /* _KERNEL */ diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index 91576c485cb4..86f7d3c35a70 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -243,3 +243,14 @@ ctl_get_opt(ctl_options_t *opts, const char *name) } return (NULL); } + +int +ctl_get_opt_number(ctl_options_t *opts, const char *name, uint64_t *val) +{ + const char *value; + + value = ctl_get_opt(opts, name); + if (value == NULL) + return (-2); + return (ctl_expand_number(value, val)); +} diff --git a/sys/cam/scsi/scsi_enc_ses.c b/sys/cam/scsi/scsi_enc_ses.c index dfb232afcd13..283e2e3ac823 100644 --- a/sys/cam/scsi/scsi_enc_ses.c +++ b/sys/cam/scsi/scsi_enc_ses.c @@ -2672,13 +2672,13 @@ ses_get_elm_devnames(enc_softc_t *enc, encioc_elm_devnames_t *elmdn) if (len < 0) return (EINVAL); - sbuf_new(&sb, elmdn->elm_devnames, len, 0); - cam_periph_unlock(enc->periph); + sbuf_new(&sb, NULL, len, SBUF_FIXEDLEN); ses_paths_iter(enc, &enc->enc_cache.elm_map[elmdn->elm_idx], ses_elmdevname_callback, &sb); sbuf_finish(&sb); elmdn->elm_names_len = sbuf_len(&sb); + copyout(sbuf_data(&sb), elmdn->elm_devnames, elmdn->elm_names_len + 1); cam_periph_lock(enc->periph); return (elmdn->elm_names_len > 0 ? 0 : ENODEV); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index f31ad2fe8f70..27de40bdf20d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -1207,18 +1207,83 @@ dmu_objset_userused_enabled(objset_t *os) DMU_USERUSED_DNODE(os) != NULL); } +typedef struct userquota_node { + uint64_t uqn_id; + int64_t uqn_delta; + avl_node_t uqn_node; +} userquota_node_t; + +typedef struct userquota_cache { + avl_tree_t uqc_user_deltas; + avl_tree_t uqc_group_deltas; +} userquota_cache_t; + +static int +userquota_compare(const void *l, const void *r) +{ + const userquota_node_t *luqn = l; + const userquota_node_t *ruqn = r; + + if (luqn->uqn_id < ruqn->uqn_id) + return (-1); + if (luqn->uqn_id > ruqn->uqn_id) + return (1); + return (0); +} + static void -do_userquota_update(objset_t *os, uint64_t used, uint64_t flags, - uint64_t user, uint64_t group, boolean_t subtract, dmu_tx_t *tx) +do_userquota_cacheflush(objset_t *os, userquota_cache_t *cache, dmu_tx_t *tx) +{ + void *cookie; + userquota_node_t *uqn; + + ASSERT(dmu_tx_is_syncing(tx)); + + cookie = NULL; + while ((uqn = avl_destroy_nodes(&cache->uqc_user_deltas, + &cookie)) != NULL) { + VERIFY0(zap_increment_int(os, DMU_USERUSED_OBJECT, + uqn->uqn_id, uqn->uqn_delta, tx)); + kmem_free(uqn, sizeof (*uqn)); + } + avl_destroy(&cache->uqc_user_deltas); + + cookie = NULL; + while ((uqn = avl_destroy_nodes(&cache->uqc_group_deltas, + &cookie)) != NULL) { + VERIFY0(zap_increment_int(os, DMU_GROUPUSED_OBJECT, + uqn->uqn_id, uqn->uqn_delta, tx)); + kmem_free(uqn, sizeof (*uqn)); + } + avl_destroy(&cache->uqc_group_deltas); +} + +static void +userquota_update_cache(avl_tree_t *avl, uint64_t id, int64_t delta) +{ + userquota_node_t search = { .uqn_id = id }; + avl_index_t idx; + + userquota_node_t *uqn = avl_find(avl, &search, &idx); + if (uqn == NULL) { + uqn = kmem_zalloc(sizeof (*uqn), KM_SLEEP); + uqn->uqn_id = id; + avl_insert(avl, uqn, idx); + } + uqn->uqn_delta += delta; +} + +static void +do_userquota_update(userquota_cache_t *cache, uint64_t used, uint64_t flags, + uint64_t user, uint64_t group, boolean_t subtract) { if ((flags & DNODE_FLAG_USERUSED_ACCOUNTED)) { int64_t delta = DNODE_SIZE + used; if (subtract) delta = -delta; - VERIFY3U(0, ==, zap_increment_int(os, DMU_USERUSED_OBJECT, - user, delta, tx)); - VERIFY3U(0, ==, zap_increment_int(os, DMU_GROUPUSED_OBJECT, - group, delta, tx)); + + userquota_update_cache(&cache->uqc_user_deltas, user, delta); + userquota_update_cache(&cache->uqc_group_deltas, group, delta); } } @@ -1227,9 +1292,15 @@ dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx) { dnode_t *dn; list_t *list = &os->os_synced_dnodes; + userquota_cache_t cache = { 0 }; ASSERT(list_head(list) == NULL || dmu_objset_userused_enabled(os)); + avl_create(&cache.uqc_user_deltas, userquota_compare, + sizeof (userquota_node_t), offsetof(userquota_node_t, uqn_node)); + avl_create(&cache.uqc_group_deltas, userquota_compare, + sizeof (userquota_node_t), offsetof(userquota_node_t, uqn_node)); + while (dn = list_head(list)) { int flags; ASSERT(!DMU_OBJECT_IS_SPECIAL(dn->dn_object)); @@ -1239,32 +1310,26 @@ dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx) /* Allocate the user/groupused objects if necessary. */ if (DMU_USERUSED_DNODE(os)->dn_type == DMU_OT_NONE) { - VERIFY(0 == zap_create_claim(os, + VERIFY0(zap_create_claim(os, DMU_USERUSED_OBJECT, DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); - VERIFY(0 == zap_create_claim(os, + VERIFY0(zap_create_claim(os, DMU_GROUPUSED_OBJECT, DMU_OT_USERGROUP_USED, DMU_OT_NONE, 0, tx)); } - /* - * We intentionally modify the zap object even if the - * net delta is zero. Otherwise - * the block of the zap obj could be shared between - * datasets but need to be different between them after - * a bprewrite. - */ - flags = dn->dn_id_flags; ASSERT(flags); if (flags & DN_ID_OLD_EXIST) { - do_userquota_update(os, dn->dn_oldused, dn->dn_oldflags, - dn->dn_olduid, dn->dn_oldgid, B_TRUE, tx); + do_userquota_update(&cache, + dn->dn_oldused, dn->dn_oldflags, + dn->dn_olduid, dn->dn_oldgid, B_TRUE); } if (flags & DN_ID_NEW_EXIST) { - do_userquota_update(os, DN_USED_BYTES(dn->dn_phys), + do_userquota_update(&cache, + DN_USED_BYTES(dn->dn_phys), dn->dn_phys->dn_flags, dn->dn_newuid, - dn->dn_newgid, B_FALSE, tx); + dn->dn_newgid, B_FALSE); } mutex_enter(&dn->dn_mtx); @@ -1285,6 +1350,7 @@ dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx) list_remove(list, dn); dnode_rele(dn, list); } + do_userquota_cacheflush(os, &cache, tx); } /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index d8c5c28211f5..1f81ec98e046 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -27,6 +27,7 @@ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright 2013 Saso Kiselkov. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Toomas Soome */ /* @@ -539,12 +540,6 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) &propval)) == 0 && !BOOTFS_COMPRESS_VALID(propval)) { error = SET_ERROR(ENOTSUP); - } else if ((error = - dsl_prop_get_int_ds(dmu_objset_ds(os), - zfs_prop_to_name(ZFS_PROP_RECORDSIZE), - &propval)) == 0 && - propval > SPA_OLD_MAXBLOCKSIZE) { - error = SET_ERROR(ENOTSUP); } else { objnum = dmu_objset_id(os); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index 9d3beaa103ff..da3461e10e6f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -24,6 +24,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright 2016 Toomas Soome */ #ifndef _ZIO_H diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index 2d8d93fc8e76..8ed546541a7e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -25,6 +25,7 @@ * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright 2013 Martin Matuska . All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Toomas Soome */ #include @@ -3474,16 +3475,10 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) /* * Check the vdev configuration to ensure that it's capable of supporting - * a root pool. + * a root pool. We do not support partial configuration. + * In addition, only a single top-level vdev is allowed. * - * On Solaris, we do not support RAID-Z or partial configuration. In - * addition, only a single top-level vdev is allowed and none of the - * leaves can be wholedisks. - * - * For FreeBSD, we can boot from any configuration. There is a - * limitation that the boot filesystem must be either uncompressed or - * compresses with lzjb compression but I'm not sure how to enforce - * that here. + * FreeBSD does not have above limitations. */ boolean_t vdev_is_bootable(vdev_t *vd) @@ -3495,8 +3490,7 @@ vdev_is_bootable(vdev_t *vd) if (strcmp(vdev_type, VDEV_TYPE_ROOT) == 0 && vd->vdev_children > 1) { return (B_FALSE); - } else if (strcmp(vdev_type, VDEV_TYPE_RAIDZ) == 0 || - strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { + } else if (strcmp(vdev_type, VDEV_TYPE_MISSING) == 0) { return (B_FALSE); } } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index d76ba07e464f..661e418e5ec4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -31,6 +31,7 @@ * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. * Copyright (c) 2013 Steven Hartland. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Toomas Soome */ /* @@ -3944,16 +3945,6 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr) intval > SPA_OLD_MAXBLOCKSIZE) { spa_t *spa; - /* - * If this is a bootable dataset then - * the we don't allow large (>128K) blocks, - * because GRUB doesn't support them. - */ - if (zfs_is_bootfs(dsname) && - intval > SPA_OLD_MAXBLOCKSIZE) { - return (SET_ERROR(ERANGE)); - } - /* * We don't allow setting the property above 1MB, * unless the tunable has been changed. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index c7042ed0867c..17c702a335fc 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -421,7 +421,7 @@ page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes) vm_page_reference(pp); vm_page_lock(pp); zfs_vmobject_wunlock(obj); - vm_page_busy_sleep(pp, "zfsmwb"); + vm_page_busy_sleep(pp, "zfsmwb", true); zfs_vmobject_wlock(obj); continue; } @@ -476,7 +476,7 @@ page_hold(vnode_t *vp, int64_t start) vm_page_reference(pp); vm_page_lock(pp); zfs_vmobject_wunlock(obj); - vm_page_busy_sleep(pp, "zfsmwb"); + vm_page_busy_sleep(pp, "zfsmwb", true); zfs_vmobject_wlock(obj); continue; } diff --git a/sys/conf/NOTES b/sys/conf/NOTES index a827fd2ed1a4..afc521518978 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -982,6 +982,8 @@ device lagg # TCPPCAP enables code which keeps the last n packets sent and received # on a TCP socket. # +# TCP_HHOOK enables the hhook(9) framework hooks for the TCP stack. +# # RADIX_MPATH provides support for equal-cost multi-path routing. # options MROUTING # Multicast routing @@ -1001,6 +1003,7 @@ options IPSTEALTH #support for stealth forwarding options PF_DEFAULT_TO_DROP #drop everything by default options TCPDEBUG options TCPPCAP +options TCP_HHOOK options RADIX_MPATH # The MBUF_STRESS_TEST option enables options which create diff --git a/sys/conf/files b/sys/conf/files index 3806bc6b0fe2..8e2ce6bb671d 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1431,6 +1431,7 @@ dev/ed/if_ed_novell.c optional ed dev/ed/if_ed_rtl80x9.c optional ed dev/ed/if_ed_pccard.c optional ed pccard dev/ed/if_ed_pci.c optional ed pci +dev/efidev/efidev.c optional efirt dev/eisa/eisa_if.m standard dev/eisa/eisaconf.c optional eisa dev/e1000/if_em.c optional em \ @@ -1572,6 +1573,7 @@ dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled +dev/gpio/gpioregulator.c optional gpioregulator fdt ext_resources dev/gpio/gpiospi.c optional gpiospi dev/gpio/gpio_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 332fd66b6eab..1aa1ce1546e4 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -45,6 +45,24 @@ arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_fdt.c optional fdt arm/arm/pmu.c standard +arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc +arm/broadcom/bcm2835/bcm2835_common.c optional fdt soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_cpufreq.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_dma.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_fbd.c optional vt soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_intr.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_mbox.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_rng.c optional random soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 +arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi @@ -96,6 +114,24 @@ arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci arm64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 +contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" +contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ + compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" crypto/blowfish/bf_enc.c optional crypto | ipsec crypto/des/des_enc.c optional crypto | ipsec | netsmb dev/acpica/acpi_if.m optional acpi @@ -103,6 +139,7 @@ dev/ahci/ahci_generic.c optional ahci fdt dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc +dev/mbox/mbox_if.m optional soc_brcm_bcm2837 dev/mmc/host/dwmmc.c optional dwmmc fdt dev/mmc/host/dwmmc_hisi.c optional dwmmc fdt soc_hisi_hi6220 dev/ofw/ofw_cpu.c optional fdt diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 0ba4aa3d4e65..be296f7849ed 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -114,6 +114,7 @@ INLINE_LIMIT?= 8000 CFLAGS += -mgeneral-regs-only # Reserve x18 for pcpu data CFLAGS += -ffixed-x18 +INLINE_LIMIT?= 8000 .endif .if ${MACHINE_CPUARCH} == "riscv" diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index 343b4f820161..b8f0c3ec62b2 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -65,7 +65,7 @@ BROKEN_OPTIONS+= CDDL ZFS .endif .if ${MACHINE_CPUARCH} == "mips" -BROKEN_OPTIONS+= CDDL ZFS +BROKEN_OPTIONS+= CDDL ZFS SSP .endif .if ${MACHINE_CPUARCH} == "powerpc" && ${MACHINE_ARCH} == "powerpc" diff --git a/sys/conf/options b/sys/conf/options index a997a53d2ef3..39e26a333d3b 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -443,6 +443,7 @@ SLIP_IFF_OPTS opt_slip.h TCPDEBUG TCPPCAP opt_global.h SIFTR +TCP_HHOOK opt_inet.h TCP_OFFLOAD opt_inet.h # Enable code to dispatch TCP offloading TCP_RFC7413 opt_inet.h TCP_RFC7413_MAX_KEYS opt_inet.h diff --git a/sys/conf/options.arm64 b/sys/conf/options.arm64 index e7f746ea1d55..ad68292d61fc 100644 --- a/sys/conf/options.arm64 +++ b/sys/conf/options.arm64 @@ -9,5 +9,6 @@ VFP opt_global.h # SoC Support SOC_ALLWINNER_A64 opt_soc.h +SOC_BRCM_BCM2837 opt_soc.h SOC_CAVM_THUNDERX opt_soc.h SOC_HISI_HI6220 opt_soc.h diff --git a/sys/contrib/octeon-sdk/cvmx-dma-engine.h b/sys/contrib/octeon-sdk/cvmx-dma-engine.h index 6f8d51cc2540..85d28780d1f2 100644 --- a/sys/contrib/octeon-sdk/cvmx-dma-engine.h +++ b/sys/contrib/octeon-sdk/cvmx-dma-engine.h @@ -87,7 +87,7 @@ typedef union PCIe memory space pointers in the LAST POINTERS block in the OUTBOUND, INBOUND, and EXTERNAL-ONLY cases. Must be zero in the INTERNAL-ONLY case. Must be zero on chips with PCI */ - cvmx_dma_engine_transfer_t type : 2; /**< Type ­ A given PCI DMA transfer is either OUTBOUND (read from L2/DRAM, + cvmx_dma_engine_transfer_t type : 2; /**< Type - A given PCI DMA transfer is either OUTBOUND (read from L2/DRAM, write into PCI / PCIe memory space), INBOUND (read from PCI / PCIe memory space, write into L2/DRAM), INTERNAL-ONLY (read from L2/DRAM, write into L2/DRAM), or EXTERNAL-ONLY (read from PCIe memory space, write into PCIe memory space). */ @@ -95,14 +95,14 @@ typedef union work-queue entry that is submitted by the hardware after completing the DMA; when WQP = 0, PTR (if non-zero) is a pointer to a byte in local memory that is written to 0 by the hardware after completing the DMA. */ - uint64_t c : 1; /**< C ­ Counter. 1 = use counter 1, 0 = use counter 0. + uint64_t c : 1; /**< C - Counter. 1 = use counter 1, 0 = use counter 0. The C bit selects between the two counters (NPEI_DMA_CNTS[DMA0,DMA1]) that can optionally be updated after an OUTBOUND or EXTERNAL-ONLY transfer, and also selects between the two forced-interrupt bits (NPEI_INT_SUMn[DMA0_FI, DMA1_FI]) that can optionally be set after an OUTBOUND or EXTERNAL-ONLY transfer. C must be zero for INBOUND or INTERNAL-ONLY transfers. */ - uint64_t ca : 1; /**< CA ­ Counter add. + uint64_t ca : 1; /**< CA - Counter add. When CA = 1, the hardware updates the selected counter after it completes the PCI DMA OUTBOUND or EXTERNAL-ONLY Instruction. - If C = 0, PCIE_DMA_CNT0 is updated @@ -117,13 +117,13 @@ typedef union When CA = 0, the hardware does not update any counters. For an INBOUND or INTERNAL-ONLY PCI DMA transfer, CA must never be set, and the hardware never adds to the counters. */ - uint64_t fi : 1; /**< FI ­ Force interrupt. + uint64_t fi : 1; /**< FI - Force interrupt. When FI is set for an OUTBOUND or EXTERNAL-ONLY transfer, the hardware sets a forced interrupt bit after it completes the PCI DMA Instruction. If C = 0, NPEI_INT_SUMn[DMA0_FI] is set, else NPEI_INT_SUMn[DMA1_FI] is set. For an INBOUND or INTERNAL-ONLY PCI DMA operation, FI must never be set, and the hardware never generates interrupts. */ - uint64_t ii : 1; /**< II­ Ignore the I bit (i.e. the I bit of the PCI DMA instruction local pointer). + uint64_t ii : 1; /**< II- Ignore the I bit (i.e. the I bit of the PCI DMA instruction local pointer). For OUTBOUND transfers when II = 1, ignore the I bit and the FL bit in the DMA HDR alone determines whether the hardware frees any/all of the local buffers in the FIRST POINTERS area: @@ -134,7 +134,7 @@ typedef union - when (FL I) is true, the hardware frees the local buffer when II=0. For INBOUND, INTERNAL-ONLY, and EXTERNAL-ONLY PCI DMA transfers, II must never be set, and local buffers are never freed. */ - uint64_t fl : 1; /**< FL ­ Free local buffer. + uint64_t fl : 1; /**< FL - Free local buffer. When FL = 1, for an OUTBOUND operation, it indicates that the local buffers in the FIRST BUFFERS area should be freed. If II = 1, the FL bit alone indicates whether the local buffer should be freed: @@ -145,7 +145,7 @@ typedef union - when (FL I) is true, the hardware frees the local buffer when II=0. For an INBOUND, INTERNAL-ONLY, or EXTERNAL-ONLY PCI DMA transfer, FL must never be set, and local buffers are never freed. */ - uint64_t nlst : 4; /**< NLST ­ Number Last pointers. + uint64_t nlst : 4; /**< NLST - Number Last pointers. The number of pointers in the LAST POINTERS area. In the INBOUND, OUTBOUND, and EXTERNAL-ONLY cases, the LAST POINTERS area contains PCI components, and the number of 64-bit words @@ -156,7 +156,7 @@ typedef union - HDR.NLST Note that the sum of the number of 64-bit words in the LAST POINTERS and FIRST POINTERS area must never exceed 31. */ - uint64_t nfst : 4; /**< NFST ­ Number First pointers. + uint64_t nfst : 4; /**< NFST - Number First pointers. The number of pointers in the FIRST POINTERS area. In the INBOUND, OUTBOUND, and INTERNAL-ONLY cases, the FIRST POINTERS area contains local pointers, and the number of 64-bit words required @@ -166,7 +166,7 @@ typedef union components, and the number of 64-bit words required in the FIRST POINTERS area is: - HDR.NFST + ((HDR.NFST + 3)/4) where the division removes the fraction. */ - uint64_t addr : 40; /**< PTR ­ Pointer, either a work-queue-entry pointer (when WQP = 1) or a local + uint64_t addr : 40; /**< PTR - Pointer, either a work-queue-entry pointer (when WQP = 1) or a local memory pointer (WQP = 0). When WQP = 1 and PTR 0x0, the hardware inserts the work-queue entry indicated by PTR into a POW input queue after the PCI DMA operation is @@ -186,12 +186,12 @@ typedef union uint64_t u64; struct { - uint64_t i : 1; /**< I ­ Invert free. + uint64_t i : 1; /**< I - Invert free. This bit gives the software the ability to free buffers independently for an OUTBOUND PCI DMA transfer. I is not used by the hardware when II is set. I must not be set, and buffers are never freed, for INBOUND, INTERNAL-ONLY, and EXTERNAL-ONLY PCI DMA transfers. */ - uint64_t back : 4; /**< Back ­ Backup amount. + uint64_t back : 4; /**< Back - Backup amount. Allows the start of a buffer that is to be freed during an OUTBOUND transfer to be different from the ptr value. Back specifies the amount to subtract from the pointer to reach the start when freeing a buffer. @@ -200,13 +200,13 @@ typedef union Back is only used by the hardware when the buffer corresponding to ptr is freed. Back must be 0x0, and buffers are never freed, for INBOUND, INTERNAL-ONLY, and EXTERNAL-ONLY PCI DMA transfers. */ - uint64_t pool : 3; /**< Pool ­ Free pool. + uint64_t pool : 3; /**< Pool - Free pool. Specifies which pool (of the eight hardware-managed FPA free pools) receives the buffer associated with ptr when freed during an OUTBOUND transfer. Pool is only used when the buffer corresponding to ptr is freed. Pool must be 0x0, and buffers are never freed, for INBOUND, INTERNAL-ONLY, and EXTERNAL-ONLY PCI DMA transfers. */ - uint64_t f : 1; /**< F ­ Full-block writes are allowed. + uint64_t f : 1; /**< F - Full-block writes are allowed. When set, the hardware is permitted to write all the bytes in the cache blocks covered by ptr, ptr + Size - 1. This can improve memory system performance when the write misses in the L2 cache. @@ -218,12 +218,12 @@ typedef union F must not be set for local pointers that are not written to: - The local pointers in the FIRST POINTERS area for OUTBOUND and INTERNAL-ONLY transfers. */ - uint64_t a : 1; /**< A ­ Allocate L2. + uint64_t a : 1; /**< A - Allocate L2. This is a hint to the hardware that the cache blocks should be allocated in the L2 cache (if they were not already). */ - uint64_t l : 1; /**< L ­ Little-endian. + uint64_t l : 1; /**< L - Little-endian. When L is set, the data at ptr is in little-endian format rather than big-endian. */ - uint64_t size : 13; /**< Size ­ Size in bytes of the contiguous space specified by ptr. A Size value of 0 is + uint64_t size : 13; /**< Size - Size in bytes of the contiguous space specified by ptr. A Size value of 0 is illegal. Note that the sum of the sizes in the FIRST POINTERS area must always exactly equal the sum of the sizes/lengths in the LAST POINTERS area: - In the OUTBOUND and INBOUND cases, the HDR.NFST size fields in the diff --git a/sys/contrib/octeon-sdk/cvmx-higig.h b/sys/contrib/octeon-sdk/cvmx-higig.h index 426ca26602b5..910f73d75ae1 100644 --- a/sys/contrib/octeon-sdk/cvmx-higig.h +++ b/sys/contrib/octeon-sdk/cvmx-higig.h @@ -120,11 +120,11 @@ typedef struct multicast (unknown L2 multicast and IPMC) packets. This field is used when OPCODE is 011 or 100 Semantics of PFM bits are as follows; For registered L2 multicast packets: - PFM= 0 ­ Flood to VLAN - PFM= 1 or 2 ­ Send to group members in the L2MC table + PFM= 0 - Flood to VLAN + PFM= 1 or 2 - Send to group members in the L2MC table For unregistered L2 multicast packets: - PFM= 0 or 1 ­ Flood to VLAN - PFM= 2 ­ Drop the packet */ + PFM= 0 or 1 - Flood to VLAN + PFM= 2 - Drop the packet */ uint32_t src_port_tgid : 6; /**< If the MSB of this field is set, then it indicates the LAG the packet ingressed on, else it represents the physical port the packet ingressed on. */ uint32_t dst_port : 5; /**< Port number of destination port on which the packet needs to egress. */ @@ -138,10 +138,10 @@ typedef struct uint32_t cng_low : 1; /**< Semantics of CNG_HIGH and CNG_LOW are as follows: The following encodings are to make it backward compatible: [CNG_HIGH, CNG_LOW] - COLOR - [0, 0] ­ Packet is green - [0, 1] ­ Packet is red - [1, 1] ­ Packet is yellow - [1, 0] ­ Undefined */ + [0, 0] - Packet is green + [0, 1] - Packet is red + [1, 1] - Packet is yellow + [1, 0] - Undefined */ uint32_t dst_modid_low : 5; /**< Bits [4-: 0] of Module ID of the destination port on which the packet needs to egress. */ } s; } dw1; @@ -273,11 +273,11 @@ typedef struct multicast (unknown L2 multicast and IPMC) packets. This field is used when OPCODE is 011 or 100 Semantics of PFM bits are as follows; For registered L2 multicast packets: - PFM= 0 ­ Flood to VLAN - PFM= 1 or 2 ­ Send to group members in the L2MC table + PFM= 0 - Flood to VLAN + PFM= 1 or 2 - Send to group members in the L2MC table For unregistered L2 multicast packets: - PFM= 0 or 1 ­ Flood to VLAN - PFM= 2 ­ Drop the packet */ + PFM= 0 or 1 - Flood to VLAN + PFM= 2 - Drop the packet */ uint32_t src_t : 1; /**< If the MSB of this field is set, then it indicates the LAG the packet ingressed on, else it represents the physical port the packet ingressed on. */ uint32_t reserved_11_12 : 2; diff --git a/sys/contrib/octeon-sdk/cvmx-pcie.c b/sys/contrib/octeon-sdk/cvmx-pcie.c index 9a8d6d94a06f..6c1c23ee7c57 100644 --- a/sys/contrib/octeon-sdk/cvmx-pcie.c +++ b/sys/contrib/octeon-sdk/cvmx-pcie.c @@ -722,8 +722,8 @@ static int __cvmx_pcie_rc_initialize_gen1(int pcie_port) /* Setup BAR2 attributes */ /* Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM]) */ - /* ­ PTLP_RO,CTLP_RO should normally be set (except for debug). */ - /* ­ WAIT_COM=0 will likely work for all applications. */ + /* - PTLP_RO,CTLP_RO should normally be set (except for debug). */ + /* - WAIT_COM=0 will likely work for all applications. */ /* Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]) */ if (pcie_port) { @@ -981,7 +981,7 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) /* Make sure we aren't trying to setup a target mode interface in host mode */ mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(pcie_port)); - ep_mode = (OCTEON_IS_MODEL(OCTEON_CN61XX || OCTEON_IS_MODEL(OCTEON_CNF71XX)) ? (mio_rst_ctl.s.prtmode != 1) : (!mio_rst_ctl.s.host_mode)); + ep_mode = ((OCTEON_IS_MODEL(OCTEON_CN61XX) || OCTEON_IS_MODEL(OCTEON_CNF71XX)) ? (mio_rst_ctl.s.prtmode != 1) : (!mio_rst_ctl.s.host_mode)); if (ep_mode) { cvmx_dprintf("PCIe: Port %d in endpoint mode.\n", pcie_port); @@ -1139,8 +1139,8 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) /* Setup BAR2 attributes */ /* Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM]) */ - /* ­ PTLP_RO,CTLP_RO should normally be set (except for debug). */ - /* ­ WAIT_COM=0 will likely work for all applications. */ + /* - PTLP_RO,CTLP_RO should normally be set (except for debug). */ + /* - WAIT_COM=0 will likely work for all applications. */ /* Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM]) */ pemx_bar_ctl.u64 = cvmx_read_csr(CVMX_PEMX_BAR_CTL(pcie_port)); pemx_bar_ctl.s.bar1_siz = 3; /* 256MB BAR1*/ diff --git a/sys/contrib/octeon-sdk/cvmx-raid.h b/sys/contrib/octeon-sdk/cvmx-raid.h index 63da6b948617..e4dbb2aff205 100644 --- a/sys/contrib/octeon-sdk/cvmx-raid.h +++ b/sys/contrib/octeon-sdk/cvmx-raid.h @@ -125,7 +125,7 @@ typedef union { uint64_t reserved_58_63 : 6; /**< Must be zero */ uint64_t fw : 1; /**< When set, indicates that RAD can modify any byte in any (128B) cache line touched - by L2/DRAM addresses OWORD[PTR] through OWORD[PTR]+CWORD[SIZE]­1. + by L2/DRAM addresses OWORD[PTR] through OWORD[PTR]+CWORD[SIZE]-1. Setting OWORD[FW] can improve hardware performance, as some DRAM loads can be avoided on L2 cache misses. The Q OWORD[FW] must not be set when CWORD[Q_CMP] is set, and the P OWORD[FW] must not be set when diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c index 93aa6f8ba27a..53d1819c6cde 100644 --- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c +++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c @@ -73,14 +73,25 @@ struct bcm_vchiq_softc { void* intr_hl; bus_space_tag_t bst; bus_space_handle_t bsh; + int regs_offset; }; static struct bcm_vchiq_softc *bcm_vchiq_sc = NULL; +#define BSD_DTB 1 +#define UPSTREAM_DTB 2 +static struct ofw_compat_data compat_data[] = { + {"broadcom,bcm2835-vchiq", BSD_DTB}, + {"brcm,bcm2835-vchiq", UPSTREAM_DTB}, + {NULL, 0} +}; + #define vchiq_read_4(reg) \ - bus_space_read_4(bcm_vchiq_sc->bst, bcm_vchiq_sc->bsh, reg) + bus_space_read_4(bcm_vchiq_sc->bst, bcm_vchiq_sc->bsh, (reg) + \ + bcm_vchiq_sc->regs_offset) #define vchiq_write_4(reg, val) \ - bus_space_write_4(bcm_vchiq_sc->bst, bcm_vchiq_sc->bsh, reg, val) + bus_space_write_4(bcm_vchiq_sc->bst, bcm_vchiq_sc->bsh, (reg) + \ + bcm_vchiq_sc->regs_offset, val) /* * Extern functions */ @@ -122,12 +133,11 @@ static int bcm_vchiq_probe(device_t dev) { - if (ofw_bus_is_compatible(dev, "broadcom,bcm2835-vchiq")) { - device_set_desc(dev, "BCM2835 VCHIQ"); - return(BUS_PROBE_DEFAULT); - } + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); - return (ENXIO); + device_set_desc(dev, "BCM2835 VCHIQ"); + return (BUS_PROBE_DEFAULT); } static int @@ -157,6 +167,9 @@ bcm_vchiq_attach(device_t dev) return (ENXIO); } + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == UPSTREAM_DTB) + sc->regs_offset = -0x40; + node = ofw_bus_get_node(dev); if ((OF_getencprop(node, "cache-line-size", &cell, sizeof(cell))) > 0) g_cache_line_size = cell; diff --git a/sys/dev/acpi_support/atk0110.c b/sys/dev/acpi_support/atk0110.c index e79a0e00e357..c2759e6b67a2 100644 --- a/sys/dev/acpi_support/atk0110.c +++ b/sys/dev/acpi_support/atk0110.c @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -51,18 +52,23 @@ ACPI_SERIAL_DECL(aibs, "aibs"); #define AIBS_MORE_SENSORS #define AIBS_VERBOSE -enum aibs_type { - AIBS_VOLT, - AIBS_TEMP, - AIBS_FAN -}; +#define AIBS_GROUP_SENSORS 0x06 + +#define AIBS_SENS_TYPE(x) (((x) >> 16) & 0xff) +#define AIBS_SENS_TYPE_VOLT 2 +#define AIBS_SENS_TYPE_TEMP 3 +#define AIBS_SENS_TYPE_FAN 4 + +#define AIBS_SENS_TYPE_VOLT_NAME "volt" +#define AIBS_SENS_TYPE_VOLT_TEMP "temp" +#define AIBS_SENS_TYPE_VOLT_FAN "fan" struct aibs_sensor { ACPI_INTEGER v; ACPI_INTEGER i; ACPI_INTEGER l; ACPI_INTEGER h; - enum aibs_type t; + int t; }; struct aibs_softc { @@ -72,14 +78,23 @@ struct aibs_softc { struct aibs_sensor *sc_asens_volt; struct aibs_sensor *sc_asens_temp; struct aibs_sensor *sc_asens_fan; + struct aibs_sensor *sc_asens_all; + + struct sysctl_oid *sc_volt_sysctl; + struct sysctl_oid *sc_temp_sysctl; + struct sysctl_oid *sc_fan_sysctl; + + bool sc_ggrp_method; }; static int aibs_probe(device_t); static int aibs_attach(device_t); static int aibs_detach(device_t); static int aibs_sysctl(SYSCTL_HANDLER_ARGS); +static int aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS); -static void aibs_attach_sif(struct aibs_softc *, enum aibs_type); +static int aibs_attach_ggrp(struct aibs_softc *); +static int aibs_attach_sif(struct aibs_softc *, int); static device_method_t aibs_methods[] = { DEVMETHOD(device_probe, aibs_probe), @@ -109,54 +124,240 @@ aibs_probe(device_t dev) { if (acpi_disabled("aibs") || ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL) - return ENXIO; + return (ENXIO); device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)"); - return 0; + return (0); } static int aibs_attach(device_t dev) { struct aibs_softc *sc = device_get_softc(dev); + int err; sc->sc_dev = dev; sc->sc_ah = acpi_get_handle(dev); - aibs_attach_sif(sc, AIBS_VOLT); - aibs_attach_sif(sc, AIBS_TEMP); - aibs_attach_sif(sc, AIBS_FAN); + sc->sc_ggrp_method = false; + err = aibs_attach_sif(sc, AIBS_SENS_TYPE_VOLT); + if (err == 0) + err = aibs_attach_sif(sc, AIBS_SENS_TYPE_TEMP); + if (err == 0) + err = aibs_attach_sif(sc, AIBS_SENS_TYPE_FAN); - return 0; + if (err == 0) + return (0); + + /* Clean up whatever was allocated earlier. */ + if (sc->sc_volt_sysctl != NULL) + sysctl_remove_oid(sc->sc_volt_sysctl, true, true); + if (sc->sc_temp_sysctl != NULL) + sysctl_remove_oid(sc->sc_temp_sysctl, true, true); + if (sc->sc_fan_sysctl != NULL) + sysctl_remove_oid(sc->sc_fan_sysctl, true, true); + aibs_detach(dev); + + sc->sc_ggrp_method = true; + err = aibs_attach_ggrp(sc); + return (err); +} + +static int +aibs_add_sensor(struct aibs_softc *sc, ACPI_OBJECT *o, + struct aibs_sensor* sensor, const char ** descr) +{ + int off; + + /* + * Packages for the old and new methods are quite + * similar except that the new package has two + * new (unknown / unused) fields after the name field. + */ + if (sc->sc_ggrp_method) + off = 4; + else + off = 2; + + if (o->Type != ACPI_TYPE_PACKAGE) { + device_printf(sc->sc_dev, + "sensor object is not a package: %i type\n", + o->Type); + return (ENXIO); + } + if (o[0].Package.Count != (off + 3) || + o->Package.Elements[0].Type != ACPI_TYPE_INTEGER || + o->Package.Elements[1].Type != ACPI_TYPE_STRING || + o->Package.Elements[off].Type != ACPI_TYPE_INTEGER || + o->Package.Elements[off + 1].Type != ACPI_TYPE_INTEGER || + o->Package.Elements[off + 2].Type != ACPI_TYPE_INTEGER) { + device_printf(sc->sc_dev, "unexpected package content\n"); + return (ENXIO); + } + + sensor->i = o->Package.Elements[0].Integer.Value; + *descr = o->Package.Elements[1].String.Pointer; + sensor->l = o->Package.Elements[off].Integer.Value; + sensor->h = o->Package.Elements[off + 1].Integer.Value; + /* For the new method the second value is a range size. */ + if (sc->sc_ggrp_method) + sensor->h += sensor->l; + sensor->t = AIBS_SENS_TYPE(sensor->i); + + switch (sensor->t) { + case AIBS_SENS_TYPE_VOLT: + case AIBS_SENS_TYPE_TEMP: + case AIBS_SENS_TYPE_FAN: + return (0); + default: + device_printf(sc->sc_dev, "unknown sensor type 0x%x", + sensor->t); + return (ENXIO); + } } static void -aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) +aibs_sensor_added(struct aibs_softc *sc, struct sysctl_oid *so, + const char *type_name, int idx, struct aibs_sensor *sensor, + const char *descr) { + char sysctl_name[8]; + + snprintf(sysctl_name, sizeof(sysctl_name), "%i", idx); +#ifdef AIBS_VERBOSE + device_printf(sc->sc_dev, "%c%i: 0x%08jx %20s %5jd / %5jd\n", + type_name[0], idx, + (uintmax_t)sensor->i, descr, (intmax_t)sensor->l, + (intmax_t)sensor->h); +#endif + SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev), + SYSCTL_CHILDREN(so), idx, sysctl_name, + CTLTYPE_INT | CTLFLAG_RD, sc, (uintptr_t)sensor, + sc->sc_ggrp_method ? aibs_sysctl_ggrp : aibs_sysctl, + sensor->t == AIBS_SENS_TYPE_TEMP ? "IK" : "I", descr); +} + +static int +aibs_attach_ggrp(struct aibs_softc *sc) +{ + ACPI_STATUS s; + ACPI_BUFFER buf; + ACPI_HANDLE h; + ACPI_OBJECT id; + ACPI_OBJECT *bp; + ACPI_OBJECT_LIST arg; + int i; + int t, v, f; + int err; + int *s_idx; + const char *name; + const char *descr; + struct aibs_sensor *sensor; + struct sysctl_oid **so; + + /* First see if GITM is available. */ + s = AcpiGetHandle(sc->sc_ah, "GITM", &h); + if (ACPI_FAILURE(s)) { + if (bootverbose) + device_printf(sc->sc_dev, "GITM not found\n"); + return (ENXIO); + } + + /* + * Now call GGRP with the appropriate argument to list sensors. + * The method lists different groups of entities depending on + * the argument. + */ + id.Integer.Value = AIBS_GROUP_SENSORS; + id.Type = ACPI_TYPE_INTEGER; + arg.Count = 1; + arg.Pointer = &id; + buf.Length = ACPI_ALLOCATE_BUFFER; + buf.Pointer = NULL; + s = AcpiEvaluateObjectTyped(sc->sc_ah, "GGRP", &arg, &buf, + ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(s)) { + device_printf(sc->sc_dev, "GGRP not found\n"); + return (ENXIO); + } + + bp = buf.Pointer; + sc->sc_asens_all = malloc(sizeof(*sc->sc_asens_all) * bp->Package.Count, + M_DEVBUF, M_WAITOK | M_ZERO); + v = t = f = 0; + for (i = 0; i < bp->Package.Count; i++) { + sensor = &sc->sc_asens_all[i]; + err = aibs_add_sensor(sc, &bp->Package.Elements[i], sensor, + &descr); + if (err != 0) + continue; + + switch (sensor->t) { + case AIBS_SENS_TYPE_VOLT: + name = "volt"; + so = &sc->sc_volt_sysctl; + s_idx = &v; + break; + case AIBS_SENS_TYPE_TEMP: + name = "temp"; + so = &sc->sc_temp_sysctl; + s_idx = &t; + break; + case AIBS_SENS_TYPE_FAN: + name = "fan"; + so = &sc->sc_fan_sysctl; + s_idx = &f; + break; + default: + panic("add_sensor succeeded for unknown sensor type %d", + sensor->t); + } + + if (*so == NULL) { + /* sysctl subtree for sensors of this type */ + *so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), + sensor->t, name, CTLFLAG_RD, NULL, NULL); + } + aibs_sensor_added(sc, *so, name, *s_idx, sensor, descr); + *s_idx += 1; + } + + AcpiOsFree(buf.Pointer); + return (0); +} + +static int +aibs_attach_sif(struct aibs_softc *sc, int st) +{ + char name[] = "?SIF"; ACPI_STATUS s; ACPI_BUFFER b; ACPI_OBJECT *bp, *o; - int i, n; const char *node; - char name[] = "?SIF"; struct aibs_sensor *as; - struct sysctl_oid *so; + struct sysctl_oid **so; + int i, n; + int err; switch (st) { - case AIBS_VOLT: + case AIBS_SENS_TYPE_VOLT: node = "volt"; name[0] = 'V'; + so = &sc->sc_volt_sysctl; break; - case AIBS_TEMP: + case AIBS_SENS_TYPE_TEMP: node = "temp"; name[0] = 'T'; + so = &sc->sc_temp_sysctl; break; - case AIBS_FAN: + case AIBS_SENS_TYPE_FAN: node = "fan"; name[0] = 'F'; + so = &sc->sc_fan_sysctl; break; default: - return; + panic("Unsupported sensor type %d", st); } b.Length = ACPI_ALLOCATE_BUFFER; @@ -164,7 +365,7 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) ACPI_TYPE_PACKAGE); if (ACPI_FAILURE(s)) { device_printf(sc->sc_dev, "%s not found\n", name); - return; + return (ENXIO); } bp = b.Pointer; @@ -172,14 +373,14 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) if (o[0].Type != ACPI_TYPE_INTEGER) { device_printf(sc->sc_dev, "%s[0]: invalid type\n", name); AcpiOsFree(b.Pointer); - return; + return (ENXIO); } n = o[0].Integer.Value; if (bp->Package.Count - 1 < n) { device_printf(sc->sc_dev, "%s: invalid package\n", name); AcpiOsFree(b.Pointer); - return; + return (ENXIO); } else if (bp->Package.Count - 1 > n) { int on = n; @@ -193,76 +394,37 @@ aibs_attach_sif(struct aibs_softc *sc, enum aibs_type st) device_printf(sc->sc_dev, "%s: no members in the package\n", name); AcpiOsFree(b.Pointer); - return; + return (ENXIO); } - as = malloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO); - if (as == NULL) { - device_printf(sc->sc_dev, "%s: malloc fail\n", name); - AcpiOsFree(b.Pointer); - return; - } + as = malloc(sizeof(*as) * n, M_DEVBUF, M_WAITOK | M_ZERO); switch (st) { - case AIBS_VOLT: + case AIBS_SENS_TYPE_VOLT: sc->sc_asens_volt = as; break; - case AIBS_TEMP: + case AIBS_SENS_TYPE_TEMP: sc->sc_asens_temp = as; break; - case AIBS_FAN: + case AIBS_SENS_TYPE_FAN: sc->sc_asens_fan = as; break; } /* sysctl subtree for sensors of this type */ - so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev), + *so = SYSCTL_ADD_NODE(device_get_sysctl_ctx(sc->sc_dev), SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)), st, node, CTLFLAG_RD, NULL, NULL); for (i = 0, o++; i < n; i++, o++) { - ACPI_OBJECT *oi; - char si[3]; - const char *desc; + const char *descr; - /* acpica5 automatically evaluates the referenced package */ - if (o[0].Type != ACPI_TYPE_PACKAGE) { - device_printf(sc->sc_dev, - "%s: %i: not a package: %i type\n", - name, i, o[0].Type); - continue; - } - oi = o[0].Package.Elements; - if (o[0].Package.Count != 5 || - oi[0].Type != ACPI_TYPE_INTEGER || - oi[1].Type != ACPI_TYPE_STRING || - oi[2].Type != ACPI_TYPE_INTEGER || - oi[3].Type != ACPI_TYPE_INTEGER || - oi[4].Type != ACPI_TYPE_INTEGER) { - device_printf(sc->sc_dev, - "%s: %i: invalid package\n", - name, i); - continue; - } - as[i].i = oi[0].Integer.Value; - desc = oi[1].String.Pointer; - as[i].l = oi[2].Integer.Value; - as[i].h = oi[3].Integer.Value; - as[i].t = st; -#ifdef AIBS_VERBOSE - device_printf(sc->sc_dev, "%c%i: " - "0x%08"PRIx64" %20s %5"PRIi64" / %5"PRIi64" " - "0x%"PRIx64"\n", - name[0], i, - (uint64_t)as[i].i, desc, (int64_t)as[i].l, - (int64_t)as[i].h, (uint64_t)oi[4].Integer.Value); -#endif - snprintf(si, sizeof(si), "%i", i); - SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->sc_dev), - SYSCTL_CHILDREN(so), i, si, CTLTYPE_INT | CTLFLAG_RD, - sc, st, aibs_sysctl, st == AIBS_TEMP ? "IK" : "I", desc); + err = aibs_add_sensor(sc, o, &as[i], &descr); + if (err == 0) + aibs_sensor_added(sc, *so, node, i, &as[i], descr); } AcpiOsFree(b.Pointer); + return (0); } static int @@ -276,7 +438,9 @@ aibs_detach(device_t dev) free(sc->sc_asens_temp, M_DEVBUF); if (sc->sc_asens_fan != NULL) free(sc->sc_asens_fan, M_DEVBUF); - return 0; + if (sc->sc_asens_all != NULL) + free(sc->sc_asens_all, M_DEVBUF); + return (0); } #ifdef AIBS_VERBOSE @@ -289,39 +453,33 @@ static int aibs_sysctl(SYSCTL_HANDLER_ARGS) { struct aibs_softc *sc = arg1; - enum aibs_type st = arg2; + struct aibs_sensor *sensor = (void *)arg2; int i = oidp->oid_number; ACPI_STATUS rs; ACPI_OBJECT p, *bp; ACPI_OBJECT_LIST mp; ACPI_BUFFER b; char *name; - struct aibs_sensor *as; ACPI_INTEGER v, l, h; int so[3]; - switch (st) { - case AIBS_VOLT: + switch (sensor->t) { + case AIBS_SENS_TYPE_VOLT: name = "RVLT"; - as = sc->sc_asens_volt; break; - case AIBS_TEMP: + case AIBS_SENS_TYPE_TEMP: name = "RTMP"; - as = sc->sc_asens_temp; break; - case AIBS_FAN: + case AIBS_SENS_TYPE_FAN: name = "RFAN"; - as = sc->sc_asens_fan; break; default: - return ENOENT; + return (ENOENT); } - if (as == NULL) - return ENOENT; - l = as[i].l; - h = as[i].h; + l = sensor->l; + h = sensor->h; p.Type = ACPI_TYPE_INTEGER; - p.Integer.Value = as[i].i; + p.Integer.Value = sensor->i; mp.Count = 1; mp.Pointer = &p; b.Length = ACPI_ALLOCATE_BUFFER; @@ -333,26 +491,91 @@ aibs_sysctl(SYSCTL_HANDLER_ARGS) "%s: %i: evaluation failed\n", name, i); ACPI_SERIAL_END(aibs); - return EIO; + return (EIO); } bp = b.Pointer; v = bp->Integer.Value; AcpiOsFree(b.Pointer); ACPI_SERIAL_END(aibs); - switch (st) { - case AIBS_VOLT: + switch (sensor->t) { + case AIBS_SENS_TYPE_VOLT: break; - case AIBS_TEMP: + case AIBS_SENS_TYPE_TEMP: v += 2731; l += 2731; h += 2731; break; - case AIBS_FAN: + case AIBS_SENS_TYPE_FAN: break; } so[0] = v; so[1] = l; so[2] = h; - return sysctl_handle_opaque(oidp, &so, sizeof(so), req); + return (sysctl_handle_opaque(oidp, &so, sizeof(so), req)); +} + +static int +aibs_sysctl_ggrp(SYSCTL_HANDLER_ARGS) +{ + struct aibs_softc *sc = arg1; + struct aibs_sensor *sensor = (void *)arg2; + ACPI_STATUS rs; + ACPI_OBJECT p, *bp; + ACPI_OBJECT_LIST arg; + ACPI_BUFFER buf; + ACPI_INTEGER v, l, h; + int so[3]; + uint32_t *ret; + uint32_t cmd[3]; + + cmd[0] = sensor->i; + cmd[1] = 0; + cmd[2] = 0; + p.Type = ACPI_TYPE_BUFFER; + p.Buffer.Pointer = (void *)cmd; + p.Buffer.Length = sizeof(cmd); + arg.Count = 1; + arg.Pointer = &p; + buf.Pointer = NULL; + buf.Length = ACPI_ALLOCATE_BUFFER; + ACPI_SERIAL_BEGIN(aibs); + rs = AcpiEvaluateObjectTyped(sc->sc_ah, "GITM", &arg, &buf, + ACPI_TYPE_BUFFER); + ACPI_SERIAL_END(aibs); + if (ACPI_FAILURE(rs)) { + device_printf(sc->sc_dev, "GITM evaluation failed\n"); + return (EIO); + } + bp = buf.Pointer; + if (bp->Buffer.Length < 8) { + device_printf(sc->sc_dev, "GITM returned short buffer\n"); + return (EIO); + } + ret = (uint32_t *)bp->Buffer.Pointer; + if (ret[0] == 0) { + device_printf(sc->sc_dev, "GITM returned error status\n"); + return (EINVAL); + } + v = ret[1]; + AcpiOsFree(buf.Pointer); + + l = sensor->l; + h = sensor->h; + + switch (sensor->t) { + case AIBS_SENS_TYPE_VOLT: + break; + case AIBS_SENS_TYPE_TEMP: + v += 2731; + l += 2731; + h += 2731; + break; + case AIBS_SENS_TYPE_FAN: + break; + } + so[0] = v; + so[1] = l; + so[2] = h; + return (sysctl_handle_opaque(oidp, &so, sizeof(so), req)); } diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index a7c003199d3d..b863fb4a3e87 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -1567,7 +1567,7 @@ cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) switch (cmd) { case SIOCSIFMTU: mtu = ifr->ifr_mtu; - if ((mtu < ETHERMIN) || (mtu > ETHERMTU_JUMBO)) + if (mtu < ETHERMIN || mtu > MAX_MTU) return (EINVAL); rc = begin_synchronized_op(sc, vi, SLEEP_OK | INTR_OK, "t4mtu"); diff --git a/sys/dev/drm2/i915/i915_gem.c b/sys/dev/drm2/i915/i915_gem.c index 2e75623ba393..6e9a86cfb962 100644 --- a/sys/dev/drm2/i915/i915_gem.c +++ b/sys/dev/drm2/i915/i915_gem.c @@ -1533,7 +1533,7 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, DRM_UNLOCK(dev); vm_page_lock(page); VM_OBJECT_WUNLOCK(vm_obj); - vm_page_busy_sleep(page, "915pee"); + vm_page_busy_sleep(page, "915pee", false); goto retry; } goto have_page; @@ -1575,7 +1575,7 @@ i915_gem_pager_fault(vm_object_t vm_obj, vm_ooffset_t offset, int prot, DRM_UNLOCK(dev); vm_page_lock(page); VM_OBJECT_WUNLOCK(vm_obj); - vm_page_busy_sleep(page, "915pbs"); + vm_page_busy_sleep(page, "915pbs", false); goto retry; } if (vm_page_insert(page, vm_obj, OFF_TO_IDX(offset))) { diff --git a/sys/dev/drm2/ttm/ttm_bo_vm.c b/sys/dev/drm2/ttm/ttm_bo_vm.c index 438077bfee09..60bf8e23c54d 100644 --- a/sys/dev/drm2/ttm/ttm_bo_vm.c +++ b/sys/dev/drm2/ttm/ttm_bo_vm.c @@ -236,7 +236,7 @@ ttm_bo_vm_fault(vm_object_t vm_obj, vm_ooffset_t offset, if (vm_page_busied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(vm_obj); - vm_page_busy_sleep(m, "ttmpbs"); + vm_page_busy_sleep(m, "ttmpbs", false); VM_OBJECT_WLOCK(vm_obj); ttm_mem_io_unlock(man); ttm_bo_unreserve(bo); diff --git a/sys/dev/efidev/efidev.c b/sys/dev/efidev/efidev.c new file mode 100644 index 000000000000..abceec8087d6 --- /dev/null +++ b/sys/dev/efidev/efidev.c @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static d_ioctl_t efidev_ioctl; + +static struct cdevsw efi_cdevsw = { + .d_name = "efi", + .d_version = D_VERSION, + .d_ioctl = efidev_ioctl, +}; + +/* ARGSUSED */ +static int +efidev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr, + int flags __unused, struct thread *td __unused) +{ + int error; + + switch (cmd) { + case EFIIOC_GET_TABLE: + { + struct efi_get_table_ioc *egtioc = + (struct efi_get_table_ioc *)addr; + + error = efi_get_table(&egtioc->uuid, &egtioc->ptr); + break; + } + case EFIIOC_GET_TIME: + { + struct efi_tm *tm = (struct efi_tm *)addr; + + error = efi_get_time(tm); + break; + } + case EFIIOC_SET_TIME: + { + struct efi_tm *tm = (struct efi_tm *)addr; + + error = efi_set_time(tm); + break; + } + case EFIIOC_VAR_GET: + { + struct efi_var_ioc *ev = (struct efi_var_ioc *)addr; + void *data; + efi_char *name; + + data = malloc(ev->datasize, M_TEMP, M_WAITOK); + name = malloc(ev->namesize, M_TEMP, M_WAITOK); + error = copyin(ev->name, name, ev->namesize); + if (error) + goto vg_out; + if (name[ev->namesize / sizeof(efi_char) - 1] != 0) { + error = EINVAL; + goto vg_out; + } + + error = efi_var_get(name, &ev->vendor, &ev->attrib, + &ev->datasize, data); + + if (error == 0) { + error = copyout(data, ev->data, ev->datasize); + } else if (error == EOVERFLOW) { + /* + * Pass back the size we really need, but + * convert the error to 0 so the copyout + * happens. datasize was updated in the + * efi_var_get call. + */ + ev->data = NULL; + error = 0; + } +vg_out: + free(data, M_TEMP); + free(name, M_TEMP); + break; + } + case EFIIOC_VAR_NEXT: + { + struct efi_var_ioc *ev = (struct efi_var_ioc *)addr; + efi_char *name; + + name = malloc(ev->namesize, M_TEMP, M_WAITOK); + error = copyin(ev->name, name, ev->namesize); + if (error) + goto vn_out; + /* Note: namesize is the buffer size, not the string lenght */ + + error = efi_var_nextname(&ev->namesize, name, &ev->vendor); + if (error == 0) { + error = copyout(name, ev->name, ev->namesize); + } else if (error == EOVERFLOW) { + ev->name = NULL; + error = 0; + } + vn_out: + free(name, M_TEMP); + break; + } + case EFIIOC_VAR_SET: + { + struct efi_var_ioc *ev = (struct efi_var_ioc *)addr; + void *data = NULL; + efi_char *name; + + /* datasize == 0 -> delete (more or less) */ + if (ev->datasize > 0) + data = malloc(ev->datasize, M_TEMP, M_WAITOK); + name = malloc(ev->namesize, M_TEMP, M_WAITOK); + if (ev->datasize) { + error = copyin(ev->data, data, ev->datasize); + if (error) + goto vs_out; + } + error = copyin(ev->name, name, ev->namesize); + if (error) + goto vs_out; + if (name[ev->namesize / sizeof(efi_char) - 1] != 0) { + error = EINVAL; + goto vs_out; + } + + error = efi_var_set(name, &ev->vendor, ev->attrib, ev->datasize, + data); +vs_out: + free(data, M_TEMP); + free(name, M_TEMP); + break; + } + default: + error = ENOTTY; + break; + } + + return (error); +} + +int +efidev_init(struct cdev **cdev) +{ + + *cdev = make_dev(&efi_cdevsw, 0, UID_ROOT, GID_WHEEL, 0700, + "efi"); + + return (0); +} + +int +efidev_uninit(struct cdev *cdev) +{ + + destroy_dev(cdev); + + return (0); +} diff --git a/sys/dev/gpio/gpioregulator.c b/sys/dev/gpio/gpioregulator.c new file mode 100644 index 000000000000..48071159123e --- /dev/null +++ b/sys/dev/gpio/gpioregulator.c @@ -0,0 +1,348 @@ +/*- + * Copyright (c) 2016 Jared McNeill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * GPIO controlled regulators + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "regdev_if.h" + +struct gpioregulator_state { + int val; + uint32_t mask; +}; + +struct gpioregulator_init_def { + struct regnode_init_def reg_init_def; + struct gpiobus_pin *enable_pin; + int enable_pin_valid; + int startup_delay_us; + int nstates; + struct gpioregulator_state *states; + int npins; + struct gpiobus_pin **pins; +}; + +struct gpioregulator_reg_sc { + struct regnode *regnode; + device_t base_dev; + struct regnode_std_param *param; + struct gpioregulator_init_def *def; +}; + +struct gpioregulator_softc { + device_t dev; + struct gpioregulator_reg_sc *reg_sc; + struct gpioregulator_init_def init_def; +}; + +static int +gpioregulator_regnode_init(struct regnode *regnode) +{ + struct gpioregulator_reg_sc *sc; + int error, n; + + sc = regnode_get_softc(regnode); + + if (sc->def->enable_pin_valid == 1) { + error = gpio_pin_setflags(sc->def->enable_pin, GPIO_PIN_OUTPUT); + if (error != 0) + return (error); + } + + for (n = 0; n < sc->def->npins; n++) { + error = gpio_pin_setflags(sc->def->pins[n], GPIO_PIN_OUTPUT); + if (error != 0) + return (error); + } + + return (0); +} + +static int +gpioregulator_regnode_enable(struct regnode *regnode, bool enable, int *udelay) +{ + struct gpioregulator_reg_sc *sc; + bool active; + int error; + + sc = regnode_get_softc(regnode); + + if (sc->def->enable_pin_valid == 1) { + active = enable; + if (!sc->param->enable_active_high) + active = !active; + error = gpio_pin_set_active(sc->def->enable_pin, active); + if (error != 0) + return (error); + } + + *udelay = sc->def->startup_delay_us; + + return (0); +} + +static int +gpioregulator_regnode_set_voltage(struct regnode *regnode, int min_uvolt, + int max_uvolt, int *udelay) +{ + struct gpioregulator_reg_sc *sc; + const struct gpioregulator_state *state; + int error, n; + + sc = regnode_get_softc(regnode); + state = NULL; + + for (n = 0; n < sc->def->nstates; n++) { + if (sc->def->states[n].val >= min_uvolt && + sc->def->states[n].val <= max_uvolt) { + state = &sc->def->states[n]; + break; + } + } + if (state == NULL) + return (EINVAL); + + for (n = 0; n < sc->def->npins; n++) { + error = gpio_pin_set_active(sc->def->pins[n], + (state->mask >> n) & 1); + if (error != 0) + return (error); + } + + *udelay = sc->def->startup_delay_us; + + return (0); +} + +static int +gpioregulator_regnode_get_voltage(struct regnode *regnode, int *uvolt) +{ + struct gpioregulator_reg_sc *sc; + uint32_t mask; + int error, n; + bool active; + + sc = regnode_get_softc(regnode); + mask = 0; + + for (n = 0; n < sc->def->npins; n++) { + error = gpio_pin_is_active(sc->def->pins[n], &active); + if (error != 0) + return (error); + mask |= (active << n); + } + + for (n = 0; n < sc->def->nstates; n++) { + if (sc->def->states[n].mask == mask) { + *uvolt = sc->def->states[n].val; + return (0); + } + } + + return (EIO); +} + +static regnode_method_t gpioregulator_regnode_methods[] = { + /* Regulator interface */ + REGNODEMETHOD(regnode_init, gpioregulator_regnode_init), + REGNODEMETHOD(regnode_enable, gpioregulator_regnode_enable), + REGNODEMETHOD(regnode_set_voltage, gpioregulator_regnode_set_voltage), + REGNODEMETHOD(regnode_get_voltage, gpioregulator_regnode_get_voltage), + REGNODEMETHOD_END +}; +DEFINE_CLASS_1(gpioregulator_regnode, gpioregulator_regnode_class, + gpioregulator_regnode_methods, sizeof(struct gpioregulator_reg_sc), + regnode_class); + +static int +gpioregulator_parse_fdt(struct gpioregulator_softc *sc) +{ + uint32_t *pstates, mask; + phandle_t node; + ssize_t len; + int error, n; + + node = ofw_bus_get_node(sc->dev); + pstates = NULL; + mask = 0; + + error = regulator_parse_ofw_stdparam(sc->dev, node, + &sc->init_def.reg_init_def); + if (error != 0) + return (error); + + /* "states" property (required) */ + len = OF_getencprop_alloc(node, "states", sizeof(*pstates), + (void **)&pstates); + if (len < 2) { + device_printf(sc->dev, "invalid 'states' property\n"); + error = EINVAL; + goto done; + } + sc->init_def.nstates = len / 2; + sc->init_def.states = malloc(sc->init_def.nstates * + sizeof(*sc->init_def.states), M_DEVBUF, M_WAITOK); + for (n = 0; n < sc->init_def.nstates; n++) { + sc->init_def.states[n].val = pstates[n * 2 + 0]; + sc->init_def.states[n].mask = pstates[n * 2 + 1]; + mask |= sc->init_def.states[n].mask; + } + + /* "startup-delay-us" property (optional) */ + len = OF_getencprop(node, "startup-delay-us", + &sc->init_def.startup_delay_us, + sizeof(sc->init_def.startup_delay_us)); + if (len <= 0) + sc->init_def.startup_delay_us = 0; + + /* "enable-gpio" property (optional) */ + error = gpio_pin_get_by_ofw_property(sc->dev, node, "enable-gpio", + &sc->init_def.enable_pin); + if (error == 0) + sc->init_def.enable_pin_valid = 1; + + /* "gpios" property */ + sc->init_def.npins = 32 - __builtin_clz(mask); + sc->init_def.pins = malloc(sc->init_def.npins * + sizeof(sc->init_def.pins), M_DEVBUF, M_WAITOK); + for (n = 0; n < sc->init_def.npins; n++) { + error = gpio_pin_get_by_ofw_idx(sc->dev, node, n, + &sc->init_def.pins[n]); + if (error != 0) { + device_printf(sc->dev, "cannot get pin %d\n", n); + goto done; + } + } + +done: + if (error != 0) { + for (n = 0; n < sc->init_def.npins; n++) { + if (sc->init_def.pins[n] != NULL) + gpio_pin_release(sc->init_def.pins[n]); + } + + free(sc->init_def.states, M_DEVBUF); + free(sc->init_def.pins, M_DEVBUF); + + } + OF_prop_free(pstates); + + return (error); +} + +static int +gpioregulator_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "regulator-gpio")) + return (ENXIO); + + device_set_desc(dev, "GPIO controlled regulator"); + return (BUS_PROBE_GENERIC); +} + +static int +gpioregulator_attach(device_t dev) +{ + struct gpioregulator_softc *sc; + struct regnode *regnode; + phandle_t node; + int error; + + sc = device_get_softc(dev); + sc->dev = dev; + node = ofw_bus_get_node(dev); + + error = gpioregulator_parse_fdt(sc); + if (error != 0) { + device_printf(dev, "cannot parse parameters\n"); + return (ENXIO); + } + sc->init_def.reg_init_def.id = 1; + sc->init_def.reg_init_def.ofw_node = node; + + regnode = regnode_create(dev, &gpioregulator_regnode_class, + &sc->init_def.reg_init_def); + if (regnode == NULL) { + device_printf(dev, "cannot create regulator\n"); + return (ENXIO); + } + + sc->reg_sc = regnode_get_softc(regnode); + sc->reg_sc->regnode = regnode; + sc->reg_sc->base_dev = dev; + sc->reg_sc->param = regnode_get_stdparam(regnode); + sc->reg_sc->def = &sc->init_def; + + regnode_register(regnode); + + return (0); +} + + +static device_method_t gpioregulator_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, gpioregulator_probe), + DEVMETHOD(device_attach, gpioregulator_attach), + + /* Regdev interface */ + DEVMETHOD(regdev_map, regdev_default_ofw_map), + + DEVMETHOD_END +}; + +static driver_t gpioregulator_driver = { + "gpioregulator", + gpioregulator_methods, + sizeof(struct gpioregulator_softc), +}; + +static devclass_t gpioregulator_devclass; + +EARLY_DRIVER_MODULE(gpioregulator, simplebus, gpioregulator_driver, + gpioregulator_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LAST); +MODULE_VERSION(gpioregulator, 1); diff --git a/sys/dev/hyperv/include/vmbus.h b/sys/dev/hyperv/include/vmbus.h index 43831eb4b955..e4cb78e60428 100644 --- a/sys/dev/hyperv/include/vmbus.h +++ b/sys/dev/hyperv/include/vmbus.h @@ -117,6 +117,7 @@ struct vmbus_chan_br { struct vmbus_channel; struct hyperv_guid; +struct task; typedef void (*vmbus_chan_callback_t)(struct vmbus_channel *, void *); @@ -134,6 +135,8 @@ int vmbus_chan_open_br(struct vmbus_channel *chan, int udlen, vmbus_chan_callback_t cb, void *cbarg); void vmbus_chan_close(struct vmbus_channel *chan); void vmbus_chan_intr_drain(struct vmbus_channel *chan); +void vmbus_chan_run_task(struct vmbus_channel *chan, + struct task *task); int vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, int size, uint32_t *gpadl); diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 30c30943882e..71f0d72424a6 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -233,6 +233,10 @@ struct hn_softc { struct vmbus_xact_ctx *hn_xact; uint32_t hn_nvs_ver; + struct taskqueue *hn_mgmt_taskq; + struct taskqueue *hn_mgmt_taskq0; + struct task hn_link_task; + uint32_t hn_caps; /* HN_CAP_ */ uint32_t hn_flags; /* HN_FLAG_ */ void *hn_rxbuf; @@ -244,6 +248,8 @@ struct hn_softc { uint32_t hn_rndis_rid; uint32_t hn_ndis_ver; + int hn_ndis_tso_szmax; + int hn_ndis_tso_sgmin; struct ndis_rssprm_toeplitz hn_rss; }; @@ -269,7 +275,6 @@ struct hn_softc { */ struct hn_send_ctx; -void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status); int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 5331fbbcf74f..67c13e532a0f 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -230,7 +230,7 @@ SYSCTL_INT(_hw_hn, OID_AUTO, trust_hostip, CTLFLAG_RDTUN, "when csum info is missing (global setting)"); /* Limit TSO burst size */ -static int hn_tso_maxlen = 0; +static int hn_tso_maxlen = IP_MAXPACKET; SYSCTL_INT(_hw_hn, OID_AUTO, tso_maxlen, CTLFLAG_RDTUN, &hn_tso_maxlen, 0, "TSO burst limit"); @@ -334,10 +334,13 @@ static void hn_fixup_tx_data(struct hn_softc *); static void hn_destroy_tx_data(struct hn_softc *); static void hn_start_taskfunc(void *, int); static void hn_start_txeof_taskfunc(void *, int); +static void hn_link_taskfunc(void *, int); +static void hn_suspend_mgmt_taskfunc(void *, int); static int hn_encap(struct hn_tx_ring *, struct hn_txdesc *, struct mbuf **); static int hn_create_rx_data(struct hn_softc *sc, int); static void hn_destroy_rx_data(struct hn_softc *sc); static void hn_set_chim_size(struct hn_softc *, int); +static void hn_set_tso_maxsize(struct hn_softc *, int, int); static int hn_chan_attach(struct hn_softc *, struct vmbus_channel *); static void hn_chan_detach(struct hn_softc *, struct vmbus_channel *); static int hn_attach_subchans(struct hn_softc *); @@ -348,7 +351,11 @@ static int hn_synth_attach(struct hn_softc *, int); static void hn_synth_detach(struct hn_softc *); static bool hn_tx_ring_pending(struct hn_tx_ring *); static void hn_suspend(struct hn_softc *); +static void hn_suspend_data(struct hn_softc *); +static void hn_suspend_mgmt(struct hn_softc *); static void hn_resume(struct hn_softc *); +static void hn_resume_data(struct hn_softc *); +static void hn_resume_mgmt(struct hn_softc *); static void hn_rx_drain(struct vmbus_channel *); static void hn_tx_resume(struct hn_softc *, int); static void hn_tx_ring_qflush(struct hn_tx_ring *); @@ -517,10 +524,8 @@ netvsc_attach(device_t dev) struct sysctl_oid_list *child; struct sysctl_ctx_list *ctx; uint8_t eaddr[ETHER_ADDR_LEN]; - uint32_t link_status; struct ifnet *ifp = NULL; int error, ring_cnt, tx_ring_cnt; - int tso_maxlen; sc->hn_dev = dev; sc->hn_prichan = vmbus_get_channel(dev); @@ -550,6 +555,15 @@ netvsc_attach(device_t dev) sc->hn_tx_taskq = hn_tx_taskq; } + /* + * Setup taskqueue for mangement tasks, e.g. link status. + */ + sc->hn_mgmt_taskq0 = taskqueue_create("hn_mgmt", M_WAITOK, + taskqueue_thread_enqueue, &sc->hn_mgmt_taskq0); + taskqueue_start_threads(&sc->hn_mgmt_taskq0, 1, PI_NET, "%s mgmt", + device_get_nameunit(dev)); + TASK_INIT(&sc->hn_link_task, 0, hn_link_taskfunc, sc); + /* * Allocate ifnet and setup its name earlier, so that if_printf * can be used by functions, which will be called after @@ -621,12 +635,6 @@ netvsc_attach(device_t dev) if (error) goto failed; - error = hn_rndis_get_linkstatus(sc, &link_status); - if (error) - goto failed; - if (link_status == NDIS_MEDIA_STATE_CONNECTED) - sc->hn_carrier = 1; - error = hn_rndis_get_eaddr(sc, eaddr); if (error) goto failed; @@ -720,24 +728,28 @@ netvsc_attach(device_t dev) /* Enable all available capabilities by default. */ ifp->if_capenable = ifp->if_capabilities; - tso_maxlen = hn_tso_maxlen; - if (tso_maxlen <= 0 || tso_maxlen > IP_MAXPACKET) - tso_maxlen = IP_MAXPACKET; - ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX; - ifp->if_hw_tsomaxsegsize = PAGE_SIZE; - ifp->if_hw_tsomax = tso_maxlen - - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); + if (ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) { + hn_set_tso_maxsize(sc, hn_tso_maxlen, ETHERMTU); + ifp->if_hw_tsomaxsegcount = HN_TX_DATA_SEGCNT_MAX; + ifp->if_hw_tsomaxsegsize = PAGE_SIZE; + } ether_ifattach(ifp, eaddr); - if (bootverbose) { - if_printf(ifp, "TSO: %u/%u/%u\n", ifp->if_hw_tsomax, + if ((ifp->if_capabilities & (IFCAP_TSO6 | IFCAP_TSO4)) && bootverbose) { + if_printf(ifp, "TSO segcnt %u segsz %u\n", ifp->if_hw_tsomaxsegcount, ifp->if_hw_tsomaxsegsize); } /* Inform the upper layer about the long frame support. */ ifp->if_hdrlen = sizeof(struct ether_vlan_header); + /* + * Kick off link status check. + */ + sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0; + hn_link_status_update(sc); + return (0); failed: if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) @@ -757,6 +769,12 @@ netvsc_detach(device_t dev) if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) hn_stop(sc); + /* + * NOTE: + * hn_stop() only suspends data, so managment + * stuffs have to be suspended manually here. + */ + hn_suspend_mgmt(sc); hn_synth_detach(sc); } HN_UNLOCK(sc); @@ -769,6 +787,7 @@ netvsc_detach(device_t dev) if (sc->hn_tx_taskq != hn_tx_taskq) taskqueue_free(sc->hn_tx_taskq); + taskqueue_free(sc->hn_mgmt_taskq0); if (sc->hn_xact != NULL) vmbus_xact_ctx_destroy(sc->hn_xact); @@ -788,6 +807,36 @@ netvsc_shutdown(device_t dev) return (0); } +static void +hn_link_taskfunc(void *xsc, int pending __unused) +{ + struct hn_softc *sc = xsc; + struct ifnet *ifp = sc->hn_ifp; + uint32_t link_status; + int error; + + error = hn_rndis_get_linkstatus(sc, &link_status); + if (error) { + /* XXX what to do? */ + return; + } + + if (link_status == NDIS_MEDIA_STATE_CONNECTED) + sc->hn_carrier = 1; + else + sc->hn_carrier = 0; + if_link_state_change(ifp, + sc->hn_carrier ? LINK_STATE_UP : LINK_STATE_DOWN); +} + +void +hn_link_status_update(struct hn_softc *sc) +{ + + if (sc->hn_mgmt_taskq != NULL) + taskqueue_enqueue(sc->hn_mgmt_taskq, &sc->hn_link_task); +} + static __inline int hn_txdesc_dmamap_load(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head, bus_dma_segment_t *segs, int *nsegs) @@ -1312,19 +1361,6 @@ hn_start_locked(struct hn_tx_ring *txr, int len) return 0; } -/* - * Link up/down notification - */ -void -netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status) -{ - if (status == 1) { - sc->hn_carrier = 1; - } else { - sc->hn_carrier = 0; - } -} - /* * Append the specified data to the indicated mbuf chain, * Extend the mbuf chain if the new data does not fit in @@ -1655,8 +1691,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp)); #endif - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - hn_suspend(sc); + /* + * Suspend this interface before the synthetic parts + * are ripped. + */ + hn_suspend(sc); /* * Detach the synthetics parts, i.e. NVS and RNDIS. @@ -1672,10 +1711,12 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) hn_set_chim_size(sc, sc->hn_chim_szmax); + hn_set_tso_maxsize(sc, hn_tso_maxlen, ifr->ifr_mtu); - /* All done! Resume now. */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - hn_resume(sc); + /* + * All done! Resume the interface now. + */ + hn_resume(sc); HN_UNLOCK(sc); break; @@ -1802,9 +1843,9 @@ hn_stop(struct hn_softc *sc) KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED, ("synthetic parts were not attached")); - /* Clear RUNNING bit _before_ hn_suspend() */ + /* Clear RUNNING bit _before_ hn_suspend_data() */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); - hn_suspend(sc); + hn_suspend_data(sc); /* Clear OACTIVE bit. */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); @@ -1897,9 +1938,6 @@ hn_init_locked(struct hn_softc *sc) /* Everything is ready; unleash! */ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_RUNNING); - - /* TODO: check RNDIS link status. */ - if_link_state_change(ifp, LINK_STATE_UP); } static void @@ -2918,6 +2956,34 @@ hn_set_chim_size(struct hn_softc *sc, int chim_size) sc->hn_tx_ring[i].hn_chim_size = chim_size; } +static void +hn_set_tso_maxsize(struct hn_softc *sc, int tso_maxlen, int mtu) +{ + struct ifnet *ifp = sc->hn_ifp; + int tso_minlen; + + if ((ifp->if_capabilities & (IFCAP_TSO4 | IFCAP_TSO6)) == 0) + return; + + KASSERT(sc->hn_ndis_tso_sgmin >= 2, + ("invalid NDIS tso sgmin %d", sc->hn_ndis_tso_sgmin)); + tso_minlen = sc->hn_ndis_tso_sgmin * mtu; + + KASSERT(sc->hn_ndis_tso_szmax >= tso_minlen && + sc->hn_ndis_tso_szmax <= IP_MAXPACKET, + ("invalid NDIS tso szmax %d", sc->hn_ndis_tso_szmax)); + + if (tso_maxlen < tso_minlen) + tso_maxlen = tso_minlen; + else if (tso_maxlen > IP_MAXPACKET) + tso_maxlen = IP_MAXPACKET; + if (tso_maxlen > sc->hn_ndis_tso_szmax) + tso_maxlen = sc->hn_ndis_tso_szmax; + ifp->if_hw_tsomax = tso_maxlen - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN); + if (bootverbose) + if_printf(ifp, "TSO size max %u\n", ifp->if_hw_tsomax); +} + static void hn_fixup_tx_data(struct hn_softc *sc) { @@ -3424,7 +3490,7 @@ hn_synth_attach(struct hn_softc *sc, int mtu) /* * Attach RNDIS _after_ NVS is attached. */ - error = hn_rndis_attach(sc); + error = hn_rndis_attach(sc, mtu); if (error) return (error); @@ -3573,7 +3639,7 @@ hn_rx_drain(struct vmbus_channel *chan) } static void -hn_suspend(struct hn_softc *sc) +hn_suspend_data(struct hn_softc *sc) { struct vmbus_channel **subch = NULL; int i, nsubch; @@ -3626,6 +3692,42 @@ hn_suspend(struct hn_softc *sc) vmbus_subchan_rel(subch, nsubch); } +static void +hn_suspend_mgmt_taskfunc(void *xsc, int pending __unused) +{ + + ((struct hn_softc *)xsc)->hn_mgmt_taskq = NULL; +} + +static void +hn_suspend_mgmt(struct hn_softc *sc) +{ + struct task task; + + HN_LOCK_ASSERT(sc); + + /* + * Make sure that hn_mgmt_taskq0 can nolonger be accessed + * through hn_mgmt_taskq. + */ + TASK_INIT(&task, 0, hn_suspend_mgmt_taskfunc, sc); + vmbus_chan_run_task(sc->hn_prichan, &task); + + /* + * Make sure that all pending management tasks are completed. + */ + taskqueue_drain_all(sc->hn_mgmt_taskq0); +} + +static void +hn_suspend(struct hn_softc *sc) +{ + + if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_suspend_data(sc); + hn_suspend_mgmt(sc); +} + static void hn_tx_resume(struct hn_softc *sc, int tx_ring_cnt) { @@ -3644,7 +3746,7 @@ hn_tx_resume(struct hn_softc *sc, int tx_ring_cnt) } static void -hn_resume(struct hn_softc *sc) +hn_resume_data(struct hn_softc *sc) { int i; @@ -3658,7 +3760,8 @@ hn_resume(struct hn_softc *sc) /* * Make sure to clear suspend status on "all" TX rings, - * since hn_tx_ring_inuse can be changed after hn_suspend(). + * since hn_tx_ring_inuse can be changed after + * hn_suspend_data(). */ hn_tx_resume(sc, sc->hn_tx_ring_cnt); @@ -3685,6 +3788,26 @@ hn_resume(struct hn_softc *sc) } } +static void +hn_resume_mgmt(struct hn_softc *sc) +{ + + /* + * Kick off link status check. + */ + sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0; + hn_link_status_update(sc); +} + +static void +hn_resume(struct hn_softc *sc) +{ + + if (sc->hn_ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_resume_data(sc); + hn_resume_mgmt(sc); +} + static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index f6e6c5f27406..d176c4b4359f 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -68,6 +70,18 @@ __FBSDID("$FreeBSD$"); #define HN_RNDIS_XFER_SIZE 2048 +#define HN_NDIS_TXCSUM_CAP_IP4 \ + (NDIS_TXCSUM_CAP_IP4 | NDIS_TXCSUM_CAP_IP4OPT) +#define HN_NDIS_TXCSUM_CAP_TCP4 \ + (NDIS_TXCSUM_CAP_TCP4 | NDIS_TXCSUM_CAP_TCP4OPT) +#define HN_NDIS_TXCSUM_CAP_TCP6 \ + (NDIS_TXCSUM_CAP_TCP6 | NDIS_TXCSUM_CAP_TCP6OPT | \ + NDIS_TXCSUM_CAP_IP6EXT) +#define HN_NDIS_TXCSUM_CAP_UDP6 \ + (NDIS_TXCSUM_CAP_UDP6 | NDIS_TXCSUM_CAP_IP6EXT) +#define HN_NDIS_LSOV2_CAP_IP6 \ + (NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT) + /* * Forward declarations */ @@ -78,9 +92,14 @@ static void hv_rf_receive_data(struct hn_rx_ring *rxr, static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0); +static int hn_rndis_query2(struct hn_softc *sc, uint32_t oid, + const void *idata, size_t idlen, void *odata, size_t *odlen0, + size_t min_odlen); static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen); -static int hn_rndis_conf_offload(struct hn_softc *sc); +static int hn_rndis_conf_offload(struct hn_softc *sc, int mtu); +static int hn_rndis_query_hwcaps(struct hn_softc *sc, + struct ndis_offload *caps); static __inline uint32_t hn_rndis_rid(struct hn_softc *sc) @@ -148,11 +167,8 @@ hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen) switch (msg->rm_status) { case RNDIS_STATUS_MEDIA_CONNECT: - netvsc_linkstatus_callback(sc, 1); - break; - case RNDIS_STATUS_MEDIA_DISCONNECT: - netvsc_linkstatus_callback(sc, 0); + hn_link_status_update(sc); break; case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG: @@ -624,6 +640,15 @@ static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0) { + + return (hn_rndis_query2(sc, oid, idata, idlen, odata, odlen0, *odlen0)); +} + +static int +hn_rndis_query2(struct hn_softc *sc, uint32_t oid, + const void *idata, size_t idlen, void *odata, size_t *odlen0, + size_t min_odlen) +{ struct rndis_query_req *req; const struct rndis_query_comp *comp; struct vmbus_xact *xact; @@ -661,7 +686,7 @@ hn_rndis_query(struct hn_softc *sc, uint32_t oid, memcpy(req + 1, idata, idlen); } - comp_len = sizeof(*comp) + odlen; + comp_len = sizeof(*comp) + min_odlen; comp = hn_rndis_xact_execute(sc, xact, rid, reqlen, &comp_len, REMOTE_NDIS_QUERY_CMPLT); if (comp == NULL) { @@ -717,26 +742,44 @@ hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) size_t caps_len; int error; - /* - * Only NDIS 6.30+ is supported. - */ - KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30, - ("NDIS 6.30+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); *rxr_cnt = 0; memset(&in, 0, sizeof(in)); in.ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_CAPS; - in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; - in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; + if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_30) { + in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_1; + in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE_6_0; + } else { + in.ndis_hdr.ndis_rev = NDIS_RSS_CAPS_REV_2; + in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE; + } caps_len = NDIS_RSS_CAPS_SIZE; - error = hn_rndis_query(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES, - &in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len); + error = hn_rndis_query2(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES, + &in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len, NDIS_RSS_CAPS_SIZE_6_0); if (error) return (error); - if (caps_len < NDIS_RSS_CAPS_SIZE_6_0) { - if_printf(sc->hn_ifp, "invalid NDIS RSS caps len %zu", - caps_len); + + /* + * Preliminary verification. + */ + if (caps.ndis_hdr.ndis_type != NDIS_OBJTYPE_RSS_CAPS) { + if_printf(sc->hn_ifp, "invalid NDIS objtype 0x%02x\n", + caps.ndis_hdr.ndis_type); + return (EINVAL); + } + if (caps.ndis_hdr.ndis_rev < NDIS_RSS_CAPS_REV_1) { + if_printf(sc->hn_ifp, "invalid NDIS objrev 0x%02x\n", + caps.ndis_hdr.ndis_rev); + return (EINVAL); + } + if (caps.ndis_hdr.ndis_size > caps_len) { + if_printf(sc->hn_ifp, "invalid NDIS objsize %u, " + "data size %zu\n", caps.ndis_hdr.ndis_size, caps_len); + return (EINVAL); + } else if (caps.ndis_hdr.ndis_size < NDIS_RSS_CAPS_SIZE_6_0) { + if_printf(sc->hn_ifp, "invalid NDIS objsize %u\n", + caps.ndis_hdr.ndis_size); return (EINVAL); } @@ -746,7 +789,7 @@ hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt) } *rxr_cnt = caps.ndis_nrxr; - if (caps_len == NDIS_RSS_CAPS_SIZE) { + if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE) { if (bootverbose) { if_printf(sc->hn_ifp, "RSS indirect table size %u\n", caps.ndis_nind); @@ -806,12 +849,19 @@ hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, size_t dlen) } static int -hn_rndis_conf_offload(struct hn_softc *sc) +hn_rndis_conf_offload(struct hn_softc *sc, int mtu) { + struct ndis_offload hwcaps; struct ndis_offload_params params; - uint32_t caps; + uint32_t caps = 0; size_t paramsz; - int error; + int error, tso_maxsz, tso_minsg; + + error = hn_rndis_query_hwcaps(sc, &hwcaps); + if (error) { + if_printf(sc->hn_ifp, "hwcaps query failed: %d\n", error); + return (error); + } /* NOTE: 0 means "no change" */ memset(¶ms, 0, sizeof(params)); @@ -826,18 +876,136 @@ hn_rndis_conf_offload(struct hn_softc *sc) } params.ndis_hdr.ndis_size = paramsz; - caps = HN_CAP_IPCS | HN_CAP_TCP4CS | HN_CAP_TCP6CS; - params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; - params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; - params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; - if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { - caps |= HN_CAP_UDP4CS | HN_CAP_UDP6CS; - params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; - params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; + /* + * TSO4/TSO6 setup. + */ + tso_maxsz = IP_MAXPACKET; + tso_minsg = 2; + if (hwcaps.ndis_lsov2.ndis_ip4_encap & NDIS_OFFLOAD_ENCAP_8023) { + caps |= HN_CAP_TSO4; + params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; + + if (hwcaps.ndis_lsov2.ndis_ip4_maxsz < tso_maxsz) + tso_maxsz = hwcaps.ndis_lsov2.ndis_ip4_maxsz; + if (hwcaps.ndis_lsov2.ndis_ip4_minsg > tso_minsg) + tso_minsg = hwcaps.ndis_lsov2.ndis_ip4_minsg; + } + if ((hwcaps.ndis_lsov2.ndis_ip6_encap & NDIS_OFFLOAD_ENCAP_8023) && + (hwcaps.ndis_lsov2.ndis_ip6_opts & HN_NDIS_LSOV2_CAP_IP6) == + HN_NDIS_LSOV2_CAP_IP6) { +#ifdef notyet + caps |= HN_CAP_TSO6; + params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON; + + if (hwcaps.ndis_lsov2.ndis_ip6_maxsz < tso_maxsz) + tso_maxsz = hwcaps.ndis_lsov2.ndis_ip6_maxsz; + if (hwcaps.ndis_lsov2.ndis_ip6_minsg > tso_minsg) + tso_minsg = hwcaps.ndis_lsov2.ndis_ip6_minsg; +#endif + } + sc->hn_ndis_tso_szmax = 0; + sc->hn_ndis_tso_sgmin = 0; + if (caps & (HN_CAP_TSO4 | HN_CAP_TSO6)) { + KASSERT(tso_maxsz <= IP_MAXPACKET, + ("invalid NDIS TSO maxsz %d", tso_maxsz)); + KASSERT(tso_minsg >= 2, + ("invalid NDIS TSO minsg %d", tso_minsg)); + if (tso_maxsz < tso_minsg * mtu) { + if_printf(sc->hn_ifp, "invalid NDIS TSO config: " + "maxsz %d, minsg %d, mtu %d; " + "disable TSO4 and TSO6\n", + tso_maxsz, tso_minsg, mtu); + caps &= ~(HN_CAP_TSO4 | HN_CAP_TSO6); + params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_OFF; + params.ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_OFF; + } else { + sc->hn_ndis_tso_szmax = tso_maxsz; + sc->hn_ndis_tso_sgmin = tso_minsg; + if (bootverbose) { + if_printf(sc->hn_ifp, "NDIS TSO " + "szmax %d sgmin %d\n", + sc->hn_ndis_tso_szmax, + sc->hn_ndis_tso_sgmin); + } + } + } + + /* IPv4 checksum */ + if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HN_NDIS_TXCSUM_CAP_IP4) == + HN_NDIS_TXCSUM_CAP_IP4) { + caps |= HN_CAP_IPCS; + params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TX; + } + if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_IP4) { + if (params.ndis_ip4csum == NDIS_OFFLOAD_PARAM_TX) + params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_TXRX; + else + params.ndis_ip4csum = NDIS_OFFLOAD_PARAM_RX; + } + + /* TCP4 checksum */ + if ((hwcaps.ndis_csum.ndis_ip4_txcsum & HN_NDIS_TXCSUM_CAP_TCP4) == + HN_NDIS_TXCSUM_CAP_TCP4) { + caps |= HN_CAP_TCP4CS; + params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TX; + } + if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_TCP4) { + if (params.ndis_tcp4csum == NDIS_OFFLOAD_PARAM_TX) + params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_TXRX; + else + params.ndis_tcp4csum = NDIS_OFFLOAD_PARAM_RX; + } + + /* UDP4 checksum */ + if (hwcaps.ndis_csum.ndis_ip4_txcsum & NDIS_TXCSUM_CAP_UDP4) { + caps |= HN_CAP_UDP4CS; + params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TX; + } + if (hwcaps.ndis_csum.ndis_ip4_rxcsum & NDIS_RXCSUM_CAP_UDP4) { + if (params.ndis_udp4csum == NDIS_OFFLOAD_PARAM_TX) + params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_TXRX; + else + params.ndis_udp4csum = NDIS_OFFLOAD_PARAM_RX; + } + + /* TCP6 checksum */ + if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HN_NDIS_TXCSUM_CAP_TCP6) == + HN_NDIS_TXCSUM_CAP_TCP6) { + caps |= HN_CAP_TCP6CS; + params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TX; + } + if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_TCP6) { + if (params.ndis_tcp6csum == NDIS_OFFLOAD_PARAM_TX) + params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_TXRX; + else + params.ndis_tcp6csum = NDIS_OFFLOAD_PARAM_RX; + } + + /* UDP6 checksum */ + if ((hwcaps.ndis_csum.ndis_ip6_txcsum & HN_NDIS_TXCSUM_CAP_UDP6) == + HN_NDIS_TXCSUM_CAP_UDP6) { + caps |= HN_CAP_UDP6CS; + params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TX; + } + if (hwcaps.ndis_csum.ndis_ip6_rxcsum & NDIS_RXCSUM_CAP_UDP6) { + if (params.ndis_udp6csum == NDIS_OFFLOAD_PARAM_TX) + params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_TXRX; + else + params.ndis_udp6csum = NDIS_OFFLOAD_PARAM_RX; + } + + if (bootverbose) { + if_printf(sc->hn_ifp, "offload csum: " + "ip4 %u, tcp4 %u, udp4 %u, tcp6 %u, udp6 %u\n", + params.ndis_ip4csum, + params.ndis_tcp4csum, + params.ndis_udp4csum, + params.ndis_tcp6csum, + params.ndis_udp6csum); + if_printf(sc->hn_ifp, "offload lsov2: ip4 %u, ip6 %u\n", + params.ndis_lsov2_ip4, + params.ndis_lsov2_ip6); } - caps |= HN_CAP_TSO4; - params.ndis_lsov2_ip4 = NDIS_OFFLOAD_LSOV2_ON; - /* XXX ndis_lsov2_ip6 = NDIS_OFFLOAD_LSOV2_ON */ error = hn_rndis_set(sc, OID_TCP_OFFLOAD_PARAMETERS, ¶ms, paramsz); if (error) { @@ -994,8 +1162,92 @@ hn_rndis_halt(struct hn_softc *sc) return (0); } +static int +hn_rndis_query_hwcaps(struct hn_softc *sc, struct ndis_offload *caps) +{ + struct ndis_offload in; + size_t caps_len, size; + int error; + + memset(&in, 0, sizeof(in)); + in.ndis_hdr.ndis_type = NDIS_OBJTYPE_OFFLOAD; + if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_30) { + in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_3; + size = NDIS_OFFLOAD_SIZE; + } else if (sc->hn_ndis_ver >= HN_NDIS_VERSION_6_1) { + in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_2; + size = NDIS_OFFLOAD_SIZE_6_1; + } else { + in.ndis_hdr.ndis_rev = NDIS_OFFLOAD_REV_1; + size = NDIS_OFFLOAD_SIZE_6_0; + } + in.ndis_hdr.ndis_size = size; + + caps_len = NDIS_OFFLOAD_SIZE; + error = hn_rndis_query2(sc, OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES, + &in, size, caps, &caps_len, NDIS_OFFLOAD_SIZE_6_0); + if (error) + return (error); + + /* + * Preliminary verification. + */ + if (caps->ndis_hdr.ndis_type != NDIS_OBJTYPE_OFFLOAD) { + if_printf(sc->hn_ifp, "invalid NDIS objtype 0x%02x\n", + caps->ndis_hdr.ndis_type); + return (EINVAL); + } + if (caps->ndis_hdr.ndis_rev < NDIS_OFFLOAD_REV_1) { + if_printf(sc->hn_ifp, "invalid NDIS objrev 0x%02x\n", + caps->ndis_hdr.ndis_rev); + return (EINVAL); + } + if (caps->ndis_hdr.ndis_size > caps_len) { + if_printf(sc->hn_ifp, "invalid NDIS objsize %u, " + "data size %zu\n", caps->ndis_hdr.ndis_size, caps_len); + return (EINVAL); + } else if (caps->ndis_hdr.ndis_size < NDIS_OFFLOAD_SIZE_6_0) { + if_printf(sc->hn_ifp, "invalid NDIS objsize %u\n", + caps->ndis_hdr.ndis_size); + return (EINVAL); + } + + if (bootverbose) { + /* + * NOTE: + * caps->ndis_hdr.ndis_size MUST be checked before accessing + * NDIS 6.1+ specific fields. + */ + if_printf(sc->hn_ifp, "hwcaps rev %u\n", + caps->ndis_hdr.ndis_rev); + + if_printf(sc->hn_ifp, "hwcaps csum: " + "ip4 tx 0x%x/0x%x rx 0x%x/0x%x, " + "ip6 tx 0x%x/0x%x rx 0x%x/0x%x\n", + caps->ndis_csum.ndis_ip4_txcsum, + caps->ndis_csum.ndis_ip4_txenc, + caps->ndis_csum.ndis_ip4_rxcsum, + caps->ndis_csum.ndis_ip4_rxenc, + caps->ndis_csum.ndis_ip6_txcsum, + caps->ndis_csum.ndis_ip6_txenc, + caps->ndis_csum.ndis_ip6_rxcsum, + caps->ndis_csum.ndis_ip6_rxenc); + if_printf(sc->hn_ifp, "hwcaps lsov2: " + "ip4 maxsz %u minsg %u encap 0x%x, " + "ip6 maxsz %u minsg %u encap 0x%x opts 0x%x\n", + caps->ndis_lsov2.ndis_ip4_maxsz, + caps->ndis_lsov2.ndis_ip4_minsg, + caps->ndis_lsov2.ndis_ip4_encap, + caps->ndis_lsov2.ndis_ip6_maxsz, + caps->ndis_lsov2.ndis_ip6_minsg, + caps->ndis_lsov2.ndis_ip6_encap, + caps->ndis_lsov2.ndis_ip6_opts); + } + return (0); +} + int -hn_rndis_attach(struct hn_softc *sc) +hn_rndis_attach(struct hn_softc *sc, int mtu) { int error; @@ -1010,7 +1262,7 @@ hn_rndis_attach(struct hn_softc *sc) * Configure NDIS offload settings. * XXX no offloading, if error happened? */ - hn_rndis_conf_offload(sc); + hn_rndis_conf_offload(sc, mtu); return (0); } diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index e48033c35ab3..517d2815908b 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -117,7 +117,7 @@ struct rndis_packet_msg; uint32_t hn_chim_alloc(struct hn_softc *sc); void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); -int hn_rndis_attach(struct hn_softc *sc); +int hn_rndis_attach(struct hn_softc *sc, int mtu); void hn_rndis_detach(struct hn_softc *sc); int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, @@ -138,6 +138,7 @@ void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info); void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); +void hn_link_status_update(struct hn_softc *sc); extern struct hn_send_ctx hn_send_ctx_none; diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h index 28920f8e09c8..fed262dddf67 100644 --- a/sys/dev/hyperv/netvsc/ndis.h +++ b/sys/dev/hyperv/netvsc/ndis.h @@ -59,6 +59,7 @@ #define NDIS_OBJTYPE_DEFAULT 0x80 #define NDIS_OBJTYPE_RSS_CAPS 0x88 #define NDIS_OBJTYPE_RSS_PARAMS 0x89 +#define NDIS_OBJTYPE_OFFLOAD 0xa7 struct ndis_object_hdr { uint8_t ndis_type; /* NDIS_OBJTYPE_ */ @@ -204,6 +205,129 @@ struct ndis_rssprm_toeplitz { uint32_t rss_ind[NDIS_HASH_INDCNT]; }; +/* + * OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES + * ndis_type: NDIS_OBJTYPE_OFFLOAD + */ + +#define NDIS_OFFLOAD_ENCAP_NONE 0x0000 +#define NDIS_OFFLOAD_ENCAP_NULL 0x0001 +#define NDIS_OFFLOAD_ENCAP_8023 0x0002 +#define NDIS_OFFLOAD_ENCAP_8023PQ 0x0004 +#define NDIS_OFFLOAD_ENCAP_8023PQ_OOB 0x0008 +#define NDIS_OFFLOAD_ENCAP_RFC1483 0x0010 + +struct ndis_csum_offload { + uint32_t ndis_ip4_txenc; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip4_txcsum; +#define NDIS_TXCSUM_CAP_IP4OPT 0x001 +#define NDIS_TXCSUM_CAP_TCP4OPT 0x004 +#define NDIS_TXCSUM_CAP_TCP4 0x010 +#define NDIS_TXCSUM_CAP_UDP4 0x040 +#define NDIS_TXCSUM_CAP_IP4 0x100 + uint32_t ndis_ip4_rxenc; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip4_rxcsum; +#define NDIS_RXCSUM_CAP_IP4OPT 0x001 +#define NDIS_RXCSUM_CAP_TCP4OPT 0x004 +#define NDIS_RXCSUM_CAP_TCP4 0x010 +#define NDIS_RXCSUM_CAP_UDP4 0x040 +#define NDIS_RXCSUM_CAP_IP4 0x100 + uint32_t ndis_ip6_txenc; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip6_txcsum; +#define NDIS_TXCSUM_CAP_IP6EXT 0x001 +#define NDIS_TXCSUM_CAP_TCP6OPT 0x004 +#define NDIS_TXCSUM_CAP_TCP6 0x010 +#define NDIS_TXCSUM_CAP_UDP6 0x040 + uint32_t ndis_ip6_rxenc; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip6_rxcsum; +#define NDIS_RXCSUM_CAP_IP6EXT 0x001 +#define NDIS_RXCSUM_CAP_TCP6OPT 0x004 +#define NDIS_RXCSUM_CAP_TCP6 0x010 +#define NDIS_RXCSUM_CAP_UDP6 0x040 +}; + +struct ndis_lsov1_offload { + uint32_t ndis_encap; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_maxsize; + uint32_t ndis_minsegs; + uint32_t ndis_opts; +}; + +struct ndis_ipsecv1_offload { + uint32_t ndis_encap; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ah_esp; + uint32_t ndis_xport_tun; + uint32_t ndis_ip4_opts; + uint32_t ndis_flags; + uint32_t ndis_ip4_ah; + uint32_t ndis_ip4_esp; +}; + +struct ndis_lsov2_offload { + uint32_t ndis_ip4_encap; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip4_maxsz; + uint32_t ndis_ip4_minsg; + uint32_t ndis_ip6_encap; /*NDIS_OFFLOAD_ENCAP_*/ + uint32_t ndis_ip6_maxsz; + uint32_t ndis_ip6_minsg; + uint32_t ndis_ip6_opts; +#define NDIS_LSOV2_CAP_IP6EXT 0x001 +#define NDIS_LSOV2_CAP_TCP6OPT 0x004 +}; + +struct ndis_ipsecv2_offload { + uint32_t ndis_encap; /*NDIS_OFFLOAD_ENCAP_*/ + uint16_t ndis_ip6; + uint16_t ndis_ip4opt; + uint16_t ndis_ip6ext; + uint16_t ndis_ah; + uint16_t ndis_esp; + uint16_t ndis_ah_esp; + uint16_t ndis_xport; + uint16_t ndis_tun; + uint16_t ndis_xport_tun; + uint16_t ndis_lso; + uint16_t ndis_extseq; + uint32_t ndis_udp_esp; + uint32_t ndis_auth; + uint32_t ndis_crypto; + uint32_t ndis_sa_caps; +}; + +struct ndis_rsc_offload { + uint16_t ndis_ip4; + uint16_t ndis_ip6; +}; + +struct ndis_encap_offload { + uint32_t ndis_flags; + uint32_t ndis_maxhdr; +}; + +struct ndis_offload { + struct ndis_object_hdr ndis_hdr; + struct ndis_csum_offload ndis_csum; + struct ndis_lsov1_offload ndis_lsov1; + struct ndis_ipsecv1_offload ndis_ipsecv1; + struct ndis_lsov2_offload ndis_lsov2; + uint32_t ndis_flags; + /* NDIS >= 6.1 */ + struct ndis_ipsecv2_offload ndis_ipsecv2; + /* NDIS >= 6.30 */ + struct ndis_rsc_offload ndis_rsc; + struct ndis_encap_offload ndis_encap_gre; +}; + +#define NDIS_OFFLOAD_SIZE sizeof(struct ndis_offload) +#define NDIS_OFFLOAD_SIZE_6_0 \ + __offsetof(struct ndis_offload, ndis_ipsecv2) +#define NDIS_OFFLOAD_SIZE_6_1 \ + __offsetof(struct ndis_offload, ndis_rsc) + +#define NDIS_OFFLOAD_REV_1 1 /* NDIS 6.0 */ +#define NDIS_OFFLOAD_REV_2 2 /* NDIS 6.1 */ +#define NDIS_OFFLOAD_REV_3 3 /* NDIS 6.30 */ + /* * Per-packet-info */ diff --git a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c index c8d7d2458025..36751d8df2eb 100644 --- a/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c +++ b/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c @@ -2210,7 +2210,7 @@ storvsc_io_done(struct hv_storvsc_request *reqp) resp_buf[3], resp_buf[4]); } if (vm_srb->srb_status == SRB_STATUS_SUCCESS && - data_len > SHORT_INQUIRY_LENGTH) { + data_len >= SHORT_INQUIRY_LENGTH) { char vendor[16]; cam_strvis(vendor, inq_data->vendor, diff --git a/sys/dev/hyperv/vmbus/vmbus_br.c b/sys/dev/hyperv/vmbus/vmbus_br.c index 99f4f8826b17..d9bd787a512e 100644 --- a/sys/dev/hyperv/vmbus/vmbus_br.c +++ b/sys/dev/hyperv/vmbus/vmbus_br.c @@ -26,6 +26,9 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +__FBSDID("$FreeBSD$"); + #include #include #include diff --git a/sys/dev/hyperv/vmbus/vmbus_chan.c b/sys/dev/hyperv/vmbus/vmbus_chan.c index e7e194715273..34b07eeff735 100644 --- a/sys/dev/hyperv/vmbus/vmbus_chan.c +++ b/sys/dev/hyperv/vmbus/vmbus_chan.c @@ -1713,3 +1713,11 @@ vmbus_chan_rx_empty(const struct vmbus_channel *chan) return (vmbus_rxbr_empty(&chan->ch_rxbr)); } + +void +vmbus_chan_run_task(struct vmbus_channel *chan, struct task *task) +{ + + taskqueue_enqueue(chan->ch_tq, task); + taskqueue_drain(chan->ch_tq, task); +} diff --git a/sys/dev/iicbus/iicsmb.c b/sys/dev/iicbus/iicsmb.c index d8f35c6e3baf..b49d93d56efa 100644 --- a/sys/dev/iicbus/iicsmb.c +++ b/sys/dev/iicbus/iicsmb.c @@ -131,8 +131,6 @@ static driver_t iicsmb_driver = { sizeof(struct iicsmb_softc), }; -#define IICBUS_TIMEOUT 100 /* us */ - static void iicsmb_identify(driver_t *driver, device_t parent) { @@ -275,238 +273,214 @@ iicsmb_callback(device_t dev, int index, void *data) return (error); } +static int +iic2smb_error(int error) +{ + switch (error) { + case IIC_NOERR: + return (SMB_ENOERR); + case IIC_EBUSERR: + return (SMB_EBUSERR); + case IIC_ENOACK: + return (SMB_ENOACK); + case IIC_ETIMEOUT: + return (SMB_ETIMEOUT); + case IIC_EBUSBSY: + return (SMB_EBUSY); + case IIC_ESTATUS: + return (SMB_EBUSERR); + case IIC_EUNDERFLOW: + return (SMB_EBUSERR); + case IIC_EOVERFLOW: + return (SMB_EBUSERR); + case IIC_ENOTSUPP: + return (SMB_ENOTSUPP); + case IIC_ENOADDR: + return (SMB_EBUSERR); + case IIC_ERESOURCE: + return (SMB_EBUSERR); + default: + return (SMB_EBUSERR); + } +} + +#define TRANSFER_MSGS(dev, msgs) iicbus_transfer(dev, msgs, nitems(msgs)) + static int iicsmb_quick(device_t dev, u_char slave, int how) { - device_t parent = device_get_parent(dev); + struct iic_msg msgs[] = { + { slave, how == SMB_QWRITE ? IIC_M_WR : IIC_M_RD, 0, NULL }, + }; int error; switch (how) { case SMB_QWRITE: - error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT); - break; - case SMB_QREAD: - error = iicbus_start(parent, slave | LSB, IICBUS_TIMEOUT); break; - default: - error = EINVAL; - break; + return (SMB_EINVAL); } - if (!error) - error = iicbus_stop(parent); - - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_sendb(device_t dev, u_char slave, char byte) { - device_t parent = device_get_parent(dev); - int error, sent; + struct iic_msg msgs[] = { + { slave, IIC_M_WR, 1, &byte }, + }; + int error; - error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT); - - if (!error) { - error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT); - - iicbus_stop(parent); - } - - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_recvb(device_t dev, u_char slave, char *byte) { - device_t parent = device_get_parent(dev); - int error, read; + struct iic_msg msgs[] = { + { slave, IIC_M_RD, 1, byte }, + }; + int error; - error = iicbus_start(parent, slave | LSB, 0); - - if (!error) { - error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT); - - iicbus_stop(parent); - } - - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_writeb(device_t dev, u_char slave, char cmd, char byte) { - device_t parent = device_get_parent(dev); - int error, sent; + uint8_t bytes[] = { cmd, byte }; + struct iic_msg msgs[] = { + { slave, IIC_M_WR, nitems(bytes), bytes }, + }; + int error; - error = iicbus_start(parent, slave & ~LSB, 0); - - if (!error) { - if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - error = iicbus_write(parent, &byte, 1, &sent, IICBUS_TIMEOUT); - - iicbus_stop(parent); - } - - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_writew(device_t dev, u_char slave, char cmd, short word) { - device_t parent = device_get_parent(dev); - int error, sent; + uint8_t bytes[] = { cmd, word & 0xff, word >> 8 }; + struct iic_msg msgs[] = { + { slave, IIC_M_WR, nitems(bytes), bytes }, + }; + int error; - char low = (char)(word & 0xff); - char high = (char)((word & 0xff00) >> 8); - - error = iicbus_start(parent, slave & ~LSB, 0); - - if (!error) { - if (!(error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - if (!(error = iicbus_write(parent, &low, 1, &sent, IICBUS_TIMEOUT))) - error = iicbus_write(parent, &high, 1, &sent, IICBUS_TIMEOUT); - - iicbus_stop(parent); - } - - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_readb(device_t dev, u_char slave, char cmd, char *byte) { - device_t parent = device_get_parent(dev); - int error, sent, read; + struct iic_msg msgs[] = { + { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd }, + { slave, IIC_M_RD, 1, byte }, + }; + int error; - if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT))) - return (error); - - if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_read(parent, byte, 1, &read, IIC_LAST_READ, IICBUS_TIMEOUT))) - goto error; - -error: - iicbus_stop(parent); - return (error); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } -#define BUF2SHORT(low,high) \ - ((short)(((high) & 0xff) << 8) | (short)((low) & 0xff)) - static int iicsmb_readw(device_t dev, u_char slave, char cmd, short *word) { - device_t parent = device_get_parent(dev); - int error, sent, read; - char buf[2]; + uint8_t buf[2]; + struct iic_msg msgs[] = { + { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd }, + { slave, IIC_M_RD, nitems(buf), buf }, + }; + int error; - if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT))) - return (error); - - if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT))) - goto error; - - /* first, receive low, then high byte */ - *word = BUF2SHORT(buf[0], buf[1]); - -error: - iicbus_stop(parent); - return (error); + error = TRANSFER_MSGS(dev, msgs); + if (error == 0) + *word = ((uint16_t)buf[1] << 8) | buf[0]; + return (iic2smb_error(error)); } static int iicsmb_pcall(device_t dev, u_char slave, char cmd, short sdata, short *rdata) { - device_t parent = device_get_parent(dev); - int error, sent, read; - char buf[2]; + uint8_t in[3] = { cmd, sdata & 0xff, sdata >> 8 }; + uint8_t out[2]; + struct iic_msg msgs[] = { + { slave, IIC_M_WR | IIC_M_NOSTOP, nitems(in), in }, + { slave, IIC_M_RD, nitems(out), out }, + }; + int error; - if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT))) - return (error); - - if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - goto error; - - /* first, send low, then high byte */ - buf[0] = (char)(sdata & 0xff); - buf[1] = (char)((sdata & 0xff00) >> 8); - - if ((error = iicbus_write(parent, buf, 2, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_read(parent, buf, 2, &read, IIC_LAST_READ, IICBUS_TIMEOUT))) - goto error; - - /* first, receive low, then high byte */ - *rdata = BUF2SHORT(buf[0], buf[1]); - -error: - iicbus_stop(parent); - return (error); + error = TRANSFER_MSGS(dev, msgs); + if (error == 0) + *rdata = ((uint16_t)out[1] << 8) | out[0]; + return (iic2smb_error(error)); } static int iicsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf) { - device_t parent = device_get_parent(dev); - int error, sent; + uint8_t bytes[2] = { cmd, count }; + struct iic_msg msgs[] = { + { slave, IIC_M_WR | IIC_M_NOSTOP, nitems(bytes), bytes }, + { slave, IIC_M_WR | IIC_M_NOSTART, count, buf }, + }; + int error; - if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_write(parent, buf, (int)count, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_stop(parent))) - goto error; - -error: - return (error); + if (count > 32 || count == 0) + return (SMB_EINVAL); + error = TRANSFER_MSGS(dev, msgs); + return (iic2smb_error(error)); } static int iicsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf) { + struct iic_msg msgs[] = { + { slave, IIC_M_WR | IIC_M_NOSTOP, 1, &cmd }, + { slave, IIC_M_RD | IIC_M_NOSTOP, 1, count }, + }; + struct iic_msg block_msg[] = { + { slave, IIC_M_RD | IIC_M_NOSTART, 0, buf }, + }; device_t parent = device_get_parent(dev); - int error, sent, read; + int error; + u_char bufsz; - if ((error = iicbus_start(parent, slave & ~LSB, IICBUS_TIMEOUT))) - return (error); + /* Stash output buffer size before overwriting it. */ + bufsz = *count; + if (bufsz == 0) + return (SMB_EINVAL); - if ((error = iicbus_write(parent, &cmd, 1, &sent, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_repeated_start(parent, slave | LSB, IICBUS_TIMEOUT))) - goto error; - - if ((error = iicbus_read(parent, buf, (int)*count, &read, - IIC_LAST_READ, IICBUS_TIMEOUT))) - goto error; - *count = read; - -error: - iicbus_stop(parent); - return (error); + /* Have to do this because the command is split in two transfers. */ + error = iicbus_request_bus(parent, dev, IIC_WAIT); + if (error == 0) + error = TRANSFER_MSGS(dev, msgs); + if (error == 0) { + /* + * If the slave offers an empty or a too long reply, + * read one byte to generate the stop or abort. + * XXX 32 is hardcoded until SMB_MAXBLOCKSIZE is restored + * to sanity. + */ + if (*count > 32 || *count == 0) + block_msg[0].len = 1; + /* If longer than the buffer, then clamp at the buffer size. */ + if (*count > bufsz) + block_msg[0].len = bufsz; + else + block_msg[0].len = *count; + error = TRANSFER_MSGS(dev, block_msg); + if (*count > 32 || *count == 0) + error = SMB_EINVAL; + } + (void)iicbus_release_bus(parent, dev); + return (iic2smb_error(error)); } DRIVER_MODULE(iicsmb, iicbus, iicsmb_driver, iicsmb_devclass, 0, 0); diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c index 397b3a85c651..19d8a5b08f0f 100644 --- a/sys/dev/iwm/if_iwm.c +++ b/sys/dev/iwm/if_iwm.c @@ -2977,6 +2977,8 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, /* rssi is in 1/2db units */ rxs.c_rssi = rssi * 2; rxs.c_nf = sc->sc_noise; + if (ieee80211_add_rx_params(m, &rxs) == 0) + goto fail; if (ieee80211_radiotap_active_vap(vap)) { struct iwm_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -3013,11 +3015,11 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc, IWM_UNLOCK(sc); if (ni != NULL) { IWM_DPRINTF(sc, IWM_DEBUG_RECV, "input m %p\n", m); - ieee80211_input_mimo(ni, m, &rxs); + ieee80211_input_mimo(ni, m); ieee80211_free_node(ni); } else { IWM_DPRINTF(sc, IWM_DEBUG_RECV, "inputall m %p\n", m); - ieee80211_input_mimo_all(ic, m, &rxs); + ieee80211_input_mimo_all(ic, m); } IWM_LOCK(sc); diff --git a/sys/dev/kbd/kbd.c b/sys/dev/kbd/kbd.c index ff49ee61b2c8..74c5a56f0878 100644 --- a/sys/dev/kbd/kbd.c +++ b/sys/dev/kbd/kbd.c @@ -888,7 +888,7 @@ genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) case PIO_KEYMAP: /* set keyboard translation table */ case OPIO_KEYMAP: /* set keyboard translation table (compat) */ #ifndef KBD_DISABLE_KEYMAP_LOAD - mapp = malloc(sizeof *mapp, M_TEMP, M_NOWAIT); + mapp = malloc(sizeof *mapp, M_TEMP, M_WAITOK); if (cmd == OPIO_KEYMAP) { omapp = (okeymap_t *)arg; mapp->n_keys = omapp->n_keys; diff --git a/sys/dev/otus/if_otus.c b/sys/dev/otus/if_otus.c index 33f6b0f93afc..d67a01602168 100644 --- a/sys/dev/otus/if_otus.c +++ b/sys/dev/otus/if_otus.c @@ -1713,7 +1713,10 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq) rxs.c_nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */ rxs.c_rssi = tail->rssi; /* XXX TODO: add MIMO RSSI/NF as well */ - ieee80211_add_rx_params(m, &rxs); + if (ieee80211_add_rx_params(m, &rxs) == 0) { + counter_u64_add(ic->ic_ierrors, 1); + return; + } /* XXX make a method */ STAILQ_INSERT_TAIL(&rxq->mq_head, m, m_stailqpkt); @@ -1826,10 +1829,10 @@ otus_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) if (ni != NULL) { if (ni->ni_flags & IEEE80211_NODE_HT) m->m_flags |= M_AMPDU; - (void)ieee80211_input_mimo(ni, m, NULL); + (void)ieee80211_input_mimo(ni, m); ieee80211_free_node(ni); } else - (void)ieee80211_input_mimo_all(ic, m, NULL); + (void)ieee80211_input_mimo_all(ic, m); } #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_ff_age_all(ic, 100); diff --git a/sys/dev/sfxge/common/ef10_nic.c b/sys/dev/sfxge/common/ef10_nic.c index 3c4058840a70..64231549059c 100644 --- a/sys/dev/sfxge/common/ef10_nic.c +++ b/sys/dev/sfxge/common/ef10_nic.c @@ -164,6 +164,7 @@ ef10_nic_get_port_mode_bandwidth( break; case TLV_PORT_MODE_10G_10G_10G_10G: case TLV_PORT_MODE_10G_10G_10G_10G_Q: + case TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2: case TLV_PORT_MODE_10G_10G_10G_10G_Q2: bandwidth = 10000 * 4; break; @@ -1098,57 +1099,74 @@ ef10_get_privilege_mask( /* - * The external port mapping is a one-based numbering of the external - * connectors on the board. It does not distinguish off-board separated - * outputs such as multi-headed cables. - * The number of ports that map to each external port connector - * on the board is determined by the chip family and the port modes to - * which the NIC can be configured. The mapping table lists modes with - * port numbering requirements in increasing order. + * Table of mapping schemes from port number to the number of the external + * connector on the board. The external numbering does not distinguish + * off-board separated outputs such as from multi-headed cables. + * + * The count of adjacent port numbers that map to each external port + * and the offset in the numbering, is determined by the chip family and + * current port mode. + * + * For the Huntington family, the current port mode cannot be discovered, + * so the mapping used is instead the last match in the table to the full + * set of port modes to which the NIC can be configured. Therefore the + * ordering of entries in the the mapping table is significant. */ static struct { efx_family_t family; uint32_t modes_mask; - uint32_t stride; + int32_t count; + int32_t offset; } __ef10_external_port_mappings[] = { - /* Supported modes requiring 1 output per port */ + /* Supported modes with 1 output per external port */ { EFX_FAMILY_HUNTINGTON, (1 << TLV_PORT_MODE_10G) | (1 << TLV_PORT_MODE_10G_10G) | (1 << TLV_PORT_MODE_10G_10G_10G_10G), + 1, 1 }, { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G) | - (1 << TLV_PORT_MODE_10G_10G) | - (1 << TLV_PORT_MODE_10G_10G_10G_10G), + (1 << TLV_PORT_MODE_10G_10G), + 1, 1 }, - /* Supported modes requiring 2 outputs per port */ + /* Supported modes with 2 outputs per external port */ { EFX_FAMILY_HUNTINGTON, (1 << TLV_PORT_MODE_40G) | (1 << TLV_PORT_MODE_40G_40G) | (1 << TLV_PORT_MODE_40G_10G_10G) | (1 << TLV_PORT_MODE_10G_10G_40G), - 2 + 2, + 1 }, { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_40G) | (1 << TLV_PORT_MODE_40G_40G) | (1 << TLV_PORT_MODE_40G_10G_10G) | - (1 << TLV_PORT_MODE_10G_10G_40G), - 2 + (1 << TLV_PORT_MODE_10G_10G_40G) | + (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2), + 2, + 1 }, - /* Supported modes requiring 4 outputs per port */ + /* Supported modes with 4 outputs per external port */ { EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q) | + (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q1), + 4, + 1, + }, + { + EFX_FAMILY_MEDFORD, (1 << TLV_PORT_MODE_10G_10G_10G_10G_Q2), - 4 + 4, + 2 }, }; @@ -1162,11 +1180,26 @@ ef10_external_port_mapping( int i; uint32_t port_modes; uint32_t matches; - uint32_t stride = 1; /* default 1-1 mapping */ + uint32_t current; + int32_t count = 1; /* Default 1-1 mapping */ + int32_t offset = 1; /* Default starting external port number */ - if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, NULL)) != 0) { - /* No port mode information available - use default mapping */ - goto out; + if ((rc = efx_mcdi_get_port_modes(enp, &port_modes, ¤t)) != 0) { + /* + * No current port mode information + * - infer mapping from available modes + */ + if ((rc = efx_mcdi_get_port_modes(enp, + &port_modes, NULL)) != 0) { + /* + * No port mode information available + * - use default mapping + */ + goto out; + } + } else { + /* Only need to scan the current mode */ + port_modes = 1 << current; } /* @@ -1180,7 +1213,8 @@ ef10_external_port_mapping( matches = (__ef10_external_port_mappings[i].modes_mask & port_modes); if (matches != 0) { - stride = __ef10_external_port_mappings[i].stride; + count = __ef10_external_port_mappings[i].count; + offset = __ef10_external_port_mappings[i].offset; port_modes &= ~matches; } } @@ -1194,9 +1228,9 @@ ef10_external_port_mapping( out: /* * Scale as required by last matched mode and then convert to - * one-based numbering + * correctly offset numbering */ - *external_portp = (uint8_t)(port / stride) + 1; + *external_portp = (uint8_t)((port / count) + offset); return (0); fail1: diff --git a/sys/dev/sfxge/common/ef10_tlv_layout.h b/sys/dev/sfxge/common/ef10_tlv_layout.h index 811d7c327cb9..033cdf9ae41b 100644 --- a/sys/dev/sfxge/common/ef10_tlv_layout.h +++ b/sys/dev/sfxge/common/ef10_tlv_layout.h @@ -553,12 +553,14 @@ struct tlv_global_port_mode { #define TLV_PORT_MODE_40G (1) /* 40G, single QSFP/40G-KR */ #define TLV_PORT_MODE_10G_10G (2) /* 2x10G, dual SFP/10G-KR or single QSFP */ #define TLV_PORT_MODE_40G_40G (3) /* 40G + 40G, dual QSFP/40G-KR (Greenport, Medford) */ -#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport, Medford) */ -#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) */ +#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport) */ +#define TLV_PORT_MODE_10G_10G_10G_10G_Q1 (4) /* 4x10G, single QSFP, cage 0 (Medford) */ +#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) OBSOLETE DO NOT USE */ #define TLV_PORT_MODE_40G_10G_10G (6) /* 1x40G + 2x10G, dual QSFP (Greenport, Medford) */ #define TLV_PORT_MODE_10G_10G_40G (7) /* 2x10G + 1x40G, dual QSFP (Greenport, Medford) */ #define TLV_PORT_MODE_10G_10G_10G_10G_Q2 (8) /* 4x10G, single QSFP, cage 1 (Medford) */ -#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q2 +#define TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2 (9) /* 2x10G + 2x10G, dual QSFP (Medford) */ +#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q1_Q2 }; /* Type of the v-switch created implicitly by the firmware */ @@ -765,8 +767,8 @@ struct tlv_rx_event_merging_config { #define TLV_RX_EVENT_MERGING_CONFIG_MAX_EVENTS_MAX ((1 << 4) - 1) uint32_t timeout_ns; }; -#define TLV_RX_EVENT_MERGING_MAX_EVENTS_DEFAULT 7 -#define TLV_RX_EVENT_MERGING_TIMEOUT_NS_DEFAULT 8740 +#define TLV_RX_EVENT_MERGING_MAX_EVENTS_DEFAULT (0xffffffff) +#define TLV_RX_EVENT_MERGING_TIMEOUT_NS_DEFAULT (0xffffffff) #define TLV_TAG_PCIE_LINK_SETTINGS (0x101f0000) struct tlv_pcie_link_settings { @@ -791,9 +793,9 @@ struct tlv_tx_event_merging_config { uint32_t timeout_ns; uint32_t qempty_timeout_ns; /* Medford only */ }; -#define TLV_TX_EVENT_MERGING_MAX_EVENTS_DEFAULT 7 -#define TLV_TX_EVENT_MERGING_TIMEOUT_NS_DEFAULT 1400 -#define TLV_TX_EVENT_MERGING_QEMPTY_TIMEOUT_NS_DEFAULT 700 +#define TLV_TX_EVENT_MERGING_MAX_EVENTS_DEFAULT (0xffffffff) +#define TLV_TX_EVENT_MERGING_TIMEOUT_NS_DEFAULT (0xffffffff) +#define TLV_TX_EVENT_MERGING_QEMPTY_TIMEOUT_NS_DEFAULT (0xffffffff) /* Tx vFIFO Low latency configuration * @@ -809,6 +811,20 @@ struct tlv_tx_vfifo_ull_mode { #define TLV_TX_VFIFO_ULL_MODE_DEFAULT 0 }; +/* BIU mode + * + * Medford2 tag for selecting VI window decode (see values below) + */ +#define TLV_TAG_BIU_VI_WINDOW_MODE (0x10280000) +struct tlv_biu_vi_window_mode { + uint32_t tag; + uint32_t length; + uint8_t mode; +#define TLV_BIU_VI_WINDOW_MODE_8K 0 /* 8k per VI, CTPIO not mapped, medford/hunt compatible */ +#define TLV_BIU_VI_WINDOW_MODE_16K 1 /* 16k per VI, CTPIO mapped */ +#define TLV_BIU_VI_WINDOW_MODE_64K 2 /* 64k per VI, CTPIO mapped, POWER-friendly */ +}; + #define TLV_TAG_LICENSE (0x30800000) typedef struct tlv_license { diff --git a/sys/dev/smbus/smbconf.h b/sys/dev/smbus/smbconf.h index f39c44287c35..2c120c1a8a08 100644 --- a/sys/dev/smbus/smbconf.h +++ b/sys/dev/smbus/smbconf.h @@ -34,6 +34,10 @@ #define n(flags) (~(flags) & (flags)) +/* Order constants for smbus children. */ +#define SMBUS_ORDER_HINTED 20 +#define SMBUS_ORDER_PNP 40 + /* * How tsleep() is called in smb_request_bus(). */ diff --git a/sys/dev/smbus/smbus.c b/sys/dev/smbus/smbus.c index 389efac1c6d4..d485094e036f 100644 --- a/sys/dev/smbus/smbus.c +++ b/sys/dev/smbus/smbus.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -41,54 +42,16 @@ __FBSDID("$FreeBSD$"); #include "smbus_if.h" #include "bus_if.h" +struct smbus_ivar +{ + uint8_t addr; +}; /* * Autoconfiguration and support routines for System Management bus */ +static void smbus_probe_device(device_t dev, u_char addr); -/* - * Device methods - */ -static int smbus_probe(device_t); -static int smbus_attach(device_t); -static int smbus_detach(device_t); - -static int smbus_child_location_str(device_t parent, device_t child, - char *buf, size_t buflen); -static int smbus_print_child(device_t parent, device_t child); -static void smbus_probe_device(device_t dev, u_char* addr); -static int smbus_read_ivar(device_t parent, device_t child, int which, - uintptr_t *result); - -static device_method_t smbus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, smbus_probe), - DEVMETHOD(device_attach, smbus_attach), - DEVMETHOD(device_detach, smbus_detach), - - /* bus interface */ - DEVMETHOD(bus_add_child, bus_generic_add_child), - DEVMETHOD(bus_child_location_str, smbus_child_location_str), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_print_child, smbus_print_child), - DEVMETHOD(bus_read_ivar, smbus_read_ivar), - - DEVMETHOD_END -}; - -driver_t smbus_driver = { - "smbus", - smbus_methods, - sizeof(struct smbus_softc), -}; - -devclass_t smbus_devclass; - -/* - * At 'probe' time, we add all the devices which we know about to the - * bus. The generic attach routine will probe and attach them if they - * are alive. - */ static int smbus_probe(device_t dev) { @@ -107,9 +70,9 @@ smbus_attach(device_t dev) mtx_init(&sc->lock, device_get_nameunit(dev), "smbus", MTX_DEF); bus_generic_probe(dev); for (addr = SMBUS_ADDR_MIN; addr < SMBUS_ADDR_MAX; ++addr) { - sc->addrs[addr] = addr; - smbus_probe_device(dev, &sc->addrs[addr]); + smbus_probe_device(dev, addr); } + bus_enumerate_hinted_children(dev); bus_generic_attach(dev); return (0); @@ -124,6 +87,7 @@ smbus_detach(device_t dev) error = bus_generic_detach(dev); if (error) return (error); + device_delete_children(dev); mtx_destroy(&sc->lock); return (0); @@ -135,34 +99,78 @@ smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err) } static void -smbus_probe_device(device_t dev, u_char* addr) +smbus_probe_device(device_t dev, u_char addr) { device_t child; int error; u_char cmd; u_char buf[2]; + struct smbus_ivar *devi; cmd = 0x01; - error = smbus_trans(dev, *addr, cmd, + error = smbus_trans(dev, addr, cmd, SMB_TRANS_NOCNT | SMB_TRANS_NOREPORT, NULL, 0, buf, 1, NULL); if (error == 0) { if (bootverbose) - device_printf(dev, "Probed address 0x%02x\n", *addr); - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, addr); + device_printf(dev, "Probed address 0x%02x\n", addr); + child = BUS_ADD_CHILD(dev, SMBUS_ORDER_PNP, NULL, -1); + if (child == NULL) + return; + devi = device_get_ivars(child); + devi->addr = addr; } } +static device_t +smbus_add_child(device_t dev, u_int order, const char *name, int unit) +{ + struct smbus_ivar *devi; + device_t child; + + child = device_add_child_ordered(dev, order, name, unit); + if (child == NULL) + return (child); + devi = malloc(sizeof(struct smbus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); + if (devi == NULL) { + device_delete_child(dev, child); + return (NULL); + } + device_set_ivars(child, devi); + return (child); +} + +static void +smbus_hinted_child(device_t bus, const char *dname, int dunit) +{ + struct smbus_ivar *devi; + device_t child; + int addr; + + addr = 0; + resource_int_value(dname, dunit, "addr", &addr); + if (addr > UINT8_MAX) { + device_printf(bus, "ignored incorrect slave address hint 0x%x" + " for %s%d\n", addr, dname, dunit); + return; + } + child = BUS_ADD_CHILD(bus, SMBUS_ORDER_HINTED, dname, dunit); + if (child == NULL) + return; + devi = device_get_ivars(child); + devi->addr = addr; +} + + static int smbus_child_location_str(device_t parent, device_t child, char *buf, size_t buflen) { - unsigned char *addr; + struct smbus_ivar *devi; - addr = device_get_ivars(child); - if (addr) - snprintf(buf, buflen, "addr=0x%x", *addr); + devi = device_get_ivars(child); + if (devi->addr != 0) + snprintf(buf, buflen, "addr=0x%x", devi->addr); else if (buflen) buf[0] = 0; return (0); @@ -171,28 +179,30 @@ smbus_child_location_str(device_t parent, device_t child, char *buf, static int smbus_print_child(device_t parent, device_t child) { - unsigned char *addr; + struct smbus_ivar *devi; int retval; - addr = device_get_ivars(child); + devi = device_get_ivars(child); retval = bus_print_child_header(parent, child); - if (addr) - retval += printf(" at addr 0x%x", *addr); + if (devi->addr != 0) + retval += printf(" at addr 0x%x", devi->addr); retval += bus_print_child_footer(parent, child); return (retval); } static int -smbus_read_ivar(device_t parent, device_t child, int which, - uintptr_t *result) +smbus_read_ivar(device_t parent, device_t child, int which, uintptr_t *result) { - unsigned char *addr; + struct smbus_ivar *devi; - addr = device_get_ivars(child); + devi = device_get_ivars(child); switch (which) { case SMBUS_IVAR_ADDR: - *result = (addr == NULL) ? -1 : *addr; + if (devi->addr != 0) + *result = devi->addr; + else + *result = -1; break; default: return (ENOENT); @@ -200,4 +210,66 @@ smbus_read_ivar(device_t parent, device_t child, int which, return (0); } +static int +smbus_write_ivar(device_t parent, device_t child, int which, uintptr_t value) +{ + struct smbus_ivar *devi; + + devi = device_get_ivars(child); + switch (which) { + case SMBUS_IVAR_ADDR: + /* Allow to set but no change the slave address. */ + if (devi->addr != 0) + return (EINVAL); + devi->addr = value; + break; + default: + return (ENOENT); + } + return (0); +} + +static void +smbus_probe_nomatch(device_t bus, device_t child) +{ + struct smbus_ivar *devi = device_get_ivars(child); + + /* + * Ignore (self-identified) devices without a slave address set. + * For example, smb(4). + */ + if (devi->addr != 0) + device_printf(bus, " at addr %#x\n", + devi->addr); +} + +/* + * Device methods + */ +static device_method_t smbus_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, smbus_probe), + DEVMETHOD(device_attach, smbus_attach), + DEVMETHOD(device_detach, smbus_detach), + + /* bus interface */ + DEVMETHOD(bus_add_child, smbus_add_child), + DEVMETHOD(bus_hinted_child, smbus_hinted_child), + DEVMETHOD(bus_probe_nomatch, smbus_probe_nomatch), + DEVMETHOD(bus_child_location_str, smbus_child_location_str), + DEVMETHOD(bus_print_child, smbus_print_child), + DEVMETHOD(bus_read_ivar, smbus_read_ivar), + DEVMETHOD(bus_write_ivar, smbus_write_ivar), + + DEVMETHOD_END +}; + +driver_t smbus_driver = { + "smbus", + smbus_methods, + sizeof(struct smbus_softc), +}; + +devclass_t smbus_devclass; + MODULE_VERSION(smbus, SMBUS_MODVER); diff --git a/sys/dev/usb/controller/dwc_otg_fdt.c b/sys/dev/usb/controller/dwc_otg_fdt.c index 73df72e78238..20ab0c5acf06 100644 --- a/sys/dev/usb/controller/dwc_otg_fdt.c +++ b/sys/dev/usb/controller/dwc_otg_fdt.c @@ -121,7 +121,12 @@ dwc_otg_attach(device_t dev) sc->sc_otg.sc_io_hdl = rman_get_bushandle(sc->sc_otg.sc_io_res); sc->sc_otg.sc_io_size = rman_get_size(sc->sc_otg.sc_io_res); - rid = 0; + + /* + * brcm,bcm2708-usb FDT provides two interrupts, + * we need only second one (VC_USB) + */ + rid = ofw_bus_is_compatible(dev, "brcm,bcm2708-usb") ? 1 : 0; sc->sc_otg.sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); if (sc->sc_otg.sc_irq_res == NULL) diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c index e90e753b1391..915dd838b380 100644 --- a/sys/dev/usb/net/if_smsc.c +++ b/sys/dev/usb/net/if_smsc.c @@ -1556,6 +1556,9 @@ smsc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } #ifdef FDT +/* + * This is FreeBSD-specific compatibility strings for RPi/RPi2 + */ static phandle_t smsc_fdt_find_eth_node(phandle_t start) { @@ -1567,11 +1570,68 @@ smsc_fdt_find_eth_node(phandle_t start) fdt_is_compatible(node, "usb,device")) return (node); child = smsc_fdt_find_eth_node(node); - if (child != 0) + if (child != -1) return (child); } - return (0); + return (-1); +} + +/* + * Check if node's path is <*>/usb/hub/ethernet + */ +static int +smsc_fdt_is_usb_eth(phandle_t node) +{ + char name[16]; + int len; + + memset(name, 0, sizeof(name)); + len = OF_getprop(node, "name", name, sizeof(name)); + if (len <= 0) + return (0); + + if (strcmp(name, "ethernet")) + return (0); + + node = OF_parent(node); + if (node == -1) + return (0); + len = OF_getprop(node, "name", name, sizeof(name)); + if (len <= 0) + return (0); + + if (strcmp(name, "hub")) + return (0); + + node = OF_parent(node); + if (node == -1) + return (0); + len = OF_getprop(node, "name", name, sizeof(name)); + if (len <= 0) + return (0); + + if (strcmp(name, "usb")) + return (0); + + return (1); +} + +static phandle_t +smsc_fdt_find_eth_node_by_path(phandle_t start) +{ + phandle_t child, node; + + /* Traverse through entire tree to find usb ethernet nodes. */ + for (node = OF_child(start); node != 0; node = OF_peer(node)) { + if (smsc_fdt_is_usb_eth(node)) + return (node); + child = smsc_fdt_find_eth_node_by_path(node); + if (child != -1) + return (child); + } + + return (-1); } /** @@ -1587,8 +1647,14 @@ smsc_fdt_find_mac(unsigned char *mac) root = OF_finddevice("/"); node = smsc_fdt_find_eth_node(root); - if (node != 0) { + /* + * If it's not FreeBSD FDT blob for RPi, try more + * generic .../usb/hub/ethernet + */ + if (node == -1) + node = smsc_fdt_find_eth_node_by_path(root); + if (node != -1) { /* Check if there is property */ if ((len = OF_getproplen(node, "local-mac-address")) > 0) { if (len != ETHER_ADDR_LEN) diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index ef946c3b687d..bc41ca376d42 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -1536,10 +1536,12 @@ rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) /* This is a number from 0..100; so let's just divide it down a bit */ rxs.c_rssi = le32toh(bss->rssi) / 2; rxs.c_nf = -96; + if (ieee80211_add_rx_params(m, &rxs) == 0) + return; /* XXX avoid a LOR */ RSU_UNLOCK(sc); - ieee80211_input_mimo_all(ic, m, &rxs); + ieee80211_input_mimo_all(ic, m); RSU_LOCK(sc); } diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c index e94c6ffe5660..1ca6eac926bb 100644 --- a/sys/fs/nandfs/nandfs_vnops.c +++ b/sys/fs/nandfs/nandfs_vnops.c @@ -2211,7 +2211,7 @@ nandfs_whiteout(struct vop_whiteout_args *ap) /* Create a new directory whiteout */ #ifdef INVARIANTS if ((cnp->cn_flags & SAVENAME) == 0) - panic("ufs_whiteout: missing name"); + panic("nandfs_whiteout: missing name"); #endif error = nandfs_add_dirent(dvp, NANDFS_WHT_INO, cnp->cn_nameptr, cnp->cn_namelen, DT_WHT); diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index aefc50753f0d..056e06499645 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -31,6 +31,7 @@ options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c index b036bd3ec3c7..43fb99451f76 100644 --- a/sys/i386/i386/mem.c +++ b/sys/i386/i386/mem.c @@ -161,12 +161,11 @@ int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { - if (dev2unit(dev) == CDEV_MINOR_MEM) + if (dev2unit(dev) == CDEV_MINOR_MEM) { *paddr = offset; - else if (dev2unit(dev) == CDEV_MINOR_KMEM) - *paddr = vtophys(offset); - /* else panic! */ - return (0); + return (0); + } + return (-1); } /* diff --git a/sys/i386/include/efi.h b/sys/i386/include/efi.h new file mode 100644 index 000000000000..02508f4d5188 --- /dev/null +++ b/sys/i386/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __I386_INCLUDE_EFI_H_ +#define __I386_INCLUDE_EFI_H_ + +#define EFIABI_ATTR /* __attribute__((ms_abi)) */ /* clang fails with this */ + +/* Note: we don't actually support this on i386 yet */ + +#endif /* __I386_INCLUDE_EFI_H_ */ diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 4758cdc2072a..1bd3ad077fdd 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -1599,7 +1599,6 @@ linker_preload(void *arg) if (error) panic("cannot add dependency"); } - lf->userrefs++; /* so we can (try to) kldunload it */ error = linker_file_lookup_set(lf, MDT_SETNAME, &start, &stop, NULL); if (!error) { @@ -1637,6 +1636,8 @@ linker_preload(void *arg) goto fail; } linker_file_register_modules(lf); + if (!TAILQ_EMPTY(&lf->modules)) + lf->flags |= LINKER_FILE_MODULES; if (linker_file_lookup_set(lf, "sysinit_set", &si_start, &si_stop, NULL) == 0) sysinit_add(si_start, si_stop); @@ -1653,6 +1654,41 @@ linker_preload(void *arg) SYSINIT(preload, SI_SUB_KLD, SI_ORDER_MIDDLE, linker_preload, 0); +/* + * Handle preload files that failed to load any modules. + */ +static void +linker_preload_finish(void *arg) +{ + linker_file_t lf, nlf; + + sx_xlock(&kld_sx); + TAILQ_FOREACH_SAFE(lf, &linker_files, link, nlf) { + /* + * If all of the modules in this file failed to load, unload + * the file and return an error of ENOEXEC. (Parity with + * linker_load_file.) + */ + if ((lf->flags & LINKER_FILE_MODULES) != 0 && + TAILQ_EMPTY(&lf->modules)) { + linker_file_unload(lf, LINKER_UNLOAD_FORCE); + continue; + } + + lf->flags &= ~LINKER_FILE_MODULES; + lf->userrefs++; /* so we can (try to) kldunload it */ + } + sx_xunlock(&kld_sx); +} + +/* + * Attempt to run after all DECLARE_MODULE SYSINITs. Unfortunately they can be + * scheduled at any subsystem and order, so run this as late as possible. init + * becomes runnable in SI_SUB_KTHREAD_INIT, so go slightly before that. + */ +SYSINIT(preload_finish, SI_SUB_KTHREAD_INIT - 100, SI_ORDER_MIDDLE, + linker_preload_finish, 0); + /* * Search for a not-loaded module by name. * diff --git a/sys/kern/subr_gtaskqueue.c b/sys/kern/subr_gtaskqueue.c index 6b431f085375..9bde3f71735b 100644 --- a/sys/kern/subr_gtaskqueue.c +++ b/sys/kern/subr_gtaskqueue.c @@ -728,7 +728,7 @@ taskqgroup_bind(struct taskqgroup *qgroup) * one. */ for (i = 0; i < qgroup->tqg_cnt; i++) { - gtask = malloc(sizeof (*gtask), M_DEVBUF, M_NOWAIT); + gtask = malloc(sizeof (*gtask), M_DEVBUF, M_WAITOK); GTASK_INIT(>ask->bt_task, 0, 0, taskqgroup_binder, gtask); gtask->bt_cpuid = qgroup->tqg_queue[i].tgc_cpu; grouptaskqueue_enqueue(qgroup->tqg_queue[i].tgc_taskq, @@ -827,11 +827,11 @@ _taskqgroup_adjust(struct taskqgroup *qgroup, int cnt, int stride) for (i = cnt; i < old_cnt; i++) taskqgroup_cpu_remove(qgroup, i); + taskqgroup_bind(qgroup); + mtx_lock(&qgroup->tqg_lock); qgroup->tqg_adjusting = 0; - taskqgroup_bind(qgroup); - return (0); } diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c index 873bff908e71..98e7b47085d1 100644 --- a/sys/kern/subr_intr.c +++ b/sys/kern/subr_intr.c @@ -145,6 +145,7 @@ static u_int intrcnt_index; static struct intr_irqsrc *intr_map_get_isrc(u_int res_id); static void intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc); +static struct intr_map_data * intr_map_get_map_data(u_int res_id); static void intr_map_copy_map_data(u_int res_id, device_t *dev, intptr_t *xref, struct intr_map_data **data); @@ -1309,6 +1310,7 @@ intr_release_msi(device_t pci, device_t child, intptr_t xref, int count, { struct intr_irqsrc **isrc; struct intr_pic *pic; + struct intr_map_data_msi *msi; int i, err; pic = pic_lookup(NULL, xref); @@ -1321,8 +1323,14 @@ intr_release_msi(device_t pci, device_t child, intptr_t xref, int count, isrc = malloc(sizeof(*isrc) * count, M_INTRNG, M_WAITOK); - for (i = 0; i < count; i++) - isrc[i] = intr_map_get_isrc(irqs[i]); + for (i = 0; i < count; i++) { + msi = (struct intr_map_data_msi *) + intr_map_get_map_data(irqs[i]); + KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI, + ("%s: irq %d map data is not MSI", __func__, + irqs[i])); + isrc[i] = msi->isrc; + } err = MSI_RELEASE_MSI(pic->pic_dev, child, count, isrc); @@ -1369,6 +1377,7 @@ intr_release_msix(device_t pci, device_t child, intptr_t xref, int irq) { struct intr_irqsrc *isrc; struct intr_pic *pic; + struct intr_map_data_msi *msi; int err; pic = pic_lookup(NULL, xref); @@ -1379,7 +1388,12 @@ intr_release_msix(device_t pci, device_t child, intptr_t xref, int irq) ("%s: Found a non-MSI controller: %s", __func__, device_get_name(pic->pic_dev))); - isrc = intr_map_get_isrc(irq); + msi = (struct intr_map_data_msi *) + intr_map_get_map_data(irq); + KASSERT(msi->hdr.type == INTR_MAP_DATA_MSI, + ("%s: irq %d map data is not MSI", __func__, + irq)); + isrc = msi->isrc; if (isrc == NULL) { intr_unmap_irq(irq); return (EINVAL); @@ -1513,6 +1527,24 @@ intr_map_set_isrc(u_int res_id, struct intr_irqsrc *isrc) mtx_unlock(&irq_map_lock); } +/* + * Get a copy of intr_map_entry data + */ +static struct intr_map_data * +intr_map_get_map_data(u_int res_id) +{ + struct intr_map_data *data; + + data = NULL; + mtx_lock(&irq_map_lock); + if (res_id >= irq_map_count || irq_map[res_id] == NULL) + panic("Attempt to copy invalid resource id: %u\n", res_id); + data = irq_map[res_id]->map_data; + mtx_unlock(&irq_map_lock); + + return (data); +} + /* * Get a copy of intr_map_entry data */ diff --git a/sys/kern/uipc_accf.c b/sys/kern/uipc_accf.c index 78ddd8641145..aa9ed741d905 100644 --- a/sys/kern/uipc_accf.c +++ b/sys/kern/uipc_accf.c @@ -250,7 +250,7 @@ do_setopt_accept_filter(struct socket *so, struct sockopt *sopt) newaf = malloc(sizeof(*newaf), M_ACCF, M_WAITOK | M_ZERO); if (afp->accf_create != NULL && afap->af_name[0] != '\0') { - int len = strlen(afap->af_name) + 1; + size_t len = strlen(afap->af_name) + 1; newaf->so_accept_filter_str = malloc(len, M_ACCF, M_WAITOK); strcpy(newaf->so_accept_filter_str, afap->af_name); diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index d27dd0d36ce4..c70366fbb54d 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2633,7 +2633,7 @@ vfs_vmio_invalidate(struct buf *bp) while (vm_page_xbusied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(obj); - vm_page_busy_sleep(m, "mbncsh"); + vm_page_busy_sleep(m, "mbncsh", true); VM_OBJECT_WLOCK(obj); } if (pmap_page_wired_mappings(m) == 0) @@ -4182,7 +4182,7 @@ vfs_drain_busy_pages(struct buf *bp) while (vm_page_xbusied(m)) { vm_page_lock(m); VM_OBJECT_WUNLOCK(bp->b_bufobj->bo_object); - vm_page_busy_sleep(m, "vbpage"); + vm_page_busy_sleep(m, "vbpage", true); VM_OBJECT_WLOCK(bp->b_bufobj->bo_object); } } diff --git a/sys/mips/conf/ADM5120 b/sys/mips/conf/ADM5120 index a131eceee6e6..a32adf69e8fb 100644 --- a/sys/mips/conf/ADM5120 +++ b/sys/mips/conf/ADM5120 @@ -33,6 +33,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/ALCHEMY b/sys/mips/conf/ALCHEMY index a4508ad339cb..2d1acd901160 100644 --- a/sys/mips/conf/ALCHEMY +++ b/sys/mips/conf/ALCHEMY @@ -33,6 +33,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/AR71XX_BASE b/sys/mips/conf/AR71XX_BASE index a296eab860b8..99e59a2c2b6f 100644 --- a/sys/mips/conf/AR71XX_BASE +++ b/sys/mips/conf/AR71XX_BASE @@ -35,6 +35,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking options INET6 # IPv6 +options TCP_HHOOK # hhook(9) framework for TCP # options NFSCL #Network Filesystem Client diff --git a/sys/mips/conf/AR724X_BASE b/sys/mips/conf/AR724X_BASE index 662e8013377f..8f4e24699a9b 100644 --- a/sys/mips/conf/AR724X_BASE +++ b/sys/mips/conf/AR724X_BASE @@ -36,6 +36,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking #options INET6 # IPv6 +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/BCM b/sys/mips/conf/BCM index 994c6c2c3cfa..04203944c712 100644 --- a/sys/mips/conf/BCM +++ b/sys/mips/conf/BCM @@ -28,6 +28,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client #options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/BERI_TEMPLATE b/sys/mips/conf/BERI_TEMPLATE index fcba5cc96c5b..7901f7722493 100644 --- a/sys/mips/conf/BERI_TEMPLATE +++ b/sys/mips/conf/BERI_TEMPLATE @@ -39,6 +39,7 @@ options FFS #Berkeley Fast Filesystem options INET options INET6 +options TCP_HHOOK # hhook(9) framework for TCP options KGSSAPI options NFSCL options NFSLOCKD diff --git a/sys/mips/conf/ERL b/sys/mips/conf/ERL index 2afd12116ca6..189ba568c38c 100644 --- a/sys/mips/conf/ERL +++ b/sys/mips/conf/ERL @@ -55,6 +55,7 @@ options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support @@ -73,6 +74,7 @@ options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization options COMPAT_FREEBSD32 # Compatible with o32 binaries +options COMPAT_FREEBSD10 # Compatible with FreeBSD10 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options STACK # stack(9) support diff --git a/sys/mips/conf/GXEMUL b/sys/mips/conf/GXEMUL index fa0b9b51899e..dcfa3d3af276 100644 --- a/sys/mips/conf/GXEMUL +++ b/sys/mips/conf/GXEMUL @@ -32,6 +32,7 @@ options SMP # Symmetric MultiProcessor Kernel options SCHED_ULE options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS #Berkeley Fast Filesystem diff --git a/sys/mips/conf/GXEMUL32 b/sys/mips/conf/GXEMUL32 index 27854c5fa2a8..da3e71a67eed 100644 --- a/sys/mips/conf/GXEMUL32 +++ b/sys/mips/conf/GXEMUL32 @@ -30,6 +30,7 @@ options SMP # Symmetric MultiProcessor Kernel options SCHED_ULE options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS #Berkeley Fast Filesystem diff --git a/sys/mips/conf/IDT b/sys/mips/conf/IDT index a6c14bbba13d..a258cdba0cd6 100644 --- a/sys/mips/conf/IDT +++ b/sys/mips/conf/IDT @@ -16,6 +16,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/MT7620 b/sys/mips/conf/MT7620 index d915517961e7..ea61949a0c92 100644 --- a/sys/mips/conf/MT7620 +++ b/sys/mips/conf/MT7620 @@ -54,6 +54,7 @@ options SCHED_ULE #options SCHED_4BSD #4BSD scheduler #options COMPAT_43 options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index 7c24f1a02aca..d3ca58ca7faf 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -54,6 +54,7 @@ options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/mips/conf/PB92 b/sys/mips/conf/PB92 index 6176668fb129..ea994ada1cda 100644 --- a/sys/mips/conf/PB92 +++ b/sys/mips/conf/PB92 @@ -37,6 +37,7 @@ options SCHED_4BSD #4BSD scheduler options INET #InterNETworking # Can't do IPv6 - it just doesn't fit. # options INET6 +options TCP_HHOOK # hhook(9) framework for TCP # options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/QCA953X_BASE b/sys/mips/conf/QCA953X_BASE index 08de505430b2..1a7da3b0a628 100644 --- a/sys/mips/conf/QCA953X_BASE +++ b/sys/mips/conf/QCA953X_BASE @@ -31,6 +31,7 @@ options ALT_BREAK_TO_DEBUGGER options SCHED_4BSD #4BSD scheduler options INET #InterNETworking #options INET6 #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/QEMU b/sys/mips/conf/QEMU index 68fe12c21b30..b8f33fe92f42 100644 --- a/sys/mips/conf/QEMU +++ b/sys/mips/conf/QEMU @@ -32,6 +32,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/RT305X b/sys/mips/conf/RT305X index ca38c72c4275..fc629b62e9d1 100644 --- a/sys/mips/conf/RT305X +++ b/sys/mips/conf/RT305X @@ -53,6 +53,7 @@ options SCHED_ULE #options SCHED_4BSD #4BSD scheduler #options COMPAT_43 options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/RT5350 b/sys/mips/conf/RT5350 index f897178b607c..b2f02c6170b1 100644 --- a/sys/mips/conf/RT5350 +++ b/sys/mips/conf/RT5350 @@ -51,6 +51,7 @@ options KDB options SCHED_ULE options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client #options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/SENTRY5 b/sys/mips/conf/SENTRY5 index ecdb5ffb12b9..60cc7e3ab53c 100644 --- a/sys/mips/conf/SENTRY5 +++ b/sys/mips/conf/SENTRY5 @@ -44,6 +44,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/XLR b/sys/mips/conf/XLR index 0133fada2343..f5ecd086a24a 100644 --- a/sys/mips/conf/XLR +++ b/sys/mips/conf/XLR @@ -62,6 +62,7 @@ options PREEMPTION # Enable kernel thread preemption #options FULL_PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/mips/conf/XLR64 b/sys/mips/conf/XLR64 index c8b1dfbb433c..70c67078c54d 100644 --- a/sys/mips/conf/XLR64 +++ b/sys/mips/conf/XLR64 @@ -36,6 +36,7 @@ options SMP #options FULL_PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/mips/conf/XLRN32 b/sys/mips/conf/XLRN32 index e2f44687d411..f8a4bf299735 100644 --- a/sys/mips/conf/XLRN32 +++ b/sys/mips/conf/XLRN32 @@ -36,6 +36,7 @@ options PREEMPTION # Enable kernel thread preemption #options FULL_PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/mips/conf/std.AR5312 b/sys/mips/conf/std.AR5312 index ff418e5b71a2..a3b055bfb743 100644 --- a/sys/mips/conf/std.AR5312 +++ b/sys/mips/conf/std.AR5312 @@ -34,6 +34,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking options INET6 # IPv6 +options TCP_HHOOK # hhook(9) framework for TCP # options NFSCL #Network Filesystem Client diff --git a/sys/mips/conf/std.AR5315 b/sys/mips/conf/std.AR5315 index cc8013f1cea2..c9f85f6c0813 100644 --- a/sys/mips/conf/std.AR5315 +++ b/sys/mips/conf/std.AR5315 @@ -33,6 +33,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking options INET6 # IPv6 +options TCP_HHOOK # hhook(9) framework for TCP # options NFSCL #Network Filesystem Client diff --git a/sys/mips/conf/std.AR91XX b/sys/mips/conf/std.AR91XX index 0fe40c5b9032..cfff918120d6 100644 --- a/sys/mips/conf/std.AR91XX +++ b/sys/mips/conf/std.AR91XX @@ -32,6 +32,7 @@ options VM_KMEM_SIZE_SCALE=1 options SCHED_4BSD #4BSD scheduler options INET #InterNETworking options INET6 #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/std.AR933X b/sys/mips/conf/std.AR933X index 6a539610a70e..f9a4d875b571 100644 --- a/sys/mips/conf/std.AR933X +++ b/sys/mips/conf/std.AR933X @@ -30,6 +30,7 @@ options ALT_BREAK_TO_DEBUGGER options SCHED_4BSD #4BSD scheduler options INET #InterNETworking #options INET6 #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/std.AR934X b/sys/mips/conf/std.AR934X index 940da461d434..19399450a493 100644 --- a/sys/mips/conf/std.AR934X +++ b/sys/mips/conf/std.AR934X @@ -31,6 +31,7 @@ options ALQ options SCHED_4BSD #4BSD scheduler options INET #InterNETworking #options INET6 #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/std.MALTA b/sys/mips/conf/std.MALTA index 7019ccf22948..c0e5cdbd07b4 100644 --- a/sys/mips/conf/std.MALTA +++ b/sys/mips/conf/std.MALTA @@ -21,6 +21,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/std.QCA955X b/sys/mips/conf/std.QCA955X index 25a8411a9036..822a03a0b754 100644 --- a/sys/mips/conf/std.QCA955X +++ b/sys/mips/conf/std.QCA955X @@ -35,6 +35,7 @@ options ALQ options SCHED_4BSD #4BSD scheduler options INET #InterNETworking #options INET6 #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP #options NFSCL #Network Filesystem Client options PSEUDOFS #Pseudo-filesystem framework options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions diff --git a/sys/mips/conf/std.SWARM b/sys/mips/conf/std.SWARM index 3e95206765c1..b59e9e962e04 100644 --- a/sys/mips/conf/std.SWARM +++ b/sys/mips/conf/std.SWARM @@ -20,6 +20,7 @@ options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking +options TCP_HHOOK # hhook(9) framework for TCP options NFSCL #Network Filesystem Client options NFS_ROOT #NFS usable as /, requires NFSCL options PSEUDOFS #Pseudo-filesystem framework diff --git a/sys/mips/conf/std.XLP b/sys/mips/conf/std.XLP index 3d249bcd769e..ac19aafab73e 100644 --- a/sys/mips/conf/std.XLP +++ b/sys/mips/conf/std.XLP @@ -15,6 +15,7 @@ options PREEMPTION # Enable kernel thread preemption #options FULL_PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem #options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists diff --git a/sys/mips/include/efi.h b/sys/mips/include/efi.h new file mode 100644 index 000000000000..8c52da2a6e6c --- /dev/null +++ b/sys/mips/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __MIPS_INCLUDE_EFI_H_ +#define __MIPS_INCLUDE_EFI_H_ + +#define EFIABI_ATTR + +/* Note: we don't actually support this on mips */ + +#endif /* __MIPS_INCLUDE_EFI_H_ */ diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index c0a25a28f1b4..a5bac7f1872a 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -433,7 +433,11 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, } else if (type == SYS_RES_IRQ) { #ifdef INTRNG #ifdef FDT - intr_activate_irq(child, r); + err = intr_activate_irq(child, r); + if (err != 0) { + rman_deactivate_resource(r); + return (err); + } #else /* * INTRNG without FDT needs to have the interrupt properly diff --git a/sys/modules/bwn/Makefile b/sys/modules/bwn/Makefile index 16e0f4fadb53..99041da1f39d 100644 --- a/sys/modules/bwn/Makefile +++ b/sys/modules/bwn/Makefile @@ -14,17 +14,15 @@ SRCS+= if_bwn_phy_n.c # Other SRCS+= device_if.h bus_if.h pci_if.h opt_bwn.h opt_wlan.h -# Uncomment this for the GPL PHY code; this requires the -# module be built with BWN_GPL_PHY set in the kernel -# configuration. - -#.PATH: ${.CURDIR}/../../gnu/dev/bwn/phy_n -#SRCS+= if_bwn_radio_2055.c -#SRCS+= if_bwn_radio_2056.c -#SRCS+= if_bwn_radio_2057.c -#SRCS+= if_bwn_phy_n_tables.c -#SRCS+= if_bwn_phy_n_ppr.c -#SRCS+= if_bwn_phy_n_core.c +# The following need the BWN_GPL_PHY kenrel option to opt-in +# to the GPL'd 802.11n PHY support for this driver. +.PATH: ${.CURDIR}/../../gnu/dev/bwn/phy_n +SRCS.BWN_GPL_PHY+= if_bwn_radio_2055.c +SRCS.BWN_GPL_PHY+= if_bwn_radio_2056.c +SRCS.BWN_GPL_PHY+= if_bwn_radio_2057.c +SRCS.BWN_GPL_PHY+= if_bwn_phy_n_tables.c +SRCS.BWN_GPL_PHY+= if_bwn_phy_n_ppr.c +SRCS.BWN_GPL_PHY+= if_bwn_phy_n_core.c .include diff --git a/sys/modules/cc/Makefile b/sys/modules/cc/Makefile index 7f4e94e659e1..ec89d89e8c80 100644 --- a/sys/modules/cc/Makefile +++ b/sys/modules/cc/Makefile @@ -1,11 +1,20 @@ # $FreeBSD$ -SUBDIR= cc_cdg \ - cc_chd \ - cc_cubic \ +SUBDIR= cc_cubic \ cc_dctcp \ + cc_htcp + + +# Do we have the TCP_HHOOK symbol defined? If not, there is no point in +# building these modules by default. +# We will default to building these modules unless $OPT_INET is defined +# and does not contain the TCP_HHOOK option. +.if defined(ALL_MODULES) || ${OPT_INET:UTCP_HHOOK:MTCP_HHOOK} != "" +SUBDIR+= \ + cc_cdg \ + cc_chd \ cc_hd \ - cc_htcp \ cc_vegas +.endif .include diff --git a/sys/modules/dtb/allwinner/Makefile b/sys/modules/dtb/allwinner/Makefile index ae8ba90c16e2..cdf34c8620af 100644 --- a/sys/modules/dtb/allwinner/Makefile +++ b/sys/modules/dtb/allwinner/Makefile @@ -9,6 +9,7 @@ DTS= \ olinuxino-lime.dts \ pcduino3.dts \ sinovoip-bpi-m3.dts \ - sun5i-a13-olinuxino.dts + sun5i-a13-olinuxino.dts \ + sun5i-r8-chip.dts .include diff --git a/sys/modules/efirt/Makefile b/sys/modules/efirt/Makefile index 2dff20d73804..993ecdb9e888 100644 --- a/sys/modules/efirt/Makefile +++ b/sys/modules/efirt/Makefile @@ -1,9 +1,10 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../../${MACHINE}/${MACHINE} +.PATH: ${.CURDIR}/../../dev/efidev KMOD= efirt -SRCS= efirt.c +SRCS= efirt.c efidev.c SRCS+= device_if.h bus_if.h .include diff --git a/sys/modules/khelp/Makefile b/sys/modules/khelp/Makefile index 1901331a3c2f..256d8838c573 100644 --- a/sys/modules/khelp/Makefile +++ b/sys/modules/khelp/Makefile @@ -1,5 +1,13 @@ # $FreeBSD$ -SUBDIR= h_ertt +SUBDIR= + +# Do we have the TCP_HHOOK symbol defined? If not, there is no point in +# building this modules by default. +# We will default to building this module unless $OPT_INET is defined +# and does not contain the TCP_HHOOK option. +.if defined(ALL_MODULES) || ${OPT_INET:UTCP_HHOOK:MTCP_HHOOK} != "" +SUBDIR+= h_ertt +.endif .include diff --git a/sys/net/if.c b/sys/net/if.c index f0b11b332767..fa55662b4233 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2206,7 +2206,7 @@ do_link_state_change(void *arg, int pending) if (log_link_state_change) log(LOG_NOTICE, "%s: link state changed to %s\n", ifp->if_xname, (link_state == LINK_STATE_UP) ? "UP" : "DOWN" ); - EVENTHANDLER_INVOKE(ifnet_link_event, ifp, ifp->if_link_state); + EVENTHANDLER_INVOKE(ifnet_link_event, ifp, link_state); CURVNET_RESTORE(); } diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index 7183cff3287c..a9b8c6d33d8c 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -66,8 +66,13 @@ static VNET_DEFINE(SLIST_HEAD(, lltable), lltables) = SLIST_HEAD_INITIALIZER(lltables); #define V_lltables VNET(lltables) -struct rwlock lltable_rwlock; -RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock"); +static struct rwlock lltable_list_lock; +RW_SYSINIT(lltable_list_lock, &lltable_list_lock, "lltable_list_lock"); +#define LLTABLE_LIST_RLOCK() rw_rlock(&lltable_list_lock) +#define LLTABLE_LIST_RUNLOCK() rw_runlock(&lltable_list_lock) +#define LLTABLE_LIST_WLOCK() rw_wlock(&lltable_list_lock) +#define LLTABLE_LIST_WUNLOCK() rw_wunlock(&lltable_list_lock) +#define LLTABLE_LIST_LOCK_ASSERT() rw_assert(&lltable_list_lock, RA_LOCKED) static void lltable_unlink(struct lltable *llt); static void llentries_unlink(struct lltable *llt, struct llentries *head); @@ -85,7 +90,7 @@ lltable_dump_af(struct lltable *llt, struct sysctl_req *wr) { int error; - LLTABLE_LOCK_ASSERT(); + LLTABLE_LIST_LOCK_ASSERT(); if (llt->llt_ifp->if_flags & IFF_LOOPBACK) return (0); @@ -108,7 +113,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr) struct lltable *llt; int error = 0; - LLTABLE_RLOCK(); + LLTABLE_LIST_RLOCK(); SLIST_FOREACH(llt, &V_lltables, llt_link) { if (llt->llt_af == af) { error = lltable_dump_af(llt, wr); @@ -117,7 +122,7 @@ lltable_sysctl_dumparp(int af, struct sysctl_req *wr) } } done: - LLTABLE_RUNLOCK(); + LLTABLE_LIST_RUNLOCK(); return (error); } @@ -531,7 +536,7 @@ lltable_drain(int af) struct llentry *lle; register int i; - LLTABLE_RLOCK(); + LLTABLE_LIST_RLOCK(); SLIST_FOREACH(llt, &V_lltables, llt_link) { if (llt->llt_af != af) continue; @@ -547,7 +552,7 @@ lltable_drain(int af) } } } - LLTABLE_RUNLOCK(); + LLTABLE_LIST_RUNLOCK(); } #endif @@ -591,14 +596,14 @@ lltable_prefix_free(int af, struct sockaddr *addr, struct sockaddr *mask, { struct lltable *llt; - LLTABLE_RLOCK(); + LLTABLE_LIST_RLOCK(); SLIST_FOREACH(llt, &V_lltables, llt_link) { if (llt->llt_af != af) continue; llt->llt_prefix_free(llt, addr, mask, flags); } - LLTABLE_RUNLOCK(); + LLTABLE_LIST_RUNLOCK(); } struct lltable * @@ -632,18 +637,18 @@ void lltable_link(struct lltable *llt) { - LLTABLE_WLOCK(); + LLTABLE_LIST_WLOCK(); SLIST_INSERT_HEAD(&V_lltables, llt, llt_link); - LLTABLE_WUNLOCK(); + LLTABLE_LIST_WUNLOCK(); } static void lltable_unlink(struct lltable *llt) { - LLTABLE_WLOCK(); + LLTABLE_LIST_WLOCK(); SLIST_REMOVE(&V_lltables, llt, lltable, llt_link); - LLTABLE_WUNLOCK(); + LLTABLE_LIST_WUNLOCK(); } @@ -739,13 +744,13 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info) } /* XXX linked list may be too expensive */ - LLTABLE_RLOCK(); + LLTABLE_LIST_RLOCK(); SLIST_FOREACH(llt, &V_lltables, llt_link) { if (llt->llt_af == dst->sa_family && llt->llt_ifp == ifp) break; } - LLTABLE_RUNLOCK(); + LLTABLE_LIST_RUNLOCK(); KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n")); error = 0; diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 51de726a621e..5e89fea09bfd 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -37,17 +37,9 @@ struct ifnet; struct sysctl_req; struct rt_msghdr; struct rt_addrinfo; - struct llentry; LIST_HEAD(llentries, llentry); -extern struct rwlock lltable_rwlock; -#define LLTABLE_RLOCK() rw_rlock(&lltable_rwlock) -#define LLTABLE_RUNLOCK() rw_runlock(&lltable_rwlock) -#define LLTABLE_WLOCK() rw_wlock(&lltable_rwlock) -#define LLTABLE_WUNLOCK() rw_wunlock(&lltable_rwlock) -#define LLTABLE_LOCK_ASSERT() rw_assert(&lltable_rwlock, RA_LOCKED) - #define LLE_MAX_LINKHDR 24 /* Full IB header */ /* * Code referencing llentry must at least hold diff --git a/sys/net/rndis.h b/sys/net/rndis.h index 2d7a5bfd370b..9da76bc08d24 100644 --- a/sys/net/rndis.h +++ b/sys/net/rndis.h @@ -87,6 +87,7 @@ #define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 #define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C +#define OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020D #define RNDIS_MEDIUM_802_3 0x00000000 diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index f5fdd5a63d49..28f1ffed81f7 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -157,8 +157,17 @@ struct ieee80211_qosframe_addr4 { #define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 #define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 #define IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define IEEE80211_FC0_SUBTYPE_QOS_CFACK 0x90 +#define IEEE80211_FC0_SUBTYPE_QOS_CFPOLL 0xa0 +#define IEEE80211_FC0_SUBTYPE_QOS_CFACKPOLL 0xb0 #define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 +#define IEEE80211_FC0_QOSDATA \ + (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0) + +#define IEEE80211_IS_QOSDATA(wh) \ + ((wh)->i_fc[0] == IEEE80211_FC0_QOSDATA) + #define IEEE80211_FC1_DIR_MASK 0x03 #define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ #define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ @@ -199,6 +208,8 @@ struct ieee80211_qosframe_addr4 { #define IEEE80211_NWID_LEN 32 #define IEEE80211_MESHID_LEN 32 +#define IEEE80211_QOS_CTL_LEN 2 + #define IEEE80211_QOS_TXOP 0x00ff /* bit 8 is reserved */ #define IEEE80211_QOS_AMSDU 0x80 diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 0943f9b09dc0..cdba429b96ed 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -779,8 +779,6 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni, int ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m) { -#define IEEE80211_FC0_QOSDATA \ - (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0) #define PROCESS 0 /* caller should process frame */ #define CONSUMED 1 /* frame consumed, caller does nothing */ struct ieee80211vap *vap = ni->ni_vap; @@ -966,7 +964,6 @@ ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m) } #undef CONSUMED #undef PROCESS -#undef IEEE80211_FC0_QOSDATA } /* diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 49c8ef1ae776..3f50268bedce 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -83,18 +83,14 @@ ieee80211_process_mimo(struct ieee80211_node *ni, struct ieee80211_rx_stats *rx) } int -ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m, - struct ieee80211_rx_stats *rx) +ieee80211_input_mimo(struct ieee80211_node *ni, struct mbuf *m) { struct ieee80211_rx_stats rxs; - if (rx) { - memcpy(&rxs, rx, sizeof(*rx)); - } else { - /* try to read from mbuf */ - bzero(&rxs, sizeof(rxs)); - ieee80211_get_rx_params(m, &rxs); - } + /* try to read stats from mbuf */ + bzero(&rxs, sizeof(rxs)); + if (ieee80211_get_rx_params(m, &rxs) != 0) + return (-1); /* XXX should assert IEEE80211_R_NF and IEEE80211_R_RSSI are set */ ieee80211_process_mimo(ni, &rxs); @@ -111,27 +107,21 @@ ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf) rx.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; rx.c_nf = nf; rx.c_rssi = rssi; - return ieee80211_input_mimo_all(ic, m, &rx); + + if (!ieee80211_add_rx_params(m, &rx)) + return (-1); + + return ieee80211_input_mimo_all(ic, m); } int -ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, - struct ieee80211_rx_stats *rx) +ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m) { - struct ieee80211_rx_stats rxs; struct ieee80211vap *vap; int type = -1; m->m_flags |= M_BCAST; /* NB: mark for bpf tap'ing */ - if (rx) { - memcpy(&rxs, rx, sizeof(*rx)); - } else { - /* try to read from mbuf */ - bzero(&rxs, sizeof(rxs)); - ieee80211_get_rx_params(m, &rxs); - } - /* XXX locking */ TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { struct ieee80211_node *ni; @@ -152,6 +142,7 @@ ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, /* * Packet contents are changed by ieee80211_decap * so do a deep copy of the packet. + * NB: tags are copied too. */ mcopy = m_dup(m, M_NOWAIT); if (mcopy == NULL) { @@ -163,7 +154,7 @@ ieee80211_input_mimo_all(struct ieee80211com *ic, struct mbuf *m, m = NULL; } ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input_mimo(ni, mcopy, &rxs); + type = ieee80211_input_mimo(ni, mcopy); ieee80211_free_node(ni); } if (m != NULL) /* no vaps, reclaim mbuf */ diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index f2b231c03c22..0b3a8f748b34 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -83,10 +83,8 @@ void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf)) int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int); -int ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *, - struct ieee80211_rx_stats *); -int ieee80211_input_mimo_all(struct ieee80211com *, struct mbuf *, - struct ieee80211_rx_stats *); +int ieee80211_input_mimo(struct ieee80211_node *, struct mbuf *); +int ieee80211_input_mimo_all(struct ieee80211com *, struct mbuf *); struct ieee80211_bpf_params; int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int, diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 7d5da0e8e0eb..da64dd31a07c 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1299,10 +1299,7 @@ in_pcbfree(struct inpcb *inp) if (inp->inp_moptions != NULL) inp_freemoptions(inp->inp_moptions); #endif - if (inp->inp_route.ro_rt) { - RTFREE(inp->inp_route.ro_rt); - inp->inp_route.ro_rt = (struct rtentry *)NULL; - } + RO_RTFREE(&inp->inp_route); if (inp->inp_route.ro_lle) LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */ @@ -2242,10 +2239,7 @@ void in_losing(struct inpcb *inp) { - if (inp->inp_route.ro_rt) { - RTFREE(inp->inp_route.ro_rt); - inp->inp_route.ro_rt = (struct rtentry *)NULL; - } + RO_RTFREE(&inp->inp_route); if (inp->inp_route.ro_lle) LLE_FREE(inp->inp_route.ro_lle); /* zeros ro_lle */ return; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index b0973b4d780e..04fa7256b002 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -704,11 +704,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, IPSTAT_INC(ips_fragmented); done: - /* - * Release the route if using our private route, or if - * (with flowtable) we don't have our own reference. - */ - if (ro == &iproute || ro->ro_flags & RT_NORTREF) + if (ro == &iproute) RO_RTFREE(ro); else if (rte == NULL) /* diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 90e564f07dcb..bce3e742ea96 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -77,7 +77,6 @@ SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b) } return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr)); } - #endif void @@ -837,14 +836,11 @@ static int sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to) { int loopback_scope; - #if defined(INET) int ipv4_local_scope, ipv4_addr_legal; - #endif #if defined(INET6) int local_scope, site_scope, ipv6_addr_legal; - #endif struct sctp_vrf *vrf; struct sctp_ifn *sctp_ifn; @@ -1216,10 +1212,8 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, if (netp != NULL) { *netp = net; } - /* - * Update the endpoint - * pointer - */ + /* Update the endpoint + * pointer */ *inp_p = inp; SCTP_INP_RUNLOCK(inp); return (stcb); @@ -1240,10 +1234,8 @@ sctp_tcb_special_locate(struct sctp_inpcb **inp_p, struct sockaddr *from, if (netp != NULL) { *netp = net; } - /* - * Update the endpoint - * pointer - */ + /* Update the endpoint + * pointer */ *inp_p = inp; SCTP_INP_RUNLOCK(inp); return (stcb); @@ -1622,15 +1614,12 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, { struct sctp_inpcb *inp; struct sctp_laddr *laddr; - #ifdef INET struct sockaddr_in *sin; - #endif #ifdef INET6 struct sockaddr_in6 *sin6; struct sockaddr_in6 *intf_addr6; - #endif int fnd; @@ -1673,10 +1662,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, case AF_INET: if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) && SCTP_IPV6_V6ONLY(inp)) { - /* - * IPv4 on a IPv6 socket with ONLY - * IPv6 set - */ + /* IPv4 on a IPv6 socket with ONLY + * IPv6 set */ SCTP_INP_RUNLOCK(inp); continue; } @@ -1689,10 +1676,8 @@ sctp_endpoint_probe(struct sockaddr *nam, struct sctppcbhead *head, #endif #ifdef INET6 case AF_INET6: - /* - * A V6 address and the endpoint is NOT - * bound V6 - */ + /* A V6 address and the endpoint is NOT + * bound V6 */ if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) { SCTP_INP_RUNLOCK(inp); continue; @@ -1926,14 +1911,11 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock, struct sctppcbhead *head; int lport; unsigned int i; - #ifdef INET struct sockaddr_in *sin; - #endif #ifdef INET6 struct sockaddr_in6 *sin6; - #endif switch (nam->sa_family) { @@ -2057,21 +2039,16 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset, struct sockaddr *dst) { struct sctp_paramhdr *phdr, parm_buf; - #if defined(INET) || defined(INET6) struct sctp_tcb *stcb; uint16_t ptype; - #endif uint16_t plen; - #ifdef INET struct sockaddr_in sin4; - #endif #ifdef INET6 struct sockaddr_in6 sin6; - #endif #ifdef INET @@ -2198,10 +2175,8 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag continue; } if (remote_tag) { - /* - * If we have both vtags that's all we match - * on - */ + /* If we have both vtags that's all we match + * on */ if (stcb->asoc.peer_vtag == remote_tag) { /* * If both tags match we consider it @@ -2319,14 +2294,11 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset, struct sctp_paramhdr parm_buf, *phdr; int ptype; int zero_address = 0; - #ifdef INET struct sockaddr_in *sin; - #endif #ifdef INET6 struct sockaddr_in6 *sin6; - #endif memset(&remote_store, 0, sizeof(remote_store)); @@ -2897,10 +2869,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, #ifdef INET6 case AF_INET6: { - /* - * Only for pure IPv6 Address. (No IPv4 - * Mapped!) - */ + /* Only for pure IPv6 Address. (No IPv4 + * Mapped!) */ struct sockaddr_in6 *sin6; sin6 = (struct sockaddr_in6 *)addr; @@ -2977,10 +2947,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, /* unlock info */ if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) { - /* - * Ok, must be one-2-one and - * allowing port re-use - */ + /* Ok, must be one-2-one and + * allowing port re-use */ port_reuse_active = 1; goto continue_anyway; } @@ -3003,10 +2971,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, /* unlock info */ if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_PORTREUSE)) && (sctp_is_feature_on(inp_tmp, SCTP_PCB_FLAGS_PORTREUSE))) { - /* - * Ok, must be one-2-one and - * allowing port re-use - */ + /* Ok, must be one-2-one and + * allowing port re-use */ port_reuse_active = 1; goto continue_anyway; } @@ -3146,11 +3112,11 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, * bind specific, make sure flags is off and add a new * address structure to the sctp_addr_list inside the ep * structure. - * - * We will need to allocate one and insert it at the head. The - * socketopt call can just insert new addresses in there as - * well. It will also have to do the embed scope kame hack - * too (before adding). + * + * We will need to allocate one and insert it at the head. + * The socketopt call can just insert new addresses in there + * as well. It will also have to do the embed scope kame + * hack too (before adding). */ struct sctp_ifa *ifa; union sctp_sockstore store; @@ -3268,11 +3234,11 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp) * from happening. But of course the iterator has a * reference on the stcb and inp. We can mark it and it will * stop. - * - * If its a single iterator situation, we set the end iterator - * flag. Otherwise we set the iterator to go to the next - * inp. - * + * + * If its a single iterator situation, we set the end + * iterator flag. Otherwise we set the iterator to go to the + * next inp. + * */ if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) { sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT; @@ -3305,10 +3271,8 @@ sctp_iterator_inp_being_freed(struct sctp_inpcb *inp) SCTP_INP_INCR_REF(it->inp); } } - /* - * When its put in the refcnt is incremented so decr - * it - */ + /* When its put in the refcnt is incremented so decr + * it */ SCTP_INP_DECR_REF(inp); } } @@ -3991,10 +3955,8 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, rmtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, net->ro.ro_rt); if (rmtu == 0) { - /* - * Start things off to match mtu of - * interface please. - */ + /* Start things off to match mtu of + * interface please. */ SCTP_SET_MTU_OF_ROUTE(&net->ro._l_addr.sa, net->ro.ro_rt, net->mtu); } else { @@ -4908,6 +4870,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre SS_ISCONNECTED); } socantrcvmore_locked(so); + socantsendmore(so); sctp_sowwakeup(inp, so); sctp_sorwakeup(inp, so); SCTP_SOWAKEUP(so); @@ -5484,10 +5447,8 @@ sctp_del_local_addr_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa) if (stcb->asoc.last_used_address == laddr) /* delete this address */ stcb->asoc.last_used_address = NULL; - /* - * Now spin through all the nets and purge any ref - * to laddr - */ + /* Now spin through all the nets and purge any ref + * to laddr */ TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { if (net->ro._s_addr == laddr->ifa) { /* Yep, purge src address selected */ @@ -5755,7 +5716,6 @@ sctp_startup_mcore_threads(void) } } - #endif void @@ -6097,14 +6057,11 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, uint8_t peer_supports_nrsack; uint8_t peer_supports_pktdrop; uint8_t peer_supports_idata; - #ifdef INET struct sockaddr_in sin; - #endif #ifdef INET6 struct sockaddr_in6 sin6; - #endif /* First get the destination address setup too. */ @@ -6267,10 +6224,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, struct mbuf *op_err; char msg[SCTP_DIAG_INFO_LEN]; - /* - * in setup state we - * abort this guy - */ + /* in setup state we + * abort this guy */ snprintf(msg, sizeof(msg), "%s:%d at %s", __FILE__, __LINE__, __func__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), @@ -6312,10 +6267,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, goto next_param; } if (IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) { - /* - * Link local make no sense without - * scope - */ + /* Link local make no sense without + * scope */ goto next_param; } sa = (struct sockaddr *)&sin6; @@ -6366,10 +6319,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, struct mbuf *op_err; char msg[SCTP_DIAG_INFO_LEN]; - /* - * in setup state we - * abort this guy - */ + /* in setup state we + * abort this guy */ snprintf(msg, sizeof(msg), "%s:%d at %s", __FILE__, __LINE__, __func__); op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), @@ -6409,10 +6360,8 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m, struct sctp_asconf_addr_param lstore, *fee; int lptype; struct sockaddr *lsa = NULL; - #ifdef INET struct sctp_asconf_addrv4_param *fii; - #endif if (stcb->asoc.asconf_supported == 0) { diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 6414a8fa9e08..258ee00cd275 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -57,7 +57,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef TCP_HHOOK #include +#endif #include #include #include /* for proc0 declaration */ @@ -278,6 +280,7 @@ kmod_tcpstat_inc(int statnum) counter_u64_add(VNET(tcpstat)[statnum], 1); } +#ifdef TCP_HHOOK /* * Wrapper for the TCP established input helper hook. */ @@ -295,6 +298,7 @@ hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to) tp->osd); } } +#endif /* * CC wrapper hook functions @@ -1024,7 +1028,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) #endif if (!((tp->t_state == TCPS_ESTABLISHED && (thflags & TH_SYN) == 0) || (tp->t_state == TCPS_LISTEN && (thflags & TH_SYN) && - !(tp->t_flags & TF_FASTOPEN)))) { + !IS_FASTOPEN(tp->t_flags)))) { if (ti_locked == TI_UNLOCKED) { if (INP_INFO_TRY_RLOCK(&V_tcbinfo) == 0) { in_pcbref(inp); @@ -1067,11 +1071,11 @@ tcp_input(struct mbuf **mp, int *offp, int proto) * state) we look into the SYN cache if this is a new connection * attempt or the completion of a previous one. */ - if (so->so_options & SO_ACCEPTCONN) { + KASSERT(tp->t_state == TCPS_LISTEN || !(so->so_options & SO_ACCEPTCONN), + ("%s: so accepting but tp %p not listening", __func__, tp)); + if (tp->t_state == TCPS_LISTEN && (so->so_options & SO_ACCEPTCONN)) { struct in_conninfo inc; - KASSERT(tp->t_state == TCPS_LISTEN, ("%s: so accepting but " - "tp not listening", __func__)); bzero(&inc, sizeof(inc)); #ifdef INET6 if (isipv6) { @@ -1117,7 +1121,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) goto dropwithreset; } #ifdef TCP_RFC7413 -new_tfo_socket: +tfo_socket_result: #endif if (so == NULL) { /* @@ -1383,7 +1387,7 @@ tcp_input(struct mbuf **mp, int *offp, int proto) tcp_dooptions(&to, optp, optlen, TO_SYN); #ifdef TCP_RFC7413 if (syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL)) - goto new_tfo_socket; + goto tfo_socket_result; #else syncache_add(&inc, &to, th, inp, &so, m, NULL, NULL); #endif @@ -1502,7 +1506,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, struct in_conninfo *inc; struct mbuf *mfree; struct tcpopt to; +#ifdef TCP_RFC7413 int tfo_syn; +#endif #ifdef TCPDEBUG /* @@ -1559,8 +1565,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * validation to ignore broken/spoofed segs. */ tp->t_rcvtime = ticks; - if (TCPS_HAVEESTABLISHED(tp->t_state)) - tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); /* * Scale up the window into a 32-bit value. @@ -1753,8 +1757,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, } acked = BYTES_THIS_ACK(tp, th); +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, &to); +#endif TCPSTAT_ADD(tcps_rcvackpack, nsegs); TCPSTAT_ADD(tcps_rcvackbyte, acked); @@ -1958,7 +1964,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, goto dropwithreset; } #ifdef TCP_RFC7413 - if (tp->t_flags & TF_FASTOPEN) { + if (IS_FASTOPEN(tp->t_flags)) { /* * When a TFO connection is in SYN_RECEIVED, the * only valid packets are the initial SYN, a @@ -2392,7 +2398,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, (tp->t_flags & TF_NEEDSYN)) { #ifdef TCP_RFC7413 if (tp->t_state == TCPS_SYN_RECEIVED && - tp->t_flags & TF_FASTOPEN) { + IS_FASTOPEN(tp->t_flags)) { tp->snd_wnd = tiwin; cc_conn_init(tp); } @@ -2455,7 +2461,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * snd_cwnd reduction that occurs when a TFO SYN|ACK * is retransmitted. */ - if (!(tp->t_flags & TF_FASTOPEN)) + if (!IS_FASTOPEN(tp->t_flags)) #endif cc_conn_init(tp); tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); @@ -2499,8 +2505,10 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, */ tp->sackhint.sacked_bytes = 0; +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, &to); +#endif if (SEQ_LEQ(th->th_ack, tp->snd_una)) { u_int maxseg; @@ -3020,8 +3028,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * case PRU_RCVD). If a FIN has already been received on this * connection then we just ignore the text. */ +#ifdef TCP_RFC7413 tfo_syn = ((tp->t_state == TCPS_SYN_RECEIVED) && - (tp->t_flags & TF_FASTOPEN)); + IS_FASTOPEN(tp->t_flags)); +#else +#define tfo_syn (false) +#endif if ((tlen || (thflags & TH_FIN) || tfo_syn) && TCPS_HAVERCVDFIN(tp->t_state) == 0) { tcp_seq save_start = th->th_seq; @@ -3245,6 +3257,9 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (tp != NULL) INP_WUNLOCK(tp->t_inpcb); m_freem(m); +#ifndef TCP_RFC7413 +#undef tfo_syn +#endif } /* diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 7e638104c922..fd549944022c 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -40,7 +40,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef TCP_HHOOK #include +#endif #include #include #include @@ -140,11 +142,14 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, sendbuf_max, CTLFLAG_VNET | CTLFLAG_RW, tcp_timer_active((tp), TT_PERSIST), \ ("neither rexmt nor persist timer is set")) +#ifdef TCP_HHOOK static void inline hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to, uint32_t len, int tso); +#endif static void inline cc_after_idle(struct tcpcb *tp); +#ifdef TCP_HHOOK /* * Wrapper for the TCP established output helper hook. */ @@ -165,6 +170,7 @@ hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th, tp->osd); } } +#endif /* * CC wrapper hook functions @@ -224,7 +230,7 @@ tcp_output(struct tcpcb *tp) * For TFO connections in SYN_RECEIVED, only allow the initial * SYN|ACK and those sent by the retransmit timer. */ - if ((tp->t_flags & TF_FASTOPEN) && + if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED) && SEQ_GT(tp->snd_max, tp->snd_una) && /* initial SYN|ACK sent */ (tp->snd_nxt != tp->snd_una)) /* not a retransmit */ @@ -420,7 +426,7 @@ tcp_output(struct tcpcb *tp) * When sending additional segments following a TFO SYN|ACK, * do not include the SYN bit. */ - if ((tp->t_flags & TF_FASTOPEN) && + if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) flags &= ~TH_SYN; #endif @@ -443,7 +449,7 @@ tcp_output(struct tcpcb *tp) * don't include data, as the presence of data may have caused the * original SYN|ACK to have been dropped by a middlebox. */ - if ((tp->t_flags & TF_FASTOPEN) && + if (IS_FASTOPEN(tp->t_flags) && (((tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_rxtshift > 0)) || (flags & TH_RST))) len = 0; @@ -780,7 +786,7 @@ tcp_output(struct tcpcb *tp) * the TFO option may have caused the original * SYN|ACK to have been dropped by a middlebox. */ - if ((tp->t_flags & TF_FASTOPEN) && + if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED) && (tp->t_rxtshift == 0)) { to.to_tfo_len = TCP_FASTOPEN_COOKIE_LEN; @@ -1306,8 +1312,10 @@ tcp_output(struct tcpcb *tp) __func__, len, hdrlen, ipoptlen, m_length(m, NULL))); #endif +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */ hhook_run_tcp_est_out(tp, th, &to, len, tso); +#endif #ifdef TCPDEBUG /* diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c index f64bc974bd0f..a31a28e70f69 100644 --- a/sys/netinet/tcp_stacks/fastpath.c +++ b/sys/netinet/tcp_stacks/fastpath.c @@ -60,9 +60,13 @@ __FBSDID("$FreeBSD$"); #include "opt_tcpdebug.h" #include +#include #include +#include #include +#ifdef TCP_HHOOK #include +#endif #include #include #include /* for proc0 declaration */ @@ -266,8 +270,10 @@ tcp_do_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, if (winup_only == 0) { acked = BYTES_THIS_ACK(tp, th); +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, to); +#endif TCPSTAT_ADD(tcps_rcvackbyte, acked); sbdrop(&so->so_snd, acked); @@ -1040,8 +1046,10 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so, */ tp->sackhint.sacked_bytes = 0; +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, to); +#endif if (SEQ_LEQ(th->th_ack, tp->snd_una)) { if (tlen == 0 && tiwin == tp->snd_wnd) { @@ -1811,8 +1819,6 @@ tcp_do_segment_fastslow(struct mbuf *m, struct tcphdr *th, struct socket *so, * validation to ignore broken/spoofed segs. */ tp->t_rcvtime = ticks; - if (TCPS_HAVEESTABLISHED(tp->t_state)) - tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); /* * Unscale the window into a 32-bit value. @@ -2127,8 +2133,10 @@ tcp_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, if (winup_only == 0) { acked = BYTES_THIS_ACK(tp, th); +#ifdef TCP_HHOOK /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */ hhook_run_tcp_est_in(tp, th, to); +#endif TCPSTAT_ADD(tcps_rcvackbyte, acked); sbdrop(&so->so_snd, acked); @@ -2256,8 +2264,6 @@ tcp_do_segment_fastack(struct mbuf *m, struct tcphdr *th, struct socket *so, * validation to ignore broken/spoofed segs. */ tp->t_rcvtime = ticks; - if (TCPS_HAVEESTABLISHED(tp->t_state)) - tcp_timer_activate(tp, TT_KEEP, TP_KEEPIDLE(tp)); /* * Unscale the window into a 32-bit value. diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 6490c68cbdae..e69c3d45d0f4 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -42,9 +42,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef TCP_HHOOK #include +#endif #include +#ifdef TCP_HHOOK #include +#endif #include #include #include @@ -238,7 +242,9 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, signature_verify_input, CTLFLAG_RW, VNET_DEFINE(uma_zone_t, sack_hole_zone); #define V_sack_hole_zone VNET(sack_hole_zone) +#ifdef TCP_HHOOK VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]); +#endif static struct inpcb *tcp_notify(struct inpcb *, int); static struct inpcb *tcp_mtudisc_notify(struct inpcb *, int); @@ -449,7 +455,9 @@ struct tcpcb_mem { struct tcpcb tcb; struct tcp_timer tt; struct cc_var ccv; +#ifdef TCP_HHOOK struct osd osd; +#endif }; static VNET_DEFINE(uma_zone_t, tcpcb_zone); @@ -605,12 +613,14 @@ tcp_init(void) tcbhash_tuneable = "net.inet.tcp.tcbhashsize"; +#ifdef TCP_HHOOK if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN, &V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0) printf("%s: WARNING: unable to register helper hook\n", __func__); if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, &V_tcp_hhh[HHOOK_TCP_EST_OUT], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0) printf("%s: WARNING: unable to register helper hook\n", __func__); +#endif hashsize = TCBHASHSIZE; TUNABLE_INT_FETCH(tcbhash_tuneable, &hashsize); if (hashsize == 0) { @@ -732,7 +742,10 @@ tcp_init(void) static void tcp_destroy(void *unused __unused) { - int error, n; + int n; +#ifdef TCP_HHOOK + int error; +#endif /* * All our processes are gone, all our sockets should be cleaned @@ -763,6 +776,7 @@ tcp_destroy(void *unused __unused) tcp_fastopen_destroy(); #endif +#ifdef TCP_HHOOK error = hhook_head_deregister(V_tcp_hhh[HHOOK_TCP_EST_IN]); if (error != 0) { printf("%s: WARNING: unable to deregister helper hook " @@ -775,6 +789,7 @@ tcp_destroy(void *unused __unused) "type=%d, id=%d: error %d returned\n", __func__, HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT, error); } +#endif } VNET_SYSUNINIT(tcp, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, tcp_destroy, NULL); #endif @@ -1204,6 +1219,7 @@ tcp_newtcpcb(struct inpcb *inp) return (NULL); } +#ifdef TCP_HHOOK tp->osd = &tm->osd; if (khelp_init_osd(HELPER_CLASS_TCP, tp->osd)) { if (tp->t_fb->tfb_tcp_fb_fini) @@ -1212,6 +1228,7 @@ tcp_newtcpcb(struct inpcb *inp) uma_zfree(V_tcpcb_zone, tm); return (NULL); } +#endif #ifdef VIMAGE tp->t_vnet = inp->inp_vnet; @@ -1477,7 +1494,9 @@ tcp_discardcb(struct tcpcb *tp) if (CC_ALGO(tp)->cb_destroy != NULL) CC_ALGO(tp)->cb_destroy(tp->ccv); +#ifdef TCP_HHOOK khelp_destroy_osd(tp->osd); +#endif CC_ALGO(tp) = NULL; inp->inp_ppcb = NULL; diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index e156ff846ecd..33e5df782d69 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1151,11 +1151,10 @@ syncache_tfo_expand(struct syncache *sc, struct socket **lsop, struct mbuf *m, * the data, we avoid this DoS scenario. * * The exception to the above is when a SYN with a valid TCP Fast Open (TFO) - * cookie is processed, V_tcp_fastopen_enabled set to true, and the - * TCP_FASTOPEN socket option is set. In this case, a new socket is created - * and returned via lsop, the mbuf is not freed so that tcp_input() can - * queue its data to the socket, and 1 is returned to indicate the - * TFO-socket-creation path was taken. + * cookie is processed and a new socket is created. In this case, any data + * accompanying the SYN will be queued to the socket by tcp_input() and will + * be ACKed either when the application sends response data or the delayed + * ACK timer expires, whichever comes first. */ int syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, @@ -1181,6 +1180,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, struct ucred *cred; #ifdef TCP_RFC7413 uint64_t tfo_response_cookie; + unsigned int *tfo_pending = NULL; int tfo_cookie_valid = 0; int tfo_response_cookie_valid = 0; #endif @@ -1209,7 +1209,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE)); #ifdef TCP_RFC7413 - if (V_tcp_fastopen_enabled && (tp->t_flags & TF_FASTOPEN) && + if (V_tcp_fastopen_enabled && IS_FASTOPEN(tp->t_flags) && (tp->t_tfo_pending != NULL) && (to->to_flags & TOF_FASTOPEN)) { /* * Limit the number of pending TFO connections to @@ -1226,8 +1226,13 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, &tfo_response_cookie); tfo_cookie_valid = (result > 0); tfo_response_cookie_valid = (result >= 0); - } else - atomic_subtract_int(tp->t_tfo_pending, 1); + } + + /* + * Remember the TFO pending counter as it will have to be + * decremented below if we don't make it to syncache_tfo_expand(). + */ + tfo_pending = tp->t_tfo_pending; } #endif @@ -1468,9 +1473,9 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, #ifdef TCP_RFC7413 if (tfo_cookie_valid) { syncache_tfo_expand(sc, lsop, m, tfo_response_cookie); - /* INP_WUNLOCK(inp) will be performed by the called */ + /* INP_WUNLOCK(inp) will be performed by the caller */ rv = 1; - goto tfo_done; + goto tfo_expanded; } #endif @@ -1496,7 +1501,16 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, m_freem(m); } #ifdef TCP_RFC7413 -tfo_done: + /* + * If tfo_pending is not NULL here, then a TFO SYN that did not + * result in a new socket was processed and the associated pending + * counter has not yet been decremented. All such TFO processing paths + * transit this point. + */ + if (tfo_pending != NULL) + tcp_fastopen_decrement_counter(tfo_pending); + +tfo_expanded: #endif if (cred != NULL) crfree(cred); diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c index 5f231c079784..f9f5c05fdce4 100644 --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -468,6 +468,26 @@ tcp_timer_keep(void *xtp) } KASSERT((tp->t_timers->tt_flags & TT_STOPPED) == 0, ("%s: tp %p tcpcb can't be stopped here", __func__, tp)); + + /* + * Because we don't regularly reset the keepalive callout in + * the ESTABLISHED state, it may be that we don't actually need + * to send a keepalive yet. If that occurs, schedule another + * call for the next time the keepalive timer might expire. + */ + if (TCPS_HAVEESTABLISHED(tp->t_state)) { + u_int idletime; + + idletime = ticks - tp->t_rcvtime; + if (idletime < TP_KEEPIDLE(tp)) { + callout_reset(&tp->t_timers->tt_keep, + TP_KEEPIDLE(tp) - idletime, tcp_timer_keep, tp); + INP_WUNLOCK(inp); + CURVNET_RESTORE(); + return; + } + } + /* * Keep-alive timer went off; send something * or drop connection if idle for too long. diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 67b7ba5d2c40..0edd723cc7d3 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -410,7 +410,7 @@ tcp_usr_listen(struct socket *so, int backlog, struct thread *td) SOCK_UNLOCK(so); #ifdef TCP_RFC7413 - if (tp->t_flags & TF_FASTOPEN) + if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); #endif out: @@ -460,7 +460,7 @@ tcp6_usr_listen(struct socket *so, int backlog, struct thread *td) SOCK_UNLOCK(so); #ifdef TCP_RFC7413 - if (tp->t_flags & TF_FASTOPEN) + if (IS_FASTOPEN(tp->t_flags)) tp->t_tfo_pending = tcp_fastopen_alloc_counter(); #endif out: @@ -826,7 +826,7 @@ tcp_usr_rcvd(struct socket *so, int flags) * application response data, or failing that, when the DELACK timer * expires. */ - if ((tp->t_flags & TF_FASTOPEN) && + if (IS_FASTOPEN(tp->t_flags) && (tp->t_state == TCPS_SYN_RECEIVED)) goto out; #endif diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 3cc9af577963..f4ea246b1837 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -349,6 +349,12 @@ struct tcpcb { #define ENTER_RECOVERY(t_flags) t_flags |= (TF_CONGRECOVERY | TF_FASTRECOVERY) #define EXIT_RECOVERY(t_flags) t_flags &= ~(TF_CONGRECOVERY | TF_FASTRECOVERY) +#if defined(_KERNEL) && !defined(TCP_RFC7413) +#define IS_FASTOPEN(t_flags) (false) +#else +#define IS_FASTOPEN(t_flags) (t_flags & TF_FASTOPEN) +#endif + #define BYTES_THIS_ACK(tp, th) (th->th_ack - tp->snd_una) /* @@ -749,8 +755,10 @@ VNET_DECLARE(int, tcp_ecn_maxretries); #define V_tcp_do_ecn VNET(tcp_do_ecn) #define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries) +#ifdef TCP_HHOOK VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST + 1]); #define V_tcp_hhh VNET(tcp_hhh) +#endif VNET_DECLARE(int, tcp_do_rfc6675_pipe); #define V_tcp_do_rfc6675_pipe VNET(tcp_do_rfc6675_pipe) @@ -788,8 +796,10 @@ void cc_ack_received(struct tcpcb *tp, struct tcphdr *th, void cc_conn_init(struct tcpcb *tp); void cc_post_recovery(struct tcpcb *tp, struct tcphdr *th); void cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type); +#ifdef TCP_HHOOK void hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to); +#endif int tcp_input(struct mbuf **, int *, int); void tcp_do_segment(struct mbuf *, struct tcphdr *, diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 7b71abd4657a..6045ee1e185b 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1064,12 +1064,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, IP6STAT_INC(ip6s_fragmented); done: - /* - * Release the route if using our private route, or if - * (with flowtable) we don't have our own reference. - */ - if (ro == &ip6route || - (ro != NULL && ro->ro_flags & RT_NORTREF)) + if (ro == &ip6route) RO_RTFREE(ro); return (error); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index d760eecd930e..f8acce55d978 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -5893,7 +5893,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct inpcb *inp) pd.sidx = (dir == PF_IN) ? 0 : 1; pd.didx = (dir == PF_IN) ? 1 : 0; pd.af = AF_INET; - pd.tos = h->ip_tos; + pd.tos = h->ip_tos & ~IPTOS_ECN_MASK; pd.tot_len = ntohs(h->ip_len); /* handle fragments that didn't get reassembled by normalization */ diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index dbc88183b6aa..b6301b6da852 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -1811,7 +1811,7 @@ pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos) u_int16_t ov, nv; ov = *(u_int16_t *)h; - h->ip_tos = tos; + h->ip_tos = tos | (h->ip_tos & IPTOS_ECN_MASK); nv = *(u_int16_t *)h; h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0); diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 478df09ff612..0e140c9af8da 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -30,6 +30,7 @@ options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/pc98/include/efi.h b/sys/pc98/include/efi.h new file mode 100644 index 000000000000..71d5728e7a85 --- /dev/null +++ b/sys/pc98/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __PC98_INCLUDE_EFI_H_ +#define __PC98_INCLUDE_EFI_H_ + +#define EFIABI_ATTR + +/* Note: we don't actually support this on pc98 */ + +#endif /* __PC98_INCLUDE_EFI_H_ */ diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index d464ac7ee120..48ea76cd6d10 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -38,6 +38,7 @@ options PREEMPTION #Enable kernel thread preemption options INET #InterNETworking options INET6 #IPv6 communications protocols options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP options SCTP #Stream Control Transmission Protocol options FFS #Berkeley Fast Filesystem options SOFTUPDATES #Enable FFS soft updates support diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 88d481110915..598944473f6a 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -37,6 +37,7 @@ options SCHED_ULE #ULE scheduler options PREEMPTION #Enable kernel thread preemption options INET #InterNETworking options INET6 #IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options SCTP #Stream Control Transmission Protocol options FFS #Berkeley Fast Filesystem options SOFTUPDATES #Enable FFS soft updates support diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX index 97464e84949c..0e60ceb24e55 100644 --- a/sys/powerpc/conf/MPC85XX +++ b/sys/powerpc/conf/MPC85XX @@ -36,6 +36,7 @@ options GDB options GEOM_PART_GPT options INET options INET6 +options TCP_HHOOK # hhook(9) framework for TCP options INVARIANTS options INVARIANT_SUPPORT options KDB diff --git a/sys/powerpc/include/efi.h b/sys/powerpc/include/efi.h new file mode 100644 index 000000000000..f4b97d62b3e0 --- /dev/null +++ b/sys/powerpc/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __POWERPC_INCLUDE_EFI_H_ +#define __POWERPC_INCLUDE_EFI_H_ + +#define EFIABI_ATTR + +/* Note: we don't actually support this on powerpc */ + +#endif /* __POWERPC_INCLUDE_EFI_H_ */ diff --git a/sys/powerpc/powerpc/mem.c b/sys/powerpc/powerpc/mem.c index a7fbfa3edf84..2bc89fd4b5af 100644 --- a/sys/powerpc/powerpc/mem.c +++ b/sys/powerpc/powerpc/mem.c @@ -179,8 +179,6 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, if (dev2unit(dev) == CDEV_MINOR_MEM) *paddr = offset; - else if (dev2unit(dev) == CDEV_MINOR_KMEM) - *paddr = vtophys(offset); else return (EFAULT); diff --git a/sys/riscv/conf/GENERIC b/sys/riscv/conf/GENERIC index 6c53da2a051c..aafa3979c186 100644 --- a/sys/riscv/conf/GENERIC +++ b/sys/riscv/conf/GENERIC @@ -32,6 +32,7 @@ options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options TCP_HHOOK # hhook(9) framework for TCP options IPSEC # IP (v4/v6) security options TCP_OFFLOAD # TCP offload options SCTP # Stream Control Transmission Protocol diff --git a/sys/riscv/include/efi.h b/sys/riscv/include/efi.h new file mode 100644 index 000000000000..4f1e2181b877 --- /dev/null +++ b/sys/riscv/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __RISCV_INCLUDE_EFI_H_ +#define __RISCV_INCLUDE_EFI_H_ + +#define EFIABI_ATTR + +/* Note: we don't actually support this on riscv */ + +#endif /* __I386_INCLUDE_EFI_H_ */ diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index a03f6367f354..4e8a31c85799 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -31,6 +31,7 @@ options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options IPSEC # IP (v4/v6) security +options TCP_HHOOK # hhook(9) framework for TCP options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support diff --git a/sys/sparc64/include/efi.h b/sys/sparc64/include/efi.h new file mode 100644 index 000000000000..1f7ad0da18af --- /dev/null +++ b/sys/sparc64/include/efi.h @@ -0,0 +1,14 @@ +/*- + * This file is in the public domain since it's just boilerplate. + * + * $FreeBSD$ + */ + +#ifndef __SPARC64_INCLUDE_EFI_H_ +#define __SPARC64_INCLUDE_EFI_H_ + +#define EFIABI_ATTR + +/* Note: we don't actually support this on sparc64 */ + +#endif /* __I386_INCLUDE_EFI_H_ */ diff --git a/sys/sys/efi.h b/sys/sys/efi.h index 68fc2816e494..81c6fd32468f 100644 --- a/sys/sys/efi.h +++ b/sys/sys/efi.h @@ -165,6 +165,9 @@ struct efi_systbl { #ifdef _KERNEL extern vm_paddr_t efi_systbl_phys; +struct cdev; +int efidev_init(struct cdev **); +int efidev_uninit(struct cdev *); #endif /* _KERNEL */ #endif /* _SYS_EFI_H_ */ diff --git a/sys/sys/efiio.h b/sys/sys/efiio.h new file mode 100644 index 000000000000..1e1cff67b62f --- /dev/null +++ b/sys/sys/efiio.h @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_EFIIO_H_ +#define _SYS_EFIIO_H_ + +#include +#include +#include + +struct efi_get_table_ioc +{ + struct uuid uuid; /* UUID to look up */ + void *ptr; /* Pointer to table in KVA space */ +}; + +struct efi_var_ioc +{ + efi_char *name; /* User pointer to name, in wide chars */ + size_t namesize; /* Number of wide characters in name */ + struct uuid vendor; /* Vendor's UUID for variable */ + uint32_t attrib; /* Attributes */ + void *data; /* User pointer to the data */ + size_t datasize; /* Number of *bytes* in the data */ +}; + +#define EFIIOC_GET_TABLE _IOWR('E', 1, struct efi_get_table_ioc) +#define EFIIOC_GET_TIME _IOR('E', 2, struct efi_tm) +#define EFIIOC_SET_TIME _IOW('E', 3, struct efi_tm) +#define EFIIOC_VAR_GET _IOWR('E', 4, struct efi_var_ioc) +#define EFIIOC_VAR_NEXT _IOWR('E', 5, struct efi_var_ioc) +#define EFIIOC_VAR_SET _IOWR('E', 6, struct efi_var_ioc) + +#endif /* _SYS_EFIIO_H_ */ diff --git a/sys/sys/linker.h b/sys/sys/linker.h index 42253a7758ab..e650967cecb1 100644 --- a/sys/sys/linker.h +++ b/sys/sys/linker.h @@ -73,6 +73,7 @@ struct linker_file { int userrefs; /* kldload(2) count */ int flags; #define LINKER_FILE_LINKED 0x1 /* file has been fully linked */ +#define LINKER_FILE_MODULES 0x2 /* file has >0 modules at preload */ TAILQ_ENTRY(linker_file) link; /* list of all loaded files */ char* filename; /* file which was loaded */ char* pathname; /* file name with full path */ diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index fdd9931515da..eac039a462b0 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -335,7 +335,7 @@ struct mbuf { #define M_HASHTYPE_RSS_TCP_IPV6 M_HASHTYPE_HASH(4) /* TCPv6 4-tuple */ #define M_HASHTYPE_RSS_IPV6_EX M_HASHTYPE_HASH(5) /* IPv6 2-tuple + * ext hdrs */ -#define M_HASHTYPE_RSS_TCP_IPV6_EX M_HASHTYPE_HASH(6) /* TCPv6 4-tiple + +#define M_HASHTYPE_RSS_TCP_IPV6_EX M_HASHTYPE_HASH(6) /* TCPv6 4-tuple + * ext hdrs */ /* Non-standard RSS hash types */ #define M_HASHTYPE_RSS_UDP_IPV4 M_HASHTYPE_HASH(7) /* IPv4 UDP 4-tuple*/ diff --git a/sys/sys/param.h b/sys/sys/param.h index 6329ab8b6be5..02576d6a2a39 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -44,7 +44,7 @@ #define BSD4_3 1 #define BSD4_4 1 -/* +/* * __FreeBSD_version numbers are documented in the Porter's Handbook. * If you bump the version for any reason, you should update the documentation * there. @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200012 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200013 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, @@ -241,7 +241,7 @@ * * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the * minimum KVM memory reservation the kernel is willing to make. - * Filesystems can of course request smaller chunks. Actual + * Filesystems can of course request smaller chunks. Actual * backing memory uses a chunk size of a page (PAGE_SIZE). * The default value here can be overridden on a per-architecture * basis by defining it in . This should @@ -250,8 +250,8 @@ * * If you make BKVASIZE too small you risk seriously fragmenting * the buffer KVM map which may slow things down a bit. If you - * make it too big the kernel will not be able to optimally use - * the KVM memory reserved for the buffer cache and will wind + * make it too big the kernel will not be able to optimally use + * the KVM memory reserved for the buffer cache and will wind * up with too-few buffers. * * The default is 16384, roughly 2x the block size used by a @@ -344,7 +344,7 @@ __END_DECLS #define dbtoc(db) /* calculates devblks to pages */ \ ((db + (ctodb(1) - 1)) >> (PAGE_SHIFT - DEV_BSHIFT)) - + #define ctodb(db) /* calculates pages to devblks */ \ ((db) << (PAGE_SHIFT - DEV_BSHIFT)) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 050ddddaa68c..9257fe83ac5f 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -321,6 +321,8 @@ RetryFault:; growstack = FALSE; goto RetryFault; } + if (fs.vp != NULL) + vput(fs.vp); return (result); } diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 17723c7308f0..7321990c5408 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1186,7 +1186,7 @@ vm_object_madvise(vm_object_t object, vm_pindex_t pindex, vm_pindex_t end, if (object != tobject) VM_OBJECT_WUNLOCK(object); VM_OBJECT_WUNLOCK(tobject); - vm_page_busy_sleep(m, "madvpo"); + vm_page_busy_sleep(m, "madvpo", false); VM_OBJECT_WLOCK(object); goto relookup; } @@ -1365,7 +1365,7 @@ vm_object_split(vm_map_entry_t entry) VM_OBJECT_WUNLOCK(new_object); vm_page_lock(m); VM_OBJECT_WUNLOCK(orig_object); - vm_page_busy_sleep(m, "spltwt"); + vm_page_busy_sleep(m, "spltwt", false); VM_OBJECT_WLOCK(orig_object); VM_OBJECT_WLOCK(new_object); goto retry; @@ -1453,7 +1453,7 @@ vm_object_collapse_scan_wait(vm_object_t object, vm_page_t p, vm_page_t next, if (p == NULL) VM_WAIT; else - vm_page_busy_sleep(p, "vmocol"); + vm_page_busy_sleep(p, "vmocol", false); VM_OBJECT_WLOCK(object); VM_OBJECT_WLOCK(backing_object); return (TAILQ_FIRST(&backing_object->memq)); @@ -1912,7 +1912,7 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, vm_page_lock(p); if (vm_page_xbusied(p)) { VM_OBJECT_WUNLOCK(object); - vm_page_busy_sleep(p, "vmopax"); + vm_page_busy_sleep(p, "vmopax", true); VM_OBJECT_WLOCK(object); goto again; } @@ -1927,7 +1927,7 @@ vm_object_page_remove(vm_object_t object, vm_pindex_t start, vm_pindex_t end, } if (vm_page_busied(p)) { VM_OBJECT_WUNLOCK(object); - vm_page_busy_sleep(p, "vmopar"); + vm_page_busy_sleep(p, "vmopar", false); VM_OBJECT_WLOCK(object); goto again; } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 91df5ff41c10..bd03a95d754a 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -655,15 +655,26 @@ void vm_page_busy_downgrade(vm_page_t m) { u_int x; + bool locked; vm_page_assert_xbusied(m); + locked = mtx_owned(vm_page_lockptr(m)); for (;;) { x = m->busy_lock; x &= VPB_BIT_WAITERS; + if (x != 0 && !locked) + vm_page_lock(m); if (atomic_cmpset_rel_int(&m->busy_lock, - VPB_SINGLE_EXCLUSIVER | x, VPB_SHARERS_WORD(1) | x)) + VPB_SINGLE_EXCLUSIVER | x, VPB_SHARERS_WORD(1))) break; + if (x != 0 && !locked) + vm_page_unlock(m); + } + if (x != 0) { + wakeup(m); + if (!locked) + vm_page_unlock(m); } } @@ -730,21 +741,20 @@ vm_page_sunbusy(vm_page_t m) * This is used to implement the hard-path of busying mechanism. * * The given page must be locked. + * + * If nonshared is true, sleep only if the page is xbusy. */ void -vm_page_busy_sleep(vm_page_t m, const char *wmesg) +vm_page_busy_sleep(vm_page_t m, const char *wmesg, bool nonshared) { u_int x; - vm_page_lock_assert(m, MA_OWNED); + vm_page_assert_locked(m); x = m->busy_lock; - if (x == VPB_UNBUSIED) { - vm_page_unlock(m); - return; - } - if ((x & VPB_BIT_WAITERS) == 0 && - !atomic_cmpset_int(&m->busy_lock, x, x | VPB_BIT_WAITERS)) { + if (x == VPB_UNBUSIED || (nonshared && (x & VPB_BIT_SHARED) != 0) || + ((x & VPB_BIT_WAITERS) == 0 && + !atomic_cmpset_int(&m->busy_lock, x, x | VPB_BIT_WAITERS))) { vm_page_unlock(m); return; } @@ -1081,7 +1091,7 @@ vm_page_sleep_if_busy(vm_page_t m, const char *msg) obj = m->object; vm_page_lock(m); VM_OBJECT_WUNLOCK(obj); - vm_page_busy_sleep(m, msg); + vm_page_busy_sleep(m, msg, false); VM_OBJECT_WLOCK(obj); return (TRUE); } @@ -3444,7 +3454,8 @@ vm_page_grab(vm_object_t object, vm_pindex_t pindex, int allocflags) vm_page_aflag_set(m, PGA_REFERENCED); vm_page_lock(m); VM_OBJECT_WUNLOCK(object); - vm_page_busy_sleep(m, "pgrbwt"); + vm_page_busy_sleep(m, "pgrbwt", (allocflags & + VM_ALLOC_IGN_SBUSY) != 0); VM_OBJECT_WLOCK(object); goto retrylookup; } else { diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 66aec76d6eb9..e39c5b1d1ef6 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -436,7 +436,7 @@ malloc2vm_flags(int malloc_flags) #endif void vm_page_busy_downgrade(vm_page_t m); -void vm_page_busy_sleep(vm_page_t m, const char *msg); +void vm_page_busy_sleep(vm_page_t m, const char *msg, bool nonshared); void vm_page_flash(vm_page_t m); void vm_page_hold(vm_page_t mem); void vm_page_unhold(vm_page_t mem); diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c index 26fc9e98e4d9..4f9d6a52be99 100644 --- a/sys/x86/x86/io_apic.c +++ b/sys/x86/x86/io_apic.c @@ -916,11 +916,16 @@ ioapic_register(void *cookie) io->io_id, flags >> 4, flags & 0xf, io->io_intbase, io->io_intbase + io->io_numintr - 1); - /* Register valid pins as interrupt sources. */ + /* + * Reprogram pins to handle special case pins (such as NMI and + * SMI) and register valid pins as interrupt sources. + */ intr_register_pic(&io->io_pic); - for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++) + for (i = 0, pin = io->io_pins; i < io->io_numintr; i++, pin++) { + ioapic_reprogram_intpin(&pin->io_intsrc); if (pin->io_irq < NUM_IO_INTS) intr_register_source(&pin->io_intsrc); + } } /* A simple new-bus driver to consume PCI I/O APIC devices. */ diff --git a/targets/pseudo/userland/misc/Makefile.depend b/targets/pseudo/userland/misc/Makefile.depend index 19ede3238843..a4091cc1d76f 100644 --- a/targets/pseudo/userland/misc/Makefile.depend +++ b/targets/pseudo/userland/misc/Makefile.depend @@ -77,7 +77,7 @@ DIRDEPS.amd64+= \ DIRDEPS.arm= ${_sys_boot_fdt} ${_sys_boot_efi} DIRDEPS.arm64= ${_sys_boot_fdt} ${_sys_boot_efi} -DIRDEPS.i386= ${DIRDEPS.x86sys} sys/boot/efi/libefi +DIRDEPS.i386= ${DIRDEPS.x86sys} ${_sys_boot_efi} DIRDEPS.powerpc= ${_sys_boot_fdt} sys/boot/libstand32 sys/boot/ofw sys/boot/uboot DIRDEPS.pc98= sys/boot/libstand32 DIRDEPS.sparc64= sys/boot/ofw ${_sys_boot_zfs} diff --git a/tests/sys/kern/kern_copyin.c b/tests/sys/kern/kern_copyin.c index 445a632274d4..7eea95e8c782 100644 --- a/tests/sys/kern/kern_copyin.c +++ b/tests/sys/kern/kern_copyin.c @@ -59,6 +59,11 @@ ATF_TC_BODY(kern_copyin, tc) { char template[] = "copyin.XXXXXX"; +#ifdef __mips__ + /* MIPS has no shared page implemented yet. */ + atf_tc_skip("Platform is not supported."); +#endif + scratch_file = mkstemp(template); ATF_REQUIRE(scratch_file != -1); unlink(template); diff --git a/tests/sys/kern/pipe/pipe_fstat_bug_test.c b/tests/sys/kern/pipe/pipe_fstat_bug_test.c index ae0b309764bc..89060a2f0495 100644 --- a/tests/sys/kern/pipe/pipe_fstat_bug_test.c +++ b/tests/sys/kern/pipe/pipe_fstat_bug_test.c @@ -26,6 +26,7 @@ SUCH DAMAGE. #include #include #include +#include #include #include #include @@ -49,10 +50,12 @@ main(void) { char buffer[32768], buffer2[32768], go[] = "go", go2[] = "go2"; int desc[2], ipc_coord[2]; + struct kevent event, ke; ssize_t error; int successes = 0; struct stat status; pid_t new_pid; + int kq; error = pipe(desc); if (error == -1) @@ -118,9 +121,24 @@ main(void) _exit(0); } + kq = kqueue(); + if (kq == -1) + _exit(1); + + EV_SET(&ke, desc[0], EVFILT_READ, EV_ADD, 0, 0, NULL); + + /* Attach event to the kqueue. */ + if (kevent(kq, &ke, 1, NULL, 0, NULL) != 0) + _exit(2); + while (successes < 5) { SYNC_W(1, go); SYNC_R(1, go2); + + /* Ensure data is available to read */ + if (kevent(kq, NULL, 0, &event, 1, NULL) != 1) + _exit(3); + fstat(desc[0], &status); error = read(desc[0], &buffer2, sizeof(buffer2)); diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 9a7e9ab29676..c2a361084932 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1089,6 +1089,7 @@ OLD_FILES+=boot/gptzfsboot OLD_FILES+=boot/zfsboot OLD_FILES+=boot/zfsloader OLD_FILES+=etc/rc.d/zfs +OLD_FILES+=etc/rc.d/zfsbe OLD_FILES+=etc/rc.d/zvol OLD_FILES+=etc/devd/zfs.conf OLD_FILES+=etc/periodic/daily/404.status-zfs @@ -6038,6 +6039,10 @@ OLD_FILES+=usr/share/man/whatis OLD_FILES+=usr/share/openssl/man/whatis .endif +.if ${MK_MANDOCDB} != no +OLD_FILES+=usr/share/man/man1/makewhatis.1.gz +.endif + .if ${MK_NDIS} == no OLD_FILES+=usr/sbin/ndiscvt OLD_FILES+=usr/sbin/ndisgen @@ -6829,29 +6834,6 @@ OLD_FILES+=usr/share/man/man8/rshd.8.gz OLD_FILES+=usr/share/man/man8/rwhod.8.gz .endif -.if ${MK_RCS} == no -OLD_FILES+=usr/bin/ci -OLD_FILES+=usr/bin/co -OLD_FILES+=usr/bin/merge -OLD_FILES+=usr/bin/rcs -OLD_FILES+=usr/bin/rcsclean -OLD_FILES+=usr/bin/rcsdiff -OLD_FILES+=usr/bin/rcsfreeze -OLD_FILES+=usr/bin/rcsmerge -OLD_FILES+=usr/bin/rlog -OLD_FILES+=usr/share/man/man1/ci.1.gz -OLD_FILES+=usr/share/man/man1/co.1.gz -OLD_FILES+=usr/share/man/man1/merge.1.gz -OLD_FILES+=usr/share/man/man1/rcs.1.gz -OLD_FILES+=usr/share/man/man1/rcsclean.1.gz -OLD_FILES+=usr/share/man/man1/rcsdiff.1.gz -OLD_FILES+=usr/share/man/man1/rcsfreeze.1.gz -OLD_FILES+=usr/share/man/man1/rcsintro.1.gz -OLD_FILES+=usr/share/man/man1/rcsmerge.1.gz -OLD_FILES+=usr/share/man/man1/rlog.1.gz -OLD_FILES+=usr/share/man/man5/rcsfile.5.gz -.endif - #.if ${MK_RESCUE} == no # to be filled in or replaced with a special target #.endif diff --git a/tools/build/options/WITHOUT_MANDOCDB b/tools/build/options/WITHOUT_MANDOCDB index 7d7ec2148a29..11ef3345a06d 100644 --- a/tools/build/options/WITHOUT_MANDOCDB +++ b/tools/build/options/WITHOUT_MANDOCDB @@ -1,6 +1,9 @@ .\" $FreeBSD$ -Use the -.Xr mandoc 1 -version of +Use the version of +.Xr makewhatis 1 +introduced in +.Fx 2.1 , +instead of the .Xr makewhatis 8 -database and utilities. +database and utilities from +.Xr mandoc 1 . diff --git a/tools/build/options/WITH_RCS b/tools/build/options/WITH_RCS deleted file mode 100644 index 0765b995717d..000000000000 --- a/tools/build/options/WITH_RCS +++ /dev/null @@ -1,4 +0,0 @@ -.\" $FreeBSD$ -Set to build -.Xr rcs 1 -and related utilities. diff --git a/usr.bin/sdiff/Makefile b/usr.bin/sdiff/Makefile index 504adc2a663e..f4772cc3da59 100644 --- a/usr.bin/sdiff/Makefile +++ b/usr.bin/sdiff/Makefile @@ -3,7 +3,7 @@ .include PROG= sdiff -SRCS= common.c edit.c sdiff.c +SRCS= edit.c sdiff.c WARNS= 3 MAN1= sdiff.1 diff --git a/usr.bin/sdiff/common.c b/usr.bin/sdiff/common.c deleted file mode 100644 index 686965c32b99..000000000000 --- a/usr.bin/sdiff/common.c +++ /dev/null @@ -1,24 +0,0 @@ -/* $OpenBSD: common.c,v 1.4 2006/05/25 03:20:32 ray Exp $ */ - -/* - * Written by Raymond Lai . - * Public domain. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "common.h" - -void -cleanup(const char *filename) -{ - - if (unlink(filename)) - err(2, "could not delete: %s", filename); - exit(2); -} diff --git a/usr.bin/sdiff/common.h b/usr.bin/sdiff/common.h deleted file mode 100644 index 127c1f4b70f2..000000000000 --- a/usr.bin/sdiff/common.h +++ /dev/null @@ -1,9 +0,0 @@ -/* $OpenBSD: common.h,v 1.2 2006/05/25 03:20:32 ray Exp $ */ -/* $FreeBSD$ */ - -/* - * Written by Raymond Lai . - * Public domain. - */ - -void cleanup(const char *) __dead2; diff --git a/usr.bin/sdiff/edit.c b/usr.bin/sdiff/edit.c index 21f7cdc6a247..993b515c49b5 100644 --- a/usr.bin/sdiff/edit.c +++ b/usr.bin/sdiff/edit.c @@ -21,10 +21,16 @@ __FBSDID("$FreeBSD$"); #include #include -#include "common.h" #include "extern.h" -int editit(const char *); +static void +cleanup(const char *filename) +{ + + if (unlink(filename)) + err(2, "could not delete: %s", filename); + exit(2); +} /* * Execute an editor on the specified pathname, which is interpreted @@ -32,7 +38,7 @@ int editit(const char *); * * Returns -1 on error, or the exit value on success. */ -int +static int editit(const char *pathname) { sig_t sighup, sigint, sigquit, sigchld; diff --git a/usr.bin/sdiff/sdiff.c b/usr.bin/sdiff/sdiff.c index 1b122d12eee7..9a4e4ca344ec 100644 --- a/usr.bin/sdiff/sdiff.c +++ b/usr.bin/sdiff/sdiff.c @@ -27,7 +27,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include "common.h" #include "extern.h" #define DIFF_PATH "/usr/bin/diff" @@ -138,24 +137,25 @@ static struct option longopts[] = { }; static const char *help_msg[] = { - "\nusage: sdiff [-abdilstW] [-I regexp] [-o outfile] [-w width] file1 file2\n", - "\t-l, --left-column, Only print the left column for identical lines.", - "\t-o OUTFILE, --output=OUTFILE, nteractively merge file1 and file2 into outfile.", - "\t-s, --suppress-common-lines, Skip identical lines.", - "\t-w WIDTH, --width=WIDTH, Print a maximum of WIDTH characters on each line.", - "\tOptions passed to diff(1) are:", - "\t\t-a, --text, Treat file1 and file2 as text files.", - "\t\t-b, --ignore-trailing-cr, Ignore trailing blank spaces.", - "\t\t-d, --minimal, Minimize diff size.", - "\t\t-I RE, --ignore-matching-lines=RE, Ignore changes whose line matches RE.", - "\t\t-i, --ignore-case, Do a case-insensitive comparison.", - "\t\t-t, --expand-tabs Expand tabs to spaces.", - "\t\t-W, --ignore-all-spaces, Ignore all spaces.", - "\t\t--speed-large-files, Assume large file with scattered changes.", - "\t\t--strip-trailing-cr, Strip trailing carriage return.", - "\t\t--ignore-file-name-case, Ignore case of file names.", - "\t\t--no-ignore-file-name-case, Do not ignore file name case", - "\t\t--tabsize NUM, Change size of tabs (default 8.)", + "usage: sdiff [-abdilstW] [-I regexp] [-o outfile] [-w width] file1 file2\n", + "-l, --left-column: only print the left column for identical lines.", + "-o OUTFILE, --output=OUTFILE: interactively merge file1 and file2 into outfile.", + "-s, --suppress-common-lines: skip identical lines.", + "-w WIDTH, --width=WIDTH: print a maximum of WIDTH characters on each line.", + "", + "Options passed to diff(1) are:", + "\t-a, --text: treat file1 and file2 as text files.", + "\t-b, --ignore-trailing-cr: ignore trailing blank spaces.", + "\t-d, --minimal: minimize diff size.", + "\t-I RE, --ignore-matching-lines=RE: ignore changes whose line matches RE.", + "\t-i, --ignore-case: do a case-insensitive comparison.", + "\t-t, --expand-tabs: sxpand tabs to spaces.", + "\t-W, --ignore-all-spaces: ignore all spaces.", + "\t--speed-large-files: assume large file with scattered changes.", + "\t--strip-trailing-cr: strip trailing carriage return.", + "\t--ignore-file-name-case: ignore case of file names.", + "\t--no-ignore-file-name-case: do not ignore file name case", + "\t--tabsize NUM: change size of tabs (default 8.)", NULL, }; diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index 6a1e9b463ffa..855f5d35f45d 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -1924,9 +1924,9 @@ print_arg(struct syscall_args *sc, unsigned long *args, long *retval, cloudabi_filestat_t fsb; if (get_struct(pid, (void *)args[sc->offset], &fsb, sizeof(fsb)) != -1) - fprintf(fp, "{ %s, %lu }", + fprintf(fp, "{ %s, %ju }", xlookup(cloudabi_filetype, fsb.st_filetype), - fsb.st_size); + (uintmax_t)fsb.st_size); else fprintf(fp, "0x%lx", args[sc->offset]); break; diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index d9fc76a68294..1a1d0ced868c 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -123,6 +123,7 @@ SUBDIR.${MK_BSNMP}+= bsnmpd SUBDIR.${MK_CTM}+= ctm SUBDIR.${MK_DIALOG}+= tzsetup SUBDIR.${MK_DIALOG}+= bsdconfig +SUBDIR.${MK_EFI}+= efivar SUBDIR.${MK_FLOPPY}+= fdcontrol SUBDIR.${MK_FLOPPY}+= fdformat SUBDIR.${MK_FLOPPY}+= fdread diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c index 457068a0f7bd..e0698dcc0fba 100644 --- a/usr.sbin/chown/chown.c +++ b/usr.sbin/chown/chown.c @@ -159,7 +159,7 @@ main(int argc, char **argv) } else a_gid(*argv); - if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) + if ((ftsp = fts_open(++argv, fts_options, NULL)) == NULL) err(1, NULL); for (rval = 0; (p = fts_read(ftsp)) != NULL;) { diff --git a/usr.sbin/ctladm/ctladm.8 b/usr.sbin/ctladm/ctladm.8 index f034240f1893..1271ed2283d6 100644 --- a/usr.sbin/ctladm/ctladm.8 +++ b/usr.sbin/ctladm/ctladm.8 @@ -35,7 +35,7 @@ .\" $Id: //depot/users/kenm/FreeBSD-test2/usr.sbin/ctladm/ctladm.8#3 $ .\" $FreeBSD$ .\" -.Dd September 26, 2015 +.Dd October 15, 2016 .Dt CTLADM 8 .Os .Sh NAME @@ -903,8 +903,21 @@ Specifies medium rotation rate of the device: 0 -- not reported, .It Va formfactor Specifies nominal form factor of the device: 0 -- not reported, 1 -- 5.25", 2 -- 3.5", 3 -- 2.5", 4 -- 1.8", 5 -- less then 1.8". +.It Va provisioning_type +When UNMAP support is enabled, this option specifies provisioning type: +"resource", "thin" or "unknown". +Default value is "thin". +Logical units without UNMAP support are reported as fully provisioned. .It Va unmap -Set to "on", enables UNMAP support for the LUN, if supported by the backend. +Setting to "on" or "off" controls UNMAP support for the logical unit. +Default value is "on" if supported by the backend. +.It Va unmap_max_lba +.It Va unmap_max_descr +Specify maximum allowed number of LBAs and block descriptors per UNMAP +command to report in Block Limits VPD page. +.It Va write_same_max_lba +Specify maximum allowed number of LBAs per WRITE SAME command to report +in Block Limits VPD page. .It Va avail-threshold .It Va used-threshold .It Va pool-avail-threshold diff --git a/usr.sbin/efivar/Makefile b/usr.sbin/efivar/Makefile new file mode 100644 index 000000000000..9a7ac90c820c --- /dev/null +++ b/usr.sbin/efivar/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= efivar +MAN= efivar.8 + +LIBADD= efivar + +.include diff --git a/usr.sbin/efivar/efivar.8 b/usr.sbin/efivar/efivar.8 new file mode 100644 index 000000000000..dccdea66ccee --- /dev/null +++ b/usr.sbin/efivar/efivar.8 @@ -0,0 +1,164 @@ +.\" Copyright (c) 2003 Netflix, Inc +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 29, 2016 +.Dt EFIVAR 8 +.Os +.Sh NAME +.Nm efivar +.Nd UEFI environemnt variable interaction +.Sh SYNOPSIS +.Nm +.Op Fl abdDHlLNpRtw +.Op Fl n Ar name +.Op Fl f Ar file +.Op Fl -append +.Op Fl -ascii +.Op Fl -attributes +.Op Fl -binary +.Op Fl -delete +.Op Fl -fromfile Ar file +.Op Fl -hex +.Op Fl -list-guids +.Op Fl -list +.Op Fl -name Ar name +.Op Fl -no-name +.Op Fl -print +.Op Fl -print-decimal +.Op Fl -raw-guid +.Op Fl -write +.Ar name Ns Op = Ns Ar value +.Sh DESCRIPTION +This program manages +.Dq Unified Extensible Firmware Interface +.Pq UEFI +environment variables. +UEFI variables have three part: A namespace, a name and a value. +The namespace is a GUID that's self assigned by the group defining the +variables. +The name is a Unicode name for the variable. +The value is binary data. +All Unicode data is presented to the user as UTF-8. +.Pp +The following options are available: +.Bl -tag -width 20m +.It Fl n Ar name Fl -name Ar name +Specify the name of the variable to operate on. +The +.Ar name +argument is the GUID of variable, followed by a dash, followed by the +UEFI variable name. +The GUID may be in numeric format, or may be one of the well known +symbolic name (see +.Fl -list-guids +for a complete list). +.It Fl f Ar file Fl -fromfile Ar file +When writing or appending to a variable, take the data for the +variable's value from +.Ar file +instead of from the command line. +This flag implies +.Fl -write +unless the +.Fl -append +flag is given. +This is not well understood and currently unimplemented. +.It Fl a Fl -append +Append the specified value to the UEFI variable rather than replacing +it.p +.It Fl t Ar attr Fl -attributes Ar attr +Specify, in user hostile hexidecimal, the attributes for this +variable. +See section 7.2 (GetVariable subsection, Related Definitions) of the +UEFI Specification for hex values to use. +.It Fl A Fl -ascii +Display the variable data as modified ascii: All printable characters +are printed, while unprintable characters are rendered as a two-digit +hexadecimal number preceeded by a % character. +.It Fl b Fl -binary +Display the variable data as binary data. +Usually will be used with the +.Fl N +or +.Fl -no-name +flag. +Useful in scripts. +.It Fl D Fl -delete +Delete the specified variable. +May not be used with either the +.Fl -write +or the +.Fl -append +flags. +No +.Ar value +may be specified. +.It Fl H Fl -hex +List variable data as a hex dump. +.It Fl L Fl -list-guids +Lists the well known GUIDs. +The names listed here may be used in place of the numeric GUID values. +These names will replace the numeric GUID values unless +.Fl -raw-guid +flag is specified. +.It Fl l Fl -list +List all the variables. +If the +.Fl -print +flag is also listed, their values will be displayed. +.It Fl N Fl -no-name +Do not display the variable name. +.It Fl p Fl -print +Print the value of the variable. +.It Fl d Fl -print-decimal +Treat the value of the variable as a number and print it as a +decimal. +This is currently unimplemented. +.It Fl R Fl -raw-guid +Do not substitute well known names for GUID numeric values in output. +.It Fl w Fl -write +Write (replace) the variable specified with the value specified. +.It Ar name +Display the +.Ar name +environment variable. +.It Ar name Ns = Ns Ar value +Set the specified +.Ar name +to +.Ar value . +This is not yet implemented. +.Sh COMPATIBILITY +The +.Nm +program is intended to be compatible (strict superset) with a progam +of the same name included in the Red Hat libefivar package. +.Sh SEE ALSO +Appendix A of the UEFI specification has the format for GUIDs. +All GUIDs +.Dq Globally Unique Identifiers +have the format described in RFC 4122. +.El diff --git a/usr.sbin/efivar/efivar.c b/usr.sbin/efivar/efivar.c new file mode 100644 index 000000000000..a4dac498d680 --- /dev/null +++ b/usr.sbin/efivar/efivar.c @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2016 Netflix, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* options descriptor */ +static struct option longopts[] = { + { "append", no_argument, NULL, 'a' }, + { "ascii", no_argument, NULL, 'A' }, + { "attributes", required_argument, NULL, 't' }, + { "binary", no_argument, NULL, 'b' }, + { "delete", no_argument, NULL, 'D' }, + { "fromfile", required_argument, NULL, 'f' }, + { "hex", no_argument, NULL, 'H' }, + { "list-guids", no_argument, NULL, 'L' }, + { "list", no_argument, NULL, 'l' }, + { "name", required_argument, NULL, 'n' }, + { "no-name", no_argument, NULL, 'N' }, + { "print", no_argument, NULL, 'p' }, + { "print-decimal", no_argument, NULL, 'd' }, + { "raw-guid", no_argument, NULL, 'R' }, + { "write", no_argument, NULL, 'w' }, + { NULL, 0, NULL, 0 } +}; + + +static int aflag, Aflag, bflag, dflag, Dflag, Hflag, Nflag, + lflag, Lflag, Rflag, wflag, pflag; +static char *varname; +static u_long attrib = EFI_VARIABLE_NON_VOLATILE |EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + +static void +usage(void) +{ + + errx(1, "efivar [-abdDHlLNpRtw] [-n name] [-f file] [--append] [--ascii]\n" + "\t[--attributes] [--binary] [--delete] [--fromfile file] [--hex]\n" + "\t[--list-guids] [--list] [--name name] [--no-name] [--print]\n" + "\t[--print-decimal] [--raw-guid] [--write] name[=value]"); +} + +static void +breakdown_name(char *name, efi_guid_t *guid, char **vname) +{ + char *cp; + + cp = strrchr(name, '-'); + if (cp == NULL) + errx(1, "Invalid name: %s", name); + *vname = cp + 1; + *cp = '\0'; + if (efi_str_to_guid(name, guid) < 0) + errx(1, "Invalid guid %s", name); +} + +static uint8_t * +get_value(char *val, size_t *datalen) +{ + static char buffer[16*1024]; + + if (val != NULL) { + *datalen = strlen(val); + return ((uint8_t *)val); + } + /* Read from stdin */ + *datalen = sizeof(buffer); + *datalen = read(0, buffer, *datalen); + return ((uint8_t *)buffer); +} + +static void +append_variable(char *name, char *val) +{ + char *vname; + efi_guid_t guid; + size_t datalen; + uint8_t *data; + + breakdown_name(name, &guid, &vname); + data = get_value(val, &datalen); + if (efi_append_variable(guid, vname, data, datalen, attrib) < 0) + err(1, "efi_append_variable"); +} + +static void +delete_variable(char *name) +{ + char *vname; + efi_guid_t guid; + + breakdown_name(name, &guid, &vname); + if (efi_del_variable(guid, vname) < 0) + err(1, "efi_del_variable"); +} + +static void +write_variable(char *name, char *val) +{ + char *vname; + efi_guid_t guid; + size_t datalen; + uint8_t *data; + + breakdown_name(name, &guid, &vname); + data = get_value(val, &datalen); + if (efi_set_variable(guid, vname, data, datalen, attrib, 0) < 0) + err(1, "efi_set_variable"); +} + +static void +asciidump(uint8_t *data, size_t datalen) +{ + size_t i; + int len; + + len = 0; + if (!Nflag) + printf("\n"); + for (i = 0; i < datalen; i++) { + if (isprint(data[i])) { + len++; + if (len > 80) { + len = 0; + printf("\n"); + } + printf("%c", data[i]); + } else { + len +=3; + if (len > 80) { + len = 0; + printf("\n"); + } + printf("%%%02x", data[i]); + } + } + printf("\n"); +} + +static void +hexdump(uint8_t *data, size_t datalen) +{ + size_t i; + + if (!Nflag) + printf("\n"); + for (i = 0; i < datalen; i++) { + if (i % 16 == 0) { + if (i != 0) + printf("\n"); + printf("%04x: ", (int)i); + } + printf("%02x ", data[i]); + } + printf("\n"); +} + +static void +bindump(uint8_t *data, size_t datalen) +{ + write(1, data, datalen); +} + +static void +print_var(efi_guid_t *guid, char *name) +{ + uint32_t att; + uint8_t *data; + size_t datalen; + char *gname; + int rv; + + efi_guid_to_str(guid, &gname); + if (!Nflag) + printf("%s-%s", gname, name); + if (pflag) { + rv = efi_get_variable(*guid, name, &data, &datalen, &att); + + if (rv < 0) + printf("\n --- Error getting value --- %d", errno); + else { + if (Aflag) + asciidump(data, datalen); + else if (bflag) + bindump(data, datalen); + else + hexdump(data, datalen); + } + } + free(gname); + if (!Nflag) + printf("\n"); +} + +static void +print_variable(char *name) +{ + char *vname; + efi_guid_t guid; + + breakdown_name(name, &guid, &vname); + print_var(&guid, vname); +} + +static void +print_variables(void) +{ + int rv; + char *name = NULL; + efi_guid_t *guid = NULL; + + while ((rv = efi_get_next_variable_name(&guid, &name)) > 0) + print_var(guid, name); + + if (rv < 0) + err(1, "Error listing names"); +} + +static void +parse_args(int argc, char **argv) +{ + int ch, i; + + while ((ch = getopt_long(argc, argv, "aAbdDf:HlLNn:pRt:w", + longopts, NULL)) != -1) { + switch (ch) { + case 'a': + aflag++; + break; + case 'A': + Aflag++; + break; + case 'b': + bflag++; + break; + case 'd': + dflag++; + break; + case 'D': + Dflag++; + break; + case 'H': + Hflag++; + break; + case 'l': + lflag++; + break; + case 'L': + Lflag++; + break; + case 'n': + varname = optarg; + break; + case 'N': + Nflag++; + break; + case 'p': + pflag++; + break; + case 'R': + Rflag++; + break; + case 't': + attrib = strtoul(optarg, NULL, 16); + break; + case 'w': + wflag++; + break; + case 'f': + case 0: + errx(1, "unknown or unimplemented option\n"); + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc == 1) + varname = argv[0]; + + if (aflag + Dflag + wflag > 1) { + warnx("Can only use one of -a (--append), " + "-D (--delete) and -w (--write)"); + usage(); + } + + if (aflag + Dflag + wflag > 0 && varname == NULL) { + warnx("Must specify a variable for -a (--append), " + "-D (--delete) or -w (--write)"); + usage(); + } + + if (aflag) + append_variable(varname, NULL); + else if (Dflag) + delete_variable(varname); + else if (wflag) + write_variable(varname, NULL); + else if (varname) { + pflag++; + print_variable(varname); + } else if (argc > 0) { + pflag++; + for (i = 0; i < argc; i++) + print_variable(argv[i]); + } else + print_variables(); +} + +int +main(int argc, char **argv) +{ + + parse_args(argc, argv); +} diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index 9537c3214690..dcc275fcd7b1 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -953,7 +953,7 @@ fetch_pick_server_init () { # "$name server selection ..."; we allow either format. MLIST="_http._tcp.${SERVERNAME}" host -t srv "${MLIST}" | - sed -nE "s/${MLIST} (has SRV record|server selection) //p" | + sed -nE "s/${MLIST} (has SRV record|server selection) //Ip" | cut -f 1,2,4 -d ' ' | sed -e 's/\.$//' | sort > serverlist_full