Пример #1
0
/*
   添加树

   每一步中,新单词与节点中存储的单词进行比较,随后,通过递归调用addtree 
   而转向左子树或右子树。该单词最终将与树中的某节点匹配(这种情况下计数
   值加 1) ,或遇到一个空指针(表明必须创建一个节点并加入到树中) 。若生成
   了新节点,则addtree 返回一个指向新节点的指针,该指针保存在父节点中
 */
struct tnode *addtree(struct tnode *p,char *w,int *nlines) {
	struct link *addlink(struct link *p,int *nlines);

	struct tnode *alloc(void);
	char *strup(char *w);
	int flag;
	/*
	   1.树还未建立,建树
	   2.比较新单词时,建树
	 */
	if(p == NULL ) {
		p = alloc();
		p->linkpoint = addlink(p->linkpoint,nlines);
		p->word = strup(w);
		p->left = p->right = NULL;
	}
	else if( (flag = strcmp(w,p->word)) == 0 ) {
		p->linkpoint= addlink(p->linkpoint,nlines);
	}
	//当小于当前节点时添加左子树
	else if(flag < 0 ) {
		p->left = addtree(p->left,w,nlines);
	}
	//当大于当前节点时添加右子树
	else {
		p->right = addtree(p->right,w,nlines);
	}

	return p;
}
Пример #2
0
/*
 * Rule for scsi disks.  If the entry is for a cdrom drive
 * we create srN and rsrN where N is logically numbered
 * starting at 0 in order of minor number.  For regular
 * disks we do the 0 <-> 3 swap, i.e., sd0a will point
 * to c0t3d0s0 and sd3a will point to c0t0d0s0.  This should
 * only be done on sun4m machines to be compatible
 * with 4.x (see bug 1157616) but we're probably stuck with it
 * being done on all machines because people may be used
 * to using the swapped names on other machines.
 */
static void
rule_sd(struct devices_ent *dep)
{
	static int first = 1;
	static int cdnum = -1;
	static int last_minor = -1;
	char *min_comp = dep->min_comp;
	int minor = dep->minor;
	char *targ_pfx;
	char *link_pfx;

	if (first) {
		find_cdsd();
		first = 0;
	}

	if (dep->iscd) {
		if (strcmp(min_comp, "c") == 0) {
			if (minor != last_minor) {
				cdnum++;
				last_minor = minor;
			}
			if (dep->israw) {
				(void) sprintf(namebuf, "rsr%d", cdnum);
				addlink(namebuf, "rdsk/", dep, 0);
			} else {
				(void) sprintf(namebuf, "sr%d", cdnum);
				addlink(namebuf, "dsk/", dep, 0);
			}
		}
		return;
	}

	if (!dep->issd)
		return;

	if (dep->israw) {
		link_pfx = "r";
		targ_pfx = "rdsk/";
	} else {
		link_pfx = "";
		targ_pfx = "dsk/";
	}

	if (minor < 8)
		(void) sprintf(namebuf, "%ssd%d%s", link_pfx, 3, min_comp);
	else if (minor >= 24 && minor < 32)
		(void) sprintf(namebuf, "%ssd%d%s", link_pfx, 0, min_comp);
	else
		(void) sprintf(namebuf, "%ssd%d%s", link_pfx, minor / 8,
		    min_comp);

	addlink(namebuf, targ_pfx, dep, 0);
}
Пример #3
0
/*
 * Rule for obsolete mt devices.  It works like the awk rule,
 * but unknown if correct.
 */
static void
rule_mt(struct devices_ent *dep)
{
	int minor = dep->minor;

	if ((minor % 8) >= 4) {
		(void) sprintf(namebuf, "rmt%d", minor);
		addlink(namebuf, "rmt/", dep, 1);
		(void) sprintf(namebuf2, "nrmt%d", minor - 4);
		addlink_nolookup(namebuf2, namebuf, 1);
	} else {
		(void) sprintf(namebuf, "rmt%d", minor);
		addlink(namebuf, "rmt/", dep, 1);
	}
}
Пример #4
0
int main(void)
{
  first = malloc(sizeof(node));
  bool check;
  for(int i = 0; i < 1000000; i++)
    {
      int j = dijpower(i);
      if (i == j)
	{
	  check = addlink(i);
	}
    
    }
  node* nextptr = first;
  int sum = 0;
  while(nextptr != NULL && nextptr->value != 1)
    {
      // printf("%d\n", nextptr->value);
      sum += nextptr->value;
      nextptr = nextptr->ptr;
    }
  printf("%d\n", sum);
   return 0;

}
Пример #5
0
/*
 * Rule for xd and xy disks.  This is broken because it does
 * the 0 <-> 3 swap that should only be done for scsi disks
 * on sun4m (see bug 1157616).  Again, we probably
 * can't change this now.
 */
static void
rule_xdxy(struct devices_ent *dep)
{
	char *min_comp = dep->min_comp;
	char *majname = dep->drp->name;
	int minor = dep->minor;
	char *targ_pfx;
	char *link_pfx;

	if (dep->israw) {
		link_pfx = "r";
		targ_pfx = "rdsk/";
	} else {
		link_pfx = "";
		targ_pfx = "dsk/";
	}

	if (minor < 8)
		(void) sprintf(namebuf, "%s%s%d%s", link_pfx, majname, 3,
		    min_comp);
	else if (minor >= 24 && minor < 32)
		(void) sprintf(namebuf, "%s%s%d%s", link_pfx, majname, 0,
		    min_comp);
	else
		(void) sprintf(namebuf, "%s%s%d%s", link_pfx, majname,
		    minor / 8, min_comp);

	addlink(namebuf, targ_pfx, dep, 0);
}
Пример #6
0
/*
 * Rule for floppy drivers.
 */
static void
rule_fd(struct devices_ent *dep)
{
	int c_slice;
	int minor = dep->minor;
	char *link_pfx;
	char *targ_pfx;

	c_slice = (strcmp(dep->min_comp, "c") == 0);

	if (dep->israw) {
		link_pfx = "r";
		targ_pfx = "rdiskette";
	} else {
		link_pfx = "";
		targ_pfx = "diskette";
	}

	(void) sprintf(namebuf, "%sfd%d%s", link_pfx, minor / 8,
	    dep->min_comp);
	addlink(namebuf, targ_pfx, dep, 0);
	if (c_slice) {
		(void) sprintf(namebuf2, "%sfd%d", link_pfx, minor / 8);
		addlink_nolookup(namebuf2, namebuf, 0);
	}
}
Пример #7
0
Файл: g28.c Проект: 8l/csolve
void adcons(int s,int g){       /* add connections through a point */
				/* but not to group g */
   int n[4],i,sn,j,k,ldtmp,c,dst;

   k = 0;
   i = fdir[s];
   for(ldtmp = ldir[i]; i != ldtmp; ++i){
      sn = s + nbr[i];
      if(board[sn] != NOGROUP && board[sn] != g)
         n[k++] = board[sn];
      }
   for(i = 0; i < k-1; ++i)
      for(j = i + 1; j != k; ++j)
         if(grcolor[n[i]] == grcolor[n[j]])
            addconn(n[i],n[j],s);
   for(i = 0; i < 4; ++i){
      sn = sqrbrd[s][i];
      dst = dstbrd[s][i];
      if(sn != NOSQUARE && (dst == 1 )){
         c = grcolor[board[sn]];
         for(j = 0; j < k; ++j)
            if(grcolor[n[j]] == c)
               addlink(n[j],board[sn],s);
         }
      if(sn != NOSQUARE && (dst == 2 )){
         c = grcolor[board[sn]];
         for(j = 0; j < k; ++j)
            if(grcolor[n[j]] == c)
               addlkg(n[j],board[sn],s);
         }
      }
   }
Пример #8
0
/* read edge list from file and build the graph */
graph *graph_from_file(const char *filename) {
  int k, minn, maxn;
  int ne = 0;
  int buflen = 0;
  unsigned int *n1 = NULL;
  unsigned int *n2 = NULL;
  int llength;
  char *line=NULL;
  FILE *fd = fopen(filename, "r");
  graph *gp = malloc(sizeof(graph));

  if (fd == NULL) {
    fprintf(stderr,"ERROR trying to open %s\n",filename);
    perror("in graph_from_file()");
    return NULL;
  }
  /* read edges */
  while (getline(&line,&llength,fd)>0) {
    if (ne > buflen-1) {
      buflen += 1024;
      n1 = realloc(n1, buflen*sizeof(unsigned int));
      n2 = realloc(n2, buflen*sizeof(unsigned int));
    }
    /* look for bad lines*/
    if (sscanf(line, "%u %u\n", &(n1[ne]), &(n2[ne])) < 2) {
      fclose(fd);
      return NULL;
    }
    ne++;
  }
  fclose(fd);

  /* look for graph size (and index of first node)*/
  minn = min(n1[0],n2[0]);
  maxn = max(n1[0],n2[0]);
  for (k=0; k<ne; k++) {
    if (n1[k] < minn)
      minn = n1[k];
    if (n2[k] < minn)
      minn = n2[k];
    if (n1[k] > maxn)
      maxn = n1[k];
    if (n2[k] > maxn)
      maxn = n2[k];
  }

  /* build graph */
  gp->n = maxn-minn+1;
  gp->node = calloc(gp->n,sizeof(node));
  gp->nlink = 0;
  for (k=0; k<ne; k++)
    addlink(gp, n1[k]-minn, n2[k]-minn);

  free(line);
  free(n1);
  free(n2);
  return gp;
}
Пример #9
0
ptr<afsdir>
afsdir::mkdir (const str &name)
{
  ref<afsdir> d = allocsubdir (this);
  if (!link (d, name))
    return NULL;
  addlink ();
  return d;
}
Пример #10
0
ptr<afsdir>
afsusrdir::mkctdir (const str &name)
{
  ref<afsdir> d = New refcounted<ctdir> (this);
  if (!link (d, name))
    return NULL;
  addlink ();
  return d;
}
Пример #11
0
ptr<afsdir>
afsusrdir::mkdir (const str &name)
{
  ref<afsdir> d (alloc (root, aid, this,
			path ? str (path << "/" << name) : name));
  if (!link (d, name))
    return NULL;
  addlink ();
  return d;
}
int  newlink(Padjlist alink)
/*
**--------------------------------------------------------------
** Input:   alink = element of node's adjacency list            
** Output:  returns 1 if successful, 0 if not                   
** Purpose: links end of current adjacent link to end nodes of  
**          all links that follow it on adjacency list          
**--------------------------------------------------------------
*/
{
   int   inode, jnode;
   Padjlist blink;

   /* Scan all entries in adjacency list that follow anode. */
   inode = alink->node;             /* End node of connection to anode */
   for (blink = alink->next; blink != NULL; blink = blink->next)
   {
      jnode = blink->node;          /* End node of next connection */

      /* If jnode still active, and inode not connected to jnode, */
      /* then add a new connection between inode and jnode.       */
      if (Degree[jnode] > 0)        /* jnode still active */
      {
         if (!linked(inode,jnode))  /* inode not linked to jnode */
         {

            /* Since new connection represents a non-zero coeff. */
	    /* in the solution matrix, update the coeff. count.  */
            Ncoeffs++;

	    /* Update adjacency lists for inode & jnode to */
	    /* reflect the new connection.                 */
            if (!addlink(inode,jnode,Ncoeffs)) return(0);
            if (!addlink(jnode,inode,Ncoeffs)) return(0);
            Degree[inode]++;
            Degree[jnode]++;
         }
      }
   }
   return(1);
}                        /* End of newlink */
Пример #13
0
struct link *addlink(struct link *p,int *nlines) {
	struct link *askMer(void);
	if(p == NULL) {
		p = askMer();
		p->x = *nlines;
		p->next = NULL;
	}
	else if(p->x != *nlines) {
		p->next = addlink(p->next,nlines);
	}

	return p;
}
Пример #14
0
/*
 * Rule for PCI cdrom drives.
 */
static void
rule_atapicd(struct devices_ent *dep)
{
	static int last_minor = -1;
	static int cdnum = -1;
	char *min_comp = dep->min_comp;
	int minor = dep->minor;

	if (strcmp(min_comp, "c") == 0) {
		if (minor != last_minor) {
			cdnum++;
			last_minor = minor;
		}
		if (dep->israw) {
			(void) sprintf(namebuf, "rsr%d", cdnum);
			addlink(namebuf, "rdsk/", dep, 0);
		} else {
			(void) sprintf(namebuf, "sr%d", cdnum);
			addlink(namebuf, "dsk/", dep, 0);
		}
	}
}
Пример #15
0
static struct inode *newdir(struct filesys *fs, struct inode *parent)
{
	struct inode *dirnode;

	/* allocate and initialize inode */
	if(!(dirnode = malloc(sizeof *dirnode))) {
		return 0;
	}
	memset(dirnode, 0, sizeof *dirnode);

	if((dirnode->ino = alloc_inode(fs)) == -1) {
		printf("failed to allocate inode for a new directory\n");
		free(dirnode);
		return 0;
	}
	dirnode->mode = S_IFDIR;

	/* add . and .. links */
	addlink(fs, dirnode, dirnode, ".");
	addlink(fs, dirnode, parent ? parent : dirnode, "..");

	return dirnode;
}
Пример #16
0
Файл: g28.c Проект: 8l/csolve
void addlks(int s,int g,int nos){ /* addlinks from g to groups adjacent to s */
				/* dont add links to nos */
   int c1,i,g2,ldtmp,sn;

   c1 = grcolor[g];
   i = fdir[s];
   for(ldtmp = ldir[i]; i < ldtmp; ++i){
      sn = s + nbr[i];
      if(sn == nos)continue;
      g2 = board[sn];
      if(g2 == g || grcolor[g2] != c1)continue;
      addlink(g,g2,s);
      }
   }
Пример #17
0
/*
 * Do a du on a single file.
 * Now takes into account indirect blocks.
 */
long dusize(void)
{
	int i;
	long blocks;

	if ((sb.st_mode & S_IFMT) != S_IFDIR
	 && sb.st_nlink > 1
	 && addlink(sb.st_dev, sb.st_ino))
		return (0);
	blocks = (sb.st_size+BUFSIZ-1) / BUFSIZ;
	for (i = 0; i < sizeof(ranges)/sizeof(ranges[0]); ++i)
		if (blocks <= ranges[i])
			break;
	return (blocks + i);
}
Пример #18
0
/*
 * Rule for Archive tapes.  "ar" isn't in name_to_major but
 * the awk-based version had a rule so it is here too.  The
 * rule works the same as the awk rule, but who knows if it
 * is correct.
 */
static void
rule_ar(struct devices_ent *dep)
{
	char *min_comp = dep->min_comp;

	if (*min_comp != '\0') {
		if (min_comp[strlen(min_comp) - 1] == 'n')
			(void) sprintf(namebuf, "%s%d", "nrar",
			    (dep->minor - 16) / 4);
		else
			(void) sprintf(namebuf, "%s%d", "rar", dep->minor / 4);

		addlink(namebuf, "rmt/", dep, 1);
	}
}
Пример #19
0
/*
 * Rule for IPI disks.  This is hopelessly broken (see bug 1157501)
 * but someone may have come to depend on the broken names.
 */
static void
rule_id(struct devices_ent *dep)
{
	char *targ_pfx;
	char *link_pfx;

	if (dep->israw) {
		link_pfx = "r";
		targ_pfx = "rdsk/";
	} else {
		link_pfx = "";
		targ_pfx = "dsk/";
	}

	(void) sprintf(namebuf, "%sid%x%s", link_pfx, dep->minor,
	    dep->min_comp);
	addlink(namebuf, targ_pfx, dep, 0);
}
Пример #20
0
Файл: g28.c Проект: 8l/csolve
void chkcon(int s,int g){  /* add connections to g at libs next to s */
				/* s has a stone on it for group g */
   int i,sn,sn2,j,cflag,gflag,c;
   int grp[4],k,l,ldtmp,ldtm2;

   for(i = 0; i < 4; i++){
       grp[i] = -1;
       }
   c = grcolor[g];
   i = fdir[s];
   for(ldtmp = ldir[i]; i != ldtmp; ++i){
      sn = s + nbr[i];
      if(board[sn] != NOGROUP)continue;
      for(j = 0; j < 4; ++j){
         if(grcolor[board[sqrbrd[sn][j]]] == c &&
           (dstbrd[sn][j] == 1  ))
            addlink(g,board[sqrbrd[sn][j]],sn);
         if(grcolor[board[sqrbrd[sn][j]]] == c &&
           (dstbrd[sn][j] == 2  ))
            addlkg(g,board[sqrbrd[sn][j]],sn);
	 }
      cflag = FALSE;
      k = 0;
      j = fdir[sn];
      for(ldtm2 = ldir[j]; j != ldtm2; ++j){
         sn2 = sn + nbr[j];
         if(sn2 == s)continue;
         if(board[sn2] == NOGROUP)continue;
         gflag = FALSE;
         for(l = 0; l != k; ++l)
            if(grp[l] == board[sn2])gflag = TRUE;
         if(gflag)continue;
         if(board[sn2] != g){
            grp[k++] = board[sn2];
            }
         else cflag = TRUE;
         }
      if(!cflag)
         for(j = 0; j != k; ++j)
            if(grcolor[grp[j]] == c)addconn(grp[j],g,sn);
      }
   }
Пример #21
0
OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
{
    CHECK_PDM_INIT(TAG);
    if (NULL == UUID1 || NULL == UUID2)
    {
        OC_LOG(ERROR, TAG, "Invalid PARAM");
        return  OC_STACK_INVALID_PARAM;
    }
    int id1 = 0;
    if (OC_STACK_OK != getIdForUUID(UUID1, &id1))
    {
        OC_LOG(ERROR, TAG, "Requested value not found");
        return OC_STACK_INVALID_PARAM;
    }
    int id2 = 0;
    if (OC_STACK_OK != getIdForUUID(UUID2, &id2))
    {
        OC_LOG(ERROR, TAG, "Requested value not found");
        return OC_STACK_INVALID_PARAM;
    }
    ASCENDING_ORDER(id1, id2);
    return addlink(id1, id2);
}
Пример #22
0
static void
rule_stxt(struct devices_ent *dep)
{
	char *min_comp = dep->min_comp;
	int minor = dep->minor;
	int drive, den;
	char *link_pfx;

	if (*min_comp != 'b' && *min_comp != 'n') {
		if ((minor & MT_BSD) == 0)
			return;		/* not BSD-style */

		drive = MTUNIT(minor);
		den = MT_DENSITY(minor);

		if (min_comp[strlen(min_comp) - 1] == 'n')
			link_pfx = "nr";
		else
			link_pfx = "r";
		(void) sprintf(namebuf, "%s%s%d", link_pfx, dep->drp->name,
		    (den * 8) + drive);
		addlink(namebuf, "rmt/", dep, 1);
	}
}
static int addlink (stralloc3 *blah, unsigned int dstpos, unsigned int srcpos)
{
  if (symlink(blah->src.s + srcpos, blah->dst.s + dstpos) >= 0) return MODIFIED ;
  if (errno != EEXIST) return ERROR ;

  {
    unsigned int dstbase = blah->dst.len ;
    unsigned int srcbase = blah->src.len ;
    unsigned int tmpbase = blah->tmp.len ;
    unsigned int dststop ;
    unsigned int srcstop ;
    signed int diffsize = 0 ;
    int collect = 1 ;

    {
      register unsigned int n = str_len(blah->dst.s + dstpos) ;
      if (!stralloc_readyplus(&blah->dst, n+1)) return ERROR ;
      stralloc_catb(&blah->dst, blah->dst.s + dstpos, n) ;
    }
    stralloc_catb(&blah->dst, "/", 1) ;
    dststop = blah->dst.len ;

    {
      int r ;
      DIR *dir = opendir(blah->dst.s + dstpos) ;
      if (!dir)
      {
        blah->dst.len = dstbase ;
        if (errno != ENOTDIR) return ERROR ;
        if ((unlink(blah->dst.s + dstpos) == -1)
         || (symlink(blah->src.s + srcpos, blah->dst.s + dstpos) == -1))
          return ERROR ;
        return OVERRIDEN ; /* replaced a link to a normal file */
      }
      r = sareadlink(&blah->src, blah->dst.s + dstpos) ;
      if ((r == -1) && (errno != EINVAL))
      {
        register int e = errno ;
        blah->dst.len = dstbase ;
        dir_close(dir) ;
        errno = e ;
        return ERROR ;
      }
      if (r < 0)
      {
        for (;;)
        {
          register direntry *d ;
          errno = 0 ;
          d = readdir(dir) ;
          if (!d) break ;
          if ((d->d_name[0] == '.') && (!d->d_name[1] || ((d->d_name[1] == '.') && !d->d_name[2])))
            continue ;
          diffsize-- ;  /* need to know the size for collect */
        }
        if (errno)
        {
          register int e = errno ;
          blah->src.len = srcbase ;
          blah->dst.len = dstbase ;
          dir_close(dir) ;
          errno = e ;
          return ERROR ;
        }
      }
      else if ((unlink(blah->dst.s + dstpos) == -1)
            || (mkdir(blah->dst.s + dstpos, 0777) == -1)
            || !stralloc_catb(&blah->src, "/", 1))
      {
        register int e = errno ;
        blah->src.len = srcbase ;
        blah->dst.len = dstbase ;
        dir_close(dir) ;
        errno = e ;
        return ERROR ;
      }
      else         /* expand */
      {
        srcstop = blah->src.len ;
        for (;;)
        {
          register direntry *d ;
          errno = 0 ;
          d = readdir(dir) ;
          if (!d) break ;
          if ((d->d_name[0] == '.') && (!d->d_name[1] || ((d->d_name[1] == '.') && !d->d_name[2])))
            continue ;
          diffsize-- ;
          blah->dst.len = dststop ;
          blah->src.len = srcstop ;
          if (!stralloc_cats(&blah->dst, d->d_name) || !stralloc_0(&blah->dst)
           || !stralloc_cats(&blah->src, d->d_name) || !stralloc_0(&blah->src)
           || (symlink(blah->src.s + srcbase, blah->dst.s + dstbase) == -1))
          {
            register int e = errno ;
            blah->src.len = srcbase ;
            blah->dst.len = dstbase ;
            dir_close(dir) ;
            errno = e ;
            return ERROR ;
          }
        }
        if (errno)
        {
          register int e = errno ;
          blah->src.len = srcbase ;
          blah->dst.len = dstbase ;
          dir_close(dir) ;
          errno = e ;
          return ERROR ;
        }
      }
      dir_close(dir) ;
    }

    blah->src.len = srcbase ;
    {
      register unsigned int n = str_len(blah->src.s + srcpos) ;
      if (!stralloc_readyplus(&blah->src, n+1))
      {
        blah->dst.len = dstbase ;
        return ERROR ;
      }
      stralloc_catb(&blah->src, blah->src.s + srcpos, n) ;
    }
    stralloc_catb(&blah->src, "/", 1) ;
    srcstop = blah->src.len ;


   /* prepare tmp for recursion */

    {
      DIR *dir = opendir(blah->src.s + srcpos) ;
      if (!dir)
      {
        blah->src.len = srcbase ;
        blah->dst.len = dstbase ;
        if (errno != ENOTDIR) return ERROR ;
        errdst.len = errsrc.len = 0 ;
        if (!stralloc_cats(&errdst, blah->dst.s + dstpos) || !stralloc_0(&errdst)
         || !stralloc_cats(&errsrc, blah->src.s + srcpos) || !stralloc_0(&errsrc))
          return ERROR ;
        return CONFLICT ; /* dst is a dir but src is not */
      }
      for (;;)
      {
        register direntry *d ;
        errno = 0 ;
        d = readdir(dir) ;
        if (!d) break ;
        if ((d->d_name[0] == '.') && (!d->d_name[1] || ((d->d_name[1] == '.') && !d->d_name[2])))
          continue ;
        if (!stralloc_cats(&blah->tmp, d->d_name) || !stralloc_0(&blah->tmp))
        {
          register int e = errno ;
          blah->tmp.len = tmpbase ;
          blah->src.len = srcbase ;
          blah->dst.len = dstbase ;
          dir_close(dir) ;
          errno = e ;
          return ERROR ;
        }
      }
      if (errno)
      {
        register int e = errno ;
        blah->tmp.len = tmpbase ;
        blah->src.len = srcbase ;
        blah->dst.len = dstbase ;
        dir_close(dir) ;
        errno = e ;
        return ERROR ;
      }
      dir_close(dir) ;
    }


   /* recurse */

    {
      unsigned int i = tmpbase ;
      while (i < blah->tmp.len)
      {
        diffsize++ ;
        blah->dst.len = dststop ;
        blah->src.len = srcstop ;
        {
          register unsigned int n = str_len(blah->tmp.s + i) + 1 ;
          if (!stralloc_catb(&blah->dst, blah->tmp.s + i, n)
           || !stralloc_catb(&blah->src, blah->tmp.s + i, n))
          {
            blah->tmp.len = tmpbase ;
            blah->src.len = srcbase ;
            blah->dst.len = dstbase ;
            return ERROR ;
          }
          i += n ;
        }
        switch (addlink(blah, dstbase, srcbase))
        {
          case ERROR :
            blah->tmp.len = tmpbase ;
            blah->src.len = srcbase ;
            blah->dst.len = dstbase ;
            return ERROR ;
          case CONFLICT :
            blah->tmp.len = tmpbase ;
            blah->src.len = srcbase ;
            blah->dst.len = dstbase ;
            return CONFLICT ;
          case MODIFIED :
            collect = 0 ;
        }
      }
    }
    blah->tmp.len = tmpbase ;
    blah->src.len = srcbase ;
    blah->dst.len = dstbase ;


   /* collect */

    if (collect && !diffsize)
    {
      if (rm_rf_in_tmp(&blah->dst, dstpos) == -1) return ERROR ;
      if (symlink(blah->src.s + srcpos, blah->dst.s + dstpos) == -1) return ERROR ;
      return OVERRIDEN ;
    }
  }
  return MODIFIED ;
}
int main (int argc, char *const *argv)
{
  stralloc3 blah = STRALLOC3_ZERO ;
  PROG = "s6-update-symlinks" ;
  if (argc < 3) strerr_dieusage(100, USAGE) ;
  {
    register char *const *p = argv + 1 ;
    for (; *p ; p++) if (**p != '/') strerr_dieusage(100, USAGE) ;
  }
  {
    register unsigned int i = str_len(argv[1]) ;
    while (i && (argv[1][i-1] == '/')) argv[1][--i] = 0 ;
    if (!i) strerr_diefu1x(100, "replace root directory") ;
  }
  if (!makeuniquename(&blah.dst, argv[1], MAGICNEW))
    strerr_diefu2sys(111, "make random unique name based on ", argv[1]) ;
  if ((unlink(blah.dst.s) == -1) && (errno != ENOENT))
    strerr_diefu2sys(111, "unlink ", blah.dst.s) ;

  {
    char *const *p = argv + 2 ;
    for (; *p ; p++)
    {
      register int r ;
      blah.src.len = 0 ;
      if (!stralloc_cats(&blah.src, *p) || !stralloc_0(&blah.src))
        strerr_diefu1sys(111, "make stralloc") ;
      r = addlink(&blah, 0, 0) ;
      if (r < 0)
      {
        stralloc_free(&blah.tmp) ;
        stralloc_free(&blah.src) ;
        cleanup(&blah.dst, 0) ;
        stralloc_free(&blah.dst) ;
        if (r == CONFLICT)
          strerr_dief4x(100, "destination ", errdst.s, " conflicts with source ", errsrc.s) ;
        else
          strerr_dief2sys(111, "error processing ", *p) ;
      }
    }
  }
  stralloc_free(&blah.tmp) ;

  if (rename(blah.dst.s, argv[1]) == -1) /* be atomic if possible */
  {
    blah.src.len = 0 ;
    if (!makeuniquename(&blah.src, argv[1], MAGICOLD))
    {
      cleanup(&blah.dst, 0) ;
      strerr_diefu2sys(111, "make random unique name based on ", argv[1]) ;
    }

    if (rename(argv[1], blah.src.s) == -1)
    {
      cleanup(&blah.dst, 0) ;
      strerr_diefu4sys(111, "rename ", argv[1], " to ", blah.src.s) ;
    }
   /* XXX: unavoidable race condition here: argv[1] does not exist */
    if (rename(blah.dst.s, argv[1]) == -1)
    {
      rename(blah.src.s, argv[1]) ;
      cleanup(&blah.dst, 0) ;
      strerr_diefu4sys(111, "rename ", blah.dst.s, " to ", argv[1]) ;
    }
    stralloc_free(&blah.dst) ;
    if (rm_rf_in_tmp(&blah.src, 0) == -1)
      strerr_warnwu2sys("remove old directory ", blah.src.s) ;
    stralloc_free(&blah.src) ;
  }

  return 0 ;
}
Пример #25
0
/*
 * Rule for frame buffers.
 */
static void
rule_fbs(struct devices_ent *dep)
{
	addlink(dep->min_comp, "fbs/", dep, 0);
}