diff options
| author | hiddenalpha.ch | 2026-09-16 23:34:08 +0200 |
|---|---|---|
| committer | hiddenalpha.ch | 2026-09-16 23:34:08 +0200 |
| commit | 317e90597d10dd1b561b2922ed3cf2b90adf3cea (patch) | |
| tree | 1bef4cc64cb2c621fb33db18e4af57b9315a0261 /src | |
| parent | b38ce202e8de807976440f5b1134f028736bb612 (diff) | |
| download | bulk-ln-317e90597d10dd1b561b2922ed3cf2b90adf3cea.tar.gz bulk-ln-317e90597d10dd1b561b2922ed3cf2b90adf3cea.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/bulk_ln.c | 147 |
1 files changed, 69 insertions, 78 deletions
diff --git a/src/bulk_ln.c b/src/bulk_ln.c index a954100..7e53d4d 100644 --- a/src/bulk_ln.c +++ b/src/bulk_ln.c @@ -74,6 +74,29 @@ end #endif +#define FLG_isDryRun (1<<0) +/* If a dry-run got requested + */ +#define FLG_isPrintEachCreateLink (1<<1) +/* If true, we will print to stdout for every link we create (like we do + * in dry run) + */ +#define FLG_isPrintEachMkdir (1<<2) +/* print every call we make to mkdir to stdout. Usually only useful for + * debugging + */ +#define FLG_isPrintStatus (1<<3) +/* if true, we periodically print some kind of progress to stderr + */ +#define FLG_isPrintSummary (1<<4) +/* if true, we print a summary what we did at the end of the run to stderr + */ +#define FLG_isRelinkExistingFiles (1<<5) +/* if true, we will override existing files. This will be enabled for + * example if --force got specified. + */ + + typedef struct BulkLn { /* Root context */ @@ -85,6 +108,10 @@ typedef struct BulkLn { FILE *dataFd; + unsigned flg; + /* bitfield containing flags defined in `FLG_xxx`. + */ + int createdLinksCount; /* Count of links we created */ @@ -93,32 +120,6 @@ typedef struct BulkLn { /* Count of direcrories we created */ - int dryRun; - /* If a dry-run got requested - */ - - int isPrintEachCreateLink; - /* If true, we will print to stdout for every link we create (like we do - * in dry run) - 0*/ - - int isPrintEachMkdir; - /* print every call we make to mkdir to stdout. Usually only useful for - * debugging - */ - - int isPrintStatus; - /* if true, we periodically print some kind of progress to stderr - */ - - int isPrintSummary; - /* if true, we print a summary what we did at the end of the run to stderr - */ - - int isRelinkExistingFiles; - /* if true, we will override existing files. This will be enabled for - * example if --force got specified. - */ } BulkLn; @@ -126,51 +127,51 @@ typedef struct BulkLn { PRIVATE(void) printHelp(){ printf(" \n %s @ " STR_QUOT(PROJECT_VERSION) "\n" - " \n" + "\n" " Takes paths (pairwise) from stdin (see --stdin for details) and\n" " creates a hardlink for each pair from the 1st path to the 2nd.\n" - " \n" + "\n" " Writing a custom implementation of 'ln' got necessary as we found no\n" " way to instruct 'ln' to create a few thousand links in an acceptable\n" " amount of time. Remind that wheels that do not fit should be\n" " re-invented (yes, no matter how much they already exist!). So now we\n" " have it. Our re-invented wheel that finally fits our use-case ;) \n" - " \n" + "\n" " See also\n" " https://pubs.opengroup.org/onlinepubs/009695399/utilities/ln.html\n" " for info about the original 'ln'.\n" - " \n" + "\n" " Options:\n" - " \n" + "\n" " --stdin\n" " Read the path pairs to link from stdin. The format is like:\n" - " \n" + "\n" " <src-path> <tab> <dst-path> <newline>\n" - " \n" + "\n" " Example:\n" - " \n" + "\n" " origin/foo.txt\tnew/gugg.txt\n" " origin/bar.txt\tnew/da.txt\n" - " \n" + "\n" " HINT: Preferred <newline> is LF. But CRLF should work too.\n" - " \n" + "\n" " --quiet\n" " Don't print status or similar stuff. Errors will still be\n" " printed to stderr.\n" - " \n" + "\n" " --verbose\n" " Print stupid amount of logs. Usually only helpful for debugging.\n" " Should NOT be combined with --quiet as this would be nonsense\n" " anyway.\n" - " \n" + "\n" " --dry-run\n" " Will print the actions to stdout instead executing them.\n" " HINT: Directory count in summary will be inaccurate in this\n" " mode.\n" - " \n" + "\n" " --force\n" " Same meaning as in original 'ln' command.\n" - " \n", strrchr(__FILE__,'/')+1 ); + "\n", strrchr(__FILE__,'/')+1 ); } @@ -180,12 +181,7 @@ PRIVATE(int) parseArgs( int argc, char**argv, BulkLn*bulkLn ){ /* init (aka set defaults) */ bulkLn->dataFilePath = NULL; - bulkLn->dryRun = 0; - bulkLn->isPrintEachCreateLink = 0; - bulkLn->isPrintEachMkdir = 0; - bulkLn->isPrintStatus = !0; - bulkLn->isPrintSummary = !0; - bulkLn->isRelinkExistingFiles = 0; + bulkLn->flg = (FLG_isPrintStatus|FLG_isPrintSummary); /* Parse args */ for( int i = 1 ; i < argc ; ++i ){ @@ -195,23 +191,23 @@ parseArgs( int argc, char**argv, BulkLn*bulkLn ){ return -1; } else if( !strcmp(arg, "--dry-run") ){ - bulkLn->dryRun = !0; + bulkLn->flg |= FLG_isDryRun; } else if( !strcmp(arg, "--force") ){ - bulkLn->isRelinkExistingFiles = !0; + bulkLn->flg |= FLG_isRelinkExistingFiles; } else if( !strcmp(arg, "--quiet") ){ - bulkLn->isPrintStatus = 0; - bulkLn->isPrintSummary = 0; + bulkLn->flg &= ~(FLG_isPrintStatus|FLG_isPrintSummary); } else if( !strcmp(arg, "--stdin") ){ bulkLn->dataFilePath = "-"; } else if( !strcmp(arg, "--verbose") ){ - bulkLn->isPrintStatus = !0; - bulkLn->isPrintSummary = !0; - bulkLn->isPrintEachCreateLink = !0; - bulkLn->isPrintEachMkdir = !0; + bulkLn->flg |= (0 + |FLG_isPrintStatus + |FLG_isPrintSummary + |FLG_isPrintEachCreateLink + |FLG_isPrintEachMkdir); } else{ fprintf(stderr, "EINVAL: '%s'\n", arg); @@ -223,7 +219,7 @@ parseArgs( int argc, char**argv, BulkLn*bulkLn ){ * requiring args is the simplest way to prevent damage in case someone (eg * accidentally) invokes the utility wihout args. Further this also makes * the utility easier to extend wihout breaking everything. */ - if( bulkLn->dataFilePath == NULL ){ + if( !bulkLn->dataFilePath ){ fprintf(stderr, "EINVAL: '--stdin' missing.\n"); return -1; } @@ -265,12 +261,11 @@ mkdirs( char*path, BulkLn*bulkLn ){ tmpEnd[0] = '\0'; /* Print if requested */ - if( bulkLn->dryRun || bulkLn->isPrintEachMkdir ){ - printf("mkdir(\"%s\")\n", path); - } + if( bulkLn->flg & (FLG_isDryRun|FLG_isPrintEachMkdir) ) + { printf("mkdir(\"%s\")\n", path); } /* Create dir up to that found path */ - if( ! bulkLn->dryRun ){ + if( (bulkLn->flg & FLG_isDryRun) == 0 ){ /* Perform the real action */ /* mode gets masked by umask and after that we have the defaults * (aka what we want) */ @@ -317,13 +312,12 @@ PRIVATE(int) createHardlink( char*srcPath, char*dstPath, BulkLn*bulkLn ){ int err; - if( bulkLn->dryRun || bulkLn->isPrintEachCreateLink ){ - printf("link(\"%s\", \"%s\")\n", srcPath, dstPath); - } + if( bulkLn->flg & (FLG_isDryRun|FLG_isPrintEachCreateLink) ) + { printf("link(\"%s\", \"%s\")\n", srcPath, dstPath); } - if( ! bulkLn->dryRun ){ + if( (bulkLn->flg & FLG_isDryRun) == 0 ){ /* Perform the real action */ - if( bulkLn->isRelinkExistingFiles ){ + if( bulkLn->flg & FLG_isRelinkExistingFiles ){ /* Delete beforehand so we can be sure 'link' does not fail due * already existing file */ err = unlink(dstPath); @@ -360,7 +354,7 @@ onPathPair( char*srcPath, char*dstPath, BulkLn*bulkLn ){ assert(bulkLn != NULL); int err; - if( bulkLn->isPrintStatus && bulkLn->createdLinksCount % 10000 == 0 ){ + if( (bulkLn->flg & FLG_isPrintStatus) && bulkLn->createdLinksCount % 10000 == 0 ){ fprintf(stderr, "Created %7d links so far.\n", bulkLn->createdLinksCount); } @@ -452,7 +446,7 @@ parseDataFileAsPairPerLine( BulkLn*bulkLn ){ if( err ){ err = -1; goto resolveWithErr; } } - if( bulkLn->isPrintStatus ){ + if( bulkLn->flg & FLG_isPrintStatus ){ fprintf(stderr, "Parsed %lu records from '%s'\n", lineNum - 1, bulkLn->dataFilePath); } @@ -486,27 +480,24 @@ bulk_ln_main( int argc, char**argv ){ err = parseDataFileAsPairPerLine(bulkLn); if( err ){ err = -1; goto resolveWithErr; } - if( bulkLn->isPrintSummary ){ - fprintf(stderr, "Created %d directories and linked %d files.\n", - bulkLn->createdDirsCount, bulkLn->createdLinksCount); - } + if( bulkLn->flg & FLG_isPrintSummary ){ + fprintf(stderr, "Created %d directories and linked %d files.\n", + bulkLn->createdDirsCount, bulkLn->createdLinksCount); + } err = 0; resolveWithErr: - if( bulkLn->dataFd != NULL && bulkLn->dataFd != stdin ){ - fclose(bulkLn->dataFd); - } - return err; - #undef bulkLn + if( bulkLn->dataFd != NULL && bulkLn->dataFd != stdin ) + { fclose(bulkLn->dataFd); } + return (err != 0); + #undef bulkLn } #if EXPOSE_MAIN int main( int argc, char**argv ){ - argc = bulk_ln_main(argc, argv); - if( argc < 0 ) argc = -argc; - return (argc >= 0 && argc <= 0x7F) ? argc : 1; + return bulk_ln_main(argc, argv); } #endif |
