00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include <fcntl.h>
00010 #include <sys/uio.h>
00011 #include <sys/mman.h>
00012 
00013 
00014 #include "global.h"
00015 #include "est_ops.h"
00016 #include "helper.h"
00017 #include "url.h"
00018 #include "status.h"
00019 #include "resolve.h"
00020 #include "waa.h"
00021 #include "hash_ops.h"
00022 #include "actions.h"
00023 
00024 
00052 int res__mark_conflict(struct estat *sts, ...)
00053 {
00054     int status;
00055     char *filename;
00056     va_list va;
00057     int filehdl;
00058     int len;
00059     struct iovec io[2] = { { 0 }, { .iov_base="\n", .iov_len=1 } };
00060 
00061 
00062     status=0;
00063     va_start(va, sts);
00064     filehdl=-1;
00065 
00066     STOPIF( ops__build_path(&filename, sts), NULL);
00067     STOPIF( waa__open_byext(filename, WAA__CONFLICT_EXT, 
00068                 (sts->flags & RF_CONFLICT) ? WAA__APPEND : WAA__WRITE,
00069                 &   filehdl), NULL );
00070 
00071     while ( (filename =va_arg(va, char*)) )
00072     {
00073         len=strlen(filename);
00074 
00075         io[0].iov_base=filename;
00076         
00077         io[0].iov_len=len+1;
00078         STOPIF_CODE_ERR( writev(filehdl, io, sizeof(io)/sizeof(io[0])) != len+1+1,
00079                 errno, "Writing the conflict list for %s", filename);
00080     }
00081 
00082     sts->flags |= RF_CONFLICT;
00083 
00084 ex:
00085     if (filehdl != -1)
00086     {
00087         len=waa__close(filehdl, status);
00088         filehdl=-1;
00089         STOPIF_CODE_ERR( !status && len==-1, errno,
00090                 "Closing the conflict list for %s", filename);
00091     }
00092     return status;
00093 }
00094 
00095 
00098 int res__action(struct estat *sts)
00099 {
00100     int status;
00101 
00102     status=0;
00103     if (sts->flags & RF_ISNEW)
00104     {
00105         
00106 
00107         sts->to_be_ignored=1;
00108     }
00109     else
00110     {
00111         if ( sts->flags & RF_CONFLICT )
00112             STOPIF( res__remove_aux_files(sts), NULL);
00113         STOPIF( st__status(sts), NULL);
00114     }
00115 
00116 ex:
00117     return status;
00118 }
00119 
00120 
00123 int res__remove_aux_files(struct estat *sts)
00124 {
00125     int status;
00126     char *filename, *to_remove;
00127     int filehdl;
00128     int len;
00129     char *mapped;
00130     struct sstat_t st;
00131 
00132 
00133     status=0;
00134     filehdl=-1;
00135     mapped=MAP_FAILED;
00136 
00137     STOPIF( ops__build_path(&filename, sts), NULL);
00138     STOPIF( waa__open_byext(filename, WAA__CONFLICT_EXT, 
00139                 WAA__READ, &filehdl), NULL );
00140 
00141     STOPIF( hlp__fstat( filehdl, &st), NULL);
00142 
00143     mapped=mmap(NULL, st.size, PROT_READ, MAP_SHARED, filehdl, 0);
00144     STOPIF_CODE_ERR( mapped==MAP_FAILED, errno, 
00145             "Can't map handle %d", filehdl);
00146 
00147     to_remove=mapped;
00148     while ( to_remove - mapped != st.size )
00149     {
00150         BUG_ON(to_remove - mapped > st.size);
00151 
00152         if (unlink(to_remove) == -1)
00153             STOPIF_CODE_ERR( errno != ENOENT, errno,
00154                     "Cannot remove conflict file \"%s\" (from \"%s\")",
00155                     to_remove, filename);
00156 
00157         to_remove += strlen(to_remove)+1;
00158         if (*to_remove == '\n') to_remove++;
00159     }
00160 
00161     sts->flags &= ~RF_CONFLICT;
00162 
00163     STOPIF( waa__delete_byext(filename, WAA__CONFLICT_EXT, 0), NULL);
00164 
00165 ex:
00166     if (filehdl != -1)
00167     {
00168         len=waa__close(filehdl, status);
00169         filehdl=-1;
00170         STOPIF_CODE_ERR( !status && len==-1, errno,
00171                 "Closing the conflict list for %s", filename);
00172     }
00173 
00174     if (mapped != MAP_FAILED)
00175         STOPIF_CODE_ERR( munmap(mapped, st.size) == -1, errno,
00176                 "Cannot munmap()");
00177 
00178     return status;
00179 }
00180 
00181 
00184 int res__work(struct estat *root, int argc, char *argv[])
00185 {
00186     int status;
00187     char **normalized;
00188 
00189 
00190     status=0;
00191     
00192     opt_recursive=-1;
00193 
00194     STOPIF( waa__find_common_base(argc, argv, &normalized), NULL);
00195     if (argc == 0) ac__Usage_this();
00196 
00197     STOPIF( url__load_nonempty_list(NULL, 0), NULL);
00198 
00199     
00200 
00201 
00202 
00203     status=waa__read_or_build_tree(root, argc, normalized, argv, NULL, 1);
00204     if (status == -ENOENT)
00205         STOPIF(status, "!No data about current entries is available.");
00206     STOPIF(status, NULL);
00207 
00208     STOPIF( waa__output_tree(root), NULL);
00209 
00210 ex:
00211     return status;
00212 }
00213