MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
autopilot.c
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/utils/autopilot.c,v 1.35 2017/01/12 15:10:27 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  *
10  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
11  * via La Masa, 34 - 20156 Milano, Italy
12  * http://www.aero.polimi.it
13  *
14  * Changing this copyright notice is forbidden.
15  *
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation (version 2 of the License).
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this program; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  */
30 
31 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 
36 #include <termios.h>
37 #include "ac/getopt.h"
38 
39 #include <stdio.h>
40 #include <errno.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <netdb.h>
47 #include <sys/un.h>
48 
49 #include <string.h>
50 
51 #ifdef HAVE_SASL2
52 #if defined(HAVE_SASL_SASL_H)
53 #include <sasl/sasl.h>
54 #elif defined (HAVE_SASL_H)
55 #include <sasl.h>
56 #endif /* HAVE_SASL_SASL_H || HAVE_SASL_H */
57 #include "mbsasl.h"
58 #endif /* HAVE_SASL2 */
59 
60 #include "sock.h"
61 
62 const unsigned short int PORT = 5555;
63 const char *SERVERHOST = "localhost";
64 const char *SERVERPATH = "/var/mbdyn/mbdyn.sock";
65 
66 static void
67 keys(FILE * fh)
68 {
69  fprintf(fh,
70  "\tkeys:\n"
71  "\t\t'i':\tswitches the incremental mode on\n"
72  "\t\t'p':\tincrements the drive\n"
73  "\t\t'm':\tdecrements the drive\n"
74  "\t\t'^D':\tquits\n\n");
75 }
76 
77 static void
78 usage(void)
79 {
80  fprintf(stderr,
81  "\n\tusage: autopilot [h:p:D:vw:Wx:] <label>\n\n"
82  "\t\t-D <user>\tuser name\n"
83  "\t\t-h <host>\thost name\n"
84  "\t\t-m <mech>\tSASL mechanism(s)\n"
85  "\t\t-p <port>\tport number\n"
86  "\t\t-P <path>\tpath for named socked\n"
87  "\t\t-S\t\tuse SASL"
88 #ifndef HAVE_SASL2
89  " (not supported)"
90 #endif /* ! HAVE_SASL2 */
91  "\n"
92  "\t\t-v\t\tverbose\n"
93  "\t\t-w <cred>\tuser credentials\n"
94  "\t\t-W\t\tprompt for user credentials\n"
95  "\t\t-x <value>\tincrement\n"
96  "\n"
97  "\t\t<label>:\tfile drive (base 1) index to modify\n\n");
98  keys(stderr);
99 }
100 
101 /* Use this variable to remember original terminal attributes. */
102 struct termios saved_attributes;
103 
104 void
106 {
107  tcsetattr(STDIN_FILENO, TCSANOW, &saved_attributes);
108 }
109 
110 void
112 {
113  struct termios tattr;
114 
115  /* Make sure stdin is a terminal. */
116  if (!isatty(STDIN_FILENO)) {
117  fprintf(stderr, "Not a terminal.\n");
118  exit(EXIT_FAILURE);
119  }
120 
121  /* Save the terminal attributes so we can restore them later. */
122  tcgetattr(STDIN_FILENO, &saved_attributes);
123  atexit(reset_input_mode);
124 
125  /* Set the funny terminal modes. */
126  tcgetattr(STDIN_FILENO, &tattr);
127  tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
128  tattr.c_cc[VMIN] = 0;
129  tattr.c_cc[VTIME] = 0;
130  if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tattr) < 0) {
131  perror("tcsetattr");
132  exit(EXIT_FAILURE);
133  }
134 }
135 
136 static int sasl = 0;
137 #ifdef HAVE_SASL2
138 static struct mbdyn_sasl_t mbdyn_sasl = MBDYN_SASL_INIT;
139 #endif /* HAVE_SASL2 */
140 
141 const char *path = NULL;
142 const char *host = NULL;
143 unsigned short int port = 0;
144 
145 int
146 send_message(const char *message)
147 {
148  int sock;
149  struct sockaddr_in peer_name;
150  FILE *fd;
151 
152  /* Create the socket. */
153  if (path) {
154  sock = mbdyn_make_named_socket(0, path, 0, NULL);
155  } else {
156  sock = mbdyn_make_inet_socket(0, host, port, 0, NULL);
157  }
158  if (sock < 0) {
159  return -1;
160  }
161 
162  /* Connect to the server. */
163  if (0 > connect(sock, (struct sockaddr *) &peer_name,
164  sizeof(peer_name))) {
165  return -1;
166  }
167 
168  if (sasl) {
169 #ifdef HAVE_SASL2
170  if (mbdyn_sasl_client_auth(sock, NULL, &mbdyn_sasl) != SASL_OK) {
171  return -1;
172  }
173 #endif /* HAVE_SASL2 */
174  }
175 
176  fd = fdopen(sock, "w");
177  fputs(message, fd);
178  fclose(fd);
179 
180  return 0;
181 }
182 
183 int
184 main(int argc, char *argv[])
185 {
186  char *user = NULL;
187  char *cred = NULL;
188 
189  char *increment = "1.";
190  char *label = NULL;
191 
192  char c;
193 
194  char *auth = NULL;
195  char *inc = NULL;
196  char *plus = NULL;
197  char *minus = NULL;
198 
199  char *mech = NULL;
200 
201  int verbose = 0;
202 
203  host = SERVERHOST;
204  port = PORT;
205 
206  while (1) {
207  int opt;
208 
209  opt = getopt(argc, argv, "D:h:m:p:P:Svw:Wx:");
210 
211  if (opt == EOF) {
212  break;
213  }
214 
215  switch (opt) {
216  case 'D':
217  user = optarg;
218  break;
219 
220  case 'h':
221  host = optarg;
222  break;
223 
224  case 'm':
225  mech = optarg;
226 #ifndef HAVE_SASL2
227  fprintf(stderr, "SASL not supported\n");
228 #endif /* ! HAVE_SASL2 */
229  break;
230 
231  case 'p':
232  port = atoi(optarg);
233  break;
234 
235  case 'P':
236  path = optarg;
237  break;
238 
239  case 'S':
240  sasl++;
241 #ifndef HAVE_SASL2
242  fprintf(stderr, "SASL not supported\n");
243  exit(EXIT_FAILURE);
244 #endif /* ! HAVE_SASL2 */
245  break;
246 
247  case 'v':
248  verbose++;
249  break;
250 
251  case 'w':
252  cred = strdup(optarg);
253  break;
254 
255  case 'W': {
256  char *tmp = getpass("password: ");
257 
258  if (tmp) {
259  cred = strdup(tmp);
260  memset(tmp, '\0', strlen(tmp));
261  }
262  break;
263  }
264 
265  case 'x':
266  increment = optarg;
267  break;
268  }
269  }
270 
271  if (argc - optind < 1) {
272  usage();
273  exit(EXIT_SUCCESS);
274  }
275 
276  label = argv[optind];
277 
278  /* messaggi: */
279  if (!sasl) {
280  if (user) {
281  size_t l = strlen(user);
282  if (cred) {
283  l += strlen(cred) + 7 + 11;
284 
285  auth = (char *)calloc(sizeof(char), l + 1);
286  snprintf(auth, l + 1, "user: %s\npassword: %s\n", user, cred);
287  } else {
288  l += 7;
289 
290  auth = (char *)calloc(sizeof(char), l + 1);
291  snprintf(auth, l + 1, "user: %s\n", user);
292  }
293  }
294  } else {
295 #ifdef HAVE_SASL2
296  if (verbose) {
297  printf("initializing SASL data...\n");
298  }
299 
300  mbdyn_sasl.use_sasl = MBDYN_SASL_CLIENT;
301  mbdyn_sasl.sasl_flags = MBDYN_SASL_FLAG_CRITICAL | MBDYN_SASL_FLAG_USERAUTHZ;
302  mbdyn_sasl.sasl_mech = mech;
303  mbdyn_sasl.sasl_user = user;
304  mbdyn_sasl.sasl_cred = cred;
305  mbdyn_sasl.sasl_hostname = host;
306 
307  if (mbdyn_sasl_client_init(&mbdyn_sasl) != SASL_OK) {
308  fprintf(stderr, "SASL init failed\n");
309  exit(EXIT_FAILURE);
310  }
311 #endif /* HAVE_SASL2 */
312  }
313 
314  if (auth) {
315  size_t l = strlen(auth) + 8 + strlen(label) + 9 + 2;
316 
317  inc = (char *)calloc(sizeof(char), l + 1);
318  snprintf(inc, l, "%slabel: %s\ninc: yes\n.\n", auth, label);
319 
320  l = strlen(auth) + 8 + strlen(label) + 8 + strlen(increment) + 2;
321  plus = (char *)calloc(sizeof(char), l + 1);
322  minus = (char *)calloc(sizeof(char), l + 1 + 1);
323  snprintf(plus, l + 1, "%slabel: %s\nvalue: %s\n.\n", auth, label, increment);
324  snprintf(minus, l + 2, "%slabel: %s\nvalue: -%s\n.\n", auth, label, increment);
325 
326  } else {
327  size_t l = 8 + strlen(label) + 9 + 2;
328 
329  inc = (char *)calloc(sizeof(char), l + 1);
330  snprintf(inc, l + 1, "label: %s\ninc: yes\n.\n", label);
331 
332  l = 8 + strlen(label) + 8 + strlen(increment) + 2;
333  plus = (char *)calloc(sizeof(char), l + 1);
334  minus = (char *)calloc(sizeof(char), l + 1 + 1);
335  snprintf(plus, l + 1, "label: %s\nvalue: %s\n.\n", label, increment);
336  snprintf(minus, l + 2, "label: %s\nvalue: -%s\n.\n", label, increment);
337  }
338 
339  set_input_mode();
340 
341  if (verbose) {
342  fprintf(stdout, "Connecting to host %s:%d\n", host, port);
343  if (user) {
344  if (cred) {
345  fprintf(stdout, "Accounting as \"%s\" (with creds)\n", user);
346 
347  } else {
348  fprintf(stdout, "Accounting as \"%s\"\n", user);
349  }
350  }
351  fprintf(stdout, "Incrementing drive %s by %s\n", label, increment);
352  keys(stdout);
353  }
354 
355  while (1) {
356  size_t i;
357 
358  i = read(STDIN_FILENO, &c, 1);
359 
360  if (i > 0) {
361  char *msg = NULL;
362 
363  if (c == '\004') { /* `C-d' */
364  break;
365  }
366 
367  switch (c) {
368  case 'i':
369  msg = inc;
370  break;
371 
372  break;
373 
374  case 'p':
375  msg = plus;
376  break;
377 
378  case 'm':
379  msg = minus;
380  break;
381 
382  }
383 
384  if (send_message(msg) == -1) {
385  fprintf(stderr, "unable to connect to host %s:%d\n",
386  host, port);
387  }
388  }
389  }
390 
391  if (cred) {
392  free(cred);
393  }
394 
395  exit(EXIT_SUCCESS);
396 }
397 
int optind
Definition: getopt.c:72
static int sasl
Definition: autopilot.c:136
void reset_input_mode(void)
Definition: autopilot.c:105
const unsigned short int PORT
Definition: autopilot.c:62
int mbdyn_make_inet_socket(struct sockaddr_in *name, const char *hostname, unsigned short int port, int dobind, int *perror)
static void usage(void)
Definition: autopilot.c:78
const char * SERVERHOST
Definition: autopilot.c:63
static void keys(FILE *fh)
Definition: autopilot.c:67
int send_message(const char *message)
Definition: autopilot.c:146
const char * host
Definition: autopilot.c:142
int main(int argc, char *argv[])
Definition: autopilot.c:184
const char * SERVERPATH
Definition: autopilot.c:64
void set_input_mode(void)
Definition: autopilot.c:111
int mbdyn_make_named_socket(struct sockaddr_un *name, const char *path, int dobind, int *perror)
static std::stack< cleanup * > c
Definition: cleanup.cc:59
int getopt(int argc, char *const argv[], const char *opts)
Definition: getopt.c:93
static int verbose
Definition: ann_tr.c:51
struct mbrtai_msg_t msg
char * optarg
Definition: getopt.c:74
unsigned short int port
Definition: autopilot.c:143
struct termios saved_attributes
Definition: autopilot.c:102
static void * read(LoadableElem *pEl, DataManager *pDM, MBDynParser &HP)
const char * path
Definition: autopilot.c:141