summaryrefslogtreecommitdiff
path: root/rmt
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-03-11 22:36:23 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-03-11 22:36:23 +0000
commit3fb3f428eec59be24933a660c6d7dca3fd1242d8 (patch)
treee3d49b215c4fec64b335acc4103536fdf4034820 /rmt
parent6d46380177ec3d18deaf2338072c1baace85eb5f (diff)
downloadpaxutils-3fb3f428eec59be24933a660c6d7dca3fd1242d8.tar.gz
(get_string): Renamed to get_string_n. All callers
changed. (get_string,free_string,i18n_setup): New function. (usage): Call i18n_setup (open_device): Use new get_string function to remove the limitation on the device name length.
Diffstat (limited to 'rmt')
-rw-r--r--rmt/rmt.c90
1 files changed, 65 insertions, 25 deletions
diff --git a/rmt/rmt.c b/rmt/rmt.c
index 669d25f..94785a2 100644
--- a/rmt/rmt.c
+++ b/rmt/rmt.c
@@ -38,7 +38,9 @@
#include <safe-read.h>
#include <full-write.h>
#include <version-etc.h>
-
+#define obstack_chunk_alloc malloc
+#define obstack_chunk_free free
+#include <obstack.h>
#include <getopt.h>
#include <sys/socket.h>
@@ -65,6 +67,9 @@ static size_t allocated_size;
/* Buffer for constructing the reply. */
static char reply_buffer[BUFSIZ];
+/* Obstack for arbitrary-sized strings */
+struct obstack string_stk;
+
/* Debugging tools. */
static FILE *debug_file;
@@ -96,18 +101,47 @@ report_numbered_error (int num)
full_write (STDOUT_FILENO, reply_buffer, strlen (reply_buffer));
}
+static char *
+get_string ()
+{
+ size_t counter;
+
+ for (counter = 0; ; counter++)
+ {
+ char c;
+ if (safe_read (STDIN_FILENO, &c, 1) != 1)
+ exit (EXIT_SUCCESS);
+
+ if (c == '\n')
+ break;
+
+ obstack_1grow (&string_stk, c);
+ }
+ obstack_1grow (&string_stk, 0);
+ return obstack_finish (&string_stk);
+}
+
+static void
+free_string (char *string)
+{
+ obstack_free (&string_stk, string);
+}
+
static void
-get_string (char *string)
+get_string_n (char *string)
{
- int counter;
+ size_t counter;
for (counter = 0; ; counter++)
{
if (safe_read (STDIN_FILENO, string + counter, 1) != 1)
exit (EXIT_SUCCESS);
- if (string[counter] == '\n' || counter == STRING_SIZE - 1)
+ if (string[counter] == '\n')
break;
+
+ if (counter == STRING_SIZE - 1)
+ report_error_message (N_("Input string too long"));
}
string[counter] = '\0';
}
@@ -244,11 +278,23 @@ static struct option const long_opts[] =
{0, 0, 0, 0}
};
+/* In-line localization is used only if --help or --version are
+ locally used. Otherwise, the localization burden lies with tar. */
+static void
+i18n_setup ()
+{
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+}
+
static void usage (int) __attribute__ ((noreturn));
static void
usage (int status)
{
+ i18n_setup ();
+
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
@@ -282,17 +328,18 @@ respond (long status)
static void
open_device (void)
{
- char device_string[STRING_SIZE];
+ char *device_string;
char oflag_string[STRING_SIZE];
- get_string (device_string);
- get_string (oflag_string);
+ device_string = get_string ();
+ get_string_n (oflag_string);
DEBUG2 ("rmtd: O %s %s\n", device_string, oflag_string);
if (tape >= 0)
close (tape);
tape = open (device_string, decode_oflag (oflag_string), MODE_RW);
+ free_string (device_string);
if (tape < 0)
report_numbered_error (errno);
else
@@ -302,9 +349,7 @@ open_device (void)
static void
close_device (void)
{
- char device_string[STRING_SIZE];
-
- get_string (device_string); /* discard */
+ free_string (get_string ()); /* discard */
DEBUG ("rmtd: C\n");
if (close (tape) < 0)
@@ -326,8 +371,8 @@ lseek_device (void)
int whence;
char *p;
- get_string (count_string);
- get_string (position_string);
+ get_string_n (count_string);
+ get_string_n (position_string);
DEBUG2 ("rmtd: L %s %s\n", count_string, position_string);
/* Parse count_string, taking care to check for overflow.
@@ -409,7 +454,7 @@ write_device (void)
size_t counter;
size_t status = 0;
- get_string (count_string);
+ get_string_n (count_string);
size = get_long (count_string);
DEBUG1 ("rmtd: W %s\n", count_string);
@@ -440,7 +485,7 @@ read_device (void)
size_t size;
size_t status;
- get_string (count_string);
+ get_string_n (count_string);
DEBUG1 ("rmtd: R %s\n", count_string);
size = get_long (count_string);
@@ -462,8 +507,8 @@ mtioctop (void)
char operation_string[STRING_SIZE];
char count_string[STRING_SIZE];
- get_string (operation_string);
- get_string (count_string);
+ get_string_n (operation_string);
+ get_string_n (count_string);
DEBUG2 ("rmtd: I %s %s\n", operation_string, count_string);
#ifdef MTIOCTOP
@@ -545,16 +590,10 @@ main (int argc, char **argv)
{
char command;
- /* FIXME: Localization is meaningless, unless --help and --version are
- locally used. Localization would be best accomplished by the calling
- tar, on messages found within error packets. */
-
program_name = argv[0];
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-
+ obstack_init (&string_stk);
+
switch (getopt_long (argc, argv, "", long_opts, NULL))
{
default:
@@ -564,6 +603,7 @@ main (int argc, char **argv)
usage (EXIT_SUCCESS);
case 'v':
+ i18n_setup ();
version_etc (stdout, "rmt", PACKAGE_NAME, PACKAGE_VERSION,
"John Gilmore", "Jay Fenlason", (char *) NULL);
close_stdout ();
@@ -624,7 +664,7 @@ main (int argc, char **argv)
break;
default:
- DEBUG1 (_("rmtd: Garbage command %c\n"), command);
+ DEBUG1 ("rmtd: Garbage command %c\n", command);
report_error_message (N_("Garbage command"));
return EXIT_FAILURE; /* exit status used to be 3 */
}