1 /***************************************************************************/
2 /* This code is part of WWW grabber called pavuk */
3 /* Copyright (c) 1997 - 2001 Stefan Ondrejicka */
4 /* Distributed under GPL 2 or later */
5 /***************************************************************************/
6
7 #include "config.h"
8
9 #include <stdio.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <string.h>
16 #include <dirent.h>
17 #include <limits.h>
18 #include <utime.h>
19
20 #include "tools.h"
21 #include "url.h"
22 #include "doc.h"
23 #include "html.h"
24 #include "gui_api.h"
25 #include "update_links.h"
26
27 static void rewrite_links(char *);
28
update_links(char * dirname)29 void update_links(char *dirname)
30 {
31 DIR *dir;
32 struct dirent *dent;
33 char next_dir[PATH_MAX];
34 struct stat estat;
35
36 xprintf(1, gettext("Entering directory %s\n"), dirname);
37 if(!(dir = opendir(dirname)))
38 {
39 xperror(dirname);
40 return;
41 }
42
43 while((dent = readdir(dir)))
44 {
45 _Xt_Serve;
46
47 sprintf(next_dir, "%s/%s", dirname, dent->d_name);
48 if(!strcmp(dent->d_name, "."))
49 continue;
50 if(!strcmp(dent->d_name, ".."))
51 continue;
52 if(stat(next_dir, &estat))
53 {
54 xperror(next_dir);
55 continue;
56 }
57
58 if(S_ISDIR(estat.st_mode))
59 {
60 if(!strcmp(dent->d_name, ".pavuk_info") && cfg.enable_info)
61 continue;
62
63 update_links(next_dir);
64 }
65 else if(file_is_html(next_dir))
66 {
67 xprintf(1, gettext("Relocating %s\n"), next_dir);
68 rewrite_links(next_dir);
69 }
70 else
71 xprintf(1, gettext("Omitting %s\n"), next_dir);
72 #ifdef I_FACE
73 if(cfg.xi_face)
74 {
75 if(cfg.rbreak || cfg.stop)
76 {
77 closedir(dir);
78 return;
79 }
80 }
81 #endif
82 }
83
84 closedir(dir);
85 xprintf(1, gettext("Leaving directory %s\n"), dirname);
86 }
87
rewrite_links(char * fn)88 static void rewrite_links(char *fn)
89 {
90 char pom[2048];
91 char *savetmp, *p;
92 int sock;
93 doc pdoc;
94 struct stat estat;
95 struct utimbuf ut;
96 url dum;
97
98 if(stat(fn, &estat) == 0)
99 {
100 if(S_ISDIR(estat.st_mode))
101 {
102 xprintf(1, gettext("Can't open directory %s\n"), fn);
103 return;
104 }
105 }
106
107 ut.actime = estat.st_atime;
108 ut.modtime = estat.st_mtime;
109
110 memset(&dum, '\0', sizeof(url));
111 dum.type = URLT_FILE;
112 dum.p.file.filename = fn;
113 dum.local_name = fn;
114 if(!strcasecmp(tl_get_extension(fn), "css"))
115 dum.status = URL_STYLE;
116 else
117 dum.status = 0;
118
119 doc_init(&pdoc, &dum);
120
121 doc_download(&pdoc, 1, TRUE);
122
123 _free(pdoc.mime);
124
125 html_process_parent_document(&pdoc, NULL, NULL);
126
127 strcpy(pom, fn);
128 p = strrchr(pom, '/');
129 sprintf(p + 1, "._lnkupd%d", (int) getpid());
130 savetmp = tl_strdup(pom);
131 rename(fn, savetmp);
132
133 if((sock = open(fn, O_BINARY | O_TRUNC | O_CREAT | O_WRONLY, 0644)) < 0)
134 {
135 xperror(fn);
136 rename(savetmp, fn);
137 free(savetmp);
138 free(pdoc.contents);
139 doc_remove_lock(&pdoc);
140 return;
141 }
142 if(write(sock, pdoc.contents, pdoc.size) != pdoc.size)
143 {
144 xperror(fn);
145 close(sock);
146 rename(savetmp, fn);
147 free(savetmp);
148 free(pdoc.contents);
149 doc_remove_lock(&pdoc);
150 return;
151 }
152 close(sock);
153 utime(fn, &ut);
154 unlink(savetmp);
155 free(savetmp);
156 free(pdoc.contents);
157 doc_remove_lock(&pdoc);
158 }
159