[comp.sys.apollo] yacp

denis@vlsisj.VLSI.COM (Denis Bohm) (08/17/90)

Here is a cut/paste tool that I wrote for DM and X a while
ago.  It should be able to handle any size cut/paste buffer.
It even comes with a man page...

Denis


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	xacp.man
#	xacp.c
#	Makefile
# This archive created: Thu Aug 16 13:09:08 1990
export PATH; PATH=/bin:$PATH
if test -f 'xacp.man'
then
	echo shar: will not over-write existing file "'xacp.man'"
else
cat << \SHAR_EOF > 'xacp.man'
.TH XACP L "1990 Aug 16"
.SH NAME
xacp \- X and apollo copy/paste utility.
.SH SYNOPSIS
.B xacp
.RB [\-hu]
.RB [\-xa]
.RB [\-b <buffer number>]
.RB [\-n <buffer name>]
.RB [\-t]
.RB [\-c]
.RB [\-p <text>]
.br
.SH DESCRIPTION
.LP
.B xacp
lets you do various things with X and apollo paste buffers.  It can be used
to transfer between the X and apollo buffers, copy from X or apollo buffer
to stdout, and paste text into an X or apollo buffer.
.SH OPTIONS
Terse help information can be accessed with
.RB (\-h).
Terse usage information can be accessed with
.RB (\-u).
To select an X buffer as the primary and an apollo buffer as the secondary use
.RB (\-x),
this is the default.
To select an apollo buffer as the primary and an X buffer as the secondary use
.RB (\-a).
The X buffer number can be selected with
.RB (\-b <buffer number>).
The apollo buffer name can be selected with
.RB (\-n <buffer name>).
The operation must be one of: transfer from primary to secondary
.RB (\-t),
copy from primary to stdout
.RB (\-c),
paste text to primary
.RB (\-p <text>).
.SH USAGE
The default options are:
.nf
  xacp -x -b 0 -n default.txt -t
.fi

.SH EXAMPLES
Copy X default paste buffer to apollo default paste buffer:
.nf
example% xacp
example% xacp -x
.fi

Copy apollo default paste buffer to X default paste buffer:
.nf
example% xacp -a
.fi

Copy any X paste buffer to any apollo paste buffer:
.nf
example% xacp -x -b 1 -n line_del
.fi

Setup the apollo numeric keypad + and - keys to transfer between the default X
and apollo cut/paste buffers (you might want to do put the next two lines
in ~/user_data/startup_dm.19l):
.nf
kd np+ cpo //lodi/users/denis/bin/xacp -a ke
kd np- cpo //lodi/users/denis/bin/xacp -x ke
.fi
.SH SEE ALSO
.B xcutsel (1)
.B dm (1)
.SH BUGS
.I None.
.SH AUTHORS
Denis Bohm
SHAR_EOF
fi # end of overwriting check
if test -f 'xacp.c'
then
	echo shar: will not over-write existing file "'xacp.c'"
else
cat << \SHAR_EOF > 'xacp.c'
/*
 * Author:  Denis Bohm
 * Address: denis@vlsisj
 * Created: 21-Dec-1989
 * File:    xacp.c
 *
 * This program (xacp) allows you to transfer the contents of the
 * X and apollo copy/paste buffers.  It has options so that you can
 * choose which of the X and apollo buffers to use.  It also has
 * options so that you can just copy a buffer to stdout and paste
 * a command line argument to any buffer.  It would be nice if it
 * could also paste from stdin, but it doesn't right now.
 *
 * Users may copy, modify or distribute this file at will.
 */

#include <stdio.h>
#include <X11/Xlib.h>
#include <apollo/base.h>
#include <apollo/error.h>
#include <apollo/type_uids.h>
#include <apollo/ios.h>
#include <apollo/pbufs.h>

extern void *malloc();

void check_status (
  status_$t &status
)
{
  if (status.all != status_$ok) {
    fprintf(stderr, "xacp: ");
    error_$print(status);
    exit(1);
  }
}

void check_status_2 (
  status_$t &status,
  long exception_1,
  long exception_2
)
{
  if ((status.all != status_$ok) && (status.all != exception_1) &&
    (status.all != exception_2)) {
    fprintf(stderr, "xacp: ");
    error_$print(status);
    exit(1);
  }
}

void pbufs_open (
  char      *buffer_name,
  boolean   &type,
  ios_$id_t *stream_id,
  status_$t *status
)
{
  name_$long_pname_t path_name;

  strcpy(path_name, "/sys/node_data/paste_buffers/");
  strncat(path_name, buffer_name, name_$long_pnamlen_max - strlen(path_name));
  *stream_id = ios_$open(path_name, strlen(path_name), ios_$unregulated_opt,
    status);
}

void pbufs_create (
  char      *buffer_name,
  boolean   &type,
  ios_$id_t *stream_id,
  status_$t *status
)
{
  name_$long_pname_t path_name;

  strcpy(path_name, "/sys/node_data/paste_buffers/");
  strncat(path_name, buffer_name, name_$long_pnamlen_max - strlen(path_name));
  ios_$create(path_name, strlen(path_name), unstruct_$uid, ios_$truncate_mode,
    ios_$write_opt | ios_$unregulated_opt, stream_id, status);
}

char *apollo_copy (
  char *name,
)
{
#define BUFFER_SIZE 32

  boolean type = false;
  ios_$id_t stream_id;
  status_$t status;
  char buffer[BUFFER_SIZE + 1];
  int amount;
  int offset;
  char *text;

/* how does type work?                              */
/* why doesn't pbufs_$open work? -denis 20-Dec-1989 */
/*
  pbufs_$open(name, type, &stream_id, &status);
*/
  pbufs_open(name, type, &stream_id, &status);
  check_status(status);

  amount = 0;
  do {
    amount += ios_$get(stream_id, ios_$no_put_get_opts, buffer, BUFFER_SIZE,
      &status);
    check_status_2(status, ios_$end_of_file, ios_$buffer_too_small);
  } while (status.all != ios_$end_of_file);

  text = (char *) malloc(amount);
  ios_$seek_to_bof(stream_id, &status);
  check_status;
  offset = 0;
  do {
    offset += ios_$get(stream_id, ios_$no_put_get_opts, &text[offset],
      amount - offset, &status);
    check_status_2(status, ios_$end_of_file, ios_$buffer_too_small);
  } while (status.all != ios_$end_of_file);
  check_status;

  ios_$close(stream_id, &status);
  check_status(status);

  return text;
}

void *apollo_paste (
  char *name,
  char *text
)
{
  boolean type = false;
  ios_$id_t stream_id;
  status_$t status;
  ios_$put_get_opts_t opts = ios_$no_put_get_opts;

/* how does type work?                                */
/* why doesn't pbufs_$create work? -denis 20-Dec-1989 */
/*
  pbufs_$create(name, type, &stream_id, &status);
*/
  pbufs_create(name, type, &stream_id, &status);
  check_status(status);
  ios_$put(stream_id, opts, text, strlen(text), &status);
  check_status(status);
  ios_$truncate(stream_id, &status);
  check_status(status);
  ios_$close(stream_id, &status);
  check_status(status);
}

char *X_copy (
  int buffer
)
{
  Display *display;
  char *text;
  int bytes;

  display = XOpenDisplay(NULL);
  if (! display) {
    fprintf(stderr, "xacp: can't open %s\n", XDisplayName(NULL));
    exit(1);
  }
  text = XFetchBuffer(display, &bytes, buffer);
/*
  fprintf(stderr, "%d %d\n", bytes, strlen(text));
*/
  {
    int i;

    for (i = 0; i < bytes; i++) {
      if (text[i] == '\0') {
        text[i] = '*';
        fprintf(stderr, "\\0 found at %d (replaced with \*)\n", i);
      }
    }
  }
  XCloseDisplay(display);

  return text;
}

void X_paste (
  int buffer,
  char *text
)
{
  Display *display;

  display = XOpenDisplay(NULL);
  if (! display) {
    fprintf(stderr, "xacp: can't open %s\n", XDisplayName(NULL));
    exit(1);
  }
  XStoreBuffer(display, text, strlen(text), buffer);
  XCloseDisplay(display);
}

void print_usage(void)
{
  fprintf(stderr,
    "Usage: xacp [-h | -u] [-x | -a] [-b number] [-n name] [-t | -c | -p text]\n");
}

void print_help(void)
{
  fprintf(stderr, "Name:\n");
  fprintf(stderr, "  xacp - X and apollo copy/paste utility.\n");
  fprintf(stderr, "Options:\n");
  fprintf(stderr, "  -h           print help message\n");
  fprintf(stderr, "  -u           print usage message\n");
  fprintf(stderr, "  -x           use X paste buffer as the primary (apollo as secondary)\n");
  fprintf(stderr, "  -a           use apollo paste buffer as the primary (X as secondary)\n");
  fprintf(stderr, "  -b [number]  specify the number of the X paste buffer to use\n");
  fprintf(stderr, "  -n [name]    specify the name of the apollo paste buffer to use\n");
  fprintf(stderr, "  -t           transfer from primary to secondary\n");
  fprintf(stderr, "  -c           copy from primary to stdout\n");
  fprintf(stderr, "  -p [text]    paste text to primary\n");
  fprintf(stderr, "Default options:\n");
  fprintf(stderr, "  xacp -x -b 0 -n default.txt -t\n");
  fprintf(stderr, "Examples:\n");
  fprintf(stderr, "  Copy X default paste buffer to apollo default paste buffer:\n");
  fprintf(stderr, "    xacp -x\n");
  fprintf(stderr, "    xacp\n");
  fprintf(stderr, "  Copy apollo default paste buffer to X default paste buffer:\n");
  fprintf(stderr, "    xacp -a\n");
  fprintf(stderr, "  Copy any X paste buffer to any apollo paste buffer:\n");
  fprintf(stderr, "    xacp -x -b 1 -n line_del\n");
}

main(argc, argv)
int argc;
char **argv;
{
  extern int optind;
  extern char *optarg;
  static char *options = "vhuaxn:b:tcp:";
  char *text;
  char *name = "default.txt";
  int buffer = 0;
  int src = 'x';
  int mode = 't';
  int opt;
  int verbose = 0;

  while ((opt = getopt(argc, argv, options)) != EOF) {
    switch (opt) {
      case 'x':
      case 'a':
        src = opt;
      break;

      case 't':
      case 'c':
      case 'p':
        mode = opt;
        if (mode == 'p') {
          text = optarg;
        }
      break;

      case 'n':
        name = ((! optarg) || (optarg[0] == '\0') ? "default.txt" : optarg);
      break;

      case 'b':
        buffer = ((! optarg) || (optarg[0] == '\0') ? 0 : atoi(optarg));
        if ((0 > buffer) || (buffer > 7)) {
          fprintf(stderr,
            "xacp: illegal X buffer %d (must be between 0 and 7)\n", buffer);
        }
      break;

      case 'v':
        verbose = 1;
        break;

      case 'h':
      case 'u':
      default:
        print_usage();
        if (opt == 'u') exit(0);
        print_help();
        if (opt == 'h') exit(0);
        exit(1);
    }
  }

  if (verbose) {
    printf("xacp: src: %c, buffer: %d, name: %s\n", src, buffer, name);
    if (mode == 'p') {
      printf("xacp: text: %s\n", text);
    }
  }

  if (mode == 't') {
    if (src == 'x') {
      apollo_paste(name, X_copy(buffer));
    } else {
      X_paste(buffer, apollo_copy(name));
    }
  } else if (mode == 'c') {
    printf("%s", (src == 'x' ? X_copy(buffer) : apollo_copy(name)));
  } else if (mode == 'p') {
    if (src == 'x') {
      X_paste(buffer, text);
    } else {
      apollo_paste(name, text);
    }
  }

  exit(0);
}
SHAR_EOF
chmod +x 'xacp.c'
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
all: xacp

xacp: xacp.c
	cc -g xacp.c -o xacp

install: xacp
	cp xacp /usr/local/bin/xacp

install.man:
	cp xacp.man /usr/local/man/manl/xacp.l

clean:
	rm xacp
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
Denis Bohm    (usenet: decwrl!vlsisj!denis)
              (internet: vlsisj!denis@decwrl.dec.com)