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