perlman@wivax.UUCP (Gary Perlman) (12/05/84)
Here is my shar. It is somewhat faster than the shell script version: 14.0 real 1.1 user 5.6 sys (shell version) 3.0 real 0.2 user 0.5 sys (C version) but another advantage is that it provides better diagnostics (I think). I know there have been other versions posted, but I saw a recent request. Gary Perlman/Wang Institute/Tyng Road/Tyngsboro, MA/01879/(617) 649-9731 #!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # shar: Shell Archiver # Run the following text with /bin/sh to create: # shar.1 # shar.c echo shar: extracting shar.1 cat - << \SHAR_EOF > shar.1 .TH SHAR 1net "December 5, 1984" .SH NAME shar \- create storage archive for extraction by /bin/sh .SH SYNOPSIS .B shar [-v] files .SH DESCRIPTION .I shar prints its input files with special lines around them to be used by the shell (/bin/sh) to extract them later. The output can be filtered through the shell to recreate copies of the original files. The -v (verbose) option prints feedback about what shar is doing. .SH AUTHOR Gary Perlman (based on a shell version by James Gosling) SHAR_EOF echo shar: extracting shar.c cat - << \SHAR_EOF > shar.c #include <stdio.h> /* Shar puts readable text files together in a package from which they are easy to extract. The original version was a shell script posted to the net, shown below: #Date: Mon Oct 18 11:08:34 1982 #From: decvax!microsof!uw-beave!jim (James Gosling at CMU) AR=$1 shift for i do echo a - $i echo "echo x - $i" >>$AR echo "cat >$i <<'!Funky!Stuff!'" >>$AR cat $i >>$AR echo "!Funky!Stuff!" >>$AR done I rewrote this version in C to provide better diagnostics and to run faster. The main difference is that my version does not affect any files because it prints to the standard output. Mine also has a -v (verbose) option. */ #define DELIM "SHAR_EOF" /* put after each file */ #define SHAR "shar" /* the name of this program */ #define READ_PERMISSION 4 /* access permission */ int Verbose = 0; /* option to provide append/extract feedback */ main (argc, argv) char **argv; { int status = 0; if (!strcmp (argv[1], "-v")) { Verbose = 1; argc--; argv++; } if (argc == 1) { fprintf (stderr, "%s: No input files\n", SHAR); fprintf (stderr, "USAGE: %s [-v] files > archive\n", SHAR); exit (1); } if (header (argc, argv)) exit (2); while (--argc) status += shar (*++argv); exit (status); } header (argc, argv) char **argv; { int i; int problems = 0; for (i = 1; i < argc; i++) if (access (argv[i], READ_PERMISSION)) { fprintf (stderr, "%s: Can't read %s\n", SHAR, argv[i]); problems++; } if (problems) return (problems); puts ("#!/bin/sh-----cut here-----cut here-----cut here-----cut here-----"); printf ("# %s: Shell Archiver\n", SHAR); puts ("# Run the following text with /bin/sh to create:"); for (i = 1; i < argc; i++) printf ("# %s ", argv[i]); putchar ('\n'); return (0); } shar (file) char *file; { char line[BUFSIZ]; FILE *ioptr; if (ioptr = fopen (file, "r")) { if (Verbose) { fprintf (stderr, "%s: appending %s\n", SHAR, file); printf ("echo %s: extracting %s\n", SHAR, file); } printf ("cat - << \\%s > %s\n", DELIM, file); while (fgets (line, BUFSIZ, ioptr)) fputs (line, stdout); (void) fclose (ioptr); puts (DELIM); return (0); } else { fprintf (stderr, "%s: Can't open %s\n", SHAR, file); return (1); } } SHAR_EOF a - shar.c
thompson@dalcs.UUCP (Michael A. Thompson) (12/10/84)
I have made several modifications to this program, and thought they might be useful to others, so I am posting this modified version of Gary Perlman's program. I am posting the whole program rather than the diffs, because the diffs would be almost as large. My changes incorperate a couple ideas that I have seen used for "Shar" type files posted to the net in the past, namely the line prefix character removal, and the exit at the end to avoid problems with signatures at the end of the article. -----Cut Here-----Cut Here-----Cut Here-----Cut Here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # shar.1 # shar.c echo shar: extracting shar.1 sed 's/^X//' << 'SHAR_EOF' > shar.1 X.TH SHAR 1net "December 5, 1984" X.SH NAME Xshar \- create storage archive for extraction by /bin/sh X.SH SYNOPSIS X.B shar X[-v] [-s] [-d'delimeter'] [-c] files X.SH DESCRIPTION X.I shar Xprints its input files with special lines around them Xto be used by the shell (/bin/sh) to extract them later. XThe output can be filtered through the shell to Xrecreate copies of the original files. XThe -v (verbose) option prints feedback about Xwhat shar is doing. XThe -s (sum) option prints the sums of the orignal and extracted files. XThe -d (delimeter) option changes the end of file marker to delimeter. XThe -c (cut here) option cause the "-----Cut Here..." line to be placed Xat the beginning of the shar archive. X.SH AUTHOR XGary Perlman X(based on a shell version by James Gosling) XMichael Thompson -- added -s -d and -c options. SHAR_EOF echo 'Orignal Sum -> 22089 1' echo -n 'Current Sum -> ' sum shar.1 echo shar: extracting shar.c sed 's/^X//' << 'SHAR_EOF' > shar.c X#ifndef lint X#ifdef RCSIDENT Xstatic char *rcsid[] = { X "$Header: shar.c,v 1.3 84/12/09 19:38:53 thompson Exp $", X "$Locker: $" X}; X#endif RCSIDENT X#endif lint X#include <stdio.h> X X/* XShar puts readable text files together in a package Xfrom which they are easy to extract. The original version Xwas a shell script posted to the net, shown below: X #Date: Mon Oct 18 11:08:34 1982 X #From: decvax!microsof!uw-beave!jim (James Gosling at CMU) X AR=$1 X shift X for i do X echo a - $i X echo "echo x - $i" >>$AR X echo "cat >$i <<'!Funky!Stuff!'" >>$AR X cat $i >>$AR X echo "!Funky!Stuff!" >>$AR X done XI rewrote this version in C to provide better diagnostics Xand to run faster. The main difference is that my version Xdoes not affect any files because it prints to the standard Xoutput. Mine also has a -v (verbose) option. X*/ X/* X * I have made several mods to this program: X * X * 1) the -----Cut Here-----... now preceds the script. X * 2) the cat has been changed to a sed which removes a prefix X * character from the beginning of each line of the extracted X * file, this prefix character is added to each line of the archived X * files and is not the same as the first character of the X * file delimeter. X * 3) added several options: X * -c - add the -----Cut Here-----... line. X * -d'del' - change the file delimeter to del. X * -s - cause the resulting script to print the sum of X * the orignal file and the sum of the extracted X * file. X * X * Michael A. Thompson X * Dalhousie University X * Halifax, N.S., Canada. X */ X X#define DELIM "SHAR_EOF"/* put after each file */ X#define PREFIX1 'X' /* goes infront of each line */ X#define PREFIX2 'Y' /* goes infront of each line if Delim X starts with PREFIX1 */ X#define PREFIX (Delim[0] == PREFIX1 ? PREFIX2 : PREFIX1) X#define SHAR "shar" /* the name of this program */ X#define READ_PERMISSION 4 /* access permission */ X#define SUM "sum" X Xint Verbose = 0; /* option to provide append/extract X feedback */ Xint Sum = 0; /* option to provide sum checking */ Xchar *Delim = DELIM; /* option to provide alternate delimeter X */ Xint Cut = 0; /* option to provide cut mark */ X XFILE * popen (); X Xmain (argc, argv) char **argv; X{ X int status = 0; X X while (argv[1][0] == '-') { X switch (argv[1][1]) { X case 'v': X Verbose = 1; X break; X case 's': X Sum = 1; X break; X case 'd': X if (argv[1][2]) X Delim = &argv[1][2]; X break; X case 'c': X Cut = 1; X break; X default: X fprintf (stderr, "%s: invalid argument\n", SHAR); X fprintf (stderr, "USAGE: %s [-v] [-s] [-d'delimeter'] [-c] files > archive\n", SHAR); X break; X } X argc--; X argv++; X } X if (argc == 1) { X fprintf (stderr, "%s: No input files\n", SHAR); X fprintf (stderr, "USAGE: %s [-v] [-s] [-d'delimeter'] [-c] files > archive\n", SHAR); X exit (1); X } X if (header (argc, argv)) X exit (2); X while (--argc) X status += shar (*++argv); X puts ("exit"); X exit (status); X} X Xheader (argc, argv) Xchar **argv; X{ X int i; X int problems = 0; X for (i = 1; i < argc; i++) X if (access (argv[i], READ_PERMISSION)) { X fprintf (stderr, "%s: Can't read %s\n", SHAR, argv[i]); X problems++; X } X if (problems) X return (problems); X if (Cut) X puts ("-----Cut Here-----Cut Here-----Cut Here-----Cut Here-----"); X puts ("#!/bin/sh"); X printf ("# %s: Shell Archiver\n", SHAR); X puts ("# Run the following text with /bin/sh to create:"); X for (i = 1; i < argc; i++) X printf ("# %s\n", argv[i]); X return (0); X} X Xshar (file) Xchar *file; X{ X char line[BUFSIZ]; X FILE * ioptr; X if (ioptr = fopen (file, "r")) { X if (Verbose) { X fprintf (stderr, "%s: appending %s\n", SHAR, file); X printf ("echo %s: extracting %s\n", SHAR, file); X } X printf ("sed 's/^%c//' << '%s' > %s\n", PREFIX, Delim, file); X while (fgets (line, BUFSIZ, ioptr)) { X putc (PREFIX, stdout); X fputs (line, stdout); X } X (void) fclose (ioptr); X puts (Delim); X if (Sum) { X FILE * pfp; X char command[BUFSIZ]; X X sprintf (command, "%s %s", SUM, file); X if ((pfp = popen (command, "r"))) { X char sum[BUFSIZ]; X X fgets (sum, BUFSIZ, pfp); X sum[strlen (sum) - 1] = '\0'; X printf ("echo 'Orignal Sum -> %s'\n", sum); X puts ("echo -n 'Current Sum -> '"); X puts (command); X pclose (pfp); X } X } X return (0); X } X else { X fprintf (stderr, "%s: Can't open %s\n", SHAR, file); X return (1); X } X} SHAR_EOF echo 'Orignal Sum -> 20927 5' echo -n 'Current Sum -> ' sum shar.c exit -- Signed: Michael A. Thompson (ask me no questions, I'll tell you no lies) Net address: ...{utcsrgv,dartvax}!dalcs!thompson Where in the world: Dalhousie University Halifax, Nova Scotia
salmi@dicome.UUCP (salmi) (03/13/86)
there have been quite a few requests for the shar script in net.sources.wanted. here is a version written in c that came off the net last year. enjoy..... -john ------------------------------cut here----------------------------------------- /* ** cshar.c */ #ifndef lint #ifdef RCSIDENT static char *rcsid[] = { "$Header: shar.c,v 1.3 84/12/09 19:38:53 thompson Exp $", "$Locker: $" }; #endif RCSIDENT #endif lint #include <stdio.h> /* Shar puts readable text files together in a package from which they are easy to extract. The original version was a shell script posted to the net, shown below: #Date: Mon Oct 18 11:08:34 1982 #From: decvax!microsof!uw-beave!jim (James Gosling at CMU) AR=$1 shift for i do echo a - $i echo "echo x - $i" >>$AR echo "cat >$i <<'!Funky!Stuff!'" >>$AR cat $i >>$AR echo "!Funky!Stuff!" >>$AR done I rewrote this version in C to provide better diagnostics and to run faster. The main difference is that my version does not affect any files because it prints to the standard output. Mine also has a -v (verbose) option. */ /* * I have made several mods to this program: * * 1) the -----Cut Here-----... now preceds the script. * 2) the cat has been changed to a sed which removes a prefix * character from the beginning of each line of the extracted * file, this prefix character is added to each line of the archived * files and is not the same as the first character of the * file delimeter. * 3) added several options: * -c - add the -----Cut Here-----... line. * -d'del' - change the file delimeter to del. * -s - cause the resulting script to print the sum of * the orignal file and the sum of the extracted * file. * * Michael A. Thompson * Dalhousie University * Halifax, N.S., Canada. */ #define DELIM "SHAR_EOF"/* put after each file */ #define PREFIX1 'X' /* goes infront of each line */ #define PREFIX2 'Y' /* goes infront of each line if Delim starts with PREFIX1 */ #define PREFIX (Delim[0] == PREFIX1 ? PREFIX2 : PREFIX1) #define SHAR "shar" /* the name of this program */ #define READ_PERMISSION 4 /* access permission */ #define SUM "sum" int Verbose = 0; /* option to provide append/extract feedback */ int Sum = 0; /* option to provide sum checking */ char *Delim = DELIM; /* option to provide alternate delimeter */ int Cut = 0; /* option to provide cut mark */ FILE * popen (); main (argc, argv) char **argv; { int status = 0; while (argv[1][0] == '-') { switch (argv[1][1]) { case 'v': Verbose = 1; break; case 's': Sum = 1; break; case 'd': if (argv[1][2]) Delim = &argv[1][2]; break; case 'c': Cut = 1; break; default: fprintf (stderr, "%s: invalid argument\n", SHAR); fprintf (stderr, "USAGE: %s [-v] [-s] [-d'delimeter'] [-c] files > archive\n", SHAR); break; } argc--; argv++; } if (argc == 1) { fprintf (stderr, "%s: No input files\n", SHAR); fprintf (stderr, "USAGE: %s [-v] [-s] [-d'delimeter'] [-c] files > archive\n", SHAR); exit (1); } if (header (argc, argv)) exit (2); while (--argc) status += shar (*++argv); puts ("exit"); exit (status); } header (argc, argv) char **argv; { int i; int problems = 0; for (i = 1; i < argc; i++) if (access (argv[i], READ_PERMISSION)) { fprintf (stderr, "%s: Can't read %s\n", SHAR, argv[i]); problems++; } if (problems) return (problems); if (Cut) puts ("-----Cut Here-----Cut Here-----Cut Here-----Cut Here-----"); puts ("#!/bin/sh"); printf ("# %s: Shell Archiver\n", SHAR); puts ("# Run the following text with /bin/sh to create:"); for (i = 1; i < argc; i++) printf ("# %s\n", argv[i]); return (0); } shar (file) char *file; { char line[BUFSIZ]; FILE * ioptr; if (ioptr = fopen (file, "r")) { if (Verbose) { fprintf (stderr, "%s: appending %s\n", SHAR, file); printf ("echo x - extracting %s\n", SHAR, file); } printf ("sed 's/^%c//' << '%s' > %s\n", PREFIX, Delim, file); while (fgets (line, BUFSIZ, ioptr)) { putc (PREFIX, stdout); fputs (line, stdout); } (void) fclose (ioptr); puts (Delim); if (Sum) { FILE * pfp; char command[BUFSIZ]; sprintf (command, "%s %s", SUM, file); if ((pfp = popen (command, "r"))) { char sum[BUFSIZ]; fgets (sum, BUFSIZ, pfp); sum[strlen (sum) - 1] = '\0'; printf ("echo 'Orignal Sum -> %s'\n", sum); puts ("echo -n 'Current Sum -> '"); puts (command); pclose (pfp); } } return (0); } else { fprintf (stderr, "%s: Can't open %s\n", SHAR, file); return (1); } }