static void c_output(const char *infile, const char *define, int extend, const char *outfile) { definition *def; char *include; const char *outfilename; long tell; c_initialize(); open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); add_warning(); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); /* .h file already contains rpc/rpc.h */ } else f_print(fout, "#include <rpc/rpc.h>\n"); tell = ftell(fout); while ( (def = get_definition()) ) emit(def); if (extend && tell == ftell(fout)) unlink(outfilename); }
/* * Compile into an RPC service */ static void s_output(int argc, char *argv[], char *infile, char *define, int extend, char *outfile, int nomain) { char *include; definition *def; int foundprogram; char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "#include <stdio.h>\n"); f_print(fout, "#include <rpc/rpc.h>\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); } foundprogram = 0; while ((def = get_definition())) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void)unlink(outfilename); return; } if (nomain) { write_programs(NULL); } else { write_most(); do_registers(argc, argv); write_rest(); write_programs("static"); } }
static void l_output(char *infile, char *define, int extend, char *outfile) { char *include; definition *def; int foundprogram; char *outfilename; open_input(infile, define); outfilename = extend ? extendfile(infile, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "#include <rpc/rpc.h>\n"); f_print(fout, "#include <sys/time.h>\n"); if (infile && (include = extendfile(infile, ".h"))) { f_print(fout, "#include \"%s\"\n", include); free(include); } foundprogram = 0; while ((def = get_definition())) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void)unlink(outfilename); return; } write_stubs(); }
/* * generate the dispatch table */ static void t_output (char *infile, char *define, int extend, char *outfile) { definition *def; int foundprogram = 0; char *outfilename; char *incfile; open_input (infile, define); outfilename = extend ? extendfile (infile, outfile) : outfile; incfile = extendfile (infile, ".h"); open_output (infile, outfilename); add_warning (); f_print (fout, "#include \"%s\"\n", incfile); while ((def = get_definition ())) { foundprogram |= (def->def_kind == DEF_PROGRAM); } if (extend && !foundprogram) { (void) unlink (outfilename); return; } write_tables (); }
static const char * file_name(const char *file, const char *ext) { char *temp; temp = extendfile(file, ext); if (access(temp, F_OK) != -1) return(temp); else return(" "); }
/* * Extend the file described by dep to length specified by length. */ int deextend(struct denode *dep, u_long length, struct kauth_cred *cred) { struct msdosfsmount *pmp = dep->de_pmp; u_long count; int error; /* * The root of a DOS filesystem cannot be extended. */ if (dep->de_vnode != NULL && !FAT32(pmp)) return EINVAL; /* * Directories cannot be extended. */ if (dep->de_Attributes & ATTR_DIRECTORY) return EISDIR; if (length <= dep->de_FileSize) return E2BIG; /* * Compute the number of clusters to allocate. */ count = de_clcount(pmp, length) - de_clcount(pmp, dep->de_FileSize); if (count > 0) { if (count > pmp->pm_freeclustercount) return (ENOSPC); error = extendfile(dep, count, NULL, NULL, DE_CLEAR); if (error) { /* truncate the added clusters away again */ (void) detrunc(dep, dep->de_FileSize, 0, cred); return (error); } } /* * Zero extend file range; ubc_zerorange() uses ubc_alloc() and a * memset(); we set the write size so ubc won't read in file data that * is zero'd later. */ dep->de_FileSize = length; dep->de_flag |= DE_UPDATE|DE_MODIFIED; return 0; }
char * generate_guard (char *pathname) { char *filename, *guard, *tmp; filename = strrchr (pathname, '/'); /* find last component */ filename = ((filename == 0) ? pathname : filename + 1); guard = strdup (filename); /* convert to upper case */ tmp = guard; while (*tmp) { if (islower (*tmp)) *tmp = toupper (*tmp); tmp++; } guard = extendfile (guard, "_H_RPCGEN"); return (guard); }
/* * Extend the file described by dep to length specified by length. */ int deextend(struct denode *dep, uint32_t length, struct ucred *cred) { struct msdosfsmount *pmp = dep->de_pmp; uint32_t count; int error; /* * The root of a DOS filesystem cannot be extended. */ if ((DETOV(dep)->v_flag & VROOT) && !FAT32(pmp)) return (EINVAL); /* * Directories cannot be extended. */ if (dep->de_Attributes & ATTR_DIRECTORY) return (EISDIR); if (length <= dep->de_FileSize) panic("deextend: file too large"); /* * Compute the number of clusters to allocate. */ count = de_clcount(pmp, length) - de_clcount(pmp, dep->de_FileSize); if (count > 0) { if (count > pmp->pm_freeclustercount) return (ENOSPC); error = extendfile(dep, count, NULL, NULL, DE_CLEAR); if (error) { /* truncate the added clusters away again */ (void) detrunc(dep, dep->de_FileSize, 0, cred, NULL); return (error); } } dep->de_FileSize = length; dep->de_flag |= DE_UPDATE|DE_MODIFIED; return (deupdat(dep, 1)); }
/* * dep - directory entry to copy into the directory * ddep - directory to add to * depp - return the address of the denode for the created directory entry * if depp != 0 * cnp - componentname needed for Win95 long filenames */ int createde(struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp) { int error, rberror; u_long dirclust, clusoffset; u_long fndoffset, havecnt = 0, wcnt = 1, i; struct direntry *ndep; struct msdosfsmount *pmp = ddep->de_pmp; struct buf *bp; daddr_t bn; int blsize; #ifdef _KERNEL int async = ddep->de_pmp->pm_mountp->mnt_flag & MNT_ASYNC; #else #define async 0 #endif #ifdef MSDOSFS_DEBUG printf("createde(dep %p, ddep %p, depp %p, cnp %p)\n", dep, ddep, depp, cnp); #endif /* * If no space left in the directory then allocate another cluster * and chain it onto the end of the file. There is one exception * to this. That is, if the root directory has no more space it * can NOT be expanded. extendfile() checks for and fails attempts * to extend the root directory. We just return an error in that * case. */ if (ddep->de_fndoffset >= ddep->de_FileSize) { u_long needlen = ddep->de_fndoffset + sizeof(struct direntry) - ddep->de_FileSize; dirclust = de_clcount(pmp, needlen); if ((error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR)) != 0) { (void)detrunc(ddep, ddep->de_FileSize, 0, NOCRED); goto err_norollback; } /* * Update the size of the directory */ ddep->de_FileSize += de_cn2off(pmp, dirclust); } /* * We just read in the cluster with space. Copy the new directory * entry in. Then write it to disk. NOTE: DOS directories * do not get smaller as clusters are emptied. */ error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset), &bn, &dirclust, &blsize); if (error) goto err_norollback; clusoffset = ddep->de_fndoffset; if (dirclust != MSDOSFSROOT) clusoffset &= pmp->pm_crbomask; if ((error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, B_MODIFY, &bp)) != 0) { goto err_norollback; } ndep = bptoep(pmp, bp, clusoffset); DE_EXTERNALIZE(ndep, dep); /* * Now write the Win95 long name */ if (ddep->de_fndcnt > 0) { u_int8_t chksum = winChksum(ndep->deName); const u_char *un = (const u_char *)cnp->cn_nameptr; int unlen = cnp->cn_namelen; u_long xhavecnt; fndoffset = ddep->de_fndoffset; xhavecnt = ddep->de_fndcnt + 1; for(; wcnt < xhavecnt; wcnt++) { if ((fndoffset & pmp->pm_crbomask) == 0) { /* we should never get here if ddep is root * directory */ if (async) (void) bdwrite(bp); else if ((error = bwrite(bp)) != 0) goto rollback; fndoffset -= sizeof(struct direntry); error = pcbmap(ddep, de_cluster(pmp, fndoffset), &bn, 0, &blsize); if (error) goto rollback; error = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, B_MODIFY, &bp); if (error) { goto rollback; } ndep = bptoep(pmp, bp, fndoffset & pmp->pm_crbomask); } else { ndep--; fndoffset -= sizeof(struct direntry); } if (!unix2winfn(un, unlen, (struct winentry *)ndep, wcnt, chksum)) break; } } if (async) bdwrite(bp); else if ((error = bwrite(bp)) != 0) goto rollback; /* * If they want us to return with the denode gotten. */ if (depp) { u_long diroffset = clusoffset; if (dep->de_Attributes & ATTR_DIRECTORY) { dirclust = dep->de_StartCluster; if (FAT32(pmp) && dirclust == pmp->pm_rootdirblk) dirclust = MSDOSFSROOT; if (dirclust == MSDOSFSROOT) diroffset = MSDOSFSROOT_OFS; else diroffset = 0; } error = deget(pmp, dirclust, diroffset, depp); #ifndef MAKEFS if (error == 0) VOP_UNLOCK(DETOV(*depp)); #endif return error; } return 0; rollback: /* * Mark all slots modified so far as deleted. Note that we * can't just call removede(), since directory is not in * consistent state. */ fndoffset = ddep->de_fndoffset; rberror = pcbmap(ddep, de_cluster(pmp, fndoffset), &bn, NULL, &blsize); if (rberror) goto err_norollback; if ((rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, B_MODIFY, &bp)) != 0) { goto err_norollback; } ndep = bptoep(pmp, bp, clusoffset); havecnt = ddep->de_fndcnt + 1; for(i = wcnt; i <= havecnt; i++) { /* mark entry as deleted */ ndep->deName[0] = SLOT_DELETED; if ((fndoffset & pmp->pm_crbomask) == 0) { /* we should never get here if ddep is root * directory */ if (async) bdwrite(bp); else if ((rberror = bwrite(bp)) != 0) goto err_norollback; fndoffset -= sizeof(struct direntry); rberror = pcbmap(ddep, de_cluster(pmp, fndoffset), &bn, 0, &blsize); if (rberror) goto err_norollback; rberror = bread(pmp->pm_devvp, de_bn2kb(pmp, bn), blsize, NOCRED, B_MODIFY, &bp); if (rberror) { goto err_norollback; } ndep = bptoep(pmp, bp, fndoffset); } else { ndep--; fndoffset -= sizeof(struct direntry); } } /* ignore any further error */ if (async) (void) bdwrite(bp); else (void) bwrite(bp); err_norollback: return error; }
static void S_output(char *infile, char *define, int extend, char *outfile, int append) { char *include; char *outfilename; char fullname[1024]; definition *def; long tell; char *currfile = (OutFileFlag ? OutFile : infile); Sflag = 1; open_input(infile, define); memset(fullname, 0, sizeof(fullname)); if (append) { strcpy(fullname, prefix); strcat(fullname, infile); } else strcpy(fullname, infile); outfilename = extend ? extendfile(fullname, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n"); if (currfile && (include = extendfile(currfile, ".h"))) { if (kflag) { f_print(fout, "#include \"%s\"\n", include); } else { f_print(fout, "#include <afsconfig.h>\n"); f_print(fout, "#include <afs/param.h>\n"); f_print(fout, "#include <roken.h>\n"); f_print(fout, "#include \"%s\"\n\n", include); } free(include); } else { if (kflag) { f_print(fout, "#include \"h/types.h\"\n"); f_print(fout, "#include \"h/socket.h\"\n"); f_print(fout, "#include \"h/file.h\"\n"); f_print(fout, "#include \"h/stat.h\"\n"); f_print(fout, "#include \"netinet/in.h\"\n"); f_print(fout, "#include \"h/time.h\"\n"); f_print(fout, "#include \"rpc/types.h\"\n"); f_print(fout, "#include \"rx/xdr.h\"\n"); f_print(fout, "#include \"afs/rxgen_consts.h\"\n"); f_print(fout, "#include \"afs/afs_osi.h\"\n"); f_print(fout, "#include \"rx/rx.h\"\n"); if (xflag) { f_print(fout, "#include \"rx/rx_globals.h\"\n"); } if (brief_flag) { f_print(fout, "#include \"rx/rx_opaque.h\"\n"); } } else { f_print(fout, "#include <sys/types.h>\n"); f_print(fout, "#include <rx/xdr.h>\n"); f_print(fout, "#include <rx/rx.h>\n"); if (xflag) { f_print(fout, "#include <rx/rx_globals.h>\n"); } if (brief_flag) { f_print(fout, "#include <rx/rx_opaque.h>\n"); } f_print(fout, "#include <afs/rxgen_consts.h>\n"); } } tell = ftell(fout); fflush(fout); while ((def = get_definition())) { fflush(fout); print_datadef(def); } er_Proc_CodeGeneration(); if (extend && tell == ftell(fout)) { (void)unlink(outfilename); } Sflag = 0; }
/* * Compile into an XDR header file */ static void h_output(char *infile, char *define, int extend, char *outfile, int append) { definition *def; char *outfilename; long tell; char fullname[1024], *p; open_input(infile, define); hflag = 1; memset(fullname, 0, sizeof(fullname)); if (append) { strcpy(fullname, prefix); strcat(fullname, infile); } else strcpy(fullname, infile); outfilename = extend ? extendfile(fullname, outfile) : outfile; open_output(infile, outfilename); strcpy(fullname, outfilename); if ((p = strchr(fullname, '.'))) *p = '\0'; f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n"); f_print(fout, "#ifndef _RXGEN_%s_\n", uppercase(fullname)); f_print(fout, "#define _RXGEN_%s_\n\n", uppercase(fullname)); f_print(fout, "#ifdef KERNEL\n"); f_print(fout, "/* The following 'ifndefs' are not a good solution to the vendor's omission of surrounding all system includes with 'ifndef's since it requires that this file is included after the system includes...*/\n"); f_print(fout, "#include <afsconfig.h>\n"); f_print(fout, "#include \"afs/param.h\"\n"); f_print(fout, "#ifdef UKERNEL\n"); f_print(fout, "#include \"afs/sysincludes.h\"\n"); f_print(fout, "#include \"rx/xdr.h\"\n"); f_print(fout, "#include \"rx/rx.h\"\n"); if (xflag) { f_print(fout, "#include \"rx/rx_globals.h\"\n"); } if (brief_flag) { f_print(fout, "#include \"rx/rx_opaque.h\"\n"); } if (uflag) f_print(fout, "#include <ubik.h>\n"); f_print(fout, "#else /* UKERNEL */\n"); f_print(fout, "#include \"h/types.h\"\n"); f_print(fout, "#ifndef SOCK_DGRAM /* XXXXX */\n"); f_print(fout, "#include \"h/socket.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "struct ubik_client;\n"); f_print(fout, "#ifndef DTYPE_SOCKET /* XXXXX */\n"); f_print(fout, "#ifndef AFS_LINUX22_ENV\n"); f_print(fout, "#include \"h/file.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "#endif\n"); f_print(fout, "#ifndef S_IFMT /* XXXXX */\n"); f_print(fout, "#include \"h/stat.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "#if defined (AFS_OBSD_ENV) && !defined (MLEN)\n"); f_print(fout, "#include \"sys/mbuf.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "#ifndef IPPROTO_UDP /* XXXXX */\n"); f_print(fout, "#include \"netinet/in.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "#ifndef DST_USA /* XXXXX */\n"); f_print(fout, "#include \"h/time.h\"\n"); f_print(fout, "#endif\n"); f_print(fout, "#ifndef AFS_LINUX22_ENV\n"); f_print(fout, "#include \"rpc/types.h\"\n"); f_print(fout, "#endif /* AFS_LINUX22_ENV */\n"); f_print(fout, "#ifndef XDR_GETLONG /* XXXXX */\n"); f_print(fout, "#ifdef AFS_LINUX22_ENV\n"); f_print(fout, "#ifndef quad_t\n"); f_print(fout, "#define quad_t __quad_t\n"); f_print(fout, "#define u_quad_t __u_quad_t\n"); f_print(fout, "#endif\n"); f_print(fout, "#endif\n"); f_print(fout, "#include \"rx/xdr.h\"\n"); f_print(fout, "#endif /* XDR_GETLONG */\n"); f_print(fout, "#endif /* UKERNEL */\n"); f_print(fout, "#include \"afs/rxgen_consts.h\"\n"); f_print(fout, "#include \"afs_osi.h\"\n"); f_print(fout, "#include \"rx/rx.h\"\n"); if (xflag) { f_print(fout, "#include \"rx/rx_globals.h\"\n"); } if (brief_flag) { f_print(fout, "#include \"rx/rx_opaque.h\"\n"); } f_print(fout, "#else /* KERNEL */\n"); f_print(fout, "#include <afs/param.h>\n"); f_print(fout, "#include <afs/stds.h>\n"); f_print(fout, "#include <sys/types.h>\n"); f_print(fout, "#include <rx/xdr.h>\n"); f_print(fout, "#include <rx/rx.h>\n"); if (xflag) { f_print(fout, "#include <rx/rx_globals.h>\n"); } if (brief_flag) { f_print(fout, "#include <rx/rx_opaque.h>\n"); } f_print(fout, "#include <afs/rxgen_consts.h>\n"); if (uflag) f_print(fout, "#include <ubik.h>\n"); f_print(fout, "#endif /* KERNEL */\n\n"); f_print(fout, "#ifdef AFS_NT40_ENV\n"); f_print(fout, "#ifndef AFS_RXGEN_EXPORT\n"); f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllimport)\n"); f_print(fout, "#endif /* AFS_RXGEN_EXPORT */\n"); f_print(fout, "#else /* AFS_NT40_ENV */\n"); f_print(fout, "#define AFS_RXGEN_EXPORT\n"); f_print(fout, "#endif /* AFS_NT40_ENV */\n\n"); tell = ftell(fout); while ((def = get_definition())) { print_datadef(def); } h_Proc_CodeGeneration(); h_opcode_stats(); hflag = 0; f_print(fout, "#endif /* _RXGEN_%s_ */\n", uppercase(fullname)); if (extend && tell == ftell(fout)) { (void)unlink(outfilename); } }
/* * Compile into an XDR routine output file */ static void c_output(char *infile, char *define, int extend, char *outfile, int append) { definition *def; char *include; char *outfilename; long tell; char fullname[1024]; char *currfile = (OutFileFlag ? OutFile : infile); int i, j; open_input(infile, define); cflag = 1; memset(fullname, 0, sizeof(fullname)); if (append) { strcpy(fullname, prefix); strcat(fullname, infile); } else strcpy(fullname, infile); outfilename = extend ? extendfile(fullname, outfile) : outfile; open_output(infile, outfilename); f_print(fout, "/* Machine generated file -- Do NOT edit */\n\n"); if (xflag) { if (kflag) { f_print(fout, "#include \"afsconfig.h\"\n"); f_print(fout, "#include \"afs/param.h\"\n"); } else { f_print(fout, "#include <afsconfig.h>\n"); f_print(fout, "#include <afs/param.h>\n"); f_print(fout, "#include <roken.h>\n"); } f_print(fout, "#ifdef AFS_NT40_ENV\n"); f_print(fout, "#define AFS_RXGEN_EXPORT __declspec(dllexport)\n"); f_print(fout, "#endif /* AFS_NT40_ENV */\n"); } if (currfile && (include = extendfile(currfile, ".h"))) { if (kflag) { f_print(fout, "#include \"%s\"\n\n", include); } else f_print(fout, "#include \"%s\"\n\n", include); free(include); } else { /* In case we can't include the interface's own header file... */ if (kflag) { f_print(fout, "#include \"h/types.h\"\n"); f_print(fout, "#include \"h/socket.h\"\n"); f_print(fout, "#include \"h/file.h\"\n"); f_print(fout, "#include \"h/stat.h\"\n"); f_print(fout, "#include \"netinet/in.h\"\n"); f_print(fout, "#include \"h/time.h\"\n"); f_print(fout, "#include \"rx/xdr.h\"\n"); f_print(fout, "#include \"afs/rxgen_consts.h\"\n"); } else { f_print(fout, "#include <rx/xdr.h>\n"); } } tell = ftell(fout); while ((def = get_definition())) { if (!yflag) { if ((!IsRxgenDefinition(def)) && def->def_kind != DEF_CUSTOMIZED) emit(def); } } /* * Print out array containing list of all functions in the interface * in order */ if (xflag) { for (j = 0; j <= PackageIndex; j++) { f_print(fout, "AFS_RXGEN_EXPORT\n"); f_print(fout, "const char *%sfunction_names[] = {\n", PackagePrefix[j]); for (i = 0; i < no_of_stat_funcs_header[j]; i++) { if (i == 0) { f_print(fout, "\t\"%s\"", function_list[j][i]); } else { f_print(fout, ",\n\t\"%s\"", function_list[j][i]); } } f_print(fout, "\n};\n"); } er_Proc_CodeGeneration(); } if (extend && tell == ftell(fout)) { (void)unlink(outfilename); } cflag = 0; }
/* * dep - directory entry to copy into the directory * ddep - directory to add to * depp - return the address of the denode for the created directory entry * if depp != 0 * cnp - componentname needed for Win95 long filenames */ int createde(struct denode *dep, struct denode *ddep, struct denode **depp, struct componentname *cnp) { int error; u_long dirclust, diroffset; struct direntry *ndep; struct msdosfsmount *pmp = ddep->de_pmp; struct buf *bp; daddr_t bn; int blsize; #ifdef MSDOSFS_DEBUG kprintf("createde(dep %p, ddep %p, depp %p, cnp %p)\n", dep, ddep, depp, cnp); #endif /* * If no space left in the directory then allocate another cluster * and chain it onto the end of the file. There is one exception * to this. That is, if the root directory has no more space it * can NOT be expanded. extendfile() checks for and fails attempts * to extend the root directory. We just return an error in that * case. */ if (ddep->de_fndoffset >= ddep->de_FileSize) { diroffset = ddep->de_fndoffset + sizeof(struct direntry) - ddep->de_FileSize; dirclust = de_clcount(pmp, diroffset); error = extendfile(ddep, dirclust, 0, 0, DE_CLEAR); if (error) { detrunc(ddep, ddep->de_FileSize, 0); return error; } /* * Update the size of the directory */ ddep->de_FileSize += de_cn2off(pmp, dirclust); } /* * We just read in the cluster with space. Copy the new directory * entry in. Then write it to disk. NOTE: DOS directories * do not get smaller as clusters are emptied. */ error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset), &bn, &dirclust, &blsize); if (error) return error; diroffset = ddep->de_fndoffset; if (dirclust != MSDOSFSROOT) diroffset &= pmp->pm_crbomask; if ((error = bread(pmp->pm_devvp, de_bntodoff(pmp, bn), blsize, &bp)) != 0) { brelse(bp); return error; } ndep = bptoep(pmp, bp, ddep->de_fndoffset); DE_EXTERNALIZE(ndep, dep); /* * Now write the Win95 long name */ if (ddep->de_fndcnt > 0) { u_int8_t chksum = winChksum(ndep->deName); const u_char *un = (const u_char *)cnp->cn_nameptr; int unlen = cnp->cn_namelen; int cnt = 1; while (--ddep->de_fndcnt >= 0) { if (!(ddep->de_fndoffset & pmp->pm_crbomask)) { if ((error = bwrite(bp)) != 0) return error; ddep->de_fndoffset -= sizeof(struct direntry); error = pcbmap(ddep, de_cluster(pmp, ddep->de_fndoffset), &bn, NULL, &blsize); if (error) return error; error = bread(pmp->pm_devvp, de_bntodoff(pmp, bn), blsize, &bp); if (error) { brelse(bp); return error; } ndep = bptoep(pmp, bp, ddep->de_fndoffset); } else { ndep--; ddep->de_fndoffset -= sizeof(struct direntry); } if (!unix2winfn(un, unlen, (struct winentry *)ndep, cnt++, chksum, pmp)) break; } } if ((error = bwrite(bp)) != 0) return error; /* * If they want us to return with the denode gotten. */ if (depp) { if (dep->de_Attributes & ATTR_DIRECTORY) { dirclust = dep->de_StartCluster; if (FAT32(pmp) && dirclust == pmp->pm_rootdirblk) dirclust = MSDOSFSROOT; if (dirclust == MSDOSFSROOT) diroffset = MSDOSFSROOT_OFS; else diroffset = 0; } return deget(pmp, dirclust, diroffset, depp); } return 0; }
static void h_output (char *infile, char *define, int extend, char *outfile) { definition *def; char *outfilename; long tell; char *guard; list *l; open_input (infile, define); outfilename = extend ? extendfile (infile, outfile) : outfile; open_output (infile, outfilename); add_warning (); guard = generate_guard (outfilename ? outfilename : infile); f_print (fout, "#ifndef _%s\n#define _%s\n\n", guard, guard); #if 0 f_print (fout, "#define RPCGEN_VERSION\t%s\n\n", RPCGEN_VERSION); f_print (fout, "#include <rpc/rpc.h>\n\n"); #else f_print (fout, "#include \"%s\"\n\n", incfile); #endif #if 0 f_print (fout, "#ifdef __cplusplus\n" "\n" "#ifndef EXTERN\n" "#define EXTERN extern \"C\" \n" "#define EXTERN_DEFINED_BY_%s\n" "#endif /* !EXTERN */\n" "#ifndef UNION_NAME\n" "#define UNION_NAME(name) u\n" "#define UNION_NAME_DEFINED_BY_%s 1\n" "#endif /* !UNION_NAME */\n" "#ifndef CONSTRUCT\n" "#define CONSTRUCT(Type, type) \\\n" "struct Type : public type { \\\n" " Type () { bzero ((type *) this, sizeof (type)); } \\\n" " ~Type () { xdr_free ((xdrproc_t) xdr_ ## type, \\\n" " (char *) (type *) this); } \\\n" "};\n" "#define CONSTRUCT_DEFINED_BY_%s\n" "#endif /* !CONSTRUCT */\n" "\n" "#else /* !__cplusplus */\n" "\n" "#ifndef EXTERN\n" "#define EXTERN extern\n" "#define EXTERN_DEFINED_BY_%s\n" "#endif /* !EXTERN */\n" "#ifndef UNION_NAME\n" "#define UNION_NAME(name) u\n" "#define UNION_NAME_DEFINED_BY_%s 1\n" "#endif /* !UNION_NAME */\n" "#ifndef CONSTRUCT\n" "#define CONSTRUCT(Type, type)\n" "#define CONSTRUCT_DEFINED_BY_%s\n" "#endif /* !CONSTRUCT */\n" "\n" "#endif /* !__cplusplus */\n", guard, guard, guard, guard, guard, guard); #endif tell = ftell (fout); /* print data definitions */ while ((def = get_definition ())) { print_datadef (def); } /* print function declarations. Do this after data definitions because they might be used as arguments for functions */ for (l = defined; l != NULL; l = l->next) { print_funcdef (l->val); } if (extend && tell == ftell (fout)) { (void) unlink (outfilename); } #if 0 f_print (fout, "\n#ifdef __cplusplus\n" "}\n" "#endif /* __cplusplus */\n"); #endif f_print (fout, "\n"); #if 0 f_print (fout, "#ifdef EXTERN_DEFINED_BY_%s\n" "#undef EXTERN\n" "#undef EXTERN_DEFINED_BY_%s\n" "#endif /* EXTERN_DEFINED_BY_%s */\n" "#ifdef UNION_NAME_DEFINED_BY_%s\n" "#undef UNION_NAME\n" "#undef UNION_NAME_DEFINED_BY_%s\n" "#endif /* UNION_NAME_DEFINED_BY_%s */\n" "#ifdef CONSTRUCT_DEFINED_BY_%s\n" "#undef CONSTRUCT\n" "#undef CONSTRUCT_DEFINED_BY_%s\n" "#endif /* CONSTRUCT_DEFINED_BY_%s */\n", guard, guard, guard, guard, guard, guard, guard, guard, guard); #endif f_print (fout, "\n#endif /* !_%s */\n", guard); }
/* * Write data to a file or directory. */ int msdosfs_write(void *v) { struct vop_write_args *ap = v; int n; int croffset; int resid; uint32_t osize; int error = 0; uint32_t count, lastcn; daddr64_t bn; struct buf *bp; int ioflag = ap->a_ioflag; struct uio *uio = ap->a_uio; struct proc *p = uio->uio_procp; struct vnode *vp = ap->a_vp; struct vnode *thisvp; struct denode *dep = VTODE(vp); struct msdosfsmount *pmp = dep->de_pmp; struct ucred *cred = ap->a_cred; #ifdef MSDOSFS_DEBUG printf("msdosfs_write(vp %08x, uio %08x, ioflag %08x, cred %08x\n", vp, uio, ioflag, cred); printf("msdosfs_write(): diroff %d, dirclust %d, startcluster %d\n", dep->de_diroffset, dep->de_dirclust, dep->de_StartCluster); #endif switch (vp->v_type) { case VREG: if (ioflag & IO_APPEND) uio->uio_offset = dep->de_FileSize; thisvp = vp; break; case VDIR: return EISDIR; default: panic("msdosfs_write(): bad file type"); } if (uio->uio_offset < 0) return (EINVAL); if (uio->uio_resid == 0) return (0); /* Don't bother to try to write files larger than the f/s limit */ if (uio->uio_offset + uio->uio_resid > MSDOSFS_FILESIZE_MAX) return (EFBIG); /* * If they've exceeded their filesize limit, tell them about it. */ if (p && ((uio->uio_offset + uio->uio_resid) > p->p_rlimit[RLIMIT_FSIZE].rlim_cur)) { psignal(p, SIGXFSZ); return (EFBIG); } /* * If the offset we are starting the write at is beyond the end of * the file, then they've done a seek. Unix filesystems allow * files with holes in them, DOS doesn't so we must fill the hole * with zeroed blocks. */ if (uio->uio_offset > dep->de_FileSize) { if ((error = deextend(dep, uio->uio_offset, cred)) != 0) return (error); } /* * Remember some values in case the write fails. */ resid = uio->uio_resid; osize = dep->de_FileSize; /* * If we write beyond the end of the file, extend it to its ultimate * size ahead of the time to hopefully get a contiguous area. */ if (uio->uio_offset + resid > osize) { count = de_clcount(pmp, uio->uio_offset + resid) - de_clcount(pmp, osize); if ((error = extendfile(dep, count, NULL, NULL, 0)) && (error != ENOSPC || (ioflag & IO_UNIT))) goto errexit; lastcn = dep->de_fc[FC_LASTFC].fc_frcn; } else lastcn = de_clcount(pmp, osize) - 1; do { if (de_cluster(pmp, uio->uio_offset) > lastcn) { error = ENOSPC; break; } bn = de_blk(pmp, uio->uio_offset); if ((uio->uio_offset & pmp->pm_crbomask) == 0 && (de_blk(pmp, uio->uio_offset + uio->uio_resid) > de_blk(pmp, uio->uio_offset) || uio->uio_offset + uio->uio_resid >= dep->de_FileSize)) { /* * If either the whole cluster gets written, * or we write the cluster from its start beyond EOF, * then no need to read data from disk. */ bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0); clrbuf(bp); /* * Do the bmap now, since pcbmap needs buffers * for the fat table. (see msdosfs_strategy) */ if (bp->b_blkno == bp->b_lblkno) { error = pcbmap(dep, de_bn2cn(pmp, bp->b_lblkno), &bp->b_blkno, 0, 0); if (error) bp->b_blkno = -1; } if (bp->b_blkno == -1) { brelse(bp); if (!error) error = EIO; /* XXX */ break; } } else { /* * The block we need to write into exists, so read it in. */ error = bread(thisvp, bn, pmp->pm_bpcluster, NOCRED, &bp); if (error) { brelse(bp); break; } } croffset = uio->uio_offset & pmp->pm_crbomask; n = min(uio->uio_resid, pmp->pm_bpcluster - croffset); if (uio->uio_offset + n > dep->de_FileSize) { dep->de_FileSize = uio->uio_offset + n; uvm_vnp_setsize(vp, dep->de_FileSize); } uvm_vnp_uncache(vp); /* * Should these vnode_pager_* functions be done on dir * files? */ /* * Copy the data from user space into the buf header. */ error = uiomove(bp->b_data + croffset, n, uio); /* * If they want this synchronous then write it and wait for * it. Otherwise, if on a cluster boundary write it * asynchronously so we can move on to the next block * without delay. Otherwise do a delayed write because we * may want to write somemore into the block later. */ if (ioflag & IO_SYNC) (void) bwrite(bp); else if (n + croffset == pmp->pm_bpcluster) bawrite(bp); else bdwrite(bp); dep->de_flag |= DE_UPDATE; } while (error == 0 && uio->uio_resid > 0); /* * If the write failed and they want us to, truncate the file back * to the size it was before the write was attempted. */ errexit: if (error) { if (ioflag & IO_UNIT) { detrunc(dep, osize, ioflag & IO_SYNC, NOCRED, NULL); uio->uio_offset -= resid - uio->uio_resid; uio->uio_resid = resid; } else { detrunc(dep, dep->de_FileSize, ioflag & IO_SYNC, NOCRED, NULL); if (uio->uio_resid != resid) error = 0; } } else if (ioflag & IO_SYNC) error = deupdat(dep, 1); return (error); }