Statistics
| Branch: | Revision:

ddr4s / fw / wiringPi / wiringPiD / wiringpid.c @ 32:cadb9025f1e0

History | View | Annotate | Download (8.12 KB)

1
/*
2
 * wiringPiD.c:
3
 *        Copyright (c) 2012-2017 Gordon Henderson
4
 ***********************************************************************
5
 * This file is part of wiringPi:
6
 *        https://projects.drogon.net/raspberry-pi/wiringpi/
7
 *
8
 *    wiringPi is free software: you can redistribute it and/or modify
9
 *    it under the terms of the GNU Lesser General Public License as published by
10
 *    the Free Software Foundation, either version 3 of the License, or
11
 *    (at your option) any later version.
12
 *
13
 *    wiringPi is distributed in the hope that it will be useful,
14
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *    GNU Lesser General Public License for more details.
17
 *
18
 *    You should have received a copy of the GNU Lesser General Public License
19
 *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
20
 ***********************************************************************
21
 */
22

    
23
#include <arpa/inet.h>
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <stdint.h>
27
#include <unistd.h>
28
#include <string.h>
29
#include <stdarg.h>
30
#include <syslog.h>
31
#include <signal.h>
32
#include <errno.h>
33

    
34
#include <wiringPi.h>
35
#include <wpiExtensions.h>
36

    
37
#include "drcNetCmd.h"
38
#include "network.h"
39
#include "runRemote.h"
40
#include "daemonise.h"
41

    
42

    
43
#define        PIDFILE        "/var/run/wiringPiD.pid"
44

    
45

    
46
// Globals
47

    
48
static const char *usage = "[-h] [-d] [-g | -1 | -z] [[-x extension:pin:params] ...] password" ;
49
static int doDaemon = FALSE ;
50

    
51
//
52

    
53
static void logMsg (const char *message, ...)
54
{
55
  va_list argp ;
56
  char buffer [1024] ;
57

    
58
  va_start (argp, message) ;
59
    vsnprintf (buffer, 1023, message, argp) ;
60
  va_end (argp) ;
61

    
62
  if (doDaemon)
63
    syslog (LOG_DAEMON | LOG_INFO, "%s", buffer) ;
64
  else
65
    printf ("%s\n", buffer) ;
66
}
67

    
68

    
69
/*
70
 * sigHandler:
71
 * setupSigHandler:
72
 *      Somehing has happened that would normally terminate the program so try
73
 *        to close down nicely.
74
 *********************************************************************************
75
 */
76

    
77
void sigHandler (int sig)
78
{
79
  logMsg ("Exiting on signal %d: %s", sig, strsignal (sig)) ;
80
  (void)unlink (PIDFILE) ;
81
  exit (EXIT_FAILURE) ;
82
}
83

    
84
void setupSigHandler (void)
85
{
86
  struct sigaction action ;
87

    
88
  sigemptyset (&action.sa_mask) ;
89
  action.sa_flags = 0 ;
90

    
91
// Ignore what we can
92

    
93
  action.sa_handler = SIG_IGN ;
94

    
95
  sigaction (SIGHUP,  &action, NULL) ;
96
  sigaction (SIGTTIN, &action, NULL) ;
97
  sigaction (SIGTTOU, &action, NULL) ;
98

    
99
// Trap what we can to exit gracefully
100

    
101
  action.sa_handler = sigHandler ;
102

    
103
  sigaction (SIGINT,  &action, NULL) ;
104
  sigaction (SIGQUIT, &action, NULL) ;
105
  sigaction (SIGILL,  &action, NULL) ;
106
  sigaction (SIGABRT, &action, NULL) ;
107
  sigaction (SIGFPE,  &action, NULL) ;
108
  sigaction (SIGSEGV, &action, NULL) ;
109
  sigaction (SIGPIPE, &action, NULL) ;
110
  sigaction (SIGALRM, &action, NULL) ;
111
  sigaction (SIGTERM, &action, NULL) ;
112
  sigaction (SIGUSR1, &action, NULL) ;
113
  sigaction (SIGUSR2, &action, NULL) ;
114
  sigaction (SIGCHLD, &action, NULL) ;
115
  sigaction (SIGTSTP, &action, NULL) ;
116
  sigaction (SIGBUS,  &action, NULL) ;
117
}
118

    
119

    
120
/*
121
 * The works...
122
 *********************************************************************************
123
 */
124

    
125
int main (int argc, char *argv [])
126
{
127
  int clientFd ;
128
  char *p, *password ;
129
  int i ;
130
  int port = DEFAULT_SERVER_PORT ;
131
  int wpiSetup = 0 ;
132

    
133
  if (argc < 2)
134
  {
135
    fprintf (stderr, "Usage: %s %s\n", argv [0], usage) ;
136
    exit (EXIT_FAILURE) ;
137
  }
138

    
139
// Help?
140

    
141
  if (strcasecmp (argv [1], "-h") == 0)
142
  {
143
    printf ("Usage: %s %s\n", argv [0], usage) ;
144
    return 0 ;
145
  }
146

    
147
// Daemonize?
148
//        Must come before the other args as e.g. some extensions
149
//        open files which get closed on daemonise...
150

    
151
  if (strcasecmp (argv [1], "-d") == 0)
152
  {
153
    if (geteuid () != 0)
154
    {
155
      fprintf (stderr, "%s: Must be root to run as a daemon.\n", argv [0]) ;
156
      exit (EXIT_FAILURE) ;
157
    }
158

    
159
    doDaemon = TRUE ;
160
    daemonise (PIDFILE) ;
161

    
162
    for (i = 2 ; i < argc ; ++i)
163
      argv [i - 1] = argv [i] ;
164
    --argc ;
165
  }
166

    
167
// Scan all other arguments
168

    
169
  while (*argv [1] == '-')
170
  {
171

    
172
// Look for wiringPi setup arguments:
173
//        Same as the gpio command and rtb.
174

    
175
//        -g - bcm_gpio
176

    
177
    if (strcasecmp (argv [1], "-g") == 0)
178
    {
179
      if (wpiSetup == 0)
180
      {
181
        logMsg ("BCM_GPIO mode selected") ;
182
        wiringPiSetupGpio () ;
183
      }
184

    
185
      for (i = 2 ; i < argc ; ++i)
186
        argv [i - 1] = argv [i] ;
187
      --argc ;
188
      ++wpiSetup ;
189
      continue ;
190
    }
191

    
192
//        -1 - physical pins
193

    
194
    if (strcasecmp (argv [1], "-1") == 0)
195
    {
196
      if (wpiSetup == 0)
197
      {
198
        logMsg ("GPIO-PHYS mode selected") ;
199
        wiringPiSetupPhys () ;
200
      }
201

    
202
      for (i = 2 ; i < argc ; ++i)
203
        argv [i - 1] = argv [i] ;
204
      --argc ;
205
      ++wpiSetup ;
206
      continue ;
207
    }
208

    
209
//        -z  - no wiringPi - blocks remotes accessing local pins
210

    
211
    if (strcasecmp (argv [1], "-z") == 0)
212
    {
213
      if (wpiSetup == 0)
214
        logMsg ("No GPIO mode selected") ;
215

    
216
      for (i = 2 ; i < argc ; ++i)
217
        argv [i - 1] = argv [i] ;
218
      --argc ;
219
      noLocalPins = TRUE ;
220
      ++wpiSetup ;
221
      continue ;
222
    }
223

    
224
// -p to select the port
225

    
226
    if (strcasecmp (argv [1], "-p") == 0)
227
    {
228
      if (argc < 3)
229
      {
230
        logMsg ("-p missing extension port") ;
231
        exit (EXIT_FAILURE) ;
232
      }
233

    
234
      logMsg ("Setting port to: %s", argv [2]) ;
235

    
236
      port = atoi (argv [2]) ;
237
      if ((port < 1) || (port > 65535))
238
      {
239
        logMsg ("Invalid server port: %d", port) ;
240
        exit (EXIT_FAILURE) ;
241
      }
242

    
243
// Shift args down by 2
244

    
245
      for (i = 3 ; i < argc ; ++i)
246
        argv [i - 2] = argv [i] ;
247
      argc -= 2 ;
248

    
249
      continue ;
250
    }
251

    
252
// Check for -x argument to load in a new extension
253
//        -x extension:base:args
254
//        Can load many modules to extend the daemon.
255

    
256
    if (strcasecmp (argv [1], "-x") == 0)
257
    {
258
      if (argc < 3)
259
      {
260
        logMsg ("-x missing extension name:data:etc.") ;
261
        exit (EXIT_FAILURE) ;
262
      }
263

    
264
      logMsg ("Loading extension: %s", argv [2]) ;
265

    
266
      if (!loadWPiExtension (argv [0], argv [2], TRUE))
267
      {
268
        logMsg ("Extension load failed: %s", strerror (errno)) ;
269
        exit (EXIT_FAILURE) ;
270
      }
271

    
272
// Shift args down by 2
273

    
274
      for (i = 3 ; i < argc ; ++i)
275
        argv [i - 2] = argv [i] ;
276
      argc -= 2 ;
277

    
278
      continue ;
279
    }
280

    
281
    logMsg ("Invalid parameter: %s", argv [1]) ;
282
    exit (EXIT_FAILURE) ;
283
  }
284

    
285
// Default to wiringPi mode
286

    
287
  if (wpiSetup == 0)
288
  {
289
    logMsg ("WiringPi GPIO mode selected") ;
290
    wiringPiSetup () ;
291
  }
292

    
293
// Finally, should just be one arg left - the password...
294

    
295
  if (argc != 2)
296
  {
297
    logMsg ("No password supplied") ;
298
    exit (EXIT_FAILURE) ;
299
  }
300

    
301
  if (strlen (argv [1]) < 6)
302
  {
303
    logMsg ("Password too short - at least 6 chars, not %d", strlen (argv [1])) ;
304
    exit (EXIT_FAILURE) ;
305
  }
306

    
307
  if ((password = malloc (strlen (argv [1]) + 1)) == NULL)
308
  {
309
    logMsg ("Out of memory") ;
310
    exit (EXIT_FAILURE) ;
311
  }
312
  strcpy (password, argv [1]) ;
313

    
314
// Wipe out the password on the command-line in a vague attempt to try to
315
//        hide it from snoopers
316

    
317
  for (p = argv [1] ; *p ; ++p)
318
    *p = ' ' ;
319

    
320
  setupSigHandler () ;
321
 
322
// Enter our big loop
323

    
324
  for (;;)
325
  {
326

    
327
    if (!doDaemon)
328
      printf ("-=-\nWaiting for a new connection...\n") ;
329

    
330
    if ((clientFd = setupServer (port)) < 0)
331
    {
332
      logMsg ("Unable to setup server: %s", strerror (errno)) ;
333
      exit (EXIT_FAILURE) ;
334
    }
335

    
336
    logMsg ("New connection from: %s.", getClientIP ()) ;
337

    
338
    if (!doDaemon)
339
      printf ("Sending Greeting.\n") ;
340

    
341
    if (sendGreeting (clientFd) < 0)
342
    {
343
      logMsg ("Unable to send greeting message: %s", strerror (errno)) ;
344
      closeServer (clientFd) ;
345
      continue ;
346
    }
347

    
348
    if (!doDaemon)
349
      printf ("Sending Challenge.\n") ;
350

    
351
    if (sendChallenge (clientFd) < 0)
352
    {
353
      logMsg ("Unable to send challenge message: %s", strerror (errno)) ;
354
      closeServer (clientFd) ;
355
      continue ;
356
    }
357

    
358
    if (!doDaemon)
359
      printf ("Waiting for response.\n") ;
360

    
361
    if (getResponse (clientFd) < 0)
362
    {
363
      logMsg ("Connection closed waiting for response: %s", strerror (errno)) ;
364
      closeServer (clientFd) ;
365
      continue ;
366
    }
367

    
368
    if (!passwordMatch (password))
369
    {
370
      logMsg ("Password failure") ;
371
      closeServer (clientFd) ;
372
      continue ;
373
    }
374

    
375
    logMsg ("Password OK - Starting") ;
376

    
377
    runRemoteCommands (clientFd) ;
378
    closeServer       (clientFd) ;
379
  }
380

    
381
  return 0 ;
382
}