From owner-freebsd-stable Mon Feb 24 11:57:00 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id LAA12480 for stable-outgoing; Mon, 24 Feb 1997 11:57:00 -0800 (PST) Received: from infowest.com (infowest.com [204.17.177.10]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id LAA12473 for ; Mon, 24 Feb 1997 11:56:58 -0800 (PST) Received: from orchestra (Garibaldi.infowest.com [204.17.177.119]) by infowest.com (8.8.5/8.8.5) with SMTP id MAA07551 for ; Mon, 24 Feb 1997 12:57:15 -0700 (MST) Message-Id: <3.0.1.32.19970224125654.00d5f0a0@infowest.com> X-Sender: agifford@infowest.com X-Mailer: Windows Eudora Light Version 3.0.1 beta 12 (32) Date: Mon, 24 Feb 1997 12:56:54 -0700 To: freebsd-stable@freebsd.org From: "Aaron D. Gifford" Subject: 2.1.7 and Tripwire ftruncate() fun (MORE INFO) Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Sender: owner-stable@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi, First the questions: Is anyone successfully running Tripwire on FreeBSD 2.1.7? If so, how did you overcome the problem with ftruncate()? Is the problem with ftruncate() in Tripwire an OS bug? Is it a compiler bug? Now for the background: I downloaded Tripwire 1.2 from ftp://coast.cs.purdue.edu/pub/Purdue/Tripwire/tripwire-1.2.tar.Z and compiled it. I followed the instructions in the README file included in the tarball and the compile and install went smoothly. I then created my own custom config file for tripwire. Last, I ran tripwire to create the initial database. Here's what happened: bash# ./tripwire -initialize ### Phase 1: Reading configuration file ### Phase 2: Generating file list ### Phase 3: Creating file information database truncate(): Invalid argument bash# I then went back to the source files for tripwire and grep'd for truncate. I found the only occurence was a call to "ftruncate()" in the file "dbase.build.c" in the subroutine "database_record_write()" and nowhere else. Looking at the code some more, I noticed that the file which was to be truncated with ftruncate() was opened the very first time database_record_write() was called by a call to fd_tempfilename_generate() in utils.c, a subroutine that opens a temporary file for reading and writing in /tmp then unlinks it and returns the file descriptor number to the caller. Just so I could see what was happening, I commented out the "unlink()" call in fd_tempfilename_generate() in utils.c so that the temporary file would stick around. In database_record_write() in dbase.build.c I then added some code around the call to ftruncate: /* Added code begins: */ fprintf(stderr, "fdsymlink = %d\n", fdsymlink); if ((err = write(fdsymlink, "Before...\n", 10)) != 10) { fprintf(stderr, "BEFORE: write() returned %d\n", err); } else { fprintf(stderr, "BEFORE: write() succeeded!\n"); } /* End of first chunk of added code */ /* The line below was altered. The original line WAS: if (ftruncate(fdsymlink, 0) < 0) { */ if ((err=ftruncate(fdsymlink, 0)) < 0) { /* More added code below: */ fprintf(stderr, "ftruncate() failed, returning %d -- fdsymlink=%d " "and errno=%d \"%s\"\n", err, fdsymlink, errno, strerror(errno)); if ((err = write(fdsymlink, "After...\n", 9)) != 9) { fprintf(stderr, "AFTER: write() returned %d\n", err); } else { fprintf(stderr, "AFTER: write() succeeded!\n"); } /* End of added code chunk #2 */ die_with_err("truncate()", NULL); } After adding the stuff above I recompiled and this is what I saw: bash# ./tripwire -initialize ### Phase 1: Reading configuration file ### Phase 2: Generating file list ### Phase 3: Creating file information database BEFORE: write() succeeded! ftruncate() failed, returning -1 -- fdsymlink=4 and errno=22 "Invalid argument" AFTER: write() succeeded! truncate(): Invalid argument bash# ls -l /tmp total 2 -rw------- 1 root bin 19 Feb 24 12:42 twz006363 bash# cat /tmp/twz006363 Before... After... bash# I must say I was (and I still am) very puzzled. A quick 'man errno' informed me: 22 EINVAL Invalid argument. Some invalid argument was supplied. (For ex- ample, specifying an undefined signal to a signal or kill func- tion). Then a quick 'man ftruncate' returned: Ftruncate() succeeds unless: [EBADF] The fd is not a valid descriptor. [EINVAL] The fd references a socket, not a file. [EINVAL] The fd is not open for writing. >From my test code and from looking at the tripwire source, the fd is a FILE (not a socket) and is open for WRITING, so why is ftruncate() returning EINVAL? I cannot understand it. From looking at the contents of the temp file after my code additions, I see that when the ftruncate() call occurs, the temp file is length 10 (from the "Before...\n"), the call failes with EINVAL then the very same file descriptor is successfully written to again ("After...\n"). So, what's going on? The tripwire source looks like it SHOULD work. Any ideas? I searched the archive at freebsd.org for "tripwire" and "truncate" and saw a few messages from about a year ago. Unfortunately, none of the messages was of any use (most just reported the bug). Thanks in advance for any and all information. I would really like to get tripwire working. Puzzled, Aaron Gifford