Bug Summary

File:obj-scan-build/libftpconn/../../libftpconn/cmd.c
Location:line 137, column 5
Description:Assigned value is garbage or undefined

Annotated Source Code

1/* Send commands to the ftp server
2
3 Copyright (C) 1997 Free Software Foundation, Inc.
4
5 Written by Miles Bader <miles@gnu.ai.mit.edu>
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include <unistd.h>
22#include <errno(*__errno_location ()).h>
23#include <string.h>
24#include <arpa/telnet.h>
25
26#include <ftpconn.h>
27#include "priv.h"
28
29/* Version of write that writes all LEN bytes of BUF if possible to FD. */
30static error_t
31_write (int fd, const void *buf, size_t len)
32{
33 while (len > 0)
34 {
35 ssize_t wr = write (fd, buf, len);
36 if (wr < 0)
37 return errno(*__errno_location ());
38 else if (wr == 0)
39 return EPIPE((0x10 << 26) | ((32) & 0x3fff));
40 buf += wr;
41 len -= wr;
42 }
43 return 0;
44}
45
46static error_t
47_skip_write (int fd, const void *buf, size_t len, size_t *skip)
48{
49 size_t sk = *skip;
50 error_t err = 0;
51
52 if (len > sk)
53 {
54 err = _write (fd, buf + sk, len - sk);
55 *skip = 0;
56 }
57 else
58 *skip = sk - len;
59
60 return err;
61}
62
63/* Ridiculous function to deal with the never-to-occur case of the ftp
64 command being too long for the buffer in ftp_conn_cmd; just writes the
65 portion of the command that wasn't written there. */
66static error_t
67_long_cmd (int fd, const char *cmd, const char *arg, size_t skip)
68{
69 error_t err = _skip_write (fd, cmd, strlen (cmd), &skip);
70 if (!err && arg)
71 {
72 err = _skip_write (fd, " ", 1, &skip);
73 if (! err)
74 err = _skip_write (fd, arg, strlen (arg), &skip);
75 }
76 if (! err)
77 err = _skip_write (fd, "\r\n", 2, &skip);
78 return err;
79}
80
81/* Send the ftp command CMD, with optional argument ARG (if non-zero) to
82 CONN's ftp server. If either of REPLY or REPLY_TXT is non-zero, then a
83 reply is waited for and returned as with ftp_conn_get_reply, otherwise
84 the next reply from the server is left unconsumed. */
85error_t
86ftp_conn_cmd (struct ftp_conn *conn, const char *cmd, const char *arg,
87 int *reply, const char **reply_txt)
88{
89 error_t err = 0;
90
91 if (conn->control < 0)
3
Taking false branch
92 err = EPIPE((0x10 << 26) | ((32) & 0x3fff));
93 else
94 /* (This used to try to call dprintf to output to conn->control, but that
95 function doesn't appear to work.) */
96 {
97 char buf[200];
98 size_t out =
99 snprintf (buf, sizeof buf, arg ? "%s %s\r\n" : "%s\r\n", cmd, arg);
4
Assuming 'arg' is non-null
5
'?' condition is true
100 err = _write (conn->control, buf, out);
101
102 if (!err && conn->hooks && conn->hooks->cntl_debug)
6
Assuming 'err' is not equal to 0
103 {
104 buf[out - 2] = '\0'; /* Stomp the CR & NL. */
105 (* conn->hooks->cntl_debug) (conn, FTP_CONN_CNTL_DEBUG_CMD1, buf);
106 }
107
108 if (!err && out == sizeof buf)
109 err = _long_cmd (conn->control, cmd, arg, sizeof buf);
110 }
111
112 if (!err && (reply || reply_txt))
113 err = ftp_conn_get_reply (conn, reply, reply_txt);
114
115 return err;
116}
117
118/* Send an ftp command to CONN's server, and optionally await a reply as with
119 ftp_conn_cmd, but also open a new connection if it appears that the old
120 one has died (as when the ftp server times it out). */
121error_t
122ftp_conn_cmd_reopen (struct ftp_conn *conn, const char *cmd, const char *arg,
123 int *reply, const char **reply_txt)
124{
125 int _reply;
1
Variable '_reply' declared without an initial value
126 error_t err;
127
128 err = ftp_conn_cmd (conn, cmd, arg, &_reply, reply_txt);
2
Calling 'ftp_conn_cmd'
7
Returning from 'ftp_conn_cmd'
129 if (err == EPIPE((0x10 << 26) | ((32) & 0x3fff)) || (!err && _reply == REPLY_CLOSED421))
130 /* Retry once after reopening the connection. */
131 {
132 err = ftp_conn_open (conn);
133 if (! err)
134 err = ftp_conn_cmd (conn, cmd, arg, reply, reply_txt);
135 }
136 else if (reply)
8
Assuming 'reply' is non-null
9
Taking true branch
137 *reply = _reply;
10
Assigned value is garbage or undefined
138
139 return err;
140}
141
142/* Send an ftp ABOR command to CONN's server, aborting any transfer in
143 progress. */
144void
145ftp_conn_abort (struct ftp_conn *conn)
146{
147 if (conn->control >= 0)
148 {
149 static const char ip[] = { IAC255, IP244, IAC255 };
150 static const char abor[] = { DM242, 'a', 'b', 'o', 'r', '\r', '\n' };
151
152 if (conn->hooks && conn->hooks->cntl_debug)
153 (* conn->hooks->cntl_debug) (conn, FTP_CONN_CNTL_DEBUG_CMD1, "abor");
154
155 if (send (conn->control, ip, sizeof ip, MSG_OOBMSG_OOB) == sizeof ip
156 && write (conn->control, abor, sizeof abor) == sizeof abor)
157 {
158 int reply;
159 error_t err;
160 do
161 err = ftp_conn_get_raw_reply (conn, &reply, 0);
162 while (reply == REPLY_ABORTED426);
163 if (reply != REPLY_TRANS_OK226 && reply != REPLY_ABORT_OK225)
164 ftp_conn_close (conn);
165 }
166 else
167 ftp_conn_close (conn);
168 }
169}