2.3.3-78
[glibc.git] / fedora / glibc_post_upgrade.c
blobdf151e3cd3772e1a59ccf38b7efcdc6a28e2cefb
1 #if defined __sparc__ && defined __arch64__
2 register void *__thread_self __asm ("g7");
3 #endif
4 #include <sys/types.h>
5 #include <sys/wait.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <sys/time.h>
10 #include <dirent.h>
11 #include <stddef.h>
12 #include <fcntl.h>
13 #include <string.h>
14 #include <sys/stat.h>
16 #define verbose_exec(failcode, path...) \
17 do \
18 { \
19 char *const arr[] = { path, NULL }; \
20 vexec (failcode, arr); \
21 } while (0)
23 __attribute__((noinline)) void vexec (int failcode, char *const path[]);
24 __attribute__((noinline)) void says (const char *str);
25 __attribute__((noinline)) void sayn (long num);
26 __attribute__((noinline)) void message (char *const path[]);
28 int
29 main (void)
31 int rerun_ldconfig = 0, rerun_cnt = 0;
32 char initpath[256];
34 #ifdef __i386__
35 char buffer[4096];
36 struct pref {
37 char *p;
38 int len;
39 } prefix[] = { { "libc-", 5 }, { "libm-", 5 },
40 { "librt-", 6 }, { "libpthread-", 11 },
41 { "librtkaio-", 10 }, { "libthread_db-", 13 } };
42 int i, j, fd;
43 off_t base;
44 ssize_t ret;
45 #ifdef ARCH_386
46 const char *remove_dirs[] = { "/lib/i686", "/lib/tls" };
47 #else
48 const char *remove_dirs[] = { "/lib/tls/i686" };
49 #endif
50 for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
52 size_t rmlen = strlen (remove_dirs[j]);
53 fd = open (remove_dirs[j], O_RDONLY);
54 if (fd >= 0
55 && (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
56 >= (ssize_t) offsetof (struct dirent, d_name))
58 for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
60 struct dirent *d = (struct dirent *) (buffer + base);
62 for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
63 if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
65 char *p = d->d_name + prefix[i].len;
67 while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
68 if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
69 && p + 3 - d->d_name
70 < sizeof (initpath) - rmlen - 1)
72 memcpy (initpath, remove_dirs[j], rmlen);
73 initpath[rmlen] = '/';
74 strcpy (initpath + rmlen + 1, d->d_name);
75 unlink (initpath);
76 break;
79 base += d->d_reclen;
81 close (fd);
84 #endif
86 int ldsocfd = open (LD_SO_CONF, O_RDONLY);
87 struct stat ldsocst;
88 if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
90 char p[ldsocst.st_size + 1];
91 if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
93 p[ldsocst.st_size] = '\0';
94 if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
96 close (ldsocfd);
97 ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
98 if (ldsocfd >= 0)
100 size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
101 if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
102 != slen
103 || write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
104 _exit (109);
108 if (ldsocfd >= 0)
109 close (ldsocfd);
114 char linkbuf[64], *linkp;
115 int linklen;
117 verbose_exec (110, "/sbin/ldconfig", "/sbin/ldconfig");
119 rerun_ldconfig = 0;
120 #ifdef LIBTLS
121 linkp = linkbuf + strlen (LIBTLS);
122 linklen = readlink (LIBTLS "librt.so.1", linkp,
123 sizeof (linkbuf) - 1 - strlen (LIBTLS));
124 if (linklen == strlen ("librtkaio-2.3.X.so")
125 && memcmp (linkp, "librtkaio-2.3.", 14) == 0
126 && strchr ("23", linkp[14])
127 && memcmp (linkp + 15, ".so", 4) == 0)
129 memcpy (linkbuf, LIBTLS, strlen (LIBTLS));
130 unlink (linkbuf);
131 rerun_ldconfig = 1;
133 #endif
135 #ifdef __i386__
136 linkp = linkbuf + strlen ("/lib/i686/");
137 linklen = readlink ("/lib/i686/librt.so.1", linkp,
138 sizeof (linkbuf) - 1 - strlen ("/lib/i686/"));
139 if (linklen == strlen ("librtkaio-2.3.X.so")
140 && memcmp (linkp, "librtkaio-2.3.", 14) == 0
141 && strchr ("23", linkp[14])
142 && memcmp (linkp + 15, ".so", 4) == 0)
144 memcpy (linkbuf, "/lib/i686/", strlen ("/lib/i686/"));
145 unlink (linkbuf);
146 rerun_ldconfig = 1;
148 #endif
150 while (rerun_ldconfig && ++rerun_cnt < 2);
152 if (! utimes (GCONV_MODULES_CACHE, NULL))
154 verbose_exec (113, "/usr/sbin/iconvconfig", "/usr/sbin/iconvconfig");
157 /* Check if telinit is available and the init fifo as well. */
158 if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
159 _exit (0);
160 /* Check if we are not inside of some chroot, because we'd just
161 timeout and leave /etc/initrunlvl. */
162 if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
163 readlink ("/proc/1/root", initpath, 256) <= 0)
164 _exit (0);
166 verbose_exec (116, "/sbin/telinit", "/sbin/telinit", "u");
168 /* Check if we can safely condrestart sshd. */
169 if (access ("/sbin/service", X_OK) == 0
170 && access ("/usr/sbin/sshd", X_OK) == 0
171 && access ("/bin/bash", X_OK) == 0)
173 verbose_exec (121, "/sbin/service", "/sbin/service", "sshd", "condrestart");
176 _exit(0);
179 int __libc_multiple_threads __attribute__((nocommon));
180 int __libc_enable_asynccancel (void) { return 0; }
181 void __libc_disable_asynccancel (int x) { }
182 void __libc_csu_init (void) { }
183 void __libc_csu_fini (void) { }
184 pid_t __fork (void) { return -1; }
185 char thr_buf[65536];
187 #ifndef __powerpc__
189 __libc_start_main (int (*main) (void), int argc, char **argv,
190 void (*init) (void), void (*fini) (void),
191 void (*rtld_fini) (void), void * stack_end)
192 #else
193 struct startup_info
195 void *sda_base;
196 int (*main) (int, char **, char **, void *);
197 int (*init) (int, char **, char **, void *);
198 void (*fini) (void);
202 __libc_start_main (int argc, char **ubp_av, char **ubp_ev,
203 void *auxvec, void (*rtld_fini) (void),
204 struct startup_info *stinfo,
205 char **stack_on_entry)
206 #endif
208 #if defined __ia64__ || defined __powerpc64__
209 register void *r13 __asm ("r13") = thr_buf + 32768;
210 __asm ("" : : "r" (r13));
211 #elif defined __sparc__
212 register void *g6 __asm ("g6") = thr_buf + 32768;
213 # ifdef __arch64__
214 __thread_self = thr_buf + 32768;
215 # else
216 register void *__thread_self __asm ("g7") = thr_buf + 32768;
217 # endif
218 __asm ("" : : "r" (g6), "r" (__thread_self));
219 #elif defined __s390__ && !defined __s390x__
220 __asm ("sar %%a0,%0" : : "d" (thr_buf + 32768));
221 #elif defined __s390x__
222 __asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 32768) : "0");
223 #elif defined __powerpc__ && !defined __powerpc64__
224 register void *r2 __asm ("r2") = thr_buf + 32768;
225 __asm ("" : : "r" (r2));
226 #endif
227 main();
228 return 0;
231 void
232 vexec (int failcode, char *const path[])
234 pid_t pid;
235 int status, save_errno;
237 pid = vfork ();
238 if (pid == 0)
240 execv (path[0], path + 1);
241 save_errno = errno;
242 message (path);
243 says (" exec failed with errno ");
244 sayn (save_errno);
245 says ("\n");
246 _exit (failcode);
248 else if (pid < 0)
250 save_errno = errno;
251 message (path);
252 says (" fork failed with errno ");
253 sayn (save_errno);
254 says ("\n");
255 _exit (failcode + 1);
257 if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
259 message (path);
260 says (" child terminated abnormally\n");
261 _exit (failcode + 2);
263 if (WEXITSTATUS (status))
265 message (path);
266 says (" child exited with exit code ");
267 sayn (WEXITSTATUS (status));
268 says ("\n");
269 _exit (WEXITSTATUS (status));
273 void
274 says (const char *str)
276 write (1, str, strlen (str));
279 void
280 sayn (long num)
282 char string[sizeof (long) * 3 + 1];
283 char *p = string + sizeof (string) - 1;
285 *p = '\0';
286 if (num == 0)
287 *--p = '0';
288 else
289 while (num)
291 *--p = '0' + num % 10;
292 num = num / 10;
295 says (p);
298 void
299 message (char *const path[])
301 says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
302 says (path[0]);