commit: 8b940079a62153e56f0b935cd3d1facb81cb6bc4
parent fdd47a4aef8b85e440c2c0bbee1a72947521ab9e
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Fri, 16 Aug 2024 01:30:58 +0200
cmd/split: split_bytes function
Diffstat:
M | cmd/split.c | 178 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
1 file changed, 91 insertions(+), 87 deletions(-)
diff --git a/cmd/split.c b/cmd/split.c
@@ -18,14 +18,100 @@
char *argv0 = "split";
+char *name = "x";
+size_t name_len = 1;
+
+size_t suffix_len = 3, bytes = 0, lines = 0;
+char *name_in = NULL;
+
+static int
+split_bytes()
+{
+ int fd_in = STDIN_FILENO;
+ if(name_in != NULL)
+ {
+ fd_in = open(name_in, O_RDONLY | O_NOCTTY);
+ if(fd_in < 0)
+ {
+ fprintf(stderr, "split: Failed opening '%s' file: %s\n", name_in, strerror(errno));
+ return 1;
+ }
+ }
+
+ struct stat fd_in_stat;
+ if(fstat(fd_in, &fd_in_stat) != 0)
+ {
+ fprintf(stderr, "split: Failed getting status from file '%s': %s", name_in, strerror(errno));
+ close(fd_in);
+ return 1;
+ }
+
+ int err = 0;
+ off_t wrote = 0;
+ int split_id = 0;
+ while(wrote < fd_in_stat.st_size)
+ {
+ char name_out[NAME_MAX] = "";
+ memcpy(name_out, name, name_len);
+ memset(name_out + name_len, 'a', suffix_len);
+
+ int id_n = split_id++;
+ size_t id_p = name_len + suffix_len;
+ do
+ {
+ name_out[id_p--] = 'a' + (id_n % 26);
+ id_n /= 26;
+ } while(id_n > 0 && id_p > name_len);
+
+ if(id_p <= name_len)
+ {
+ fprintf(stderr,
+ "split: Failed representing %d into suffix of length %zu\n",
+ split_id,
+ suffix_len);
+ return 1;
+ }
+
+ int fd_out = open(name_out, O_WRONLY | O_NOCTTY | O_CREAT, 0644);
+ if(fd_out < 0)
+ {
+ fprintf(stderr, "split: Failed opening '%s' file: %s\n", name_out, strerror(errno));
+ return 1;
+ }
+
+ int ret = auto_file_copy(fd_in, fd_out, bytes, 0);
+ if(ret < 0)
+ {
+ fprintf(stderr,
+ "split: Error while copying from file '%s' to file '%s': %s\n",
+ name_in ? name_in : "<stdin>",
+ name_out,
+ strerror(errno));
+ close(fd_out);
+ err = 1;
+ break;
+ }
+
+ wrote += ret;
+
+ if(close(fd_out) < 0)
+ {
+ fprintf(stderr, "split: Failing closing file '%s': %s\n", name_out, strerror(errno));
+ err = 1;
+ break;
+ }
+ }
+
+ if(name_in != NULL) close(fd_in);
+
+ return err;
+}
+
static char *error_opt_b_l = "split: Options -b and -l are mutually exclusive\n";
int
main(int argc, char *argv[])
{
- char *name = "x";
- size_t suffix_len = 3, bytes = 0, lines = 0;
-
int c = -1;
while((c = getopt(argc, argv, ":a:b:l:")) != -1)
{
@@ -101,8 +187,6 @@ main(int argc, char *argv[])
if(lines == 0 && bytes == 0) lines = 1000;
- char *name_in = NULL;
-
if(argc > 2 || argc < 0)
{
fprintf(stderr, "split: Expected 0, 1, or 2 arguments, got %d\n", argc);
@@ -115,7 +199,7 @@ main(int argc, char *argv[])
if(argc == 2) name = argv[1];
}
- size_t name_len = strlen(name);
+ name_len = strlen(name);
if(name_len + suffix_len > NAME_MAX)
{
fprintf(stderr,
@@ -126,87 +210,7 @@ main(int argc, char *argv[])
return 1;
}
- if(bytes != 0)
- {
- int fd_in = STDIN_FILENO;
- if(name_in != NULL)
- {
- fd_in = open(name_in, O_RDONLY | O_NOCTTY);
- if(fd_in < 0)
- {
- fprintf(stderr, "split: Failed opening '%s' file: %s\n", name_in, strerror(errno));
- return 1;
- }
- }
-
- struct stat fd_in_stat;
- if(fstat(fd_in, &fd_in_stat) != 0)
- {
- fprintf(stderr, "split: Failed getting status from file '%s': %s", name_in, strerror(errno));
- close(fd_in);
- return 1;
- }
-
- int err = 0;
- off_t wrote = 0;
- int split_id = 0;
- while(wrote < fd_in_stat.st_size)
- {
- char name_out[NAME_MAX] = "";
- memcpy(name_out, name, name_len);
- memset(name_out + name_len, 'a', suffix_len);
-
- int id_n = split_id++;
- size_t id_p = name_len + suffix_len;
- do
- {
- name_out[id_p--] = 'a' + (id_n % 26);
- id_n /= 26;
- } while(id_n > 0 && id_p > name_len);
-
- if(id_p <= name_len)
- {
- fprintf(stderr,
- "split: Failed representing %d into suffix of length %zu\n",
- split_id,
- suffix_len);
- return 1;
- }
-
- int fd_out = open(name_out, O_WRONLY | O_NOCTTY | O_CREAT, 0644);
- if(fd_out < 0)
- {
- fprintf(stderr, "split: Failed opening '%s' file: %s\n", name_out, strerror(errno));
- return 1;
- }
-
- int ret = auto_file_copy(fd_in, fd_out, bytes, 0);
- if(ret < 0)
- {
- fprintf(stderr,
- "split: Error while copying from file '%s' to file '%s': %s\n",
- name_in ? name_in : "<stdin>",
- name_out,
- strerror(errno));
- close(fd_out);
- err = 1;
- break;
- }
-
- wrote += ret;
-
- if(close(fd_out) < 0)
- {
- fprintf(stderr, "split: Failing closing file '%s': %s\n", name_out, strerror(errno));
- err = 1;
- break;
- }
- }
-
- if(name_in != NULL) close(fd_in);
-
- return err;
- }
+ if(bytes != 0) return split_bytes();
return 0;
}