]>
Commit | Line | Data |
---|---|---|
6dbe3af9 KZ |
1 | /* |
2 | * A swapon(8)/swapoff(8) for Linux 0.99. | |
3 | * swapon.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp | |
fd6b7a7f | 4 | * Added '-s' (Summary option) <Vincent.Renardias@waw.com> 02/1997. |
6dbe3af9 KZ |
5 | */ |
6 | ||
fd6b7a7f KZ |
7 | #include <stdlib.h> |
8 | #include <stdio.h> | |
9 | #include <getopt.h> | |
10 | #include <string.h> | |
11 | #include <mntent.h> | |
12 | #include <errno.h> | |
5c36a0eb KZ |
13 | #include <sys/stat.h> |
14 | #include "swap_constants.h" | |
fd6b7a7f KZ |
15 | #include "swapargs.h" |
16 | ||
17 | #define streq(s, t) (strcmp ((s), (t)) == 0) | |
18 | ||
19 | #define _PATH_FSTAB "/etc/fstab" | |
20 | #define PROC_SWAPS "/proc/swaps" | |
21 | ||
5c36a0eb | 22 | #define SWAPON_NEEDS_TWO_ARGS |
6dbe3af9 KZ |
23 | |
24 | /* Nonzero for chatty (-v). This is a nonstandard flag (not in BSD). */ | |
25 | int verbose = 0; | |
726f69e2 | 26 | int priority = -1; /* non-prioritized swap by default */ |
6dbe3af9 KZ |
27 | |
28 | extern char version[]; | |
29 | static char *program_name; | |
30 | static struct option longopts[] = | |
31 | { | |
32 | { "all", 0, 0, 'a' }, | |
33 | { "help", 0, 0, 'h' }, | |
726f69e2 | 34 | { "priority", required_argument, 0, 'p' }, |
fd6b7a7f | 35 | { "summary", 0, 0, 's' }, |
6dbe3af9 KZ |
36 | { "verbose", 0, 0, 'v' }, |
37 | { "version", 0, 0, 'V' }, | |
38 | { NULL, 0, 0, 0 } | |
39 | }; | |
40 | ||
726f69e2 KZ |
41 | const char *usage_string = "\ |
42 | usage: %s [-hV]\n\ | |
43 | %s -a [-v]\n\ | |
44 | %s [-v] [-p priority] special ...\n\ | |
fd6b7a7f | 45 | %s [-s]\n\ |
726f69e2 | 46 | "; |
6dbe3af9 KZ |
47 | |
48 | static void | |
49 | usage (FILE *fp, int n) | |
50 | { | |
fd6b7a7f | 51 | fprintf (fp, usage_string, program_name, program_name, program_name, program_name); |
6dbe3af9 KZ |
52 | exit (n); |
53 | } | |
54 | ||
fd6b7a7f KZ |
55 | #ifdef SWAPON_HAS_TWO_ARGS |
56 | #define SWAPON_NEEDS_TWO_ARGS | |
57 | #endif | |
58 | ||
59 | #ifdef SWAPON_NEEDS_TWO_ARGS | |
60 | #ifdef SWAPON_HAS_TWO_ARGS | |
61 | /* libc is OK */ | |
62 | #include <unistd.h> | |
63 | #else | |
64 | /* We want a swapon with two args, but have an old libc. | |
65 | Build the kernel call by hand. */ | |
66 | #include <linux/unistd.h> | |
67 | static | |
68 | _syscall2(int, swapon, const char *, path, int, flags); | |
69 | static | |
70 | _syscall1(int, swapoff, const char *, path); | |
71 | #endif | |
726f69e2 | 72 | #else |
fd6b7a7f KZ |
73 | /* just do as libc says */ |
74 | #include <unistd.h> | |
726f69e2 | 75 | #endif |
fd6b7a7f KZ |
76 | |
77 | static int | |
78 | swap (const char *special, int prio) | |
6dbe3af9 KZ |
79 | { |
80 | int status; | |
5c36a0eb | 81 | struct stat st; |
6dbe3af9 KZ |
82 | |
83 | if (verbose) | |
5c36a0eb | 84 | printf("%s on %s\n", program_name, special); |
6dbe3af9 | 85 | |
726f69e2 | 86 | if (streq (program_name, "swapon")) { |
5c36a0eb KZ |
87 | if (stat(special, &st) < 0) { |
88 | fprintf (stderr, "swapon: cannot stat %s: %s\n", special, strerror (errno)); | |
89 | return -1; | |
90 | } | |
91 | ||
92 | if ((st.st_mode & 07077) != 0) { | |
93 | fprintf(stderr, "swapon: warning: %s has insecure permissions %04o, " | |
94 | "0600 suggested\n", special, st.st_mode & 07777); | |
95 | } | |
96 | ||
97 | /* test for holes by LBT */ | |
98 | if (S_ISREG(st.st_mode)) { | |
99 | if (st.st_blocks * 512 < st.st_size) { | |
100 | fprintf(stderr, | |
101 | "swapon: Skipping file %s - it appears to have holes.\n", | |
102 | special); | |
103 | return -1; | |
104 | } | |
105 | } | |
106 | ||
fd6b7a7f | 107 | #ifdef SWAPON_NEEDS_TWO_ARGS |
5c36a0eb | 108 | { |
fd6b7a7f KZ |
109 | int flags = 0; |
110 | ||
111 | #ifdef SWAP_FLAG_PREFER | |
726f69e2 | 112 | if (prio >= 0) { |
fd6b7a7f KZ |
113 | if (prio > SWAP_FLAG_PRIO_MASK) |
114 | prio = SWAP_FLAG_PRIO_MASK; | |
726f69e2 KZ |
115 | flags = SWAP_FLAG_PREFER |
116 | | ((prio & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT); | |
117 | } | |
fd6b7a7f | 118 | #endif |
726f69e2 | 119 | status = swapon (special, flags); |
5c36a0eb | 120 | } |
726f69e2 KZ |
121 | #else |
122 | status = swapon (special); | |
123 | #endif | |
124 | } else | |
125 | status = swapoff (special); | |
6dbe3af9 KZ |
126 | |
127 | if (status < 0) | |
128 | fprintf (stderr, "%s: %s: %s\n", program_name, special, strerror (errno)); | |
129 | ||
130 | return status; | |
131 | } | |
132 | ||
fd6b7a7f KZ |
133 | static int |
134 | display_summary(void) | |
135 | { | |
136 | FILE *swaps; | |
137 | char line[200] ; | |
138 | ||
139 | if ((swaps = fopen(PROC_SWAPS, "r")) == NULL) { | |
140 | fprintf (stderr, "%s: %s: %s\n", program_name, PROC_SWAPS, | |
141 | strerror (errno)); | |
142 | return -1 ; | |
143 | } | |
144 | while ( fgets(line, sizeof(line), swaps)) | |
145 | printf ("%s", line); | |
146 | ||
147 | return 0 ; | |
148 | } | |
149 | ||
6dbe3af9 KZ |
150 | int |
151 | main (int argc, char *argv[]) | |
152 | { | |
fd6b7a7f | 153 | struct mntent *fstab; |
6dbe3af9 KZ |
154 | int status; |
155 | int all = 0; | |
156 | int c; | |
157 | ||
158 | if (strrchr (argv[0], '/') != NULL) | |
159 | program_name = strrchr (argv[0], '/') + 1; | |
160 | else | |
161 | program_name = argv[0]; | |
162 | ||
fd6b7a7f | 163 | while ((c = getopt_long (argc, argv, "ahp:svV", longopts, NULL)) != EOF) |
6dbe3af9 KZ |
164 | switch (c) |
165 | { | |
166 | case 'a': /* all */ | |
167 | ++all; | |
168 | break; | |
169 | case 'h': /* help */ | |
170 | usage (stdout, 0); | |
171 | break; | |
726f69e2 KZ |
172 | case 'p': /* priority */ |
173 | priority = atoi(optarg); | |
174 | break; | |
fd6b7a7f KZ |
175 | case 's': /* tell about current use of swap areas */ |
176 | status = display_summary(); | |
177 | exit(status); | |
6dbe3af9 KZ |
178 | case 'v': /* be chatty */ |
179 | ++verbose; | |
180 | break; | |
181 | case 'V': /* version */ | |
fd6b7a7f | 182 | printf ("%s: %s\n", program_name, version); |
6dbe3af9 KZ |
183 | exit (0); |
184 | case 0: | |
185 | break; | |
186 | case '?': | |
187 | default: | |
188 | usage (stderr, 1); | |
189 | } | |
190 | ||
191 | argv += optind; | |
192 | ||
193 | status = 0; | |
194 | ||
fd6b7a7f KZ |
195 | if (all) { |
196 | FILE *fp = setmntent(_PATH_FSTAB, "r"); | |
197 | if (fp == NULL) { | |
198 | fprintf(stderr, "%s: cannot open %s: %s\n", program_name, | |
199 | _PATH_FSTAB, strerror(errno)); | |
200 | exit(2); | |
201 | } | |
202 | while ((fstab = getmntent(fp)) != NULL) { | |
203 | if (streq (fstab->mnt_type, MNTTYPE_SWAP)) { | |
204 | /* parse mount options; */ | |
205 | char *opt, *opts = strdup(fstab->mnt_opts); | |
726f69e2 | 206 | |
fd6b7a7f KZ |
207 | for (opt = strtok (opts, ","); opt != NULL; |
208 | opt = strtok (NULL, ",")) | |
209 | if (strncmp(opt, "pri=", 4) == 0) | |
210 | priority = atoi(opt+4); | |
211 | status |= swap (fstab->mnt_fsname, priority); | |
212 | } | |
726f69e2 | 213 | } |
fd6b7a7f KZ |
214 | } else if (*argv == NULL) { |
215 | usage (stderr, 2); | |
216 | } else { | |
217 | while (*argv != NULL) | |
218 | status |= swap (*argv++,priority); | |
219 | } | |
6dbe3af9 KZ |
220 | return status; |
221 | } |