For SNAT, don't store the pre-fragment L2 header before actions are applied.
[sliver-openvswitch.git] / utilities / ofp-kill.c
1 /* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
2  * Junior University
3  *
4  * We are making the OpenFlow specification and associated documentation
5  * (Software) available for public use and benefit with the expectation
6  * that others will use, modify and enhance the Software and contribute
7  * those enhancements back to the community. However, since we would
8  * like to make the Software available for broadest use, with as few
9  * restrictions as possible permission is hereby granted, free of
10  * charge, to any person obtaining a copy of this Software to deal in
11  * the Software under the copyrights without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27  * SOFTWARE.
28  *
29  * The name and trademarks of copyright holder(s) may NOT be used in
30  * advertising or publicity pertaining to the Software or any
31  * derivatives without specific, written prior permission.
32  */
33
34 #include <config.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <getopt.h>
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include "command-line.h"
43 #include "daemon.h"
44 #include "timeval.h"
45 #include "util.h"
46 #include "vlog.h"
47
48 /* -s, --signal: signal to send. */
49 static int sig_nr = SIGTERM;
50
51 /* -f, --force: ignore errors. */
52 static bool force;
53
54 static void cond_error(int err_no, const char *, ...) PRINTF_FORMAT(2, 3);
55
56 static void parse_options(int argc, char *argv[]);
57 static void usage(void);
58
59 int
60 main(int argc, char *argv[])
61 {
62     bool ok = true;
63     int i;
64
65     set_program_name(argv[0]);
66     time_init();
67     vlog_init();
68     parse_options(argc, argv);
69
70     argc -= optind;
71     argv += optind;
72     if (argc < 1) {
73         if (!force) {
74             ofp_fatal(0, "need at least one non-option argument; "
75                       "use --help for usage");
76         }
77     }
78
79     for (i = 0; i < argc; i++) {
80         char *pidfile;
81         pid_t pid;
82
83         pidfile = make_pidfile_name(argv[i]);
84         pid = read_pidfile(pidfile);
85         if (pid >= 0) {
86             if (kill(pid, sig_nr) < 0) {
87                 cond_error(errno, "%s: kill(%ld)", pidfile, (long int) pid);
88             }
89         } else {
90             cond_error(-pid, "could not read %s", pidfile);
91         }
92         free(pidfile);
93     }
94
95     return ok || force ? EXIT_SUCCESS : EXIT_FAILURE;
96 }
97
98 static void
99 parse_options(int argc, char *argv[])
100 {
101     static struct option long_options[] = {
102         {"signal",      required_argument, 0, 's'},
103         {"force",       no_argument, 0, 'f'},
104         {"help",        no_argument, 0, 'h'},
105         {"version",     no_argument, 0, 'V'},
106         {0, 0, 0, 0},
107     };
108     char *short_options = long_options_to_short_options(long_options);
109
110     for (;;) {
111         int c;
112
113         c = getopt_long(argc, argv, short_options, long_options, NULL);
114         if (c == -1) {
115             break;
116         }
117
118         switch (c) {
119         case 's':
120             if (atoi(optarg) || !strcmp(optarg, "0")) {
121                 sig_nr = atoi(optarg);
122             } else {
123                 struct signal_name {
124                     const char *name;
125                     int number;
126                 };
127
128                 static const struct signal_name signals[] = {
129 #define SIGNAL(NAME) { #NAME, NAME }
130                     SIGNAL(SIGABRT),
131                     SIGNAL(SIGALRM),
132                     SIGNAL(SIGBUS),
133                     SIGNAL(SIGCHLD),
134                     SIGNAL(SIGCONT),
135                     SIGNAL(SIGFPE),
136                     SIGNAL(SIGHUP),
137                     SIGNAL(SIGILL),
138                     SIGNAL(SIGINT),
139                     SIGNAL(SIGKILL),
140                     SIGNAL(SIGPIPE),
141                     SIGNAL(SIGQUIT),
142                     SIGNAL(SIGSEGV),
143                     SIGNAL(SIGSTOP),
144                     SIGNAL(SIGTERM),
145                     SIGNAL(SIGTSTP),
146                     SIGNAL(SIGTTIN),
147                     SIGNAL(SIGTTOU),
148                     SIGNAL(SIGUSR1),
149                     SIGNAL(SIGUSR2),
150 #ifdef SIGPOLL
151                     SIGNAL(SIGPOLL),
152 #endif
153                     SIGNAL(SIGPROF),
154                     SIGNAL(SIGSYS),
155                     SIGNAL(SIGTRAP),
156                     SIGNAL(SIGURG),
157                     SIGNAL(SIGVTALRM),
158                     SIGNAL(SIGXCPU),
159                     SIGNAL(SIGXFSZ),
160 #undef SIGNAL
161                 };
162                 int i;
163
164                 for (i = 0; i < ARRAY_SIZE(signals); i++) {
165                     const struct signal_name *s = &signals[i];
166                     if (!strcmp(optarg, s->name)
167                         || !strcmp(optarg, s->name + 3)) {
168                         sig_nr = s->number;
169                         goto got_name;
170                     }
171                 }
172                 ofp_fatal(0, "unknown signal \"%s\"", optarg);
173             got_name: ;
174             }
175             break;
176
177         case 'f':
178             force = true;
179             break;
180
181         case 'h':
182             usage();
183
184         case 'V':
185             printf("%s %s compiled "__DATE__" "__TIME__"\n",
186                    program_name, VERSION BUILDNR);
187             exit(EXIT_SUCCESS);
188
189         case '?':
190             exit(EXIT_FAILURE);
191
192         default:
193             abort();
194         }
195     }
196     free(short_options);
197 }
198
199 static void
200 usage(void)
201 {
202     printf("%s: kills a program using a pidfile\n"
203            "usage: %s [OPTIONS] PIDFILE [PIDFILE...]\n"
204            "where each PIDFILE is a pidfile created by an OpenFlow daemon.\n"
205            "\nOptions:\n"
206            "  -s, --signal=NUMBER|NAME  signal to send (default: TERM)\n"
207            "  -f, --force             ignore errors\n"
208            "  -h, --help              display this help message\n"
209            "  -V, --version           display version information\n",
210            program_name, program_name);
211     exit(EXIT_SUCCESS);
212 }
213
214 static void
215 cond_error(int err_no, const char *format, ...)
216 {
217     if (!force) {
218         va_list args;
219
220         fprintf(stderr, "%s: ", program_name);
221         va_start(args, format);
222         vfprintf(stderr, format, args);
223         va_end(args);
224         if (err_no != 0)
225             fprintf(stderr, " (%s)", strerror(err_no));
226         putc('\n', stderr);
227     }
228 }