// creates a hard link void mklink_cmd(int term, char **args, int argc) { char *path = NULL, *path2 = NULL; if(argc != 2) { term_color_print(term, invalid_params, 12); term_color_print(term, "Usage: ln filename linkname.\n", 7); return; } path = build_path(args[0], term); if(path == NULL) { term_color_print(term, "Invalid filename.\n", 7); return; } path2 = build_path(args[1], term); if(path2 == NULL) { term_color_print(term, "Invalid linkname.\n", 7); return; } if(mklink(path, path2)) { term_color_print(term, mapioerr(ioerror()), 12); term_color_print(term, "\n", 11); } free(path); free(path2); }
int mklink_sa(stralloc* target, stralloc* link) { size_t i; stralloc_nul(target); stralloc_nul(link); if(stralloc_rchr(target, '/') == target->len && (i = stralloc_rchr(link, '/')) != link->len) { size_t len = i + 1; stralloc_insertb(target, link->s, 0, len); } /*if(verbose) { buffer_putsa(buffer_2, link); buffer_puts(buffer_2, " -> "); buffer_putsa(buffer_2, target); buffer_putnlflush(buffer_2); }*/ stralloc_nul(target); return mklink(target->s, link->s); }
int main(int argc, char **argv) { char *db_dir = NULL; extern int errno; int (*mklink)(const char*, const char*) = link; /* Parse options. */ int c; extern int optind; extern char *optarg; while ((c = getopt(argc, argv, "+d:sh")) != -1) { switch (c) { case 'd': db_dir = strdup(optarg); break; case 's': mklink = symlink; break; case 'h': usage(argv[0]); return 0; } } /* Default db_dir. */ if (db_dir == NULL && (db_dir = getenv("PHASHDB")) == NULL) { char *home = getenv("HOME"); if (home == NULL) home = "/tmp"; db_dir = malloc(strlen(home) + 10); snprintf(db_dir, strlen(home) + 10, "%s/.phashdb", home); } /* Calculate hash. */ errno = 0; uint64_t h = phash_dct(argv[optind]); if (h == (uint64_t)0 && errno == EINVAL) /* Not an image; ignore. */ return 0; /* Create db_dir if it doesn't exist yet. */ errno = 0; if (mkdir(db_dir, 0755) != 0 && errno != EEXIST) { perror("Can't create DB dir"); return 1; } /* Create the hash folder if it doesn't exist yet. */ unsigned sz = strlen(db_dir) + 16 + 2; char *hdir = malloc(sz); snprintf(hdir, sz, "%s/%016" PRIx64, db_dir, h); errno = 0; if (mkdir(hdir, 0755) != 0 && errno != EEXIST) { perror("Can't create folder in DB dir"); return 1; } /* Determine a valid filename. */ char *arg = strdup(argv[optind]), *bn = basename(arg), *fn = malloc((sz = strlen(hdir) + strlen(bn) + 2)); FILE *f; snprintf(fn, sz, "%s/%s", hdir, bn); while ((f = fopen(fn, "r")) != NULL) { fclose(f); char *ext = strdup(strrchr(fn, '.')); if (ext == NULL) ext = ""; int el = strlen(ext); fn = realloc(fn, ++sz); strcpy(fn + sz - el - 1, ext); free(ext); fn[sz - el - 2] = '_'; } /* Create link. */ if (mklink(argv[optind], fn) != 0) { perror("Can't link"); return 1; } return 0; }
int yyparse(void) { struct { YYSTYPE yyv; int yys; } yys[YYMAXDEPTH], *yyp, *yypt; short *yyxi; int yyj, yym, yystate, yyn, yyg; long yychar; YYSTYPE save1, save2; int save3, save4; save1 = yylval; save2 = yyval; save3 = yynerrs; save4 = yyerrflag; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; yyp = &yys[-1]; goto yystack; ret0: yyn = 0; goto ret; ret1: yyn = 1; goto ret; ret: yylval = save1; yyval = save2; yynerrs = save3; yyerrflag = save4; return yyn; yystack: /* put a state and value onto the stack */ if(yydebug >= 4) fprint(2, "char %s in %s", yytokname(yychar), yystatname(yystate)); yyp++; if(yyp >= &yys[YYMAXDEPTH]) { yyerror("yacc stack overflow"); goto ret1; } yyp->yys = yystate; yyp->yyv = yyval; yynewstate: yyn = yypact[yystate]; if(yyn <= YYFLAG) goto yydefault; /* simple state */ if(yychar < 0) yychar = yylex1(); yyn += yychar; if(yyn < 0 || yyn >= YYLAST) goto yydefault; yyn = yyact[yyn]; if(yychk[yyn] == yychar) { /* valid shift */ yychar = -1; yyval = yylval; yystate = yyn; if(yyerrflag > 0) yyerrflag--; goto yystack; } yydefault: /* default state action */ yyn = yydef[yystate]; if(yyn == -2) { if(yychar < 0) yychar = yylex1(); /* look through exception table */ for(yyxi=yyexca;; yyxi+=2) if(yyxi[0] == -1 && yyxi[1] == yystate) break; for(yyxi += 2;; yyxi += 2) { yyn = yyxi[0]; if(yyn < 0 || yyn == yychar) break; } yyn = yyxi[1]; if(yyn < 0) goto ret0; } if(yyn == 0) { /* error ... attempt to resume parsing */ switch(yyerrflag) { case 0: /* brand new error */ yyerror("syntax error"); yynerrs++; if(yydebug >= 1) { fprint(2, "%s", yystatname(yystate)); fprint(2, "saw %s\n", yytokname(yychar)); } case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while(yyp >= yys) { yyn = yypact[yyp->yys] + YYERRCODE; if(yyn >= 0 && yyn < YYLAST) { yystate = yyact[yyn]; /* simulate a shift of "error" */ if(yychk[yystate] == YYERRCODE) goto yystack; } /* the current yyp has no shift onn "error", pop stack */ if(yydebug >= 2) fprint(2, "error recovery pops state %d, uncovers %d\n", yyp->yys, (yyp-1)->yys ); yyp--; } /* there is no state on the stack with an error shift ... abort */ goto ret1; case 3: /* no shift yet; clobber input char */ if(yydebug >= 2) fprint(2, "error recovery discards %s\n", yytokname(yychar)); if(yychar == YYEOFCODE) goto ret1; yychar = -1; goto yynewstate; /* try again in the same state */ } } /* reduction by production yyn */ if(yydebug >= 2) fprint(2, "reduce %d in:\n\t%s", yyn, yystatname(yystate)); yypt = yyp; yyp -= yyr2[yyn]; yyval = (yyp+1)->yyv; yym = yyn; /* consult goto table to find next state */ yyn = yyr1[yyn]; yyg = yypgo[yyn]; yyj = yyg + yyp->yys + 1; if(yyj >= YYLAST || yychk[yystate=yyact[yyj]] != -yyn) yystate = yyact[yyg]; switch(yym) { case 1: #line 41 "asm.y" { assem(yypt[-0].yyv.inst); } break; case 2: #line 47 "asm.y" { yyval.inst = nil; } break; case 3: #line 49 "asm.y" { if(yypt[-0].yyv.inst != nil) { yypt[-0].yyv.inst->link = yypt[-1].yyv.inst; yyval.inst = yypt[-0].yyv.inst; } else yyval.inst = yypt[-1].yyv.inst; } break; case 4: #line 60 "asm.y" { yypt[-0].yyv.inst->sym = yypt[-2].yyv.sym; yyval.inst = yypt[-0].yyv.inst; } break; case 5: #line 65 "asm.y" { heap(yypt[-3].yyv.ival, yypt[-1].yyv.ival, yypt[-0].yyv.string); yyval.inst = nil; } break; case 6: #line 70 "asm.y" { yyval.inst = nil; } break; case 8: #line 77 "asm.y" { yyval.ival = yypt[-0].yyv.ival; } break; case 9: #line 81 "asm.y" { yypt[-0].yyv.sym->value = heapid++; yyval.ival = yypt[-0].yyv.sym->value; } break; case 10: #line 88 "asm.y" { yyval.string = nil; } break; case 11: #line 90 "asm.y" { yyval.string = yypt[-0].yyv.string; } break; case 12: #line 96 "asm.y" { yyval.list = newi(yypt[-0].yyv.ival, nil); } break; case 13: #line 100 "asm.y" { yyval.list = newi(yypt[-0].yyv.ival, yypt[-2].yyv.list); } break; case 14: #line 106 "asm.y" { yyval.inst = ai(yypt[-3].yyv.ival); yyval.inst->src = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 15: #line 112 "asm.y" { yyval.inst = ai(yypt[-5].yyv.ival); yyval.inst->src = yypt[-4].yyv.addr; yyval.inst->reg = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 16: #line 119 "asm.y" { yyval.inst = ai(yypt[-3].yyv.ival); yyval.inst->src = yypt[-2].yyv.addr; yyval.inst->dst = yypt[-0].yyv.addr; } break; case 17: #line 125 "asm.y" { yyval.inst = ai(yypt[-1].yyv.ival); yyval.inst->dst = yypt[-0].yyv.addr; } break; case 18: #line 130 "asm.y" { yyval.inst = ai(yypt[-0].yyv.ival); } break; case 19: #line 136 "asm.y" { data(DEFB, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 20: #line 140 "asm.y" { data(DEFW, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 21: #line 144 "asm.y" { data(DEFL, yypt[-2].yyv.ival, yypt[-0].yyv.list); } break; case 22: #line 148 "asm.y" { data(DEFF, yypt[-2].yyv.ival, newi(dtocanon((double)yypt[-0].yyv.ival), nil)); } break; case 23: #line 152 "asm.y" { data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(yypt[-0].yyv.fval), nil)); } break; case 24: #line 156 "asm.y" { if(strcmp(yypt[-0].yyv.sym->name, "Inf") == 0 || strcmp(yypt[-0].yyv.sym->name, "Infinity") == 0) { u.l = (uvlong)0x7ff00000<<32; data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(u.d), nil)); } else if(strcmp(yypt[-0].yyv.sym->name, "NaN") == 0) { u.l = ((uvlong)0x7fffffff<<32) | (uvlong)0xffffffffUL; data(DEFF, yypt[-2].yyv.ival, newi(dtocanon(u.d), nil)); } else diag("bad value for real: %s", yypt[-0].yyv.sym->name); } break; case 25: #line 167 "asm.y" { data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(-(double)yypt[-0].yyv.ival), nil)); } break; case 26: #line 171 "asm.y" { data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(-yypt[-0].yyv.fval), nil)); } break; case 27: #line 175 "asm.y" { if(strcmp(yypt[-0].yyv.sym->name, "Inf") == 0 || strcmp(yypt[-0].yyv.sym->name, "Infinity") == 0) { u.l = (uvlong)0xfff00000<<32; data(DEFF, yypt[-3].yyv.ival, newi(dtocanon(u.d), nil)); } else diag("bad value for real: %s", yypt[-0].yyv.sym->name); } break; case 28: #line 183 "asm.y" { data(DEFS, yypt[-2].yyv.ival, news(yypt[-0].yyv.string, nil)); } break; case 29: #line 187 "asm.y" { if(yypt[-2].yyv.sym->ds != 0) diag("%s declared twice", yypt[-2].yyv.sym->name); yypt[-2].yyv.sym->ds = yypt[-0].yyv.ival; yypt[-2].yyv.sym->value = dseg; dseg += yypt[-0].yyv.ival; } break; case 30: #line 195 "asm.y" { ext(yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.string); } break; case 31: #line 199 "asm.y" { mklink(yypt[-6].yyv.ival, yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.string); } break; case 32: #line 203 "asm.y" { if(module != nil) diag("this module already defined as %s", yypt[-0].yyv.sym->name); else module = yypt[-0].yyv.sym; } break; case 33: #line 210 "asm.y" { if(pcentry >= 0) diag("this module already has entry point %d, %d" , pcentry, dentry); pcentry = yypt[-2].yyv.ival; dentry = yypt[-0].yyv.ival; } break; case 34: #line 217 "asm.y" { data(DEFA, yypt[-4].yyv.ival, newa(yypt[-2].yyv.ival, yypt[-0].yyv.ival)); } break; case 35: #line 221 "asm.y" { data(DIND, yypt[-2].yyv.ival, newa(yypt[-0].yyv.ival, 0)); } break; case 36: #line 225 "asm.y" { data(DAPOP, 0, newa(0, 0)); } break; case 37: #line 229 "asm.y" { ldts(yypt[-0].yyv.ival); } break; case 38: #line 233 "asm.y" { excs(yypt[-0].yyv.ival); } break; case 39: #line 237 "asm.y" { exc(yypt[-10].yyv.ival, yypt[-8].yyv.ival, yypt[-6].yyv.ival, yypt[-4].yyv.ival, yypt[-2].yyv.ival, yypt[-0].yyv.ival); } break; case 40: #line 241 "asm.y" { etab(yypt[-2].yyv.string, yypt[-0].yyv.ival); } break; case 41: #line 245 "asm.y" { etab(nil, yypt[-0].yyv.ival); } break; case 42: #line 249 "asm.y" { source(yypt[-0].yyv.string); } break; case 43: #line 255 "asm.y" { yyval.addr = aa(yypt[-0].yyv.ival); yyval.addr->mode = AXIMM; if(yyval.addr->val > 0x7FFF || yyval.addr->val < -0x8000) diag("immediate %d too large for middle operand", yyval.addr->val); } break; case 44: #line 262 "asm.y" { if(yypt[-0].yyv.addr->mode == AMP) yypt[-0].yyv.addr->mode = AXINM; else yypt[-0].yyv.addr->mode = AXINF; if(yypt[-0].yyv.addr->mode == AXINM && (ulong)yypt[-0].yyv.addr->val > 0xFFFF) diag("register offset %d(mp) too large", yypt[-0].yyv.addr->val); if(yypt[-0].yyv.addr->mode == AXINF && (ulong)yypt[-0].yyv.addr->val > 0xFFFF) diag("register offset %d(fp) too large", yypt[-0].yyv.addr->val); yyval.addr = yypt[-0].yyv.addr; } break; case 45: #line 276 "asm.y" { yyval.addr = aa(yypt[-0].yyv.ival); yyval.addr->mode = AIMM; } break; case 46: #line 281 "asm.y" { yyval.addr = aa(0); yyval.addr->sym = yypt[-0].yyv.sym; } break; case 48: #line 289 "asm.y" { yypt[-0].yyv.addr->mode |= AIND; yyval.addr = yypt[-0].yyv.addr; } break; case 49: #line 294 "asm.y" { yypt[-1].yyv.addr->mode |= AIND; if(yypt[-1].yyv.addr->val & 3) diag("indirect offset must be word size"); if(yypt[-1].yyv.addr->mode == (AMP|AIND) && ((ulong)yypt[-1].yyv.addr->val > 0xFFFF || (ulong)yypt[-3].yyv.ival > 0xFFFF)) diag("indirect offset %d(%d(mp)) too large", yypt[-3].yyv.ival, yypt[-1].yyv.addr->val); if(yypt[-1].yyv.addr->mode == (AFP|AIND) && ((ulong)yypt[-1].yyv.addr->val > 0xFFFF || (ulong)yypt[-3].yyv.ival > 0xFFFF)) diag("indirect offset %d(%d(fp)) too large", yypt[-3].yyv.ival, yypt[-1].yyv.addr->val); yypt[-1].yyv.addr->off = yypt[-1].yyv.addr->val; yypt[-1].yyv.addr->val = yypt[-3].yyv.ival; yyval.addr = yypt[-1].yyv.addr; } break; case 51: #line 310 "asm.y" { yyval.addr = aa(yypt[-3].yyv.ival); yyval.addr->mode = AMP; } break; case 52: #line 315 "asm.y" { yyval.addr = aa(yypt[-3].yyv.ival); yyval.addr->mode = AFP; } break; case 54: #line 323 "asm.y" { yyval.ival = yypt[-0].yyv.sym->value; } break; case 55: #line 327 "asm.y" { yyval.ival = -yypt[-0].yyv.ival; } break; case 56: #line 331 "asm.y" { yyval.ival = yypt[-0].yyv.ival; } break; case 57: #line 335 "asm.y" { yyval.ival = ~yypt[-0].yyv.ival; } break; case 58: #line 339 "asm.y" { yyval.ival = yypt[-1].yyv.ival; } break; case 60: #line 346 "asm.y" { yyval.ival = yypt[-2].yyv.ival + yypt[-0].yyv.ival; } break; case 61: #line 350 "asm.y" { yyval.ival = yypt[-2].yyv.ival - yypt[-0].yyv.ival; } break; case 62: #line 354 "asm.y" { yyval.ival = yypt[-2].yyv.ival * yypt[-0].yyv.ival; } break; case 63: #line 358 "asm.y" { yyval.ival = yypt[-2].yyv.ival / yypt[-0].yyv.ival; } break; case 64: #line 362 "asm.y" { yyval.ival = yypt[-2].yyv.ival % yypt[-0].yyv.ival; } break; case 65: #line 366 "asm.y" { yyval.ival = yypt[-3].yyv.ival << yypt[-0].yyv.ival; } break; case 66: #line 370 "asm.y" { yyval.ival = yypt[-3].yyv.ival >> yypt[-0].yyv.ival; } break; case 67: #line 374 "asm.y" { yyval.ival = yypt[-2].yyv.ival & yypt[-0].yyv.ival; } break; case 68: #line 378 "asm.y" { yyval.ival = yypt[-2].yyv.ival ^ yypt[-0].yyv.ival; } break; case 69: #line 382 "asm.y" { yyval.ival = yypt[-2].yyv.ival | yypt[-0].yyv.ival; } break; } goto yystack; /* stack new state and value */ }