Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleaddcom.c
Go to the documentation of this file.
1 /*
2  * This software is copyrighted as noted below. It may be freely copied,
3  * modified, and redistributed, provided that the copyright notice is
4  * preserved on all copies.
5  *
6  * There is no warranty or other guarantee of fitness for this software,
7  * it is provided solely "as is". Bug reports or fixes may be sent
8  * to the author, who may or may not act on them as he desires.
9  *
10  * You may not include this software in a program or other software product
11  * without supplying the source, or without informing the end-user that the
12  * source is available for no extra charge.
13  *
14  * If you modify this software, you should include a notice giving the
15  * name of the person performing the modification, the date of modification,
16  * and the reason for such modification.
17  */
18 /*
19  * rle_addcom.c - Add comment[s] to an RLE file.
20  *
21  * Author: Spencer W. Thomas
22  * Computer Science Dept.
23  * University of Utah
24  * Date: Sun Jan 25 1987
25  * Copyright (c) 1987, University of Utah
26  */
27 
28 #include "rle.h"
29 #ifndef _XOPEN_SOURCE
30 #define _XOPEN_SOURCE /* For mkstemp */
31 #endif /* !_XOPEN_SOURCE */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <sys/types.h>
38 #include <sys/param.h> /* for MAXPATHLEN */
39 #include <sys/stat.h>
40 
41 #ifndef MAXPATHLEN
42 # define MAXPATHLEN BUFSIZ
43 #endif
44 
45 static char temp[] = "rleaddcomXXXXXX";
46 static char buf[MAXPATHLEN+1];
47 
48 #include <string.h>
49 
50 /*****************************************************************
51  * TAG( main )
52  *
53  * Add one or more comments to an RLE file.
54  *
55  * Usage:
56  * rle_addcom [-d] [-i] [-o outfile] infile comments ...
57  * Inputs:
58  * -d: Delete matching comments instead of adding any.
59  * -i: Do it "in place" -- replace the input file.
60  * outfile: Modified file with comments (defaults to stdout).
61  * infile: File to add comments to.
62  * comments: One or more strings. Each will be inserted as
63  * a separate comment. They will usually be of the
64  * form "name=value".
65  * Outputs:
66  * Writes modified RLE file to standard output.
67  * Assumptions:
68  * [None]
69  * Algorithm:
70  * [None]
71  */
72 void
74 int argc;
75 char **argv;
76 {
77  rle_hdr in_hdr, out_hdr;
78  char * fname = NULL, * out_fname = NULL;
79  char *i_fname = NULL;
80  FILE *outfile = stdout;
81  char ** comments = NULL;
82  char *my_name = cmd_name( argv );
83  int oflag = 0, iflag = 0, delflag = 0, ncomment = 0;
84  int is_pipe = 0;
85  register int j;
86  int rle_cnt, rle_err;
87 
88  in_hdr = *rle_hdr_init( NULL );
89  out_hdr = *rle_hdr_init( NULL );
90 
91  if ( scanargs( argc, argv, "% d%- i%- o%-outfile!s infile!s comments!*s",
92  &delflag, &iflag, &oflag, &out_fname, &fname,
93  &ncomment, &comments ) == 0 )
94  exit( 1 );
95 
96  if ( iflag )
97  {
98  register char *cp;
99 
100  if ( oflag )
101  i_fname = out_fname;
102  else
103  i_fname = fname;
104 
105  /* Recognize rle_open_f special cases. */
106  if ( strcmp( i_fname, "-" ) == 0 )
107  {
108  fprintf( stderr,
109  "%s: Can't add comments \"in place\" to standard %s.\n",
110  my_name, oflag ? "output" : "input" );
111  exit( 1 );
112  }
113 #ifndef NO_OPEN_PIPES
114  if ( *i_fname == '|' )
115  {
116  fprintf( stderr,
117  "%s: Can't add comments \"in place\" to piped %s.\n",
118  my_name, oflag ? "output" : "input" );
119  exit( 1 );
120  }
121 #endif
122  strcpy( buf, i_fname );
123  if ( (cp = rindex( buf, '/' )) != NULL )
124  {
125  *++cp = 0;
126  strcat( buf, temp );
127  }
128  else
129  strcpy( buf, temp );
130  mkstemp( buf );
131 
132 #ifndef NO_OPEN_PIPES
133  /* Compressed file special case. */
134  cp = i_fname + strlen( i_fname ) - 2;
135  if ( cp > i_fname && *cp == '.' && *(cp + 1) == 'Z' )
136  {
137  strcat( buf, ".Z" );
138  is_pipe = 1;
139  }
140 #endif
141  out_fname = buf;
142  }
143 
144  in_hdr.rle_file = rle_open_f(my_name, fname, "r");
145  rle_names( &in_hdr, my_name, fname, 0 );
146  rle_names( &out_hdr, out_hdr.cmd, out_fname, 0 );
147 
148  /* Read in header */
149  for ( rle_cnt = 0;
150  (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
151  rle_cnt++ )
152  {
153  (void)rle_hdr_cp( &in_hdr, &out_hdr );
154  if ( rle_cnt == 0 )
155  outfile = rle_open_f( my_name, out_fname, "w" );
156  out_hdr.rle_file = outfile;
157 
158  /* Copy input to the_hdr struct */
159  for ( j = 0; j < ncomment; j++ )
160  {
161  if ( ! delflag )
162  rle_putcom( comments[j], &out_hdr );
163  else
164  rle_delcom( comments[j], &out_hdr );
165  }
166 
167  /* Start output file */
168  rle_put_setup( &out_hdr );
169 
170  /* Copy rest of input to output */
171  rle_cp( &in_hdr, &out_hdr );
172  }
173  /* Check for an error. EOF or EMPTY is ok if at least one image
174  * has been read. Otherwise, print an error message.
175  */
176  if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
177  {
178  rle_get_error( rle_err, my_name, fname );
179  rle_err = 1;
180  }
181  else
182  rle_err = 0;
183 
184  if ( iflag )
185  {
186  if ( rle_err )
187  fprintf( stderr, "%s: %s not replaced\n",
188  my_name, i_fname );
189  else
190  {
191 #ifndef NO_OPEN_PIPES
192  /* Have to call pclose, else file may not exist yet! */
193  if ( is_pipe )
194  pclose( outfile );
195  else
196 #endif
197  fclose( outfile );
198  if ( rename( buf, i_fname ) < 0 )
199  {
200  fprintf( stderr, "%s: rename failed: ", my_name );
201  perror( "" );
202  unlink( buf ); /* Get rid of temp file. */
203  }
204  }
205  }
206 
207  exit( 0 );
208 }
209 
210 #ifdef NEED_RENAME
211 rename( file1, file2 )
212 char *file1, *file2;
213 {
214  struct stat st;
215 
216  if ( stat(file2, &st) >= 0 && unlink(file2) < 0 )
217  return -1;
218  if ( link(file1, file2) < 0 )
219  return -1;
220  return unlink( file1 );
221 }
222 #endif
FILE * rle_open_f(char *prog_name, char *file_name, char *mode)
Definition: rle_open_f.c:216
rle_hdr * rle_hdr_cp(rle_hdr *from_hdr, rle_hdr *to_hdr)
Definition: rle_hdr.c:119
void rle_cp(rle_hdr *in_hdr, rle_hdr *the_hdr)
Definition: rle_cp.c:69
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
#define RLE_EMPTY
Definition: rle.h:73
char * cmd_name(char **argv)
Definition: cmd_name.c:31
void main(int argc, char **argv)
Definition: aliastorle.c:121
int rle_get_setup(rle_hdr *the_hdr)
Definition: rle_getrow.c:74
#define rindex
Definition: rle_config.h:97
static char temp[]
Definition: rleaddcom.c:45
#define RLE_SUCCESS
Definition: rle.h:70
int rle_get_error(int code, const char *pgmname, const char *fname)
Definition: rle_error.c:76
int scanargs(int argc, char **argv, const char *format,...)
Definition: scanargs.c:94
const char * cmd
Definition: rle.h:133
const char * rle_delcom(char *name, the_hdr) const
Definition: rle_putcom.c:140
#define RLE_EOF
Definition: rle.h:74
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
const char * rle_putcom(char *value, rle_hdr *the_hdr) const
Definition: rle_putcom.c:82
static char buf[4096 +1]
Definition: rleaddcom.c:46
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
FILE * rle_file
Definition: rle.h:114