/* Modified by address@hidden to support the command argument syntax: -M !:scriptname which executes the script when a medium change is needed. The script will be called with the (incremented) reel number as its first (and only) argument. Limitations in the string "scriptname": no %d syntax supported, and it must fit in the new_name buffer (see ds_init statement below) */ void get_next_reel (tape_des) int tape_des; { static int reel_number = 1; FILE *tty_in; /* File for interacting with user. */ FILE *tty_out; /* File for interacting with user. */ int old_tape_des; char *systemcmd; char *next_archive_name; int retval; dynamic_string new_name; char *str_res; ds_init (&new_name, 128); if ((new_media_message) && ((new_media_message[0] == ':')&&(new_media_message[1] == '!'))) { systemcmd = &new_media_message[2]; } else { systemcmd = NULL; /* Open files for interactive communication. */ tty_in = fopen (CONSOLE, "r"); if (tty_in == NULL) error (2, errno, CONSOLE); tty_out = fopen (CONSOLE, "w"); if (tty_out == NULL) error (2, errno, CONSOLE); } old_tape_des = tape_des; tape_offline (tape_des); rmtclose (tape_des); ++reel_number; if (!systemcmd) { /* Give message and wait for carrage return. User should hit carriage return only after loading the next tape. */ if (new_media_message) fprintf (tty_out, "%s", new_media_message); else if (new_media_message_with_number) fprintf (tty_out, "%s%d%s", new_media_message_with_number, reel_number, new_media_message_after_number); else if (archive_name) fprintf (tty_out, "Found end of tape. Load next tape and press RETURN. "); else fprintf (tty_out, "Found end of tape. To continue, type device/file name when ready.\n"); fflush (tty_out); if (archive_name) { int c; do c = getc (tty_in); while (c != EOF && c != '\n'); tape_des = open_archive (archive_name); if (tape_des == -1) error (1, errno, "%s", archive_name); } else { do { if (tape_des < 0) { fprintf (tty_out, "To continue, type device/file name when ready.\n"); fflush (tty_out); } str_res = ds_fgets (tty_in, &new_name); if (str_res == NULL || str_res[0] == '\0') exit (1); next_archive_name = str_res; tape_des = open_archive (next_archive_name); if (tape_des == -1) error (0, errno, "%s", next_archive_name); } while (tape_des < 0); } } else { /* We have a command to execute: 128-12 char max stringlength; 12 chars as safety margin is a more or less arbitrary choice */ strncpy(new_name.ds_string, systemcmd, 128-12); new_name.ds_string[128-12] = '\0'; /* safety first */ sprintf(&new_name.ds_string[strlen(new_name.ds_string)], " %-10d", reel_number); retval = system(new_name.ds_string); if (retval != 0) error (retval, errno, "%s", new_name.ds_string); tape_des = open_archive (archive_name); if (tape_des == -1) error (1, errno, "%s", archive_name); } /* We have to make sure that `tape_des' has not changed its value even though we closed it and reopened it, since there are local copies of it in other routines. This works fine on Unix (even with rmtread and rmtwrite) since open will always return the lowest available file descriptor and we haven't closed any files (e.g., stdin, stdout or stderr) that were opened before we originally opened the archive. */ if (tape_des != old_tape_des) error (1, 0, "internal error: tape descriptor changed from %d to %d", old_tape_des, tape_des); free (new_name.ds_string); if (!systemcmd) { fclose (tty_in); fclose (tty_out); } }