void cmd_retr(t_ftpserv *ftpserv, t_client *client, char *args) { int pid; logline(ftpserv, 1, "user ^ retr ^.\n", client->username, args); if ((pid = fork()) == -1) { send_msg2client(client, "451 fork error. Please try again later.\r\n"); return ; } if (pid == 0) { if (client->mode == MODE_ACTF) make_connect_socket(client); send_msg2client(client, "150 Opening data connection.\r\n"); if (client->mode == MODE_PASV) passiv_connect(ftpserv, client); do_retr(ftpserv, client, args); shutdown(client->data_fd, SHUT_RDWR); close(client->data_fd); if (client->mode == MODE_PASV) close(client->data_servfd); send_msg2client(client, "226 Transfer complete.\r\n"); } }
static void loop() { char buf[BUFSIZ]; char *p; int c; signal(SIGALRM, bye); while (alarm(300), fgets(buf, sizeof(buf), stdin)) { bytes_received_count += strlen(buf); alarm(0); if ((p=strchr(buf, '\n')) != 0) *p=0; else while ((c=getc(stdin)) >= 0 && c != '\n') ; p=strtok(buf, " \t\r"); if (!p) p=""; mkupper(p); if (strcmp(p, "QUIT") == 0) { printed(printf("+OK Bye-bye.\r\n")); fflush(stdout); cleanup(); acctout("INFO: LOGOUT"); return; } if (strcmp(p, "STAT") == 0) { do_stat(); continue; } if (strcmp(p, "LIST") == 0) { do_list(strtok(NULL, " \t\r")); continue; } if (strcmp(p, "RETR") == 0) { unsigned i; if ((i=getmsgnum(strtok(NULL, " \t\r"))) == 0) continue; do_retr(i-1, 0); continue; } if (strcmp(p, "CAPA") == 0) { pop3dcapa(); continue; } if (strcmp(p, "DELE") == 0) { unsigned i; if ((i=getmsgnum(strtok(NULL, " \t\r"))) == 0) continue; msglist_a[i-1]->isdeleted=1; printed(printf("+OK Deleted.\r\n")); fflush(stdout); continue; } if (strcmp(p, "NOOP") == 0) { printed(printf("+OK Yup.\r\n")); fflush(stdout); continue; } if (strcmp(p, "RSET") == 0) { unsigned i; for (i=0; i<msglist_cnt; i++) msglist_a[i]->isdeleted=0; printed(printf("+OK Resurrected.\r\n")); fflush(stdout); continue; } if (strcmp(p, "TOP") == 0) { unsigned i, j; const char *q; if ((i=getmsgnum(strtok(NULL, " \t\r"))) == 0) continue; q=strtok(NULL, " \t\r"); if (!q) goto error; j=atoi(q); do_retr(i-1, &j); continue; } if (strcmp(p, "UIDL") == 0) { do_uidl(strtok(NULL, " \t\r")); continue; } error: printed(printf("-ERR Invalid command.\r\n")); fflush(stdout); } acctout("INFO: DISCONNECTED"); }
void client_read(client *cl) { int status, pn; status = mr_cont_receive(cl->con, &cl->req); if (status == -1) return; else if (status != MR_SUCCESS) { cl->state = CL_CLOSING; if (status != MR_NOT_CONNECTED) com_err(whoami, status, "while reading from socket"); return; } pn = cl->req.u.mr_procno; if (pn < 0 || pn > MR_MAX_PROC) { com_err(whoami, 0, "procno out of range"); client_reply(cl, MR_UNKNOWN_PROC); goto out; } log_args(procnames[pn], 2, cl->req.mr_argc, cl->req.mr_argv); if (dormant == ASLEEP && pn != MR_NOOP && pn != MR_MOTD) { client_reply(cl, MR_DOWN); com_err(whoami, MR_DOWN, "(query refused)"); goto out; } /* make sure this gets cleared before every operation */ dbms_errno = 0; switch (pn) { case MR_NOOP: client_reply(cl, MR_SUCCESS); break; case MR_AUTH: do_auth(cl); break; case MR_QUERY: do_retr(cl); break; case MR_ACCESS: do_access(cl); break; case MR_SHUTDOWN: do_shutdown(cl); break; case MR_DO_UPDATE: client_reply(cl, MR_PERM); break; case MR_MOTD: get_motd(cl); break; case MR_PROXY: do_proxy(cl); break; case MR_SETVERSION: do_version(cl); break; case MR_KRB5_AUTH: do_krb5_auth(cl); break; } out: mr_destroy_reply(cl->req); memset(&cl->req, 0, sizeof(mr_params)); }