Esempio n. 1
0
STATIC void test37()
{
unsigned int i;
int ofs;
u_int16_t param = VolID;
char *name = "t37 dir";
int  dir;
int  did;
u_int16_t vol = VolID;
DSI *dsi;
unsigned int ret;
unsigned char cmd;

	dsi = &Conn->dsi;

	enter_test();
    fprintf(stdout,"===================\n");
    fprintf(stdout,"Errror:test37: no folder error ==> ERR_NOOBJ\n");

	dir  = FPCreateDir(Conn,vol, DIRDID_ROOT , name);
	if (!dir) {
		nottested();
		goto fin;
	}
	did  = dir +1;

	for (i = 0 ;i < sizeof(afp_cmd_with_vol_did1);i++) {
		memset(dsi->commands, 0, DSI_CMDSIZ);
		dsi->header.dsi_flags = DSIFL_REQUEST;     
		dsi->header.dsi_command = DSIFUNC_CMD;
		dsi->header.dsi_requestID = htons(dsi_clientID(dsi));

		ofs = 0;
		cmd = afp_cmd_with_vol_did1[i];
		dsi->commands[ofs++] = cmd;
		dsi->commands[ofs++] = 0;

		memcpy(dsi->commands +ofs, &param, sizeof(param));
		ofs += sizeof(param);

		memcpy(dsi->commands +ofs, &did, sizeof(did));  /* directory did */
		ofs += sizeof(did);
		
		dsi->datalen = ofs;
		dsi->header.dsi_len = htonl(dsi->datalen);
		dsi->header.dsi_code = 0; 
 
   		my_dsi_stream_send(dsi, dsi->commands, dsi->datalen);
		my_dsi_cmd_receive(dsi);
		ret = dsi->header.dsi_code;
    	if (ntohl(AFPERR_NOOBJ) != ret) {
			fprintf(stdout,"\tFAILED command %3i %s\t result %d %s\n", cmd, AfpNum2name(cmd),ntohl(ret), afp_error(ret));
			failed_nomsg();
    	}
    }
fin:
	FAIL (FPDelete(Conn, vol,  DIRDID_ROOT, name)) 
	exit_test("test37");
}
Esempio n. 2
0
STATIC void test35()
{
unsigned int i;
int ofs;
u_int16_t param = VolID+1;
DSI *dsi;
unsigned int ret;
unsigned char cmd;

	dsi = &Conn->dsi;

	enter_test();
    fprintf(stdout,"===================\n");
    fprintf(stdout,"Error:test35: illegal volume (-5019 AFP_ERRPARAM)\n");

	for (i = 0 ;i < sizeof(afp_cmd_with_vol);i++) {
		memset(dsi->commands, 0, DSI_CMDSIZ);
		dsi->header.dsi_flags = DSIFL_REQUEST;     
		dsi->header.dsi_command = DSIFUNC_CMD;
		dsi->header.dsi_requestID = htons(dsi_clientID(dsi));

		ofs = 0;
		cmd = afp_cmd_with_vol[i];
		dsi->commands[ofs++] = cmd;
		dsi->commands[ofs++] = 0;

		memcpy(dsi->commands +ofs, &param, sizeof(param));
		ofs += sizeof(param);
		
		dsi->datalen = ofs;
		dsi->header.dsi_len = htonl(dsi->datalen);
		dsi->header.dsi_code = 0; 
 
   		my_dsi_stream_send(dsi, dsi->commands, dsi->datalen);
		my_dsi_cmd_receive(dsi);
		ret = dsi->header.dsi_code;
		
    	if (ntohl(AFPERR_PARAM) != ret) {
			fprintf(stdout,"\tFAILED command %3i %s\t result %d %s\n", cmd, AfpNum2name(cmd),ntohl(ret), afp_error(ret));
			failed_nomsg();
    	}
    }
	exit_test("test35");
}
Esempio n. 3
0
/* -------------------------------------------
 afp over dsi. this never returns. 
*/
void afp_over_dsi(AFPObj *obj)
{
    DSI *dsi = (DSI *) obj->handle;
    int rc_idx;
    u_int32_t err, cmd;
    u_int8_t function;

    AFPobj = obj;
    obj->exit = afp_dsi_die;
    obj->reply = (int (*)()) dsi_cmdreply;
    obj->attention = (int (*)(void *, AFPUserBytes)) dsi_attention;
    dsi->tickle = 0;

    afp_over_dsi_sighandlers(obj);

    if (dircache_init(obj->options.dircachesize) != 0)
        afp_dsi_die(EXITERR_SYS);

    /* set TCP snd/rcv buf */
    if (obj->options.tcp_rcvbuf) {
        if (setsockopt(dsi->socket,
                       SOL_SOCKET,
                       SO_RCVBUF,
                       &obj->options.tcp_rcvbuf,
                       sizeof(obj->options.tcp_rcvbuf)) != 0) {
            LOG(log_error, logtype_dsi, "afp_over_dsi: setsockopt(SO_RCVBUF): %s", strerror(errno));
        }
    }
    if (obj->options.tcp_sndbuf) {
        if (setsockopt(dsi->socket,
                       SOL_SOCKET,
                       SO_SNDBUF,
                       &obj->options.tcp_sndbuf,
                       sizeof(obj->options.tcp_sndbuf)) != 0) {
            LOG(log_error, logtype_dsi, "afp_over_dsi: setsockopt(SO_SNDBUF): %s", strerror(errno));
        }
    }

    /* set TCP_NODELAY */
    int flag = 1;
    setsockopt(dsi->socket, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));

    /* get stuck here until the end */
    while (1) {
        if (sigsetjmp(recon_jmp, 1) != 0)
            /* returning from SIGALARM handler for a primary reconnect */
            continue;

        /* Blocking read on the network socket */
        cmd = dsi_stream_receive(dsi);

        if (cmd == 0) {
            /* cmd == 0 is the error condition */
            if (dsi->flags & DSI_RECONSOCKET) {
                /* we just got a reconnect so we immediately try again to receive on the new fd */
                dsi->flags &= ~DSI_RECONSOCKET;
                continue;
            }

            /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
            if (dsi->flags & DSI_AFP_LOGGED_OUT) {
                LOG(log_note, logtype_afpd, "afp_over_dsi: client logged out, terminating DSI session");
                afp_dsi_close(obj);
                exit(0);
            }

#if 0
            /*  got ECONNRESET in read from client => exit*/
            if (dsi->flags & DSI_GOT_ECONNRESET) {
                LOG(log_note, logtype_afpd, "afp_over_dsi: client connection reset");
                afp_dsi_close(obj);
                exit(0);
            }
#endif

            if (dsi->flags & DSI_RECONINPROG) {
                LOG(log_note, logtype_afpd, "afp_over_dsi: failed reconnect");
                afp_dsi_close(obj);
                exit(0);
            }

            /* Some error on the client connection, enter disconnected state */
            if (dsi_disconnect(dsi) != 0)
                afp_dsi_die(EXITERR_CLNT);

            while (dsi->flags & DSI_DISCONNECTED)
                pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
            continue; /* continue receiving until disconnect timer expires
                       * or a primary reconnect succeeds  */
        }

        if (!(dsi->flags & DSI_EXTSLEEP) && (dsi->flags & DSI_SLEEPING)) {
            LOG(log_debug, logtype_afpd, "afp_over_dsi: got data, ending normal sleep");
            dsi->flags &= ~DSI_SLEEPING;
            dsi->tickle = 0;
        }

        if (reload_request) {
            reload_request = 0;
            load_volumes(AFPobj);
        }

        /* The first SIGINT enables debugging, the next restores the config */
        if (debug_request) {
            static int debugging = 0;
            debug_request = 0;

            dircache_dump();
            uuidcache_dump();

            if (debugging) {
                if (obj->options.logconfig)
                    setuplog(obj->options.logconfig);
                else
                    setuplog("default log_note");
                debugging = 0;
            } else {
                char logstr[50];
                debugging = 1;
                sprintf(logstr, "default log_maxdebug /tmp/afpd.%u.XXXXXX", getpid());
                setuplog(logstr);
            }
        }


        dsi->flags |= DSI_DATA;
        dsi->tickle = 0;

        switch(cmd) {

        case DSIFUNC_CLOSE:
            LOG(log_debug, logtype_afpd, "DSI: close session request");
            afp_dsi_close(obj);
            LOG(log_note, logtype_afpd, "done");
            exit(0);

        case DSIFUNC_TICKLE:
            dsi->flags &= ~DSI_DATA; /* thats no data in the sense we use it in alarm_handler */
            LOG(log_debug, logtype_afpd, "DSI: client tickle");
            /* timer is not every 30 seconds anymore, so we don't get killed on the client side. */
            if ((dsi->flags & DSI_DIE))
                dsi_tickle(dsi);
            break;

        case DSIFUNC_CMD:
#ifdef AFS
            if ( writtenfork ) {
                if ( flushfork( writtenfork ) < 0 ) {
                    LOG(log_error, logtype_afpd, "main flushfork: %s", strerror(errno) );
                }
                writtenfork = NULL;
            }
#endif /* AFS */

            function = (u_char) dsi->commands[0];

            /* AFP replay cache */
            rc_idx = dsi->clientID % REPLAYCACHE_SIZE;
            LOG(log_debug, logtype_dsi, "DSI request ID: %u", dsi->clientID);

            if (replaycache[rc_idx].DSIreqID == dsi->clientID
                && replaycache[rc_idx].AFPcommand == function) {
                LOG(log_note, logtype_afpd, "AFP Replay Cache match: id: %u / cmd: %s",
                    dsi->clientID, AfpNum2name(function));
                err = replaycache[rc_idx].result;
            /* AFP replay cache end */
            } else {
                /* send off an afp command. in a couple cases, we take advantage
                 * of the fact that we're a stream-based protocol. */
                if (afp_switch[function]) {
                    dsi->datalen = DSI_DATASIZ;
                    dsi->flags |= DSI_RUNNING;

                    LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));

                    err = (*afp_switch[function])(obj,
                                                  (char *)&dsi->commands, dsi->cmdlen,
                                                  (char *)&dsi->data, &dsi->datalen);

                    LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
                        AfpNum2name(function), AfpErr2name(err));

                    dir_free_invalid_q();

#ifdef FORCE_UIDGID
                    /* bring everything back to old euid, egid */
                    if (obj->force_uid)
                        restore_uidgid ( &obj->uidgid );
#endif /* FORCE_UIDGID */
                    dsi->flags &= ~DSI_RUNNING;

                    /* Add result to the AFP replay cache */
                    replaycache[rc_idx].DSIreqID = dsi->clientID;
                    replaycache[rc_idx].AFPcommand = function;
                    replaycache[rc_idx].result = err;
                } else {
                    LOG(log_error, logtype_afpd, "bad function %X", function);
                    dsi->datalen = 0;
                    err = AFPERR_NOOP;
                }
            }

            /* single shot toggle that gets set by dsi_readinit. */
            if (dsi->flags & DSI_NOREPLY) {
                dsi->flags &= ~DSI_NOREPLY;
                break;
            } else if (!dsi_cmdreply(dsi, err)) {
                LOG(log_error, logtype_afpd, "dsi_cmdreply(%d): %s", dsi->socket, strerror(errno) );
                if (dsi_disconnect(dsi) != 0)
                    afp_dsi_die(EXITERR_CLNT);
            }
            break;

        case DSIFUNC_WRITE: /* FPWrite and FPAddIcon */
            function = (u_char) dsi->commands[0];
            if ( afp_switch[ function ] != NULL ) {
                dsi->datalen = DSI_DATASIZ;
                dsi->flags |= DSI_RUNNING;

                LOG(log_debug, logtype_afpd, "<== Start AFP command: %s", AfpNum2name(function));

                err = (*afp_switch[function])(obj,
                                              (char *)&dsi->commands, dsi->cmdlen,
                                              (char *)&dsi->data, &dsi->datalen);

                LOG(log_debug, logtype_afpd, "==> Finished AFP command: %s -> %s",
                    AfpNum2name(function), AfpErr2name(err));

                dsi->flags &= ~DSI_RUNNING;
#ifdef FORCE_UIDGID
            	/* bring everything back to old euid, egid */
		if (obj->force_uid)
            	    restore_uidgid ( &obj->uidgid );
#endif /* FORCE_UIDGID */
            } else {
                LOG(log_error, logtype_afpd, "(write) bad function %x", function);
                dsi->datalen = 0;
                err = AFPERR_NOOP;
            }

            if (!dsi_wrtreply(dsi, err)) {
                LOG(log_error, logtype_afpd, "dsi_wrtreply: %s", strerror(errno) );
                if (dsi_disconnect(dsi) != 0)
                    afp_dsi_die(EXITERR_CLNT);
            }
            break;

        case DSIFUNC_ATTN: /* attention replies */
            break;

            /* error. this usually implies a mismatch of some kind
             * between server and client. if things are correct,
             * we need to flush the rest of the packet if necessary. */
        default:
            LOG(log_info, logtype_afpd,"afp_dsi: spurious command %d", cmd);
            dsi_writeinit(dsi, dsi->data, DSI_DATASIZ);
            dsi_writeflush(dsi);
            break;
        }
        pending_request(dsi);

        fce_pending_events(obj);
    }

    /* error */
    afp_dsi_die(EXITERR_CLNT);
}