X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/a05e4467dee55248f2135dcb532b4729154d69c5..f87532949a0834686852e1cf59519d948c59eee7:/clients/disorderfm.c diff --git a/clients/disorderfm.c b/clients/disorderfm.c index d8dffb6..ed31dd0 100644 --- a/clients/disorderfm.c +++ b/clients/disorderfm.c @@ -1,25 +1,27 @@ /* * This file is part of DisOrder. - * Copyright (C) 2006 Richard Kettlewell + * Copyright (C) 2006, 2007, 2008 Richard Kettlewell * - * This program is free software; you can redistribute it and/or modify + * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * along with this program. If not, see . */ - -#include -#include "types.h" +/** @file clients/disorderfm.c + * @brief DisOrder file manager + * + * Intended to support encoding conversion, tag extraction, etc. Not yet + * complete (and hasn't been worked on for ages). + */ +#include "common.h" #include #include @@ -29,7 +31,6 @@ #include #include #include -#include #include #include "syscalls.h" @@ -38,6 +39,7 @@ #include "charset.h" #include "defs.h" #include "mem.h" +#include "version.h" /* Arguments etc ----------------------------------------------------------- */ @@ -127,13 +129,6 @@ static void help(void) { exit(0); } -/* display version number and terminate */ -static void version(void) { - xprintf("%s", disorder_version_string); - xfclose(stdout); - exit(0); -} - /* Utilities --------------------------------------------------------------- */ /* Copy FROM to TO. Has the same signature as link/symlink. */ @@ -141,17 +136,25 @@ static int copy(const char *from, const char *to) { int fdin, fdout; char buffer[4096]; int n; + struct stat sb; if((fdin = open(from, O_RDONLY)) < 0) - fatal(errno, "error opening %s", from); + disorder_fatal(errno, "error opening %s", from); if((fdout = open(to, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) - fatal(errno, "error opening %s", to); + disorder_fatal(errno, "error opening %s", to); while((n = read(fdin, buffer, sizeof buffer)) > 0) { if(write(fdout, buffer, n) < 0) - fatal(errno, "error writing to %s", to); + disorder_fatal(errno, "error writing to %s", to); } - if(n < 0) fatal(errno, "error reading %s", from); - if(close(fdout) < 0) fatal(errno, "error closing %s", to); + if(n < 0) + disorder_fatal(errno, "error reading %s", from); + if(fstat(fdin, &sb) < 0) + disorder_fatal(errno, "error stating %s", from); + if(fchown(fdout, sb.st_uid, sb.st_gid) < 0) + disorder_fatal(errno, "error chowning %s", from); + if(fchmod(fdout, sb.st_mode & 07777) < 0) + disorder_fatal(errno, "error chmoding %s", from); + if(close(fdout) < 0) disorder_fatal(errno, "error closing %s", to); xclose(fdin); return 0; } @@ -286,25 +289,25 @@ static void visit(const char *path, const char *destpath) { * directory. In that case we'd better not descend into it when we encounter * it in the source. */ if(!strcmp(fullsourcepath, destination)) { - info("%s matches destination directory, not recursing", errsourcepath); + disorder_info("%s matches destination directory, not recursing", errsourcepath); return; } /* Find out what kind of file we're dealing with */ if(stat(fullsourcepath, &sb) < 0) { - error(errno, "cannot stat %s", errsourcepath ); + disorder_error(errno, "cannot stat %s", errsourcepath ); ++errors; return; } if(S_ISREG(sb.st_mode)) { if(copier != nocopy) if(unlink(fulldestpath) < 0 && errno != ENOENT) { - error(errno, "cannot remove %s", errdestpath); + disorder_error(errno, "cannot remove %s", errdestpath); ++errors; return; } if(copier(fullsourcepath, fulldestpath) < 0) { - error(errno, "cannot link %s to %s", errsourcepath, errdestpath); + disorder_error(errno, "cannot link %s to %s", errsourcepath, errdestpath); ++errors; return; } @@ -315,14 +318,27 @@ static void visit(const char *path, const char *destpath) { /* We create the directory on the destination side. If it already exists, * that's fine. */ - if(dirmaker(fulldestpath, 0777) < 0 && errno != EEXIST) { - error(errno, "cannot mkdir %s", errdestpath); + if(dirmaker(fulldestpath, 0700) == 0) { + if(dirmaker != nomkdir) { + /* Created new directory. Adjust permissions and ownership to match the + * old one. */ + if(chown(fulldestpath, sb.st_uid, sb.st_gid) < 0) { + disorder_error(errno, "cannot chown %s", errdestpath); + ++errors; + } + if(chmod(fulldestpath, sb.st_mode & 07777) < 0) { + disorder_error(errno, "cannot chmod %s", errdestpath); + ++errors; + } + } + } else if(errno != EEXIST) { + disorder_error(errno, "cannot mkdir %s", errdestpath); ++errors; return; } /* We read the directory and visit all the files in it in any old order. */ if(!(dp = opendir(fullsourcepath))) { - error(errno, "cannot open directory %s", errsourcepath); + disorder_error(errno, "cannot open directory %s", errsourcepath); ++errors; return; } @@ -339,11 +355,12 @@ static void visit(const char *path, const char *destpath) { } visit(childpath, childdestpath); } - if(errno) fatal(errno, "error reading directory %s", errsourcepath); + if(errno) + disorder_fatal(errno, "error reading directory %s", errsourcepath); closedir(dp); } else { /* We don't handle special files, but we'd better warn the user. */ - info("ignoring %s", errsourcepath); + disorder_info("ignoring %s", errsourcepath); } } @@ -352,11 +369,12 @@ int main(int argc, char **argv) { struct pattern *p; mem_init(); - if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale"); + if(!setlocale(LC_CTYPE, "")) + disorder_fatal(errno, "error calling setlocale"); while((n = getopt_long(argc, argv, "hVdf:t:i:e:ET:u:wlscn", options, 0)) >= 0) { switch(n) { case 'h': help(); - case 'V': version(); + case 'V': version("disorderfm"); case 'd': debugging = 1; break; case 'f': fromencoding = optarg; break; case 't': toencoding = optarg; break; @@ -378,17 +396,19 @@ int main(int argc, char **argv) { case 's': copier = symlink; break; case 'c': copier = copy; break; case 'n': copier = nocopy; dirmaker = nomkdir; break; - default: fatal(0, "invalid option"); + default: disorder_fatal(0, "invalid option"); } } - if(optind == argc) fatal(0, "missing SOURCE and DESTINATION arguments"); - else if(optind + 1 == argc) fatal(0, "missing DESTINATION argument"); - else if(optind + 2 != argc) fatal(0, "redundant extra arguments"); - if(extracttags) fatal(0, "--extract-tags is not implemented yet"); /* TODO */ + if(optind == argc) + disorder_fatal(0, "missing SOURCE and DESTINATION arguments"); + else if(optind + 1 == argc) disorder_fatal(0, "missing DESTINATION argument"); + else if(optind + 2 != argc) disorder_fatal(0, "redundant extra arguments"); + if(extracttags) + disorder_fatal(0, "--extract-tags is not implemented yet"); /* TODO */ if(tagencoding && !extracttags) - fatal(0, "--tag-encoding without --extra-tags does not make sense"); + disorder_fatal(0, "--tag-encoding without --extra-tags does not make sense"); if(untagged && !extracttags) - fatal(0, "--untagged without --extra-tags does not make sense"); + disorder_fatal(0, "--untagged without --extra-tags does not make sense"); source = argv[optind]; destination = argv[optind + 1]; nativeencoding = nl_langinfo(CODESET);