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