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 28const char uupick_rcsid[] = "$Id: uupick.c,v 1.19 2002/03/05 19:10:42 ian Rel $"; 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 41static void upmovedir P((const char *zfull, const char *zrelative, 42 pointer pinfo)); 43static void upmove P((const char *zfrom, const char *zto)); 44 45/* Long getopt options. */ 46static 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 58static void upusage P((void)); 59static void uphelp P((void)); 60 61int 62main (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 if (argc < 1) 82 upusage (); 83 84 while ((iopt = getopt_long (argc, argv, "I:s:vx:", asPlongopts, 85 (int *) NULL)) != EOF) 86 { 87 switch (iopt) 88 { 89 case 's': 90 /* System name to get files from. */ 91 zsystem = optarg; 92 break; 93 94 case 'I': 95 /* Name configuration file. */ 96 if (fsysdep_other_config (optarg)) 97 zconfig = optarg; 98 break; 99 100 case 'x': 101#if DEBUG > 1 102 /* Set debugging level. */ 103 iDebug |= idebug_parse (optarg); 104#endif 105 break; 106 107 case 'v': 108 /* Print version and exit. */ 109 printf ("uupick (Taylor UUCP) %s\n", VERSION); 110 printf ("Copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor\n"); 111 printf ("This program is free software; you may redistribute it under the terms of\n"); 112 printf ("the GNU General Public LIcense. This program has ABSOLUTELY NO WARRANTY.\n"); 113 exit (EXIT_SUCCESS); 114 /*NOTREACHED*/ 115 116 case 1: 117 /* --help. */ 118 uphelp (); 119 exit (EXIT_SUCCESS); 120 /*NOTREACHED*/ 121 122 case 0: 123 /* Long option found and flag set. */ 124 break; 125 126 default: 127 upusage (); 128 /*NOTREACHED*/ 129 } 130 } 131 132 if (argc != optind) 133 upusage (); 134 135 iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig); 136 if (iuuconf != UUCONF_SUCCESS) 137 ulog_uuconf (LOG_FATAL, puuconf, iuuconf); 138 139 usysdep_initialize (puuconf, INIT_GETCWD | INIT_NOCHDIR); 140 141 zpubdir = NULL; 142 if (zsystem != NULL) 143 { 144 struct uuconf_system ssys; 145 146 /* Get the public directory for the system. If we can't find 147 the system information, just use the standard public 148 directory, since uupick is not setuid. */ 149 iuuconf = uuconf_system_info (puuconf, zsystem, &ssys); 150 if (iuuconf == UUCONF_SUCCESS) 151 { 152 zpubdir = zbufcpy (ssys.uuconf_zpubdir); 153 (void) uuconf_system_free (puuconf, &ssys); 154 } 155 } 156 if (zpubdir == NULL) 157 { 158 iuuconf = uuconf_pubdir (puuconf, &zpubdir); 159 if (iuuconf != UUCONF_SUCCESS) 160 ulog_uuconf (LOG_FATAL, puuconf, iuuconf); 161 } 162 163 if (! fsysdep_uupick_init (zsystem, zpubdir)) 164 usysdep_exit (FALSE); 165 166 zallsys = NULL; 167 fquit = FALSE; 168 169 while (! fquit 170 && ((zfile = zsysdep_uupick (zsystem, zpubdir, &zfrom, &zfull)) 171 != NULL)) 172 { 173 boolean fdir; 174 char *zto, *zlocal; 175 FILE *e; 176 boolean fcontinue; 177 178 fdir = fsysdep_directory (zfull); 179 180 do 181 { 182 boolean fbadname; 183 184 fcontinue = FALSE; 185 186 if (zallsys == NULL 187 || strcmp (zallsys, zfrom) != 0) 188 { 189 if (zallsys != NULL) 190 { 191 ubuffree (zallsys); 192 zallsys = NULL; 193 } 194 195 printf ("from %s: %s %s ?\n", zfrom, fdir ? "dir" : "file", 196 zfile); 197 198 if (fgets (ab, sizeof ab, stdin) == NULL) 199 break; 200 } 201 202 if (ab[0] == 'q') 203 { 204 fquit = TRUE; 205 break; 206 } 207 208 switch (ab[0]) 209 { 210 case '\n': 211 break; 212 213 case 'd': 214 if (fdir) 215 (void) fsysdep_rmdir (zfull); 216 else 217 { 218 if (remove (zfull) != 0) 219 ulog (LOG_ERROR, "remove (%s): %s", zfull, 220 strerror(errno)); 221 } 222 break; 223 224 case 'm': 225 case 'a': 226 zto = ab + 1 + strspn (ab + 1, " \t"); 227 zto[strcspn (zto, " \t\n")] = '\0'; 228 zlocal = zsysdep_uupick_local_file (zto, &fbadname); 229 if (zlocal == NULL) 230 { 231 if (! fbadname) 232 usysdep_exit (FALSE); 233 ulog (LOG_ERROR, "%s: bad local file name", zto); 234 fcontinue = TRUE; 235 break; 236 } 237 zto = zsysdep_in_dir (zlocal, zfile); 238 ubuffree (zlocal); 239 if (zto == NULL) 240 usysdep_exit (FALSE); 241 if (! fdir) 242 upmove (zfull, zto); 243 else 244 { 245 usysdep_walk_tree (zfull, upmovedir, (pointer) zto); 246 (void) fsysdep_rmdir (zfull); 247 } 248 ubuffree (zto); 249 250 if (ab[0] == 'a') 251 { 252 zallsys = zbufcpy (zfrom); 253 ab[0] = 'm'; 254 } 255 256 break; 257 258 case 'p': 259 if (fdir) 260 ulog (LOG_ERROR, "Can't print directory"); 261 else 262 { 263 e = fopen (zfull, "r"); 264 if (e == NULL) 265 ulog (LOG_ERROR, "fopen (%s): %s", zfull, 266 strerror (errno)); 267 else 268 { 269 while (fgets (ab, sizeof ab, e) != NULL) 270 (void) fputs (ab, stdout); 271 (void) fclose (e); 272 } 273 } 274 fcontinue = TRUE; 275 break; 276 277 case '!': 278 (void) system (ab + 1); 279 fcontinue = TRUE; 280 break; 281 282 default: 283 printf ("uupick commands:\n"); 284 printf ("q: quit\n"); 285 printf ("<return>: skip file\n"); 286 printf ("m [dir]: move file to directory\n"); 287 printf ("a [dir]: move all files from this system to directory\n"); 288 printf ("p: list file to stdout\n"); 289 printf ("d: delete file\n"); 290 printf ("! command: shell escape\n"); 291 fcontinue = TRUE; 292 break; 293 } 294 } 295 while (fcontinue); 296 297 ubuffree (zfull); 298 ubuffree (zfrom); 299 ubuffree (zfile); 300 } 301 302 (void) fsysdep_uupick_free (zsystem, zpubdir); 303 304 usysdep_exit (TRUE); 305 306 /* Avoid error about not returning. */ 307 return 0; 308} 309 310/* Print usage message and die. */ 311 312static void 313upusage () 314{ 315 fprintf (stderr, 316 "Usage: %s [-s system] [-I config] [-x debug]\n", zProgram); 317 fprintf (stderr, "Use %s --help for help\n", zProgram); 318 exit (EXIT_FAILURE); 319} 320 321/* Print help message. */ 322 323static void 324uphelp () 325{ 326 printf ("Taylor UUCP %s, copyright (C) 1991, 92, 93, 94, 1995, 2002 Ian Lance Taylor\n", 327 VERSION); 328 printf (" -s,--system system: Only consider files from named system\n"); 329 printf (" -x,--debug debug: Set debugging level\n"); 330#if HAVE_TAYLOR_CONFIG 331 printf (" -I,--config file: Set configuration file to use\n"); 332#endif /* HAVE_TAYLOR_CONFIG */ 333 printf (" -v,--version: Print version and exit\n"); 334 printf (" --help: Print help and exit\n"); 335 printf ("Report bugs to taylor-uucp@gnu.org\n"); 336} 337 338/* This routine is called by usysdep_walk_tree when moving the 339 contents of an entire directory. */ 340 341static void 342upmovedir (zfull, zrelative, pinfo) 343 const char *zfull; 344 const char *zrelative; 345 pointer pinfo; 346{ 347 const char *ztodir = (const char *) pinfo; 348 char *zto; 349 350 zto = zsysdep_in_dir (ztodir, zrelative); 351 if (zto == NULL) 352 usysdep_exit (FALSE); 353 upmove (zfull, zto); 354 ubuffree (zto); 355} 356 357/* Move a file. */ 358 359static void 360upmove (zfrom, zto) 361 const char *zfrom; 362 const char *zto; 363{ 364 (void) fsysdep_move_file (zfrom, zto, TRUE, TRUE, FALSE, 365 (const char *) NULL); 366} 367