home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!destroyer!gatech!emory!emory!not-for-mail
- From: johnl@obelix.informix.com (Jonathan Leffler)
- Newsgroups: comp.databases.informix
- Subject: Re: Inserting BLOB into Database Table
- Date: 5 Nov 1992 14:53:17 -0500
- Organization: Mailing List Gateway
- Lines: 1180
- Sender: walt@mathcs.emory.edu
- Distribution: world
- Message-ID: <1dbu3dINNqhe@emory.mathcs.emory.edu>
- Reply-To: johnl@obelix.informix.com (Jonathan Leffler)
- NNTP-Posting-Host: emory.mathcs.emory.edu
- X-Informix-List-ID: <list.1572>
-
-
- You don't say what tools you have available...
-
- If you have ISQL, the following info may be of relevance:
-
- >From: johnl (Jonathan Leffler)
- >Date: Wed Nov 4 09:53:59 1992
- >To: skidwell@jupiter
- >Subject: Re: loading into blob space thru sql
- >
- >>Date: Tue, 3 Nov 92 14:45:21 CST
- >>From: skidwell@jupiter (Sherri Kidwell)
- >>To: tech@jupiter
- >>Subject: loading into blob space thru sql
- >
- >>I have a customer that wants to load a gif file as a blob into
- >>a table through SQL only. Can this be done? If so, how?
- >
- >Dear Sherri,
- >
- >The only possible route is through The PROGRAM attribute in the blob field
- >attributes of a Perform screen -- the load command requires the data in its
- >own format, and nothing else gets close.
- >
- >The program specified by the form will be invoked with the name of a
- >temporary file as the blob. When the program returns, the contents of that
- >file will be used as the blob. So, the obvious solution seems to be a
- >script of some sort which allows the user to specify a GIF file name. I
- >tried a solution which removed the original temporary file, and did a
- >symbolic link to the GIF file. Perform should have cleaned up after itself
- >by removing the symbolic link. However, this did not work satisfactorily
- >-- it zapped the script I had developed (because I pretended that the
- >script was a GIF file), which was a nuisance though hardly serious. It
- >seems that the successful way of doing it is to copy the GIF file over the
- >temporary file, which leads to the following Bourne Shell script:
- >
- >echo
- >#echo -n "Enter name of GIF file: "
- >echo "Enter name of GIF file: \c"
- >read file
- >cp $file $1
- >
- >The first echo places the prompt on the line after the "Please wait!"
- >message issued by Perform. The commented out echo might be necessary on a
- >BSD system where the Bourne shell does not recognise the "\c"
- >metacharacter, which means suppress the newline.
- >
- >Yours,
- >Jonathan Leffler (johnl@obelix)
-
- If you ESQL/C, you may be interested in the program in the shell archive below.
- You may not need getopt.c and/or memmove.c, but I've supplied them just in
- case. The code was developed on Intercative 386/IX 3.2.2 under OnLine and
- ESQL/C 5.00.UC1. You use the program updblob as:
-
- updblob -d database -t table -k column1=1234,column2=ABC -f blob-file
-
- Put quotes around the key strings if there are spaces in the key.
- I cannot guarantee the behaviour of the key parsing code if you have
- either commas or equals signs in the key string.
-
- Yours,
- Jonathan Leffler (johnl@obelix.informix.com) #include <disclaimer.h>
-
- : "@(#)shar.sh 1.8"
- #! /bin/sh
- #
- # This is a shell archive.
- # Remove everything above this line and run sh on the resulting file.
- # If this archive is complete, you will see this message at the end:
- # "All files extracted"
- #
- # Created: Thu Nov 5 10:02:33 GMT 1992 by johnl at Informix Software Ltd.
- # Files archived in this archive:
- # updblob.ec
- # getopt.c
- # getopt.h
- # stderr.c
- # stderr.h
- # memmove.c
- #
- #--------------------
- if [ -f updblob.ec -a "$1" != "-c" ]
- then echo shar: updblob.ec already exists
- else
- echo 'x - updblob.ec (4395 characters)'
- sed -e 's/^X//' >updblob.ec <<'SHAR-EOF'
- X/*
- X@(#)File: updblob.ec
- X@(#)Version: 1.1
- X@(#)Last changed: 92/10/13
- X@(#)Purpose: General program to update a blob from file
- X@(#)Author: J Leffler
- X@(#)Copyright: (C) JLSS 1992
- X@(#)Product: :PRODUCT:
- X*/
- X
- X/*TABSTOP=4*/
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <sqlca.h>
- X#include <locator.h>
- X#include <sqltypes.h>
- X#include "stderr.h"
- X#include "getopt.h"
- X
- X#define BUFFSIZE 2048
- X#define NIL(x) ((x)0)
- X#define DIM(x) (sizeof(x)/sizeof(*(x)))
- X
- Xextern void sql_error();
- Xextern void locate_file();
- X
- Xstatic char usestr[] =
- X "[-Vx] -d dbase -t table -c blobcolumn -k column=value,... [-f] blobfile";
- X
- X#ifndef lint
- Xstatic char sccs[] = "@(#)updblob.ec 1.1 92/10/13";
- X#endif
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X EXEC SQL BEGIN DECLARE SECTION;
- X char *dbase = (char *)0;
- X loc_t blob;
- X char stmt[BUFFSIZE];
- X EXEC SQL END DECLARE SECTION;
- X char *table = (char *)0;
- X char *blobcol = (char *)0;
- X int nkeycols = 0;
- X char *keycol[16];
- X char *keyval[16];
- X char *blobfile = (char *)0;
- X int opt;
- X char *pad;
- X char *s;
- X int i;
- X int xflag = 0;
- X int len;
- X
- X setarg0(argv[0]);
- X while ((opt = getopt(argc, argv, "Vxd:t:c:k:f:")) != EOF)
- X {
- X switch (opt)
- X {
- X case 'x':
- X xflag = 1;
- X break;
- X case 'V':
- X puts(&"@(#):UPDBLOB:"[4]);
- X exit(0);
- X /*NOTREACHED*/
- X case 't':
- X table = optarg;
- X break;
- X case 'c':
- X blobcol = optarg;
- X break;
- X case 'd':
- X dbase = optarg;
- X break;
- X case 'f':
- X blobfile = optarg;
- X break;
- X case 'k':
- X nkeycols = parse_columns(optarg, keycol, keyval, DIM(keyval));
- X break;
- X default:
- X usage(usestr);
- X /*NOTREACHED*/
- X }
- X }
- X
- X if (blobfile == (char *)0 && optind == argc - 1)
- X blobfile = argv[optind++];
- X if (optind != argc || blobfile == NIL(char *) || dbase == NIL(char *) ||
- X table == NIL(char *) || nkeycols == 0 || blobcol == NIL(char *))
- X usage(usestr);
- X
- X locate_file(&blob, SQLBYTES, blobfile);
- X EXEC SQL DATABASE :dbase;
- X if (sqlca.sqlcode != 0)
- X sql_error("database", dbase);
- X
- X sprintf(stmt, "UPDATE %s SET %s = ? WHERE", table, blobcol);
- X pad = "";
- X s = stmt + strlen(stmt);
- X for (i = 0; i < nkeycols; i++)
- X {
- X sprintf(s, "%s %s = '%s'", pad, keycol[i], keyval[i]);
- X pad = " AND";
- X s += strlen(s);
- X }
- X
- X if (xflag)
- X {
- X len = strlen(stmt);
- X for (i = 0; i < len; i += 75)
- X printf("%.75s\n", &stmt[i]);
- X }
- X
- X EXEC SQL PREPARE p_update FROM :stmt;
- X if (sqlca.sqlcode != 0)
- X sql_error("prepare update", table);
- X EXEC SQL EXECUTE p_update USING :blob;
- X if (sqlca.sqlcode != 0)
- X sql_error("execute update", table);
- X
- X return(0);
- X}
- X
- Xvoid locate_file(blob, type, file)
- Xloc_t *blob;
- Xint type;
- Xchar *file;
- X{
- X blob->loc_indicator = 0;
- X blob->loc_type = type;
- X blob->loc_loctype = LOCFNAME;
- X blob->loc_fname = file;
- X blob->loc_oflags = LOC_RONLY;
- X blob->loc_size = -1;
- X}
- X
- X/* Database generated error */
- Xvoid sql_error(s1, s2)
- Xchar *s1;
- Xchar *s2;
- X{
- X char buffer[512];
- X
- X fflush(stdout);
- X rgetmsg(sqlca.sqlcode, buffer, sizeof(buffer));
- X fprintf(stderr, "SQL %d: ", sqlca.sqlcode);
- X if (sqlca.sqlerrd[1] != 0)
- X fprintf(stderr, "(ISAM %d) ", sqlca.sqlerrd[1]);
- X fprintf(stderr, buffer, sqlca.sqlerrm);
- X if (s1 != NIL(char *))
- X fprintf(stderr, "%s %s\n", s1, (s2 ? s2 : ""));
- X}
- X
- Xchar *process_quote(optarg)
- Xchar **optarg;
- X{
- X char *s = *optarg;
- X char q = *s++;
- X char *p = s;
- X char oc = '\0'; /* Anything except the quote in q */
- X char c;
- X
- X while ((c == *s++) != '\0')
- X {
- X if (c == q && oc != '\\')
- X {
- X *(s-1) = '\0';
- X break;
- X }
- X oc = c;
- X }
- X
- X if (c != q)
- X error2("unclosed quotes in key value", p - 1);
- X
- X *optarg = s;
- X return(p);
- X}
- X
- Xint parse_columns(optarg, keycol, keyval, maxkey)
- Xchar *optarg;
- Xchar **keycol;
- Xchar **keyval;
- Xint maxkey;
- X{
- X int i;
- X char *s;
- X
- X for (i = 0; i < maxkey && *optarg != '\0'; i++)
- X {
- X if ((s = strchr(optarg, '=')) == NIL(char *))
- X error2("key column format error (no '=')", optarg);
- X *keycol++ = optarg;
- X *s = '\0';
- X optarg = s + 1;
- X if (!*optarg)
- X error2("key column with no key value", *(keycol-1));
- X if (*optarg == '\'' || *optarg == '"')
- X *keyval++ = process_quote(&optarg);
- X else if ((s = strchr(optarg, ',')) == NIL(char *))
- X {
- X /* All done -- the only normal return from this code */
- X *keyval++ = optarg;
- X return(i+1);
- X }
- X else
- X {
- X *keyval++ = optarg;
- X *s = '\0';
- X optarg = s + 1;
- X }
- X }
- X error2("too many key columns specified", optarg);
- X /*NOTREACHED*/
- X}
- SHAR-EOF
- chmod 444 updblob.ec
- if [ `wc -c <updblob.ec` -ne 4395 ]
- then echo shar: updblob.ec unpacked with wrong size
- fi
- # end of overwriting check
- fi
- #--------------------
- if [ -f getopt.c -a "$1" != "-c" ]
- then echo shar: getopt.c already exists
- else
- echo 'x - getopt.c (17640 characters)'
- sed -e 's/^X//' >getopt.c <<'SHAR-EOF'
- X/*
- X@(#)File: getopt.c
- X@(#)Version: 2.6
- X@(#)Last changed: 91/12/22
- X@(#)Purpose: GNU version of GETOPT(3)
- X@(#)Copyright: (C) 1987 Free Software Foundation, Inc.
- X@(#)Amendments: J Leffler, JLSS
- X@(#)Product: :PRODUCT:
- X*/
- X
- X/*TABSTOP=4*/
- X/*LINTLIBRARY*/
- X
- X#ifndef lint
- Xstatic char sccs[] = "@(#)getopt.c 2.6 91/12/22";
- X#endif
- X
- X/*
- X** Function xmalloc removed -- inline code used instead.
- X** Changed error message to "out of memory".
- X** Use stdlib.h to declare malloc(). Use memmove() instead of memcpy().
- X** Remove BSD bcopy and index stuff -- not POSIX compatible.
- X**
- X** J Leffler, JLSS, 15th December 1991.
- X*/
- X
- X/*
- X** Global variable optopt added to conform with System V Release 4.
- X** This contains the function return value unless the return value is the
- X** error return '?', in which case, optopt contains the value of the option
- X** which caused the error return. Also use isprint() (from ctype.h) to
- X** determine whether character is printable (instead of the non-portable
- X** and not always helpful (c < 040 || c >= 0177)).
- X**
- X** J Leffler, Informix Software Ltd, 17th December 1990.
- X*/
- X
- X/*
- X** Format of code and comments revised to suit local conventions.
- X** Function completely unaltered, though appended memcpy() removed.
- X** Default compilation changed to SYSV mode -- unless BSD is defined,
- X** it will be compiled using strchr and memcpy.
- X**
- X** NB: this version of getopt(3) allows for flags which take optional
- X** arguments. This is done by using "f::" in place of "f:" in the
- X** option string. The optional argument must be attached to flag.
- X**
- X** J Leffler, Sphinx Ltd, 3rd April 1990.
- X*/
- X
- X/*
- X Getopt for GNU.
- X Modified by David MacKenzie to use malloc and free instead of alloca,
- X and memcpy instead of bcopy under System V.
- X Copyright (C) 1987 Free Software Foundation, Inc.
- X
- X NO WARRANTY
- X
- XBECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
- XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
- XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
- XWITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
- XBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- XFITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
- XAND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
- XDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
- XCORRECTION.
- X
- XIN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
- XWHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
- XLIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
- XOTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- XUSE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
- XDATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
- XA FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
- XPROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- XDAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- X
- X GENERAL PUBLIC LICENSE TO COPY
- X
- X 1. You may copy and distribute verbatim copies of this source file
- Xas you receive it, in any medium, provided that you conspicuously and
- Xappropriately publish on each copy a valid copyright notice "Copyright
- X (C) 1987 Free Software Foundation, Inc."; and include following the
- Xcopyright notice a verbatim copy of the above disclaimer of warranty
- Xand of this License. You may charge a distribution fee for the
- Xphysical act of transferring a copy.
- X
- X 2. You may modify your copy or copies of this source file or
- Xany portion of it, and copy and distribute such modifications under
- Xthe terms of Paragraph 1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating
- X that you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish,
- X that in whole or in part contains or is a derivative of this
- X program or any part thereof, to be licensed at no charge to all
- X third parties on terms identical to those contained in this
- X License Agreement (except that you may choose to grant more
- X extensive warranty protection to third parties, at your option).
- X
- X c) You may charge a distribution fee for the physical act of
- X transferring a copy, and you may at your option offer warranty
- X protection in exchange for a fee.
- X
- X 3. You may copy and distribute this program or any portion of it in
- Xcompiled, executable or object code form under the terms of Paragraphs
- X1 and 2 above provided that you do the following:
- X
- X a) cause each such copy to be accompanied by the
- X corresponding machine-readable source code, which must
- X be distributed under the terms of Paragraphs 1 and 2 above; or,
- X
- X b) cause each such copy to be accompanied by a
- X written offer, with no time limit, to give any third party
- X free (except for a nominal shipping charge) a machine readable
- X copy of the corresponding source code, to be distributed
- X under the terms of Paragraphs 1 and 2 above; or,
- X
- X c) in the case of a recipient of this program in compiled, executable
- X or object code form (without the corresponding source code) you
- X shall cause copies you distribute to be accompanied by a copy
- X of the written offer of source code which you received along
- X with the copy you received.
- X
- X 4. You may not copy, sublicense, distribute or transfer this program
- Xexcept as expressly provided under this License Agreement. Any attempt
- Xotherwise to copy, sublicense, distribute or transfer this program is void and
- Xyour rights to use the program under this License agreement shall be
- Xautomatically terminated. However, parties who have received computer
- Xsoftware programs from you with this License Agreement will not have
- Xtheir licenses terminated so long as such parties remain in full compliance.
- X
- X 5. If you wish to incorporate parts of this program into other free
- Xprograms whose distribution conditions are different, write to the Free
- XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
- Xworked out a simple rule that can be stated here, but we will often permit
- Xthis. We will be guided by the two goals of preserving the free status of
- Xall derivatives of our free software and of promoting the sharing and reuse of
- Xsoftware.
- X
- XIn other words, you are welcome to use, share and improve this program.
- XYou are forbidden to forbid anyone else to use, share and improve
- Xwhat you give them. Help stamp out software-hoarding!
- X*/
- X
- X/*
- X** This version of `getopt' appears to the caller like standard Unix `getopt'
- X** but it behaves differently for the user, since it allows the user
- X** to intersperse the options with the other arguments.
- X**
- X** As `getopt' works, it permutes the elements of `argv' so that,
- X** when it is done, all the options precede everything else. Thus
- X** all application programs are extended to handle flexible argument order.
- X**
- X** Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
- X** Then the behavior is completely standard.
- X**
- X** GNU application programs can use a third alternative mode in which
- X** they can distinguish the relative order of options and other arguments.
- X*/
- X
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <string.h>
- X#include <ctype.h>
- X
- X/*
- X** optarg -- for communication from `getopt' to the caller.
- X** When `getopt' finds an option that takes an argument,
- X** the argument value is returned here.
- X** Also, when `ordering' is RETURN_IN_ORDER,
- X** each non-option ARGV-element is returned here.
- X*/
- Xchar *optarg = 0;
- X
- X/*
- X** optind -- index in ARGV of the next element to be scanned.
- X** This is used for communication to and from the caller
- X** and for communication between successive calls to `getopt'.
- X**
- X** On entry to `getopt', zero means this is the first call; initialize.
- X**
- X** When `getopt' returns EOF, this is the index of the first of the
- X** non-option elements that the caller should itself scan.
- X**
- X** Otherwise, `optind' communicates from one call to the next
- X** how much of ARGV has been scanned so far.
- X*/
- Xint optind = 0;
- X
- X/*
- X** nextchar -- the next char to be scanned in the option-element
- X** in which the last option character we returned was found.
- X** This allows us to pick up the scan where we left off.
- X**
- X** If this is zero, or a null string, it means resume the scan
- X** by advancing to the next ARGV-element.
- X*/
- Xstatic char *nextchar;
- X
- X/*
- X** opterr -- callers store zero here to inhibit the error message
- X** for unrecognized options.
- X*/
- Xint opterr = 1;
- X
- X/*
- X** optopt -- copy of option which was detected. It is the same as the
- X** function return value unless the function returns '?' (for an invalid
- X** option) when optopt contains the actual flag which caused the error.
- X** Added in conformity with UNIX System V Release 4.
- X*/
- Xint optopt;
- X
- X/*
- X** Describe how to deal with options that follow non-option ARGV-elements.
- X**
- X** UNSPECIFIED means the caller did not specify anything;
- X** the default is then REQUIRE_ORDER if the environment variable
- X** _POSIX_OPTION_ORDER is defined, PERMUTE otherwise.
- X**
- X** REQUIRE_ORDER means don't recognize them as options.
- X** Stop option processing when the first non-option is seen.
- X** This is what Unix does.
- X**
- X** PERMUTE is the default. We permute the contents of `argv' as we scan,
- X** so that eventually all the options are at the end. This allows options
- X** to be given in any order, even with programs that were not written to
- X** expect this.
- X**
- X** RETURN_IN_ORDER is an option available to programs that were written
- X** to expect options and other ARGV-elements in any order and that care about
- X** the ordering of the two. We describe each non-option ARGV-element
- X** as if it were the argument of an option with character code zero.
- X** Using `-' as the first character of the list of option characters
- X** requests this mode of operation.
- X**
- X** The special argument `--' forces an end of option-scanning regardless
- X** of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- X** `--' can cause `getopt' to return EOF with `optind' != ARGC.
- X*/
- Xstatic enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
- X
- X/* Handle permutation of arguments. */
- X
- X/*
- X** Describe the part of ARGV that contains non-options that have
- X** been skipped. `first_nonopt' is the index in ARGV of the first of them;
- X** `last_nonopt' is the index after the last of them.
- X*/
- Xstatic int first_nonopt;
- Xstatic int last_nonopt;
- X
- X/*
- X** Exchange two adjacent subsequences of ARGV.
- X** One subsequence is elements [first_nonopt,last_nonopt)
- X** which contains all the non-options that have been skipped so far.
- X** The other is elements [last_nonopt,optind), which contains all
- X** the options processed since those non-options were skipped.
- X** `first_nonopt' and `last_nonopt' are relocated so that they describe
- X** the new indices of the non-options in ARGV after they are moved.
- X*/
- X
- Xstatic void exchange(argv)
- Xchar **argv;
- X{
- X int nonopts_size = (last_nonopt - first_nonopt) * sizeof(char *);
- X char **temp;
- X
- X if ((temp = (char **)malloc(nonopts_size)) == (char **)0)
- X {
- X fprintf(stderr, "out of memory\n");
- X exit(1);
- X }
- X
- X /* Interchange the two blocks of data in argv. */
- X memmove(temp, &argv[first_nonopt], nonopts_size);
- X memmove(&argv[first_nonopt], &argv[last_nonopt],
- X (optind - last_nonopt) * sizeof(char *));
- X memmove(&argv[first_nonopt + optind - last_nonopt], temp, nonopts_size);
- X
- X free(temp);
- X
- X /* Update records for the slots the non-options now occupy. */
- X first_nonopt += (optind - last_nonopt);
- X last_nonopt = optind;
- X}
- X
- X/*
- X** Scan elements of ARGV (whose length is ARGC) for option characters
- X** given in OPTSTRING.
- X**
- X** If an element of ARGV starts with '-', and is not exactly "-" or "--",
- X** then it is an option element. The characters of this element
- X** (aside from the initial '-') are option characters. If `getopt'
- X** is called repeatedly, it returns successively each of the option characters
- X** from each of the option elements.
- X**
- X** If `getopt' finds another option character, it returns that character,
- X** updating `optind' and `nextchar' so that the next call to `getopt' can
- X** resume the scan with the following option character or ARGV-element.
- X**
- X** If there are no more option characters, `getopt' returns `EOF'.
- X** Then `optind' is the index in ARGV of the first ARGV-element
- X** that is not an option. (The ARGV-elements have been permuted
- X** so that those that are not options now come last.)
- X**
- X** OPTSTRING is a string containing the legitimate option characters.
- X** A colon in OPTSTRING means that the previous character is an option
- X** that wants an argument. The argument is taken from the rest of the
- X** current ARGV-element, or from the following ARGV-element,
- X** and returned in `optarg'.
- X**
- X** If an option character is seen that is not listed in OPTSTRING,
- X** return '?' after printing an error message. If you set `opterr' to
- X** zero, the error message is suppressed but we still return '?'.
- X**
- X** If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- X** so the following text in the same ARGV-element, or the text of the following
- X** ARGV-element, is returned in `optarg. Two colons mean an option that
- X** wants an optional arg; if there is text in the current ARGV-element,
- X** it is returned in `optarg'.
- X**
- X** If OPTSTRING starts with `-', it requests a different method of handling the
- X** non-option ARGV-elements. See the comments about RETURN_IN_ORDER, above.
- X*/
- X
- Xint getopt(argc, argv, optstring)
- Xint argc;
- Xchar **argv;
- Xchar *optstring;
- X{
- X
- X if (optind == 0)
- X {
- X /*
- X ** Initialize the internal data when the first call is made.
- X ** Start processing options with ARGV-element 1 (since ARGV-element 0
- X ** is the program name); the sequence of previously skipped
- X ** non-option ARGV-elements is empty.
- X */
- X first_nonopt = last_nonopt = optind = 1;
- X nextchar = 0;
- X
- X /* Determine how to handle the ordering of options and nonoptions. */
- X if (optstring[0] == '-')
- X ordering = RETURN_IN_ORDER;
- X else if (getenv("_POSIX_OPTION_ORDER") != 0)
- X ordering = REQUIRE_ORDER;
- X else
- X ordering = PERMUTE;
- X }
- X
- X if (nextchar == 0 || *nextchar == 0)
- X {
- X if (ordering == PERMUTE)
- X {
- X /*
- X ** If we have just processed some options following some
- X ** non-options, exchange them so that the options come first.
- X */
- X if (first_nonopt != last_nonopt && last_nonopt != optind)
- X exchange(argv);
- X else if (last_nonopt != optind)
- X first_nonopt = optind;
- X
- X /*
- X ** Now skip any additional non-options and extend
- X ** the range of non-options previously skipped.
- X */
- X while (optind < argc &&
- X (argv[optind][0] != '-' || argv[optind][1] == 0))
- X optind++;
- X last_nonopt = optind;
- X }
- X
- X /*
- X ** Special ARGV-element `--' means premature end of options.
- X ** Skip it like a null option, then exchange with previous
- X ** non-options as if it were an option, then skip everything else
- X ** like a non-option.
- X */
- X if (optind != argc && !strcmp(argv[optind], "--"))
- X {
- X optind++;
- X
- X if (first_nonopt != last_nonopt && last_nonopt != optind)
- X exchange(argv);
- X else if (first_nonopt == last_nonopt)
- X first_nonopt = optind;
- X last_nonopt = argc;
- X
- X optind = argc;
- X }
- X
- X /*
- X ** If we have done all the ARGV-elements, stop the scan
- X ** and back over any non-options that we skipped and permuted.
- X */
- X if (optind == argc)
- X {
- X /*
- X ** Set the next-arg-index to point at the non-options
- X ** that we previously skipped, so the caller will digest them.
- X */
- X if (first_nonopt != last_nonopt)
- X optind = first_nonopt;
- X return EOF;
- X }
- X
- X /*
- X ** If we have come to a non-option and did not permute it,
- X ** either stop the scan or describe it to the caller and pass it by.
- X */
- X if (argv[optind][0] != '-' || argv[optind][1] == 0)
- X {
- X if (ordering == REQUIRE_ORDER)
- X return EOF;
- X optarg = argv[optind++];
- X return 0;
- X }
- X
- X /*
- X ** We have found another option-ARGV-element.
- X ** Start decoding its characters.
- X */
- X nextchar = argv[optind] + 1;
- X }
- X
- X /* Look at and handle the next option-character. */
- X {
- X char c = *nextchar++;
- X char *temp = strchr(optstring, c);
- X
- X /* Set optopt */
- X optopt = c;
- X
- X /* Increment `optind' when we start to process its last character. */
- X if (*nextchar == 0)
- X optind++;
- X
- X if (temp == 0 || c == ':')
- X {
- X if (opterr != 0)
- X {
- X if (!isprint(c))
- X fprintf(stderr, "%s: unrecognized option, character code 0%o\n",
- X argv[0], c);
- X else
- X fprintf(stderr, "%s: unrecognized option `-%c'\n",
- X argv[0], c);
- X }
- X return '?';
- X }
- X if (temp[1] == ':')
- X {
- X if (temp[2] == ':')
- X {
- X /* This is an option that accepts an argument optionally. */
- X if (*nextchar != 0)
- X {
- X optarg = nextchar;
- X optind++;
- X }
- X else
- X optarg = 0;
- X nextchar = 0;
- X }
- X else
- X {
- X /* This is an option that requires an argument. */
- X if (*nextchar != 0)
- X {
- X optarg = nextchar;
- X /*
- X ** If we end this ARGV-element by taking the rest as
- X ** an arg, we must advance to the next element now.
- X */
- X optind++;
- X }
- X else if (optind == argc)
- X {
- X if (opterr != 0)
- X fprintf(stderr, "%s: no argument for `-%c' option\n",
- X argv[0], c);
- X c = '?';
- X }
- X else
- X {
- X /*
- X ** We already incremented `optind' once; increment it
- X ** again when taking next ARGV-elt as argument.
- X */
- X optarg = argv[optind++];
- X }
- X nextchar = 0;
- X }
- X }
- X return c;
- X }
- X}
- SHAR-EOF
- chmod 444 getopt.c
- if [ `wc -c <getopt.c` -ne 17640 ]
- then echo shar: getopt.c unpacked with wrong size
- fi
- # end of overwriting check
- fi
- #--------------------
- if [ -f getopt.h -a "$1" != "-c" ]
- then echo shar: getopt.h already exists
- else
- echo 'x - getopt.h (489 characters)'
- sed -e 's/^X//' >getopt.h <<'SHAR-EOF'
- X/*
- X@(#)File: getopt.h
- X@(#)Version: 1.1
- X@(#)Last changed: 92/03/23
- X@(#)Purpose: Definitions for GETOPT(3)
- X@(#)Author: J Leffler
- X@(#)Copyright: JLSS (C) 1992
- X*/
- X
- X#ifndef GETOPT_H
- X#define GETOPT_H
- X
- Xextern int optopt;
- Xextern int opterr;
- Xextern int optind;
- Xextern char *optarg;
- X
- X#ifdef __STDC__
- Xextern int getopt(int argc, char **argv, char *opts);
- X#else
- Xextern int getopt();
- X#endif /* __STDC__ */
- X
- X#endif /* GETOPT_H */
- SHAR-EOF
- chmod 444 getopt.h
- if [ `wc -c <getopt.h` -ne 489 ]
- then echo shar: getopt.h unpacked with wrong size
- fi
- # end of overwriting check
- fi
- #--------------------
- if [ -f stderr.c -a "$1" != "-c" ]
- then echo shar: stderr.c already exists
- else
- echo 'x - stderr.c (2995 characters)'
- sed -e 's/^X//' >stderr.c <<'SHAR-EOF'
- X/*
- X@(#)File: stderr.c
- X@(#)Version: 6.2
- X@(#)Last changed: 91/12/22
- X@(#)Purpose: Error reporting routines -- using stdio
- X@(#)Author: J Leffler
- X@(#)Copyright: (C) JLSS 1991
- X@(#)Product: :PRODUCT:
- X*/
- X
- X/*TABSTOP=4*/
- X/*LINTLIBRARY*/
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <stdlib.h>
- X
- X#include "stderr.h"
- X
- X#ifdef __STDC__
- X#include <stdarg.h>
- X#else
- X#include <varargs.h>
- X#endif /* __STDC__ */
- X
- X#define global /* Defined here -- accessible elsewhere */
- X#define NIL(x) ((x)0)
- X#define MAX_CLEANUPS 32 /* Same as Standard C for atexit */
- X
- Xstatic void (*cleanuplist[MAX_CLEANUPS])();
- Xstatic int n_cleanups = 0;
- Xstatic char _arg0[15] = "**undefined**"; /* Actual string */
- Xglobal char *arg0 = _arg0; /* Name of command */
- X
- X#ifndef lint
- Xstatic char sccs[] = "@(#)stderr.c 6.2 91/12/22";
- X#endif /* lint */
- X
- Xvoid err_setcleanup(p)
- Xvoid (*p)();
- X{
- X if (n_cleanups < MAX_CLEANUPS)
- X cleanuplist[n_cleanups++] = p;
- X}
- X
- Xvoid remark2(s1, s2)
- Xchar *s1; /* In: First error message string */
- Xchar *s2; /* In: Second error message string */
- X{
- X err_report(ERR_REM, ERR_STAT, "%s %s\n", (s1), (s2));
- X}
- X
- Xvoid remark(s1)
- Xchar *s1; /* In: Error message */
- X{
- X err_report(ERR_REM, ERR_STAT, "%s\n", (s1));
- X}
- X
- Xvoid error2(s1, s2)
- Xchar *s1; /* In: First error message string */
- Xchar *s2; /* In: Second error message string */
- X{
- X err_report(ERR_ERR, ERR_STAT, "%s %s\n", (s1), (s2));
- X}
- X
- Xvoid error(s1)
- Xchar *s1; /* In: Error message */
- X{
- X err_report(ERR_ERR, ERR_STAT, "%s\n", (s1));
- X}
- X
- Xvoid stop(s1)
- Xchar *s1; /* In: Error message */
- X{
- X err_report(ERR_ABT, ERR_STAT, "%s\n", (s1));
- X}
- X
- Xvoid usage(s1)
- Xchar *s1; /* In: Usage message */
- X{
- X err_report(ERR_USE, ERR_STAT, (s1));
- X}
- X
- Xvoid setarg0(s)
- Xchar *s; /* In: argv[0] */
- X{
- X char *cp;
- X
- X while ((cp = strrchr(s, '/')) != NIL(char *) &&*(cp + 1) == '\0')
- X *cp = '\0';
- X (void)strncpy(_arg0, ((cp == NIL(char *)) ? s : cp + 1), 14);
- X}
- X
- X/* VARARGS */
- X#ifdef __STDC__
- Xvoid err_report(int flags, int estat, char *string,...)
- X#else
- Xvoid err_report(va_alist)
- Xva_dcl
- X#endif /* __STDC__ */
- X{
- X int i;
- X va_list args;
- X
- X#ifndef __STDC__
- X int flags;
- X int estat;
- X char *string;
- X
- X va_start(args);
- X flags = va_arg(args, int);
- X estat = va_arg(args, int);
- X string = va_arg(args, char *);
- X#else
- X va_start(args, string);
- X#endif /* __STDC__ */
- X
- X if (flags & ERR_FLUSH)
- X (void)fflush(stdout);
- X if (flags & ERR_USAGE)
- X (void)fprintf(stderr, "Usage: %s %s\n", arg0, string);
- X else if (flags & ERR_COMM)
- X {
- X (void)fprintf(stderr, "%s: ", arg0);
- X (void)vfprintf(stderr, string, args);
- X }
- X if (flags & ERR_ABORT)
- X abort();
- X if (flags & ERR_EXIT)
- X {
- X for (i = 0; i < n_cleanups; i++)
- X (*cleanuplist[i])();
- X exit(estat);
- X }
- X}
- SHAR-EOF
- chmod 444 stderr.c
- if [ `wc -c <stderr.c` -ne 2995 ]
- then echo shar: stderr.c unpacked with wrong size
- fi
- # end of overwriting check
- fi
- #--------------------
- if [ -f stderr.h -a "$1" != "-c" ]
- then echo shar: stderr.h already exists
- else
- echo 'x - stderr.h (1591 characters)'
- sed -e 's/^X//' >stderr.h <<'SHAR-EOF'
- X/*
- X@(#)File: stderr.h
- X@(#)Version: 6.1
- X@(#)Last changed: 91/12/15
- X@(#)Purpose: Header file for standard error functions
- X@(#)Author: J Leffler
- X*/
- X
- X#ifndef STDERR_H
- X#define STDERR_H
- X
- X#ifdef MAIN_PROGRAM
- X#ifndef lint
- Xstatic char stderr_h[] = "@(#)stderr.h 6.1 91/12/15";
- X#endif
- X#endif
- X
- X/* -- Definitions for error handling */
- X
- X#define ERR_STAT (1) /* Default exit status */
- X
- X#define ERR_COMM (0x01) /* Print message on stderr */
- X#define ERR_USAGE (0x02) /* Print usage on stderr */
- X#define ERR_EXIT (0x04) /* Exit -- do not return */
- X#define ERR_ABORT (0x08) /* Abort -- do not return */
- X#define ERR_FLUSH (0x10) /* Flush stdout */
- X
- X/* -- Standard combinations of flags */
- X
- X#define ERR_USE (ERR_USAGE|ERR_EXIT|ERR_FLUSH)
- X#define ERR_REM (ERR_COMM|ERR_FLUSH)
- X#define ERR_ERR (ERR_COMM|ERR_EXIT|ERR_FLUSH)
- X#define ERR_ABT (ERR_COMM|ERR_ABORT|ERR_FLUSH)
- X
- X/* -- Global definitions */
- X
- Xextern char *arg0;
- X
- X#ifdef __STDC__
- X
- Xextern void err_report(int flags, int estat, char *string, ...);
- Xextern void err_setcleanup(void (*func)());
- Xextern void error(char *s1);
- Xextern void error2(char *s1, char *s2);
- Xextern void remark(char *s1);
- Xextern void remark2(char *s1, char *s2);
- Xextern void setarg0(char *arg0);
- Xextern void stop(char *s1);
- Xextern void usage(char *s1);
- X
- X#else
- X
- X/* VARARGS */
- Xextern void err_report();
- Xextern void err_setcleanup();
- Xextern void error();
- Xextern void error2();
- Xextern void remark();
- Xextern void remark2();
- Xextern void setarg0();
- Xextern void stop();
- Xextern void usage();
- X
- X#endif /* __STDC__ */
- X
- X#endif /* STDERR_H */
- SHAR-EOF
- chmod 444 stderr.h
- if [ `wc -c <stderr.h` -ne 1591 ]
- then echo shar: stderr.h unpacked with wrong size
- fi
- # end of overwriting check
- fi
- #--------------------
- if [ -f memmove.c -a "$1" != "-c" ]
- then echo shar: memmove.c already exists
- else
- echo 'x - memmove.c (1418 characters)'
- sed -e 's/^X//' >memmove.c <<'SHAR-EOF'
- X/*
- X@(#)File: memmove.c
- X@(#)Version: 1.2
- X@(#)Last changed: 91/12/22
- X@(#)Purpose: Simulate MEMMOVE(3)
- X@(#)Author: J Leffler
- X@(#)Copyright: (C) JLSS 1991
- X@(#)Product: :PRODUCT:
- X*/
- X
- X/*TABSTOP=4*/
- X/*LINTLIBRARY*/
- X
- X#ifndef lint
- Xstatic char sccs[] = "@(#)memmove.c 1.2 91/12/22";
- X#endif
- X
- Xvoid *memmove(s1, s2, n)
- Xvoid *s1;
- Xvoid *s2;
- Xint n;
- X{
- X char *t;
- X char *t1 = (char *)s1;
- X char *t2 = (char *)s2;
- X void *s = s1;
- X
- X if (t1 < t2)
- X { /* Copy forwards */
- X t = t1 + n;
- X while (t1 < t)
- X *t1++ = *t2++;
- X }
- X else
- X { /* Copy backwards */
- X t = t2;
- X t1 += n;
- X t2 += n;
- X while (t2 > t)
- X *--t1 = *--t2;
- X }
- X return(s);
- X}
- X
- X#ifdef TEST
- X
- Xmain()
- X{
- X char buffer[80];
- X int ok = 0;
- X
- X strcpy(&buffer[0], "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
- X printf("buffer = %s\n", buffer);
- X printf("memmove(&buffer[0], &buffer[9], 10);\n");
- X memmove(&buffer[0], &buffer[9], 10);
- X printf("buffer = %s\n", buffer);
- X if (strcmp(buffer, "JKLMNOPQRSKLMNOPQRSTUVWXYZ") != 0)
- X ok++, printf("** FAILED **\n");
- X printf("memmove(&buffer[5], &buffer[0], 10);\n");
- X memmove(&buffer[5], &buffer[0], 10);
- X printf("buffer = %s\n", buffer);
- X if (strcmp(buffer, "JKLMNJKLMNOPQRSPQRSTUVWXYZ") != 0)
- X ok++, printf("** FAILED **\n");
- X
- X if (ok == 0)
- X printf("OK\n");
- X return(0);
- X}
- X
- X#endif /* TEST */
- SHAR-EOF
- chmod 444 memmove.c
- if [ `wc -c <memmove.c` -ne 1418 ]
- then echo shar: memmove.c unpacked with wrong size
- fi
- # end of overwriting check
- fi
- echo All files extracted
- exit 0
-