1
- /* $Id: cmd-load-buffer.c,v 1.16 2010-07-02 02:52:13 tcunha Exp $ */
1
+ /* $Id: cmd-load-buffer.c,v 1.17 2010-08-09 21:44:25 tcunha Exp $ */
2
2
3
3
/*
4
4
* Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
31
31
*/
32
32
33
33
int cmd_load_buffer_exec (struct cmd * , struct cmd_ctx * );
34
+ void cmd_load_buffer_callback (struct client * , void * );
34
35
35
36
const struct cmd_entry cmd_load_buffer_entry = {
36
37
"load-buffer" , "loadb" ,
@@ -43,37 +44,55 @@ const struct cmd_entry cmd_load_buffer_entry = {
43
44
cmd_buffer_print
44
45
};
45
46
47
+ struct cmd_load_buffer_cdata {
48
+ struct session * session ;
49
+ int buffer ;
50
+ };
51
+
46
52
int
47
53
cmd_load_buffer_exec (struct cmd * self , struct cmd_ctx * ctx )
48
54
{
49
- struct cmd_buffer_data * data = self -> data ;
50
- struct session * s ;
51
- FILE * f , * close_f ;
52
- char * pdata , * new_pdata ;
53
- size_t psize ;
54
- u_int limit ;
55
- int ch ;
55
+ struct cmd_buffer_data * data = self -> data ;
56
+ struct cmd_load_buffer_cdata * cdata ;
57
+ struct session * s ;
58
+ struct client * c = ctx -> cmdclient ;
59
+ FILE * f ;
60
+ char * pdata , * new_pdata ;
61
+ size_t psize ;
62
+ u_int limit ;
63
+ int ch ;
56
64
57
65
if ((s = cmd_find_session (ctx , data -> target )) == NULL )
58
66
return (-1 );
59
67
60
- if (strcmp (data -> arg , "-" ) == 0 ) {
61
- if (ctx -> cmdclient == NULL ) {
68
+ if (strcmp (data -> arg , "-" ) == 0 ) {
69
+ if (c == NULL ) {
62
70
ctx -> error (ctx , "%s: can't read from stdin" , data -> arg );
63
71
return (-1 );
64
72
}
65
- f = ctx -> cmdclient -> stdin_file ;
66
- if (isatty (fileno (ctx -> cmdclient -> stdin_file ))) {
73
+ if (c -> flags & CLIENT_TERMINAL ) {
67
74
ctx -> error (ctx , "%s: stdin is a tty" , data -> arg );
68
75
return (-1 );
69
76
}
70
- close_f = NULL ;
71
- } else {
72
- if ((f = fopen (data -> arg , "rb" )) == NULL ) {
73
- ctx -> error (ctx , "%s: %s" , data -> arg , strerror (errno ));
77
+ if (c -> stdin_fd == -1 ) {
78
+ ctx -> error (ctx , "%s: can't read from stdin" , data -> arg );
74
79
return (-1 );
75
80
}
76
- close_f = f ;
81
+
82
+ cdata = xmalloc (sizeof * cdata );
83
+ cdata -> session = s ;
84
+ cdata -> buffer = data -> buffer ;
85
+ c -> stdin_data = cdata ;
86
+ c -> stdin_callback = cmd_load_buffer_callback ;
87
+
88
+ c -> references ++ ;
89
+ bufferevent_enable (c -> stdin_event , EV_READ );
90
+ return (1 );
91
+ }
92
+
93
+ if ((f = fopen (data -> arg , "rb" )) == NULL ) {
94
+ ctx -> error (ctx , "%s: %s" , data -> arg , strerror (errno ));
95
+ return (-1 );
77
96
}
78
97
79
98
pdata = NULL ;
@@ -94,8 +113,8 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
94
113
if (pdata != NULL )
95
114
pdata [psize ] = '\0' ;
96
115
97
- if ( close_f != NULL )
98
- fclose ( close_f ) ;
116
+ fclose ( f );
117
+ f = NULL ;
99
118
100
119
limit = options_get_number (& s -> options , "buffer-limit" );
101
120
if (data -> buffer == -1 ) {
@@ -104,15 +123,62 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
104
123
}
105
124
if (paste_replace (& s -> buffers , data -> buffer , pdata , psize ) != 0 ) {
106
125
ctx -> error (ctx , "no buffer %d" , data -> buffer );
107
- goto error ;
126
+ return ( -1 ) ;
108
127
}
109
128
110
129
return (0 );
111
130
112
131
error :
113
132
if (pdata != NULL )
114
133
xfree (pdata );
115
- if (close_f != NULL )
116
- fclose (close_f );
134
+ if (f != NULL )
135
+ fclose (f );
117
136
return (-1 );
118
137
}
138
+
139
+ void
140
+ cmd_load_buffer_callback (struct client * c , void * data )
141
+ {
142
+ struct cmd_load_buffer_cdata * cdata = data ;
143
+ struct session * s = cdata -> session ;
144
+ char * pdata ;
145
+ size_t psize ;
146
+ u_int limit ;
147
+ int idx ;
148
+
149
+ /*
150
+ * Event callback has already checked client is not dead and reduced
151
+ * its reference count. But tell it to exit.
152
+ */
153
+ c -> flags |= CLIENT_EXIT ;
154
+
155
+ /* Does the target session still exist? */
156
+ if (session_index (s , & idx ) != 0 )
157
+ goto out ;
158
+
159
+ psize = EVBUFFER_LENGTH (c -> stdin_event -> input );
160
+ if (psize == 0 )
161
+ goto out ;
162
+
163
+ pdata = malloc (psize + 1 );
164
+ if (pdata == NULL )
165
+ goto out ;
166
+ bufferevent_read (c -> stdin_event , pdata , psize );
167
+ pdata [psize ] = '\0' ;
168
+
169
+ limit = options_get_number (& s -> options , "buffer-limit" );
170
+ if (cdata -> buffer == -1 ) {
171
+ paste_add (& s -> buffers , pdata , psize , limit );
172
+ goto out ;
173
+ }
174
+ if (paste_replace (& s -> buffers , cdata -> buffer , pdata , psize ) != 0 ) {
175
+ /* No context so can't use server_client_msg_error. */
176
+ evbuffer_add_printf (
177
+ c -> stderr_event -> output , "no buffer %d\n" , cdata -> buffer );
178
+ bufferevent_enable (c -> stderr_event , EV_WRITE );
179
+ goto out ;
180
+ }
181
+
182
+ out :
183
+ xfree (cdata );
184
+ }
0 commit comments