2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
4 * File.xs contains XS code for exacct file manipulation.
8 #include "../exacct_common.xh"
10 /* Pull in the file generated by extract_defines. */
11 #include "FileDefs.xi"
14 * The XS code exported to perl is below here. Note that the XS preprocessor
15 * has its own commenting syntax, so all comments from this point on are in
19 MODULE = Sun::Solaris::Exacct::File PACKAGE = Sun::Solaris::Exacct::File
23 # Define the stash pointers if required and create and populate @_Constants.
28 define_constants(PKGBASE "::File", constants);
32 # Open an exacct file and return an object with which to manipulate it.
33 # The parameters are the filename, the open mode and a list of optional
34 # (key => value) parameters where the key may be one of creator, aflags or
35 # mode. For a full explanation of the various combinations, see the manpage
36 # for ea_open_file(3EXACCT).
39 new(class, name, oflags, ...)
45 /* Assume usernames are <= 32 chars (pwck(1M) assumes <= 8) */
52 * Account for the mandatory parameters,
53 * and the rest must be an even number.
57 croak("Usage: Sun::Solaris::Exacct::File::new"
58 "(class, name, oflags, ...)");
61 /* Process any optional parameters. */
62 for (i = 3; i < items; i += 2) {
63 if (strEQ(SvPV_nolen(ST(i)), "creator")) {
64 creator = SvPV_nolen(ST(i + 1));
65 } else if (strEQ(SvPV_nolen(ST(i)), "aflags")) {
66 aflags = SvIV(ST(i + 1));
67 } else if (strEQ(SvPV_nolen(ST(i)), "mode")) {
68 mode = SvIV(ST(i + 1));
70 croak("invalid named argument %s", SvPV_nolen(ST(i)));
74 /* Check and default the creator parameter. */
75 if (oflags & O_CREAT && creator == NULL) {
80 if ((pwent = getpwuid(uid)) == NULL) {
81 snprintf(user, sizeof (user), "%d", uid);
83 strlcpy(user, pwent->pw_name, sizeof (user));
88 /* Check and default the aflags parameter. */
90 if (oflags == O_RDONLY) {
96 RETVAL = ea_alloc(sizeof (ea_file_t));
97 PERL_ASSERT(RETVAL != NULL);
98 if (ea_open(RETVAL, name, creator, aflags, oflags, mode) == -1) {
99 ea_free(RETVAL, sizeof (ea_file_t));
110 ea_free(self, sizeof(ea_file_t));
113 # Return the creator of the file.
121 if ((creator = ea_get_creator(self)) == NULL) {
122 RETVAL = &PL_sv_undef;
124 RETVAL = newSVpv(creator, 0);
130 # Return the hostname the file was created on.
136 const char *hostname;
138 if ((hostname = ea_get_hostname(self)) == NULL) {
139 RETVAL = &PL_sv_undef;
141 RETVAL = newSVpv(hostname, 0);
147 # Get the next/previous record from the file and return its type.
148 # These two operations are so similar that the XSUB ALIAS functionality is
149 # used to merge them into one function.
157 ea_object_type_t type;
158 const char *type_str;
161 static const char *const type_map[] =
162 { "EO_NONE", "EO_GROUP", "EO_ITEM" };
164 /* Call the appropriate next/last function. */
166 type = ea_next_object(self, &object);
168 type = ea_previous_object(self, &object);
171 /* Work out the call context. */
174 /* In a scalar context, just return the type. */
176 if (type == EO_ERROR) {
180 sv_setpv(sv, type_map[type]);
182 PUSHs(sv_2mortal(sv));
186 /* In a list contect, return the type and catalog. */
188 if (type == EO_ERROR) {
193 sv_setpv(sv, type_map[type]);
195 PUSHs(sv_2mortal(sv));
196 PUSHs(sv_2mortal(new_catalog(object.eo_catalog)));
201 /* In a void context, return nothing. */
206 # Get the next object from the file and return as an ::Object.
214 if ((obj = ea_get_object_tree(self, 1)) != NULL) {
215 RETVAL = new_xs_ea_object(obj);
217 RETVAL = &PL_sv_undef;
223 # Write the passed list of ::Objects to the file.
224 # Returns true on success and false on failure.
235 for (i = 1; i < items; i++) {
236 /* Check the value is either an ::Item or a ::Group. */
238 stash = sv ? SvSTASH(sv) : NULL;
239 if (stash != Sun_Solaris_Exacct_Object_Item_stash &&
240 stash != Sun_Solaris_Exacct_Object_Group_stash) {
244 /* Deflate and write the object. */
245 obj = deflate_xs_ea_object(ST(i));
246 PERL_ASSERT(obj != NULL);
247 if (ea_write_object(self, obj) == -1) {