/* rtfd.c - RT-file transfer utility -- responder */
static char *rcsid
= "$Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.2 91/02/22 09:34:20 mrose Interim $";
* $Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.2 91/02/22 09:34:20 mrose Interim $
* Revision 7.2 91/02/22 09:34:20 mrose
* Revision 7.1 90/07/01 21:04:48 mrose
* Revision 7.0 89/11/23 22:10:49 mrose
* Acquisition, use, and distribution of this module and related
* materials are subject to the restrictions of a license agreement.
* Consult the Preface in the User's Manual for the full terms of
struct passwd
*getpwnam ();
static char *myname
= "rtfd";
static char *destination
;
int downtrans (), uptrans ();
register struct passwd
*pw
;
register struct RtSAPstart
*rts
= &rtss
;
struct RtSAPindication rtis
;
register struct RtSAPindication
*rti
= &rtis
;
register struct RtSAPabort
*rta
= &rti
-> rti_abort
;
struct type_RTF_Request
*req
;
if (myname
= rindex (argv
[0], '/'))
if (myname
== NULL
|| *myname
== NULL
)
if (debug
= isatty (fileno (stderr
)))
ll_dbinit (pgm_log
, myname
);
ll_hdinit (pgm_log
, myname
);
advise (LLOG_NOTICE
, NULLCP
, "starting");
if (RtBInit (argc
, argv
, rts
, rti
) == NOTOK
)
rts_adios (rta
, "(RtB)initialization fails");
advise (LLOG_NOTICE
, NULLCP
,
"RT-BEGIN.INDICATION: <%d, %s, %s, <%d, %s>, 0x%x>",
rts
-> rts_sd
, rts
-> rts_mode
== RTS_TWA
? "twa" : "monologue",
rts
-> rts_turn
== RTS_RESPONDER
? "responder" : "initiator",
saddr2str (&rts
-> rts_initiator
.rta_addr
),
if (rts
-> rts_data
== NULLPE
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "rejected -- no user-data parameter");
if (RtBeginResponse (sd
, RTS_REJECT
, NULLPE
, rti
) == NOTOK
)
rts_adios (rta
, "RT-BEGIN.RESPONSE (reject)");
if (decode_RTF_Request (rts
-> rts_data
, 1, NULLIP
, NULLVP
, &req
)
advise (LLOG_EXCEPTIONS
, NULLCP
,
"rejected -- error decoding request: %s", PY_pepy
);
PLOGP (pgm_log
,RTF_Request
, rts
-> rts_data
, "Request", 1);
if (qb_pullup (req
-> user
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, NULLCP
, "rejected -- out of memory");
if (qb_pullup (req
-> password
) == NOTOK
)
if ((cp
= qb2str (req
-> file
)) == NULL
)
advise (LLOG_NOTICE
, NULLCP
, "%s: %s \"%s\"",
user
= req
-> user
-> qb_forw
-> qb_data
,
(turn
= rts
-> rts_turn
) == RTS_RESPONDER
? "get" : "put", cp
);
if (strcmp (cp
, "ANON") == 0 || strcmp (user
, ANON
) == 0) {
if ((pw
= getpwnam (ANON
)) && pw
-> pw_uid
== 0)
pw
= baduser (NULLCP
, user
) ? NULL
: getpwnam (user
);
advise (LLOG_EXCEPTIONS
, NULLCP
, "rejected -- no such user");
if (RtBeginResponse (sd
, RTS_VALIDATE
, NULLPE
, rti
) == NOTOK
)
rts_adios (rta
, "RT-BEGIN.RESPONSE (validate)");
if (*pw
-> pw_passwd
== NULL
|| (!guest
&& strcmp (crypt (req
-> password
-> qb_forw
-> qb_data
,
pw
-> pw_passwd
), pw
-> pw_passwd
))) {
advise (LLOG_EXCEPTIONS
, NULLCP
,
"authentication failure for \"%s\"%s requesting %s of \"%s\"",
user
, guest
? " (guest)" : "",
(turn
= rts
-> rts_turn
) == RTS_RESPONDER
? "get" : "put",
if (chdir (pw
-> pw_dir
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, pw
-> pw_dir
,
"unable to change directory to");
if (RtBeginResponse (sd
, RTS_BUSY
, NULLPE
, rti
) == NOTOK
)
rts_adios (rta
, "RT-BEGIN.RESPONSE (busy)");
if (guest
&& chroot (pw
-> pw_dir
) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, pw
-> pw_dir
,
"unable to change root to");
(void) setgid (pw
-> pw_gid
);
(void) initgroups (pw
-> pw_name
, pw
-> pw_gid
);
(void) setuid (pw
-> pw_uid
);
if (turn
== RTS_RESPONDER
) {
if ((fd
= open (cp
, O_RDONLY
, 0x00)) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, cp
, "rejected -- unable to open");
if (RtBeginResponse (sd
, RTS_ACCEPT
, NULLPE
, rti
) == NOTOK
)
rts_adios (rta
, "RT-BEGIN.RESPONSE (accept)");
if (turn
== RTS_RESPONDER
) {
if (RtSetDownTrans (sd
, downtrans
, rti
) == NOTOK
)
rts_adios (rta
, "set DownTrans upcall");
if (RtTransferRequest (sd
, NULLPE
, NOTOK
, rti
) == NOTOK
)
rts_adios (rta
, "RT-TRANSFER.REQUEST");
advise (LLOG_NOTICE
, NULLCP
, "transfer complete");
if (RtSetUpTrans (sd
, uptrans
, rti
) == NOTOK
)
rts_adios (rta
, "set UpTrans upcall");
switch (result
= RtWaitRequest (sd
, NOTOK
, rti
)) {
adios (NULLCP
, "unknown return from RtWaitRequest=%d",
switch (rti
-> rti_type
) {
register struct RtSAPturn
*rtu
= &rti
-> rti_turn
;
if (RtGTurnRequest (sd
, rti
) == NOTOK
)
rts_adios (rta
, "RT-TURN-GIVE.REQUEST");
adios (NULLCP
, "protocol screw-up");
register struct RtSAPtransfer
*rtt
= &rti
-> rti_transfer
;
advise (LLOG_NOTICE
, NULLCP
, "transfer complete");
register struct RtSAPabort
*rtb
= &rti
-> rti_abort
;
rts_adios (rtb
, "RT-U-ABORT.INDICATION");
if (RTS_FATAL (rtb
-> rta_reason
))
rts_adios (rtb
, "RT-P-ABORT.INDICATION");
rts_advise (rtb
, "RT-P-ABORT.INDICATION");
register struct RtSAPclose
*rtc
= &rti
-> rti_close
;
advise (LLOG_NOTICE
, NULLCP
, "RT-END.INDICATION");
if (RtEndResponse (sd
, rti
) == NOTOK
)
rts_adios (rta
, "RT-END.RESPONSE");
adios (NULLCP
, "unexpected indication type=%d",
adios (NULLCP
, "unknown indication type=%d", rti
-> rti_type
);
static int downtrans (sd
, base
, len
, size
, ssn
, ack
, rti
)
struct RtSAPindication
*rti
;
advise (LLOG_DEBUG
, NULLCP
, "RT-PLEASE.INDICATION: %d", size
);
if (fstat (fd
, &st
) == NOTOK
)
return rtsaplose (rti
, RTS_TRANSFER
, destination
,
bsize
= st
.st_blksize
> 0 ? st
.st_blksize
: BUFSIZ
;
if (size
== 0) /* no checkpointing... */
if ((bp
= malloc ((unsigned) n
)) == NULL
)
return rtsaplose (rti
, RTS_CONGEST
, NULLCP
, "out of memory");
advise (LLOG_DEBUG
, NULLCP
, "Selecting block size of %d", n
);
advise (LLOG_DEBUG
, NULLCP
,
" based on blksize of %d and RTTR size of %d",
*base
= NULLCP
, *len
= 0;
for (ep
= (dp
= bp
) + (cc
= bsize
); dp
< ep
; dp
+= n
, cc
-= n
) {
switch (n
= read (fd
, dp
, cc
)) {
return rtsaplose (rti
, RTS_TRANSFER
, "failed", "read");
if ((cc
= dp
- bp
) > 0) {
static int uptrans (sd
, type
, addr
, rti
)
struct RtSAPindication
*rti
;
register struct qbuf
*qb
= (struct qbuf
*) addr
;
register struct qbuf
*qp
;
for (qp
= qb
-> qb_forw
; qp
!= qb
; qp
= qp
-> qb_forw
)
if (write (fd
, qp
-> qb_data
, qp
-> qb_len
) !=qp
-> qb_len
)
return rtsaplose (rti
, RTS_TRANSFER
, "failed","write");
register struct SSAPsync
*sn
= (struct SSAPsync
*) addr
;
advise (LLOG_DEBUG
, NULLCP
, "S-MINOR-SYNC.INDICATION: %ld",
register struct SSAPactivity
*sv
= (struct SSAPactivity
*)addr
;
advise (LLOG_DEBUG
, NULLCP
,
"S-ACTIVITY-START.INDICATION");
if ((fd
= creat (destination
, 0666)) == NOTOK
) {
advise (LLOG_EXCEPTIONS
, destination
,
return rtsaplose (rti
, RTS_TRANSFER
, destination
,
advise (LLOG_EXCEPTIONS
, NULLCP
,
sv
-> sv_type
== SV_INTRIND
? "interrupted"
SReportString (sv
-> sv_reason
));
advise (LLOG_DEBUG
, NULLCP
,
"S-ACTIVITY-END.INDICATION");
return rtsaplose (rti
, RTS_TRANSFER
, destination
,
return rtsaplose (rti
, RTS_TRANSFER
, NULLCP
,
"unexpected activity indication=0x%x",
register struct SSAPreport
*sp
= (struct SSAPreport
*) addr
;
return rtsaplose (rti
, RTS_TRANSFER
, NULLCP
,
"unexpected provider-initiated exception report");
advise (LLOG_EXCEPTIONS
, NULLCP
,
"exception: %s", SReportString (sp
-> sp_reason
));
return rtsaplose (rti
, RTS_TRANSFER
, NULLCP
,
"unknown uptrans type=0x%x", type
);
if (stat (file
, &st
) != NOTOK
&& (st
.st_mode
& S_IFMT
) == S_IFREG
&& unlink (file
) == NOTOK
)
advise (LLOG_EXCEPTIONS
, file
, "unable to unlink");