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 <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include "rle.h"
32 #include <sys/types.h>
33 #include <sys/param.h> /* for MAXPATHLEN */
34 #include <sys/stat.h>
35
36 #ifndef MAXPATHLEN
37 # define MAXPATHLEN BUFSIZ
38 #endif
39
40 static char temp[] = "intoXXXXXXXX";
41 static char buf[MAXPATHLEN+1];
42
43 /*****************************************************************
44 * TAG( main )
45 *
46 * Add one or more comments to an RLE file.
47 *
48 * Usage:
49 * rle_addcom [-d] [-i] [-o outfile] infile comments ...
50 * Inputs:
51 * -d: Delete matching comments instead of adding any.
52 * -i: Do it "in place" -- replace the input file.
53 * outfile: Modified file with comments (defaults to stdout).
54 * infile: File to add comments to.
55 * comments: One or more strings. Each will be inserted as
56 * a separate comment. They will usually be of the
57 * form "name=value".
58 * Outputs:
59 * Writes modified RLE file to standard output.
60 * Assumptions:
61 * [None]
62 * Algorithm:
63 * [None]
64 */
65 int
main(argc,argv)66 main( argc, argv )
67 int argc;
68 char **argv;
69 {
70 rle_hdr in_hdr, out_hdr;
71 char * fname = NULL, * out_fname = NULL;
72 char *i_fname = NULL;
73 FILE *outfile = stdout;
74 char ** comments = NULL;
75 char *my_name = cmd_name( argv );
76 int oflag = 0, iflag = 0, delflag = 0, ncomment = 0;
77 int is_pipe = 0;
78 register int j;
79 int rle_cnt, rle_err;
80
81 in_hdr = *rle_hdr_init( NULL );
82 out_hdr = *rle_hdr_init( NULL );
83
84 if ( scanargs( argc, argv, "% d%- i%- o%-outfile!s infile!s comments!*s",
85 &delflag, &iflag, &oflag, &out_fname, &fname,
86 &ncomment, &comments ) == 0 )
87 exit( 1 );
88
89 if ( iflag )
90 {
91 register char *cp;
92
93 if ( oflag )
94 i_fname = out_fname;
95 else
96 i_fname = fname;
97
98 /* Recognize rle_open_f special cases. */
99 if ( strcmp( i_fname, "-" ) == 0 )
100 {
101 fprintf( stderr,
102 "%s: Can't add comments \"in place\" to standard %s.\n",
103 my_name, oflag ? "output" : "input" );
104 exit( 1 );
105 }
106 #ifndef NO_OPEN_PIPES
107 if ( *i_fname == '|' )
108 {
109 fprintf( stderr,
110 "%s: Can't add comments \"in place\" to piped %s.\n",
111 my_name, oflag ? "output" : "input" );
112 exit( 1 );
113 }
114 #endif
115 strcpy( buf, i_fname );
116 if ( (cp = rindex( buf, '/' )) != NULL )
117 {
118 *++cp = 0;
119 strcat( buf, temp );
120 }
121 else
122 strcpy( buf, temp );
123 mkstemp( buf );
124 #ifndef NO_OPEN_PIPES
125 /* Compressed file special case. */
126 cp = i_fname + strlen( i_fname ) - 2;
127 if ( cp > i_fname && *cp == '.' && *(cp + 1) == 'Z' )
128 {
129 strcat( buf, ".Z" );
130 is_pipe = 1;
131 }
132 #endif
133 out_fname = buf;
134 }
135
136 in_hdr.rle_file = rle_open_f(my_name, fname, "r");
137 rle_names( &in_hdr, my_name, fname, 0 );
138 rle_names( &out_hdr, out_hdr.cmd, out_fname, 0 );
139
140 /* Read in header */
141 for ( rle_cnt = 0;
142 (rle_err = rle_get_setup( &in_hdr )) == RLE_SUCCESS;
143 rle_cnt++ )
144 {
145 (void)rle_hdr_cp( &in_hdr, &out_hdr );
146 if ( rle_cnt == 0 )
147 outfile = rle_open_f( my_name, out_fname, "w" );
148 out_hdr.rle_file = outfile;
149
150 /* Copy input to the_hdr struct */
151 for ( j = 0; j < ncomment; j++ )
152 {
153 if ( ! delflag )
154 rle_putcom( comments[j], &out_hdr );
155 else
156 rle_delcom( comments[j], &out_hdr );
157 }
158
159 /* Start output file */
160 rle_put_setup( &out_hdr );
161
162 /* Copy rest of input to output */
163 rle_cp( &in_hdr, &out_hdr );
164 }
165 /* Check for an error. EOF or EMPTY is ok if at least one image
166 * has been read. Otherwise, print an error message.
167 */
168 if ( rle_cnt == 0 || (rle_err != RLE_EOF && rle_err != RLE_EMPTY) )
169 {
170 rle_get_error( rle_err, my_name, fname );
171 rle_err = 1;
172 }
173 else
174 rle_err = 0;
175
176 if ( iflag )
177 {
178 if ( rle_err )
179 fprintf( stderr, "%s: %s not replaced\n",
180 my_name, i_fname );
181 else
182 {
183 #ifndef NO_OPEN_PIPES
184 /* Have to call pclose, else file may not exist yet! */
185 if ( is_pipe )
186 pclose( outfile );
187 else
188 #endif
189 fclose( outfile );
190 if ( rename( buf, i_fname ) < 0 )
191 {
192 fprintf( stderr, "%s: rename failed: ", my_name );
193 perror( "" );
194 unlink( buf ); /* Get rid of temp file. */
195 }
196 }
197 }
198
199 exit( 0 );
200 }
201
202 #ifdef NEED_RENAME
rename(file1,file2)203 rename( file1, file2 )
204 char *file1, *file2;
205 {
206 struct stat st;
207
208 if ( stat(file2, &st) >= 0 && unlink(file2) < 0 )
209 return -1;
210 if ( link(file1, file2) < 0 )
211 return -1;
212 return unlink( file1 );
213 }
214 #endif
215