From 3435d0a48ee2ab9e7230a6c78312ce5de182cdf3 Mon Sep 17 00:00:00 2001 From: Chris Dorman Date: Tue, 17 May 2022 19:24:54 -0700 Subject: [PATCH] Push to V0.7.1 --- Makefile | 6 +- Makefile.musl | 7 +- docs/README.txt | 5 + src/enc.c | 2 +- src/eprintf.c | 2 +- src/inc/deps.h | 46 +- src/inc/enc.h | 2 +- src/inc/eprintf.h | 2 +- src/inc/inset.h | 2 +- src/inc/lexer.h | 3 +- src/inc/math.h | 2 +- src/inc/md5.h | 4 +- src/inc/network.h | 2 +- src/inc/pipe.h | 2 +- src/inc/search.h | 4 +- src/inc/tar.h | 164 ------ src/inc/util.h | 3 +- src/inc/vars.h | 2 +- src/inc/x3mem.h | 2 +- src/inset.c | 3 +- src/lexer.c | 134 +---- src/main.c | 5 +- src/math.c | 2 +- src/md5.c | 4 +- src/network.c | 2 +- src/pipe.c | 2 +- src/search.c | 6 +- src/tar.c | 1233 --------------------------------------------- src/util.c | 16 +- src/vars.c | 2 +- src/x3mem.c | 2 +- 31 files changed, 101 insertions(+), 1572 deletions(-) delete mode 100644 src/inc/tar.h delete mode 100644 src/tar.c diff --git a/Makefile b/Makefile index 9597a66..a1071c8 100755 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ # SlideScript makefile -# (C) Copyright 2014-2021 Chris Dorman, some rights reserved (GPLv2) +# (C) Copyright 2014-2022 Chris Dorman, some rights reserved (GPLv2) # Some changes and tweaks from Menchers -VERSION = \"0.7.0\" +VERSION = \"0.7.1\" VERSION_EXTRA = \"$(EXTRA)\" PREFIX ?= /usr #CC ?= musl-gcc -CC ?= gcc +CC ?= gcc-9 #CC ?= tcc #CC ?= musl-tcc CFLAGS += -O3 -g -Wall -Wextra diff --git a/Makefile.musl b/Makefile.musl index f0f6e1b..8848223 100755 --- a/Makefile.musl +++ b/Makefile.musl @@ -1,8 +1,8 @@ # SlideScript makefile -# (C) Copyright 2014-2021 Chris Dorman, some rights reserved (GPLv2) +# (C) Copyright 2014-2022 Chris Dorman, some rights reserved (GPLv2) # Some changes and tweaks from Menchers -VERSION = \"0.6.0\" +VERSION = \"0.7.1\" VERSION_EXTRA = \"$(EXTRA)\" PREFIX ?= /usr @@ -16,11 +16,10 @@ CPPFLAGS += -DVERSION=$(VERSION) -D_FORTIFY_SOURCE=2 LDFLAGS += -lc -L/planck/lib/tcc -L/planck/lib -ltcc1 -dynamic-linker /planck/lib/libc.so /planck/lib/crti.o /planck/lib/crt1.o /planck/lib/crtn.o -nostdlib BIN ?= slidescript -SRCS=$(wildcard src/*.c) +SRCS=$(wildcard src/*.c) $(wildcard src/lz78/*.c) OBJECTS=$(SRCS:%.c=%.o) - all: main fresh: clean all diff --git a/docs/README.txt b/docs/README.txt index a5f6387..fb779de 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -151,6 +151,11 @@ Changelog Changes between version bumps in SlideScript. Hoping to have a lightweight top-down scripting language by V1.0.0 release! From there it will be molding and preserving the art. +* V0.7.1 + * Removed tar sources from SlideScript, does it need to create tar packages. (You can use system utils) + * Reworked compress / decompress for single file operations. Great for resources FOR slidescript (assets) + * Working on the lexer engine for line parsing and cleaner syntax. + * V0.7.0 * Ditched old LZ77 example code, and went with a more polished LZ78 () * Converted dynamic memory management layer into LZ78 engine and tar code. diff --git a/src/enc.c b/src/enc.c index ce1d1bd..4627f8a 100644 --- a/src/enc.c +++ b/src/enc.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/eprintf.c b/src/eprintf.c index 8a75a0f..efd8c7d 100644 --- a/src/eprintf.c +++ b/src/eprintf.c @@ -4,7 +4,7 @@ // Filename: eprintf.c // Purpose: TTY and error-message routines -// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021. +// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2022. /* ------------------------------------------------------------ */ /* header files */ diff --git a/src/inc/deps.h b/src/inc/deps.h index 98bd35f..875186b 100644 --- a/src/inc/deps.h +++ b/src/inc/deps.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -8,7 +8,7 @@ #include #include #include -#include +//#include #include #include #include @@ -81,26 +81,26 @@ // HELP PRINTOUT -#define FUNCTION_HELP "-[Main Functions]-\nlist:\n" \ - " print \"\" |" \ - " sleep |" \ - " encode \"\"\n" \ - " decode \"\" |" \ - " compress \"\" \"\"\n" \ - " decompress \"\" |" \ - " calc \" <+/-*> \"\n" \ - " move \"\" \"\" |" \ - " chdir \"\" |" \ - " showdir |" \ - " showpath\n" \ - " isdir \"\" |" \ - " isfile \"\" |" \ - " delete \"\"\n" \ - " nethttp \"\" \"\" (1 forks, 0 nofork)\n" \ - " read \"\" |" \ - " write \"\" \"\"\n" \ - " cat \"\" \"\" |" \ - " exec \"\" | unset \"\"\n" \ +#define FUNCTION_HELP "-[Main Functions]-\n Need function information? Use: help \n list:\n" \ + "print, " \ + "sleep, " \ + "encode, " \ + "decode, " \ + "compress, " \ + "decompress, " \ + "calc, " \ + "move, " \ + "chdir, " \ + "showdir, " \ + "showpath, " \ + "isdir, " \ + "isfile, " \ + "delete, " \ + "nethttp, " \ + "read, " \ + "write, " \ + "cat, " \ + "exec, unset \n " \ "\n-[Variables, Pipes, and Backquoting]-\nExample:\n" \ " FORK=`isfile \"index.html\"` -> returns 1 on find\n" \ " write \"port.txt\" \"8888\" -> writes '8888' to port.txt\n" \ @@ -113,7 +113,7 @@ "if(n): ; -> Processes function if true or false\n" // Purpose: UX3 basic definitions -// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021. +// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2022. #ifndef _X3BASIC_H /* skip this file if loaded */ #define _X3BASIC_H 1 /* flag this file */ diff --git a/src/inc/enc.h b/src/inc/enc.h index e1c3c6c..3706c49 100644 --- a/src/inc/enc.h +++ b/src/inc/enc.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/eprintf.h b/src/inc/eprintf.h index a518cba..90f6d32 100644 --- a/src/inc/eprintf.h +++ b/src/inc/eprintf.h @@ -4,7 +4,7 @@ // Filename: eprintf.h // Purpose: TTY and error-message routines -// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021. +// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2022. /* ------------------------------------------------------------ */ /* header file setup */ diff --git a/src/inc/inset.h b/src/inc/inset.h index 9c5d9b9..5ab9a70 100644 --- a/src/inc/inset.h +++ b/src/inc/inset.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/lexer.h b/src/inc/lexer.h index 88212f4..3b89a59 100644 --- a/src/inc/lexer.h +++ b/src/inc/lexer.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -9,5 +9,4 @@ UX3_EXT QLIST QM_SS [ONE]; // Dynamic-memory QLIST - char *process_line(char *line); diff --git a/src/inc/math.h b/src/inc/math.h index ec5a7f5..09212a2 100644 --- a/src/inc/math.h +++ b/src/inc/math.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/md5.h b/src/inc/md5.h index 1542b0c..3bc37e7 100644 --- a/src/inc/md5.h +++ b/src/inc/md5.h @@ -1,10 +1,10 @@ // BUSYBOX MD5 code, repurposed for the function in SlideScript // Licensing and contributions to the BusyBox development team, changes -// and cleanup done by Bob (OldCoder) Kiraly, 2021 +// and cleanup done by Bob (OldCoder) Kiraly, 2022 /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/network.h b/src/inc/network.h index 99ddb6b..356007e 100644 --- a/src/inc/network.h +++ b/src/inc/network.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/pipe.h b/src/inc/pipe.h index 84531db..69b53eb 100644 --- a/src/inc/pipe.h +++ b/src/inc/pipe.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/search.h b/src/inc/search.h index 30335e2..b8031b2 100644 --- a/src/inc/search.h +++ b/src/inc/search.h @@ -1,10 +1,8 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ -#define TMPBUF_LEN 2048 - char *ss_search(const char *filename, FILE *fd, char *pat); diff --git a/src/inc/tar.h b/src/inc/tar.h deleted file mode 100644 index 885c0dd..0000000 --- a/src/inc/tar.h +++ /dev/null @@ -1,164 +0,0 @@ -/* -tar.h -tar data structure and accompanying functions - -Copyright (c) 2015 Jason Lee - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE -*/ - -#ifndef __TAR__ -#define __TAR__ - -#include "x3mem.h" - -UX3_EXT QLIST QM_TAR [ONE]; // Dynamic-memory QLIST - - -extern void tar_free_pool (void); - -#ifndef _DEFAULT_SOURCE -#define _DEFAULT_SOURCE -#endif - -#define DEFAULT_DIR_MODE S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH // 0755 - -#define BLOCKSIZE 512 -#define BLOCKING_FACTOR 20 -#define RECORDSIZE 10240 - -// file type values (1 octet) -#define REGULAR 0 -#define NORMAL '0' -#define HARDLINK '1' -#define SYMLINK '2' -#define CHAR '3' -#define BLOCK '4' -#define DIRECTORY '5' -#define FIFO '6' -#define CONTIGUOUS '7' - -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) - -// tar entry metadata structure (singly-linked list) -struct tar_t { - char original_name[100]; // original filenme; only availible when writing into a tar - unsigned int begin; // location of data in file (including metadata) - union { - union { - // Pre-POSIX.1-1988 format - struct { - char name[100]; // file name - char mode[8]; // permissions - char uid[8]; // user id (octal) - char gid[8]; // group id (octal) - char size[12]; // size (octal) - char mtime[12]; // modification time (octal) - char check[8]; // sum of unsigned characters in block, with spaces in the check field while calculation is done (octal) - char link; // link indicator - char link_name[100]; // name of linked file - }; - - // UStar format (POSIX IEEE P1003.1) - struct { - char old[156]; // first 156 octets of Pre-POSIX.1-1988 format - char type; // file type - char also_link_name[100]; // name of linked file - char ustar[8]; // ustar\000 - char owner[32]; // user name (string) - char group[32]; // group name (string) - char major[8]; // device major number - char minor[8]; // device minor number - char prefix[155]; - }; - }; - - char block[512]; // raw memory (500 octets of actual data, padded to 1 block) - }; - - struct tar_t * next; -}; - -// core functions ////////////////////////////////////////////////////////////// -// read a tar file -// archive should be address to null pointer -int tar_read(const int fd, struct tar_t ** archive, const char verbosity); - -// write to a tar file -// if archive contains data, the new data will be appended to the back of the file (terminating blocks will be rewritten) -int tar_write(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); - -// recursive freeing of entries -void tar_free(struct tar_t * archive); -// ///////////////////////////////////////////////////////////////////////////// - -// utilities /////////////////////////////////////////////////////////////////// -// print contents of archive -// verbosity should be greater than 0 -int tar_ls(FILE * f, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); - -// extracts files from an archive -int tar_extract(const int fd, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); - -// update files in tar with provided list -int tar_update(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); - -// remove entries from tar -int tar_remove(const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity); - -// show files that are missing from the current directory -int tar_diff(FILE * f, struct tar_t * archive, const char verbosity); -// ///////////////////////////////////////////////////////////////////////////// - -// internal functions; generally don't call from outside /////////////////////// -// print raw data with definitions (meant for debugging) -int print_entry_metadata(FILE * f, struct tar_t * entry); - -// print metadata of entire tar file -int print_tar_metadata(FILE * f, struct tar_t * archive); - -// check if file with original name/modified name exists -struct tar_t * exists(struct tar_t * archive, const char * filename, const char ori); - -// read file and construct metadata -int format_tar_data(struct tar_t * entry, const char * filename, const char verbosity); - -// calculate checksum (6 ASCII octet digits + NULL + space) -unsigned int calculate_checksum(struct tar_t * entry); - -// print single entry -// verbosity should be greater than 0 -int ls_entry(FILE * f, struct tar_t * archive, const size_t filecount, const char * files[], const char verbosity); - -// extracts a single entry -// expects file descriptor offset to already be set to correct location -int extract_entry(const int fd, struct tar_t * entry, const char verbosity); - -// write entries to a tar file -int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, const size_t filecount, const char * files[], int * offset, const char verbosity); - -// add ending data -int write_end_data(const int fd, int size, const char verbosity); - -// check if entry is a match for any of the given file names -// returns index + 1 if match is found -int check_match(struct tar_t * entry, const size_t filecount, const char * files[]); -// ///////////////////////////////////////////////////////////////////////////// - -#endif diff --git a/src/inc/util.h b/src/inc/util.h index 521d9c2..54209dd 100644 --- a/src/inc/util.h +++ b/src/inc/util.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -40,3 +40,4 @@ char *ss_concat(char *str1, char *str2); void parse_args(int argc, char** argv); char *ss_time(); void gen_random_string(char *s, const int len); +char *remove_extension(char *string); diff --git a/src/inc/vars.h b/src/inc/vars.h index e421ee8..e6fc72a 100644 --- a/src/inc/vars.h +++ b/src/inc/vars.h @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/inc/x3mem.h b/src/inc/x3mem.h index f794ca8..af96ddf 100644 --- a/src/inc/x3mem.h +++ b/src/inc/x3mem.h @@ -4,7 +4,7 @@ // Filename: x3mem.h // Purpose: Memory management -// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021. +// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2022. /* ------------------------------------------------------------ */ /* header file setup */ diff --git a/src/inset.c b/src/inset.c index aca54aa..9118efe 100644 --- a/src/inset.c +++ b/src/inset.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -8,7 +8,6 @@ #include "inc/deps.h" #include "inc/inset.h" #include "inc/lexer.h" -#include "inc/tar.h" #include "inc/vars.h" #include "inc/util.h" diff --git a/src/lexer.c b/src/lexer.c index 183c363..3545a1a 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -15,9 +15,7 @@ #include "inc/network.h" #include "inc/search.h" #include "inc/inset.h" - -// For slidescript compression algorithm -#include "inc/tar.h" +// For compression! #include "lz78/wrapper.h" #define strtok_next(s) strtok_r (NULL, s, &strtok_save) @@ -57,6 +55,15 @@ char *process_line (char *line) { x_warn(":ss:help:\n%s", FUNCTION_HELP); return NULL; + + /* if(strncmp("read", tok_srch[5], 4) == 0) + { + + } + else if() + { + + }*/ } // Lets add if and loop statements, make this @@ -485,9 +492,8 @@ char *process_line (char *line) /* COMPRESSION AND DECOMPRESSION */ else if (strncmp("decompress",tok_srch,10) == 0) { - char *filename; - struct tar_t *archive = NULL; - int fd, lzret; + char *filename, *decomp_filename; + int lzret; wrapper *lzwrapper; int bsize = B_SIZE_DEFAULT; uint8_t w_mode = WRAPPER_MODE_DECOMPRESS; @@ -502,17 +508,14 @@ char *process_line (char *line) return NULL; } - if (strtok_next ("\"")==NULL) + if (strtok_next ("\"") == NULL) { x_warn("ss:warn:decompress syntax error, missing end quote?"); return NULL; } filename = parse_vars(tok_srch); - - char filedecout[128]; - - sprintf(filedecout, "uncompressed.tar"); + decomp_filename = remove_extension(parse_vars(tok_srch)); if (bsize <= 0) { x_warn("ss:warn:compress, default buffer not set?"); @@ -527,8 +530,8 @@ char *process_line (char *line) } /* Executes the wrapper function */ - lzret = wrapper_exec(lzwrapper, filename, filedecout); - + lzret = wrapper_exec(lzwrapper, filename, decomp_filename); + if (lzret != WRAPPER_SUCCESS) { x_warn("ss:warn:decompress, failed to decompress tarball: %d", lzret); @@ -536,34 +539,7 @@ char *process_line (char *line) } /* Destroyes the wrapper instance */ - //wrapper_destroy(lzwrapper); - - // open existing file - if ((fd = open(filedecout, O_RDWR)) < 0) { - x_warn("ss:warn:decompress, failed to tar open archive"); - return NULL; - } - - // read in data - if (tar_read(fd, &archive, '1') < 0) { - close(fd); - x_warn("ss:warn:decompress, failed to read archive"); - return NULL; - } - - // perform operation - if (tar_extract(fd, archive, 0, NULL, '1') < 0) { // extract entries - x_warn("ss:warn:decompress, error occured"); - return NULL; - } - - usleep(50); - - tar_free(archive); - - close(fd); // don't bother checking for fd < 0 - - remove(filedecout); + wrapper_destroy(lzwrapper); return retbuf; @@ -572,9 +548,9 @@ char *process_line (char *line) /* Compression function of tar */ else if (strncmp("compress",tok_srch,8) == 0) { - char filename[MAX_FILENAME_LEN+1]; // Files to be added into the archive - struct tar_t *archive = NULL; - int fd, lzret; + char filename[MAX_FILENAME_LEN+1]; + char cfilename[MAX_FILENAME_LEN+4]; + int lzret; wrapper *lzwrapper; int bsize = B_SIZE_DEFAULT; uint8_t w_mode = WRAPPER_MODE_COMPRESS; @@ -582,7 +558,6 @@ char *process_line (char *line) retbuf = qmalloc(QM_SS, 8129); - tar_free_pool(); tok_srch = strtok_next ("\""); if (tok_srch == NULL) { @@ -590,16 +565,11 @@ char *process_line (char *line) return NULL; } - if (strcmp(tok_srch, "\n") == 0 || strcmp(tok_srch, " \n") == 0) - { - x_warn("ss:warn:compress syntax error, missing archive name..."); - return NULL; - } - // Save tarball filename - if (strlen(parse_vars(tok_srch)) < MAX_FILENAME_LEN) + if (strlen(parse_vars(tok_srch)+3) < MAX_FILENAME_LEN) { sprintf(filename, "%s", parse_vars(tok_srch)); + sprintf(cfilename, "%s.lz", filename); } else { @@ -607,11 +577,6 @@ char *process_line (char *line) return NULL; } - if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) == -1){ - x_warn("ss:warn:compress, failed to open new archive"); - return NULL; - } - tok_srch = strtok_next ("\""); if (tok_srch == NULL) { @@ -619,52 +584,6 @@ char *process_line (char *line) return NULL; } - tok_srch = strtok_next ("\""); - if (tok_srch == NULL) - { - x_warn("ss:warn:compress syntax error, missing quote?"); - return NULL; - } - - if (strcmp(tok_srch, "\n") == 0 || strcmp(tok_srch, " \n") == 0) - { - x_warn("ss:warn:compress, missing file path (what are we gonna compress?)"); - return NULL; - } - - if (strtok_next ("\"")==NULL) - { - x_warn("ss:warn:compress syntax error, missing end quote?"); - return NULL; - } - - int argc = 0; - char *argv [MAX_FILES]; - char *alt_save; - char *p2 = strtok_r (tok_srch, " ", &alt_save); - - while (p2 && argc < MAX_FILES-1) - { - argv[argc++] = p2; - p2 = strtok_r (NULL, " ", &alt_save); - } - - argv[argc] = 0; - const char **tarin = (const char **) &argv[0]; - - if (tar_write(fd, &archive, argc, tarin, '1') < 0) { - x_warn("ss:warn:compress, failed to create tar archive"); - return NULL; - } - - tar_free(archive); - - close(fd); // don't bother checking for fd < 0 - - char file_comp[MAX_FILENAME_LEN+9]; - - sprintf(file_comp, "%s.tar.ss", filename); - if (bsize <= 0) { x_warn("ss:warn:compress, default buffer not set?"); return NULL; @@ -678,7 +597,7 @@ char *process_line (char *line) } /* Executes the wrapper function */ - lzret = wrapper_exec(lzwrapper, filename, file_comp); + lzret = wrapper_exec(lzwrapper, filename, cfilename); if (lzret != WRAPPER_SUCCESS) { @@ -687,15 +606,12 @@ char *process_line (char *line) } else { - sprintf(retbuf, "Compressed -> %s.tar.ss", filename); + sprintf(retbuf, "Compressed -> %s.lz", filename); } /* Destroyes the wrapper instance */ wrapper_destroy(lzwrapper); - // Remove the decompressed version for sanity check - remove(filename); - return retbuf; } diff --git a/src/main.c b/src/main.c index 812ed43..c209cec 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -14,7 +14,6 @@ #include "inc/util.h" #include "inc/lexer.h" #include "inc/pipe.h" -#include "inc/tar.h" #include "inc/inset.h" #include "inc/vars.h" @@ -66,7 +65,6 @@ int main(int argc, char **argv) pipechk = get_cmd_count(); return_dat = process_line(spipe[0].command); - tar_free_pool(); // Blank line, getting up outta here. if(return_dat == NULL) continue; @@ -79,7 +77,6 @@ int main(int argc, char **argv) set_var(varc, "PIPE", return_dat); // Process functions based on previous pipe return return_dat = process_line(spipe[ii].command); - tar_free_pool(); set_var(varc, "\0", "\0"); diff --git a/src/math.c b/src/math.c index 262e6f4..1c7a537 100644 --- a/src/math.c +++ b/src/math.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/md5.c b/src/md5.c index 508c480..bfe6967 100644 --- a/src/md5.c +++ b/src/md5.c @@ -1,10 +1,10 @@ // BUSYBOX MD5 code, repurposed for the function in SlideScript // Licensing and contributions to the BusyBox development team, changes -// and cleanup done by Bob (OldCoder) Kiraly, 2021 +// and cleanup done by Bob (OldCoder) Kiraly, 2022 /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/network.c b/src/network.c index aa71492..11d2a10 100644 --- a/src/network.c +++ b/src/network.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/pipe.c b/src/pipe.c index 0e6cbbf..18f01c7 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/search.c b/src/search.c index 2682f51..b39b705 100644 --- a/src/search.c +++ b/src/search.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -18,7 +18,6 @@ char *ss_search(const char *filename, FILE *fp, char *pat) char *s_buf = NULL; size_t size = 0; int ret; - char tmpbuf[TMPBUF_LEN+1]; int flags = REG_NOSUB; /* don't need where-matched info */ bzero(retbuf, MAX_SEARCH_LEN); @@ -40,9 +39,10 @@ char *ss_search(const char *filename, FILE *fp, char *pat) { if(strlen(s_buf) < MAX_SEARCH_LEN) { + char tmpbuf[strlen(s_buf) + strlen(filename) + 7]; sprintf(tmpbuf, "ss: %s: %s", filename, s_buf); strcat(retbuf, tmpbuf); - bzero(tmpbuf, TMPBUF_LEN); + bzero(tmpbuf, strlen(tmpbuf)); } else { diff --git a/src/tar.c b/src/tar.c deleted file mode 100644 index c74fdcf..0000000 --- a/src/tar.c +++ /dev/null @@ -1,1233 +0,0 @@ -#include "inc/deps.h" -#include "inc/util.h" -#include "inc/tar.h" - -#define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#define MAX(x, y) (((x) > (y)) ? (x) : (y)) -// only print in verbose mode -#define V_PRINT(f, fmt, ...) if (verbosity) { fprintf(f, fmt "\n", ##__VA_ARGS__); } -// generic error -#define ERROR(fmt, ...) fprintf(stderr, "Error: " fmt "\n", ##__VA_ARGS__); return -1; -// capture errno when erroring -#define RC_ERROR(fmt, ...) const int rc = errno; ERROR(fmt, ##__VA_ARGS__); return -1; -#define WRITE_ERROR(fmt, ...) { ERROR(fmt, ##__VA_ARGS__); tar_free(*archive); *archive = NULL; return -1; } -#define EXIST_ERROR(fmt, ...) const int rc = errno; if (rc != EEXIST) { ERROR(fmt, ##__VA_ARGS__); return -1; } - -// force read() to complete -static int read_size(int fd, char * buf, int size); - -// force write() to complete -static int write_size(int fd, char * buf, int size); - -// convert octal string to unsigned integer -static unsigned int oct2uint(char * oct, unsigned int size); - -// check if a buffer is zeroed -static int iszeroed(char * buf, size_t size); - -// make directory recursively -static int recursive_mkdir(const char * dir, const unsigned int mode); - -int tar_read (const int fd, - struct tar_t **archive, const char verbosity) -{ - if (fd < 0) - { - ERROR("Bad file descriptor"); - } - - if (!archive || *archive) - { - ERROR("Bad archive"); - } - - unsigned int offset = 0; - int count = 0; - - struct tar_t ** tar = archive; - char update = 1; - - for(count = 0; ; count++) - { - *tar = qmalloc (QM_TAR, sizeof (struct tar_t)); - if (update && (read_size(fd, (*tar) -> block, 512) != 512)) - { - V_PRINT(stderr, "Error: Bad read. Stopping"); - tar_free(*tar); - *tar = NULL; - break; - } - - update = 1; - // if current block is all zeros - if (iszeroed((*tar) -> block, 512)) - { - if (read_size(fd, (*tar) -> block, 512) != 512) - { - V_PRINT(stderr, "Error: Bad read. Stopping"); - tar_free(*tar); - *tar = NULL; - break; - } - - // check if next block is all zeros as well - if (iszeroed((*tar) -> block, 512)) - { - tar_free(*tar); - *tar = NULL; - - // skip to end of record - if (lseek(fd, RECORDSIZE - (offset % RECORDSIZE), SEEK_CUR) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - - break; - } - - update = 0; - } - - // set current entry's file offset - (*tar) -> begin = offset; - - // skip over data and unfilled block - unsigned int jump = oct2uint((*tar) -> size, 11); - - if (jump % 512) - { - jump += 512 - (jump % 512); - } - - // move file descriptor - offset += 512 + jump; - - if (lseek(fd, jump, SEEK_CUR) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - - // ready next value - tar = &((*tar) -> next); - } - - return count; -} - -int tar_write (const int fd, - struct tar_t ** archive, - const size_t filecount, - const char * files[], - const char verbosity) -{ - if (fd < 0) - { - ERROR("Bad file descriptor"); - } - - if (!archive) - { - ERROR("Bad archive"); - } - - // where file descriptor offset is - int offset = 0; - - // if there is old data - struct tar_t ** tar = archive; - - if (*tar) - { - // skip to last entry - while (*tar && (*tar) -> next) - { - tar = &((*tar) -> next); - } - - // get offset past final entry - unsigned int jump = 512 + oct2uint((*tar) -> size, 11); - if (jump % 512) - { - jump += 512 - (jump % 512); - } - - // move file descriptor - offset = (*tar) -> begin + jump; - if (lseek(fd, offset, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - tar = &((*tar) -> next); - } - - // write entries first - if (write_entries (fd, tar, archive, - filecount, files, &offset, verbosity) < 0) - { - WRITE_ERROR("Failed to write entries"); - } - - // write ending data - if (write_end_data(fd, offset, verbosity) < 0) - { - ERROR("Failed to write end data"); - } - - // clear original names from data - tar = archive; - - while (*tar) - { - memset((*tar) -> name, 0, 100); - tar = &((*tar) -> next); - } - - return offset; -} - -static void *woof (void *bark) -{ - return (bark); -} - -void tar_free (struct tar_t *archive) -{ - // Silence "gcc" - (void) woof ((void *) archive); - -#ifdef NOTDEF - while (archive) - { - struct tar_t * next = archive -> next; - free(archive); - archive = next; - } -#endif -} - -void tar_free_pool (void) -{ - qflush (QM_TAR); -} - -int tar_ls (FILE * f, - struct tar_t * archive, - const size_t filecount, - const char * files[], - const char verbosity) -{ - if (!verbosity) - { - return 0; - } - - if (filecount && !files) - { - ERROR("Non-zero file count provided, but file list is NULL"); - } - - while (archive) - { - if (ls_entry(f, archive, filecount, files, verbosity) < 0) - { - return -1; - } - archive = archive -> next; - } - - return 0; -} - -int tar_extract (const int fd, - struct tar_t * archive, - const size_t filecount, - const char * files[], - const char verbosity) -{ - int ret = 0; - - // extract entries with given names - if (filecount) - { - if (!files) - { - ERROR("Received non-zero file count but got NULL file list"); - } - - while (archive) - { - for(size_t i = 0; i < filecount; i++) - { - if (!strncmp(archive -> name, files[i], MAX(strlen(archive -> name), strlen(files[i])))) - { - if (lseek(fd, archive -> begin, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - - if (extract_entry(fd, archive, verbosity) < 0) - { - ret = -1; - } - break; - } - } - archive = archive -> next; - } - } - // extract all - else - { - // move offset to beginning - if (lseek(fd, 0, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - - // extract each entry - while (archive) - { - if (extract_entry(fd, archive, verbosity) < 0) - { - ret = -1; - } - archive = archive -> next; - } - } - - return ret; -} - -int tar_update (const int fd, - struct tar_t ** archive, - const size_t filecount, - const char * files[], - const char verbosity) -{ - if (!filecount) - { - return 0; - } - - if (filecount && !files) - { - ERROR("Non-zero file count provided, but file list is NULL"); - } - - // buffer for subset of files that need to be updated - char ** newer = qcalloc (QM_TAR, filecount, sizeof(char *)); - - struct stat st; - int count = 0; - int all = 1; - - // check each source to see if it was updated - struct tar_t * tar = *archive; - for(int i = 0; i < (int)filecount; i++) - { - // make sure original file exists - if (lstat(files[i], &st)) - { - all = 0; - RC_ERROR("Could not stat %s: %s", files[i], strerror(rc)); - } - - // find the file in the archive - struct tar_t * old = exists(tar, files[i], 1); - newer[count] = qcalloc (QM_TAR, - strlen (files [i]) + 1, sizeof (char)); - - // if there is an older version, check its timestamp - if (old) - { - if (st.st_mtime > oct2uint(old -> mtime, 11)) - { - strcpy(newer[count++], files[i]); - V_PRINT(stdout, "%s", files[i]); - } - } - // if there is no older version, just add it - else - { - strcpy(newer[count++], files[i]); - V_PRINT(stdout, "%s", files[i]); - } - } - - // update listed files only - if (tar_write(fd, archive, count, (const char **) newer, verbosity) < 0) - { - ERROR("Unable to update archive"); - } - - // cleanup - for(int i = 0; i < count; i++) - { - // free(newer[i]); - } - // free(newer); - - return all?0:-1; -} - -int tar_remove (const int fd, struct tar_t ** archive, const size_t filecount, const char * files[], const char verbosity) -{ - if (fd < 0) - { - return -1; - } - - // archive has to exist - if (!archive || !*archive) - { - ERROR("Got bad archive"); - } - - if (filecount && !files) - { - ERROR("Non-zero file count provided, but file list is NULL"); - } - - if (!filecount) - { - V_PRINT(stderr, "No entries specified"); - return 0; - } - - // get file permissions - struct stat st; - if (fstat(fd, &st)) - { - RC_ERROR("Unable to stat archive: %s", strerror(rc)); - } - - // reset offset of original file - if (lseek(fd, 0, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Unable to seek file: %s", strerror(rc)); - } - - // find first file to be removed that does not exist - int ret = 0; - - for(int i = 0; i < (int)filecount; i++) - { - if (!exists(*archive, files[i], 0)) - { - ERROR("'%s' not found in archive", files[i]); - } - } - - unsigned int read_offset = 0; - unsigned int write_offset = 0; - struct tar_t * prev = NULL; - struct tar_t * curr = *archive; - - while(curr) - { - // get original size - int total = 512; - - if ((curr -> type == REGULAR) || (curr -> type == NORMAL) || (curr -> type == CONTIGUOUS)) - { - total += oct2uint(curr -> size, 11); - if (total % 512) - { - total += 512 - (total % 512); - } - } - - const int match = check_match(curr, filecount, files); - - if (match < 0) - { - ERROR("Match failed"); - } - else if (!match) - { - // if the old data is not in the right place, move it - if (write_offset < read_offset) - { - int got = 0; - while (got < total) - { - // go to old data - if (lseek(fd, read_offset, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Cannot seek: %s", strerror(rc)); - } - - char buf[512]; - - // copy chunk out - if (read_size(fd, buf, 512) != 512) - {// guaranteed 512 octets - ERROR("Read error"); - } - - // go to new position - if (lseek(fd, write_offset, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Cannot seek: %s", strerror(rc)); - } - - // write data in - if (write_size(fd, buf, 512) != 512) - { - RC_ERROR("Write error: %s", strerror(rc)); - } - - // increment offsets - got += 512; - read_offset += 512; - write_offset += 512; - } - } - else - { - read_offset += total; - write_offset += total; - - // skip past data - if (lseek(fd, read_offset, SEEK_SET) == (off_t) (-1)) - { - RC_ERROR("Cannot seek: %s", strerror(rc)); - } - } - prev = curr; - curr = curr -> next; - } - else - {// if name matches, skip the data - // struct tar_t * tmp = curr; - if (!prev) - { - *archive = curr -> next; - if (*archive) - { - (*archive) -> begin = 0; - } - } - else - { - prev -> next = curr -> next; - - if (prev -> next) - { - prev -> next -> begin = curr -> begin; - } - } - - curr = curr -> next; - // free(tmp); - - // next read starts after current entry - read_offset += total; - } - } - - // resize file - if (ftruncate(fd, write_offset) < 0) - { - RC_ERROR("Could not truncate file: %s", strerror(rc)); - } - - // add end data - if (write_end_data(fd, write_offset, verbosity) < 0) - { - V_PRINT(stderr, "Error: Could not close file"); - } - - return ret; -} - -int tar_diff (FILE * f, struct tar_t * archive, const char verbosity) -{ - struct stat st; - while (archive) - { - V_PRINT(f, "%s", archive -> name); - - // if not found, print error - if (lstat(archive -> name, &st)) - { - int rc = errno; - fprintf(f, "Could not "); - if (archive -> type == SYMLINK) - { - fprintf(f, "readlink"); - } - else - { - fprintf(f, "stat"); - } - fprintf(f, " %s: %s", archive -> name, strerror(rc)); - } - else - { - if (st.st_mtime != oct2uint(archive -> mtime, 11)) - { - fprintf(f, "%s: Mod time differs", archive -> name); - } - if (st.st_size != oct2uint(archive -> size, 11)) - { - fprintf(f, "%s: Mod time differs", archive -> name); - } - } - - archive = archive -> next; - } - return 0; -} - -int print_entry_metadata(FILE * f, struct tar_t * entry) -{ - if (!entry){ - return -1; - } - - time_t mtime = oct2uint(entry -> mtime, 12); - char mtime_str[32]; - strftime(mtime_str, sizeof(mtime_str), "%c", localtime(&mtime)); - fprintf(f, "File Name: %s\n", entry -> name); - fprintf(f, "File Mode: %s (%03o)\n", entry -> mode, oct2uint(entry -> mode, 8)); - fprintf(f, "Owner UID: %s (%d)\n", entry -> uid, oct2uint(entry -> uid, 12)); - fprintf(f, "Owner GID: %s (%d)\n", entry -> gid, oct2uint(entry -> gid, 12)); - fprintf(f, "File Size: %s (%d)\n", entry -> size, oct2uint(entry -> size, 12)); - fprintf(f, "Time : %s (%s)\n", entry -> mtime, mtime_str); - fprintf(f, "Checksum : %s\n", entry -> check); - fprintf(f, "File Type: "); - switch (entry -> type){ - case REGULAR: case NORMAL: - fprintf(f, "Normal File"); - break; - case HARDLINK: - fprintf(f, "Hard Link"); - break; - case SYMLINK: - fprintf(f, "Symbolic Link"); - break; - case CHAR: - fprintf(f, "Character Special"); - break; - case BLOCK: - fprintf(f, "Block Special"); - break; - case DIRECTORY: - fprintf(f, "Directory"); - break; - case FIFO: - fprintf(f, "FIFO"); - break; - case CONTIGUOUS: - fprintf(f, "Contiguous File"); - break; - } - fprintf(f, " (%c)\n", entry -> type?entry -> type:'0'); - fprintf(f, "Link Name: %s\n", entry -> link_name); - fprintf(f, "Ustar\\000: %c%c%c%c%c\\%2x\\%2x\\%02x\n", entry -> ustar[0], entry -> ustar[1], entry -> ustar[2], entry -> ustar[3], entry -> ustar[4], entry -> ustar[5], entry -> ustar[6], entry -> ustar[7]); - fprintf(f, "Username : %s\n", entry -> owner); - fprintf(f, "Group : %s\n", entry -> group); - fprintf(f, "Major : %s\n", entry -> major); - fprintf(f, "Minor : %s\n", entry -> minor); - fprintf(f, "Prefix : %s\n", entry -> prefix); - fprintf(f, "\n"); - - return 0; -} - -int print_tar_metadata(FILE * f, struct tar_t * archive){ - while (archive){ - print_entry_metadata(f, archive); - archive = archive -> next; - } - return 0; -} - -struct tar_t * exists(struct tar_t * archive, const char * filename, const char ori){ - while (archive){ - if (ori){ - if (!strncmp(archive -> original_name, filename, MAX(strlen(archive -> original_name), strlen(filename)) + 1)){ - return archive; - } - } - else{ - if (!strncmp(archive -> name, filename, MAX(strlen(archive -> name), strlen(filename)) + 1)){ - return archive; - } - } - archive = archive -> next; - } - return NULL; -} - -int format_tar_data(struct tar_t * entry, const char * filename, const char verbosity){ - if (!entry){ - ERROR("Bad destination entry"); - } - - struct stat st; - if (lstat(filename, &st)){ - RC_ERROR("Cannot stat %s: %s", filename, strerror(rc)); - } - - // remove relative path - int move = 0; - if (!strncmp(filename, "/", 1)){ - move = 1; - } - else if (!strncmp(filename, "./", 2)){ - move = 2; - } - else if (!strncmp(filename, "../", 3)){ - move = 3; - } - - // start putting in new data (all fields are NULL terminated ASCII strings) - memset(entry, 0, sizeof(struct tar_t)); - strcpy(entry -> original_name, filename); - strcpy(entry -> name, filename + move); - snprintf(entry -> mode, sizeof(entry -> mode), "%07o", st.st_mode & 0777); - snprintf(entry -> uid, sizeof(entry -> uid), "%07o", st.st_uid); - snprintf(entry -> gid, sizeof(entry -> gid), "%07o", st.st_gid); - snprintf(entry -> size, sizeof(entry -> size), "%011o", (int) st.st_size); - snprintf(entry -> mtime, sizeof(entry -> mtime), "%011o", (int) st.st_mtime); - strncpy(entry -> group, "None", 5); // default value - memcpy(entry -> ustar, "ustar \x00", 8); - - // figure out filename type and fill in type-specific fields - switch (st.st_mode & S_IFMT) { - case S_IFREG: - entry -> type = NORMAL; - break; - case S_IFLNK: - entry -> type = SYMLINK; - - // file size is 0, but will print link size - memset(entry -> size, '0', sizeof(entry -> size) - 1); - - // get link name - if (readlink(filename, entry -> link_name, 100) < 0){ - RC_ERROR("Could not read link %s: %s", filename, strerror(rc)); - } - - break; - case S_IFCHR: - entry -> type = CHAR; - // get character device major and minor values - snprintf(entry -> major, sizeof(entry -> major), "%07o", major(st.st_rdev)); - snprintf(entry -> minor, sizeof(entry -> minor), "%07o", minor(st.st_rdev)); - break; - case S_IFBLK: - entry -> type = BLOCK; - // get block device major and minor values - snprintf(entry -> major, sizeof(entry -> major), "%07o", major(st.st_rdev)); - snprintf(entry -> minor, sizeof(entry -> minor), "%07o", minor(st.st_rdev)); - break; - case S_IFDIR: - memset(entry -> size, '0', 11); - entry -> type = DIRECTORY; - break; - case S_IFIFO: - entry -> type = FIFO; - break; - case S_IFSOCK: - entry -> type = -1; - ERROR("Error: Cannot tar socket"); - default: - entry -> type = -1; - ERROR("Error: Unknown filetype"); - } - - // get username - struct passwd pwd; - char buffer[4096]; - struct passwd * result = NULL; - if (getpwuid_r(st.st_uid, &pwd, buffer, sizeof(buffer), &result)) { - const int err = errno; - V_PRINT(stderr, "Warning: Unable to get username of uid %u for entry '%s': %s", st.st_uid, filename, strerror(err)); - } - - if(sizeof(entry -> owner) < 4096) - { - strcpy(entry -> owner, buffer); - } - else - { - syn_warn("ss:warn:tar, failed to get username entry..."); - } - - // get group name - struct group * grp = getgrgid(st.st_gid); - if (grp){ - strncpy(entry -> group, grp -> gr_name, sizeof(entry -> group) - 1); - } - - // get the checksum - calculate_checksum(entry); - - return 0; -} - -unsigned int calculate_checksum(struct tar_t * entry){ - // use spaces for the checksum bytes while calculating the checksum - memset(entry -> check, ' ', 8); - - // sum of entire metadata - unsigned int check = 0; - for(int i = 0; i < 512; i++){ - check += (unsigned char) entry -> block[i]; - } - - snprintf(entry -> check, sizeof(entry -> check), "%06o0", check); - - entry -> check[6] = '\0'; - entry -> check[7] = ' '; - return check; -} - -int ls_entry(FILE * f, struct tar_t * entry, const size_t filecount, const char * files[], const char verbosity){ - if (!verbosity){ - return 0; - } - - if (filecount && !files){ - V_PRINT(stderr, "Error: Non-zero file count given but no files given"); - return -1; - } - - // figure out whether or not to print - // if no files were specified, print everything - char print = !filecount; - // otherwise, search for matching names - for(size_t i = 0; i < filecount; i++){ - if (strncmp(entry -> name, files[i], MAX(strlen(entry -> name), strlen(files[i])))){ - print = 1; - break; - } - } - - if (print){ - if (verbosity > 1){ - const mode_t mode = oct2uint(entry -> mode, 7); - const char mode_str[26] = { "-hlcbdp-"[entry -> type?entry -> type - '0':0], - mode & S_IRUSR?'r':'-', - mode & S_IWUSR?'w':'-', - mode & S_IXUSR?'x':'-', - mode & S_IRGRP?'r':'-', - mode & S_IWGRP?'w':'-', - mode & S_IXGRP?'x':'-', - mode & S_IROTH?'r':'-', - mode & S_IWOTH?'w':'-', - mode & S_IXOTH?'x':'-', - 0}; - fprintf(f, "%s %s/%s ", mode_str, entry -> owner, entry -> group); - char size_buf[22] = {0}; - int rc = -1; - switch (entry -> type){ - case REGULAR: case NORMAL: case CONTIGUOUS: - rc = sprintf(size_buf, "%u", oct2uint(entry -> size, 11)); - break; - case HARDLINK: case SYMLINK: case DIRECTORY: case FIFO: - rc = sprintf(size_buf, "%u", oct2uint(entry -> size, 11)); - break; - case CHAR: case BLOCK: - rc = sprintf(size_buf, "%d,%d", oct2uint(entry -> major, 7), oct2uint(entry -> minor, 7)); - break; - } - - if (rc < 0){ - ERROR("Failed to write length"); - } - - fprintf(f, "%s", size_buf); - - time_t mtime = oct2uint(entry -> mtime, 11); - struct tm * time = localtime(&mtime); - fprintf(f, " %d-%02d-%02d %02d:%02d ", time -> tm_year + 1900, time -> tm_mon + 1, time -> tm_mday, time -> tm_hour, time -> tm_min); - } - - fprintf(f, "%s", entry -> name); - - if (verbosity > 1){ - switch (entry -> type){ - case HARDLINK: - fprintf(f, " link to %s", entry -> link_name); - break; - case SYMLINK: - fprintf(f, " -> %s", entry -> link_name); - break; - break; - } - } - - fprintf(f, "\n"); - } - - return 0; -} - -int extract_entry(const int fd, struct tar_t * entry, const char verbosity){ - V_PRINT(stdout, "%s", entry -> name); - - if ((entry -> type == REGULAR) || (entry -> type == NORMAL) || (entry -> type == CONTIGUOUS)){ - // create intermediate directories - size_t len = strlen(entry -> name); - if (!len) - { - ERROR("Attempted to extract entry with empty name"); - } - - char * path = qcalloc (QM_TAR, len + 1, sizeof(char)); - strcpy(path, entry -> name); - - // remove file from path - while (--len && (path[len] != '/')); - path[len] = '\0'; // if nothing was found, path is terminated - - if (recursive_mkdir(path, DEFAULT_DIR_MODE) < 0){ - V_PRINT(stderr, "Could not make directory %s", path); - // free(path); - return -1; - } - // free(path); - - // create file - const unsigned int size = oct2uint(entry -> size, 11); - int f = open(entry -> name, O_WRONLY | O_CREAT | O_TRUNC, oct2uint(entry -> mode, 7) & 0777); - if (f < 0){ - RC_ERROR("Unable to open file %s: %s", entry -> name, strerror(rc)); - } - - // move archive pointer to data location - if (lseek(fd, 512 + entry -> begin, SEEK_SET) == (off_t) (-1)){ - RC_ERROR("Bad index: %s", strerror(rc)); - } - - // copy data to file - char buf[512]; - int got = 0; - while (got < (int)size){ - int r; - if ((r = read_size(fd, buf, MIN(size - got, 512))) < 0){ - EXIST_ERROR("Unable to read from archive: %s", strerror(rc)); - } - - if (write(f, buf, r) != r){ - EXIST_ERROR("Unable to write to %s: %s", entry -> name, strerror(rc)); - } - - got += r; - } - - close(f); - } - else if ((entry -> type == CHAR) || (entry -> type == BLOCK)){ - if (mknod(entry -> name, oct2uint(entry -> mode, 7), (oct2uint(entry -> major, 7) << 20) | oct2uint(entry -> minor, 7)) < 0){ - EXIST_ERROR("Unable to make device %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == HARDLINK){ - if (link(entry -> link_name, entry -> name) < 0){ - EXIST_ERROR("Unable to create hardlink %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == SYMLINK){ - if (symlink(entry -> link_name, entry -> name) < 0){ - EXIST_ERROR("Unable to make symlink %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == CHAR){ - if (mknod(entry -> name, S_IFCHR | (oct2uint(entry -> mode, 7) & 0777), (oct2uint(entry -> major, 7) << 20) | oct2uint(entry -> minor, 7)) < 0){ - EXIST_ERROR("Unable to create directory %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == BLOCK){ - if (mknod(entry -> name, S_IFBLK | (oct2uint(entry -> mode, 7) & 0777), (oct2uint(entry -> major, 7) << 20) | oct2uint(entry -> minor, 7)) < 0){ - EXIST_ERROR("Unable to create directory %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == DIRECTORY){ - if (recursive_mkdir(entry -> name, oct2uint(entry -> mode, 7) & 0777) < 0){ - EXIST_ERROR("Unable to create directory %s: %s", entry -> name, strerror(rc)); - } - } - else if (entry -> type == FIFO){ - if (mkfifo(entry -> name, oct2uint(entry -> mode, 7) & 0777) < 0){ - EXIST_ERROR("Unable to make pipe %s: %s", entry -> name, strerror(rc)); - } - } - return 0; -} - -int write_entries(const int fd, struct tar_t ** archive, struct tar_t ** head, const size_t filecount, const char * files[], int * offset, const char verbosity){ - if (fd < 0){ - ERROR("Bad file descriptor"); - } - - if (!archive || *archive){ - ERROR("Bad archive"); - } - - if (filecount && !files){ - ERROR("Non-zero file count provided, but file list is NULL"); - } - - // add new data - struct tar_t ** tar = archive; // current entry - for(unsigned int i = 0; i < filecount; i++){ - *tar = malloc(sizeof(struct tar_t)); - - // stat file - if (format_tar_data(*tar, files[i], verbosity) < 0){ - WRITE_ERROR("Failed to stat %s", files[i]); - } - - (*tar) -> begin = *offset; - - // directories need special handling - if ((*tar) -> type == DIRECTORY){ - // save parent directory name (source will change) - const size_t len = strlen((*tar) -> name); - char * parent = qcalloc (QM_TAR, len + 1, sizeof(char)); - strncpy(parent, (*tar) -> name, len); - - // add a '/' character to the end - if ((len < 99) && ((*tar) -> name[len - 1] != '/')){ - (*tar) -> name[len] = '/'; - (*tar) -> name[len + 1] = '\0'; - calculate_checksum(*tar); - } - - V_PRINT(stdout, "Writing %s", (*tar) -> name); - - // write metadata to (*tar) file - if (write_size(fd, (*tar) -> block, 512) != 512){ - WRITE_ERROR("Failed to write metadata to archive"); - } - - // go through directory - DIR * d = opendir(parent); - if (!d){ - WRITE_ERROR("Cannot open directory %s", parent); - } - - struct dirent * dir; - while ((dir = readdir(d))){ - // if not special directories . and .. - const size_t sublen = strlen(dir -> d_name); - if (strncmp(dir -> d_name, ".", sublen) && strncmp(dir -> d_name, "..", sublen)){ - char * path = qcalloc (QM_TAR, - len + sublen + 2, sizeof(char)); - sprintf(path, "%s/%s", parent, dir -> d_name); - - // recursively write each subdirectory - if (write_entries(fd, &((*tar) -> next), head, 1, (const char **) &path, offset, verbosity) < 0){ - WRITE_ERROR("Recurse error"); - } - - // go to end of new data - while ((*tar) -> next){ - tar = &((*tar) -> next); - } - - // free(path); - } - } - closedir(d); - - // free(parent); - - tar = &((*tar) -> next); - } - else{ // if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS) || ((*tar) -> type == SYMLINK) || ((*tar) -> type == CHAR) || ((*tar) -> type == BLOCK) || ((*tar) -> type == FIFO)){ - V_PRINT(stdout, "Writing %s", (*tar) -> name); - - char tarred = 0; // whether or not the file has already been put into the archive - if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS) || ((*tar) -> type == SYMLINK)){ - struct tar_t * found = exists(*head, files[i], 1); - tarred = (found != (*tar)); - - // if file has already been included, modify the header - if (tarred){ - // change type to hard link - (*tar) -> type = HARDLINK; - - // change link name to (*tar)red file name (both are the same) - strncpy((*tar) -> link_name, (*tar) -> name, 100); - - // change size to 0 - memset((*tar) -> size, '0', sizeof((*tar) -> size) - 1); - - // recalculate checksum - calculate_checksum(*tar); - } - } - - // write metadata to (*tar) file - if (write_size(fd, (*tar) -> block, 512) != 512){ - WRITE_ERROR("Failed to write metadata to archive"); - } - - if (((*tar) -> type == REGULAR) || ((*tar) -> type == NORMAL) || ((*tar) -> type == CONTIGUOUS)){ - // if the file isn't already in the tar file, copy the contents in - if (!tarred){ - int f = open((*tar) -> name, O_RDONLY); - if (f < 0){ - WRITE_ERROR("Could not open %s", files[i]); - } - - int r = 0; - char buf[512]; - while ((r = read_size(f, buf, 512)) > 0){ - if (write_size(fd, buf, r) != r){ - RC_ERROR("Could not write to archive: %s", strerror(rc)); - } - } - - close(f); - } - } - - // pad data to fill block - const unsigned int size = oct2uint((*tar) -> size, 11); - const unsigned int pad = 512 - size % 512; - if (pad != 512){ - for(unsigned int j = 0; j < pad; j++){ - if (write_size(fd, "\0", 1) != 1){ - WRITE_ERROR("Could not write padding data"); - } - } - *offset += pad; - } - *offset += size; - tar = &((*tar) -> next); - } - - // add metadata size - *offset += 512; - } - - return 0; -} - -int write_end_data(const int fd, int size, const char verbosity){ - if (fd < 0){ - return -1; - } - - // complete current record - const int pad = RECORDSIZE - (size % RECORDSIZE); - for(int i = 0; i < pad; i++){ - if (write(fd, "\0", 1) != 1){ - V_PRINT(stderr, "Error: Unable to close tar file"); - return -1; - } - } - - // if the current record does not have 2 blocks of zeros, add a whole other record - if (pad < (2 * BLOCKSIZE)){ - for(int i = 0; i < RECORDSIZE; i++){ - if (write(fd, "\0", 1) != 1){ - V_PRINT(stderr, "Error: Unable to close tar file"); - return -1; - } - } - return pad + RECORDSIZE; - } - - return pad; -} - -int check_match(struct tar_t * entry, const size_t filecount, const char * files[]){ - if (!entry){ - return -1; - } - - if (!filecount){ - return 0; - } - - if (filecount && !files){ - return -1; - } - - for(size_t i = 0; i < filecount; i++){ - if (!strncmp(entry -> name, files[i], MAX(strlen(entry -> name), strlen(files[i])) + 1)){ - return i + 1; - } - } - - return 0; -} - -int read_size(int fd, char * buf, int size){ - int got = 0, rc; - while ((got < size) && ((rc = read(fd, buf + got, size - got)) > 0)){ - got += rc; - } - return got; -} - -int write_size(int fd, char * buf, int size){ - int wrote = 0, rc; - while ((wrote < size) && ((rc = write(fd, buf + wrote, size - wrote)) > 0)){ - wrote += rc; - } - return wrote; -} - -unsigned int oct2uint(char * oct, unsigned int size){ - unsigned int out = 0; - int i = 0; - while ((i < (int)size) && oct[i]){ - out = (out << 3) | (unsigned int) (oct[i++] - '0'); - } - return out; -} - -int iszeroed(char * buf, size_t size){ - for(size_t i = 0; i < size; buf++, i++){ - if (* (char *) buf){ - return 0; - } - } - return 1; -} - -int recursive_mkdir(const char * dir, const unsigned int mode){ - int rc = 0; - const size_t len = strlen(dir); - - if (!len){ - return 0; - } - - char * path = qcalloc (QM_TAR, len + 1, sizeof(char)); - strcpy(path, dir); - - // remove last '/' - if (path[len - 1] == '/'){ - path[len - 1] = 0; - } - - // all subsequent directories do not exist - for(char * p = path + 1; *p; p++){ - if (*p == '/'){ - *p = '\0'; - - if ((rc = mkdir(path, mode?mode:DEFAULT_DIR_MODE))){ - EXIST_ERROR("Could not create directory %s: %s", path, strerror(rc)); - } - - *p = '/'; - } - } - - if (mkdir(path, mode?mode:DEFAULT_DIR_MODE) < 0){ - EXIST_ERROR("Could not create directory %s: %s", path, strerror(rc)); - } - - // free(path); - return 0; -} diff --git a/src/util.c b/src/util.c index 63393e6..05a0042 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ @@ -109,7 +109,7 @@ void parse_args(int argc, char** argv) /* -v flag given, show version */ else if(argc == 2 && strncmp("-v", argv[1], 2) == 0) { - printf("SlideScript %s, Chris Dorman (cddo@riseup.net), 2021\n", VERSION); + printf("SlideScript %s, Chris Dorman (cddo@riseup.net), 2022\n", VERSION); exit(EXIT_SUCCESS); } @@ -133,3 +133,15 @@ void gen_random_string(char *s, const int len) { s[len] = 0; } + +char *remove_extension(char *string) { + char *ret_string; + char *lastExt; + if (string == NULL) return (char *)NULL; + if ((ret_string = malloc (strlen (string) + 1)) == NULL) return (char *)NULL; + strcpy (ret_string, string); + lastExt = strrchr (ret_string, '.'); + if (lastExt != NULL) + *lastExt = '\0'; + return ret_string; +} diff --git a/src/vars.c b/src/vars.c index a888f68..6fcfa81 100644 --- a/src/vars.c +++ b/src/vars.c @@ -1,6 +1,6 @@ /* SlideScript - minimalistic top-down scripting language. - (C) Copyright 2014-2021 Chris Dorman - some rights reserved (GPLv2) + (C) Copyright 2014-2022 Chris Dorman - some rights reserved (GPLv2) View README file supplied with this software for more details */ diff --git a/src/x3mem.c b/src/x3mem.c index 5adfecb..a157789 100644 --- a/src/x3mem.c +++ b/src/x3mem.c @@ -4,7 +4,7 @@ // Filename: x3mem.c // Purpose: Memory management -// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2021. +// License: MIT/X. (c) OldCoder (Robert Kiraly) 1987-2022. /* ------------------------------------------------------------ */ /* header files */