|
|
1.1 ! root 1: /* xcmd.c ! 2: Routines to handle work requests. ! 3: ! 4: Copyright (C) 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #if USE_RCS_ID ! 29: const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.1 93/07/30 08:00:19 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <errno.h> ! 33: ! 34: #include "uudefs.h" ! 35: #include "uuconf.h" ! 36: #include "system.h" ! 37: #include "prot.h" ! 38: #include "trans.h" ! 39: ! 40: /* Local functions. */ ! 41: ! 42: static boolean flocal_xcmd_request P((struct stransfer *qtrans, ! 43: struct sdaemon *qdaemon)); ! 44: static boolean flocal_xcmd_await_reply P((struct stransfer *qtrans, ! 45: struct sdaemon *qdaemon, ! 46: const char *zdata, size_t cdata)); ! 47: static boolean fremote_xcmd_reply P((struct stransfer *qtrans, ! 48: struct sdaemon *qdaemon)); ! 49: ! 50: /* Handle a local work request. We just set up the request for ! 51: transmission. */ ! 52: ! 53: boolean ! 54: flocal_xcmd_init (qdaemon, qcmd) ! 55: struct sdaemon *qdaemon; ! 56: struct scmd *qcmd; ! 57: { ! 58: struct stransfer *qtrans; ! 59: ! 60: qtrans = qtransalc (qcmd); ! 61: qtrans->psendfn = flocal_xcmd_request; ! 62: ! 63: return fqueue_local (qdaemon, qtrans); ! 64: } ! 65: ! 66: /* Send the execution request to the remote system. */ ! 67: ! 68: static boolean ! 69: flocal_xcmd_request (qtrans, qdaemon) ! 70: struct stransfer *qtrans; ! 71: struct sdaemon *qdaemon; ! 72: { ! 73: size_t clen; ! 74: char *zsend; ! 75: boolean fret; ! 76: ! 77: ulog (LOG_NORMAL, "Requesting work: %s to %s", qtrans->s.zfrom, ! 78: qtrans->s.zto); ! 79: ! 80: /* We send the string ! 81: X from to user options ! 82: We put a dash in front of options. */ ! 83: clen = (strlen (qtrans->s.zfrom) + strlen (qtrans->s.zto) ! 84: + strlen (qtrans->s.zuser) + strlen (qtrans->s.zoptions) + 7); ! 85: zsend = zbufalc (clen); ! 86: sprintf (zsend, "X %s %s %s -%s", qtrans->s.zfrom, qtrans->s.zto, ! 87: qtrans->s.zuser, qtrans->s.zoptions); ! 88: ! 89: fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal, ! 90: qtrans->iremote); ! 91: ubuffree (zsend); ! 92: if (! fret) ! 93: { ! 94: utransfree (qtrans); ! 95: return FALSE; ! 96: } ! 97: ! 98: qtrans->fcmd = TRUE; ! 99: qtrans->precfn = flocal_xcmd_await_reply; ! 100: ! 101: return fqueue_receive (qdaemon, qtrans); ! 102: } ! 103: ! 104: /* Get a reply to an execution request from the remote system. */ ! 105: ! 106: /*ARGSUSED*/ ! 107: static boolean ! 108: flocal_xcmd_await_reply (qtrans, qdaemon, zdata, cdata) ! 109: struct stransfer *qtrans; ! 110: struct sdaemon *qdaemon; ! 111: const char *zdata; ! 112: size_t cdata; ! 113: { ! 114: qtrans->precfn = NULL; ! 115: ! 116: if (zdata[0] != 'X' ! 117: || (zdata[1] != 'Y' && zdata[1] != 'N')) ! 118: { ! 119: ulog (LOG_ERROR, "Bad response to work request"); ! 120: utransfree (qtrans); ! 121: return FALSE; ! 122: } ! 123: ! 124: if (zdata[1] == 'N') ! 125: { ! 126: ulog (LOG_ERROR, "%s: work request denied", qtrans->s.zfrom); ! 127: (void) fmail_transfer (FALSE, qtrans->s.zuser, (const char *) NULL, ! 128: "work request denied", ! 129: qtrans->s.zfrom, qdaemon->qsys->uuconf_zname, ! 130: qtrans->s.zto, (const char *) NULL, ! 131: (const char *) NULL); ! 132: } ! 133: ! 134: (void) fsysdep_did_work (qtrans->s.pseq); ! 135: utransfree (qtrans); ! 136: ! 137: return TRUE; ! 138: } ! 139: ! 140: /* Handle a remote work request. This just queues up the requests for ! 141: later processing. */ ! 142: ! 143: boolean ! 144: fremote_xcmd_init (qdaemon, qcmd, iremote) ! 145: struct sdaemon *qdaemon; ! 146: struct scmd *qcmd; ! 147: int iremote; ! 148: { ! 149: const struct uuconf_system *qsys; ! 150: const char *zexclam; ! 151: const struct uuconf_system *qdestsys; ! 152: struct uuconf_system sdestsys; ! 153: char *zdestfile; ! 154: boolean fmkdirs; ! 155: struct stransfer *qtrans; ! 156: char *zuser; ! 157: char aboptions[5]; ! 158: char *zfrom; ! 159: boolean fret; ! 160: char *zfile; ! 161: ! 162: ulog (LOG_NORMAL, "Work requested: %s to %s", qcmd->zfrom, ! 163: qcmd->zto); ! 164: ! 165: qsys = qdaemon->qsys; ! 166: ! 167: zexclam = strchr (qcmd->zto, '!'); ! 168: if (zexclam == NULL ! 169: || zexclam == qcmd->zto ! 170: || strncmp (qdaemon->zlocalname, qcmd->zto, ! 171: (size_t) (zexclam - qcmd->zto)) == 0) ! 172: { ! 173: const char *zconst; ! 174: ! 175: /* The files are supposed to be copied to the local system. */ ! 176: qdestsys = NULL; ! 177: if (zexclam == NULL) ! 178: zconst = qcmd->zto; ! 179: else ! 180: zconst = zexclam + 1; ! 181: ! 182: zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir); ! 183: if (zdestfile == NULL) ! 184: return FALSE; ! 185: ! 186: zuser = NULL; ! 187: fmkdirs = strchr (qcmd->zoptions, 'f') != NULL; ! 188: } ! 189: else ! 190: { ! 191: size_t clen; ! 192: char *zcopy; ! 193: int iuuconf; ! 194: char *zoptions; ! 195: ! 196: clen = zexclam - qcmd->zto; ! 197: zcopy = zbufalc (clen + 1); ! 198: memcpy (zcopy, qcmd->zto, clen); ! 199: zcopy[clen] = '\0'; ! 200: ! 201: iuuconf = uuconf_system_info (qdaemon->puuconf, zcopy, &sdestsys); ! 202: if (iuuconf == UUCONF_NOT_FOUND) ! 203: { ! 204: if (! funknown_system (qdaemon->puuconf, zcopy, &sdestsys)) ! 205: { ! 206: ulog (LOG_ERROR, "%s: System not found", zcopy); ! 207: ubuffree (zcopy); ! 208: qtrans = qtransalc (qcmd); ! 209: qtrans->psendfn = fremote_xcmd_reply; ! 210: qtrans->pinfo = (pointer) "XN"; ! 211: qtrans->iremote = iremote; ! 212: return fqueue_remote (qdaemon, qtrans); ! 213: } ! 214: } ! 215: else if (iuuconf != UUCONF_SUCCESS) ! 216: { ! 217: ulog_uuconf (LOG_ERROR, qdaemon->puuconf, iuuconf); ! 218: ubuffree (zcopy); ! 219: return FALSE; ! 220: } ! 221: ! 222: ubuffree (zcopy); ! 223: ! 224: qdestsys = &sdestsys; ! 225: zdestfile = zbufcpy (zexclam + 1); ! 226: ! 227: zuser = zbufalc (strlen (qdestsys->uuconf_zname) ! 228: + strlen (qcmd->zuser) + sizeof "!"); ! 229: sprintf (zuser, "%s!%s", qdestsys->uuconf_zname, qcmd->zuser); ! 230: zoptions = aboptions; ! 231: *zoptions++ = 'C'; ! 232: if (strchr (qcmd->zoptions, 'd') != NULL) ! 233: *zoptions++ = 'd'; ! 234: if (strchr (qcmd->zoptions, 'm') != NULL) ! 235: *zoptions++ = 'm'; ! 236: *zoptions = '\0'; ! 237: fmkdirs = TRUE; ! 238: } ! 239: ! 240: /* At this point we prepare to confirm the remote request. We could ! 241: actually fork here and let the child spool up the requests. */ ! 242: qtrans = qtransalc (qcmd); ! 243: qtrans->psendfn = fremote_xcmd_reply; ! 244: qtrans->pinfo = (pointer) "XY"; ! 245: qtrans->iremote = iremote; ! 246: if (! fqueue_remote (qdaemon, qtrans)) ! 247: { ! 248: ubuffree (zdestfile); ! 249: ubuffree (zuser); ! 250: return FALSE; ! 251: } ! 252: ! 253: /* Now we have to process each source file. The source ! 254: specification may or may use wildcards. */ ! 255: zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir); ! 256: if (zfrom == NULL) ! 257: { ! 258: ubuffree (zdestfile); ! 259: ubuffree (zuser); ! 260: return FALSE; ! 261: } ! 262: ! 263: if (! fsysdep_wildcard_start (zfrom)) ! 264: { ! 265: ubuffree (zfrom); ! 266: ubuffree (zdestfile); ! 267: ubuffree (zuser); ! 268: return FALSE; ! 269: } ! 270: ! 271: fret = TRUE; ! 272: ! 273: while ((zfile = zsysdep_wildcard (zfrom)) != NULL) ! 274: { ! 275: char *zto; ! 276: char abtname[CFILE_NAME_LEN]; ! 277: ! 278: if (! fsysdep_file_exists (zfile)) ! 279: { ! 280: ulog (LOG_ERROR, "%s: no such file", zfile); ! 281: continue; ! 282: } ! 283: ! 284: /* Make sure the remote system is permitted to read the ! 285: specified file. */ ! 286: if (! fin_directory_list (zfile, qsys->uuconf_pzremote_send, ! 287: qsys->uuconf_zpubdir, TRUE, TRUE, ! 288: (const char *) NULL)) ! 289: { ! 290: ulog (LOG_ERROR, "%s: not permitted to send", zfile); ! 291: break; ! 292: } ! 293: ! 294: if (qdestsys != NULL) ! 295: { ! 296: /* We really should get the original grade here. */ ! 297: zto = zsysdep_data_file_name (qdestsys, qdaemon->zlocalname, ! 298: BDEFAULT_UUCP_GRADE, FALSE, ! 299: abtname, (char *) NULL, ! 300: (char *) NULL); ! 301: if (zto == NULL) ! 302: { ! 303: fret = FALSE; ! 304: break; ! 305: } ! 306: } ! 307: else ! 308: { ! 309: zto = zsysdep_add_base (zdestfile, zfile); ! 310: if (zto == NULL) ! 311: { ! 312: fret = FALSE; ! 313: break; ! 314: } ! 315: /* We only accept a local destination if the remote system ! 316: has the right to create files there. */ ! 317: if (! fin_directory_list (zto, qsys->uuconf_pzremote_receive, ! 318: qsys->uuconf_zpubdir, TRUE, FALSE, ! 319: (const char *) NULL)) ! 320: { ! 321: ulog (LOG_ERROR, "%s: not permitted to receive", zto); ! 322: ubuffree (zto); ! 323: break; ! 324: } ! 325: } ! 326: ! 327: /* Copy the file either to the final destination or to the ! 328: spool directory. */ ! 329: if (! fcopy_file (zfile, zto, qdestsys == NULL, fmkdirs)) ! 330: { ! 331: ubuffree (zto); ! 332: break; ! 333: } ! 334: ! 335: ubuffree (zto); ! 336: ! 337: /* If there is a destination system, queue it up. */ ! 338: if (qdestsys != NULL) ! 339: { ! 340: struct scmd ssend; ! 341: char *zjobid; ! 342: ! 343: ssend.bcmd = 'S'; ! 344: ssend.pseq = NULL; ! 345: ssend.zfrom = zfile; ! 346: ssend.zto = zdestfile; ! 347: ssend.zuser = zuser; ! 348: ssend.zoptions = aboptions; ! 349: ssend.ztemp = abtname; ! 350: ssend.imode = ixsysdep_file_mode (zfile); ! 351: ssend.znotify = ""; ! 352: ssend.cbytes = -1; ! 353: ssend.zcmd = NULL; ! 354: ssend.ipos = 0; ! 355: ! 356: zjobid = zsysdep_spool_commands (qdestsys, BDEFAULT_UUCP_GRADE, ! 357: 1, &ssend); ! 358: if (zjobid == NULL) ! 359: break; ! 360: ubuffree (zjobid); ! 361: } ! 362: ! 363: ubuffree (zfile); ! 364: } ! 365: ! 366: if (zfile != NULL) ! 367: ubuffree (zfile); ! 368: ! 369: (void) fsysdep_wildcard_end (); ! 370: ! 371: ubuffree (zdestfile); ! 372: if (qdestsys != NULL) ! 373: (void) uuconf_system_free (qdaemon->puuconf, &sdestsys); ! 374: ! 375: ubuffree (zfrom); ! 376: ubuffree (zuser); ! 377: ! 378: return fret; ! 379: } ! 380: ! 381: /* Reply to a remote work request. */ ! 382: ! 383: static boolean ! 384: fremote_xcmd_reply (qtrans, qdaemon) ! 385: struct stransfer *qtrans; ! 386: struct sdaemon *qdaemon; ! 387: { ! 388: boolean fret; ! 389: ! 390: fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, ! 391: (const char *) qtrans->pinfo, ! 392: qtrans->ilocal, ! 393: qtrans->iremote); ! 394: utransfree (qtrans); ! 395: return fret; ! 396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.