/* * Copyright(c) 1997, Space Science and Engineering Center, UW-Madison * Refer to "McIDAS Software Acquisition and Distribution Policies" * in the file mcidas/data/license.txt */ /**** $Id: mcclean.c,v 1.7 1999/03/31 21:59:14 rodr Exp $ ****/ /* * mcclean.cp j.benson 95-08-01 * * Find and remove McIDAS temporary file space and * shared memory objects which are no longer in use. * * Files are looked for in directories of the form /tmp/mctmp/NNN * where NNN represents the ascii representation of a decimal number, * and in $HOME/.mctmp/NNN. * In each case, the file named in the macro MCCLEAN_FILE is checked. * If it exists and is not locked, then the directory is assumed to be * one of ours, whose user has died without cleaning itself up. * The files, their directory, and the shared memory object whose key * is represented by the NNN are all removed if it is possible to do so. */ #include #include #include #include #include #include #include #include #include #include #include "m0glue.h" #ifdef __OPENNT # include #endif /* * delete shared memory whose key is passed to you * as an ascii string. Return success or failure */ static int remove_memory( char *key) { return shmctl(atoi(key), IPC_RMID, 0); } /* * remove the contents of a directory * and then remove the directory */ static int remove_dir(char *dir) { char command[255]; strcpy(command, "rm "); strcat(command, dir); strcat(command, "/* "); system(command); return rmdir(dir); } /* * Test the directory name given for the presence of the MCCLEAN_FILE * file. If it is present and not locked, perform deletes. */ static void maybe_clobber(char *dir) { char file[255]; int fd; struct flock lk; int key; strcpy(file, dir); strcat(file, "/" MCCLEAN_FILE); fd = open(file, O_RDWR); lk.l_type = F_WRLCK; lk.l_start = 0; lk.l_whence = SEEK_SET; lk.l_len = 1; if(fd>=0 && fcntl(fd, F_GETLK, &lk) == 0 && lk.l_type != F_UNLCK ) { fprintf(stderr, "%s in use\n", dir); return; } /* Look for and Remove GRAPHICS.KEY and if present read the first (int) value and that is the previouse key that is locked */ strcpy(file, dir); strcat(file, "/GRAPHICS.KEY"); fd = open(file, O_RDWR); read(fd,&key,sizeof(int)); shmctl(key,IPC_RMID,0); close(fd); fprintf(stderr,"Removed Graphics Memory Object\n"); /* * We get here if the lockfile does not exist or is not locked * which means we are free to remove the resources in its * scope: the subdirectory of per-instance files, and if it * exists, the shared memory segment whose key has the same * numeric value as the directory name. */ if( !remove_dir(dir)) { fprintf(stderr, "Removed %s\n", dir); } else { fprintf(stderr, "Could not clean up %s", dir); } /* * the plus one on the next line is to tab past the * final slash found by strrchr, leaving only the * subdirectory name, which is normally numeric, and * implies the key of the associated shared memory object. */ if (!remove_memory(strrchr(dir,'/')+1)) { fprintf(stderr, "Removed memory object\n"); } } /* * Read a directory, looking for the names of its entries, * which are subdirectories * (ignore . and ..) * Otherwise, for each name found, perform the maybe_clobber function */ static void scan_dir( const char *path) { DIR *dp; struct dirent *entry; char pathname[255]; dp = opendir(path); if(!dp) { return; } while ((entry=readdir(dp))!=0) { if(strcmp(entry->d_name,".")==0) continue; if(strcmp(entry->d_name,"..")==0) continue; strcpy(pathname, path); strcat(pathname,"/"); strcat(pathname,entry->d_name); maybe_clobber(pathname); } closedir(dp); } /* * main program */ int main(void) { char path[255]; char *home; char *tmp_dir; /* always try /tmp/mctmp */ /* if we are NT, then get the tmp directory from */ #ifndef __OPENNT tmp_dir = "/tmp/mctmp"; #else tmp_dir = _prefixInstallPath ("/tmp/mctmp", NULL, 0); #endif scan_dir( tmp_dir ); /* try $HOME/.mctmp, unless we are homeless streetperson */ home = getenv("HOME"); if(home && *home) { strcpy(path, home); strcat(path, "/.mctmp"); scan_dir( path ); } return 0; }