1 /* Copyright 2003-2008 Wang, Chun-Pin All rights reserved. */
2 #include <stdio.h>
3 #include <signal.h>
4 #include <syslog.h>
5 #include <errno.h>
6 #include <string.h>
7 
8 #include "smbftpd.h"
9 
10 static int transflag  = 0;
11 static int recvurg = 0;
12 
13 /**
14  * Turn on recvurg flag if we are transfering files.
15  *
16  * This function is called by sigurg.
17  */
set_receive_sigurg()18 void set_receive_sigurg()
19 {
20 	if (!transflag) {
21 		return;
22 	}
23 	recvurg = 1;
24 }
25 
26 /**
27  * Check whether we have received SIGURG. If yes, reset the flag.
28  *
29  * @return 1: Yes, we got SIGURG
30  *         0: No SIGURG pedding
31  */
sigurg_received()32 int sigurg_received()
33 {
34 	if (recvurg) {
35 		recvurg = 0;
36 		return 1;
37 	}
38 	return 0;
39 }
40 
41 /**
42  * Mask/unmask the SIGURG
43  *
44  * @param flag   0: unblock SIGURG
45  *               1: block SIGURG
46  */
maskurg(int flag)47 void maskurg(int flag)
48 {
49 	int oerrno;
50 	sigset_t sset;
51 
52 	if (!transflag) {
53 		syslog(LOG_ERR, "Internal: maskurg() while no transfer");
54 		return;
55 	}
56 	oerrno = errno;
57 	sigemptyset(&sset);
58 	sigaddset(&sset, SIGURG);
59 	sigprocmask(flag ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
60 	errno = oerrno;
61 }
62 
63 /**
64  * When start transfer, turn on transflag and unmask SIGURG.
65  * After transfer end, turn off transflag and mask SIGURG.
66  *
67  * @param flag   1: Start transfer
68  *               0: End transfer
69  */
flagxfer(int flag)70 void flagxfer(int flag)
71 {
72 	if (flag) {
73 		if (transflag)
74 			syslog(LOG_ERR, "Internal: flagxfer(1): "
75 					"transfer already under way");
76 		transflag = 1;
77 		maskurg(0);
78 		recvurg = 0;
79 	} else {
80 		if (!transflag)
81 			syslog(LOG_ERR, "Internal: flagxfer(0): "
82 					"no active transfer");
83 		maskurg(1);
84 		transflag = 0;
85 	}
86 }
87 
88 /*
89  * Returns 0 if OK to resume or -1 if abort requested.
90  */
check_oob(void)91 int check_oob(void)
92 {
93 	char tmpline[16];
94 	int ret;
95 #ifdef WITH_SSL /* "pseudo-OOB" with SSL */
96 	fd_set mask;
97 	struct timeval tv;
98 #endif
99 
100 	if (!transflag) {
101 		syslog(LOG_ERR, "Internal: myoob() while no transfer");
102 		return (0);
103 	}
104 
105 #ifdef WITH_SSL /* "pseudo-OOB" with SSL */
106 	FD_ZERO(&mask);
107 	FD_SET(fileno(stdin),&mask);
108 	tv.tv_sec=0;
109 	tv.tv_usec=0;
110 
111 	if (0 == select(fileno(stdin)+1, &mask, NULL, NULL, &tv)) {
112 		return 0;
113 	}
114 #endif /*USE_SSL*/
115 
116 	bzero(tmpline, sizeof(tmpline));
117 	ret = mygetline(tmpline, sizeof(tmpline), stdin);
118 	if (ret == -1) {
119 		reply_noformat(221, "You could at least say goodbye.");
120 		dologout(0);
121 	} else if (ret == -2) {
122 		/* Ignore truncated command. */
123 		return (0);
124 	}
125 
126 	if (strcasecmp(tmpline, "ABOR\r\n") == 0) {
127 		reply_noformat(426, "Transfer aborted. Data connection closed.");
128 		reply_noformat(226, "Abort successful.");
129 		return (-1);
130 	}
131 
132 	return (0);
133 }
134 
135