🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: mod.amiga.sources
1 messages
1 total messages Started by doc Tue, 22 Jul 1986 21:09
SHAR.c (v 860715 DBW) fixes several bugs....
#10
Author: doc
Date: Tue, 22 Jul 1986 21:09
415 lines
12207 bytes
[*  This is a newer version of the shell archiver by Dave Wecker that
works on the Amiga, Ultrix and I have even ran it on 4.2BSD with succes *]

/* Shar puts readable text files together in a package
   from which they are easy to extract.

    v 860712 D. Wecker for ULTRIX and the AMIGA
    - stripped down.. does patterns but no directories
    - added a -u (unshar) switch
    v 860715 DBW
    - fixed bug with leading white space in unshar command recognition
    - fixed bug in getting sh paramaters with quotes
 */

#include <stdio.h>

#ifdef    AMIGA
#include <exec/types.h>
extern char *getenv(),*scdir(),*malloc(),*index();
#endif

#ifdef    ULTRIX
#include <sys/types.h>
extern char *getenv(),*scdir(),*malloc(),*index();
#endif

#ifdef    VMS
#include <types.h>
extern char *getenv(),*scdir(),*malloc();
#endif


#define BADCH    ((int)'?')
#define EMSG    ""
#define tell(s)    {fputs(*nargv,stderr);fputs((s),stderr); \
        fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);}
#define rescanopts()    (optind = 1)

int    optind = 1,        /* index into parent argv vector */
    optopt;            /* character checked for validity */
long    fsize;            /* length of file */
char    *optarg;        /* argument associated with option */
char    *sav[100];        /* saved file names */
int    savind;            /* save index */

/* OPTIONS */
int     Verbose = 0;           /* provide append/extract feedback */
int     Basename = 0;          /* extract into basenames */
int     Count = 0;             /* count characters to check transfer */
char    *Delim = "SHAR_EOF";   /* put after each file */
char    Filter[100] = "cat";   /* used to extract archived files */
char    *Prefix = NULL;        /* line prefix to avoid funny chars */
int    UnShar = 0;           /* do we unshar an input file? */

#define    SED "sed 's/^%s//'"    /* used to remove prefix from lines */
#define    USAGE "[-u archive] [[-a] [-p prefix] [-d delim] [-bcv] files > archive]"
#define    OPTSTRING "u:ap:d:bcv"

#ifdef    VMS
char *index(s,c)
char    *s;
char    c;
{
    while (*s != 0 && *s != c) s++;
    if (*s == 0 && *s != c) s = 0;
    return(s);    
}
#endif

int header(ppchFiles)
char *ppchFiles[];
{
    extern char *ctime();
    register int i;
    auto long clock;
    register int  problems = 0;
    register char **ppchList;
    register char *pchOrg = getenv("ORGANIZATION");
    register char *pchName = getenv("NAME");

    puts("#\tThis is a shell archive.");
    puts("#\tRemove everything above and including the cut line.");
    puts("#\tThen run the rest of the file through sh.");
    puts("#----cut here-----cut here-----cut here-----cut here----#");
    puts("#!/bin/sh");
    puts("# shar:    Shell Archiver");
    puts("#\tRun the following text with /bin/sh to create:");
    for (ppchList = ppchFiles; *ppchList; ++ppchList)
        printf("#\t%s\n", *ppchList);
    (void) time(& clock);
    printf("# This archive created: %s", ctime(&clock));
    if (pchName)
        printf("# By:\t%s (%s)\n", pchName, 
        pchOrg ? pchOrg : "Dave Wecker Midnight Hacks");
    return(0);
}

int archive(input, output)
char *input, *output;
{
    auto char line[BUFSIZ];
    register FILE *ioptr;

    if (ioptr = fopen(input, "r")) {
        printf("%s << \\%s > %s\n", Filter, Delim, output);
        while(fgets(line, BUFSIZ, ioptr)) {
            if (Prefix) fputs(Prefix, stdout);
            fputs(line, stdout);
            if (Count) fsize += strlen(line);
        }
        puts(Delim);
        (void) fclose(ioptr);
        return(0);
    } 
    else {
        fprintf(stderr, "shar: Can't open '%s'\n", input);
        return(1);
    }
}


void shar(file)
char *file;
{
    register char *basefile = file;
    if (!strcmp(file, "."))
        return;
    fsize = 0;
    if (Basename) {
        while(*basefile)
            basefile++;        /* go to end of name */
        while(basefile > file && *(basefile-1) != '/')
            basefile--;
    }
    if (Verbose) printf("echo shar: extracting %s\n", basefile);
    if (archive(file, basefile)) exit(66);
    if (Count) {
        printf("if test %ld -ne \"`wc -c %s`\"\n",fsize,basefile);
        printf("then\necho shar: error transmitting %s ",basefile);
        printf("'(should have been %ld characters)'\nfi\n",fsize);
    }
}

int main(argc, argv)
int argc;
char **argv;    
{
    auto char *ppchFiles[256];
    register int  C;
    register char **ppchList = ppchFiles;
    register int errflg = 0;

    while(EOF != (C = getopt(argc, argv, OPTSTRING))) {
        switch(C) {
        case 'v': 
            Verbose++; 
            break;
        case 'c': 
            Count++; 
            break;
        case 'b': 
            Basename++; 
            break;
        case 'd': 
            Delim = optarg; 
            break;
        case 'a': /* all the options */
            optarg = "XX";
            Verbose++;
            Count++;
            Basename++;
            /* fall through to set prefix */
        case 'p': 
            (void) sprintf(Filter, SED, Prefix = optarg); 
            break;
        case 'u':
            UnShar++;
            dounshar(optarg);
            break;
        default: 
            errflg++;
        }
    }

    if (UnShar) exit(0);

    C = getarg(argc, argv);
    if (errflg || EOF == C) {
        if (EOF == C)
            fprintf(stderr, "shar: No input files\n");
        fprintf(stderr, "usage: shar %s\n", USAGE);
        exit(1);
    }

    savind = 0;
    do {
        if (getpat(optarg)) exit(2);
    } 
    while (EOF != (C = getarg(argc, argv)));

    sav[savind] = 0;
    header(sav);
    for (ppchList = sav; *ppchList; ++ppchList) shar(*ppchList);
    puts("#\tEnd of shell archive");
    puts("exit 0");
    exit(0);
}

getpat(pattern)
char *pattern;
{
    register char *ptr;

#ifdef AMIGA
    while (ptr = scdir(pattern)) {
#else
    ptr = pattern;
    {
#endif
        sav[savind] = malloc(strlen(ptr)+1);
        strcpy(sav[savind++],ptr);
        if (access(ptr,4)) {
            printf("No read access for file: %s\n",ptr);
            return(-1);
        }
    }
    return(0);
}

/*
 * get option letter from argument vector
 */
int
getopt(nargc, nargv, ostr)
int nargc;
char **nargv, *ostr;
{
    register char    *oli;        /* option letter list index */
    static char    *place = EMSG;    /* option letter processing */

    if(!*place) {            /* update scanning pointer */
        if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
        if (*place == '-') {    /* found "--" */
            ++optind;
            return EOF;
        }
    }                /* option letter okay? */
    if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
        if(!*place) ++optind;
        tell(": illegal option -- ");
    }
    if (*++oli != ':') {        /* don't need argument */
        optarg = NULL;
        if (!*place)
            ++optind;
    } 
    else {                /* need an argument */
        if (*place) {            /* no white space */
            optarg = place;
        } 
        else if (nargc <= ++optind) {    /* no arg */
            place = EMSG;
            tell(": option requires an argument -- ");
        } 
        else {
            optarg = nargv[optind];    /* white space */
        }
        place = EMSG;
        ++optind;
    }
    return optopt;            /* dump back option letter */
}

int
getarg(nargc, nargv)
int nargc;
char **nargv;
{
    if (nargc <= optind) {
        optarg = (char *) 0;
        return EOF;
    } 
    else {
        optarg = nargv[optind++];
        return 0;
    }
}

dounshar(ArcNam)
char *ArcNam;
{
    register int i,j,strt;
    register FILE *inptr,*outptr;
    auto char line[BUFSIZ];
    int DirNum = -1;
    int Prefix = 0;
    char Dirs[5][40],FilNam[128],Delim[40],ScrStr[128];
    char *ptr;

    if (!(inptr = fopen(ArcNam,"r"))) {
        fprintf(stderr,"shar: Can't open archive '%s'\n", ArcNam);
        return;
    }
    while (fgets(line,BUFSIZ,inptr)) {
        for (strt = 0; line[strt] == ' ' || line[strt] == '\t'; strt++) ;
        if (strncmp(&line[strt],"sed ",4) == 0) {
            Prefix = 0;
            if (!(ptr = index(&line[strt],'/'))) goto getfil;
            if (*++ptr == '^') ++ptr;
            while (*ptr++ != '/') Prefix++;
            goto getfil;
        }
        else if (strncmp(&line[strt],"cat ",4) == 0) {
            Prefix = 0;
            ;
getfil:

#if    VMS
            strcpy(FilNam,"[");
#else
            FilNam[0] = 0;
#endif

            for (i = 0; i <= DirNum; i++) {

#if    VMS
                strcat(FilNam,".");
                strcat(FilNam,Dirs[i]);
#else
                strcat(FilNam,Dirs[i]);
                strcat(FilNam,"/");
#endif

            }


#if    VMS
            strcat(FilNam,"]");
#endif

            getshpar(line,">",ScrStr);
            strcat(FilNam,ScrStr);
            getshpar(line,"<<",Delim);
            fprintf(stderr,"Creating %s ...",FilNam);
            outptr = fopen(FilNam,"w");
            while (fgets(line,BUFSIZ,inptr)) {
                if (strncmp(line,Delim,strlen(Delim)) == 0) break;
                if (outptr) fputs(&line[Prefix],outptr);
            }
            if (outptr) {
                fclose(outptr);
                fprintf(stderr,"...done\n");
            }
            else fprintf(stderr,"...error in creating file\n");
        }
        else if (strncmp(&line[strt],"mkdir ",6) == 0) {
            sprintf(stderr,"Need to make directory:\t%s\n",&line[strt+6]);
        }
        else if (strncmp(&line[strt],"chdir ",6) == 0) {
            if (line[strt+6] == '.' && line[strt+7] == '.') DirNum--;
            else strcpy(Dirs[++DirNum],&line[strt+6]);
            if (DirNum < -1) DirNum = -1;
        }
        else if (strncmp(&line[strt],"cd ",3) == 0) {
            if (line[strt+3] == '.' && line[strt+4] == '.') DirNum--;
            else strcpy(Dirs[++DirNum],&line[strt+3]);
            if (DirNum < -1) DirNum = -1;
        }
    }
    fclose(inptr);
}

getshpar(line,sea,par)
char *line,*sea,*par;
{
    register int i,j,k;
    register char *scr1,*scr2;

    while (*line) {
        scr1 = line;
        scr2 = sea;
        while (*scr1 && *scr2 && *scr1 == *scr2) { 
            scr1++; 
            scr2++; 
        }
        if (*scr2 == 0) {
            if (*scr1 == 0) { 
                *par = 0; 
                return; 
            }
            while ( *scr1 == ' ' || *scr1 == '\t' ||
                *scr1 == '\\' || *scr1 == '\'' || *scr1 == '"') {
                if (*scr1 == '\'' || *scr1 == '"') {
                    scr2 = scr1++;
                    break;
                }
                scr1++;
            }
            if (*scr2 != 0) {
                while (*scr1 != *scr2 && *scr1 != 0) *par++ = *scr1++;
                *par = 0;
                return;
            }
            while ( *scr1 != 0 && *scr1 != ' ' && *scr1 != '\t' &&
                *scr1 != '\n' && *scr1 != '\r') {
                if (*scr1 != '\\') *par++ = *scr1++;
                else            scr1++;
            }
            *par = 0;
            return;
        }
        line++;
    }
    *par = 0;
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads