ftp.nice.ch/pub/next/unix/disk/vmount.0.6a.s.tar.gz#/vmount.0.6a.s/vumount.c

This is vumount.c in view mode; [Download] [Up]

/*
 * Name: vumount.c
 * Description: Unmount the given vmounted volume
 * Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
 * Date: 1997-04-30
 * Copyright: GNU-GPL
 * Tabsize: 4
 */

#include <libc.h>
#include <errno.h>
#include <mntent.h>
#include "my_defines.h"

/* ------------------------------------------------------------------------- */

extern int	errno;
static char	*my_name;

/* ------------------------------------------------------------------------- */

static void	remove_entry(char *path)
{
FILE			*fpout, *fpin;
struct mntent	*ent;
char			tempfile[2048];
int				changed = 0;

	sprintf(tempfile, "%s-%d.tmp", MOUNTED, getpid());
	if((fpin = setmntent(MOUNTED, "r")) == NULL){
		fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
										my_name, MOUNTED, strerror(errno));
		return;
	}else{
		if((fpout = setmntent(tempfile, "w")) == NULL){
			fprintf(stderr, "%s: error creating ->%s<-: %s\n",
										my_name, tempfile, strerror(errno));
			endmntent(fpin);
			return;
		}
		while((ent = getmntent(fpin)) != NULL){
			if(strcmp(ent->mnt_dir, path) != 0)
				addmntent(fpout, ent);
			else
				changed = 1;
		}
		endmntent(fpout);
		endmntent(fpin);
		if(changed){
			if(rename(tempfile, MOUNTED) != 0){
				fprintf(stderr, "%s: error moving temp file ->%s<- to "
									"->%s<-\n", my_name, tempfile, MOUNTED);
				unlink(tempfile);
			}
		}else
			unlink(tempfile);
	}
}

/* ------------------------------------------------------------------------- */

static int	umount_dir(char *path)
{
FILE			*fpin;
struct mntent	*ent;
int				i, pid, rval = 0, found_any = 0;

	if((fpin = setmntent(MOUNTED, "r")) == NULL){
		fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
										my_name, MOUNTED, strerror(errno));
		return -1;
	}else{
		while((ent = getmntent(fpin)) != NULL){
			if(strcmp(ent->mnt_dir, path) == 0){
				found_any = 1;
				if(sscanf(ent->mnt_type, "vmount-%d", &pid) == 1){
					if(unmount(path) != 0){
						fprintf(stderr, "%s: cannot unmount ->%s<-: %s\n",
									my_name, ent->mnt_dir, strerror(errno));
						rval = -1;
					}else{
						if(fork() != 0){	/* parent */
							kill(pid, 1);
							for(i=0; kill(pid, 0) == 0 && i < 600; i++){
								usleep(100000);
							}	/* wait up to 60s for terminate */
						}else{
							signal(SIGHUP, SIG_IGN);
							signal(SIGTERM, SIG_IGN);
							signal(SIGTSTP, SIG_IGN);
							signal(SIGQUIT, SIG_IGN);
							signal(SIGPIPE, SIG_IGN);
							signal(SIGURG, SIG_IGN);
							signal(SIGCONT, SIG_IGN);
							signal(SIGCHLD, SIG_IGN);
							signal(SIGTTIN, SIG_IGN);
							signal(SIGTTOU, SIG_IGN);
							signal(SIGIO, SIG_IGN);
							signal(SIGWINCH, SIG_IGN);
/*
 * Note: This is an evil hack. Workspace overwrites /etc/mtab to what it
 * thinks is correct, but that is wrong if more than one volume was mounted
 * by an *.util program. So we wait several seconds (until Workspace has
 * done its evil things) and overwrite mtab with what _we_ think is correct.
 */
							sleep(4);
							lock_mtab();
							remove_entry(path);
							unlock_mtab();
							exit(0);
						}
					}
				}else{
					fprintf(stderr, "%s: type ->%s<- not mounted by vmount\n",
													my_name, ent->mnt_type);
					rval = -1;
				}
			}
		}
		endmntent(fpin);
		if(!found_any){
			fprintf(stderr, "%s: directory ->%s<- not found in mtab\n",
															my_name, path);
		}
	}
	return rval;
}

/* ------------------------------------------------------------------------- */

static void	print_all(void)
{
FILE			*fpin;
struct mntent	*ent;
int				pid;

	if((fpin = setmntent(MOUNTED, "r")) == NULL){
		fprintf(stderr, "%s: cannot open mtab file ->%s<-: %s\n",
										my_name, MOUNTED, strerror(errno));
		return;
	}else{
		while((ent = getmntent(fpin)) != NULL){
			if(sscanf(ent->mnt_type, "vmount-%d", &pid) == 1){
				printf("%s\n", ent->mnt_dir);
			}
		}
		endmntent(fpin);
	}
}

/* ------------------------------------------------------------------------- */

int	main(int argc, char **argv)
{
int		i, error = 0, rval;

	my_name = argv[0];
	if(argc == 1){
		printf("vmount mounted directories:\n");
		print_all();
	}else{
		for(i=1;i<argc;i++){
			error |= umount_dir(argv[i]);
		}
	}
	rval = error ? 1 : 0;
	return rval;
}

/* ------------------------------------------------------------------------- */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.