/* * Dissassociate ourselves from our tty, and close all files */ int mk_daemon( char *logfile) { int fd; int i; struct rlimit lim; struct sigaction act; #ifdef NOTYET if ((pid = fork()) == -1) return (-1); if (pid) exit(0); (void) setsid(); (void) chdir("/"); #endif /* NOTYET */ /* * Determine how many open files we've got and close * then all */ if (getrlimit(RLIMIT_NOFILE, &lim) < 0 ) { errno_msg("Can't determine max number of open files"); return(1); } for (i=0; i<lim.rlim_cur; i++) (void)close(i); /* * For error reporting, we re-direct stdout and stderr to a * logfile. */ if ((fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0755)) < 0) { errno_msg("Can't open logfile %s", logfile); return(1); } (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); close(fd); /* * Set up signals so that we can wait for spawned children */ act.sa_handler = migin_exit; act.sa_flags = 0; sigemptyset(&act.sa_mask); (void)sigaction(SIGHUP, &act, NULL); (void)sigaction(SIGINT, &act, NULL); (void)sigaction(SIGQUIT, &act, NULL); (void)sigaction(SIGTERM, &act, NULL); (void)sigaction(SIGUSR1, &act, NULL); (void)sigaction(SIGUSR1, &act, NULL); (void)sigaction(SIGUSR2, &act, NULL); return(0); }
/* * Write a file's data to the staging file. We write the file out * in 4meg chunks. */ int save_filedata( dm_sessid_t sid, void *hanp, size_t hlen, int stg_fd, dm_size_t fsize) { char *filebuf; int i, nbufs; int retval; dm_ssize_t nread, lastbuf; ssize_t nwrite; dm_off_t off; nbufs = fsize / CHUNKSIZE; off = 0; retval = 0; filebuf = malloc(CHUNKSIZE); if (filebuf == NULL) { err_msg("%s/%d: Can't alloc memory for file buffer", __FILE__, __LINE__); goto out; } for (i = 0; i<nbufs; i++) { nread = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN, off, (dm_ssize_t)CHUNKSIZE, filebuf); if (nread != CHUNKSIZE) { #ifdef __sgi errno_msg("%s/%d: invis read err: got %lld, expected %lld, buf %d", #else errno_msg("%s/%d: invis read err: got %d, expected %d, buf %d", #endif __FILE__, __LINE__, nread, (dm_ssize_t)CHUNKSIZE, i); retval = 1; goto out; } off += nread; nwrite = write(stg_fd, filebuf, CHUNKSIZE); if (nwrite != CHUNKSIZE) { errno_msg("%s/%d: write err %d, expected %d, buf %d", __FILE__, __LINE__, nwrite, CHUNKSIZE, i); retval = 1; goto out; } }
/* * Get the complete list of all managed regions for a file. For now, * we know that most implementations only support a small number of * regions, so we don't handle the E2BIG error here. */ int mr_info( dm_sessid_t sid, void *hanp, size_t hlen) { u_int i; u_int ret; dm_region_t rgn[MAX_RGNS]; memset((char *)&rgn, 0, (sizeof(dm_region_t) * MAX_RGNS)); if (dm_get_region(sid, hanp, hlen, DM_NO_TOKEN, MAX_RGNS, rgn, &ret)) { errno_msg("Can't get list of managed regions"); return(1); } printf("\n"); for (i=0; i<ret; i++) { printf("\tRegion %d:\n", i); printf("\t\toffset %lld, ", (long long) rgn[i].rg_offset); printf("size %llu, ", (unsigned long long) rgn[i].rg_size); printf("flags 0x%x", rgn[i].rg_flags); printf(" ( "); if (rgn[i].rg_flags & DM_REGION_NOEVENT) printf("noevent "); if (rgn[i].rg_flags & DM_REGION_READ) printf("read "); if (rgn[i].rg_flags & DM_REGION_WRITE) printf("write "); if (rgn[i].rg_flags & DM_REGION_TRUNCATE) printf("trunc "); printf(" )\n"); } return(0); }
/* * Get the allocation info for a file. We pick some small number * of extents to get the residency info on at one time */ int alloc_info( dm_sessid_t sid, void *hanp, size_t hlen) { int i, more; dm_off_t offset; u_int nextents, nret; dm_extent_t ext[NUM_EXTENTS]; nextents = NUM_EXTENTS; offset = 0; printf("\n\tAllocation info \n"); do { more = dm_get_allocinfo(sid, hanp, hlen, DM_NO_TOKEN, &offset, nextents, ext, &nret); if (more == -1) { errno_msg("Can't get alloc info for file"); return(1); } for (i=0; i<nret; i++) { printf("\t\tExtent %d ", i); if (ext[i].ex_type == DM_EXTENT_RES) printf("(resident): "); if (ext[i].ex_type == DM_EXTENT_HOLE) printf("(hole): "); printf("offset %lld, ", (long long) ext[i].ex_offset); printf("len %llu\n", (unsigned long long) ext[i].ex_length); } } while (more == 1); return(0); }
/* * Get the file's change indicator */ int get_dmchange( dm_sessid_t sid, void *hanp, size_t hlen, dm_token_t token, u_int *change_start) { int error; dm_stat_t statbuf; error = dm_get_fileattr(sid, hanp, hlen, token, DM_AT_CFLAG, &statbuf); if (error == -1) { errno_msg("%s/%d: Can't stat file (%d)", __FILE__, __LINE__, errno); return(1); } *change_start = statbuf.dt_change; return(0); }
/* * Set the event disposition of the managed region events */ int set_events( dm_sessid_t sid, void *fs_hanp, size_t fs_hlen) { dm_eventset_t eventlist; DMEV_ZERO(eventlist); DMEV_SET(DM_EVENT_READ, eventlist); DMEV_SET(DM_EVENT_WRITE, eventlist); DMEV_SET(DM_EVENT_TRUNCATE, eventlist); if (dm_set_disp(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &eventlist, DM_EVENT_MAX) == -1) { errno_msg("Can't set event disposition"); return(1); } return(0); }
int main (int argc, char *argv[]) { if (argc == 2) { // Might got called as Script Executioner //FILE *fp = fopen(argv[1],"r"); // Prepare a file Pointer char *readString; // Read lines here /*while (fgets(readString, READBUFFERSIZE, fp) != NULL) {*/ while ((readString = readline("Test"))) { remove_leading_whitespaces(readString); if (*readString != '#') { parse_cmd(readString); } } return EXIT_SUCCESS; // Exit this instance of shawn. } last_exit_code = 0; char *shell = malloc(sizeof(char[80])); // Prepare variable for path if (*argv[0] == '.') { // Has shawn been called with a relative path? strcat(shell,getenv("PWD")); // Yes, prepare string strcat(shell,strchr(argv[0],'/')); // Concat Strings to an absolute path } else { shell = argv[0]; // No, just take call of shawn } char *hostname = malloc(sizeof(char[80])); // Whats the Name of this Host? if (gethostname(hostname,80) != 0) { // Could we read it? errno_msg("Reading hostname",0); // No, give an error and quit } set("SHELL",shell); // Set SHELL Env Variable. debug_msg("Debugmode enabled!"); // Inform user, he is running in DEBUG mode. printf("Welcome to shawn 1.1\n"); char readString[READBUFFERSIZE]; // Prepare Buffer do { // Loop. printf("%s:(%s)%s$ ",hostname,getenv("USER"),getenv("PWD")); fgets(readString, READBUFFERSIZE, stdin); // Read user command. parse_cmd(readString); } while (quit==0); // Infinite loop, quit is now recognized and handled in parsecmd() return EXIT_SUCCESS; // We can quit now, but this will never get called. }
static void event_loop( dm_sessid_t sid, int waitflag) { void *msgbuf; size_t bufsize; int error; dm_eventmsg_t *msg; int count; /* * We take a swag at a buffer size. If it's wrong, we can * always resize it */ bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; bufsize *= 50; msgbuf = (void *)malloc(bufsize); if (msgbuf == NULL) { err_msg("Can't allocate memory for buffer"); return; } for (;;) { error = dm_get_events(sid, ALL_AVAIL_MSGS, waitflag ? DM_EV_WAIT:0, bufsize, msgbuf, &bufsize); if (error) { if (errno == EAGAIN) { if (waitflag) continue; break; } if (errno == E2BIG) { free(msgbuf); msgbuf = (void *)malloc(bufsize); if (msgbuf == NULL) { err_msg("Can't resize msg buffer"); return; } continue; } errno_msg("Error getting events from DMAPI"); break; } /* * Walk through the message buffer, pull out each individual * message, and dispatch the messages to handle_message(), * which will respond to the events. */ count = 0; msg = (dm_eventmsg_t *)msgbuf; while (msg != NULL ) { count++; error = handle_message(sid, msg); if (error) { free(msgbuf); return; } printf("end_of_message\n"); msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); } if (count != 1 && Verbose) { err_msg("Found %d events in one call to " "dm_get_events\n", count); } } if (msgbuf != NULL) free(msgbuf); }
/* * Get the attributes for all the files in a filesystem in bulk, * and print out the handles and sizes of any that meet our target * criteria. * * We are not interested in file names; if we were, then we would * have to do a dm_get_dirattrs() on each directroy, then use * dm_handle_to_path() to get the pathname. */ int scan_fs( dm_sessid_t sid, void *fs_hanp, size_t fs_hlen, dm_off_t target_size) { u_int mask; /* attributes to scan for */ dm_stat_t *dm_statbuf, *sbuf; /* attributes buffer */ dm_attrloc_t locp; /* opaque location in fs */ size_t rlenp; /* ret length of stat info */ size_t buflen; /* length of stat buffer */ void *hanp; /* file handle */ size_t hlen; /* file handle */ int more; /* loop terminator */ int error; /* * Size the stat buffer to return info on 1K files at a time */ buflen = sizeof(dm_stat_t) * 1024; #ifdef VERITAS_21 if (buflen > 65536) buflen = 65536; #endif dm_statbuf = (dm_stat_t *)calloc(1, buflen); if (dm_statbuf == NULL) { err_msg("Can't get memory for stat buffer"); return(1); } /* * Initialize the offset opaque offset cookie that * we use in successive calls to dm_get_bulkattr() */ error = dm_init_attrloc(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, &locp); if (error == -1) { errno_msg("%s/%d: Can't initialize offset cookie (%d)", __FILE__, __LINE__, errno); free(dm_statbuf); return(1); } /* * Set our stat mask so that we'll only get the normal stat(2) * info and the file's handle */ mask = DM_AT_HANDLE | DM_AT_STAT; do { more = dm_get_bulkattr(sid, fs_hanp, fs_hlen, DM_NO_TOKEN, mask, &locp, buflen, dm_statbuf, &rlenp); if (more == -1) { errno_msg("%s/%d: Can't get bulkattr for filesystem", __FILE__, __LINE__, errno); break; } /* * Walk through the stat buffer and pull out files * that are of interest * * The stat buffer is variable length, so we must * use the DM_STEP_TO_NEXT macro to access each individual * dm_stat_t structure in the returned buffer. */ sbuf = dm_statbuf; while (sbuf != NULL) { if (S_ISREG(sbuf->dt_mode) && sbuf->dt_size >= target_size) { hanp = DM_GET_VALUE(sbuf, dt_handle, void *); hlen = DM_GET_LEN(sbuf, dt_handle); print_victim(hanp, hlen, sbuf->dt_size); } sbuf = DM_STEP_TO_NEXT(sbuf, dm_stat_t *); } } while (more == 1); free(dm_statbuf); if (more == -1) return(1); return(0); }
int main( int argc, char *argv[]) { int c; int error; dm_off_t size; char *fsname; dm_sessid_t sid; void *fs_hanp; size_t fs_hlen; char *sizep = "0"; Progname = argv[0]; size = 0; while ((c = getopt(argc, argv, "s:")) != EOF) { switch (c) { case 's': sizep = optarg; break; case '?': default: usage(Progname); exit(1); } } if (optind >= argc) { usage(Progname); exit(1); } /* * Verify the input size string is legit */ error = verify_size(sizep, &size); if (error) exit(1); fsname = argv[optind]; /* * Now we have our filesystem name and possibly a size threshold * to look for. Init the dmapi, and get a filesystem handle so * we can scan the filesystem */ error = setup_dmapi(&sid); if (error) exit(1); if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) { errno_msg("Can't get filesystem handle"); exit(1); } /* * Get the attributes of all files in the filesystem */ error = scan_fs(sid, fs_hanp, fs_hlen, size); if (error) exit(1); /* * We're done, so we can shut down our session. */ if (dm_destroy_session(sid) == -1) { errno_msg("Can't close session"); exit(1); } return(0); }
int main( int argc, char *argv[]) { int c; int error; int mr_flag, alloc_flag, handle_flag, event_flag; void *hanp; size_t hlen; char *filename; dm_sessid_t sid; Progname = argv[0]; mr_flag = alloc_flag = handle_flag = event_flag = 0; while ((c = getopt(argc, argv, "maeh")) != EOF) { switch (c) { case 'm': mr_flag = 1; break; case 'a': alloc_flag = 1; break; case 'e': event_flag = 1; break; case 'h': handle_flag = 1; break; case '?': default: usage(Progname); exit(1); } } if (optind >= argc) { usage(Progname); exit(1); } filename = argv[optind]; if (filename == NULL) { usage(Progname); exit(1); } /* * Set up our link to the DMAPI, and get a handle for * the file we want to query */ error = setup_dmapi(&sid); if (error) exit(1); if (dm_path_to_handle(filename, &hanp, &hlen) == -1) { printf("Can't get handle for path %s", filename); error = 1; goto out; } printf("File %s:\n", filename); if (mr_flag) { error = mr_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (alloc_flag) { error = alloc_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (event_flag) { error = event_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } if (handle_flag) { error = handle_info(sid, hanp, hlen); if (error) { error = 1; goto out; } } out: if (dm_destroy_session(sid)) { errno_msg("Can't shut down session"); error = 1; } return(error); }
/* * Get the complete list of events for a file. */ int event_info( dm_sessid_t sid, void *hanp, size_t hlen) { u_int ret; dm_eventset_t eventlist; DMEV_ZERO(eventlist); if (dm_get_eventlist(sid, hanp, hlen, DM_NO_TOKEN, DM_EVENT_MAX, &eventlist, &ret)) { errno_msg("Can't get list of events"); return(1); } printf("\n\tEvent list: \n\t\t"); if (DMEV_ISSET(DM_EVENT_MOUNT, eventlist)) printf("mount "); if (DMEV_ISSET(DM_EVENT_PREUNMOUNT, eventlist)) printf("preunmount "); if (DMEV_ISSET(DM_EVENT_UNMOUNT, eventlist)) printf("unmount "); if (DMEV_ISSET(DM_EVENT_DEBUT, eventlist)) printf("debut "); if (DMEV_ISSET(DM_EVENT_CREATE, eventlist)) printf("create "); if (DMEV_ISSET(DM_EVENT_POSTCREATE, eventlist)) printf("postcreate "); if (DMEV_ISSET(DM_EVENT_REMOVE, eventlist)) printf("remove "); if (DMEV_ISSET(DM_EVENT_POSTREMOVE, eventlist)) printf("postmount "); if (DMEV_ISSET(DM_EVENT_RENAME, eventlist)) printf("rename "); if (DMEV_ISSET(DM_EVENT_POSTRENAME, eventlist)) printf("postrename "); if (DMEV_ISSET(DM_EVENT_LINK, eventlist)) printf("link "); if (DMEV_ISSET(DM_EVENT_POSTLINK, eventlist)) printf("postlink "); if (DMEV_ISSET(DM_EVENT_SYMLINK, eventlist)) printf("symlink "); if (DMEV_ISSET(DM_EVENT_POSTSYMLINK, eventlist)) printf("postsymlink "); if (DMEV_ISSET(DM_EVENT_READ, eventlist)) printf("read "); if (DMEV_ISSET(DM_EVENT_WRITE, eventlist)) printf("write "); if (DMEV_ISSET(DM_EVENT_TRUNCATE, eventlist)) printf("truncate "); if (DMEV_ISSET(DM_EVENT_ATTRIBUTE, eventlist)) printf("attribute "); if (DMEV_ISSET(DM_EVENT_DESTROY, eventlist)) printf("destroy "); if (DMEV_ISSET(DM_EVENT_NOSPACE, eventlist)) printf("nospace "); if (DMEV_ISSET(DM_EVENT_USER, eventlist)) printf("user "); printf("\n"); return(0); }
void parse_cmd(char *cmd) { cmd = remove_leading_whitespaces(cmd); char *tok = find_next_space(cmd); // Find Command int status; debug_msg(cmd); #if USEBUILTINCLEAR if (strcmp(cmd, "clear") == 0) { clear(); } else #endif if (strcmp(cmd, "env") == 0) { env(); } else if (strcmp(cmd, "quit") == 0) { exit(EXIT_SUCCESS); } else if (strcmp(cmd, "version") == 0) { version(); } else if (strcmp(cmd, "pwd") == 0) { pwd(); } #if USEBUILTINLS else if (strcmp(cmd, "ls") == 0) { ls(); } #endif else if (strcmp(cmd, "echo") == 0) { find_next_space(tok); remove_character(tok,'\\'); echo(tok); } else if (strcmp(cmd, "cd") == 0) { find_next_space(tok); // Get Path remove_character(tok,'\\'); // Remove all '\' in target Path. debug_msg(tok); cd(tok); } else if (strcmp(cmd, "set") == 0) { // Get Name of Variable char *buffer = strtok(tok,"="); // Get new Value of Variable and set. set(buffer, strtok(NULL,"=")); } else if (strcmp(cmd, "\0") == 0) { // Do nothing. } else { // Fork application here pid_t pID = fork(); if (pID < 0) { // pID == -1: There was an error! Quit shawn!! errno_msg("Could not fork.",0); } else if (pID > 0) { // Parent Process, pID is PID of child. pID = wait(&status); // Wait for childs completion. if (WIFEXITED(status)) { // Has Child ended? last_exit_code = WEXITSTATUS(status); // Set our internal $? #if DEBUG printf("[DEBUG] Child exited with %i\n",last_exit_code); #endif } } else { // PID == 0 // Child Process. // We need to fork here. unsigned int i = 2; // Prepare a counter char *parameters[count_paramters(tok)]; // Create a list for parameters char *buffer = find_next_space(tok); // Select first parameter. remove_character(tok,'\\'); parameters[0] = cmd; // Set name of call. See execvp() Documentation parameters[1] = tok; // Set first parameter. // Save every Parameter now for our Call while (buffer != NULL) { // We need a second pointer here. char *placeholder = find_next_space(buffer); // remove all \ characters while(remove_next_special_character(buffer,'\\') == 1); // Set the Parameter to our newly delimited string parameters[i] = buffer; // Replace buffer with our placeholder buffer = placeholder; i++; // Increment i, so we set the next parameter } parameters[i-1] = NULL; // Remove an empty Parameter. Else This would be a whitespace // Run Application now. int result = execvp(cmd,parameters); if (result != 0) { errno_msg("Executing Application",1); } exit(result); } } // End of fork() Stuff. }
int main( int argc, char *argv[]) { int c; int error; char *fsname, *logfile; dm_sessid_t sid; void *fs_hanp; size_t fs_hlen; Progname = argv[0]; fsname = NULL; logfile = NULL; while ((c = getopt(argc, argv, "vl:")) != EOF) { switch (c) { case 'v': Verbose = 1; break; case 'l': logfile = optarg; break; case '?': default: usage(Progname); exit(1); } } if (optind >= argc) { usage(Progname); exit(1); } fsname = argv[optind]; if (fsname == NULL) { usage(Progname); exit(1); } /* * If no logfile name is specified, we'll just send * all output to some file in /tmp */ if (logfile == NULL) logfile = LOG_DEFAULT; /* * Now we have our filesystem name and possibly a size threshold * to look for. Init the dmapi, and get a filesystem handle so * we can set up our events */ error = setup_dmapi(&sid); if (error) exit(1); if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) { errno_msg("Can't get filesystem handle"); exit(1); } /* * Turn ourselves into a daemon */ error = mk_daemon(logfile); if (error) exit(1); /* * Set the event disposition so that our session will receive * the managed region events (read, write, and truncate) */ error = set_events(sid, fs_hanp, fs_hlen); if (error) exit(1); /* * Now wait forever for messages, spawning kids to * do the actual work */ event_loop(sid); return(0); }
void migin_exit(int x) { dm_sessid_t *sidbuf, *sid; void *infobuf; char *cp; u_int nsessions, nret; int i, found, error; size_t buflen, retlen; sidbuf = NULL; infobuf = NULL; /* * We could try and kill off all our kids, but we're not * 'Mr. Mean', so we just wait for them to die. */ err_msg("%s: waiting for all children to die...", Progname); while (wait3((int *)0, WNOHANG, (struct rusage *)0) > 0) ; fprintf(stdout, "\n"); /* * Now search for our session and try and shut it down. We * could just as easily make the session ID a global, but * this demonstrates how sessions can be queried */ nsessions = 4; sidbuf = (dm_sessid_t *)malloc(nsessions * sizeof(dm_sessid_t)); if (sidbuf == NULL) { err_msg("Can't alloc mem to shut down session"); goto out; } error = dm_getall_sessions(nsessions, sidbuf, &nret); if (error == -1) { if (errno != E2BIG) { errno_msg("Can't get list of active sessions"); goto out; } free(sidbuf); nsessions = nret; sidbuf = (dm_sessid_t *)malloc(nsessions * sizeof(dm_sessid_t)); if (sidbuf == NULL) { err_msg("Can't alloc mem to shut down session"); goto out; } error = dm_getall_sessions(nsessions, sidbuf, &nret); if (error == -1) { errno_msg("Can't get list of active sessions"); goto out; } } /* * Now we have all the active sessions in our system. * Query each one until we find ourselves. */ sid = sidbuf; buflen = DM_SESSION_INFO_LEN; infobuf = malloc(buflen); if (infobuf == NULL) { err_msg("Can't alloc memory for session info buffer"); goto out; } /* * When we registered our session, we just hammered the last component * of the path name, so that's all we look for here. This prevents * mismatches when running at ./migin or some other such foo */ cp = strrchr(Progname, '/'); if (cp) cp++; else cp = Progname; found = 0; for (i=0; i<nret; i++) { error = dm_query_session(*sid, buflen, infobuf, &retlen); if (error == -1) continue; /* We just punt on errors */ if (strstr(infobuf, cp)) { found = 1; break; } sid++; } /* * XXXX FIXME XXX * * Should do a set_disp to 0 and then drain the session * queue as well. On the SGI, we'll need to make the * filesystem handle global so that we can get at it */ if (!found) { err_msg("Can't find session to shut down"); goto out; } error = dm_destroy_session(*sid); if (error == -1) { errno_msg("Can't shut down session"); } out: if (infobuf) free(infobuf); if (sidbuf) free(sidbuf); exit(0); }
int main( int argc, char *argv[]) { int c; int error; char *fsname; dm_sessid_t sid; void *fs_hanp; size_t fs_hlen; dm_attrname_t dmattr; size_t bufsz = 65536; dm_attrname_t *dmattrp = NULL; int verbose = V_PRINT; Progname = argv[0]; memset(&dmattr, 0, sizeof(dmattr)); while ((c = getopt(argc, argv, "a:b:vq")) != EOF) { switch (c) { case 'a': if (strlen(optarg) > (DM_ATTR_NAME_SIZE-1)){ printf("Arg for -a too long\n"); exit(1); } strcpy((char*)dmattr.an_chars, optarg); dmattrp = &dmattr; break; case 'b': bufsz = atoi(optarg); break; case 'v': verbose |= V_VERBOSE; break; case 'q': verbose &= ~V_PRINT; break; case '?': default: usage(Progname); exit(1); } } if (optind >= argc) { usage(Progname); exit(1); } fsname = argv[optind]; /* * Now we have our filesystem name and possibly a size threshold * to look for. Init the dmapi, and get a filesystem handle so * we can scan the filesystem */ error = setup_dmapi(&sid); if (error) exit(1); if (dm_path_to_fshandle(fsname, &fs_hanp, &fs_hlen) == -1) { errno_msg("Can't get filesystem handle"); exit(1); } /* * Get the attributes of all files in the filesystem */ error = scan_fs(sid, fs_hanp, fs_hlen, dmattrp, bufsz, verbose); if (error) exit(1); /* * We're done, so we can shut down our session. */ if (dm_destroy_session(sid) == -1) { errno_msg("Can't close session"); exit(1); } return(0); }
/* * Main event loop processing */ void event_loop( dm_sessid_t sid) { void *msgbuf; size_t bufsize, rlen; int error; dm_eventmsg_t *msg; /* * We take a swag at a buffer size. If it's wrong, we can * always resize it */ bufsize = sizeof(dm_eventmsg_t) + sizeof(dm_data_event_t) + HANDLE_LEN; bufsize *= 16; msgbuf = (void *)malloc(bufsize); if (msgbuf == NULL) { err_msg("Can't allocate memory for buffer"); goto out; } for (;;) { error = dm_get_events(sid, ALL_AVAIL_MSGS, DM_EV_WAIT, bufsize, msgbuf, &rlen); if (error == -1) { if (errno == E2BIG) { free(msgbuf); msgbuf = (void *)malloc(rlen); if (msgbuf == NULL) { err_msg("Can't resize msg buffer"); goto out; } continue; } errno_msg("Error getting events from DMAPI"); goto out; } /* * Walk thru the message buffer, pull out each individual * message, and dispatch the messages to child processes * with the sid, token, and data. The children will * respond to the events. */ msg = (dm_eventmsg_t *)msgbuf; while (msg != NULL ) { if (Verbose) { fprintf(stderr, "Received %s, token %d\n", (msg->ev_type == DM_EVENT_READ ? "read" : (msg->ev_type == DM_EVENT_WRITE ? "write" : "trunc")), msg->ev_token); } switch (msg->ev_type) { case DM_EVENT_READ: spawn_kid(sid, msg->ev_token, RESTORE_FILE); break; case DM_EVENT_WRITE: case DM_EVENT_TRUNCATE: spawn_kid(sid, msg->ev_token, INVAL_FILE); break; default: err_msg("Invalid msg type %d\n", msg->ev_type); break; } msg = DM_STEP_TO_NEXT(msg, dm_eventmsg_t *); } } out: if (msgbuf != NULL) free(msgbuf); migin_exit(0); }