1 /* uupick.c
2    Get files stored in the public directory by uucp -t.
3 
4    Copyright (C) 1992, 1993, 1994, 1995, 2002 Ian Lance Taylor
5 
6    This file is part of the Taylor UUCP package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21 
22    The author of the program may be contacted at ian@airs.com.
23    */
24 
25 #include "uucp.h"
26 
27 #if USE_RCS_ID
28 const char uupick_rcsid[] = "$FreeBSD$";
29 #endif
30 
31 #include <errno.h>
32 
33 #include "getopt.h"
34 
35 #include "uudefs.h"
36 #include "uuconf.h"
37 #include "system.h"
38 
39 /* Local functions.  */
40 
41 static void upmovedir P((const char *zfull, const char *zrelative,
42 			 pointer pinfo));
43 static void upmove P((const char *zfrom, const char *zto));
44 
45 /* Long getopt options.  */
46 static const struct option asPlongopts[] =
47 {
48   { "system", required_argument, NULL, 's' },
49   { "config", required_argument, NULL, 'I' },
50   { "debug", required_argument, NULL, 'x' },
51   { "version", no_argument, NULL, 'v' },
52   { "help", no_argument, NULL, 1 },
53   { NULL, 0, NULL, 0 }
54 };
55 
56 /* Local functions.  */
57 
58 static void upusage P((void));
59 static void uphelp P((void));
60 
61 int
main(argc,argv)62 main (argc, argv)
63      int argc;
64      char **argv;
65 {
66   /* -s: system name.  */
67   const char *zsystem = NULL;
68   /* -I: configuration file name.  */
69   const char *zconfig = NULL;
70   int iopt;
71   pointer puuconf;
72   int iuuconf;
73   const char *zpubdir;
74   char *zfile, *zfrom, *zfull;
75   char *zallsys;
76   char ab[1000];
77   boolean fquit;
78 
79   zProgram = "uupick";
80 
81   while ((iopt = getopt_long (argc, argv, "I:s:vx:", asPlongopts,
82 			      (int *) NULL)) != EOF)
83     {
84       switch (iopt)
85 	{
86 	case 's':
87 	  /* System name to get files from.  */
88 	  zsystem = optarg;
89 	  break;
90 
91 	case 'I':
92 	  /* Name configuration file.  */
93 	  if (fsysdep_other_config (optarg))
94 	    zconfig = optarg;
95 	  break;
96 
97 	case 'x':
98 #if DEBUG > 1
99 	  /* Set debugging level.  */
100 	  iDebug |= idebug_parse (optarg);
101 #endif
102 	  break;
103 
104 	case 'v':
105 	  /* Print version and exit.  */
106 	  printf ("uupick (Taylor UUCP) %s\n", VERSION);
107 	  printf ("Copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor\n");
108 	  printf ("This program is free software; you may redistribute it under the terms of\n");
109 	  printf ("the GNU General Public LIcense.  This program has ABSOLUTELY NO WARRANTY.\n");
110 	  exit (EXIT_SUCCESS);
111 	  /*NOTREACHED*/
112 
113 	case 1:
114 	  /* --help.  */
115 	  uphelp ();
116 	  exit (EXIT_SUCCESS);
117 	  /*NOTREACHED*/
118 
119 	case 0:
120 	  /* Long option found and flag set.  */
121 	  break;
122 
123 	default:
124 	  upusage ();
125 	  /*NOTREACHED*/
126 	}
127     }
128 
129   if (argc != optind)
130     upusage ();
131 
132   iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig);
133   if (iuuconf != UUCONF_SUCCESS)
134     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
135 
136   usysdep_initialize (puuconf, INIT_GETCWD | INIT_NOCHDIR);
137 
138   zpubdir = NULL;
139   if (zsystem != NULL)
140     {
141       struct uuconf_system ssys;
142 
143       /* Get the public directory for the system.  If we can't find
144          the system information, just use the standard public
145          directory, since uupick is not setuid.  */
146       iuuconf = uuconf_system_info (puuconf, zsystem, &ssys);
147       if (iuuconf == UUCONF_SUCCESS)
148 	{
149 	  zpubdir = zbufcpy (ssys.uuconf_zpubdir);
150 	  (void) uuconf_system_free (puuconf, &ssys);
151 	}
152     }
153   if (zpubdir == NULL)
154     {
155       iuuconf = uuconf_pubdir (puuconf, &zpubdir);
156       if (iuuconf != UUCONF_SUCCESS)
157 	ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
158     }
159 
160   if (! fsysdep_uupick_init (zsystem, zpubdir))
161     usysdep_exit (FALSE);
162 
163   zallsys = NULL;
164   fquit = FALSE;
165 
166   while (! fquit
167 	 && ((zfile = zsysdep_uupick (zsystem, zpubdir, &zfrom, &zfull))
168 	     != NULL))
169     {
170       boolean fdir;
171       char *zto, *zlocal;
172       FILE *e;
173       boolean fcontinue;
174 
175       fdir = fsysdep_directory (zfull);
176 
177       do
178 	{
179 	  boolean fbadname;
180 
181 	  fcontinue = FALSE;
182 
183 	  if (zallsys == NULL
184 	      || strcmp (zallsys, zfrom) != 0)
185 	    {
186 	      if (zallsys != NULL)
187 		{
188 		  ubuffree (zallsys);
189 		  zallsys = NULL;
190 		}
191 
192 	      printf ("from %s: %s %s ?\n", zfrom, fdir ? "dir" : "file",
193 		      zfile);
194 
195 	      if (fgets (ab, sizeof ab, stdin) == NULL)
196 		break;
197 	    }
198 
199 	  if (ab[0] == 'q')
200 	    {
201 	      fquit = TRUE;
202 	      break;
203 	    }
204 
205 	  switch (ab[0])
206 	    {
207 	    case '\n':
208 	      break;
209 
210 	    case 'd':
211 	      if (fdir)
212 		(void) fsysdep_rmdir (zfull);
213 	      else
214 		{
215 		  if (remove (zfull) != 0)
216 		    ulog (LOG_ERROR, "remove (%s): %s", zfull,
217 			  strerror(errno));
218 		}
219 	      break;
220 
221 	    case 'm':
222 	    case 'a':
223 	      zto = ab + 1 + strspn (ab + 1, " \t");
224 	      zto[strcspn (zto, " \t\n")] = '\0';
225 	      zlocal = zsysdep_uupick_local_file (zto, &fbadname);
226 	      if (zlocal == NULL)
227 		{
228 		  if (! fbadname)
229 		    usysdep_exit (FALSE);
230 		  ulog (LOG_ERROR, "%s: bad local file name", zto);
231 		  fcontinue = TRUE;
232 		  break;
233 		}
234 	      zto = zsysdep_in_dir (zlocal, zfile);
235 	      ubuffree (zlocal);
236 	      if (zto == NULL)
237 		usysdep_exit (FALSE);
238 	      if (! fdir)
239 		upmove (zfull, zto);
240 	      else
241 		{
242 		  usysdep_walk_tree (zfull, upmovedir, (pointer) zto);
243 		  (void) fsysdep_rmdir (zfull);
244 		}
245 	      ubuffree (zto);
246 
247 	      if (ab[0] == 'a')
248 		{
249 		  zallsys = zbufcpy (zfrom);
250 		  ab[0] = 'm';
251 		}
252 
253 	      break;
254 
255 	    case 'p':
256 	      if (fdir)
257 		ulog (LOG_ERROR, "Can't print directory");
258 	      else
259 		{
260 		  e = fopen (zfull, "r");
261 		  if (e == NULL)
262 		    ulog (LOG_ERROR, "fopen (%s): %s", zfull,
263 			  strerror (errno));
264 		  else
265 		    {
266 		      while (fgets (ab, sizeof ab, e) != NULL)
267 			(void) fputs (ab, stdout);
268 		      (void) fclose (e);
269 		    }
270 		}
271 	      fcontinue = TRUE;
272 	      break;
273 
274 	    case '!':
275 	      (void) system (ab + 1);
276 	      fcontinue = TRUE;
277 	      break;
278 
279 	    default:
280 	      printf ("uupick commands:\n");
281 	      printf ("q: quit\n");
282 	      printf ("<return>: skip file\n");
283 	      printf ("m [dir]: move file to directory\n");
284 	      printf ("a [dir]: move all files from this system to directory\n");
285 	      printf ("p: list file to stdout\n");
286 	      printf ("d: delete file\n");
287 	      printf ("! command: shell escape\n");
288 	      fcontinue = TRUE;
289 	      break;
290 	    }
291 	}
292       while (fcontinue);
293 
294       ubuffree (zfull);
295       ubuffree (zfrom);
296       ubuffree (zfile);
297     }
298 
299   (void) fsysdep_uupick_free (zsystem, zpubdir);
300 
301   usysdep_exit (TRUE);
302 
303   /* Avoid error about not returning.  */
304   return 0;
305 }
306 
307 /* Print usage message and die.  */
308 
309 static void
upusage()310 upusage ()
311 {
312   fprintf (stderr,
313 	   "Usage: %s [-s system] [-I config] [-x debug]\n", zProgram);
314   fprintf (stderr, "Use %s --help for help\n", zProgram);
315   exit (EXIT_FAILURE);
316 }
317 
318 /* Print help message.  */
319 
320 static void
uphelp()321 uphelp ()
322 {
323   printf ("Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor\n",
324 	  VERSION);
325   printf (" -s,--system system: Only consider files from named system\n");
326   printf (" -x,--debug debug: Set debugging level\n");
327 #if HAVE_TAYLOR_CONFIG
328   printf (" -I,--config file: Set configuration file to use\n");
329 #endif /* HAVE_TAYLOR_CONFIG */
330   printf (" -v,--version: Print version and exit\n");
331   printf (" --help: Print help and exit\n");
332   printf ("Report bugs to taylor-uucp@gnu.org\n");
333 }
334 
335 /* This routine is called by usysdep_walk_tree when moving the
336    contents of an entire directory.  */
337 
338 static void
upmovedir(zfull,zrelative,pinfo)339 upmovedir (zfull, zrelative, pinfo)
340      const char *zfull;
341      const char *zrelative;
342      pointer pinfo;
343 {
344   const char *ztodir = (const char *) pinfo;
345   char *zto;
346 
347   zto = zsysdep_in_dir (ztodir, zrelative);
348   if (zto == NULL)
349     usysdep_exit (FALSE);
350   upmove (zfull, zto);
351   ubuffree (zto);
352 }
353 
354 /* Move a file.  */
355 
356 static void
upmove(zfrom,zto)357 upmove (zfrom, zto)
358      const char *zfrom;
359      const char *zto;
360 {
361   (void) fsysdep_move_file (zfrom, zto, TRUE, TRUE, FALSE,
362 			    (const char *) NULL);
363 }
364