+ {
+ char count_string[STRING_SIZE];
+ char position_string[STRING_SIZE];
+ off_t count = 0;
+ int negative;
+ int whence;
+ char *p;
+
+ get_string (count_string);
+ get_string (position_string);
+ DEBUG2 ("rmtd: L %s %s\n", count_string, position_string);
+
+ /* Parse count_string, taking care to check for overflow.
+ We can't use standard functions,
+ since off_t might be longer than long. */
+
+ for (p = count_string; *p == ' ' || *p == '\t'; p++)
+ continue;
+
+ negative = *p == '-';
+ p += negative || *p == '+';
+
+ for (;;)
+ {
+ int digit = *p++ - '0';
+ if (9 < (unsigned) digit)
+ break;
+ else
+ {
+ off_t c10 = 10 * count;
+ off_t nc = negative ? c10 - digit : c10 + digit;
+ if (c10 / 10 != count || (negative ? c10 < nc : nc < c10))
+ {
+ report_error_message (N_("Seek offset out of range"));
+ exit (EXIT_FAILURE);
+ }
+ count = nc;
+ }
+ }
+
+ switch (atoi (position_string))
+ {
+ case 0: whence = SEEK_SET; break;
+ case 1: whence = SEEK_CUR; break;
+ case 2: whence = SEEK_END; break;
+ default:
+ report_error_message (N_("Seek direction out of range"));
+ exit (EXIT_FAILURE);
+ }
+ count = lseek (tape, count, whence);
+ if (count < 0)
+ goto ioerror;
+
+ /* Convert count back to string for reply.
+ We can't use sprintf, since off_t might be longer than long. */
+ p = count_string + sizeof count_string;
+ *--p = '\0';
+ do
+ *--p = '0' + (int) (count % 10);
+ while ((count /= 10) != 0);
+
+ DEBUG1 ("rmtd: A %s\n", p);
+
+ sprintf (reply_buffer, "A%s\n", p);
+ full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
+ goto top;
+ }