From 2813a833b48e63970ccced97a8e887ea61b6a810 Mon Sep 17 00:00:00 2001 From: Pierre Pronchery Date: Fri, 26 Mar 2004 00:10:43 +0000 Subject: [PATCH] Should be functional --- src/ln.c | 124 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 73 insertions(+), 51 deletions(-) diff --git a/src/ln.c b/src/ln.c index 52c2301..1798fcc 100644 --- a/src/ln.c +++ b/src/ln.c @@ -6,63 +6,86 @@ #include #include extern int optind; +#include #include #include +#include -/* ln */ -int ln(int flgf, int flgs, int argc, char * argv[]) + +/* types */ +/* force link */ +typedef enum _LinkForce { + LF_NO, + LF_YES +} LinkForce; +/* link type */ +typedef enum _LinkType { + LT_HARD = 0, + LT_SOFT +} LinkType; + + +/* ln + * PRE lf whether to unlink destination if already exists or not + * lt whether to link or symlink + * argc number of source + destination arguments + * POST + * 0 success + * 2 error */ +static int _ln_is_directory(char * dest); +static int _ln_single(LinkForce lf, LinkType lt, char * src, char * dest); +static int _ln_multiple(LinkForce lf, LinkType lt, int argc, char * argv[]); +static int _ln(LinkForce lf, LinkType lt, int argc, char * argv[]) +{ + if(argc == 2 && !_ln_is_directory(argv[1])) + return _ln_single(lf, lt, argv[0], argv[1]); + return _ln_multiple(lf, lt, argc, argv); +} + +static int _ln_is_directory(char * dest) { struct stat buf; - int i; - if(argc <= 1) - return 1; - if(stat(argv[argc-1], &buf) == -1) - { - if(errno != ENOENT) - { - perror("stat"); - return 2; - } - if(argc > 2) - return 1; - if(flgs) - { - if(symlink(argv[0], argv[1]) == -1) - { - perror("symlink"); - return 3; - } - } - else - { - if(link(argv[0], argv[1]) == -1) - { - perror("link"); - return 3; - } - } + if(stat(dest, &buf) == -1 || !S_ISDIR(buf.st_mode)) return 0; - } - else - { - if(S_ISDIR(buf.st_mode)) - { - char * newpath; + return 1; +} - for(i = 0; i < argc - 1; i++) - { - /* FIXME */ - } - return 0; /* FIXME could be errors */ - } - if(argc > 2) - return 1; +static int _ln_single(LinkForce lf, LinkType lt, char * src, char * dest) +{ + if(lf == LF_YES) + unlink(dest); + if((lt == LT_HARD ? link(src, dest) + : symlink(src, dest)) == -1) + { + perror(src); + return 2; } return 0; } +static int _ln_multiple(LinkForce lf, LinkType lt, int argc, char * argv[]) +{ + int i; + char * dest = argv[argc-1]; + char * p; + + for(i = 0; i < argc - 1; i++) + { + if((p = realloc(dest, strlen(dest) + strlen(argv[i]) + 2)) + == NULL) + { + perror("realloc"); + continue; + } + sprintf(dest, "%s/%s", argv[argc-1], argv[i]); + _ln_single(lf, lt, argv[i], dest); + } + free(dest); + return 0; +} + /* usage */ static int usage(void) @@ -78,26 +101,25 @@ static int usage(void) /* main */ int main(int argc, char * argv[]) { - int flgf = 0; - int flgs = 0; + LinkForce flgf = LF_NO; + LinkType flgs = LT_HARD; int o; - int res; while((o = getopt(argc, argv, "fs")) != -1) { switch(o) { case 'f': - flgf = 1; + flgf = LF_YES; break; case 's': - flgs = 1; + flgs = LT_SOFT; break; case '?': return usage(); } } - if((res = ln(flgf, flgs, argc - optind, &argv[optind])) == 1) + if(argc - optind <= 1) return usage(); - return res; + return _ln(flgf, flgs, argc - optind, &argv[optind]); }