From owner-freebsd-hackers@FreeBSD.ORG Mon Jun 25 02:28:00 2007 Return-Path: X-Original-To: freebsd-hackers@freebsd.org Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8138316A400 for ; Mon, 25 Jun 2007 02:28:00 +0000 (UTC) (envelope-from angus@aggyb.org) Received: from aggyb.org (87-194-8-28.bethere.co.uk [87.194.8.28]) by mx1.freebsd.org (Postfix) with ESMTP id EB75D13C43E for ; Mon, 25 Jun 2007 02:27:59 +0000 (UTC) (envelope-from angus@aggyb.org) Received: from localhost (localhost.org [127.0.0.1]) by aggyb.org (Postfix) with ESMTP id 21E3D3D183D for ; Mon, 25 Jun 2007 03:31:06 +0100 (BST) X-Virus-Scanned: amavisd-new at aggyb.org Received: from aggyb.org ([127.0.0.1]) by localhost (aggyb.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KWGZuv+aHlsI for ; Mon, 25 Jun 2007 03:31:00 +0100 (BST) Received: from [192.168.1.10] (agb.studnet [192.168.1.10]) by aggyb.org (Postfix) with ESMTP id 38D9A3D1835 for ; Mon, 25 Jun 2007 03:31:00 +0100 (BST) Message-ID: <467F2411.7070709@aggyb.org> Date: Mon, 25 Jun 2007 03:10:25 +0100 From: Angus Barrow User-Agent: Thunderbird 2.0.0.4 (Windows/20070604) MIME-Version: 1.0 To: freebsd-hackers@freebsd.org Content-Type: multipart/mixed; boundary="------------020502060506000100030004" Subject: libelf question X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 25 Jun 2007 02:28:00 -0000 This is a multi-part message in MIME format. --------------020502060506000100030004 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi there, I'm trying to develop a BSD licensed version of the ar utility using the new libelf library as this seems to be listed on the project ideas page but doesn't seem to be being worked on. I've started off simply trying to get a toc printed for the archive but for some reason the time-stamp seems to be coming back wrong for the contents of the archives. The code in question uses libelf to fetch a struct for each entry in an archive and it prints out the data as a table: ... Elf_Arhdr *arh; while ((object = elf_begin(fd, ELF_C_READ, archive)) != NULL) { if ((arh = elf_getarhdr(object)) == NULL) errx(EX_SOFTWARE, "elf_getarhdr() failed: %s.", elf_errmsg(-1)); ... char timestring[20]; time_t timet=arh->ar_date; strftime(timestring, sizeof(timestring), "%b %e %H:%M %Y", gmtime(&timet)); The time shown in arh->ar_date (this is the struct that the libelf library provides for each entry in the ar archive) seems to have a negative value (using the GNU ar the date is Jun 3 13:09 2007, I've loaded the program in gdb also and this seems to suggest the problem is with the library: 30 time_t timet=arh->ar_date; (gdb) n 31 strftime(timestring, sizeof(timestring), "%b %e %H:%M %Y", gmtime(&timet)); (gdb) n ... (gdb) print timet $1 = -1515870811 (gdb) print timestring $2 = "Dec 19 04:46 1921\000\000" My question is, should I log a PR about this or is there something obvious that I'm doing wrong here. I'm totally new to writing anything serious in C as all my uni courses use Java and VB.net etc. Please find the program attached in full. Thanks for any advice. Angus Barrow --------------020502060506000100030004 Content-Type: text/plain; name="print.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="print.c" #include #include #include #include #include #include void prettyMode(int, char*); int printToc(int fd, Elf *archive, int argc, char *argv, int VERBOSE_FLAG) { Elf *object; printf("(DBG)\tprint.c:printToc(Elf, char) - argc=%d verb=%d\n",argc, VERBOSE_FLAG); Elf_Kind type = elf_kind(archive); if(type!=ELF_K_AR) errx(EX_DATAERR, "Type of object is not ELF_K_AR\n"); Elf_Arhdr *arh; while ((object = elf_begin(fd, ELF_C_READ, archive)) != NULL) { if ((arh = elf_getarhdr(object)) == NULL) errx(EX_SOFTWARE, "elf_getarhdr() failed: %s.", elf_errmsg(-1)); if(VERBOSE_FLAG!=1) { printf("%s\n", arh->ar_name); } else { char timestring[20]; time_t timet=arh->ar_date; strftime(timestring, sizeof(timestring), "%b %e %H:%M %Y", gmtime(&timet)); char perms[10]="---------\0"; prettyMode(arh->ar_mode, perms); printf("%s %u/%u %8u %s %s\n", perms, arh->ar_uid, arh->ar_gid, arh->ar_size, timestring, arh->ar_name); } elf_next(object); elf_end(object); } elf_end(archive); return 0; } void prettyMode(int mode, char *string) { /* There must be a better way or a library for this!*/ if(strlen(string)<9) { printf("Urgh, that is not good!\nGive me a longer array!"); return; } if((mode & 0400)==0400) string[0]='r'; if((mode & 0200)==0200) string[1]='w'; if((mode & 0100)==0100) string[2]='x'; if((mode & 040)==040) string[3]='r'; if((mode & 020)==020) string[4]='w'; if((mode & 010)==010) string[5]='x'; if((mode & 04)==04) string[6]='r'; if((mode & 02)==02) string[7]='w'; if((mode & 01)==01) string[8]='x'; } --------------020502060506000100030004 Content-Type: text/plain; name="ar.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ar.c" /*- * Copyright (c) 2007 Angus Barrow * 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 unmodified, 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. */ #include #include #include #include #include #include #include #include static int VERBOSE_FLAG; int tflag; /* * This is a BSD licenced attempt at the ar program as in POSIX 1003.1. * It makes use of the Elf and GElf API's in FreeBSD 7-CURRENT. */ int main(int argc, char *argv[]) { int ch; /* Decide how we've been invoked and try to decide what to do! */ VERBOSE_FLAG=-1; while ((ch = getopt(argc, argv, "htv")) != -1) switch (ch) { case 't': tflag = 1; break; case 'v': VERBOSE_FLAG=1; printf("(DBG)\tVerbose flag set\n"); break; case 'h': printf("(DBG)\tDisplay help\n"); /* FLOWS THROUGH */ default: usage(); /* NOTREACHED */ } argc-=optind; argv+=optind; printf("(DBG)\tFile to open is: %s\n", *argv); /* Open file */ int fd; if ((fd = open(*argv, O_RDONLY, 0)) < 0) err(EX_NOINPUT, "open \%s\" failed", *argv); /* Open library */ if (elf_version(EV_CURRENT) == EV_NONE) errx(EX_SOFTWARE, "ELF library initialization failed: %s", elf_errmsg(-1)); /* Open elf object/archive */ Elf *elf; if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1)); if(tflag==1) { printToc(fd, elf, argc, argv, VERBOSE_FLAG); } close(fd); return 0; } int usage() { printf("Options are:\nh\t-\tDisplay this help!\nt\t-\tDisplay TOC\nv\t-\tEnable verbose mode\n"); exit(0); } --------------020502060506000100030004--