umount_davfs.c (davfs2-1.6.1) | : | umount_davfs.c (davfs2-1.7.0) | ||
---|---|---|---|---|
skipping to change at line 22 | skipping to change at line 22 | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | |||
along with davfs2; if not, write to the Free Software Foundation, | along with davfs2; if not, write to the Free Software Foundation, | |||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ | Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ | |||
#include "config.h" | #include "config.h" | |||
#include <error.h> | ||||
#include <errno.h> | ||||
#include <getopt.h> | #include <getopt.h> | |||
#ifdef HAVE_LIBINTL_H | #ifdef HAVE_LIBINTL_H | |||
#include <libintl.h> | #include <libintl.h> | |||
#endif | #endif | |||
#ifdef HAVE_LOCALE_H | #ifdef HAVE_LOCALE_H | |||
#include <locale.h> | #include <locale.h> | |||
#endif | #endif | |||
#include <stdio.h> | #include <stdio.h> | |||
#ifdef HAVE_STDLIB_H | #ifdef HAVE_STDLIB_H | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#endif | #endif | |||
#include <string.h> | #include <string.h> | |||
#ifdef HAVE_UNISTD_H | #ifdef HAVE_UNISTD_H | |||
#include <unistd.h> | #include <unistd.h> | |||
#endif | #endif | |||
#include <ne_string.h> | #include <ne_string.h> | |||
#include "util.h" | ||||
#include "defaults.h" | #include "defaults.h" | |||
#ifdef ENABLE_NLS | #ifdef ENABLE_NLS | |||
#define _(String) gettext(String) | #define _(String) gettext(String) | |||
#else | #else | |||
#define _(String) String | #define _(String) String | |||
#define textdomain(Domainname) | #define textdomain(Domainname) | |||
#define bindtextdomain(Domainname, Dirname) | #define bindtextdomain(Domainname, Dirname) | |||
#endif | #endif | |||
#if defined(__linux__) | ||||
#define UMOUNT_CMD "umount -i" | ||||
#elif defined(__FreeBSD__) | ||||
#define UMOUNT_CMD "umount" | ||||
#endif | ||||
/* This is lazy programming. All the dirty work is left to the real umount | /* This is lazy programming. All the dirty work is left to the real umount | |||
program, while we just sit and wait for mount.davfs to terminate. | program, while we just sit and wait for mount.davfs to terminate. | |||
umount.davfs is a umount helper. It is usually called by umount and makes | umount.davfs is a umount helper. It is usually called by umount and makes | |||
sure, that umount will not return until mount.davfs has synchronized all | sure, that umount will not return until mount.davfs has synchronized all | |||
files. | files. | |||
It first reads the pid-file and identifies the mount.davfs process. Then | It first reads the pid-file and identifies the mount.davfs process. Then | |||
it calls mount again, with option -i (to not be called again), to do the | it calls mount again, with option -i (to not be called again), to do the | |||
real unmounting. In a loop it will watch the process list. When the | real unmounting. In a loop it will watch the process list. When the | |||
mount.davfs process terminates, it will return. | mount.davfs process terminates, it will return. | |||
If it can't identify the mount.davfs process, it will call umount -i anyway, | If it can't identify the mount.davfs process, it will call umount -i anyway, | |||
skipping to change at line 109 | skipping to change at line 114 | |||
exit(EXIT_SUCCESS); | exit(EXIT_SUCCESS); | |||
case 'f': | case 'f': | |||
case 'l': | case 'l': | |||
case 'n': | case 'n': | |||
case 'r': | case 'r': | |||
case 'v': | case 'v': | |||
case 't': | case 't': | |||
case '?': | case '?': | |||
break; | break; | |||
default: | default: | |||
error(EXIT_FAILURE, 0, _("unknown error parsing arguments")); | ERR(_("unknown error parsing arguments")); | |||
} | } | |||
o = getopt_long(argc, argv, short_options, options, NULL); | o = getopt_long(argc, argv, short_options, options, NULL); | |||
} | } | |||
if (optind > (argc - 1)) | if (optind > (argc - 1)) | |||
error(EXIT_FAILURE, 0, _("missing argument")); | ERR(_("missing argument")); | |||
if (optind < (argc - 1)) | if (optind < (argc - 1)) | |||
error(EXIT_FAILURE, 0, _("too many arguments")); | ERR(_("too many arguments")); | |||
char *mpoint = canonicalize_file_name(argv[optind]); | char *mpoint = mcanonicalize_file_name(argv[optind]); | |||
char *umount_command = NULL; | char *umount_command = NULL; | |||
if (mpoint) { | if (mpoint) { | |||
umount_command = ne_concat("umount -i '", mpoint, "'", NULL); | umount_command = ne_concat(UMOUNT_CMD " '", mpoint, "'", NULL); | |||
} else { | } else { | |||
umount_command = ne_concat("umount -i '", argv[optind], "'", NULL); | umount_command = ne_concat(UMOUNT_CMD " '", argv[optind], "'", NULL); | |||
error(0, 0, | WARN(_("\n" | |||
_("\n" | " can't evaluate PID file name;\n" | |||
" can't evaluate PID file name;\n" | " trying to unmount anyway;\n" | |||
" trying to unmount anyway;\n" | " please wait for %s to terminate"), PROGRAM_NAME); | |||
" please wait for %s to terminate"), PROGRAM_NAME); | ||||
return system(umount_command); | return system(umount_command); | |||
} | } | |||
char *m = mpoint; | char *m = mpoint; | |||
while (*m == '/') | while (*m == '/') | |||
m++; | m++; | |||
char *mp = ne_strdup(m); | char *mp = ne_strdup(m); | |||
m = strchr(mp, '/'); | m = strchr(mp, '/'); | |||
while (m) { | while (m) { | |||
*m = '-'; | *m = '-'; | |||
m = strchr(mp, '/'); | m = strchr(mp, '/'); | |||
} | } | |||
char *pidfile = ne_concat(DAV_SYS_RUN, "/", mp, ".pid", NULL); | char *pidfile = ne_concat(DAV_SYS_RUN, "/", mp, ".pid", NULL); | |||
free(mp); | free(mp); | |||
char *pid = NULL; | char pid[32]; | |||
memset (pid, '\0', sizeof(pid)); | ||||
FILE *file = fopen(pidfile, "r"); | FILE *file = fopen(pidfile, "r"); | |||
if (!file || fscanf(file, "%m[0-9]", &pid) != 1 || !pid) { | if (!file || fscanf(file, "%s[0-9]", pid) != 1 || pid[0] == '\0') { | |||
error(0, 0, | WARN(_("\n" | |||
_("\n" | " can't read PID from file %s;\n" | |||
" can't read PID from file %s;\n" | " trying to unmount anyway;\n" | |||
" trying to unmount anyway;\n" | " please wait for %s to terminate"), pidfile, PROGRAM_NAME); | |||
" please wait for %s to terminate"), pidfile, PROGRAM_NAME); | ||||
return system(umount_command); | return system(umount_command); | |||
} | } | |||
fclose(file); | fclose(file); | |||
char *ps_command = ne_concat("ps -p ", pid, NULL); | char *ps_command = ne_concat("ps -p ", pid, NULL); | |||
FILE *ps_in = popen(ps_command, "r"); | FILE *ps_in = popen(ps_command, "r"); | |||
if (!ps_in) { | if (!ps_in) { | |||
error(0, 0, | WARN(_("\n" | |||
_("\n" | " can't read process list;\n" | |||
" can't read process list;\n" | " trying to unmount anyway;\n" | |||
" trying to unmount anyway;\n" | " please wait for %s to terminate"), PROGRAM_NAME); | |||
" please wait for %s to terminate"), PROGRAM_NAME); | ||||
return system(umount_command); | return system(umount_command); | |||
} | } | |||
int found = 0; | int found = 0; | |||
size_t n = 0; | size_t n = 0; | |||
char *ps_line = NULL; | char *ps_line = NULL; | |||
while (!found && getline(&ps_line, &n, ps_in) > 0) | while (!found && getline(&ps_line, &n, ps_in) > 0) | |||
found = (strstr(ps_line, pid) && strstr(ps_line, PROGRAM_NAME)); | found = (strstr(ps_line, pid) && strstr(ps_line, PROGRAM_NAME)); | |||
pclose(ps_in); | pclose(ps_in); | |||
if (!found) { | if (!found) { | |||
error(0, 0, | WARN(_("\n" | |||
_("\n" | " can't find %s-process with pid %s;\n" | |||
" can't find %s-process with pid %s;\n" | " trying to unmount anyway.\n" | |||
" trying to unmount anyway.\n" | " you propably have to remove %s manually"), | |||
" you propably have to remove %s manually"), | ||||
PROGRAM_NAME, pid, pidfile); | PROGRAM_NAME, pid, pidfile); | |||
return system(umount_command); | return system(umount_command); | |||
} | } | |||
if (system(umount_command) != 0) | if (system(umount_command) != 0) | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
printf(_("%s: waiting for %s (pid %s) to terminate gracefully ."), | printf(_("%s: waiting for %s (pid %s) to terminate gracefully ."), | |||
argv[0], PROGRAM_NAME, pid); | argv[0], PROGRAM_NAME, pid); | |||
fflush(stdout); | fflush(stdout); | |||
while (found) { | while (found) { | |||
sleep(3); | sleep(3); | |||
printf("."); | printf("."); | |||
fflush(stdout); | fflush(stdout); | |||
ps_in = popen(ps_command, "r"); | ps_in = popen(ps_command, "r"); | |||
if (!ps_in) { | if (!ps_in) { | |||
printf("\n"); | printf("\n"); | |||
error(EXIT_FAILURE, 0, _("an error occurred while waiting; " | ERR(_("an error occurred while waiting; " | |||
"please wait for %s to terminate"), PROGRAM_NAME); | "please wait for %s to terminate"), PROGRAM_NAME); | |||
} | } | |||
found = 0; | found = 0; | |||
while (!found && getline(&ps_line, &n, ps_in) > 0) | while (!found && getline(&ps_line, &n, ps_in) > 0) | |||
found = (strstr(ps_line, pid) && strstr(ps_line, PROGRAM_NAME)); | found = (strstr(ps_line, pid) && strstr(ps_line, PROGRAM_NAME)); | |||
pclose(ps_in); | pclose(ps_in); | |||
} | } | |||
printf(" OK\n"); | printf(" OK\n"); | |||
End of changes. 14 change blocks. | ||||
31 lines changed or deleted | 33 lines changed or added |