Exemplo n.º 1
0
static int logfile_cycle()
{
	logfile_t *log;
	int i;
	char suffix[32];
	char *newfname;

	putlog(LOG_MISC, "*", _("Cycling logfiles..."));
	flushlogs();

	/* Determine suffix for cycled logfiles. */
	if (core_config.logging.keep_all) {
		strftime(suffix, 32, core_config.logging.suffix, localtime(&now));
	}

	for (i = nlogfiles - 1; i >= 0; i--) {
		log = &logfiles[i];

		fclose(log->fp);

		if (core_config.logging.keep_all) newfname = egg_mprintf("%s%s", log->filename, suffix);
		else newfname = egg_mprintf("%s.yesterday", log->filename);

		unlink(newfname);
		movefile(log->filename, newfname);
		free(newfname);

		log->fp = fopen(log->filename, "a");
		if (!log->fp) logfile_del(log->filename);
	}
	
	return(0);
}
Exemplo n.º 2
0
/* Converts old versions of the filedb to the newest. Returns 1 if all went
 * well and otherwise 0. The new db is first written to a temporary place
 * and then moved over to the original db's position.
 *
 * Note: Unfortunately there is a small time-frame where aren't locking the
 *       DB, but want to replace it with a new one, using movefile().
 *       TODO: Copy old db to tmp file and then build the new db directly
 *             in the original file. This solves the tiny locking problem.
 *
 * Also remember to check the returned *fdb_s on failure, as it could be
 * NULL.
 */
static int convert_old_db(FILE ** fdb_s, char *filedb)
{
    filedb_top fdbt;
    FILE *fdb_t;
    int ret = 0;                  /* Default to 'failure' */

    filedb_readtop(*fdb_s, &fdbt);
    /* Old DB version? */
    if (fdbt.version > 0 && fdbt.version < FILEDB_VERSION3) {
        char *tempdb;

        putlog(LOG_MISC, "*", "Converting old filedb %s to newest format.",
               filedb);
        /* Create temp DB name */
        tempdb = nmalloc(strlen(filedb) + 5);
        simple_sprintf(tempdb, "%s-tmp", filedb);

        fdb_t = fopen(tempdb, "w+b");       /* Open temp DB         */
        if (fdb_t) {
            filedb_initdb(fdb_t);     /* Initialise new DB    */

            /* Convert old database to new one, saving
             * in temporary db file
             */
            if (fdbt.version == FILEDB_VERSION1)
                convert_version1(*fdb_s, fdb_t);        /* v1 -> v3             */
            else
                convert_version2(*fdb_s, fdb_t);        /* v2 -> v3             */

            unlockfile(*fdb_s);
            fclose(fdb_t);
            fclose(*fdb_s);

            /* Move over db to new location */
            if (movefile(tempdb, filedb))
                putlog(LOG_MISC, "*", "(!) Moving file db from %s to %s failed.",
                       tempdb, filedb);

            *fdb_s = fopen(filedb, "r+b");    /* Reopen new db        */
            if (*fdb_s) {
                lockfile(*fdb_s);
                /* Now we should have recreated the original situation,
                 * with the file pointer just pointing to the new version
                 * of the DB instead of the original one.
                 */
                ret = 1;
            } else
                putlog(LOG_MISC, "*", "(!) Reopening db %s failed.", filedb);
        }
        my_free(tempdb);
        /* Database already at the newest version? */
    } else if (fdbt.version == FILEDB_VERSION3)
        ret = 1;
    else
        putlog(LOG_MISC, "*", "(!) Unknown db version: %d", fdbt.version);
    if (!ret)
        putlog(LOG_MISC, "*", "Conversion of filedb %s failed.", filedb);
    return ret;
}
Exemplo n.º 3
0
void
dotrim(struct conf_entry *ent)
{
	char file1[MAXPATHLEN], file2[MAXPATHLEN], oldlog[MAXPATHLEN];
	int fd;

	/* Is there a separate backup dir? */
	if (ent->backdir != NULL)
		snprintf(oldlog, sizeof(oldlog), "%s/%s", ent->backdir,
		    ent->logbase);
	else
		strlcpy(oldlog, ent->log, sizeof(oldlog));

	if (ent->numlogs > 0)
		rotate(ent, oldlog);
	if (!noaction && !(ent->flags & CE_BINARY))
		(void)log_trim(ent->log);

	(void)snprintf(file2, sizeof(file2), "%s.XXXXXXXXXX", ent->log);
	if (noaction)  {
		printf("\tmktemp %s\n", file2);
	} else {
		if ((fd = mkstemp(file2)) < 0)
			err(1, "can't start '%s' log", file2);
		if (fchmod(fd, ent->permissions))
			err(1, "can't chmod '%s' log file", file2);
		if (fchown(fd, ent->uid, ent->gid))
			err(1, "can't chown '%s' log file", file2);
		(void)close(fd);
		/* Add status message */
		if (!(ent->flags & CE_BINARY) && log_trim(file2))
			err(1, "can't add status message to log '%s'", file2);
	}

	if (ent->numlogs == 0) {
		if (noaction)
			printf("\trm %s\n", ent->log);
		else if (unlink(ent->log))
			warn("can't rm %s", ent->log);
	} else {
		(void)snprintf(file1, sizeof(file1), "%s.0", oldlog);
		if (noaction) {
			printf("\tmv %s to %s\n", ent->log, file1);
			printf("\tchmod %o %s\n", ent->permissions, file1);
			printf("\tchown %u:%u %s\n", ent->uid, ent->gid, file1);
		} else if (movefile(ent->log, file1, ent->uid, ent->gid,
		    ent->permissions))
			warn("can't mv %s to %s", ent->log, file1);
	}

	/* Now move the new log file into place */
	if (noaction)
		printf("\tmv %s to %s\n", file2, ent->log);
	else if (rename(file2, ent->log))
		warn("can't mv %s to %s", file2, ent->log);
}
Exemplo n.º 4
0
/* Get rid of old useless notes.
 */
static void expire_notes()
{
  FILE *f, *g;
  char s[513], *to, *from, *ts, *s1;
  int tot = 0, lapse;

  if (!notefile[0])
    return;
  f = fopen(notefile, "r");
  if (f == NULL)
    return;
  sprintf(s, "%s~new", notefile);
  g = fopen(s, "w");
  if (g == NULL) {
    fclose(f);
    return;
  }
  chmod(s, userfile_perm);      /* Use userfile permissions. */
  while (!feof(f)) {
    fgets(s, 512, f);
    if (!feof(f)) {
      if (s[strlen(s) - 1] == '\n')
        s[strlen(s) - 1] = 0;
      rmspace(s);
      if ((s[0]) && (s[0] != '#') && (s[0] != ';')) {   /* Not comment */
        s1 = s;
        to = newsplit(&s1);
        from = newsplit(&s1);
        ts = newsplit(&s1);
        lapse = (now - (time_t) atoi(ts)) / 86400;
        if (lapse > note_life)
          tot++;
        else if (!get_user_by_handle(userlist, to))
          tot++;
        else
          fprintf(g, "%s %s %s %s\n", to, from, ts, s1);
      } else
        fprintf(g, "%s\n", s);
    }
  }
  fclose(f);
  fclose(g);
  unlink(notefile);
  sprintf(s, "%s~new", notefile);
  movefile(s, notefile);
  if (tot > 0)
    putlog(LOG_MISC, "*", NOTES_EXPIRED, tot, tot == 1 ? "" : "s");
}
Exemplo n.º 5
0
/* Change someone's handle.
 */
static void notes_change(char *oldnick, char *newnick)
{
  FILE *f, *g;
  char s[513], *to, *s1;
  int tot = 0;

  if (!egg_strcasecmp(oldnick, newnick))
    return;
  if (!notefile[0])
    return;
  f = fopen(notefile, "r");
  if (f == NULL)
    return;
  sprintf(s, "%s~new", notefile);
  g = fopen(s, "w");
  if (g == NULL) {
    fclose(f);
    return;
  }
  chmod(s, userfile_perm);      /* Use userfile permissions. */
  while (!feof(f)) {
    fgets(s, 512, f);
    if (!feof(f)) {
      if (s[strlen(s) - 1] == '\n')
        s[strlen(s) - 1] = 0;
      rmspace(s);
      if ((s[0]) && (s[0] != '#') && (s[0] != ';')) {   /* Not comment */
        s1 = s;
        to = newsplit(&s1);
        if (!egg_strcasecmp(to, oldnick)) {
          tot++;
          fprintf(g, "%s %s\n", newnick, s1);
        } else
          fprintf(g, "%s %s\n", to, s1);
      } else
        fprintf(g, "%s\n", s);
    }
  }
  fclose(f);
  fclose(g);
  unlink(notefile);
  sprintf(s, "%s~new", notefile);
  movefile(s, notefile);
  putlog(LOG_MISC, "*", NOTES_SWITCHED_NOTES, tot, tot == 1 ? "" : "s",
         oldnick, newnick);
}
AppendBehavior PatchFilesResourceSource::AppendResources(const std::vector<const ResourceBlob*> &blobs)
{
    for (const ResourceBlob *blob : blobs)
    {
        std::string filename = GetFileNameFor(*blob);
        std::string fullPath = _gameFolder + "\\" + filename;
        std::string bakPath = _gameFolder + "\\" + filename + ".bak";
        // Write to the bak file
        {
            ScopedFile file(bakPath, GENERIC_WRITE, 0, CREATE_ALWAYS);
            blob->SaveToHandle(file.hFile, true);
        }
        // move it to the main guy
        deletefile(fullPath);
        movefile(bakPath, fullPath);
    }
    return AppendBehavior::Replace;
}
Exemplo n.º 7
0
/* Compresses a file `filename' and saves it as `filename'.
 */
int compress_file(char *filename, int mode_num)
{
  char *temp_fn = NULL, randstr[5] = "";
  int ret;

  /* Create temporary filename. */
  temp_fn = (char *) my_calloc(1, strlen(filename) + 5);
  make_rand_str(randstr, 4);
  strcpy(temp_fn, filename);
  strcat(temp_fn, randstr);

  /* Compress file. */
  ret = compress_to_file(filename, temp_fn, mode_num);

  /* Overwrite old file with compressed version.  Only do so
   * if the compression routine succeeded.
   */
  if (ret == COMPF_SUCCESS)
    movefile(temp_fn, filename);

  free(temp_fn);
  return ret;
}
Exemplo n.º 8
0
/* Uncompresses a file `filename' and saves it as `filename'.
 */
static int uncompress_file(char *filename)
{
  char *temp_fn, randstr[5];
  int ret;

  /* Create temporary filename. */
  temp_fn = nmalloc(strlen(filename) + 5);
  make_rand_str(randstr, 4);
  strcpy(temp_fn, filename);
  strcat(temp_fn, randstr);

  /* Uncompress file. */
  ret = uncompress_to_file(filename, temp_fn);

  /* Overwrite old file with uncompressed version.  Only do so
   * if the uncompression routine succeeded.
   */
  if (ret == COMPF_SUCCESS)
    movefile(temp_fn, filename);

  nfree(temp_fn);
  return ret;
}
Exemplo n.º 9
0
static void check_logsizes()
{
	int size, i;
	char *newfname;

	if (core_config.logging.keep_all || core_config.logging.max_size <= 0) return;

	for (i = 0; i < nlogfiles; i++) {
		logfile_t *log = &logfiles[i];
		
		size = ftell(log->fp) / 1024; /* Size in kilobytes. */
		if (size < core_config.logging.max_size) continue;

		/* It's too big. */
		putlog(LOG_MISC, "*", _("Cycling logfile %s: over max-logsize (%d kilobytes)."), log->filename, size);
		fclose(log->fp);

		newfname = egg_mprintf("%s.yesterday", log->filename);
		unlink(newfname);
		movefile(log->filename, newfname);
		free(newfname);
	}
}
Exemplo n.º 10
0
/**
 * Perform rotation
 * 
 * @param   first  The first image
 * @param   diff   The index difference between successive images
 * @param   end    The image after the last image
 * @return         Zero on success, -1 on error
 */
static int perform_rotate(size_t first, size_t diff, size_t end)
{
  char* command[] = { (char*)"gm", (char*)"convert", buffer1,
		      (char*)"-flip", (char*)"-flop", buffer2, NULL };
  size_t i;
  pid_t pid;
  int status;
  
  for (i = first; i < end; i += diff)
    {
      sprintf(buffer1, "%zu.pnm", i);
      sprintf(buffer2, "%zu.temp.pnm", i);
      if (access(buffer1, F_OK))
	break;
      
      pid = fork();
      t (pid < 0);
      
      if (pid == 0)
	execvp(*command, command), perror(*command), exit(1);
      
    rewait:
      if (waitpid(pid, &status, 0) < 0)
	{
	  t (errno != EINTR);
	  goto rewait;
	}
      if (status)
	return errno = 0, -1;
      
      t (unlink(buffer1) || movefile(buffer2, buffer1));
    }
  
  return 0;
 fail:
  return -1;
}
Exemplo n.º 11
0
void Banlist_writebans()
/*
 * Prefix codes are:
 *    'n' - <nick>
 *    'b' - <ban>
 *    't' - <time_set>
 *    'e' - <expires>
 *    'u' - <used>
 */
{
	FILE	*f;
	banlrec	*b;
	int	x;
	char	banlist[256], tmpfile[256];

	/* bail if banlist is inactive (pending read) */
	if(!(Banlist->flags & BANLIST_ACTIVE))
	{
		Log_write(LOG_MAIN,"*","Banlist list is not active.  Ignoring write request.");
		return;
	}

	/* Open for writing */
	sprintf(banlist,"%s/%s",Grufti->botdir,Grufti->banlist);
	sprintf(tmpfile,"%s.tmp",banlist);
	f = fopen(tmpfile,"w");
	if(f == NULL)
	{
		Log_write(LOG_MAIN|LOG_ERROR,"*","Couldn't write banlist.");
		return;
	}

	/* write header */
	writeheader(f,"Banlist->banlist - The shitlist",banlist);

	/* write each record */
	for(b=Banlist->banlist; b!=NULL; b=b->next)
	{
		/* Write nick */
		if(fprintf(f,"n %s\n",b->nick) == EOF)
			return;

		/* Write ban */
		if(fprintf(f,"b %s\n",b->ban) == EOF)
			return;

		/* Write time */
		if(fprintf(f,"t %lu\n",(u_long)b->time_set) == EOF)
			return;

		/* Write expires */
		if(fprintf(f,"e %lu\n",(u_long)b->expires) == EOF)
			return;

		/* Write used */
		if(fprintf(f,"u %d\n",b->used) == EOF)
			return;
	}

	fclose(f);

	/* Move tmpfile over to main response */
	if(Grufti->keep_tmpfiles)
		x = copyfile(tmpfile,banlist);
	else
		x = movefile(tmpfile,banlist);

	verify_write(x,tmpfile,banlist);
	if(x == 0)
	{
		Log_write(LOG_MAIN,"*","Wrote banlist.");
		Banlist->flags &= ~BANLIST_NEEDS_WRITE;
	}
}
Exemplo n.º 12
0
static int tcl_mv_cp(Tcl_Interp *irp, int argc, char **argv, int copy)
{
  char *p, *fn = NULL, *oldpath = NULL, *s = NULL, *s1 = NULL;
  char *newfn = NULL, *newpath = NULL;
  int ok = 0, only_first, skip_this;
  FILE *fdb_old, *fdb_new;
  filedb_entry *fdbe_old, *fdbe_new;
  long where;

  BADARGS(3, 3, " oldfilepath newfilepath");

  malloc_strcpy(fn, argv[1]);
  p = strrchr(fn, '/');
  if (p != NULL) {
    *p = 0;
    malloc_strcpy(s, fn);
    strcpy(fn, p + 1);
    if (!resolve_dir("/", s, &oldpath, -1)) {
      /* Tcl can do * anything */
      Tcl_AppendResult(irp, "-1", NULL);        /* Invalid source */
      my_free(fn);
      my_free(oldpath);
      return TCL_OK;
    }
    my_free(s);
  } else
    malloc_strcpy(oldpath, "/");
  malloc_strcpy(s, argv[2]);
  if (!resolve_dir("/", s, &newpath, -1)) {
    /* Destination is not just a directory */
    p = strrchr(s, '/');
    if (!p) {
      malloc_strcpy(newfn, s);
      s[0] = 0;
    } else {
      *p = 0;
      malloc_strcpy(newfn, p + 1);
    }
    my_free(newpath);
    if (!resolve_dir("/", s, &newpath, -1)) {
      Tcl_AppendResult(irp, "-2", NULL);        /* Invalid desto */
      my_free(newpath);
      my_free(s);
      my_free(newfn);
      return TCL_OK;
    }
  } else
    malloc_strcpy(newfn, "");
  my_free(s);

  /* Stupidness checks */
  if ((!strcmp(oldpath, newpath)) && (!newfn[0] || !strcmp(newfn, fn))) {
    my_free(newfn);
    my_free(fn);
    my_free(oldpath);
    my_free(newpath);
    Tcl_AppendResult(irp, "-3", NULL);  /* Stupid copy to self */
    return TCL_OK;
  }
  /* Be aware of 'cp * this.file' possibility: ONLY COPY FIRST ONE */
  if ((strchr(fn, '?') || strchr(fn, '*')) && newfn[0])
    only_first = 1;
  else
    only_first = 0;

  fdb_old = filedb_open(oldpath, 0);
  if (!strcmp(oldpath, newpath))
    fdb_new = fdb_old;
  else
    fdb_new = filedb_open(newpath, 0);
  if (!fdb_old || !fdb_new) {
    my_free(newfn);
    my_free(fn);
    my_free(oldpath);
    my_free(newpath);
    if (fdb_old)
      filedb_close(fdb_old);
    else if (fdb_new)
      filedb_close(fdb_new);
    Tcl_AppendResult(irp, "-5", NULL);  /* DB access failed */
    return -1;
  }

  filedb_readtop(fdb_old, NULL);
  fdbe_old = filedb_matchfile(fdb_old, ftell(fdb_old), fn);
  if (!fdbe_old) {
    my_free(newfn);
    my_free(fn);
    my_free(oldpath);
    my_free(newpath);
    if (fdb_new != fdb_old)
      filedb_close(fdb_new);
    filedb_close(fdb_old);
    Tcl_AppendResult(irp, "-4", NULL);  /* No match */
    return -2;
  }
  while (fdbe_old) {
    where = ftell(fdb_old);
    skip_this = 0;
    if (!(fdbe_old->stat & (FILE_HIDDEN | FILE_DIR))) {
      s = nmalloc(strlen(dccdir) + strlen(oldpath)
                  + strlen(fdbe_old->filename) + 2);
      s1 = nmalloc(strlen(dccdir) + strlen(newpath)
                   + strlen(newfn[0] ? newfn : fdbe_old->filename) + 2);
      sprintf(s, "%s%s%s%s", dccdir, oldpath,
              oldpath[0] ? "/" : "", fdbe_old->filename);
      sprintf(s1, "%s%s%s%s", dccdir, newpath,
              newpath[0] ? "/" : "", newfn[0] ? newfn : fdbe_old->filename);
      if (!strcmp(s, s1)) {
        Tcl_AppendResult(irp, "-3", NULL);      /* Stupid copy to self */
        skip_this = 1;
      }
      /* Check for existence of file with same name in new dir */
      filedb_readtop(fdb_new, NULL);
      fdbe_new = filedb_matchfile(fdb_new, ftell(fdb_new),
                                  newfn[0] ? newfn : fdbe_old->filename);
      if (fdbe_new) {
        /* It's ok if the entry in the new dir is a normal file (we'll
         * just scrap the old entry and overwrite the file) -- but if
         * it's a directory, this file has to be skipped.
         */
        if (fdbe_new->stat & FILE_DIR)
          skip_this = 1;
        else
          filedb_delfile(fdb_new, fdbe_new->pos);
        free_fdbe(&fdbe_new);
      }
      if (!skip_this) {
        if ((fdbe_old->sharelink) ||
            ((copy ? copyfile(s, s1) : movefile(s, s1)) == 0)) {
          /* Raw file moved okay: create new entry for it */
          ok++;
          fdbe_new = malloc_fdbe();
          fdbe_new->stat = fdbe_old->stat;
          /* We don't have to worry about any entries to be
           * NULL, because malloc_strcpy takes care of that.
           */
          malloc_strcpy(fdbe_new->flags_req, fdbe_old->flags_req);
          malloc_strcpy(fdbe_new->chan, fdbe_old->chan);
          malloc_strcpy(fdbe_new->filename, fdbe_old->filename);
          malloc_strcpy(fdbe_new->desc, fdbe_old->desc);
          if (newfn[0])
            malloc_strcpy(fdbe_new->filename, newfn);
          malloc_strcpy(fdbe_new->uploader, fdbe_old->uploader);
          fdbe_new->uploaded = fdbe_old->uploaded;
          fdbe_new->size = fdbe_old->size;
          fdbe_new->gots = fdbe_old->gots;
          malloc_strcpy(fdbe_new->sharelink, fdbe_old->sharelink);
          filedb_addfile(fdb_new, fdbe_new);
          if (!copy)
            filedb_delfile(fdb_old, fdbe_old->pos);
          free_fdbe(&fdbe_new);
        }
      }
      my_free(s);
      my_free(s1);
    }
    free_fdbe(&fdbe_old);
    fdbe_old = filedb_matchfile(fdb_old, where, fn);
    if (ok && only_first) {
      free_fdbe(&fdbe_old);
    }
  }
  if (fdb_old != fdb_new)
    filedb_close(fdb_new);
  filedb_close(fdb_old);
  if (!ok)
    Tcl_AppendResult(irp, "-4", NULL);  /* No match */
  else {
    char x[30];

    sprintf(x, "%d", ok);
    Tcl_AppendResult(irp, x, NULL);
  }
  my_free(newfn);
  my_free(fn);
  my_free(oldpath);
  my_free(newpath);
  return TCL_OK;
}
Exemplo n.º 13
0
static void filedb_update(char *path, FILE * f, int sort)
{
  struct dirent *dd;
  DIR *dir;
  filedb fdb[2];
  char name[61];
  long where, oldwhere;
  struct stat st;
  char s[512];
  int ret;

  /* FIRST: make sure every real file is in the database */
  dir = opendir(path);
  if (dir == NULL) {
    putlog(LOG_MISC, "*", FILES_NOUPDATE);
    return;
  }
  dd = readdir(dir);
  while (dd != NULL) {
    strncpy(name, dd->d_name, 60);
    name[60] = 0;
    if (NAMLEN(dd) <= 60)
      name[NAMLEN(dd)] = 0;
    else {
      /* truncate name on disk */
      char s1[512], s2[256];

      strcpy(s1, path);
      strcat(s1, "/");
      strncat(s1, dd->d_name, NAMLEN(dd));
      s1[strlen(path) + NAMLEN(dd) + 1] = 0;
      sprintf(s2, "%s/%s", path, name);
      movefile(s1, s2);
    }
    if (name[0] != '.') {
      sprintf(s, "%s/%s", path, name);
      stat(s, &st);
      where = 0;
      ret = findmatch(f, name, &where, &fdb[0]);
      if (!ret) {
	/* new file! */
	where = findempty(f);
	fseek(f, where, SEEK_SET);
	fdb[0].version = FILEVERSION;
	fdb[0].stat = 0;	/* by default, visible regular file */
	strcpy(fdb[0].filename, name);
	fdb[0].desc[0] = 0;
	strcpy(fdb[0].uploader, botnetnick);
	fdb[0].gots = 0;
	fdb[0].flags_req[0] = 0;
	fdb[0].uploaded = now;
	fdb[0].size = st.st_size;
	fdb[0].sharelink[0] = 0;
	if (S_ISDIR(st.st_mode))
	  fdb[0].stat |= FILE_DIR;
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      } else if (fdb[0].version < FILEVERSION) {
	/* old version filedb, do the dirty */
	if (fdb[0].version == FILEVERSION_OLD) {
	  filedb_old *fdbo = (filedb_old *) & fdb[0];

	  fdb[0].desc[185] = 0;	/* truncate it */
	  fdb[0].chname[0] = 0;	/* new entry */
	  strcpy(fdb[0].uploader, fdbo->uploader);	/* moved forward
							 * a few bytes */
	  strcpy(fdb[0].flags_req, fdbo->flags_req);	/* and again */
	  fdb[0].version = FILEVERSION;
	  fdb[0].size = st.st_size;
	  fseek(f, where, SEEK_SET);
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	} else {
	  putlog(LOG_MISC, "*", "!!! Unknown filedb type !");
	}
      } else {
	/* update size if needed */
	fdb[0].size = st.st_size;
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      }
    }
    dd = readdir(dir);
  }
  closedir(dir);
  /* SECOND: make sure every db file is real, and sort as we go,
   * if we're sorting */
  rewind(f);
  while (!feof(f)) {
    where = ftell(f);
    fread(&fdb[0], sizeof(filedb), 1, f);
    if (!feof(f)) {
      if (!(fdb[0].stat & FILE_UNUSED) && !fdb[0].sharelink[0]) {
	sprintf(s, "%s/%s", path, fdb[0].filename);
	if (stat(s, &st) != 0) {
	  /* gone file */
	  fseek(f, where, SEEK_SET);
	  fdb[0].stat |= FILE_UNUSED;
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	  /* sunos and others will puke bloody chunks if you write the
	   * last record in a file and then attempt to read to EOF: */
	  fseek(f, where, SEEK_SET);
	  continue;		/* cycle to next one */
	}
      }
      if (sort && !(fdb[0].stat & FILE_UNUSED)) {
	rewind(f);
	oldwhere = ftell(f);
	ret = 0;
	while (!feof(f) && (oldwhere < where)) {
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  if (!feof(f)) {
	    if ((fdb[0].stat & FILE_UNUSED) ||
		(strcasecmp(fdb[ret].filename,
			    fdb[1 - ret].filename) < 0)) {
	      /* our current is < the checked one, insert here */
	      fseek(f, oldwhere, SEEK_SET);
	      fwrite(&fdb[ret], sizeof(filedb), 1, f);
	      ret = 1 - ret;
	      /* and fall out */
	    }
	    /* otherwise read next entry */
	    oldwhere = ftell(f);
	  }
	}
	/* here, either we've found a place to insert, or got to
	 * the end of the list */
	/* if we've got to the end of the current list oldwhere == where
	 * so we fall through ret will point to the current valid one */
	while (!feof(f) && (oldwhere < where)) {
	  /* need to move this entry up 1 .. */
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  oldwhere = ftell(f);
	  /* write lower record here */
	  fseek(f, oldwhere, SEEK_SET);
	  fwrite(&fdb[ret], sizeof(filedb), 1, f);
	  ret = 1 - ret;
	}
	/* when we get here fdb[ret] holds the last record,
	 * which needs  to be written where we first grabbed the
	 * record from */
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[ret], sizeof(filedb), 1, f);
      }
    }
  }
  /* write new timestamp */
  filedb_timestamp(f);
}
Exemplo n.º 14
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
          botnetnick, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f,
            "channel add %s { chanmode %s idle-kick %d stopnethack-mode %d "
            "revenge-mode %d need-op %s need-invite %s need-key %s "
            "need-unban %s need-limit %s flood-chan %d:%d flood-ctcp %d:%d "
            "flood-join %d:%d flood-kick %d:%d flood-deop %d:%d "
            "flood-nick %d:%d aop-delay %d:%d ban-type %d ban-time %d "
            "exempt-time %d invite-time %d %cenforcebans %cdynamicbans "
            "%cuserbans %cautoop %cautohalfop %cbitch %cgreet %cprotectops "
            "%cprotecthalfops %cprotectfriends %cdontkickops %cstatuslog "
            "%crevenge %crevengebot %cautovoice %csecret %cshared %ccycle "
            "%cseen %cinactive %cdynamicexempts %cuserexempts %cdynamicinvites "
            "%cuserinvites %cnodesynch %cstatic }" "\n",
            name, w2, chan->idle_kick, chan->stopnethack_mode,
            chan->revenge_mode, need1, need2, need3, need4, need5,
            chan->flood_pub_thr, chan->flood_pub_time,
            chan->flood_ctcp_thr, chan->flood_ctcp_time,
            chan->flood_join_thr, chan->flood_join_time,
            chan->flood_kick_thr, chan->flood_kick_time,
            chan->flood_deop_thr, chan->flood_deop_time,
            chan->flood_nick_thr, chan->flood_nick_time,
            chan->aop_min, chan->aop_max, chan->ban_type, chan->ban_time,
            chan->exempt_time, chan->invite_time,
            PLSMNS(channel_enforcebans(chan)),
            PLSMNS(channel_dynamicbans(chan)),
            PLSMNS(!channel_nouserbans(chan)),
            PLSMNS(channel_autoop(chan)),
            PLSMNS(channel_autohalfop(chan)),
            PLSMNS(channel_bitch(chan)),
            PLSMNS(channel_greet(chan)),
            PLSMNS(channel_protectops(chan)),
            PLSMNS(channel_protecthalfops(chan)),
            PLSMNS(channel_protectfriends(chan)),
            PLSMNS(channel_dontkickops(chan)),
            PLSMNS(channel_logstatus(chan)),
            PLSMNS(channel_revenge(chan)),
            PLSMNS(channel_revengebot(chan)),
            PLSMNS(channel_autovoice(chan)),
            PLSMNS(channel_secret(chan)),
            PLSMNS(channel_shared(chan)),
            PLSMNS(channel_cycle(chan)),
            PLSMNS(channel_seen(chan)),
            PLSMNS(channel_inactive(chan)),
            PLSMNS(channel_dynamicexempts(chan)),
            PLSMNS(!channel_nouserexempts(chan)),
            PLSMNS(channel_dynamicinvites(chan)),
            PLSMNS(!channel_nouserinvites(chan)),
            PLSMNS(channel_nodesynch(chan)),
            PLSMNS(channel_static(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
        if (ul->type == UDEF_FLAG)
          fprintf(f, "channel set %s %c%s%s\n", name, getudef(ul->values,
                  chan->dname) ? '+' : '-', "udef-flag-", ul->name);
        else if (ul->type == UDEF_INT)
          fprintf(f, "channel set %s %s%s %d\n", name, "udef-int-", ul->name,
                  (int) getudef(ul->values, chan->dname));
        else if (ul->type == UDEF_STR) {
          char *p = (char *) getudef(ul->values, chan->dname);

          if (!p)
            p = "{}";

          fprintf(f, "channel set %s udef-str-%s %s\n", name, ul->name, p);
        } else
          debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}
Exemplo n.º 15
0
Arquivo: misc.c Projeto: kirune/wraith
int updatebin(int idx, char *par, int secs)
{
  if (!par || !par[0]) {
    logidx(idx, "Not enough parameters.");
    return 1;
  }

  size_t path_siz = strlen(binname) + strlen(par) + 2;
  char *path = (char *) my_calloc(1, path_siz);
  char *newbin = NULL, buf[DIRMAX] = "";
  const char* argv[5];
  int i;

  strlcpy(path, binname, path_siz);
  newbin = strrchr(path, '/');
  if (!newbin) {
    free(path);
    logidx(idx, STR("Don't know current binary name"));
    return 1;
  }
  newbin++;
  if (strchr(par, '/')) {
    *newbin = 0;
    logidx(idx, STR("New binary must be in %s and name must be specified without path information"), path);
    free(path);
    return 1;
  }
  strcpy(newbin, par);
  if (!strcmp(path, binname)) {
    free(path);
    logidx(idx, STR("Can't update with the current binary"));
    return 1;
  }
  if (!can_stat(path)) {
    logidx(idx, STR("%s can't be accessed"), path);
    free(path);
    return 1;
  }
  if (fixmod(path)) {
    logidx(idx, STR("Can't set mode 0600 on %s"), path);
    free(path);
    return 1;
  }

  /* Check if the new binary is compatible */
  int initialized_code = check_bin_initialized(path);
  if (initialized_code == 2) {
    logidx(idx, STR("New binary is corrupted or the wrong architecture/operating system."));
    free(path);
    return 1;
  } else if (initialized_code == 1 && !check_bin_compat(path)) {
    logidx(idx, STR("New binary must be initialized as pack structure has been changed in new version."));
    free(path);
    return 1;
  }


  /* make a backup just in case. */

  simple_snprintf(buf, sizeof(buf), STR("%s/.bin.old"), conf.datadir);
  copyfile(binname, buf);

  write_settings(path, -1, 0, initialized_code ? 0 : 1);	/* re-write the binary with our packdata */

  Tempfile *conffile = new Tempfile("conf");

  if (writeconf(NULL, conffile->fd, CONF_ENC)) {
    logidx(idx, STR("Failed to write temporary config file for update."));
    delete conffile;
    return 1;
  }

  /* The binary should return '2' when ran with -2, if not it's probably corrupt. */
  putlog(LOG_DEBUG, "*", STR("Running for update binary test: %s -2"), path);
  argv[0] = path;
  argv[1] = "-2";
  argv[2] = 0;
  i = simple_exec(argv);
  if (i == -1 || WEXITSTATUS(i) != 2) {
    logidx(idx, STR("Couldn't restart new binary (error %d)"), i);
    delete conffile;
    return i;
  }

  /* now to send our config to the new binary */
  putlog(LOG_DEBUG, "*", STR("Running for update conf: %s -4 %s"), path, conffile->file);
  argv[0] = path;
  argv[1] = "-4";
  argv[2] = conffile->file;
  argv[3] = 0;
  i = simple_exec(argv);
  delete conffile;
  if (i == -1 || WEXITSTATUS(i) != 6) { /* 6 for successfull config read/write */
    logidx(idx, STR("Couldn't pass config to new binary (error %d)"), i);
    return i;
  }

  if (movefile(path, binname)) {
    logidx(idx, STR("Can't rename %s to %s"), path, binname);
    free(path);
    return 1;
  }

  if (updating == UPDATE_EXIT) {	  /* dont restart/kill/spawn bots, just die ! */
    printf(STR("* Moved binary to: %s\n"), binname);
    fatal(STR("Binary updated."), 0);
  }
  if (updating == UPDATE_AUTO) {
    /* Make all other bots do a soft restart */
    conf_checkpids(conf.bots);
    conf_killbot(conf.bots, NULL, NULL, SIGHUP);

    if (conf.bot->pid)
      kill(conf.bot->pid, SIGHUP);
    exit(0);
  }

  if (!conf.bot->hub && secs > 0) {
    /* Make all other bots do a soft restart */
    conf_checkpids(conf.bots);
    conf_killbot(conf.bots, NULL, NULL, SIGHUP);
    
    /* invoked with -u */
    if (updating == UPDATE_AUTO) {
      if (conf.bot->pid)
        kill(conf.bot->pid, SIGHUP);
      exit(0);
    }
    /* this odd statement makes it so specifying 1 sec will restart other bots running
     * and then just restart with no delay */
    updating = UPDATE_AUTO;
    if (secs > 1) {
      egg_timeval_t howlong;
      howlong.sec = secs;
      howlong.usec = 0;
      timer_create_complex(&howlong, STR("restarting for update"), (Function) restart, (void *) (long) idx, 0);
    } else
      restart(idx);

    return 0;
  } else
    restart(idx);	/* no timer */

 /* this should never be reached */
  return 2;
}
Exemplo n.º 16
0
/* Called once a second.
 *
 * Note:  Try to not put any Context lines in here (guppy 21Mar2000).
 */
static void core_secondly()
{
  static int cnt = 0;
  int miltime;

  do_check_timers(&utimer);     /* Secondly timers */
  cnt++;
  if (cnt >= 10) {              /* Every 10 seconds */
    cnt = 0;
    check_expired_dcc();
    if (con_chan && !backgrd) {
      dprintf(DP_STDOUT, "\033[2J\033[1;1H");
      tell_verbose_status(DP_STDOUT);
      do_module_report(DP_STDOUT, 0, "server");
      do_module_report(DP_STDOUT, 0, "channels");
      tell_mem_status_dcc(DP_STDOUT);
    }
  }
  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  if (nowtm.tm_min != lastmin) {
    int i = 0;

    /* Once a minute */
    lastmin = (lastmin + 1) % 60;
    call_hook(HOOK_MINUTELY);
    check_expired_ignores();
    autolink_cycle(NULL);       /* Attempt autolinks */
    /* In case for some reason more than 1 min has passed: */
    while (nowtm.tm_min != lastmin) {
      /* Timer drift, dammit */
      debug2("timer: drift (lastmin=%d, now=%d)", lastmin, nowtm.tm_min);
      i++;
      lastmin = (lastmin + 1) % 60;
      call_hook(HOOK_MINUTELY);
    }
    if (i > 1)
      putlog(LOG_MISC, "*", "(!) timer drift -- spun %d minutes", i);
    miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min);
    if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) {     /* 5 min */
      call_hook(HOOK_5MINUTELY);
      check_botnet_pings();
      if (!quick_logs) {
        flushlogs();
        check_logsize();
      }
      if (!miltime) {           /* At midnight */
        char s[25];
        int j;

        strncpyz(s, ctime(&now), sizeof s);
        if (quiet_save < 3)
          putlog(LOG_ALL, "*", "--- %.11s%s", s, s + 20);
        call_hook(HOOK_BACKUP);
        for (j = 0; j < max_logs; j++) {
          if (logs[j].filename != NULL && logs[j].f != NULL) {
            fclose(logs[j].f);
            logs[j].f = NULL;
          }
        }
      }
    }
    if (nowtm.tm_min == notify_users_at)
      call_hook(HOOK_HOURLY);
    /* These no longer need checking since they are all check vs minutely
     * settings and we only get this far on the minute.
     */
    if (miltime == switch_logfiles_at) {
      call_hook(HOOK_DAILY);
      if (!keep_all_logs) {
        if (quiet_save < 3)
          putlog(LOG_MISC, "*", MISC_LOGSWITCH);
        for (i = 0; i < max_logs; i++)
          if (logs[i].filename) {
            char s[1024];

            if (logs[i].f) {
              fclose(logs[i].f);
              logs[i].f = NULL;
            }
            egg_snprintf(s, sizeof s, "%s.yesterday", logs[i].filename);
            unlink(s);
            movefile(logs[i].filename, s);
          }
      }
    }
  }
}
Exemplo n.º 17
0
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;

  Context;
  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, 0600);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file ...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
	  origbotname, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->name, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f, "channel %s %s%schanmode %s idle-kick %d \
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
flood-kick %d:%d flood-deop %d:%d \
%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
%cgreet %cprotectops %cprotectfriends %cdontkickops %cwasoptest \
%cstatuslog %cstopnethack %crevenge %crevengebot %cautovoice %csecret \
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
%cdynamicinvites %cuserinvites%s\n",
	channel_static(chan) ? "set" : "add",
	name,
	channel_static(chan) ? " " : " { ",
	w2,
/* now bot write chanmode "" too,
 * so bot wont use default-chanmode instead of "" -- bugfix
 */
	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
	need1, need2, need3, need4, need5,
/* yes we will write empty need-xxxx too, why not? (less code + lazyness) */
	chan->flood_pub_thr, chan->flood_pub_time,
        chan->flood_ctcp_thr, chan->flood_ctcp_time,
        chan->flood_join_thr, chan->flood_join_time,
        chan->flood_kick_thr, chan->flood_kick_time,
        chan->flood_deop_thr, chan->flood_deop_time,
	PLSMNS(channel_clearbans(chan)),
	PLSMNS(channel_enforcebans(chan)),
	PLSMNS(channel_dynamicbans(chan)),
	PLSMNS(!channel_nouserbans(chan)),
	PLSMNS(channel_autoop(chan)),
	PLSMNS(channel_bitch(chan)),
	PLSMNS(channel_greet(chan)),
	PLSMNS(channel_protectops(chan)),
        PLSMNS(channel_protectfriends(chan)),
	PLSMNS(channel_dontkickops(chan)),
	PLSMNS(channel_wasoptest(chan)),
	PLSMNS(channel_logstatus(chan)),
	PLSMNS(channel_stopnethack(chan)),
	PLSMNS(channel_revenge(chan)),
	PLSMNS(channel_revengebot(chan)),
	PLSMNS(channel_autovoice(chan)),
	PLSMNS(channel_secret(chan)),
	PLSMNS(channel_shared(chan)),
	PLSMNS(channel_cycle(chan)),
	PLSMNS(channel_seen(chan)),
	PLSMNS(channel_inactive(chan)),
        PLSMNS(channel_dynamicexempts(chan)),
        PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(channel_dynamicinvites(chan)),
        PLSMNS(!channel_nouserinvites(chan)),
	channel_static(chan) ? "" : " }");
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}
Exemplo n.º 18
0
/*
*  Test movefile
*
*
 */
void test_movefile(){
	char pathlist[100][50];
	movefile("H:/musictest1/temp.txt","H:/musictest1/movetest.txt");
	listdir("H:/musictest1",pathlist);
	CU_ASSERT(strcmp(pathlist[0],"H:/musictest1/movetest.txt") == 0);  
}
Exemplo n.º 19
0
void processcommand( char *command, char *P1, char *P2, char *P3 ) {

    if( strcmp(command, "createvfs") == 0 ) {
        int size = atoi(P2);
        if( (0 == strcmp(P1,"")) || 0 == P2 ) {
            printf("createvfs_FAILURE %s \n",ERR_VFS_CREATE_00);
        } else {
            createvfs (P1,size);
        }
    }
    else if( strcmp(command, "mountvfs") == 0 ) {
        if( (0 == strcmp(P1,"")) ) {
            printf("mountvfs_FAILURE %s \n",ERR_VFS_MOUNT_05);
        } else {
            if( 1 == ui_mountFlag ) {
                printf("mountvfs_FAILURE %s \n",ERR_VFS_MOUNT_04);
            } else {
                mountvfs (P1);
            }
        }
    }
    else if( strcmp(command, "unmountvfs") == 0 ) {
        if( (0 == strcmp(P1,"")) ) {
            printf("unmountvfs_FAILURE %s \n",ERR_VFS_UNMOUNT_00);
        } else {
            if( 0 == ui_mountFlag ) {
                printf("unmountvfs_FAILURE %s \n",ERR_VFS_UNMOUNT_04);
            } else {
                unmountvfs (P1);
            }
        }
    }
    else if( strcmp(command, "makedir") == 0 ) {
        if( (0 == strcmp(P1,"")) || (0 == strcmp(P2,"")) ) {
            printf("makedir_FAILURE %s \n",ERR_VFS_MAKEDIR_00);
        } else {
            if( 0 == ui_mountFlag ) {
                printf("makedir_FAILURE %s \n",ERR_VFS_MAKEDIR_05);
            } else {
                makedir (P1,P2);
            }
        }
    }
    else if( strcmp(command, "deletedir") == 0 )
        deletedir (P1);
    else if( strcmp(command, "movedir") == 0 )
        movedir (P1,P2);
    else if( strcmp(command, "listdir") == 0 ) {
        int flag = atoi(P2);
        listdir (P1,flag,P3);
    }
    else if( strcmp(command, "addfile") == 0 )
        addfile (P1,P2,P3);
    else if( strcmp(command, "listfile") == 0 )
        listfile (P1,P2);
    else if( strcmp(command, "updatefile") == 0 )
        updatefile (P1,P2);
    else if( strcmp(command, "removefile") == 0 )
        removefile (P1);
    else if( strcmp(command, "movefile") == 0 )
        movefile (P1,P2);
    else if( strcmp(command, "copyfile") == 0 )
        copyfile (P1,P2);
    else if( strcmp(command, "exportfile") == 0 )
        exportfile (P1,P2);
    else if( strcmp(command, "searchfile") == 0 )
        searchfile (P1,P2);
    else
        printf("Ignoring invalid command %s\n", command);
}
Exemplo n.º 20
0
static void
build(void)
{
	int	i;
	FILE	*oldrefs;	/* old cross-reference file */
	time_t	reftime;	/* old crossref modification time */
	char	*file;			/* current file */
	char	*oldfile;		/* file in old cross-reference */
	char	newdir[PATHLEN + 1];	/* directory in new cross-reference */
	char	olddir[PATHLEN + 1];	/* directory in old cross-reference */
	char	oldname[PATHLEN + 1];	/* name in old cross-reference */
	int	oldnum;			/* number in old cross-ref */
	struct	stat statstruct;	/* file status */
	int	firstfile;		/* first source file in pass */
	int	lastfile;		/* last source file in pass */
	int	built = 0;		/* built crossref for these files */
	int	copied = 0;		/* copied crossref for these files */
	BOOL	interactive = YES;	/* output progress messages */

	/*
	 * normalize the current directory relative to the home directory so
	 * the cross-reference is not rebuilt when the user's login is moved
	 */
	(void) strcpy(newdir, currentdir);
	if (strcmp(currentdir, home) == 0) {
		(void) strcpy(newdir, "$HOME");
	} else if (strncmp(currentdir, home, strlen(home)) == 0) {
		(void) sprintf(newdir, "$HOME%s", currentdir + strlen(home));
	}
	/* sort the source file names (needed for rebuilding) */
	qsort((char *)srcfiles, (unsigned)nsrcfiles, sizeof (char *), compare);

	/*
	 * if there is an old cross-reference and its current directory
	 * matches or this is an unconditional build
	 */
	if ((oldrefs = vpfopen(reffile, "r")) != NULL && unconditional == NO &&
	    fscanf(oldrefs, "cscope %d %s", &fileversion, olddir) == 2 &&
	    (strcmp(olddir, currentdir) == 0 || /* remain compatible */
	    strcmp(olddir, newdir) == 0)) {

		/* get the cross-reference file's modification time */
		(void) fstat(fileno(oldrefs), &statstruct);
		reftime = statstruct.st_mtime;
		if (fileversion >= 8) {
			BOOL	oldcompress = YES;
			BOOL	oldinvertedindex = NO;
			BOOL	oldtruncatesyms = NO;
			int	c;

			/* see if there are options in the database */
			for (;;) {
				while ((c = getc(oldrefs)) == ' ') {
				}
				if (c != '-') {
					(void) ungetc(c, oldrefs);
					break;
				}
				switch (c = getc(oldrefs)) {
				case 'c':	/* ASCII characters only */
					oldcompress = NO;
					break;
				case 'q':	/* quick search */
					oldinvertedindex = YES;
					(void) fscanf(oldrefs,
					    "%ld", &totalterms);
					break;
				case 'T':
					/* truncate symbols to 8 characters */
					oldtruncatesyms = YES;
					break;
				}
			}
			/* check the old and new option settings */
			if (oldcompress != compress ||
			    oldtruncatesyms != truncatesyms) {
				(void) fprintf(stderr,
				    "cscope: -c or -T option mismatch between "
				    "command line and old symbol database\n");
				goto force;
			}
			if (oldinvertedindex != invertedindex) {
				(void) fprintf(stderr,
				    "cscope: -q option mismatch between "
				    "command line and old symbol database\n");
				if (invertedindex == NO) {
					removeindex();
				}
				goto outofdate;
			}
			/* seek to the trailer */
			if (fscanf(oldrefs, "%ld", &traileroffset) != 1 ||
			    fseek(oldrefs, traileroffset, 0) == -1) {
				(void) fprintf(stderr,
				    "cscope: incorrect symbol database file "
				    "format\n");
				goto force;
			}
		}
		/* if assuming that some files have changed */
		if (fileschanged == YES) {
			goto outofdate;
		}
		/* see if the view path is the same */
		if (fileversion >= 13 &&
		    samelist(oldrefs, vpdirs, vpndirs) == NO) {
			goto outofdate;
		}
		/* see if the directory lists are the same */
		if (samelist(oldrefs, srcdirs, nsrcdirs) == NO ||
		    samelist(oldrefs, incdirs, nincdirs) == NO ||
		    fscanf(oldrefs, "%d", &oldnum) != 1 ||
		    fileversion >= 9 && fscanf(oldrefs, "%*s") != 0) {
			/* skip the string space size */
			goto outofdate;
		}
		/*
		 * see if the list of source files is the same and
		 * none have been changed up to the included files
		 */
		for (i = 0; i < nsrcfiles; ++i) {
			if (fscanf(oldrefs, "%s", oldname) != 1 ||
			    strnotequal(oldname, srcfiles[i]) ||
			    vpstat(srcfiles[i], &statstruct) != 0 ||
			    statstruct.st_mtime > reftime) {
				goto outofdate;
			}
		}
		/* the old cross-reference is up-to-date */
		/* so get the list of included files */
		while (i++ < oldnum && fscanf(oldrefs, "%s", oldname) == 1) {
			addsrcfile(oldname);
		}
		(void) fclose(oldrefs);
		return;

outofdate:
		/* if the database format has changed, rebuild it all */
		if (fileversion != FILEVERSION) {
			(void) fprintf(stderr,
			    "cscope: converting to new symbol database file "
			    "format\n");
			goto force;
		}
		/* reopen the old cross-reference file for fast scanning */
		if ((symrefs = vpopen(reffile, O_RDONLY)) == -1) {
			cannotopen(reffile);
			myexit(1);
		}
		/* get the first file name in the old cross-reference */
		blocknumber = -1;
		(void) readblock();	/* read the first cross-ref block */
		(void) scanpast('\t');	/* skip the header */
		oldfile = getoldfile();
	} else {	/* force cross-referencing of all the source files */
force:
		reftime = 0;
		oldfile = NULL;
	}
	/* open the new cross-reference file */
	if ((newrefs = fopen(newreffile, "w")) == NULL) {
		cannotopen(newreffile);
		myexit(1);
	}
	if (invertedindex == YES && (postings = fopen(temp1, "w")) == NULL) {
		cannotopen(temp1);
		cannotindex();
	}
	(void) fprintf(stderr, "cscope: building symbol database\n");
	putheader(newdir);
	fileversion = FILEVERSION;
	if (buildonly == YES && !isatty(0)) {
		interactive = NO;
	} else {
		initprogress();
	}
	/* output the leading tab expected by crossref() */
	dbputc('\t');

	/*
	 * make passes through the source file list until the last level of
	 * included files is processed
	 */
	firstfile = 0;
	lastfile = nsrcfiles;
	if (invertedindex == YES) {
		srcoffset = mymalloc((nsrcfiles + 1) * sizeof (long));
	}
	for (;;) {

		/* get the next source file name */
		for (fileindex = firstfile; fileindex < lastfile; ++fileindex) {
			/* display the progress about every three seconds */
			if (interactive == YES && fileindex % 10 == 0) {
				if (copied == 0) {
					progress("%ld files built",
					    (long)built, 0L);
				} else {
					progress("%ld files built, %ld "
					    "files copied", (long)built,
					    (long)copied);
				}
			}
			/* if the old file has been deleted get the next one */
			file = srcfiles[fileindex];
			while (oldfile != NULL && strcmp(file, oldfile) > 0) {
				oldfile = getoldfile();
			}
			/*
			 * if there isn't an old database or this is
			 * a new file
			 */
			if (oldfile == NULL || strcmp(file, oldfile) < 0) {
				crossref(file);
				++built;
			} else if (vpstat(file, &statstruct) == 0 &&
			    statstruct.st_mtime > reftime) {
				/* if this file was modified */
				crossref(file);
				++built;

				/*
				 * skip its old crossref so modifying the last
				 * source file does not cause all included files
				 * to be built.  Unfortunately a new file that
				 * is alphabetically last will cause all
				 * included files to be built, but this is
				 * less likely
				 */
				oldfile = getoldfile();
			} else {	/* copy its cross-reference */
				putfilename(file);
				if (invertedindex == YES) {
					copyinverted();
				} else {
					copydata();
				}
				++copied;
				oldfile = getoldfile();
			}
		}
		/* see if any included files were found */
		if (lastfile == nsrcfiles) {
			break;
		}
		firstfile = lastfile;
		lastfile = nsrcfiles;
		if (invertedindex == YES) {
			srcoffset = myrealloc(srcoffset,
			    (nsrcfiles + 1) * sizeof (long));
		}
		/* sort the included file names */
		qsort((char *)&srcfiles[firstfile],
		    (unsigned)(lastfile - firstfile), sizeof (char *), compare);
	}
	/* add a null file name to the trailing tab */
	putfilename("");
	dbputc('\n');

	/* get the file trailer offset */

	traileroffset = dboffset;

	/*
	 * output the view path and source and include directory and
	 * file lists
	 */
	putlist(vpdirs, vpndirs);
	putlist(srcdirs, nsrcdirs);
	putlist(incdirs, nincdirs);
	putlist(srcfiles, nsrcfiles);
	if (fflush(newrefs) == EOF) {
		/* rewind doesn't check for write failure */
		cannotwrite(newreffile);
		/* NOTREACHED */
	}
	/* create the inverted index if requested */
	if (invertedindex == YES) {
		char	sortcommand[PATHLEN + 1];

		if (fflush(postings) == EOF) {
			cannotwrite(temp1);
			/* NOTREACHED */
		}
		(void) fstat(fileno(postings), &statstruct);
		(void) fprintf(stderr,
		    "cscope: building symbol index: temporary file size is "
		    "%ld bytes\n", statstruct.st_size);
		(void) fclose(postings);
	/*
	 * sort -T is broken until it is fixed we don't have too much choice
	 */
	/*
	 * (void) sprintf(sortcommand, "sort -y -T %s %s", tmpdir, temp1);
	 */
	(void) sprintf(sortcommand, "LC_ALL=C sort %s", temp1);
		if ((postings = popen(sortcommand, "r")) == NULL) {
			(void) fprintf(stderr,
			    "cscope: cannot open pipe to sort command\n");
			cannotindex();
		} else {
			if ((totalterms = invmake(newinvname, newinvpost,
			    postings)) > 0) {
				movefile(newinvname, invname);
				movefile(newinvpost, invpost);
			} else {
				cannotindex();
			}
			(void) pclose(postings);
		}
		(void) unlink(temp1);
		(void) free(srcoffset);
		(void) fprintf(stderr,
		    "cscope: index has %ld references to %ld symbols\n",
		    npostings, totalterms);
	}
	/* rewrite the header with the trailer offset and final option list */
	rewind(newrefs);
	putheader(newdir);
	(void) fclose(newrefs);

	/* close the old database file */
	if (symrefs >= 0) {
		(void) close(symrefs);
	}
	if (oldrefs != NULL) {
		(void) fclose(oldrefs);
	}
	/* replace it with the new database file */
	movefile(newreffile, reffile);
}
Exemplo n.º 21
0
void moveFilesProc(XtPointer fsel, int conf)
{
 SelFileNamesRec *fnames = (SelFileNamesRec *) fsel;
 struct stat tostats, tolstats, frstats;
 char from[MAXPATHLEN], to[MAXPATHLEN];
 String name, cwd;
 String op_name, from_err, to_err;
 size_t toend, fromend;
 int devto, devfrom, deverr = -1, i, perm, res;
 Boolean is_dir, is_link;

 if (conf != YES || !fnames->op)
 {
     freeSelFiles(fnames);
     return;
 }
 if (chdir(fnames->directory))
 {
     sysError(fnames->shell, "System error:");
     freeSelFiles(fnames);
     return;
 }
 chdir(user.home);
 switch (fnames->op)
 {
     case COPY:
	 op_name = "Copy:";
	 from_err = "Error copying";
	 to_err = "Error copying to";
	 break;
     case MOVE:
	 op_name = "Move:";
	 from_err = "Error moving";
	 to_err = "Error moving to";
	 break;
     default:  /* i.e. LINK */
	 op_name = "Link:";
	 from_err = "Error creating symlink to";
	 to_err = "Error creating symlink in";
 }
 if (fnames->target[0] != '/' && fnames->target[0] != '~' && fnames->target != 0)
 {
     strcpy(to, fnames->directory);
     if (to[strlen(to)-1] != '/')  strcat(to, "/");
 }
 else to[0] = 0;
 strcat(to, fnames->target);
 fnexpand(to);
 if (!(cwd = absolutePath(to)))
 {
     error(fnames->shell, no_target, to);
     freeSelFiles(fnames);
     return;
 }
 strcpy(to, cwd);
 XTFREE(cwd);
 fromend = strlen(strcpy(from, fnames->directory));
 if (from[fromend-1] != '/')
 {
     from[fromend++] = '/';
     from[fromend] = 0;
 }
 devfrom = findDev(from);
 if (mountDev(devto = findDev(to), False))
     deverr = devto;
 else if (mountDev(devfrom, False))
     deverr = devfrom;
 if (deverr != -1)
 {
     error(fnames->shell, "Cannot mount device on", mntable.devices[deverr].def_mpoint);
     umountDev(devto, False);
     freeSelFiles(fnames);
     return;
 }
 if (!(stat(to, &tostats)) && S_ISDIR(tostats.st_mode))
 {
     if (chdir(to) || !(perm = permission(&tostats, P_WRITE)))
     {
	 chdir(user.home);
	 if (!perm)
	     error(fnames->shell, "You have no write permission for ", to);
	 else  sysError(fnames->shell, "System error:");
	 umountDev(devto, False);
	 umountDev(devfrom, False);
	 freeSelFiles(fnames);
	 return;
     }
     chdir(user.home);
     fnames->dirtarget = True;
     toend = strlen(to);
     if (to[toend-1] != '/')
     {
	 to[toend++] = '/';
	 to[toend] = 0;
     }
 }
 else if (fnames->n_sel == 1)  fnames->dirtarget = False;
 else
 {
     error(fnames->shell, op_name, "Target for multiple files must be a folder");
     umountDev(devto, False);
     umountDev(devfrom, False);
     freeSelFiles(fnames);
     return;
 }
 if (!fnames->first)  zzz();
 XTFREE(fnames->target);
 fnames->target = XtNewString(to);
 for (i = fnames->first; i < fnames->n_sel; i++)
 {
     name = fnames->names[i];
     if (fnames->op != LINK && (!strcmp(name, ".") || !strcmp(name, "..")))
     {
	 error(fnames->shell, "Cannot move or copy . or ..", NULL);
	 continue;
     }
     strcpy(from+fromend, name);
     if (fnames->dirtarget)
     {
	 if (fnames->op != LINK && prefix(from, to))
	 {
	     String err_str, format = "Cannot move or copy %s to";
	     err_str = (String) XtMalloc((strlen(format) + strlen(from)) * sizeof(char));
	     sprintf(err_str, format, from);
	     error(fnames->shell, err_str, to);
	     XTFREE(err_str);
	     umountDev(devto, False);
	     umountDev(devfrom, False);
	     freeSelFiles(fnames);
	     wakeUp();
	     return;
	 }
	 strcpy(to+toend, name);
     }
     if (!(lstat(to, &tolstats)))
     {
	 fnames->first = i;
	 is_dir = False;
	 if (!(stat(to, &tostats)))
	 {
	     if (S_ISDIR(tostats.st_mode))
		 is_dir = True;
	     if (!stat(from, &frstats) && tostats.st_ino == frstats.st_ino)
	     {
		 error(fnames->shell, op_name, "Source and destination are identical");
		 umountDev(devto, False);
		 umountDev(devfrom, False);
		 freeSelFiles(fnames);
		 wakeUp();
		 return;
	     }
	 }
	 if (S_ISLNK(tolstats.st_mode))
	     is_link = True;
	 else  is_link = False;

	 if (fnames->conf_ovwr || (is_dir && (!is_link || fnames->op == COPY) && resources.confirm_delete_folder))
	     overwriteDialog(fnames, to, (fnames->op == COPY && is_dir && (lstat(from, &frstats) || !S_ISDIR(frstats.st_mode)))?
			     "File copy:" : op_name,
			     is_dir && (!is_link || fnames->op == COPY));
	 else overwriteProc(fsel, YES);
	 umountDev(devto, False);
	 umountDev(devfrom, False);
	 return;
     }
     switch (fnames->op)
     {
	 case COPY:	rcopy(from, to, False); res = 0; break;
	 case MOVE:	res = movefile(from, to); break;
	 default:	res = makeLink(from, to);
     }
     if (res)
     {
	 if (opError(fnames->shell, from_err, name) != YES)
	     break;
     }
     else  fnames->update = True;
 }
 umountDev(devto, False);
 umountDev(devfrom, False);
 if (fnames->update)
 {
     if (fnames->op == COPY)
	 intUpdate(CHECK_DIR);		/* Check for new subdirectories */
     if (fnames->op == MOVE)
	 markForUpdate(fnames->directory, CHECK_FILES);
     markForUpdate(to, RESHOW);
     if (fnames->op != COPY)
	 intUpdate(CHECK_DIR);
 }
 freeSelFiles(fnames);
 wakeUp();
}
Exemplo n.º 22
0
void overwriteProc(XtPointer fsel, int conf)
{
 SelFileNamesRec *fnames = (SelFileNamesRec *) fsel;
 char to[MAXPATHLEN], from[MAXPATHLEN];
 String errstr;
 struct stat tolstats;
 size_t len;
 int devto, devfrom, deverr = -1, res;

 switch (conf)
 {
     case CANCEL:	fnames->first = fnames->n_sel; break;
     case ALL:		fnames->conf_ovwr = False;
     case YES:
	 switch (fnames->op)
	 {
	     case COPY:	errstr = "Error copying"; break;
	     case MOVE: errstr = "Error moving"; break;
	     default: errstr = "Error creating symlink to";
	 }
	 strcpy(from, fnames->directory);
	 if (from[(len = strlen(from)) - 1] != '/')
	     strcat(from, "/");
	 strcat(from, fnames->names[fnames->first]);
	 strcpy(to, fnames->target);
	 devfrom = findDev(from);
	 if (mountDev(devto = findDev(to), False))
	     deverr = devto;
	 else if (mountDev(devfrom, False))
	     deverr = devfrom;
	 if (deverr != -1)
	 {
	     error(fnames->shell, "Cannot mount device on", mntable.devices[deverr].def_mpoint);
	     fnames->first = fnames->n_sel;
	     umountDev(devto, False);
	     break;
	 }
	 if (fnames->dirtarget)  strcat(to, fnames->names[fnames->first]);
	 if (!(lstat(to, &tolstats)))
	 {
	     if (fnames->op != COPY && S_ISDIR(tolstats.st_mode))
		 rdelete(to);
	     else if (fnames->op == LINK || (fnames->op == MOVE && S_ISLNK(tolstats.st_mode)))
	     {
		 unlink(to);
		 fnames->update = True;
	     }
	 }
	 switch (fnames->op)
	 {
	     case COPY:	rcopy(from, to, False); res = 0; break;
	     case MOVE:	res = movefile(from, to); break;
	     default:	res = makeLink(from, to);
	 }
	 if (res)
	 {
	     if (opError(fnames->shell, errstr, from) != YES)
	     {
		 fnames->first = fnames->n_sel;
		 break;
	     }
	 }
	 else  fnames->update = True;
	 umountDev(devto, False);
	 umountDev(devfrom, False);
     case NO:	fnames->first++;
 }
 moveFilesProc(fsel, YES);
}
Exemplo n.º 23
0
/*
 * sdl="-" : erase all msgs
 * else    : erase msg in list : (ex: .notes erase 2-4;8;16-)
 * idx=-1  : /msg
 */
static void notes_del(char *hand, char *nick, char *sdl, int idx)
{
  FILE *f, *g;
  char s[513], *to, *s1;
  int in = 1;
  int er = 0;
  int dl[128];                  /* Is it enough ? */

  if (sdl[0] == 0)
    sdl = "-";
  if (!notefile[0]) {
    if (idx >= 0)
      dprintf(idx, "%s.\n", NOTES_NO_MESSAGES);
    else
      dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, NOTES_NO_MESSAGES);
    return;
  }
  f = fopen(notefile, "r");
  if (f == NULL) {
    if (idx >= 0)
      dprintf(idx, "%s.\n", NOTES_NO_MESSAGES);
    else
      dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, NOTES_NO_MESSAGES);
    return;
  }
  sprintf(s, "%s~new", notefile);
  g = fopen(s, "w");
  if (g == NULL) {
    if (idx >= 0)
      dprintf(idx, "%s. :(\n", NOTES_FAILED_CHMOD);
    else
      dprintf(DP_HELP, "NOTICE %s :%s. :(\n", nick, NOTES_FAILED_CHMOD);
    fclose(f);
    return;
  }
  chmod(s, userfile_perm);      /* Use userfile permissions. */
  notes_parse(dl, sdl);
  while (!feof(f)) {
    fgets(s, 512, f);
    if (s[strlen(s) - 1] == '\n')
      s[strlen(s) - 1] = 0;
    if (!feof(f)) {
      rmspace(s);
      if ((s[0]) && (s[0] != '#') && (s[0] != ';')) {   /* Not comment */
        s1 = s;
        to = newsplit(&s1);
        if (!egg_strcasecmp(to, hand)) {
          if (!notes_in(dl, in))
            fprintf(g, "%s %s\n", to, s1);
          else
            er++;
          in++;
        } else
          fprintf(g, "%s %s\n", to, s1);
      } else
        fprintf(g, "%s\n", s);
    }
  }
  fclose(f);
  fclose(g);
  unlink(notefile);
  sprintf(s, "%s~new", notefile);
  movefile(s, notefile);
  if ((er == 0) && (in > 1)) {
    if (idx >= 0)
      dprintf(idx, "%s.\n", NOTES_NOT_THAT_MANY);
    else
      dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, NOTES_NOT_THAT_MANY);
  } else if (in == 1) {
    if (idx >= 0)
      dprintf(idx, "%s.\n", NOTES_NO_MESSAGES);
    else
      dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, NOTES_NO_MESSAGES);
  } else {
    if (er == (in - 1)) {
      if (idx >= 0)
        dprintf(idx, "%s.\n", NOTES_ERASED_ALL);
      else
        dprintf(DP_HELP, "NOTICE %s :%s.\n", nick, NOTES_ERASED_ALL);
    } else {
      if (idx >= 0)
        dprintf(idx, "%s %d note%s; %d %s.\n", NOTES_ERASED, er,
                (er != 1) ? "s" : "", in - 1 - er, NOTES_LEFT);
      else
        dprintf(DP_HELP, "NOTICE %s :%s %d note%s; %d %s.\n", nick, MISC_ERASED,
                er, (er != 1) ? "s" : "", in - 1 - er, NOTES_LEFT);
    }
  }
}
Exemplo n.º 24
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  Context;
  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file ...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
	  origbotname, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
%cgreet %cprotectops %cprotectfriends %cdontkickops \
%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
%cdynamicinvites %cuserinvites %cnodesynch ",
	channel_static(chan) ? "set" : "add",
	name,
	channel_static(chan) ? " " : " { ",
	w2,
	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
	chan->stopnethack_mode,
	need1, need2, need3, need4, need5,
	chan->flood_pub_thr, chan->flood_pub_time,
        chan->flood_ctcp_thr, chan->flood_ctcp_time,
        chan->flood_join_thr, chan->flood_join_time,
        chan->flood_kick_thr, chan->flood_kick_time,
        chan->flood_deop_thr, chan->flood_deop_time,
	chan->flood_nick_thr, chan->flood_nick_time,
	PLSMNS(channel_clearbans(chan)),
	PLSMNS(channel_enforcebans(chan)),
	PLSMNS(channel_dynamicbans(chan)),
	PLSMNS(!channel_nouserbans(chan)),
	PLSMNS(channel_autoop(chan)),
	PLSMNS(channel_bitch(chan)),
	PLSMNS(channel_greet(chan)),
	PLSMNS(channel_protectops(chan)),
        PLSMNS(channel_protectfriends(chan)),
	PLSMNS(channel_dontkickops(chan)),
	PLSMNS(channel_logstatus(chan)),
	PLSMNS(channel_revenge(chan)),
	PLSMNS(channel_revengebot(chan)),
	PLSMNS(channel_autovoice(chan)),
	PLSMNS(channel_secret(chan)),
	PLSMNS(channel_shared(chan)),
	PLSMNS(channel_cycle(chan)),
	PLSMNS(channel_seen(chan)),
	PLSMNS(channel_inactive(chan)),
        PLSMNS(channel_dynamicexempts(chan)),
        PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(channel_dynamicinvites(chan)),
        PLSMNS(!channel_nouserinvites(chan)),
	PLSMNS(channel_nodesynch(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
	if (ul->type == UDEF_FLAG)
	  fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
		  "udef-flag-", ul->name);
	else if (ul->type == UDEF_INT)
	  fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
		  chan->dname));
	else
	  debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}