home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume36 / libtouch / part01 < prev    next >
Encoding:
Text File  |  1993-04-18  |  13.1 KB  |  434 lines

  1. Newsgroups: comp.sources.misc
  2. From: chris@sparky.sterling.com (Chris Olson)
  3. Subject: v36i112:  libtouch - Make utility to touch archive elements, Part01/01
  4. Message-ID: <1993Apr19.033100.13988@sparky.imd.sterling.com>
  5. X-Md4-Signature: bc85f95e64762cc8735fc2933d41bcc0
  6. Date: Mon, 19 Apr 1993 03:31:00 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: chris@sparky.sterling.com (Chris Olson)
  10. Posting-number: Volume 36, Issue 112
  11. Archive-name: libtouch/part01
  12. Environment: UNIX
  13.  
  14. Why libtouch?  It helps to shorten make times and removes the need to
  15. have .o's and timestamp files lying around.  A personal pet peeve.
  16. A large archive (256 objects) could have an object deleted out of it
  17. in 10 secs, this gem updates the date of the file (accomplishing the
  18. same thing (see makefile)) in less than 3.
  19.  
  20. A portable makefile which takes advantage of libtouch to put off the
  21. archive step until just before the end:
  22.  
  23. LibFullName = lib$(LibName).a
  24. LibPath = ../lib
  25. LibFullPath = $(LibPath)/$(LibFullName)
  26.  
  27. .c.a:
  28.     $(CC) -c $(CFLAGS) $(CPPFLAGS) $<
  29.     libtouch $(LibFullName) $%
  30.  
  31. LibName = sample
  32. .PRECIOUS: $(LibFullPath)
  33.  
  34. ALL: $(LibFullPath)
  35.  
  36. LibObjects = sample1.o sample2.o sample3.o sample4.o sample5.o\
  37.     sample6.o
  38.  
  39. $(LibFullPath): $(LibFullPath)(sample1.o)\
  40.     $(LibFullPath)(sample2.o)\
  41.     $(LibFullPath)(sample3.o)\
  42.     $(LibFullPath)(sample4.o)\
  43.     $(LibFullPath)(sample5.o)
  44.     ar ruv $@ `ls $(LibObjects) 2>/dev/null`
  45.     rm -f $(LibObjects)
  46.     ranlib $@
  47.  
  48. depend:
  49.       makedepend $(CFLAGS) -fGNUmakefile -- *.c
  50.       fixdepend -l$(UnLibFullPath) -fGNUmakefile $(LibObjects)
  51. -----------8<----------------8<----------------8<----------------------
  52. #! /bin/sh
  53. # This is a shell archive.  Remove anything before this line, then feed it
  54. # into a shell via "sh file" or similar.  To overwrite existing files,
  55. # type "sh file -c".
  56. # Contents:  README Makefile libtouch.c libtouch.l
  57. # Wrapped by kent@sparky on Sun Apr 18 22:27:47 1993
  58. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  59. echo If this archive is complete, you will see the following message:
  60. echo '          "shar: End of archive 1 (of 1)."'
  61. if test -f 'README' -a "${1}" != "-c" ; then 
  62.   echo shar: Will not clobber existing file \"'README'\"
  63. else
  64.   echo shar: Extracting \"'README'\" \(1070 characters\)
  65.   sed "s/^X//" >'README' <<'END_OF_FILE'
  66. XWhy libtouch?  It helps to shorten make times and removes the need to
  67. Xhave .o's and timestamp files lying around.  A personal pet peeve.
  68. XA large archive (256 objects) could have an object deleted out of it
  69. Xin 10 secs, this gem updates the date of the file (accomplishing the
  70. Xsame thing (see makefile)) in less than 3.
  71. X
  72. XA portable makefile which takes advantage of libtouch to put off the
  73. Xarchive step until just before the end:
  74. X
  75. XLibFullName = lib$(LibName).a
  76. XLibPath = ../lib
  77. XLibFullPath = $(LibPath)/$(LibFullName)
  78. X
  79. X.c.a:
  80. X    $(CC) -c $(CFLAGS) $(CPPFLAGS) $<
  81. X    libtouch $(LibFullName) $%
  82. X
  83. XLibName = sample
  84. X.PRECIOUS: $(LibFullPath)
  85. X
  86. XALL: $(LibFullPath)
  87. X
  88. XLibObjects = sample1.o sample2.o sample3.o sample4.o sample5.o\
  89. X    sample6.o
  90. X
  91. X$(LibFullPath): $(LibFullPath)(sample1.o)\
  92. X    $(LibFullPath)(sample2.o)\
  93. X    $(LibFullPath)(sample3.o)\
  94. X    $(LibFullPath)(sample4.o)\
  95. X    $(LibFullPath)(sample5.o)
  96. X    ar ruv $@ `ls $(LibObjects) 2>/dev/null`
  97. X    rm -f $(LibObjects)
  98. X    ranlib $@
  99. X
  100. Xdepend:
  101. X      makedepend $(CFLAGS) -fGNUmakefile -- *.c
  102. X      fixdepend -l$(UnLibFullPath) -fGNUmakefile $(LibObjects)
  103. END_OF_FILE
  104.   if test 1070 -ne `wc -c <'README'`; then
  105.     echo shar: \"'README'\" unpacked with wrong size!
  106.   fi
  107.   # end of 'README'
  108. fi
  109. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  110.   echo shar: Will not clobber existing file \"'Makefile'\"
  111. else
  112.   echo shar: Extracting \"'Makefile'\" \(519 characters\)
  113.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  114. X#
  115. X#  Copyright 1993 by Chris Olson
  116. X#
  117. X#  Permision is hereby granted to copy, distribute, or otherwise use any
  118. X#  part of this package as long as you do not try to make money from it or
  119. X#  pretend that you wrote it.  This copyright notice must be maintained in
  120. X#  any copy made.
  121. X#
  122. XCC=gcc
  123. XCFLAGS=-O -pipe
  124. XBINDIR=/usr/local/bin
  125. XMANDIR=/usr/local/man
  126. X
  127. Xlibtouch: libtouch.o
  128. X    $(CC) -o libtouch libtouch.o
  129. X
  130. Xinstall:
  131. X    cp libtouch $(BINDIR)
  132. X    chmod 755 $(BINDIR)/libtouch
  133. X    cp libtouch.l $(MANDIR)
  134. X    chmod 444 $(MANDIR)/libtouch.l
  135. END_OF_FILE
  136.   if test 519 -ne `wc -c <'Makefile'`; then
  137.     echo shar: \"'Makefile'\" unpacked with wrong size!
  138.   fi
  139.   # end of 'Makefile'
  140. fi
  141. if test -f 'libtouch.c' -a "${1}" != "-c" ; then 
  142.   echo shar: Will not clobber existing file \"'libtouch.c'\"
  143. else
  144.   echo shar: Extracting \"'libtouch.c'\" \(5966 characters\)
  145.   sed "s/^X//" >'libtouch.c' <<'END_OF_FILE'
  146. X/*
  147. X *  libtouch.c - Update just the datestamp of an archive for the files
  148. X *         requested.  It's faster than any other way of updating the
  149. X *         archive I've been able to find.
  150. X *
  151. X *  Chris Olson
  152. X *  v1.0
  153. X *  92/02/20
  154. X *
  155. X *  Copyright 1993 by Chris Olson
  156. X *
  157. X *  Permision is hereby granted to copy, distribute, or otherwise use any
  158. X *  part of this package as long as you do not try to make money from it or
  159. X *  pretend that you wrote it.  This copyright notice must be maintained in
  160. X *  any copy made.
  161. X *
  162. X *
  163. X *  Why libtouch?  It helps to shorten make times and removes the need to
  164. X *  have .o's and timestamp files lying around.     A personal pet peeve.
  165. X *  A large archive (256 objects) could have an object deleted out of it
  166. X *  in 10 secs, this gem updates the date of the file (accomplishing the
  167. X *  same thing (see makefile)) in less than 3.
  168. X *
  169. X *  A portable makefile which takes advantage of libtouch to put off the
  170. X *  archive step until just before the end:
  171. X *
  172. X *  LibFullName = lib$(LibName).a
  173. X *  LibPath = ../lib
  174. X *  LibFullPath = $(LibPath)/$(LibFullName)
  175. X *
  176. X *  .c.a:
  177. X *        $(CC) -c $(CFLAGS) $(CPPFLAGS) $<
  178. X *        libtouch $(LibFullName) $%
  179. X *
  180. X *  LibName = sample
  181. X *  .PRECIOUS: $(LibFullPath)
  182. X *
  183. X *  ALL: $(LibFullPath)
  184. X *
  185. X *  LibObjects = sample1.o sample2.o sample3.o sample4.o sample5.o\
  186. X *        sample6.o
  187. X *
  188. X *  $(LibFullPath): $(LibFullPath)(sample1.o)\
  189. X *        $(LibFullPath)(sample2.o)\
  190. X *        $(LibFullPath)(sample3.o)\
  191. X *        $(LibFullPath)(sample4.o)\
  192. X *        $(LibFullPath)(sample5.o)
  193. X *        ar ruv $@ `ls $(LibObjects) 2>/dev/null`
  194. X *        rm -f $(LibObjects)
  195. X *        ranlib $@
  196. X *
  197. X *  depend:
  198. X *      makedepend $(CFLAGS) -fGNUmakefile -- *.c
  199. X *      fixdepend -l$(UnLibFullPath) -fGNUmakefile $(LibObjects)
  200. X */
  201. X
  202. X#include <stdio.h>
  203. X#include <ar.h>
  204. X#include <varargs.h>
  205. X#include <errno.h>
  206. X
  207. Xextern int errno;
  208. X
  209. X/*
  210. X *  Global variables used to keep track of the archive.
  211. X */
  212. Xstatic FILE *Archive;              /* Handle used to access the archive. */
  213. Xstatic char *Archive_name;          /* Name of the archive.            */
  214. Xstatic unsigned long ArchiveDate;     /* Date stamp of the archive.        */
  215. Xstatic struct ar_hdr Archive_header;  /* Archive entry header.            */
  216. Xstatic unsigned long Archive_pos;     /* Location of current header.        */
  217. X
  218. X/* The max length of an archive member name (Is this defined somewhere?) */
  219. X#define MAX_MEMBER_NAME 15
  220. X
  221. X/*
  222. X *  Simple error handling routine.
  223. X */
  224. Xstatic void error (va_alist)
  225. X   va_dcl
  226. X{
  227. X   char *format;  /* Format string to print from.          */
  228. X   va_list ptr;      /* Used to step through the function arguments. */
  229. X
  230. X   va_start(ptr);
  231. X   format = va_arg(ptr, char *);
  232. X   vfprintf(stderr, format, ptr);
  233. X   va_end(ptr);
  234. X   if (Archive)
  235. X      fclose(Archive);
  236. X   exit(-1);
  237. X} /* error */
  238. X
  239. X/*
  240. X *  Open the archive and check for integrety.
  241. X */
  242. Xstatic void open_archive (archive_name)
  243. X   char *archive_name;    /* Name of the archive. */
  244. X{
  245. X   char magic[SARMAG];    /* Archive magic number storage. */
  246. X
  247. X   if ((Archive = fopen(archive_name, "r+")) == NULL) {
  248. X      if (errno == EACCES ||
  249. X      errno == EISDIR ||
  250. X      errno == EROFS ||
  251. X      errno == ELOOP ||
  252. X      errno == ENAMETOOLONG ||
  253. X      errno == EPERM) {
  254. X     /*
  255. X      *  It is an error not to be allowed to open the archive...
  256. X      */
  257. X     error("Unable to open archive, permision denied.\n");
  258. X      }
  259. X      /*
  260. X       *  It's not really an error not to find the archive...
  261. X       */
  262. X      fprintf(stderr, "Archive file is missing.\n");
  263. X      exit(0);
  264. X   }
  265. X   if (fread(magic, SARMAG, 1, Archive) != 1)
  266. X      error("Unable to read magic number for '%s'\n", archive_name);
  267. X   if (strncmp(magic, ARMAG, SARMAG))
  268. X      error("'%s' is not in archive format.\n", archive_name);
  269. X   Archive_name = archive_name;
  270. X} /* archive_name */
  271. X
  272. X/*
  273. X *  Read in the archive record header and check it's integrety.
  274. X */
  275. Xstatic int read_header ()
  276. X{
  277. X   Archive_pos = ftell(Archive);
  278. X   if (fread(&Archive_header, sizeof(struct ar_hdr), 1, Archive) != 1) {
  279. X      fclose(Archive);
  280. X      exit(0);
  281. X   }
  282. X   if (strncmp(Archive_header.ar_fmag, ARFMAG, 2))
  283. X      error("Error in archive member format.\n");
  284. X} /* read_header */
  285. X
  286. X/*
  287. X *  Skip over the body of the current archive record, rememeber to make sure
  288. X *  we stay aligned on an even boundary!
  289. X */
  290. Xstatic void skip_member ()
  291. X{
  292. X   unsigned long size;    /* Size of the data to be skipped. */
  293. X
  294. X   size = atol(Archive_header.ar_size);
  295. X   size += size % 2;
  296. X   fseek(Archive, size, 1);
  297. X} /* skip_member */
  298. X
  299. X/*
  300. X *  Update just the ar_date field of the record, and the rewrite that
  301. X *  record.
  302. X */
  303. Xstatic void touch_member ()
  304. X{
  305. X   char buffer[13];  /* Workspace to create new time stamp. */
  306. X   
  307. X   unsigned long time();
  308. X   
  309. X   fseek(Archive, Archive_pos, 0);
  310. X   sprintf(buffer, "%ld", time(NULL));
  311. X   memcpy(Archive_header.ar_date, buffer, strlen(buffer));
  312. X   fwrite(&Archive_header, sizeof(struct ar_hdr), 1, Archive);
  313. X} /* touch_member */
  314. X
  315. X/*
  316. X *  Usage:
  317. X *    libtouch archive-name [lib-members ...]
  318. X */
  319. Xint main (argc, argv)
  320. X   int argc;      /* Number of arguments on the command line. */
  321. X   char **argv;      /* Each command line argument...          */
  322. X{
  323. X   int i;  /* Simple loop counter. */
  324. X   
  325. X   if (argc < 2)
  326. X      error("Usage: %s archive-name [lib-members]\n", argv[0]);
  327. X
  328. X   open_archive(argv[1]);
  329. X   do {
  330. X      read_header();
  331. X      for (i = 2; i < argc; i++) {
  332. X     /* Check only the member name length */
  333. X     if (!strncmp(argv[i], Archive_header.ar_name, 
  334. X        (strlen(argv[i]) <= MAX_MEMBER_NAME) ? 
  335. X            strlen(argv[i]) : MAX_MEMBER_NAME)) {
  336. X        /*
  337. X         *    A little tricky here: touch the current header, copy the
  338. X         *    last header to here, and reduce the number to search through.
  339. X         *    This lets us find the correct record with a steadily
  340. X         *    reducing number of comparisons, does not require any sort
  341. X         *    order on any of the two lists, and only makes one pass
  342. X         *    through the archive.
  343. X         */
  344. X        touch_member();
  345. X        argv[i] = argv[argc - 1];
  346. X        argc--;
  347. X        break;
  348. X     }
  349. X      }
  350. X      skip_member();
  351. X   } while (argc != 2);
  352. X   fclose(Archive);
  353. X   return 0;
  354. X} /* main */
  355. END_OF_FILE
  356.   if test 5966 -ne `wc -c <'libtouch.c'`; then
  357.     echo shar: \"'libtouch.c'\" unpacked with wrong size!
  358.   fi
  359.   # end of 'libtouch.c'
  360. fi
  361. if test -f 'libtouch.l' -a "${1}" != "-c" ; then 
  362.   echo shar: Will not clobber existing file \"'libtouch.l'\"
  363. else
  364.   echo shar: Extracting \"'libtouch.l'\" \(1620 characters\)
  365.   sed "s/^X//" >'libtouch.l' <<'END_OF_FILE'
  366. X.TH LIBTOUCH L "25 March 1993"
  367. X.SH NAME
  368. Xlibtouch \- update the access and modification times of an object in a library
  369. X.SH SYNOPSIS
  370. X.B libtouch
  371. X.I library
  372. X.I filename .\|.\|.
  373. X.SH DESCRIPTION
  374. X.IX  "libtouch command"  ""  "\fLlibtouch\fP \(em update last modified date of an object in a library"
  375. X.IX  "update last modified date of object in a library"  ""  "update last modified date of object in a library \(em \fLlibtouch\fP"
  376. X.IX  "object in library"  "update last modified date of"  ""  "update last modified date of \(em \fLlibtouch\fP"
  377. X.IX  "programming tools"  libtouch  ""  "\fLlibtouch\fP \(em update last modified date of object in library"
  378. X.B libtouch
  379. Xsets the access and modification times of each
  380. Xargument after the first to the current time.
  381. XThe first argument is a library containing the files in the rest of the list.
  382. X.LP
  383. X.B libtouch
  384. Xis valuable when used in conjunction with
  385. X.BR make (1),
  386. Xwhere, for instance, you might want to delay the actual archival and
  387. Xranlib'ing of a library composed of many pieces, but still mark the object
  388. Xas having been modified.  In such a case, you might use:
  389. X.RS
  390. X.IP
  391. X.nf
  392. X.B     \fBlibtouch  libsample.a test.o\fP
  393. X.fi
  394. X.RE
  395. X.LP
  396. X.BR make (1)
  397. Xwould then see that the
  398. X.B .c
  399. Xobject was more
  400. Xrecent than the corresponding
  401. X.B .o
  402. Xfiles, and would start
  403. Xthe compilation of dependent objects.  A rule later would see to the actual archiving and ranlib'ing.
  404. XIt would likely depend on the fact that the library's modification date was also changed by
  405. X.B libtouch
  406. X.SH SEE ALSO
  407. X.BR make (1),
  408. X.BR utimes (2)
  409. X.SH BUGS
  410. XIt also sets the modification time of the archive, which can be a problem.
  411. END_OF_FILE
  412.   if test 1620 -ne `wc -c <'libtouch.l'`; then
  413.     echo shar: \"'libtouch.l'\" unpacked with wrong size!
  414.   fi
  415.   # end of 'libtouch.l'
  416. fi
  417. echo shar: End of archive 1 \(of 1\).
  418. cp /dev/null ark1isdone
  419. MISSING=""
  420. for I in 1 ; do
  421.     if test ! -f ark${I}isdone ; then
  422.     MISSING="${MISSING} ${I}"
  423.     fi
  424. done
  425. if test "${MISSING}" = "" ; then
  426.     echo You have the archive.
  427.     rm -f ark[1-9]isdone
  428. else
  429.     echo You still must unpack the following archives:
  430.     echo "        " ${MISSING}
  431. fi
  432. exit 0
  433. exit 0 # Just in case...
  434.