int bs_config_string_set(const char *file, const char *label, const char *target)
{
	FILE    *fp, *fw;
	char    buf[BUFSIZ];
	char    tmp_file[BUFSIZ];
	char    value[BUFSIZ];
	char    key[BUFSIZ];
	int     found = 0;
	int     ret = -1;
	int     changed = 0;
	struct stat st;
	

	if (NULL == file)
		goto out;
	if (stat(file, &st)){
	    /* not existed, create a new one */
	    touch(file);
	}
	if ( (fp = fopen(file, "r")) == NULL ){
		printf("%s:%d (%s) can not be opened\n", __FILE__, __LINE__, file);
		goto out;
	}
	snprintf(tmp_file, BUFSIZ, "%s.bk", file);
	if ( (fw = fopen(tmp_file, "w")) == NULL ) {
		printf("%s:%d (%s) can not be opened\n", __FILE__, __LINE__, tmp_file);
		fclose(fp);
		goto out;
	}

	while(fgets(buf,BUFSIZ,fp)) {
		securesoho_parse_value(buf, key, value );	
		if (!strcmp(key, label)) {
			if ( strcmp(value, target) ) {
				changed = 1;
				strcpy( value, target );
			}
			found++;
		}
		fprintf(fw, "%s='%s'\n", key, value);
	}
	if (!found) {
		changed = 1;
		fprintf(fw,"%s='%s'\n", label, target );
	}

	fclose(fp);
	fclose(fw);

	if (changed) {
		unlink(file);
		safe_rename(tmp_file, (char *)file);
		DEBUGP("\033[1;33mstring_set: %s: [%s], changed\033[0m\n", label, target);
	} else {
		unlink(tmp_file);
		DEBUGP("\033[1;33mstring_set: %s: [%s], no change\033[0m\n", label, target);
	}
out:
	return ret;
}
Exemple #2
0
static int mutt_put_file_in_place (const char *path, const char *safe_file, const char *safe_dir)
{
  int rv;
  
  rv = safe_rename (safe_file, path);
  unlink (safe_file);
  rmdir (safe_dir);
  return rv;
}
int securesoho_string_set(const char *label,const char *target )
{
	FILE    *fp, *fw;
	char    buf[BUFSIZ];
	char    value[BUFSIZ];
	char    key[BUFSIZ];
	int     found = 0;
	int	lockfd = -1;
	int	ret = 0;
	int     changed = 0;
	
	lockfd = securesoho_config_lock();
	if ( (fp = fopen(SECURESOHO_CONFIG, "r")) == NULL ) {
		ret = -ESEC_IO_ERROR;
		goto OUT;
	}

	if ( (fw = fopen( SECURESOHO_TMP_CONFIG, "w")) == NULL ) {
		fclose(fp);
		ret = -ESEC_IO_ERROR;
		goto OUT;
	}

	while(fgets(buf,BUFSIZ,fp)) {
		securesoho_parse_value(buf, key, value );	
		if (!strcmp(key, label)) {
			if ( strcmp(value, target) ) {
				changed = 1;
				strcpy( value, target );
			}
			found++;
		}
		fprintf(fw, "%s='%s'\n", key, value);
	}
	if (!found) {
		changed = 1;
		fprintf(fw,"%s='%s'\n", label, target );
	}

	fclose(fp);
	fclose(fw);

	if (changed) {
		unlink(SECURESOHO_CONFIG);
		safe_rename( SECURESOHO_TMP_CONFIG, SECURESOHO_CONFIG );
		DEBUGP("\033[1;33mstring_set: %s: [%s], changed\033[0m\n", label, target);
	} else {
		unlink(SECURESOHO_TMP_CONFIG);
		DEBUGP("\033[1;33mstring_set: %s: [%s], no change\033[0m\n", label, target);
	}

OUT:
	securesoho_config_unlock( lockfd );
	return ret;
}
Exemple #4
0
static void
handle_ended_download(DCUserConn *uc, bool success, const char *reason)
{
    bytes_received += uc->transfer_pos - uc->transfer_start;
    if (uc->occupied_slot) {
        used_dl_slots--;
        uc->occupied_slot = false;
    }
    /* If we removed from the queued item during download,
     * queue_pos will point outside the queue. */
    if (uc->queued_valid) {
        DCQueuedFile *queued;

        /*
        queued = uc->info->download_queue->buf[uc->queue_pos];
        uc->queue_pos++;
        */
        queued = (DCQueuedFile*) ptrv_remove(uc->info->download_queue, uc->queue_pos);
        uc->queued_valid = false;
        if (success) {
            queued->status = DC_QS_DONE;
            if (queued->flag == DC_TF_LIST) {
                if (uc->local_file != NULL) {
                    ptrv_append(delete_files, xstrdup(uc->local_file));
                }
                if (browse_user != NULL && strcmp(browse_user->nick, uc->info->nick) == 0 && browse_list == NULL) {
                    add_parse_request(browse_list_parsed, uc->local_file, xstrdup(browse_user->nick));
                }
            } else {
                char *final_file = xstrndup(uc->local_file, strlen(uc->local_file)-5);
                if (safe_rename(uc->local_file, final_file) != 0) {
                    warn(_("%s: Cannot rename file to %s - %s\n"), quotearg_n(0, uc->local_file), quote_n(1, final_file), errstr);
                    reason = _("cannot rename file"); /* XXX: would like a more elaborate error message here perhaps? */
                    queued->status = DC_QS_ERROR;
                    success = false;
                }
                free(final_file);
            }
        } else {
            queued->status = DC_QS_ERROR;
        }
        display_transfer_ended_msg(false, uc, success, " (%s)", reason);
    } else {
        display_transfer_ended_msg(false, uc, success, " but unqueued (%s)", reason);
    }
    free(uc->transfer_file);
    free(uc->local_file);
    uc->transfer_file = NULL;
    uc->local_file = NULL;
    uc->transfer_start = 0;
    uc->transfer_pos = 0;
    uc->transferring = false;
}
Exemple #5
0
Fichier : mh.c Projet : hww3/pexts
int maildir_commit_message (CONTEXT *ctx, MESSAGE *msg, HEADER *hdr)
{
  char subdir[4];
  char suffix[16];
  char path[_POSIX_PATH_MAX];
  char full[_POSIX_PATH_MAX];
  char *s;

  if (safe_fclose (&msg->fp) != 0)
    return -1;
  
  /* extract the subdir */
  s = strrchr (msg->path, '/') + 1;
  strfcpy (subdir, s, 4);

  /* extract the flags */  
  if ((s = strchr (s, ':')))
    strfcpy (suffix, s, sizeof (suffix));
  else
    suffix[0] = '\0';

  /* construct a new file name. */
  FOREVER
  {
    snprintf (path, _POSIX_PATH_MAX, "%s/%ld.%d_%d.%s%s", subdir,
	      time (NULL), getpid(), Counter++, NONULL (Hostname), suffix);
    snprintf (full, _POSIX_PATH_MAX, "%s/%s", ctx->path, path);

    dprint (2, (debugfile, "maildir_commit_message (): renaming %s to %s.\n",
		msg->path, full));

    if (safe_rename (msg->path, full) == 0)
    {
      if (hdr) 
	mutt_str_replace (&hdr->path, path);
      FREE (&msg->path);
      return 0;
    }
    else if (errno != EEXIST)
    {
      mutt_perror (ctx->path);
      return -1;
    }
  }
}
Exemple #6
0
Fichier : mh.c Projet : hww3/pexts
static int _mh_commit_message (CONTEXT *ctx, MESSAGE *msg, HEADER *hdr, short updseq)
{
  DIR *dirp;
  struct dirent *de;
  char *cp, *dep;
  unsigned int n, hi = 0;
  char path[_POSIX_PATH_MAX];
  char tmp[16];

  if (safe_fclose (&msg->fp) != 0)
    return -1;
  
  if ((dirp = opendir (ctx->path)) == NULL)
  {
    mutt_perror (ctx->path);
    return (-1);
  }
  
  /* figure out what the next message number is */
  while ((de = readdir (dirp)) != NULL)
  {
    dep = de->d_name;
    if (*dep == ',')
      dep++;
    cp = dep;
    while (*cp)
    {
      if (!isdigit ((unsigned char) *cp))
	break;
      cp++;
    }
    if (!*cp)
    {
      n = atoi (dep);
      if (n > hi)
	hi = n;
    }
  }
  closedir (dirp);

  /* 
   * Now try to rename the file to the proper name.
   * 
   * Note: We may have to try multiple times, until we find a free
   * slot.
   */

  FOREVER
  {
    hi++;
    snprintf (tmp, sizeof (tmp), "%d", hi);
    snprintf (path, sizeof (path), "%s/%s", ctx->path, tmp);
    if (safe_rename (msg->path, path) == 0)
    {
      if (hdr)
	mutt_str_replace (&hdr->path, tmp);
      FREE (&msg->path);
      break;
    }
    else if (errno != EEXIST)
    {
      mutt_perror (ctx->path);
      return -1;
    }
  }
  if (updseq)
    mh_sequences_add_one (ctx, hi, !msg->flags.read, msg->flags.flagged, msg->flags.replied);
  return 0;
}
Exemple #7
0
Fichier : mh.c Projet : hww3/pexts
static void mh_sequences_add_one (CONTEXT *ctx, int n, short unseen, short flagged, short replied)
{
  short unseen_done = 0;
  short flagged_done = 0;
  short replied_done = 0;
  
  FILE *ofp = NULL, *nfp = NULL;
 
  char *tmpfname;
  char sequences[_POSIX_PATH_MAX];

  char seq_unseen[STRING];
  char seq_replied[STRING];
  char seq_flagged[STRING];
  
  char *buff = NULL;
  int line;
  size_t sz;
  
  if (mh_mkstemp (ctx, &nfp, &tmpfname) == -1)
    return;

  snprintf (seq_unseen, sizeof (seq_unseen), "%s:", NONULL (MhUnseen));
  snprintf (seq_replied, sizeof (seq_replied), "%s:", NONULL (MhReplied));
  snprintf (seq_flagged, sizeof (seq_flagged), "%s:", NONULL (MhFlagged));
  
  snprintf (sequences, sizeof (sequences), "%s/.mh_sequences", ctx->path);
  if ((ofp = fopen (sequences, "r")))
  {
    while ((buff = mutt_read_line (buff, &sz, ofp, &line)))
    {
      if (unseen && !strncmp (buff, seq_unseen, mutt_strlen (seq_unseen)))
      {
	fprintf (nfp, "%s %d\n", buff, n);
	unseen_done = 1;
      }
      else if (flagged && !strncmp (buff, seq_flagged, mutt_strlen (seq_flagged)))
      {
	fprintf (nfp, "%s %d\n", buff, n);
	flagged_done = 1;
      }
      else if (replied && !strncmp (buff, seq_replied, mutt_strlen (seq_replied)))
      {
	fprintf (nfp, "%s %d\n", buff, n);
	replied_done = 1;
      }
      else
	fprintf (nfp, "%s\n", buff);
    }
  }
  safe_fclose (&ofp);
  safe_free ((void **) &buff);
  
  if (!unseen_done  && unseen)   fprintf (nfp, "%s: %d\n", NONULL (MhUnseen), n);
  if (!flagged_done && flagged)  fprintf (nfp, "%s: %d\n", NONULL (MhFlagged), n);
  if (!replied_done && replied)  fprintf (nfp, "%s: %d\n", NONULL (MhReplied), n);
  
  safe_fclose (&nfp);
  
  unlink (sequences);
  if (safe_rename (tmpfname, sequences) != 0)
    unlink (tmpfname);
  
  safe_free ((void **) &tmpfname);
}
Exemple #8
0
Fichier : mh.c Projet : hww3/pexts
void mh_update_sequences (CONTEXT *ctx)
{
  FILE *ofp, *nfp;
  
  char sequences[_POSIX_PATH_MAX];
  char *tmpfname;
  char *buff = NULL;
  char *p;
  size_t s;
  int l = 0;
  int i;

  int unseen = 0; 
  int flagged = 0;
  int replied = 0;

  char seq_unseen[STRING];
  char seq_replied[STRING];
  char seq_flagged[STRING];

  
  struct mh_sequences mhs;
  memset (&mhs, 0, sizeof (mhs));
  
  snprintf (seq_unseen, sizeof (seq_unseen), "%s:", NONULL (MhUnseen));
  snprintf (seq_replied, sizeof (seq_replied), "%s:", NONULL (MhReplied));
  snprintf (seq_flagged, sizeof (seq_flagged), "%s:", NONULL (MhFlagged));
  
  if (mh_mkstemp (ctx, &nfp, &tmpfname) != 0)
  {
    /* error message? */
    return;
  }

  snprintf (sequences, sizeof (sequences), "%s/.mh_sequences", ctx->path);

  
  /* first, copy unknown sequences */
  if ((ofp = fopen (sequences, "r")))
  {
    while ((buff = mutt_read_line (buff, &s, ofp, &l)))
    {
      if (!mutt_strncmp (buff, seq_unseen, mutt_strlen (seq_unseen)))
	continue;
      if (!mutt_strncmp (buff, seq_flagged, mutt_strlen (seq_flagged)))
	continue;
      if (!mutt_strncmp (buff, seq_replied, mutt_strlen (seq_replied)))
	continue;
	
      fprintf (nfp, "%s\n", buff);
    }
  }
  safe_fclose (&ofp);
  
  /* now, update our unseen, flagged, and replied sequences */
  for (l = 0; l < ctx->msgcount; l++)
  {
    if (ctx->hdrs[l]->deleted)
      continue;
    
    if ((p = strrchr (ctx->hdrs[l]->path, '/')))
      p++;
    else
      p = ctx->hdrs[l]->path;

    i = atoi (p);
    
    if (!ctx->hdrs[l]->read)
    {
      mhs_set (&mhs, i, MH_SEQ_UNSEEN);
      unseen++;
    }
    if (ctx->hdrs[l]->flagged)
    {
      mhs_set (&mhs, i, MH_SEQ_FLAGGED);
      flagged++;
    }
    if (ctx->hdrs[l]->replied)
    {
      mhs_set (&mhs, i, MH_SEQ_REPLIED);
      replied++;
    }
  }

  /* write out the new sequences */
  if (unseen)  mhs_write_one_sequence (nfp, &mhs, MH_SEQ_UNSEEN, NONULL (MhUnseen));
  if (flagged) mhs_write_one_sequence (nfp, &mhs, MH_SEQ_FLAGGED, NONULL (MhFlagged));
  if (replied) mhs_write_one_sequence (nfp, &mhs, MH_SEQ_REPLIED, NONULL (MhReplied));

  mhs_free_sequences (&mhs);

  
  /* try to commit the changes - no guarantee here */
  safe_fclose (&nfp);
  
  unlink (sequences);
  if (safe_rename (tmpfname, sequences) != 0)
  {
    /* report an error? */
    unlink (tmpfname);
  }
  
  safe_free ((void **) &tmpfname);
}
Exemple #9
0
Fichier : mh.c Projet : hww3/pexts
int mh_check_mailbox(CONTEXT *ctx, int *index_hint)
{
  char buf[_POSIX_PATH_MAX], b1[LONG_STRING], b2[LONG_STRING];
  struct stat st, st_cur;
  short modified = 0, have_new = 0, occult = 0;
  struct maildir *md, *p;
  struct maildir **last;
  HASH *fnames;
  int i, j;
  
  if(!option (OPTCHECKNEW))
    return 0;
  
  if(ctx->magic == M_MH)
  {
    strfcpy(buf, ctx->path, sizeof(buf));
    if(stat(buf, &st) == -1)
      return -1;

    /* create .mh_sequences when there isn't one. */
    snprintf (buf, sizeof (buf), "%s/.mh_sequences", ctx->path);
    if (stat (buf, &st_cur) == -1)
    {
      if (errno == ENOENT)
      {
	char *tmp;
	FILE *fp = NULL;

	if (mh_mkstemp (ctx, &fp, &tmp) == 0)
	{
	  safe_fclose (&fp);
	  if (safe_rename (tmp, buf) == -1)
	    unlink (tmp);
	  safe_free ((void **) &tmp);
	}
	
	if (stat (buf, &st_cur) == -1)
	  modified = 1;
      }
      else
	modified = 1;
    }
  }
  else if(ctx->magic == M_MAILDIR)
  {
    snprintf(buf, sizeof(buf), "%s/new", ctx->path);
    if(stat(buf, &st) == -1)
      return -1;
    
    snprintf(buf, sizeof(buf), "%s/cur", ctx->path);
    if(stat(buf, &st_cur) == -1)			/* XXX - name is bad. */
      modified = 1;

  }
  
  if(!modified && ctx->magic == M_MAILDIR && st_cur.st_mtime > ctx->mtime_cur)
    modified = 1;
  
  if(!modified && ctx->magic == M_MH && (st.st_mtime > ctx->mtime || st_cur.st_mtime > ctx->mtime_cur))
    modified = 1;
  
  if(modified || (ctx->magic == M_MAILDIR && st.st_mtime > ctx->mtime))
    have_new = 1;
  
  if(!modified && !have_new)
    return 0;

  ctx->mtime_cur = st_cur.st_mtime;
  ctx->mtime = st.st_mtime;

#if 0
  if(Sort != SORT_ORDER)
  {
    short old_sort;
    
    old_sort = Sort;
    Sort = SORT_ORDER;
    mutt_sort_headers(ctx, 1);
    Sort = old_sort;
  }
#endif

  md = NULL;
  last = &md;

  if(ctx->magic == M_MAILDIR)
  {
    if(have_new)
      maildir_parse_dir(ctx, &last, "new", NULL);
    if(modified)
      maildir_parse_dir(ctx, &last, "cur", NULL);
  }
  else if(ctx->magic == M_MH)
  {
    struct mh_sequences mhs;
    memset (&mhs, 0, sizeof (mhs));
    maildir_parse_dir (ctx, &last, NULL, NULL);
    mh_read_sequences (&mhs, ctx->path);
    mh_update_maildir (md, &mhs);
    mhs_free_sequences (&mhs);
  }

  /* check for modifications and adjust flags */

  fnames = hash_create (1031);
  
  for(p = md; p; p = p->next)
  {
    if(ctx->magic == M_MAILDIR)
    {
      maildir_canon_filename(b2, p->h->path, sizeof(b2));
      p->canon_fname = safe_strdup(b2);
    }
    else
      p->canon_fname = safe_strdup(p->h->path);
    
    hash_insert(fnames, p->canon_fname, p, 0);
  }

  
  for(i = 0; i < ctx->msgcount; i++)
  {
    ctx->hdrs[i]->active = 0;

    if(ctx->magic == M_MAILDIR)
      maildir_canon_filename(b1, ctx->hdrs[i]->path, sizeof(b1));
    else
      strfcpy(b1, ctx->hdrs[i]->path, sizeof(b1));

    dprint(2, (debugfile, "%s:%d: mh_check_mailbox(): Looking for %s.\n", __FILE__, __LINE__, b1));
    
    if((p = hash_find(fnames, b1)) && p->h &&
       mbox_strict_cmp_headers(ctx->hdrs[i], p->h))
    {
      /* found the right message */

      dprint(2, (debugfile, "%s:%d: Found.  Flags before: %s%s%s%s%s\n", __FILE__, __LINE__,
		 ctx->hdrs[i]->flagged ? "f" : "",
		 ctx->hdrs[i]->deleted ? "D" : "",
		 ctx->hdrs[i]->replied ? "r" : "",
		 ctx->hdrs[i]->old     ? "O" : "",
		 ctx->hdrs[i]->read    ? "R" : ""));

      if(mutt_strcmp(ctx->hdrs[i]->path, p->h->path))
	mutt_str_replace (&ctx->hdrs[i]->path, p->h->path);

      if(modified)
      {
	if(!ctx->hdrs[i]->changed)
	{
	  mutt_set_flag (ctx, ctx->hdrs[i], M_FLAG, p->h->flagged);
	  mutt_set_flag (ctx, ctx->hdrs[i], M_REPLIED, p->h->replied);
	  mutt_set_flag (ctx, ctx->hdrs[i], M_READ, p->h->read);
	}

	mutt_set_flag(ctx, ctx->hdrs[i], M_OLD, p->h->old);
      }

      ctx->hdrs[i]->active = 1;

      dprint(2, (debugfile, "%s:%d:         Flags after: %s%s%s%s%s\n", __FILE__, __LINE__,
		 ctx->hdrs[i]->flagged ? "f" : "",
		 ctx->hdrs[i]->deleted ? "D" : "",
		 ctx->hdrs[i]->replied ? "r" : "",
		 ctx->hdrs[i]->old     ? "O" : "",
		 ctx->hdrs[i]->read    ? "R" : ""));

      mutt_free_header(&p->h);
    }
    else if (ctx->magic == M_MAILDIR && !modified && !strncmp("cur/", ctx->hdrs[i]->path, 4))
    {
      /* If the cur/ part wasn't externally modified for a maildir
       * type folder, assume the message is still active. Actually,
       * we simply don't know.
       */

      ctx->hdrs[i]->active = 1;
    }
    else if (modified || (ctx->magic == M_MAILDIR && !strncmp("new/", ctx->hdrs[i]->path, 4)))
    {
      
      /* Mailbox was modified, or a new message vanished. */

      /* Note: This code will _not_ apply for a new message which
       * is just moved to cur/, as this would modify cur's time
       * stamp and lead to modified == 1.  Thus, we'd have parsed
       * the complete folder above, and the message would have
       * been found in the look-up table.
       */
      
      dprint(2, (debugfile, "%s:%d: Not found.  Flags were: %s%s%s%s%s\n", __FILE__, __LINE__,
		 ctx->hdrs[i]->flagged ? "f" : "",
		 ctx->hdrs[i]->deleted ? "D" : "",
		 ctx->hdrs[i]->replied ? "r" : "",
		 ctx->hdrs[i]->old     ? "O" : "",
		 ctx->hdrs[i]->read    ? "R" : ""));
      
      occult = 1;

    }
  }

  /* destroy the file name hash */

  hash_destroy(&fnames, NULL);

  /* If we didn't just get new mail, update the tables. */
  
  if(modified || occult)
  {
    short old_sort;
    int old_count;

#ifndef LIBMUTT
    if (Sort != SORT_ORDER)
    {
      old_sort = Sort;
      Sort = SORT_ORDER;
      mutt_sort_headers (ctx, 1);
      Sort = old_sort;
    }
#endif
  
    old_count = ctx->msgcount;
    for (i = 0, j = 0; i < old_count; i++)
    {
      if (ctx->hdrs[i]->active && index_hint && *index_hint == i)
	*index_hint = j;

      if (ctx->hdrs[i]->active)
	ctx->hdrs[i]->index = j++;
    }
    mx_update_tables(ctx, 0);
  }

  /* Incorporate new messages */

  maildir_move_to_context(ctx, &md);

  return (modified || occult) ? M_REOPENED : have_new ? M_NEW_MAIL : 0;
}
Exemple #10
0
Fichier : mh.c Projet : hww3/pexts
static int mh_rewrite_message (CONTEXT *ctx, int msgno)
{
  HEADER *h = ctx->hdrs[msgno];
  MESSAGE *dest;

  int rc;
  short restore = 1;
  char oldpath[_POSIX_PATH_MAX];
  char newpath[_POSIX_PATH_MAX];
  char partpath[_POSIX_PATH_MAX];

  long old_body_offset = h->content->offset;
  long old_body_length = h->content->length;
  long old_hdr_lines   = h->lines;

  if ((dest = mx_open_new_message (ctx, h, 0)) == NULL)
    return -1;

  if ((rc = mutt_copy_message (dest->fp, ctx, h, 
	       M_CM_UPDATE, CH_UPDATE | CH_UPDATE_LEN)) == 0)
  {
    snprintf (oldpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path);
    strfcpy  (partpath, h->path, _POSIX_PATH_MAX);

    if (ctx->magic == M_MAILDIR)
      rc = maildir_commit_message (ctx, dest, h);
    else
      rc = _mh_commit_message (ctx, dest, h, 0);
    
    mx_close_message (&dest);

    if (rc == 0)
    {
      unlink (oldpath);
      restore = 0;
    }

    /* 
     * Try to move the new message to the old place.
     * (MH only.)
     *
     * This is important when we are just updating flags.
     *
     * Note that there is a race condition against programs which
     * use the first free slot instead of the maximum message
     * number.  Mutt does _not_ behave like this.
     * 
     * Anyway, if this fails, the message is in the folder, so
     * all what happens is that a concurrently runnung mutt will
     * lose flag modifications.
     */

    if (ctx->magic == M_MH && rc == 0)
    {
      snprintf (newpath, _POSIX_PATH_MAX, "%s/%s", ctx->path, h->path);
      if ((rc = safe_rename (newpath, oldpath)) == 0)
	mutt_str_replace (&h->path, partpath);
    }
  }
  else 
    mx_close_message (&dest);

  if (rc == -1 && restore)
  {
    h->content->offset = old_body_offset;
    h->content->length = old_body_length;
    h->lines           = old_hdr_lines;
  }

  mutt_free_body (&h->content->parts);
  return rc;
}
Exemple #11
0
/* run the real compiler and put the result in cache */
static void to_cache(ARGS *args)
{
	char *path_stderr;
	char *tmp_stdout, *tmp_stderr, *tmp_outfiles;
	struct stat st1;
	int status;
	int cached_files_count = 0;
	int files_size = 0;

	x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir, tmp_string());
	x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string());
	x_asprintf(&tmp_outfiles, "%s/tmp.outfiles.%s", temp_dir, tmp_string());

	if (strip_c_option && !swig) {
		args_add(stripped_args, "-c");
	}

	if (output_file) {
		args_add(args, "-o");
		args_add(args, output_file);
	}

	/* Turn off DEPENDENCIES_OUTPUT when running cc1, because
	 * otherwise it will emit a line like
	 *
	 *  tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i
	 *
	 * unsetenv() is on BSD and Linux but not portable. */
	putenv("DEPENDENCIES_OUTPUT");

	/* Give SWIG a filename for it to create and populate with a list of files that it generates */
	if (swig) {
		char *ccache_outfiles;
		x_asprintf(&ccache_outfiles, "CCACHE_OUTFILES=%s", tmp_outfiles);
		unlink(tmp_outfiles);
		if (getenv("CCACHE_OUTFILES") || putenv(ccache_outfiles) == -1) {
			cc_log("CCACHE_OUTFILES env variable already set or could not be set\n");
			stats_update(STATS_ERROR);
			failed();
		}
	}
	
	if (getenv("CCACHE_CPP2")) {
		args_add(args, input_file);
	} else {
		if (swig) {
			args_add(args, "-nopreprocess");
		}
		args_add(args, i_tmpfile);
	}
	status = execute(args->argv, tmp_stdout, tmp_stderr);
	args_pop(args, 3);

	if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) {
		cc_log("compiler produced stdout for %s\n", input_file);
		stats_update(STATS_STDOUT);
		unlink(tmp_stdout);
		unlink(tmp_stderr);
		unlink(tmp_outfiles);
		if (!swig) unlink(output_file);
		failed();
	}
	unlink(tmp_stdout);

	if (status != 0) {
		int fd;
		cc_log("compile of %s gave status = %d\n", input_file, status);
		stats_update(STATS_STATUS);

		fd = open(tmp_stderr, O_RDONLY | O_BINARY);
		if (fd != -1) {
			if (cpp_stderr) {
				/* we might have some stderr from cpp */
				int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY);
				if (fd2 != -1) {
					copy_fd(fd2, 2);
					close(fd2);
					unlink(cpp_stderr);
					cpp_stderr = NULL;
				}
			}

			/* we can use a quick method of
			   getting the failed output */
			copy_fd(fd, 2);
			close(fd);
			unlink(tmp_stderr);
			if (i_tmpfile && !direct_i_file) {
				unlink(i_tmpfile);
			}
			exit(status);
		}
		
		unlink(tmp_stderr);
		unlink(tmp_outfiles);
		if (!swig) unlink(output_file);
		failed();
	} else {
		int hardlink = (getenv("CCACHE_NOCOMPRESS") != 0) && (getenv("CCACHE_HARDLINK") != 0);
		if (swig) {
			/* read the list of generated files and copy each of them into the cache */
			FILE *file;
			file = fopen(tmp_outfiles, "r");
			if (file) {
				char out_filename[FILENAME_MAX + 1];
				char out_filename_cache[FILENAME_MAX + 1];
				while (fgets(out_filename, FILENAME_MAX, file)) {
					char *linefeed = strchr(out_filename, '\n');
					if (linefeed) {
						char *potential_cr = linefeed - 1;
						if (potential_cr >= out_filename && *potential_cr == '\r')
						  *potential_cr = 0;
						*linefeed = 0;

						if (cached_files_count == 0) {
							strcpy(out_filename_cache, hashname);
						} else {
							sprintf(out_filename_cache, "%s.%d", hashname, cached_files_count);
						}

						if (commit_to_cache(out_filename, out_filename_cache, hardlink) != 0) {
							fclose(file);
							unlink(tmp_outfiles);
							failed();
						}
						to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count);
					} else {
						cached_files_count = 0;
						break;
					}
				}
				fclose(file);
				if (cached_files_count == 0) {
					cc_log("failed to copy output files to cache - internal error\n");
					stats_update(STATS_ERROR);
					unlink(tmp_outfiles);
					failed();
				}

				/* also copy the (uncompressed) file containing the list of generated files into the cache */
				sprintf(out_filename_cache, "%s.outfiles", hashname);
				if (stat(tmp_outfiles, &st1) != 0 ||
					safe_rename(tmp_outfiles, out_filename_cache) != 0) {
					cc_log("failed to copy outfiles file to cache - %s\n", strerror(errno));
					stats_update(STATS_ERROR);
					unlink(tmp_outfiles);
					failed();
				}
				to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count);
				unlink(tmp_outfiles);
			} else {
				cc_log("failed to open temp outfiles file - %s\n", strerror(errno));
				stats_update(STATS_ERROR);
				failed();
			}
		} else {
			if (commit_to_cache(output_file, hashname, hardlink) != 0) {
				failed();
			}
			to_cache_stats_helper(&st1, hashname, 0, &files_size, &cached_files_count);
		}
	}

	x_asprintf(&path_stderr, "%s.stderr", hashname);

	if (stat(tmp_stderr, &st1) != 0 ||
		move_file(tmp_stderr, path_stderr) != 0) {
		cc_log("failed to rename tmp files - %s\n", strerror(errno));
		stats_update(STATS_ERROR);
		failed();
	}

	to_cache_stats_helper(&st1, path_stderr, 0, &files_size, &cached_files_count);

	cc_log("Placed %d files for %s into cache\n", cached_files_count, input_file);
	stats_tocache(files_size, cached_files_count);

	free(tmp_stderr);
	free(tmp_stdout);
	free(tmp_outfiles);
	free(path_stderr);
}