Back to index

nordugrid-arc-nox  1.1.0~rc6
info_files.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 /*
00006  routines to work with informational files
00007 */
00008 
00009 #include <string>
00010 #include <list>
00011 #include <iostream>
00012 #include <fstream>
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include <unistd.h>
00016 #include <dirent.h>
00017 #include <fcntl.h>
00018 #include <errno.h>
00019 #include <limits>
00020 
00021 #include <arc/StringConv.h>
00022 #include <arc/DateTime.h>
00023 #include "../files/delete.h"
00024 #include "../misc/escaped.h"
00025 
00026 #include "../run/run_function.h"
00027 #include "../run/run_redirected.h"
00028 
00029 #include "../conf/conf.h"
00030 //@ #include <arc/certificate.h>
00031 #include "info_types.h"
00032 #include "info_files.h"
00033 
00034 #if defined __GNUC__ && __GNUC__ >= 3
00035 
00036 #define istream_readline(__f,__s,__n) {      \
00037    __f.get(__s,__n,__f.widen('\n'));         \
00038    if(__f.fail()) __f.clear();               \
00039    __f.ignore(std::numeric_limits<std::streamsize>::max(), __f.widen('\n')); \
00040 }
00041 
00042 #else
00043 
00044 #define istream_readline(__f,__s,__n) {      \
00045    __f.get(__s,__n,'\n');         \
00046    if(__f.fail()) __f.clear();               \
00047    __f.ignore(INT_MAX,'\n'); \
00048 }
00049 
00050 #endif
00051 
00052 
00053 const char * const sfx_failed      = ".failed";
00054 const char * const sfx_cancel      = ".cancel";
00055 const char * const sfx_restart     = ".restart";
00056 const char * const sfx_clean       = ".clean";
00057 const char * const sfx_status      = ".status";
00058 const char * const sfx_local       = ".local";
00059 const char * const sfx_errors      = ".errors";
00060 const char * const sfx_rsl         = ".description";
00061 const char * const sfx_diag        = ".diag";
00062 const char * const sfx_lrmsoutput  = ".comment";
00063 const char * const sfx_diskusage   = ".disk";
00064 const char * const sfx_acl         = ".acl";
00065 const char * const sfx_proxy         = ".proxy";
00066 
00067 static Arc::Logger& logger = Arc::Logger::getRootLogger();
00068 
00069 bool fix_file_permissions(const std::string &fname,bool executable) {
00070   mode_t mode = S_IRUSR | S_IWUSR;
00071   if(executable) { mode |= S_IXUSR; };
00072   return (chmod(fname.c_str(),mode) == 0);
00073 }
00074 
00075 static bool fix_file_permissions(const std::string &fname,const JobUser &user) {
00076   mode_t mode = S_IRUSR | S_IWUSR;
00077   if(user.ShareLevel() == JobUser::jobinfo_share_group) {
00078     mode |= S_IRGRP;
00079   } else if(user.ShareLevel() == JobUser::jobinfo_share_all) {
00080     mode |= S_IRGRP | S_IROTH;
00081   };
00082   return (chmod(fname.c_str(),mode) == 0);
00083 }
00084 
00085 bool fix_file_owner(const std::string &fname,const JobUser &user) {
00086   if(getuid() == 0) {
00087     if(lchown(fname.c_str(),user.get_uid(),user.get_gid()) == -1) {
00088       logger.msg(Arc::ERROR,"Failed setting file owner: %s",fname);
00089       return false;
00090     };
00091   };
00092   return true;
00093 }
00094 
00095 bool fix_file_owner(const std::string &fname,const JobDescription &desc,const JobUser &user) {
00096   if(getuid() == 0) {
00097     uid_t uid = desc.get_uid();
00098     gid_t gid = desc.get_gid();
00099     if( uid == 0 ) {
00100       uid=user.get_uid(); gid=user.get_gid();
00101     };
00102     if(lchown(fname.c_str(),uid,gid) == -1) {
00103       logger.msg(Arc::ERROR,"Failed setting file owner: %s",fname);
00104       return false;
00105     };
00106   };
00107   return true;
00108 }
00109 
00110 bool check_file_owner(const std::string &fname,const JobUser &user) {
00111   uid_t uid;
00112   gid_t gid;
00113   time_t t;
00114   return check_file_owner(fname,user,uid,gid,t);
00115 }
00116 
00117 bool check_file_owner(const std::string &fname,const JobUser &user,uid_t &uid,gid_t &gid) {
00118   time_t t;
00119   return check_file_owner(fname,user,uid,gid,t);
00120 }
00121 
00122 bool check_file_owner(const std::string &fname,const JobUser &user,uid_t &uid,gid_t &gid,time_t &t) {
00123   struct stat st;
00124   if(lstat(fname.c_str(),&st) != 0) return false;
00125   if(!S_ISREG(st.st_mode)) return false;
00126   uid=st.st_uid; gid=st.st_gid; t=st.st_ctime;
00127   /* superuser can't run jobs */
00128   if(uid == 0) return false;
00129   /* accept any file if superuser */
00130   if(user.get_uid() != 0) {
00131     if(uid != user.get_uid()) return false;
00132   };
00133   return true;
00134 }
00135 
00136 bool job_lrms_mark_put(const JobDescription &desc,JobUser &user,int code) {
00137   LRMSResult r(code);
00138   return job_lrms_mark_put(desc,user,r);
00139 }
00140 
00141 bool job_lrms_mark_put(const JobDescription &desc,JobUser &user,LRMSResult r) {
00142   std::string fname = user.ControlDir()+"/job."+desc.get_id()+".lrms_done";
00143   std::string content = Arc::tostring(r.code());
00144   content+=" ";
00145   content+=r.description();
00146   return job_mark_write_s(fname,content) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00147 }
00148 
00149 bool job_lrms_mark_check(JobId &id,JobUser &user) {
00150   std::string fname = user.ControlDir() + "/job." + id + ".lrms_done";
00151   return job_mark_check(fname);
00152 }
00153 
00154 bool job_lrms_mark_remove(JobId &id,JobUser &user) {
00155   std::string fname = user.ControlDir() + "/job." + id + ".lrms_done";
00156   return job_mark_remove(fname);
00157 }
00158 
00159 LRMSResult job_lrms_mark_read(JobId &id,JobUser &user) {
00160   std::string fname = user.ControlDir() + "/job." + id + ".lrms_done";
00161   LRMSResult r("-1 Internal error");
00162   std::ifstream f(fname.c_str()); if(! f.is_open() ) return r;
00163   f>>r;
00164   return r;
00165 }
00166 
00167 bool job_cancel_mark_put(const JobDescription &desc,JobUser &user) {
00168   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_cancel;
00169   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00170 }
00171 
00172 bool job_cancel_mark_check(JobId &id,JobUser &user) {
00173   std::string fname = user.ControlDir() + "/job." + id + sfx_cancel;
00174   return job_mark_check(fname);
00175 }
00176 
00177 bool job_cancel_mark_remove(JobId &id,JobUser &user) {
00178   std::string fname = user.ControlDir() + "/job." + id + sfx_cancel;
00179   return job_mark_remove(fname);
00180 }
00181 
00182 bool job_restart_mark_put(const JobDescription &desc,JobUser &user) {
00183   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_restart;
00184   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00185 }
00186 
00187 bool job_restart_mark_check(JobId &id,JobUser &user) {
00188   std::string fname = user.ControlDir() + "/job." + id + sfx_restart;
00189   return job_mark_check(fname);
00190 }
00191 
00192 bool job_restart_mark_remove(JobId &id,JobUser &user) {
00193   std::string fname = user.ControlDir() + "/job." + id + sfx_restart;
00194   return job_mark_remove(fname);
00195 }
00196 
00197 bool job_clean_mark_put(const JobDescription &desc,JobUser &user) {
00198   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_clean;
00199   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00200 }
00201 
00202 bool job_clean_mark_check(JobId &id,JobUser &user) {
00203   std::string fname = user.ControlDir() + "/job." + id + sfx_clean;
00204   return job_mark_check(fname);
00205 }
00206 
00207 bool job_clean_mark_remove(JobId &id,JobUser &user) {
00208   std::string fname = user.ControlDir() + "/job." + id + sfx_clean;
00209   return job_mark_remove(fname);
00210 }
00211 
00212 bool job_errors_mark_put(const JobDescription &desc,JobUser &user) {
00213   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_errors;
00214   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00215 }
00216 
00217 bool job_failed_mark_put(const JobDescription &desc,JobUser &user,const std::string &content) {
00218   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_failed;
00219   if(job_mark_size(fname) > 0) return true;
00220   return job_mark_write_s(fname,content) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname,user);
00221 }
00222 
00223 bool job_failed_mark_add(const JobDescription &desc,JobUser &user,const std::string &content) {
00224   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_failed;
00225   return job_mark_add_s(fname,content) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname,user);
00226 }
00227 
00228 bool job_failed_mark_check(const JobId &id,JobUser &user) {
00229   std::string fname = user.ControlDir() + "/job." + id + sfx_failed;
00230   return job_mark_check(fname);
00231 }
00232 
00233 bool job_failed_mark_remove(const JobId &id,JobUser &user) {
00234   std::string fname = user.ControlDir() + "/job." + id + sfx_failed;
00235   return job_mark_remove(fname);
00236 }
00237 
00238 std::string job_failed_mark_read(const JobId &id,JobUser &user) {
00239   std::string fname = user.ControlDir() + "/job." + id + sfx_failed;
00240   return job_mark_read_s(fname);
00241 }
00242 
00243 static int job_mark_put_callback(void* arg) {
00244   std::string& fname = *((std::string*)arg);
00245   if(job_mark_put(fname) & fix_file_permissions(fname)) return 0;
00246   return -1;
00247 }
00248 
00249 static int job_mark_remove_callback(void* arg) {
00250   std::string& fname = *((std::string*)arg);
00251   if(job_mark_remove(fname)) return 0;
00252   return -1;
00253 }
00254 
00255 static int job_dir_create_callback(void* arg) {
00256   std::string& dname = *((std::string*)arg);
00257   if(job_dir_create(dname) & fix_file_permissions(dname,true)) return 0;
00258   return -1;
00259 }
00260 
00261 typedef struct {
00262   const std::string* fname;
00263   const std::string* content;
00264 } job_mark_add_t;
00265 
00266 static int job_mark_add_callback(void* arg) {
00267   const std::string& fname = *(((job_mark_add_t*)arg)->fname);
00268   const std::string& content = *(((job_mark_add_t*)arg)->content);
00269   if(job_mark_add_s(fname,content) & fix_file_permissions(fname)) return 0;
00270   return -1;
00271 }
00272 
00273 typedef struct {
00274   const std::string* dname;
00275   const std::list<FileData>* flist;
00276 } job_dir_remove_t;
00277 
00278 static int job_dir_remove_callback(void* arg) {
00279   const std::string& dname = *(((job_dir_remove_t*)arg)->dname);
00280   const std::list<FileData>& flist = *(((job_dir_remove_t*)arg)->flist);
00281   delete_all_files(dname,flist,true);
00282   remove(dname.c_str());
00283   return 0;
00284 }
00285 
00286 bool job_diagnostics_mark_put(const JobDescription &desc,JobUser &user) {
00287   std::string fname = desc.SessionDir() + sfx_diag;
00288   if(user.StrictSession()) {
00289     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00290     return (RunFunction::run(tmp_user,"job_diagnostics_mark_put",&job_mark_put_callback,&fname,10) == 0);
00291   };
00292   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00293 }
00294 
00295 bool job_session_create(const JobDescription &desc,JobUser &user) {
00296   std::string dname = desc.SessionDir();
00297   if(user.StrictSession()) {
00298     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00299     return (RunFunction::run(tmp_user,"job_session_create",&job_dir_create_callback,&dname,10) == 0);
00300   };
00301   return job_dir_create(dname) & fix_file_owner(dname,desc,user) & fix_file_permissions(dname,true);
00302 }
00303 
00304 bool job_controldiag_mark_put(const JobDescription &desc,JobUser &user,char const * const args[]) {
00305   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_diag;
00306   if(!job_mark_put(fname)) return false;
00307   if(!fix_file_owner(fname,desc,user)) return false;
00308   if(!fix_file_permissions(fname)) return false;
00309   if(args == NULL) return true;
00310   int h = open(fname.c_str(),O_WRONLY);
00311   if(h == -1) return false;
00312   int r;
00313   int t = 10;
00314   JobUser tmp_user((uid_t)0);
00315   r=RunRedirected::run(tmp_user,"job_controldiag_mark_put",-1,h,-1,(char**)args,t);
00316   close(h);
00317   if(r != 0) return false;
00318   return true;
00319 }
00320 
00321 bool job_lrmsoutput_mark_put(const JobDescription &desc,JobUser &user) {
00322   std::string fname = desc.SessionDir() + sfx_lrmsoutput;
00323   if(user.StrictSession()) {
00324     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00325     return (RunFunction::run(tmp_user,"job_lrmsoutput_mark_put",&job_mark_put_callback,&fname,10) == 0);
00326   };
00327   return job_mark_put(fname) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00328 }
00329 
00330 bool job_diagnostics_mark_add(const JobDescription &desc,JobUser &user,const std::string &content) {
00331   std::string fname = desc.SessionDir() + sfx_diag;
00332   if(user.StrictSession()) {
00333     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00334     job_mark_add_t arg; arg.fname=&fname; arg.content=&content;
00335     return (RunFunction::run(tmp_user,"job_diagnostics_mark_add",&job_mark_add_callback,&arg,10) == 0);
00336   };
00337   return job_mark_add_s(fname,content) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00338 }
00339 
00340 bool job_diagnostics_mark_remove(const JobDescription &desc,JobUser &user) {
00341   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_diag;
00342   bool res1 = job_mark_remove(fname);
00343   fname = desc.SessionDir() + sfx_diag;
00344   if(user.StrictSession()) {
00345     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00346     return (res1 | (RunFunction::run(tmp_user,"job_diagnostics_mark_remove",&job_mark_remove_callback,&fname,10) == 0));
00347   };
00348   return (res1 | job_mark_remove(fname));
00349 }
00350 
00351 bool job_lrmsoutput_mark_remove(const JobDescription &desc,JobUser &user) {
00352   std::string fname = desc.SessionDir() + sfx_lrmsoutput;
00353   if(user.StrictSession()) {
00354     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00355     return (RunFunction::run(tmp_user,"job_lrmsoutpur_mark_remove",&job_mark_remove_callback,&fname,10) == 0);
00356   };
00357   return job_mark_remove(fname);
00358 }
00359 
00360 typedef struct {
00361   int h;
00362   const std::string* fname;
00363 } job_file_read_t;
00364 
00365 static int job_file_read_callback(void* arg) {
00366   int h = ((job_file_read_t*)arg)->h;
00367   const std::string& fname = *(((job_file_read_t*)arg)->fname);
00368   int h1=open(fname.c_str(),O_RDONLY);
00369   if(h1==-1) return -1;
00370   char buf[256];
00371   int l;
00372   for(;;) {
00373     l=read(h1,buf,256);
00374     if((l==0) || (l==-1)) break;
00375     (write(h,buf,l) != -1);
00376   };
00377   close(h1); close(h);
00378   unlink(fname.c_str());
00379   return 0;
00380 }
00381 
00382 bool job_diagnostics_mark_move(const JobDescription &desc,JobUser &user) {
00383   std::string fname2 = user.ControlDir() + "/job." + desc.get_id() + sfx_diag;
00384   int h2=open(fname2.c_str(),O_WRONLY | O_APPEND,S_IRUSR | S_IWUSR);
00385   if(h2==-1) return false;
00386   fix_file_owner(fname2,desc,user);
00387   fix_file_permissions(fname2,user);
00388   std::string fname1 = user.SessionRoot(desc.get_id()) + "/" + desc.get_id() + sfx_diag;
00389   if(user.StrictSession()) {
00390     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
00391     job_file_read_t arg; arg.h=h2; arg.fname=&fname1;
00392     RunFunction::run(tmp_user,"job_diagnostics_mark_move",&job_file_read_callback,&arg,10);
00393     close(h2);
00394     return true;
00395   };
00396   int h1=open(fname1.c_str(),O_RDONLY);
00397   if(h1==-1) { close(h2); return false; };
00398   char buf[256];
00399   int l;
00400   for(;;) {
00401     l=read(h1,buf,256);
00402     if((l==0) || (l==-1)) break;
00403     (write(h2,buf,l) != -1);
00404   };
00405   close(h1); close(h2);
00406   unlink(fname1.c_str());
00407   return true;
00408 }
00409 
00410 bool job_stdlog_move(const JobDescription& /*desc*/,JobUser& /*user*/,const std::string& /*logname*/) {
00411 /*
00412 
00413  Status data is now available during runtime.
00414 
00415 */
00416   return true;
00417 }
00418 
00419 bool job_dir_create(const std::string &dname) {
00420   int err=mkdir(dname.c_str(),S_IRUSR | S_IWUSR | S_IXUSR);
00421   return (err==0);
00422 }
00423 
00424 bool job_mark_put(const std::string &fname) {
00425   int h=open(fname.c_str(),O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR);
00426   if(h==-1) return false; close(h); return true;
00427 }
00428 
00429 bool job_mark_check(const std::string &fname) {
00430   struct stat st;
00431   if(lstat(fname.c_str(),&st) != 0) return false;
00432   if(!S_ISREG(st.st_mode)) return false;
00433   return true;
00434 }
00435 
00436 bool job_mark_remove(const std::string &fname) {
00437   if(unlink(fname.c_str()) != 0) { if(errno != ENOENT) return false; };
00438   return true;
00439 }
00440 
00441 std::string job_mark_read_s(const std::string &fname) {
00442   std::string s("");
00443   std::ifstream f(fname.c_str()); if(! f.is_open() ) return s;
00444   char buf[256]; f.getline(buf,254); s=buf;
00445   return s;
00446 }
00447 
00448 long int job_mark_read_i(const std::string &fname) {
00449   std::ifstream f(fname.c_str()); if(! f.is_open() ) return -1;
00450   char buf[32]; f.getline(buf,30); f.close();
00451   char* e; long int i;
00452   i=strtol(buf,&e,10); if((*e) == 0) return i;
00453   return -1;
00454 }
00455 
00456 bool job_mark_write_s(const std::string &fname,const std::string &content) {
00457   int h=open(fname.c_str(),O_WRONLY | O_CREAT | O_TRUNC,S_IRUSR | S_IWUSR);
00458   if(h==-1) return false;
00459   (write(h,(const void *)content.c_str(),content.length()) != -1);
00460   close(h); return true;
00461 }
00462 
00463 bool job_mark_add_s(const std::string &fname,const std::string &content) {
00464   int h=open(fname.c_str(),O_WRONLY | O_CREAT | O_APPEND,S_IRUSR | S_IWUSR);
00465   if(h==-1) return false;
00466   (write(h,(const void *)content.c_str(),content.length()) != -1);
00467   close(h); return true;
00468 }
00469 
00470 time_t job_mark_time(const std::string &fname) {
00471   struct stat st;
00472   if(lstat(fname.c_str(),&st) != 0) return 0;
00473   return st.st_mtime;
00474 }
00475 
00476 long int job_mark_size(const std::string &fname) {
00477   struct stat st;
00478   if(lstat(fname.c_str(),&st) != 0) return 0;
00479   if(!S_ISREG(st.st_mode)) return 0;
00480   return st.st_size;
00481 }
00482 
00483 bool job_diskusage_create_file(const JobDescription &desc,JobUser& /*user*/,unsigned long long int &requested) {
00484   std::string fname = desc.SessionDir() + sfx_diskusage;
00485   int h=open(fname.c_str(),O_WRONLY | O_CREAT,S_IRUSR | S_IWUSR);
00486   if(h==-1) return false;
00487   char content[200];
00488   snprintf(content, sizeof(content), "%llu 0\n",requested);
00489   (write(h,content,strlen(content)) != -1);
00490   close(h); return true;
00491 }
00492 
00493 bool job_diskusage_read_file(const JobDescription &desc,JobUser& /*user*/,unsigned long long int &requested,unsigned long long int &used) {
00494   std::string fname = desc.SessionDir() + sfx_diskusage;
00495   int h=open(fname.c_str(),O_RDONLY);
00496   if(h==-1) return false;
00497   char content[200];
00498   ssize_t l=read(h,content,199);
00499   if(l==-1) { close(h); return false; };
00500   content[l]=0;
00501   unsigned long long int req_,use_;
00502   if(sscanf(content,"%llu %llu",&req_,&use_) != 2) { close(h); return false; };
00503   requested=req_; used=use_;  
00504   close(h); return true;
00505 }
00506 
00507 bool job_diskusage_change_file(const JobDescription &desc,JobUser& /*user*/,signed long long int used,bool &result) {
00508   // lock file, read, write, unlock
00509   std::string fname = desc.SessionDir() + sfx_diskusage;
00510   int h=open(fname.c_str(),O_RDWR);
00511   if(h==-1) return false;
00512   struct flock lock;
00513   lock.l_type=F_WRLCK;
00514   lock.l_whence=SEEK_SET;
00515   lock.l_start=0;
00516   lock.l_len=0;
00517   for(;;) {
00518     if(fcntl(h,F_SETLKW,&lock) != -1) break;
00519     if(errno == EINTR) continue;
00520     close(h); return false;
00521   };
00522   char content[200];
00523   ssize_t l=read(h,content,199);
00524   if(l==-1) {
00525     lock.l_whence=SEEK_SET; lock.l_start=0; lock.l_len=0;
00526     lock.l_type=F_UNLCK; fcntl(h,F_SETLK,&lock);
00527     close(h); return false;
00528   };
00529   content[l]=0;
00530   unsigned long long int req_,use_;
00531   if(sscanf(content,"%llu %llu",&req_,&use_) != 2) {
00532     lock.l_whence=SEEK_SET; lock.l_start=0; lock.l_len=0;
00533     lock.l_type=F_UNLCK; fcntl(h,F_SETLK,&lock);
00534     close(h); return false;
00535   };
00536   if((-used) > use_) {
00537     result=true; use_=0; // ??????
00538   }
00539   else {
00540     use_+=used; result=true;
00541     if(use_>req_) result=false;
00542   };
00543   lseek(h,0,SEEK_SET);  
00544   snprintf(content,sizeof(content),"%llu %llu\n",req_,use_);
00545   (write(h,content,strlen(content)) != -1);
00546   lock.l_whence=SEEK_SET; lock.l_start=0; lock.l_len=0;
00547   lock.l_type=F_UNLCK; fcntl(h,F_SETLK,&lock);
00548   close(h); return true;
00549 }
00550 
00551 bool job_diskusage_remove_file(const JobDescription &desc,JobUser& /*user*/) {
00552   std::string fname = desc.SessionDir() + sfx_diskusage;
00553   return job_mark_remove(fname);
00554 }
00555 
00556 time_t job_state_time(const JobId &id,JobUser &user) {
00557   std::string fname = user.ControlDir() + "/job." + id + sfx_status;
00558   return job_mark_time(fname);
00559 }
00560 
00561 job_state_t job_state_read_file(const JobId &id,const JobUser &user) {
00562   std::string fname = user.ControlDir() + "/job." + id + sfx_status;
00563   bool pending;
00564   return job_state_read_file(fname,pending);
00565 }
00566 
00567 job_state_t job_state_read_file(const JobId &id,const JobUser &user,bool& pending) {
00568   std::string fname = user.ControlDir() + "/job." + id + sfx_status;
00569   return job_state_read_file(fname,pending);
00570 }
00571 
00572 bool job_state_write_file(const JobDescription &desc,JobUser &user,job_state_t state,bool pending) {
00573   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_status;
00574   return job_state_write_file(fname,state,pending) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname,user);
00575 }
00576 
00577 job_state_t job_state_read_file(const std::string &fname,bool &pending) {
00578   std::ifstream f(fname.c_str());
00579   if(!f.is_open() ) return JOB_STATE_UNDEFINED; /* can't open file */
00580   char buf[32];
00581   f.getline(buf,30);
00582   /* interpret information */
00583   char* p = buf;
00584   if(!strncmp("PENDING:",p,8)) { p+=8; pending=true; } else { pending=false; };
00585   for(int i = 0;states_all[i].name != NULL;i++) {
00586     if(!strcmp(states_all[i].name,p)) {
00587       f.close();
00588       return states_all[i].id;
00589     };
00590   };
00591   f.close();
00592   return JOB_STATE_UNDEFINED; /* broken file */
00593 }
00594 
00595 bool job_state_write_file(const std::string &fname,job_state_t state,bool pending) {
00596   std::ofstream f(fname.c_str(),std::ios::out | std::ios::trunc);
00597   if(! f.is_open() ) return false; /* can't open file */
00598   if(pending) f<<"PENDING:";
00599   f<<states_all[state].name<<std::endl;
00600   f.close();
00601   return true;
00602 }
00603 
00604 bool job_description_read_file(JobId &id,JobUser &user,std::string &rsl) {
00605   std::string fname = user.ControlDir() + "/job." + id + sfx_rsl;
00606   return job_description_read_file(fname,rsl);
00607 }
00608 
00609 bool job_description_read_file(const std::string &fname,std::string &rsl) {
00610   char buf[256];
00611   std::string::size_type n=0;
00612   std::ifstream f(fname.c_str());
00613   if(! f.is_open() ) return false; /* can't open file */
00614   rsl.erase();
00615   while(!f.eof()) {
00616     memset(buf,0,256);
00617     f.read(buf,255); rsl+=buf;
00618     for(;(n=rsl.find('\n',n)) != std::string::npos;) rsl.erase(n,1);
00619     n=rsl.length();
00620   };
00621   f.close();
00622   return true;
00623 }
00624 
00625 bool job_description_write_file(const std::string &fname,std::string &rsl) {
00626   return job_description_write_file(fname,rsl.c_str());
00627 }
00628 
00629 bool job_description_write_file(const std::string &fname,const char* rsl) {
00630   std::ofstream f(fname.c_str(),std::ios::out | std::ios::trunc);
00631   if(! f.is_open() ) return false; /* can't open file */
00632   f.write(rsl,strlen(rsl));
00633   f.close();
00634   return true;
00635 }
00636 
00637 bool job_acl_read_file(JobId &id,JobUser &user,std::string &acl) {
00638   std::string fname = user.ControlDir() + "/job." + id + sfx_acl;
00639   return job_description_read_file(fname,acl);
00640 }
00641 
00642 bool job_acl_write_file(JobId &id,JobUser &user,std::string &acl) {
00643   std::string fname = user.ControlDir() + "/job." + id + sfx_acl;
00644   return job_description_write_file(fname,acl.c_str());
00645 }
00646 
00647 bool job_local_write_file(const JobDescription &desc,const JobUser &user,const JobLocalDescription &job_desc) {
00648   std::string fname = user.ControlDir() + "/job." + desc.get_id() + sfx_local;
00649   return job_local_write_file(fname,job_desc) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname,user);
00650 }
00651 
00652 inline void write_pair(std::ofstream &f,const std::string &name,const std::string &value) {
00653   if(value.length()) f << name << '=' << value << std::endl;
00654 }
00655 
00656 inline void write_pair(std::ofstream &f,const std::string &name,const Arc::Time &value) {
00657   if(value != -1) f << name << '=' << value.str(Arc::MDSTime) << std::endl;
00658 }
00659 
00660 inline void write_pair(std::ofstream &f,const std::string &name,bool value) {
00661   f << name << '=' << (value?"yes":"no") << std::endl;
00662 }
00663 
00664 bool job_local_write_file(const std::string &fname,const JobLocalDescription &job_desc) {
00665   std::ofstream f(fname.c_str(),std::ios::out | std::ios::trunc);
00666   if(! f.is_open() ) return false; /* can't open file */
00667   for (std::list<std::string>::const_iterator it=job_desc.jobreport.begin();
00668        it!=job_desc.jobreport.end();
00669        it++)
00670     {
00671       write_pair(f,"jobreport",*it);
00672     }
00673   write_pair(f,"globalid",job_desc.globalid);
00674   write_pair(f,"lrms",job_desc.lrms);
00675   write_pair(f,"queue",job_desc.queue);
00676   write_pair(f,"localid",job_desc.localid);
00677   f << "args=";
00678   if(job_desc.arguments.size()) {
00679     for(std::list<std::string>::const_iterator i=job_desc.arguments.begin(); \
00680         i!=job_desc.arguments.end(); ++i) {
00681       output_escaped_string(f,*i);
00682       f << " ";
00683     };
00684   };
00685   f << std::endl;
00686   write_pair(f,"subject",job_desc.DN);
00687   write_pair(f,"starttime",job_desc.starttime);
00688   write_pair(f,"lifetime",job_desc.lifetime);
00689   write_pair(f,"notify",job_desc.notify);
00690   write_pair(f,"processtime",job_desc.processtime);
00691   write_pair(f,"exectime",job_desc.exectime);
00692   write_pair(f,"rerun",Arc::tostring(job_desc.reruns));
00693   if(job_desc.downloads>=0) write_pair(f,"downloads",Arc::tostring(job_desc.downloads));
00694   if(job_desc.uploads>=0) write_pair(f,"uploads",Arc::tostring(job_desc.uploads));
00695   if(job_desc.rtes>=0) write_pair(f,"rtes",Arc::tostring(job_desc.rtes));
00696   write_pair(f,"jobname",job_desc.jobname);
00697   for (std::list<std::string>::const_iterator ppn=job_desc.projectnames.begin();
00698        ppn!=job_desc.projectnames.end();
00699        ++ppn)
00700     {
00701       write_pair(f,"projectname",*ppn);
00702     }
00703   write_pair(f,"gmlog",job_desc.stdlog);
00704   write_pair(f,"cleanuptime",job_desc.cleanuptime);
00705   write_pair(f,"delegexpiretime",job_desc.expiretime);
00706   write_pair(f,"clientname",job_desc.clientname);
00707   write_pair(f,"clientsoftware",job_desc.clientsoftware);
00708   write_pair(f,"sessiondir",job_desc.sessiondir);
00709   write_pair(f,"diskspace",Arc::tostring(job_desc.diskspace));
00710   write_pair(f,"failedstate",job_desc.failedstate);
00711   write_pair(f,"credentialserver",job_desc.credentialserver);
00712   for(std::list<std::string>::const_iterator act_id=job_desc.activityid.begin();
00713       act_id != job_desc.activityid.end(); ++act_id) {
00714     write_pair(f,"activityid",(*act_id));
00715   };
00716   if (job_desc.migrateactivityid != "") {
00717     write_pair(f,"migrateactivityid",job_desc.migrateactivityid);
00718     write_pair(f,"forcemigration",job_desc.forcemigration);
00719   }
00720   write_pair(f,"transfershare",job_desc.transfershare);
00721   f.close();
00722   return true;
00723 }
00724 
00725 bool job_local_read_file(const JobId &id,const JobUser &user,JobLocalDescription &job_desc) {
00726   std::string fname = user.ControlDir() + "/job." + id + sfx_local;
00727   return job_local_read_file(fname,job_desc);
00728 }
00729 
00730 bool job_local_read_file(const std::string &fname,JobLocalDescription &job_desc) {
00731   char buf[4096];
00732   std::ifstream f(fname.c_str());
00733   if(! f.is_open() ) return false; /* can't open file */
00734   std::string name;
00735   job_desc.activityid.clear();
00736   for(;!f.eof();) {
00737     istream_readline(f,buf,sizeof(buf));
00738     name.erase();
00739     int p=input_escaped_string(buf,name,'=');
00740     if(name.length() == 0) continue;
00741     if(buf[p] == 0) continue;
00742     if(name == "lrms") { job_desc.lrms = buf+p; }
00743     else if(name == "queue") { job_desc.queue = buf+p; }
00744     else if(name == "localid") { job_desc.localid = buf+p; }
00745     else if(name == "subject") { job_desc.DN = buf+p; }
00746     else if(name == "starttime") { job_desc.starttime = buf+p; }
00747 //    else if(name == "UI") { job_desc.UI = buf+p; }
00748     else if(name == "lifetime") { job_desc.lifetime = buf+p; }
00749     else if(name == "notify") { job_desc.notify = buf+p; }
00750     else if(name == "processtime") { job_desc.processtime = buf+p; }
00751     else if(name == "exectime") { job_desc.exectime = buf+p; }
00752     else if(name == "jobreport") { job_desc.jobreport.push_back(std::string(buf+p)); }
00753     else if(name == "globalid") { job_desc.globalid = buf+p; }
00754     else if(name == "jobname") { job_desc.jobname = buf+p; }
00755     else if(name == "projectname") { job_desc.projectnames.push_back(std::string(buf+p)); }
00756     else if(name == "gmlog") { job_desc.stdlog = buf+p; }
00757     else if(name == "rerun") {
00758       std::string temp_s(buf+p); int n;
00759       if(!Arc::stringto(temp_s,n)) { f.close(); return false; };
00760       job_desc.reruns = n;
00761     }
00762     else if(name == "downloads") {
00763       std::string temp_s(buf+p); int n;
00764       if(!Arc::stringto(temp_s,n)) { f.close(); return false; };
00765       job_desc.downloads = n;
00766     }
00767     else if(name == "uploads") {
00768       std::string temp_s(buf+p); int n;
00769       if(!Arc::stringto(temp_s,n)) { f.close(); return false; };
00770       job_desc.uploads = n;
00771     }
00772     else if(name == "rtes") {
00773       std::string temp_s(buf+p); int n;
00774       if(!Arc::stringto(temp_s,n)) { f.close(); return false; };
00775       job_desc.rtes = n;
00776     }
00777     else if(name == "args") {
00778       job_desc.arguments.clear();
00779       for(int n=p;buf[n] != 0;) {
00780         std::string arg;
00781         n+=input_escaped_string(buf+n,arg);
00782         job_desc.arguments.push_back(arg);
00783       };
00784     }
00785     else if(name == "cleanuptime") { job_desc.cleanuptime = buf+p; }
00786     else if(name == "delegexpiretime") { job_desc.expiretime = buf+p; }
00787     else if(name == "clientname") { job_desc.clientname = buf+p; }
00788     else if(name == "clientsoftware") { job_desc.clientsoftware = buf+p; }
00789     else if(name == "sessiondir") { job_desc.sessiondir = buf+p; }
00790     else if(name == "failedstate") { job_desc.failedstate = buf+p; }
00791     else if(name == "credentialserver") { job_desc.credentialserver = buf+p; }
00792     else if(name == "diskspace") {
00793       std::string temp_s(buf+p);
00794       unsigned long long int n;
00795       if(!Arc::stringto(temp_s,n)) { f.close(); return false; };
00796       job_desc.diskspace = n;
00797     }
00798     else if(name == "activityid") { 
00799       std::string temp_s(buf+p);
00800       job_desc.activityid.push_back(temp_s);
00801     }
00802     else if(name == "migrateactivityid") { job_desc.migrateactivityid = buf+p; }
00803     else if(name == "forcemigration") { 
00804       if(strcasecmp("yes",buf+p) == 0) { job_desc.forcemigration = true; }
00805       else if(strcasecmp("true",buf+p) == 0) { job_desc.forcemigration = true; }
00806       else job_desc.forcemigration = false;
00807     }
00808     else if(name == "transfershare") { job_desc.transfershare = buf+p; };
00809   }
00810   f.close();
00811   return true;
00812 }
00813 
00814 bool job_local_read_var(const std::string &fname,const std::string &vnam,std::string &value) {
00815   char buf[1024];
00816   std::ifstream f(fname.c_str());
00817   if(! f.is_open() ) return false; /* can't open file */
00818   std::string name;
00819   bool found = false;
00820   for(;!f.eof();) {
00821     istream_readline(f,buf,sizeof(buf));
00822     name.erase();
00823     int p=input_escaped_string(buf,name,'=');
00824     if(name.length() == 0) continue;
00825     if(buf[p] == 0) continue;
00826     if(name == vnam) { value = buf+p; found=true; break; };
00827   };
00828   f.close();
00829   return found;
00830 }
00831 
00832 bool job_local_read_lifetime(const JobId &id,const JobUser &user,time_t &lifetime) {
00833   std::string fname = user.ControlDir() + "/job." + id + sfx_local;
00834   std::string str;
00835   if(!job_local_read_var(fname,"lifetime",str)) return false;
00836   char* str_e;
00837   unsigned long int t = strtoul(str.c_str(),&str_e,10);
00838   if((*str_e) != 0) return false;
00839   lifetime=t;
00840   return true;
00841 }
00842 
00843 bool job_local_read_cleanuptime(const JobId &id,const JobUser &user,time_t &cleanuptime) {
00844   std::string fname = user.ControlDir() + "/job." + id + sfx_local;
00845   std::string str;
00846   if(!job_local_read_var(fname,"cleanuptime",str)) return false;
00847   cleanuptime=Arc::Time(str).GetTime();
00848   return true;
00849 }
00850 
00851 bool job_local_read_notify(const JobId &id,const JobUser &user,std::string &notify) {
00852   std::string fname = user.ControlDir() + "/job." + id + sfx_local;
00853   if(!job_local_read_var(fname,"notify",notify)) return false;
00854   return true;
00855 }
00856 
00857 bool job_local_read_string(const std::string &fname,unsigned int num,std::string &str) {
00858   std::ifstream f(fname.c_str());
00859   if(! f.is_open() ) return false; /* can't open file */
00860   for(;num;num--) {
00861     f.ignore(INT_MAX,'\n'); 
00862   };
00863   if(f.eof()) { f.close(); return false; };
00864   char buf[256];
00865   f.get(buf,255,'\n'); if(!buf[0]) { f.close(); return false; };
00866   str=buf; 
00867   f.close();
00868   return true;
00869 }
00870 
00871 /* job.ID.input functions */
00872 
00873 bool job_input_write_file(const JobDescription &desc,JobUser &user,std::list<FileData> &files) {
00874   std::string fname = user.ControlDir() + "/job." + desc.get_id() + ".input";
00875   return job_Xput_write_file(fname,files) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00876 }
00877 
00878 bool job_input_read_file(const JobId &id,JobUser &user,std::list<FileData> &files) {
00879   std::string fname = user.ControlDir() + "/job." + id + ".input";
00880   return job_Xput_read_file(fname,files);
00881 }
00882 
00883 std::string job_proxy_filename(const JobId &id, const JobUser &user){
00884        return user.ControlDir() + "/job." + id + sfx_proxy;
00885 }
00886 /* job.ID.rte functions */
00887 
00888 bool job_rte_write_file(const JobDescription &desc,JobUser &user,std::list<std::string> &rtes) {
00889   std::string fname = user.ControlDir() + "/job." + desc.get_id() + ".rte";
00890   return job_strings_write_file(fname,rtes) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00891 }
00892 
00893 bool job_rte_read_file(const JobId &id,JobUser &user,std::list<std::string> &rtes) {
00894   std::string fname = user.ControlDir() + "/job." + id + ".rte";
00895   return job_strings_read_file(fname,rtes);
00896 }
00897 
00898 /* job.ID.output functions */
00899 /*
00900 bool job_cache_write_file(const JobDescription &desc,JobUser &user,std::list<FileData> &files) {
00901   std::string fname = user.ControlDir() + "/job." + desc.get_id() + ".cache";
00902   return job_Xput_write_file(fname,files) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00903 }
00904 */
00905 
00906 bool job_output_write_file(const JobDescription &desc,JobUser &user,std::list<FileData> &files) {
00907   std::string fname = user.ControlDir() + "/job." + desc.get_id() + ".output";
00908   return job_Xput_write_file(fname,files) & fix_file_owner(fname,desc,user) & fix_file_permissions(fname);
00909 }
00910 
00911 /*
00912 bool job_cache_read_file(const JobId &id,JobUser &user,std::list<FileData> &files) {
00913   std::string fname = user.ControlDir() + "/job." + id + ".cache";
00914   return job_Xput_read_file(fname,files);
00915 }
00916 */
00917 
00918 bool job_output_read_file(const JobId &id,JobUser &user,std::list<FileData> &files) {
00919   std::string fname = user.ControlDir() + "/job." + id + ".output";
00920   return job_Xput_read_file(fname,files);
00921 }
00922 
00923 /* common finctions */
00924 
00925 bool job_Xput_write_file(const std::string &fname,std::list<FileData> &files) {
00926   std::ofstream f(fname.c_str(),std::ios::out | std::ios::trunc);
00927   if(! f.is_open() ) return false; /* can't open file */
00928   for(FileData::iterator i=files.begin();i!=files.end(); ++i) { 
00929     f << (*i) << std::endl;
00930   };
00931   f.close();
00932   return true;
00933 }
00934 
00935 bool job_Xput_read_file(std::list<FileData> &files) {
00936   for(;!std::cin.eof();) {
00937     FileData fd; std::cin >> fd;
00938 //    if((fd.pfn.length() != 0) && (fd.pfn != "/")) {
00939     if(fd.pfn.length() != 0) {  /* returns zero length only if empty std::string */
00940       files.push_back(fd);
00941     };
00942   };
00943   return true;
00944 }
00945 
00946 bool job_Xput_read_file(const std::string &fname,std::list<FileData> &files) {
00947   std::ifstream f(fname.c_str());
00948   if(! f.is_open() ) return false; /* can't open file */
00949   for(;!f.eof();) {
00950     FileData fd; f >> fd;
00951 //    if((fd.pfn.length() != 0) && (fd.pfn != "/")) {
00952     if(fd.pfn.length() != 0) {  /* returns zero length only if empty std::string */
00953       files.push_back(fd);
00954     };
00955   };
00956   f.close();
00957   return true;
00958 }
00959 
00960 bool job_strings_write_file(const std::string &fname,std::list<std::string> &strs) {
00961   std::ofstream f(fname.c_str(),std::ios::out | std::ios::trunc);
00962   if(! f.is_open() ) return false; /* can't open file */
00963   for(std::list<std::string>::iterator i=strs.begin();i!=strs.end(); ++i) {
00964     f << (*i) << std::endl;
00965   };
00966   f.close();
00967   return true;
00968 }
00969 
00970 bool job_strings_read_file(const std::string &fname,std::list<std::string> &strs) {
00971   std::ifstream f(fname.c_str());
00972   if(! f.is_open() ) return false; /* can't open file */
00973   for(;!f.eof();) {
00974     std::string str; f >> str;
00975     if(!str.empty()) strs.push_back(str);
00976   };
00977   f.close();
00978   return true;
00979 }
00980 
00981 bool job_clean_finished(const JobId &id,JobUser &user) {
00982   std::string fname;
00983   fname = user.ControlDir()+"/job."+id+".proxy.tmp"; remove(fname.c_str());
00984   fname = user.ControlDir()+"/job."+id+".lrms_done"; remove(fname.c_str());
00985   return true;
00986 }
00987 
00988 bool job_clean_deleted(const JobDescription &desc,JobUser &user,std::list<std::string> cache_per_job_dirs) {
00989   std::string id = desc.get_id();
00990   job_clean_finished(id,user);
00991   std::string fname;
00992   fname = user.ControlDir()+"/job."+id+".proxy"; remove(fname.c_str());
00993   fname = user.ControlDir()+"/job."+id+sfx_restart; remove(fname.c_str());
00994   fname = user.ControlDir()+"/job."+id+sfx_errors; remove(fname.c_str());
00995   fname = user.ControlDir()+"/job."+id+sfx_cancel; remove(fname.c_str());
00996   fname = user.ControlDir()+"/job."+id+sfx_clean;  remove(fname.c_str());
00997   fname = user.ControlDir()+"/job."+id+".output"; remove(fname.c_str());
00998   fname = user.ControlDir()+"/job."+id+".input"; remove(fname.c_str());
00999   fname = user.ControlDir()+"/job."+id+".rte"; remove(fname.c_str());
01000   fname = user.ControlDir()+"/job."+id+".grami_log"; remove(fname.c_str());
01001   fname = user.SessionRoot(id)+"/"+id+sfx_lrmsoutput; remove(fname.c_str());
01002   /* remove session directory */
01003   std::list<FileData> flist;
01004   std::string dname = user.SessionRoot(id)+"/"+id;
01005   if(user.StrictSession()) {
01006     JobUser tmp_user(user.get_uid()==0?desc.get_uid():user.get_uid());
01007     job_dir_remove_t arg; arg.dname=&dname; arg.flist=&flist;
01008     return (RunFunction::run(tmp_user,"job_clean_deleted",&job_dir_remove_callback,&arg,10) == 0);
01009   } else {
01010     delete_all_files(dname,flist,true);
01011     remove(dname.c_str());
01012   };
01013   // remove cache per-job links, in case this failed earlier
01014   // list all files in the dir and delete them
01015   for (std::list<std::string>::iterator i = cache_per_job_dirs.begin(); i != cache_per_job_dirs.end(); i++) {
01016     std::string cache_job_dir = (*i) + "/" + id;
01017     DIR * dirp = opendir(cache_job_dir.c_str());
01018     if ( dirp == NULL) return true; // already deleted
01019     struct dirent *dp;
01020     while ((dp = readdir(dirp)))  {
01021       if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue;
01022       std::string to_delete = cache_job_dir + "/" + dp->d_name; 
01023       remove(to_delete.c_str());
01024     }
01025     closedir(dirp);
01026     // remove now-empty dir
01027     rmdir(cache_job_dir.c_str());
01028   }
01029   return true;
01030 }
01031 
01032 bool job_clean_final(const JobDescription &desc,JobUser &user) {
01033   std::string id = desc.get_id();
01034   job_clean_finished(id,user);
01035   job_clean_deleted(desc,user);
01036   std::string fname;
01037   fname = user.ControlDir()+"/job."+id+sfx_local;  remove(fname.c_str());
01038   fname = user.ControlDir()+"/job."+id+".grami"; remove(fname.c_str());
01039   fname = user.ControlDir()+"/job."+id+sfx_failed; remove(fname.c_str());
01040   job_diagnostics_mark_remove(desc,user);
01041   job_lrmsoutput_mark_remove(desc,user);
01042   fname = user.ControlDir()+"/job."+id+sfx_status; remove(fname.c_str());
01043   fname = user.ControlDir()+"/job."+id+sfx_rsl;    remove(fname.c_str());
01044   return true;
01045 }
01046 
01047