home *** CD-ROM | disk | FTP | other *** search
- /*
- * Split - Split a file into pieces
- *
- * Version 1 =TP= ??-???-89 (Write some comments ;-( )
- * Unix look-alike command
- * Version 37.2 =TP= 21-Jan-92 26-Jan-92
- * Compile with SAS/C 5.10 and link without startup code:
- * lc -cqfist -v -b0 -rr -O -ms Split
- * blink Time.o to Split sd sc
- * protect Split +p
- *
- * Copyright (c) 1989, 1992 Torsten Poulin
- *
- * Note: The program do not check for errors while writing
- * because the include files for SAS/C declared
- * FPutC() to be VOID instead of LONG!!!! ;-(
- *
- * Torsten Poulin
- * Banebrinken 99, 2, lejlighed 77
- * DK 2400 København NV
- * DENMARK
- */
-
- /****** English:SPLIT ******************************************************
- *
- * FORMAT
- * SPLIT [[FROM] <file>] [TO <name>] [NUMBER <n> [PARTS]]
- * [BYTES] [PROMPT]
- *
- * TEMPLATE
- * FROM,TO/K,NUM=NUMBER/K/N,PARTS/S,BYTES/S,PROMPT/S
- *
- * PURPOSE
- * To split a file into pieces.
- *
- * SPECIFICATION
- * Split reads <file> and writes it in <n>-line pieces (default
- * 1000 lines) onto a set of output files. The name of the
- * first output file is <name> with aa appended, and so on
- * lexicographically, up to zz (a maximum of 676 files). <name>
- * is truncated to 28 characters if it is longer. If no output
- * name is given, x is default.
- *
- * If the BYTES switch is used, the input file will be split in
- * <n>-character pieces instead. This is especially useful
- * if the input is a binary file.
- *
- * The PARTS switch, which can only be used in conjunction with
- * the NUMBER option, splits the input file in the specified
- * number of parts.
- *
- * The PARTS switch implies the BYTES switch.
- *
- * If the PROMPT switch is specified, the user will be prompted
- * before each output file is written, to make it possible to
- * change disks.
- *
- * If no input file is given then the default input is used
- * making it possible to use Split as the end of a pipe-line.
- *
- * EXAMPLE
- * If the file `myfile' is split up with a command like this:
- * 1> SPLIT myfile TO splitfile.
- * it can be assembled again with the following command:
- * 1> CONCAT splitfile.?? TO newfile SORT
- *
- * WARNING
- * Do not use the PARTS switch if reading from a pipe as
- * it causes Split to attempt to determine the size of it's
- * input using the dos.library function Seek(). If you do
- * it chances are that you end up with lots of small files
- * typically containing one byte each.
- *
- * SEE ALSO
- * CONCAT, JOIN, TYPE
- *
- ***************************************************************************
- *
- */
- /****** dansk:SPLIT *******************************************************
- *
- * FORMAT
- * SPLIT [[FROM] <fil>] [TO <navn>] [NUMBER <n> [PARTS]]
- * [BYTES] [PROMPT]
- *
- * SKABELON
- * FROM,TO/K,NUM=NUMBER/K/N,PARTS/S,BYTES/S,PROMPT/S
- *
- * FORMÅL
- * At splitte en fil i mindre stykker.
- *
- * SPECIFIKATION
- * Split læser <fil> og udskriver den i <n>-linje stykker
- * (standard er 1000 linjer) som en gruppe filer. Navnet
- * på den første uddatafil er <navn> efterfulgt af aa og
- * så fremdeles, leksikografisk, indtil zz (højst 676 filer).
- * <navn> forkortes til 28 tegn hvis det er længere. Hvis
- * der ikke er angivet noget uddatanavn, bruges x.
- *
- * Hvis kontakten BYTES bruges vil inddatafilen blive delt
- * i stykker på <n> tegn i stedet. Dette er særlig nyttigt
- * hvis inddata er en binær fil.
- *
- * Kontakten PARTS, der kun kan bruges sammen med argumentet
- * NUMBER, deler inddatafilen i det angivne antal dele.
- *
- * Kontakten PARTS indebærer automatisk kontakten BYTES.
- *
- * Hvis kontakten PROMPT angives vil brugeren blive spurgt
- * før hver uddatafil skrives for at muliggøre disketteskift.
- *
- * Hvis ingen inddatafil er angivet læses fra standardinputtet,
- * hvilket gør det muligt at bruge Split som afslutningen på
- * en pipe.
- *
- * EKSEMPEL
- * Hvis filen `minfil' splittes op med en kommando som
- * 1> SPLIT minfil TO splitfil.
- * kan den samles igen med følgende kommando:
- * 1> CONCAT splitfil.?? TO nyfil SORT
- *
- * ADVARSEL
- * Brug ikke kontakten PARTS hvis der læses fra en pipe, da
- * den får Split til at forsøge at bestemme størrelsen af
- * sit input med funktionen Seek() fra dos.library. Hvis
- * man gør det vil man sandsynligvis ende med en mængde
- * små filer med typisk én oktet i hver.
- *
- * SE OGSÅ
- * CONCAT, JOIN, TYPE
- *
- ***************************************************************************
- *
- */
-
-
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
- #include <string.h>
-
- #define EOF (-1)
-
- #define OPT_FROM 0
- #define OPT_TO 1
- #define OPT_NUM 2
- #define OPT_PARTS 3
- #define OPT_BYTES 4
- #define OPT_PROMPT 5
-
-
- char const *version = "\0$VER: Split 37.2 (26.1.92)\
- ©1989,92 Torsten Poulin";
-
- LONG error(struct DosLibrary *, LONG);
-
- LONG entrypoint(void)
- {
- struct RDArgs *args;
- struct Library *UtilityBase;
- struct DosLibrary *DOSBase;
- struct Library *SysBase;
-
- LONG arg[6];
- LONG rc = RETURN_OK;
- BPTR in, out = NULL;
- LONG c, cnt, totalfiles = 0;
- LONG len = 1;
- UBYTE name[31] = "x";
- ULONG number = 1000L;
- register UBYTE breakcheck = 0;
-
- SysBase = *(struct Library **) 4L;
- if(!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto exit1;
- }
- if(!(UtilityBase = OpenLibrary("utility.library", 37L)))
- {
- rc = RETURN_FAIL;
- goto exit2;
- }
-
- arg[OPT_FROM] = arg[OPT_TO] = arg[OPT_NUM] =
- arg[OPT_PARTS] = arg[OPT_BYTES] = arg[OPT_PROMPT] = 0L;
-
- if(args = ReadArgs("FROM,TO/K,NUM=NUMBER/K/N,PARTS/S,BYTES/S,PROMPT/S",
- arg, NULL))
- {
- if(arg[OPT_NUM])
- {
- number = *(ULONG *) arg[OPT_NUM];
- if(number < 1L)
- number = 1L;
- }
-
- if(arg[OPT_TO])
- {
- UBYTE *a = (UBYTE *) arg[OPT_TO];
-
- for(len = 0; len < 28 && a[len]; len++)
- name[len] = a[len];
- name[len] = '\0';
- }
-
- if(in = arg[OPT_FROM] ? Open((UBYTE *) arg[OPT_FROM], MODE_OLDFILE)
- : Input())
- {
- name[len] = 'a';
- name[len + 1] = 'a' - 1;
- name[len + 2] = '\0';
-
- if((BOOL) arg[OPT_PARTS] && arg[OPT_NUM])
- {
- ULONG n = (ULONG) number;
-
- if(n > 676L)
- n = 676L;
- Seek(in, 0L, OFFSET_END);
- number = Seek(in, 0L, OFFSET_BEGINNING);
- number = UDivMod32((ULONG) number, n) + 1L;
- arg[OPT_BYTES] = TRUE;
- }
- cnt = number;
-
- while((c = FGetC(in)) != EOF)
- {
- if(cnt == number && 676L > totalfiles++)
- {
- cnt = 0;
- if(name[len + 1] < 'z')
- name[len + 1]++;
- else
- {
- name[len + 1] = 'a';
- name[len]++;
- }
- name[len + 2] = '\0';
- if(out)
- Close(out);
- if((BOOL) arg[OPT_PROMPT])
- {
- BPTR console;
-
- Write(Output(), "Press RETURN to write ", 22L);
- Write(Output(), name, strlen(name));
- if(console = Open("CONSOLE:", MODE_OLDFILE))
- {
- FGetC(console);
- Close(console);
- }
- }
- if(!(out = Open(name, MODE_NEWFILE)))
- {
- rc = error(DOSBase, RETURN_ERROR);
- goto openErr;
- }
- }
- /* if( */ FPutC(out, c) /* == EOF)
- {
- rc = error(DOSBase, RETURN_FAIL);
- goto writeErr;
- }
- */;
- if((BOOL) arg[OPT_BYTES] || c == '\n')
- cnt++;
- if(!(breakcheck -= 8) && SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
- {
- PrintFault(ERROR_BREAK, NULL);
- rc = RETURN_WARN;
- break;
- }
- }
- writeErr:
- Close(out);
- openErr:
- if(arg[OPT_FROM])
- Close(in);
- }
- else
- rc = error(DOSBase, RETURN_ERROR);
-
- FreeArgs(args);
- }
- else
- rc = error(DOSBase, RETURN_ERROR);
-
- CloseLibrary(UtilityBase);
- exit2:
- CloseLibrary((struct Library *) DOSBase);
- exit1:
- return rc;
- }
-
-
- LONG error(struct DosLibrary *DOSBase, LONG code)
- {
- LONG err = IoErr();
-
- PrintFault(err, "Split");
- return code;
- }
-