1 | /* Copyright 1996 by the Massachusetts Institute of Technology. |
---|
2 | * |
---|
3 | * Permission to use, copy, modify, and distribute this |
---|
4 | * software and its documentation for any purpose and without |
---|
5 | * fee is hereby granted, provided that the above copyright |
---|
6 | * notice appear in all copies and that both that copyright |
---|
7 | * notice and this permission notice appear in supporting |
---|
8 | * documentation, and that the name of M.I.T. not be used in |
---|
9 | * advertising or publicity pertaining to distribution of the |
---|
10 | * software without specific, written prior permission. |
---|
11 | * M.I.T. makes no representations about the suitability of |
---|
12 | * this software for any purpose. It is provided "as is" |
---|
13 | * without express or implied warranty. |
---|
14 | */ |
---|
15 | |
---|
16 | /* This is the source for the upvers program, which runs the |
---|
17 | * appropriate scripts during the update process. |
---|
18 | */ |
---|
19 | |
---|
20 | static char rcsid[] = "$Id: upvers.c,v 1.16 1998-04-15 19:54:56 ghudson Exp $"; |
---|
21 | |
---|
22 | #include <sys/types.h> |
---|
23 | #include <stdio.h> |
---|
24 | #include <stdlib.h> |
---|
25 | #include <string.h> |
---|
26 | #include <dirent.h> |
---|
27 | |
---|
28 | struct verfile { |
---|
29 | int major; |
---|
30 | int minor; |
---|
31 | int patch; |
---|
32 | }; |
---|
33 | |
---|
34 | static int version_compare(const void *arg1, const void *arg2); |
---|
35 | static void usage(void); |
---|
36 | |
---|
37 | int main(int argc, char **argv) |
---|
38 | { |
---|
39 | struct verfile vf[1024], oldv, newv; |
---|
40 | DIR *dp; |
---|
41 | struct dirent *dirp; |
---|
42 | int n = 0, i, start, end; |
---|
43 | char command[1024], *args = "", scratch; |
---|
44 | int ch; |
---|
45 | extern int optind; |
---|
46 | extern char *optarg; |
---|
47 | |
---|
48 | while ((ch = getopt(argc, argv, "a:")) != -1) |
---|
49 | { |
---|
50 | switch (ch) |
---|
51 | { |
---|
52 | case 'a': |
---|
53 | args = optarg; |
---|
54 | break; |
---|
55 | default: |
---|
56 | usage(); |
---|
57 | } |
---|
58 | } |
---|
59 | argc -= optind; |
---|
60 | argv += optind; |
---|
61 | |
---|
62 | if (argc < 3) |
---|
63 | usage(); |
---|
64 | |
---|
65 | /* Parse old-vers and new-vers. */ |
---|
66 | if (sscanf(argv[0], "%d.%d.%d%c", &oldv.major, &oldv.minor, &oldv.patch, |
---|
67 | &scratch) != 3 |
---|
68 | || sscanf(argv[1], "%d.%d.%d%c", &newv.major, &newv.minor, |
---|
69 | &newv.patch, &scratch) != 3) |
---|
70 | { |
---|
71 | fprintf(stderr, "First two arguments must be dotted triplets.\n"); |
---|
72 | return 1; |
---|
73 | } |
---|
74 | |
---|
75 | /* Get the names of all the version files in libdir. */ |
---|
76 | dp = opendir(argv[2]); |
---|
77 | if (!dp) |
---|
78 | { |
---|
79 | perror("opendir"); |
---|
80 | return 1; |
---|
81 | } |
---|
82 | while (dirp = readdir(dp)) |
---|
83 | { |
---|
84 | if (sscanf(dirp->d_name, "%d.%d.%d%c", &vf[n].major, &vf[n].minor, |
---|
85 | &vf[n].patch, &scratch) == 3) |
---|
86 | n++; |
---|
87 | } |
---|
88 | closedir(dp); |
---|
89 | |
---|
90 | /* Sort the version files names and decide where to start and end at. */ |
---|
91 | qsort(vf, n, sizeof(struct verfile), version_compare); |
---|
92 | start = n + 1; |
---|
93 | end = n; |
---|
94 | for (i = 0; i < n; i++) |
---|
95 | { |
---|
96 | if (version_compare(&vf[i], &oldv) > 0 && start == n + 1) |
---|
97 | start = i; |
---|
98 | if (version_compare(&vf[i], &newv) > 0 && end == n) |
---|
99 | end = i; |
---|
100 | } |
---|
101 | |
---|
102 | /* Now run the appropriate files. */ |
---|
103 | for (i = start; i < end; i++) |
---|
104 | { |
---|
105 | sprintf(command, "%s/%d.%d.%d %s", argv[2], vf[i].major, vf[i].minor, |
---|
106 | vf[i].patch, args); |
---|
107 | printf("Running %s\n", command); |
---|
108 | fflush(stdout); |
---|
109 | system(command); |
---|
110 | } |
---|
111 | |
---|
112 | return 0; |
---|
113 | } |
---|
114 | |
---|
115 | static int version_compare(const void *arg1, const void *arg2) |
---|
116 | { |
---|
117 | const struct verfile *v1 = (const struct verfile *) arg1; |
---|
118 | const struct verfile *v2 = (const struct verfile *) arg2; |
---|
119 | |
---|
120 | /* Compare major version, then minor version, then patchlevel. */ |
---|
121 | return (v1->major != v2->major) ? v1->major - v2->major |
---|
122 | : (v1->minor != v2->minor) ? v1->minor - v2->minor |
---|
123 | : v1->patch - v2->patch; |
---|
124 | } |
---|
125 | |
---|
126 | static void usage(void) |
---|
127 | { |
---|
128 | fprintf(stderr, "Usage: upvers [-a arg] <old-vers> <new-vers> <libdir>\n"); |
---|
129 | exit(1); |
---|
130 | } |
---|