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